[vlc-devel] [PATCH] Support for loading any MFT in case video format is not found from the hardcoded list
Jean-Baptiste Kempf
jb at videolan.org
Sun Mar 4 13:06:19 CET 2018
Hello,
On Sun, 4 Mar 2018, at 11:53, Teemu Ikonen wrote:
> Adds support in Media Foundation (MFT) module to use decoders whose
> FCC is not found from the hardcoded list. Improves compatibility and
> adds support for common uncompressed formats decoders might prefer.
This looks cool, but how do you have examples of such things?
> Internal formats (like MFVideoFormat_RGB32) are bottom up (negative
> stride). Code just changes the to ORIENT_BOTTOM_LEFT in this case and
> it works, but is this the right thing do?
Did you look at the avi code?
Best,
>
> ---
> modules/codec/mft.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++----> 1 file changed, 62 insertions(+), 4 deletions(-)
>
> diff --git a/modules/codec/mft.c b/modules/codec/mft.c
> index 24eaaa55cb..3cf6aa494d 100644
> --- a/modules/codec/mft.c
> +++ b/modules/codec/mft.c
> @@ -92,6 +92,8 @@ struct decoder_sys_t
>
> const GUID* major_type;
> const GUID* subtype;
> + /* Container for a dynamically constructed subtype */
> + GUID custom_subtype;
>
> /* For asynchronous MFT */
> bool is_async;
> @@ -183,6 +185,20 @@ static const pair_format_guid
> video_format_table[] => { 0, NULL }
> };
>
> +// 8-bit luminance only
> +DEFINE_MEDIATYPE_GUID (MFVideoFormat_L8, 50);
> +
> +/*
> + * Table to map MF Transform raw 3D3 output formats to native VLC
> FourCC> + */
> +static const pair_format_guid d3d_format_table[] = {
> + { VLC_CODEC_RGB32, &MFVideoFormat_RGB32 },
> + { VLC_CODEC_RGB24, &MFVideoFormat_RGB24 },
> + { VLC_CODEC_RGBA, &MFVideoFormat_ARGB32 },
> + { VLC_CODEC_GREY, &MFVideoFormat_L8 },
> + { 0, NULL }
> +};
> +
> #if defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 4
> DEFINE_GUID(MFAudioFormat_Dolby_AC3, 0xe06d802c, 0xdb46, 0x11cf,
> 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea);> #endif
> @@ -210,6 +226,15 @@ static const GUID *FormatToGUID(const
> pair_format_guid table[], vlc_fourcc_t fou> return NULL;
> }
>
> +static vlc_fourcc_t GUIDToFormat(const pair_format_guid table[],
> const GUID* guid)> +{
> + for (int i = 0; table[i].fourcc; ++i)
> + if (IsEqualGUID(table[i].guid, guid))
> + return table[i].fourcc;
> +
> + return 0;
> +}
> +
> /*
> * Low latency mode for Windows 8. Without this option, the H264
> * decoder will fill *all* its internal buffers before returning a
> @@ -272,6 +297,16 @@ static int SetInputType(decoder_t *p_dec, DWORD
> stream_id, IMFMediaType **result> hr = IMFMediaType_SetUINT64(input_media_type,
> &MF_MT_FRAME_SIZE, frame_size);> if (FAILED(hr))
> goto error;
> +
> + /* Some transforms like to know the frame rate and may reject
> the input type otherwise. */> + UINT64 frame_ratio_num = p_dec->fmt_in.video.i_frame_rate;
> + UINT64 frame_ratio_dem = p_dec-
> >fmt_in.video.i_frame_rate_base;> + if(frame_ratio_num && frame_ratio_dem) {
> + UINT64 frame_rate = (frame_ratio_num << 32) |
> frame_ratio_dem;> + hr = IMFMediaType_SetUINT64(input_media_type,
> &MF_MT_FRAME_RATE, frame_rate);> + if(FAILED(hr))
> + goto error;
> + }
> }
> else
> {
> @@ -356,7 +391,7 @@ static int SetOutputType(decoder_t *p_dec, DWORD
> stream_id, IMFMediaType **resul> * preference thus we will use the first one unless YV12/I420 is> * available for video or float32 for audio.
> */
> - int output_type_index = 0;
> + int output_type_index = -1;
> bool found = false;
> for (int i = 0; !found; ++i)
> {
> @@ -380,6 +415,10 @@ static int SetOutputType(decoder_t *p_dec, DWORD
> stream_id, IMFMediaType **resul> {
> if (IsEqualGUID(&subtype, &MFVideoFormat_YV12) ||
> IsEqualGUID(&subtype, &MFVideoFormat_I420))> found = true;
> + /* Transform might offer output in a D3DFMT propietary
> FCC. If we can> + * use it, fall back to it in case we do not find YV12 or
> I420 */> + else if(output_type_index < 0 &&
> GUIDToFormat(d3d_format_table, &subtype) > 0)> + output_type_index = i;
> }
> else
> {
> @@ -399,9 +438,12 @@ static int SetOutputType(decoder_t *p_dec, DWORD
> stream_id, IMFMediaType **resul> }
> /*
> * It's not an error if we don't find the output type we were
> - * looking for, in this case we use the first available type
> which> - * is the "preferred" output type for this MFT.
> + * looking for, in this case we use the first available type.
> */
> + if(output_type_index < 0)
> + /* No output format found we prefer, just pick the first one
> preferred> + * by the MFT */
> + output_type_index = 0;
>
> hr = IMFTransform_GetOutputAvailableType(p_sys->mft, stream_id,
> output_type_index, &output_media_type);> if (FAILED(hr))
> @@ -419,7 +461,17 @@ static int SetOutputType(decoder_t *p_dec, DWORD
> stream_id, IMFMediaType **resul> if (p_dec->fmt_in.i_cat == VIDEO_ES)
> {
> video_format_Copy( &p_dec->fmt_out.video, &p_dec-
> >fmt_in.video );> - p_dec->fmt_out.i_codec = vlc_fourcc_GetCodec(p_dec-
> >fmt_in.i_cat, subtype.Data1);> +
> + /* Transform might offer output in a D3DFMT propietary FCC */> + vlc_fourcc_t fcc = GUIDToFormat(d3d_format_table, &subtype);> + if(fcc) {
> + /* D3D formats are upside down */
> + p_dec->fmt_out.video.orientation = ORIENT_BOTTOM_LEFT;
> + } else {
> + fcc = vlc_fourcc_GetCodec(p_dec->fmt_in.i_cat,
> subtype.Data1);> + }
> +
> + p_dec->fmt_out.i_codec = fcc;
> }
> else
> {
> @@ -1046,6 +1098,12 @@ static int FindMFT(decoder_t *p_dec)
> category = MFT_CATEGORY_VIDEO_DECODER;
> p_sys->major_type = &MFMediaType_Video;
> p_sys->subtype = FormatToGUID(video_format_table, p_dec-
> >fmt_in.i_codec);> + if(!p_sys->subtype) {
> + /* Codec is not well known. Construct a MF transform
> subtype from the fourcc */> + p_sys->custom_subtype = MFVideoFormat_Base;
> + p_sys->custom_subtype.Data1 = p_dec->fmt_in.i_codec;
> + p_sys->subtype = &p_sys->custom_subtype;
> + }
> }
> else
> {
> --
> 2.14.1
>
> _________________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
--
Jean-Baptiste Kempf - President
+33 672 704 734
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20180304/dad08706/attachment.html>
More information about the vlc-devel
mailing list