2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
22 #define _WIN32_WINNT 0x0602
26 #include "libavutil/pixdesc.h"
28 HRESULT
ff_MFGetAttributeSize(IMFAttributes
*pattr
, REFGUID guid
,
29 UINT32
*pw
, UINT32
*ph
)
32 HRESULT hr
= IMFAttributes_GetUINT64(pattr
, guid
, &t
);
40 HRESULT
ff_MFSetAttributeSize(IMFAttributes
*pattr
, REFGUID guid
,
43 UINT64 t
= (((UINT64
)uw
) << 32) | uh
;
44 return IMFAttributes_SetUINT64(pattr
, guid
, t
);
47 #define ff_MFSetAttributeRatio ff_MFSetAttributeSize
48 #define ff_MFGetAttributeRatio ff_MFGetAttributeSize
50 char *ff_hr_str_buf(char *buf
, size_t size
, HRESULT hr
)
52 #define HR(x) case x: return (char *) # x;
56 HR(MF_E_INVALIDMEDIATYPE
)
57 HR(MF_E_INVALIDSTREAMNUMBER
)
59 HR(MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING
)
60 HR(MF_E_TRANSFORM_TYPE_NOT_SET
)
61 HR(MF_E_UNSUPPORTED_D3D_TYPE
)
62 HR(MF_E_TRANSFORM_NEED_MORE_INPUT
)
63 HR(MF_E_TRANSFORM_STREAM_CHANGE
)
65 HR(MF_E_NO_SAMPLE_TIMESTAMP
)
66 HR(MF_E_NO_SAMPLE_DURATION
)
69 snprintf(buf
, size
, "%x", (unsigned)hr
);
73 // If fill_data!=NULL, initialize the buffer and set the length. (This is a
74 // subtle but important difference: some decoders want CurrentLength==0 on
75 // provided output buffers.)
76 IMFSample
*ff_create_memory_sample(MFFunctions
*f
,void *fill_data
, size_t size
,
81 IMFMediaBuffer
*buffer
;
83 hr
= f
->MFCreateSample(&sample
);
87 align
= FFMAX(align
, 16); // 16 is "recommended", even if not required
89 hr
= f
->MFCreateAlignedMemoryBuffer(size
, align
- 1, &buffer
);
96 hr
= IMFMediaBuffer_Lock(buffer
, &tmp
, NULL
, NULL
);
98 IMFMediaBuffer_Release(buffer
);
99 IMFSample_Release(sample
);
102 memcpy(tmp
, fill_data
, size
);
104 IMFMediaBuffer_SetCurrentLength(buffer
, size
);
105 IMFMediaBuffer_Unlock(buffer
);
108 IMFSample_AddBuffer(sample
, buffer
);
109 IMFMediaBuffer_Release(buffer
);
114 enum AVSampleFormat
ff_media_type_to_sample_fmt(IMFAttributes
*type
)
120 hr
= IMFAttributes_GetUINT32(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &bits
);
122 return AV_SAMPLE_FMT_NONE
;
124 hr
= IMFAttributes_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
);
126 return AV_SAMPLE_FMT_NONE
;
128 if (IsEqualGUID(&subtype
, &MFAudioFormat_PCM
)) {
130 case 8: return AV_SAMPLE_FMT_U8
;
131 case 16: return AV_SAMPLE_FMT_S16
;
132 case 32: return AV_SAMPLE_FMT_S32
;
134 } else if (IsEqualGUID(&subtype
, &MFAudioFormat_Float
)) {
136 case 32: return AV_SAMPLE_FMT_FLT
;
137 case 64: return AV_SAMPLE_FMT_DBL
;
141 return AV_SAMPLE_FMT_NONE
;
144 struct mf_pix_fmt_entry
{
146 enum AVPixelFormat pix_fmt
;
149 static const struct mf_pix_fmt_entry mf_pix_fmts
[] = {
150 {&MFVideoFormat_IYUV
, AV_PIX_FMT_YUV420P
},
151 {&MFVideoFormat_I420
, AV_PIX_FMT_YUV420P
},
152 {&MFVideoFormat_NV12
, AV_PIX_FMT_NV12
},
153 {&MFVideoFormat_P010
, AV_PIX_FMT_P010
},
154 {&MFVideoFormat_P016
, AV_PIX_FMT_P010
}, // not equal, but compatible
155 {&MFVideoFormat_YUY2
, AV_PIX_FMT_YUYV422
},
158 enum AVPixelFormat
ff_media_type_to_pix_fmt(IMFAttributes
*type
)
164 hr
= IMFAttributes_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
);
166 return AV_PIX_FMT_NONE
;
168 for (i
= 0; i
< FF_ARRAY_ELEMS(mf_pix_fmts
); i
++) {
169 if (IsEqualGUID(&subtype
, mf_pix_fmts
[i
].guid
))
170 return mf_pix_fmts
[i
].pix_fmt
;
173 return AV_PIX_FMT_NONE
;
176 const GUID
*ff_pix_fmt_to_guid(enum AVPixelFormat pix_fmt
)
180 for (i
= 0; i
< FF_ARRAY_ELEMS(mf_pix_fmts
); i
++) {
181 if (mf_pix_fmts
[i
].pix_fmt
== pix_fmt
)
182 return mf_pix_fmts
[i
].guid
;
188 // If this GUID is of the form XXXXXXXX-0000-0010-8000-00AA00389B71, then
189 // extract the XXXXXXXX prefix as FourCC (oh the pain).
190 int ff_fourcc_from_guid(const GUID
*guid
, uint32_t *out_fourcc
)
192 if (guid
->Data2
== 0 && guid
->Data3
== 0x0010 &&
193 guid
->Data4
[0] == 0x80 &&
194 guid
->Data4
[1] == 0x00 &&
195 guid
->Data4
[2] == 0x00 &&
196 guid
->Data4
[3] == 0xAA &&
197 guid
->Data4
[4] == 0x00 &&
198 guid
->Data4
[5] == 0x38 &&
199 guid
->Data4
[6] == 0x9B &&
200 guid
->Data4
[7] == 0x71) {
201 *out_fourcc
= guid
->Data1
;
206 return AVERROR_UNKNOWN
;
214 #define GUID_ENTRY(var) {&(var), # var}
216 static struct GUID_Entry guid_names
[] = {
217 GUID_ENTRY(MFT_FRIENDLY_NAME_Attribute
),
218 GUID_ENTRY(MFT_TRANSFORM_CLSID_Attribute
),
219 GUID_ENTRY(MFT_ENUM_HARDWARE_URL_Attribute
),
220 GUID_ENTRY(MFT_CONNECTED_STREAM_ATTRIBUTE
),
221 GUID_ENTRY(MFT_CONNECTED_TO_HW_STREAM
),
222 GUID_ENTRY(MF_SA_D3D_AWARE
),
223 GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT
),
224 GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE
),
225 GUID_ENTRY(ff_MF_SA_D3D11_BINDFLAGS
),
226 GUID_ENTRY(ff_MF_SA_D3D11_USAGE
),
227 GUID_ENTRY(ff_MF_SA_D3D11_AWARE
),
228 GUID_ENTRY(ff_MF_SA_D3D11_SHARED
),
229 GUID_ENTRY(ff_MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
230 GUID_ENTRY(MF_MT_SUBTYPE
),
231 GUID_ENTRY(MF_MT_MAJOR_TYPE
),
232 GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
233 GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS
),
234 GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK
),
235 GUID_ENTRY(MF_MT_FRAME_SIZE
),
236 GUID_ENTRY(MF_MT_INTERLACE_MODE
),
237 GUID_ENTRY(MF_MT_USER_DATA
),
238 GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO
),
239 GUID_ENTRY(MFMediaType_Audio
),
240 GUID_ENTRY(MFMediaType_Video
),
241 GUID_ENTRY(MFAudioFormat_PCM
),
242 GUID_ENTRY(MFAudioFormat_Float
),
243 GUID_ENTRY(ff_MFVideoFormat_AV1
),
244 GUID_ENTRY(MFVideoFormat_H264
),
245 GUID_ENTRY(MFVideoFormat_H264_ES
),
246 GUID_ENTRY(ff_MFVideoFormat_HEVC
),
247 GUID_ENTRY(ff_MFVideoFormat_HEVC_ES
),
248 GUID_ENTRY(MFVideoFormat_MPEG2
),
249 GUID_ENTRY(MFVideoFormat_MP43
),
250 GUID_ENTRY(MFVideoFormat_MP4V
),
251 GUID_ENTRY(MFVideoFormat_WMV1
),
252 GUID_ENTRY(MFVideoFormat_WMV2
),
253 GUID_ENTRY(MFVideoFormat_WMV3
),
254 GUID_ENTRY(MFVideoFormat_WVC1
),
255 GUID_ENTRY(MFAudioFormat_Dolby_AC3
),
256 GUID_ENTRY(MFAudioFormat_Dolby_DDPlus
),
257 GUID_ENTRY(MFAudioFormat_AAC
),
258 GUID_ENTRY(MFAudioFormat_MP3
),
259 GUID_ENTRY(MFAudioFormat_MSP1
),
260 GUID_ENTRY(MFAudioFormat_WMAudioV8
),
261 GUID_ENTRY(MFAudioFormat_WMAudioV9
),
262 GUID_ENTRY(MFAudioFormat_WMAudio_Lossless
),
263 GUID_ENTRY(MF_MT_ALL_SAMPLES_INDEPENDENT
),
264 GUID_ENTRY(MF_MT_COMPRESSED
),
265 GUID_ENTRY(MF_MT_FIXED_SIZE_SAMPLES
),
266 GUID_ENTRY(MF_MT_SAMPLE_SIZE
),
267 GUID_ENTRY(MF_MT_WRAPPED_TYPE
),
268 GUID_ENTRY(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
269 GUID_ENTRY(MF_MT_AAC_PAYLOAD_TYPE
),
270 GUID_ENTRY(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
271 GUID_ENTRY(MF_MT_AUDIO_BITS_PER_SAMPLE
),
272 GUID_ENTRY(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
273 GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK
),
274 GUID_ENTRY(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
275 GUID_ENTRY(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
276 GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS
),
277 GUID_ENTRY(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
278 GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
279 GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
280 GUID_ENTRY(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
281 GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGREF
),
282 GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGTARGET
),
283 GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKREF
),
284 GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
285 GUID_ENTRY(MF_MT_AVG_BIT_ERROR_RATE
),
286 GUID_ENTRY(MF_MT_AVG_BITRATE
),
287 GUID_ENTRY(MF_MT_DEFAULT_STRIDE
),
288 GUID_ENTRY(MF_MT_DRM_FLAGS
),
289 GUID_ENTRY(MF_MT_FRAME_RATE
),
290 GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MAX
),
291 GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MIN
),
292 GUID_ENTRY(MF_MT_FRAME_SIZE
),
293 GUID_ENTRY(MF_MT_GEOMETRIC_APERTURE
),
294 GUID_ENTRY(MF_MT_INTERLACE_MODE
),
295 GUID_ENTRY(MF_MT_MAX_KEYFRAME_SPACING
),
296 GUID_ENTRY(MF_MT_MINIMUM_DISPLAY_APERTURE
),
297 GUID_ENTRY(MF_MT_MPEG_SEQUENCE_HEADER
),
298 GUID_ENTRY(MF_MT_MPEG_START_TIME_CODE
),
299 GUID_ENTRY(MF_MT_MPEG2_FLAGS
),
300 GUID_ENTRY(MF_MT_MPEG2_LEVEL
),
301 GUID_ENTRY(MF_MT_MPEG2_PROFILE
),
302 GUID_ENTRY(MF_MT_PAD_CONTROL_FLAGS
),
303 GUID_ENTRY(MF_MT_PALETTE
),
304 GUID_ENTRY(MF_MT_PAN_SCAN_APERTURE
),
305 GUID_ENTRY(MF_MT_PAN_SCAN_ENABLED
),
306 GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO
),
307 GUID_ENTRY(MF_MT_SOURCE_CONTENT_HINT
),
308 GUID_ENTRY(MF_MT_TRANSFER_FUNCTION
),
309 GUID_ENTRY(MF_MT_VIDEO_CHROMA_SITING
),
310 GUID_ENTRY(MF_MT_VIDEO_LIGHTING
),
311 GUID_ENTRY(MF_MT_VIDEO_NOMINAL_RANGE
),
312 GUID_ENTRY(MF_MT_VIDEO_PRIMARIES
),
313 GUID_ENTRY(MF_MT_VIDEO_ROTATION
),
314 GUID_ENTRY(MF_MT_YUV_MATRIX
),
315 GUID_ENTRY(ff_CODECAPI_AVDecVideoThumbnailGenerationMode
),
316 GUID_ENTRY(ff_CODECAPI_AVDecVideoDropPicWithMissingRef
),
317 GUID_ENTRY(ff_CODECAPI_AVDecVideoSoftwareDeinterlaceMode
),
318 GUID_ENTRY(ff_CODECAPI_AVDecVideoFastDecodeMode
),
319 GUID_ENTRY(ff_CODECAPI_AVLowLatencyMode
),
320 GUID_ENTRY(ff_CODECAPI_AVDecVideoH264ErrorConcealment
),
321 GUID_ENTRY(ff_CODECAPI_AVDecVideoMPEG2ErrorConcealment
),
322 GUID_ENTRY(ff_CODECAPI_AVDecVideoCodecType
),
323 GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVAMode
),
324 GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVABusEncryption
),
325 GUID_ENTRY(ff_CODECAPI_AVDecVideoSWPowerLevel
),
326 GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedWidth
),
327 GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedHeight
),
328 GUID_ENTRY(ff_CODECAPI_AVDecNumWorkerThreads
),
329 GUID_ENTRY(ff_CODECAPI_AVDecSoftwareDynamicFormatChange
),
330 GUID_ENTRY(ff_CODECAPI_AVDecDisableVideoPostProcessing
),
333 char *ff_guid_str_buf(char *buf
, size_t buf_size
, const GUID
*guid
)
337 for (n
= 0; n
< FF_ARRAY_ELEMS(guid_names
); n
++) {
338 if (IsEqualGUID(guid
, guid_names
[n
].guid
)) {
339 snprintf(buf
, buf_size
, "%s", guid_names
[n
].name
);
344 if (ff_fourcc_from_guid(guid
, &fourcc
) >= 0) {
345 snprintf(buf
, buf_size
, "<FourCC %s>", av_fourcc2str(fourcc
));
349 snprintf(buf
, buf_size
,
350 "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
351 (unsigned) guid
->Data1
, guid
->Data2
, guid
->Data3
,
352 guid
->Data4
[0], guid
->Data4
[1],
353 guid
->Data4
[2], guid
->Data4
[3],
354 guid
->Data4
[4], guid
->Data4
[5],
355 guid
->Data4
[6], guid
->Data4
[7]);
359 void ff_attributes_dump(void *log
, IMFAttributes
*attrs
)
365 hr
= IMFAttributes_GetCount(attrs
, &count
);
369 for (n
= 0; n
< count
; n
++) {
371 MF_ATTRIBUTE_TYPE type
;
372 char extra
[80] = {0};
373 const char *name
= NULL
;
375 hr
= IMFAttributes_GetItemByIndex(attrs
, n
, &key
, NULL
);
379 name
= ff_guid_str(&key
);
381 if (IsEqualGUID(&key
, &MF_MT_AUDIO_CHANNEL_MASK
)) {
383 hr
= IMFAttributes_GetUINT32(attrs
, &key
, &v
);
386 snprintf(extra
, sizeof(extra
), " (0x%x)", (unsigned)v
);
387 } else if (IsEqualGUID(&key
, &MF_MT_FRAME_SIZE
)) {
390 hr
= ff_MFGetAttributeSize(attrs
, &MF_MT_FRAME_SIZE
, &w
, &h
);
393 snprintf(extra
, sizeof(extra
), " (%dx%d)", (int)w
, (int)h
);
394 } else if (IsEqualGUID(&key
, &MF_MT_PIXEL_ASPECT_RATIO
) ||
395 IsEqualGUID(&key
, &MF_MT_FRAME_RATE
)) {
398 hr
= ff_MFGetAttributeRatio(attrs
, &key
, &num
, &den
);
401 snprintf(extra
, sizeof(extra
), " (%d:%d)", (int)num
, (int)den
);
404 hr
= IMFAttributes_GetItemType(attrs
, &key
, &type
);
409 case MF_ATTRIBUTE_UINT32
: {
411 hr
= IMFAttributes_GetUINT32(attrs
, &key
, &v
);
414 av_log(log
, AV_LOG_VERBOSE
, " %s=%d%s\n", name
, (int)v
, extra
);
416 case MF_ATTRIBUTE_UINT64
: {
418 hr
= IMFAttributes_GetUINT64(attrs
, &key
, &v
);
421 av_log(log
, AV_LOG_VERBOSE
, " %s=%lld%s\n", name
, (long long)v
, extra
);
424 case MF_ATTRIBUTE_DOUBLE
: {
426 hr
= IMFAttributes_GetDouble(attrs
, &key
, &v
);
429 av_log(log
, AV_LOG_VERBOSE
, " %s=%f%s\n", name
, (double)v
, extra
);
432 case MF_ATTRIBUTE_STRING
: {
433 wchar_t s
[512]; // being lazy here
434 hr
= IMFAttributes_GetString(attrs
, &key
, s
, sizeof(s
), NULL
);
437 av_log(log
, AV_LOG_VERBOSE
, " %s='%ls'%s\n", name
, s
, extra
);
440 case MF_ATTRIBUTE_GUID
: {
442 hr
= IMFAttributes_GetGUID(attrs
, &key
, &v
);
445 av_log(log
, AV_LOG_VERBOSE
, " %s=%s%s\n", name
, ff_guid_str(&v
), extra
);
448 case MF_ATTRIBUTE_BLOB
: {
451 hr
= IMFAttributes_GetBlobSize(attrs
, &key
, &sz
);
454 if (sz
<= sizeof(buffer
)) {
458 hr
= IMFAttributes_GetBlob(attrs
, &key
, buffer
, sizeof(buffer
), &sz
);
461 for (pos
= 0; pos
< sz
; pos
++) {
462 const char *hex
= "0123456789ABCDEF";
463 if (pos
* 3 + 3 > sizeof(str
))
465 str
[pos
* 3 + 0] = hex
[buffer
[pos
] >> 4];
466 str
[pos
* 3 + 1] = hex
[buffer
[pos
] & 15];
467 str
[pos
* 3 + 2] = ' ';
469 str
[pos
* 3 + 0] = 0;
470 av_log(log
, AV_LOG_VERBOSE
, " %s=<blob size %d: %s>%s\n", name
, (int)sz
, str
, extra
);
472 av_log(log
, AV_LOG_VERBOSE
, " %s=<blob size %d>%s\n", name
, (int)sz
, extra
);
476 case MF_ATTRIBUTE_IUNKNOWN
: {
477 av_log(log
, AV_LOG_VERBOSE
, " %s=<IUnknown>%s\n", name
, extra
);
481 av_log(log
, AV_LOG_VERBOSE
, " %s=<unknown type>%s\n", name
, extra
);
486 if (IsEqualGUID(&key
, &MF_MT_SUBTYPE
)) {
488 fmt
= av_get_sample_fmt_name(ff_media_type_to_sample_fmt(attrs
));
490 av_log(log
, AV_LOG_VERBOSE
, " FF-sample-format=%s\n", fmt
);
492 fmt
= av_get_pix_fmt_name(ff_media_type_to_pix_fmt(attrs
));
494 av_log(log
, AV_LOG_VERBOSE
, " FF-pixel-format=%s\n", fmt
);
499 av_log(log
, AV_LOG_VERBOSE
, " %s=<failed to get value>\n", name
? name
: "?");
503 void ff_media_type_dump(void *log
, IMFMediaType
*type
)
505 ff_attributes_dump(log
, (IMFAttributes
*)type
);
508 const CLSID
*ff_codec_to_mf_subtype(enum AVCodecID codec
)
511 case AV_CODEC_ID_AV1
: return &ff_MFVideoFormat_AV1
;
512 case AV_CODEC_ID_H264
: return &MFVideoFormat_H264
;
513 case AV_CODEC_ID_HEVC
: return &ff_MFVideoFormat_HEVC
;
514 case AV_CODEC_ID_AC3
: return &MFAudioFormat_Dolby_AC3
;
515 case AV_CODEC_ID_AAC
: return &MFAudioFormat_AAC
;
516 case AV_CODEC_ID_MP3
: return &MFAudioFormat_MP3
;
517 default: return NULL
;
521 static int init_com_mf(void *log
, MFFunctions
*f
)
525 hr
= CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
526 if (hr
== RPC_E_CHANGED_MODE
) {
527 av_log(log
, AV_LOG_ERROR
, "COM must not be in STA mode\n");
528 return AVERROR(EINVAL
);
529 } else if (FAILED(hr
)) {
530 av_log(log
, AV_LOG_ERROR
, "could not initialize COM\n");
531 return AVERROR(ENOSYS
);
534 hr
= f
->MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
536 av_log(log
, AV_LOG_ERROR
, "could not initialize MediaFoundation\n");
538 return AVERROR(ENOSYS
);
544 static void uninit_com_mf(MFFunctions
*f
)
550 // Find and create a IMFTransform with the given input/output types. When done,
551 // you should use ff_free_mf() to destroy it, which will also uninit COM.
552 int ff_instantiate_mf(void *log
,
555 MFT_REGISTER_TYPE_INFO
*in_type
,
556 MFT_REGISTER_TYPE_INFO
*out_type
,
563 IMFActivate
**activate
;
565 IMFActivate
*winner
= 0;
568 ret
= init_com_mf(log
, f
);
572 flags
= MFT_ENUM_FLAG_SORTANDFILTER
;
575 flags
|= MFT_ENUM_FLAG_HARDWARE
;
577 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
580 hr
= f
->MFTEnumEx(category
, flags
, in_type
, out_type
, &activate
,
583 goto error_uninit_mf
;
587 av_log(log
, AV_LOG_ERROR
, "could not find any MFT for the given media type\n");
589 for (n
= 0; n
< num_activate
; n
++) {
590 av_log(log
, AV_LOG_VERBOSE
, "MF %d attributes:\n", n
);
591 ff_attributes_dump(log
, (IMFAttributes
*)activate
[n
]);
596 for (n
= 0; n
< num_activate
; n
++) {
598 av_log(log
, AV_LOG_VERBOSE
, "activate MFT %d\n", n
);
599 hr
= IMFActivate_ActivateObject(activate
[n
], &IID_IMFTransform
,
602 winner
= activate
[n
];
603 IMFActivate_AddRef(winner
);
608 for (n
= 0; n
< num_activate
; n
++)
609 IMFActivate_Release(activate
[n
]);
610 CoTaskMemFree(activate
);
614 av_log(log
, AV_LOG_ERROR
, "could not create MFT\n");
615 goto error_uninit_mf
;
619 wchar_t s
[512]; // being lazy here
620 IMFAttributes
*attrs
;
621 hr
= IMFTransform_GetAttributes(*res
, &attrs
);
622 if (!FAILED(hr
) && attrs
) {
624 av_log(log
, AV_LOG_VERBOSE
, "MFT attributes\n");
625 ff_attributes_dump(log
, attrs
);
626 IMFAttributes_Release(attrs
);
629 hr
= IMFActivate_GetString(winner
, &MFT_FRIENDLY_NAME_Attribute
, s
,
632 av_log(log
, AV_LOG_INFO
, "MFT name: '%ls'\n", s
);
636 IMFActivate_Release(winner
);
642 return AVERROR(ENOSYS
);
645 void ff_free_mf(MFFunctions
*f
, IMFTransform
**mft
)
648 IMFTransform_Release(*mft
);