]> git.sesse.net Git - vlc/blob - modules/codec/mft.c
upnp: change item b_net and i_type
[vlc] / modules / codec / mft.c
1 /*****************************************************************************
2  * mft.c : Media Foundation Transform audio/video decoder
3  *****************************************************************************
4  * Copyright (C) 2014 VLC authors and VideoLAN
5  *
6  * Author: Felix Abecassis <felix.abecassis@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #undef WINVER
28 #define WINVER 0x0601
29
30 /* Needed for many mingw macros. */
31 #define COBJMACROS
32
33 /* Avoid having GUIDs being defined as "extern". */
34 #define INITGUID
35
36 #ifndef STDCALL
37 # define STDCALL __stdcall
38 #endif
39
40 #include <assert.h>
41
42 #include <vlc_common.h>
43 #include <vlc_plugin.h>
44 #include <vlc_codec.h>
45 #include <h264_nal.h>
46 #define _VIDEOINFOHEADER_
47 #include <vlc_codecs.h>
48
49 #include <mfapi.h>
50 #include <mftransform.h>
51 #include <mferror.h>
52 #include <mfobjects.h>
53
54 static int  Open(vlc_object_t *);
55 static void Close(vlc_object_t *);
56
57 vlc_module_begin()
58     set_description(N_("Media Foundation Transform decoder"))
59     add_shortcut("mft")
60     set_capability("decoder", 1)
61     set_callbacks(Open, Close)
62     set_category(CAT_INPUT)
63     set_subcategory(SUBCAT_INPUT_VCODEC)
64 vlc_module_end()
65
66 typedef struct
67 {
68     HINSTANCE mfplat_dll;
69     HRESULT (STDCALL *fptr_MFTEnumEx)(GUID guidCategory, UINT32 Flags,
70                                  const MFT_REGISTER_TYPE_INFO *pInputType,
71                                  const MFT_REGISTER_TYPE_INFO *pOutputType,
72                                  IMFActivate ***pppMFTActivate, UINT32 *pcMFTActivate);
73     HRESULT (STDCALL *fptr_MFCreateSample)(IMFSample **ppIMFSample);
74     HRESULT (STDCALL *fptr_MFCreateMemoryBuffer)(DWORD cbMaxLength, IMFMediaBuffer **ppBuffer);
75     HRESULT (STDCALL *fptr_MFCreateAlignedMemoryBuffer)(DWORD cbMaxLength, DWORD fAlignmentFlags, IMFMediaBuffer **ppBuffer);
76 } MFHandle;
77
78 struct decoder_sys_t
79 {
80     MFHandle mf_handle;
81
82     IMFTransform *mft;
83
84     const GUID* major_type;
85     const GUID* subtype;
86
87     /* For asynchronous MFT */
88     bool is_async;
89     IMFMediaEventGenerator *event_generator;
90     int pending_input_events;
91     int pending_output_events;
92
93     /* Input stream */
94     DWORD input_stream_id;
95     IMFMediaType *input_type;
96
97     /* Output stream */
98     DWORD output_stream_id;
99     IMFSample *output_sample;
100     IMFMediaType *output_type;
101
102     /* H264 only. */
103     uint32_t nal_size;
104 };
105
106 static const int pi_channels_maps[9] =
107 {
108     0,
109     AOUT_CHAN_CENTER,
110     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
111     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
112     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
113      | AOUT_CHAN_REARRIGHT,
114     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
115      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
116     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
117      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
118     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
119      | AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT
120      | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE,
121     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
122      | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
123      | AOUT_CHAN_LFE,
124 };
125
126 /* Possibly missing from mingw headers */
127 #ifndef MF_E_TRANSFORM_NEED_MORE_INPUT
128 # define MF_E_TRANSFORM_NEED_MORE_INPUT _HRESULT_TYPEDEF_(0xc00d6d72)
129 #endif
130
131 #ifndef MF_E_TRANSFORM_STREAM_CHANGE
132 # define MF_E_TRANSFORM_STREAM_CHANGE _HRESULT_TYPEDEF_(0xc00d6d61)
133 #endif
134
135 #ifndef MF_E_NO_EVENTS_AVAILABLE
136 # define MF_E_NO_EVENTS_AVAILABLE _HRESULT_TYPEDEF_(0xC00D3E80L)
137 #endif
138
139 #ifndef MF_EVENT_FLAG_NO_WAIT
140 # define MF_EVENT_FLAG_NO_WAIT 0x00000001
141 #endif
142
143 /*
144  * The MFTransformXXX values might not be defined in mingw headers,
145  * thus we use our own enum with the VLC prefix.
146  */
147 enum
148 {
149     VLC_METransformUnknown = 600,
150     VLC_METransformNeedInput,
151     VLC_METransformHaveOutput,
152     VLC_METransformDrainComplete,
153     VLC_METransformMarker,
154 };
155
156 typedef struct
157 {
158     vlc_fourcc_t fourcc;
159     const GUID   *guid;
160 } pair_format_guid;
161
162 /*
163  * We need this table since the FOURCC used for GUID is not the same
164  * as the FOURCC used by VLC, for instance h264 vs H264.
165  */
166 static const pair_format_guid video_format_table[] =
167 {
168     { VLC_CODEC_H264, &MFVideoFormat_H264 },
169     { VLC_CODEC_MJPG, &MFVideoFormat_MJPG },
170     { VLC_CODEC_WMV1, &MFVideoFormat_WMV1 },
171     { VLC_CODEC_WMV2, &MFVideoFormat_WMV2 },
172     { VLC_CODEC_WMV3, &MFVideoFormat_WMV3 },
173     { VLC_CODEC_VC1,  &MFVideoFormat_WVC1 },
174     { 0, NULL }
175 };
176
177 #if defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 4
178 DEFINE_GUID(MFAudioFormat_Dolby_AC3, 0xe06d802c, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea);
179 #endif
180 /*
181  * We cannot use the FOURCC code for audio either since the
182  * WAVE_FORMAT value is used to create the GUID.
183  */
184 static const pair_format_guid audio_format_table[] =
185 {
186     { VLC_CODEC_MPGA, &MFAudioFormat_MPEG      },
187     { VLC_CODEC_MP3,  &MFAudioFormat_MP3       },
188     { VLC_CODEC_DTS,  &MFAudioFormat_DTS       },
189     { VLC_CODEC_MP4A, &MFAudioFormat_AAC       },
190     { VLC_CODEC_WMA2, &MFAudioFormat_WMAudioV8 },
191     { VLC_CODEC_A52,  &MFAudioFormat_Dolby_AC3 },
192     { 0, NULL }
193 };
194
195 static const GUID *FormatToGUID(const pair_format_guid table[], vlc_fourcc_t fourcc)
196 {
197     for (int i = 0; table[i].fourcc; ++i)
198         if (table[i].fourcc == fourcc)
199             return table[i].guid;
200
201     return NULL;
202 }
203
204 /*
205  * Low latency mode for Windows 8. Without this option, the H264
206  * decoder will fill *all* its internal buffers before returning a
207  * frame. Because of this behavior, the decoder might return no frame
208  * for more than 500 ms, making it unusable for playback.
209  */
210 DEFINE_GUID(CODECAPI_AVLowLatencyMode, 0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee);
211
212 static int SetInputType(decoder_t *p_dec, DWORD stream_id, IMFMediaType **result)
213 {
214     decoder_sys_t *p_sys = p_dec->p_sys;
215     HRESULT hr;
216
217     *result = NULL;
218
219     IMFMediaType *input_media_type = NULL;
220
221     /* Search a suitable input type for the MFT. */
222     int input_type_index = 0;
223     bool found = false;
224     for (int i = 0; !found; ++i)
225     {
226         hr = IMFTransform_GetInputAvailableType(p_sys->mft, stream_id, i, &input_media_type);
227         if (hr == MF_E_NO_MORE_TYPES)
228             break;
229         else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET)
230         {
231             /* The output type must be set before setting the input type for this MFT. */
232             return VLC_SUCCESS;
233         }
234         else if (FAILED(hr))
235             goto error;
236
237         GUID subtype;
238         hr = IMFMediaType_GetGUID(input_media_type, &MF_MT_SUBTYPE, &subtype);
239         if (FAILED(hr))
240             goto error;
241
242         if (IsEqualGUID(&subtype, p_sys->subtype))
243             found = true;
244
245         if (found)
246             input_type_index = i;
247
248         IMFMediaType_Release(input_media_type);
249         input_media_type = NULL;
250     }
251     if (!found)
252         goto error;
253
254     hr = IMFTransform_GetInputAvailableType(p_sys->mft, stream_id, input_type_index, &input_media_type);
255     if (FAILED(hr))
256         goto error;
257
258     if (p_dec->fmt_in.i_cat == VIDEO_ES)
259     {
260         UINT64 width = p_dec->fmt_in.video.i_width;
261         UINT64 height = p_dec->fmt_in.video.i_height;
262         UINT64 frame_size = (width << 32) | height;
263         hr = IMFMediaType_SetUINT64(input_media_type, &MF_MT_FRAME_SIZE, frame_size);
264         if (FAILED(hr))
265             goto error;
266     }
267     else
268     {
269         hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_ORIGINAL_WAVE_FORMAT_TAG, p_sys->subtype->Data1);
270         if (FAILED(hr))
271             goto error;
272         if (p_dec->fmt_in.audio.i_rate)
273         {
274             hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, p_dec->fmt_in.audio.i_rate);
275             if (FAILED(hr))
276                 goto error;
277         }
278         if (p_dec->fmt_in.audio.i_channels)
279         {
280             hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_AUDIO_NUM_CHANNELS, p_dec->fmt_in.audio.i_channels);
281             if (FAILED(hr))
282                 goto error;
283         }
284         if (p_dec->fmt_in.audio.i_bitspersample)
285         {
286             hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, p_dec->fmt_in.audio.i_bitspersample);
287             if (FAILED(hr))
288                 goto error;
289         }
290         if (p_dec->fmt_in.audio.i_blockalign)
291         {
292             hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, p_dec->fmt_in.audio.i_blockalign);
293             if (FAILED(hr))
294                 goto error;
295         }
296         if (p_dec->fmt_in.i_bitrate)
297         {
298             hr = IMFMediaType_SetUINT32(input_media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, p_dec->fmt_in.i_bitrate / 8);
299             if (FAILED(hr))
300                 goto error;
301         }
302     }
303
304     if (p_dec->fmt_in.i_extra > 0)
305     {
306         UINT32 blob_size = 0;
307         hr = IMFMediaType_GetBlobSize(input_media_type, &MF_MT_USER_DATA, &blob_size);
308         /*
309          * Do not overwrite existing user data in the input type, this
310          * can cause the MFT to reject the type.
311          */
312         if (hr == MF_E_ATTRIBUTENOTFOUND)
313         {
314             hr = IMFMediaType_SetBlob(input_media_type, &MF_MT_USER_DATA,
315                                       (const UINT8*)p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra);
316             if (FAILED(hr))
317                 goto error;
318         }
319     }
320
321     hr = IMFTransform_SetInputType(p_sys->mft, stream_id, input_media_type, 0);
322     if (FAILED(hr))
323         goto error;
324
325     *result = input_media_type;
326
327     return VLC_SUCCESS;
328
329 error:
330     msg_Err(p_dec, "Error in SetInputType()");
331     if (input_media_type)
332         IMFMediaType_Release(input_media_type);
333     return VLC_EGENERIC;
334 }
335
336 static int SetOutputType(decoder_t *p_dec, DWORD stream_id, IMFMediaType **result)
337 {
338     decoder_sys_t *p_sys = p_dec->p_sys;
339     HRESULT hr;
340
341     *result = NULL;
342
343     IMFMediaType *output_media_type = NULL;
344
345     /*
346      * Enumerate available output types. The list is ordered by
347      * preference thus we will use the first one unless YV12/I420 is
348      * available for video or float32 for audio.
349      */
350     int output_type_index = 0;
351     bool found = false;
352     for (int i = 0; !found; ++i)
353     {
354         hr = IMFTransform_GetOutputAvailableType(p_sys->mft, stream_id, i, &output_media_type);
355         if (hr == MF_E_NO_MORE_TYPES)
356             break;
357         else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET)
358         {
359             /* The input type must be set before setting the output type for this MFT. */
360             return VLC_SUCCESS;
361         }
362         else if (FAILED(hr))
363             goto error;
364
365         GUID subtype;
366         hr = IMFMediaType_GetGUID(output_media_type, &MF_MT_SUBTYPE, &subtype);
367         if (FAILED(hr))
368             goto error;
369
370         if (p_dec->fmt_in.i_cat == VIDEO_ES)
371         {
372             if (IsEqualGUID(&subtype, &MFVideoFormat_YV12) || IsEqualGUID(&subtype, &MFVideoFormat_I420))
373                 found = true;
374         }
375         else
376         {
377             UINT32 bits_per_sample;
378             hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits_per_sample);
379             if (FAILED(hr))
380                 continue;
381             if (bits_per_sample == 32 && IsEqualGUID(&subtype, &MFAudioFormat_Float))
382                 found = true;
383         }
384
385         if (found)
386             output_type_index = i;
387
388         IMFMediaType_Release(output_media_type);
389         output_media_type = NULL;
390     }
391     /*
392      * It's not an error if we don't find the output type we were
393      * looking for, in this case we use the first available type which
394      * is the "preferred" output type for this MFT.
395      */
396
397     hr = IMFTransform_GetOutputAvailableType(p_sys->mft, stream_id, output_type_index, &output_media_type);
398     if (FAILED(hr))
399         goto error;
400
401     hr = IMFTransform_SetOutputType(p_sys->mft, stream_id, output_media_type, 0);
402     if (FAILED(hr))
403         goto error;
404
405     GUID subtype;
406     hr = IMFMediaType_GetGUID(output_media_type, &MF_MT_SUBTYPE, &subtype);
407     if (FAILED(hr))
408         goto error;
409
410     if (p_dec->fmt_in.i_cat == VIDEO_ES)
411     {
412         p_dec->fmt_out.video = p_dec->fmt_in.video;
413         p_dec->fmt_out.i_codec = vlc_fourcc_GetCodec(p_dec->fmt_in.i_cat, subtype.Data1);
414     }
415     else
416     {
417         p_dec->fmt_out.audio = p_dec->fmt_in.audio;
418
419         UINT32 bitspersample = 0;
420         hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bitspersample);
421         if (SUCCEEDED(hr) && bitspersample)
422             p_dec->fmt_out.audio.i_bitspersample = bitspersample;
423
424         UINT32 channels = 0;
425         hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_NUM_CHANNELS, &channels);
426         if (SUCCEEDED(hr) && channels)
427             p_dec->fmt_out.audio.i_channels = channels;
428
429         UINT32 rate = 0;
430         hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate);
431         if (SUCCEEDED(hr) && rate)
432             p_dec->fmt_out.audio.i_rate = rate;
433
434         vlc_fourcc_t fourcc;
435         wf_tag_to_fourcc(subtype.Data1, &fourcc, NULL);
436         p_dec->fmt_out.i_codec = vlc_fourcc_GetCodecAudio(fourcc, p_dec->fmt_out.audio.i_bitspersample);
437
438         p_dec->fmt_out.audio.i_physical_channels = pi_channels_maps[p_dec->fmt_out.audio.i_channels];
439         p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_physical_channels;
440     }
441
442     *result = output_media_type;
443
444     return VLC_SUCCESS;
445
446 error:
447     msg_Err(p_dec, "Error in SetOutputType()");
448     if (output_media_type)
449         IMFMediaType_Release(output_media_type);
450     return VLC_EGENERIC;
451 }
452
453 static int AllocateInputSample(decoder_t *p_dec, DWORD stream_id, IMFSample** result, DWORD size)
454 {
455     decoder_sys_t *p_sys = p_dec->p_sys;
456     MFHandle *mf = &p_sys->mf_handle;
457     HRESULT hr;
458
459     *result = NULL;
460
461     IMFSample *input_sample = NULL;
462
463     MFT_INPUT_STREAM_INFO input_info;
464     hr = IMFTransform_GetInputStreamInfo(p_sys->mft, stream_id, &input_info);
465     if (FAILED(hr))
466         goto error;
467
468     hr = mf->fptr_MFCreateSample(&input_sample);
469     if (FAILED(hr))
470         goto error;
471
472     IMFMediaBuffer *input_media_buffer = NULL;
473     DWORD allocation_size = __MAX(input_info.cbSize, size);
474     hr = mf->fptr_MFCreateMemoryBuffer(allocation_size, &input_media_buffer);
475     if (FAILED(hr))
476         goto error;
477
478     hr = IMFSample_AddBuffer(input_sample, input_media_buffer);
479     IMFMediaBuffer_Release(input_media_buffer);
480     if (FAILED(hr))
481         goto error;
482
483     *result = input_sample;
484
485     return VLC_SUCCESS;
486
487 error:
488     msg_Err(p_dec, "Error in AllocateInputSample()");
489     if (input_sample)
490         IMFSample_Release(input_sample);
491     if (input_media_buffer)
492         IMFMediaBuffer_Release(input_media_buffer);
493     return VLC_EGENERIC;
494 }
495
496 static int AllocateOutputSample(decoder_t *p_dec, DWORD stream_id, IMFSample **result)
497 {
498     decoder_sys_t *p_sys = p_dec->p_sys;
499     MFHandle *mf = &p_sys->mf_handle;
500     HRESULT hr;
501
502     *result = NULL;
503
504     IMFSample *output_sample = NULL;
505
506     MFT_OUTPUT_STREAM_INFO output_info;
507     hr = IMFTransform_GetOutputStreamInfo(p_sys->mft, stream_id, &output_info);
508     if (FAILED(hr))
509         goto error;
510
511     if (output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES))
512     {
513         /* The MFT will provide an allocated sample. */
514         return VLC_SUCCESS;
515     }
516
517     DWORD expected_flags = 0;
518     if (p_dec->fmt_in.i_cat == VIDEO_ES)
519         expected_flags |= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
520                         | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
521                         | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
522     if ((output_info.dwFlags & expected_flags) != expected_flags)
523         goto error;
524
525     hr = mf->fptr_MFCreateSample(&output_sample);
526     if (FAILED(hr))
527         goto error;
528
529     IMFMediaBuffer *output_media_buffer = NULL;
530     DWORD allocation_size = output_info.cbSize;
531     DWORD alignment = output_info.cbAlignment;
532     if (alignment > 0)
533         hr = mf->fptr_MFCreateAlignedMemoryBuffer(allocation_size, alignment - 1, &output_media_buffer);
534     else
535         hr = mf->fptr_MFCreateMemoryBuffer(allocation_size, &output_media_buffer);
536     if (FAILED(hr))
537         goto error;
538
539     hr = IMFSample_AddBuffer(output_sample, output_media_buffer);
540     if (FAILED(hr))
541         goto error;
542
543     *result = output_sample;
544
545     return VLC_SUCCESS;
546
547 error:
548     msg_Err(p_dec, "Error in AllocateOutputSample()");
549     if (output_sample)
550         IMFSample_Release(output_sample);
551     return VLC_EGENERIC;
552 }
553
554 static int ProcessInputStream(decoder_t *p_dec, DWORD stream_id, block_t *p_block)
555 {
556     decoder_sys_t *p_sys = p_dec->p_sys;
557     HRESULT hr;
558     IMFSample *input_sample = NULL;
559
560     if (AllocateInputSample(p_dec, stream_id, &input_sample, p_block->i_buffer))
561         goto error;
562
563     IMFMediaBuffer *input_media_buffer = NULL;
564     hr = IMFSample_GetBufferByIndex(input_sample, 0, &input_media_buffer);
565     if (FAILED(hr))
566         goto error;
567
568     BYTE *buffer_start;
569     hr = IMFMediaBuffer_Lock(input_media_buffer, &buffer_start, NULL, NULL);
570     if (FAILED(hr))
571         goto error;
572
573     memcpy(buffer_start, p_block->p_buffer, p_block->i_buffer);
574
575     if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
576     {
577         /* in-place NAL to annex B conversion. */
578         struct H264ConvertState convert_state = { 0, 0 };
579         convert_h264_to_annexb(buffer_start, p_block->i_buffer, p_sys->nal_size, &convert_state);
580     }
581
582     hr = IMFMediaBuffer_Unlock(input_media_buffer);
583     if (FAILED(hr))
584         goto error;
585
586     hr = IMFMediaBuffer_SetCurrentLength(input_media_buffer, p_block->i_buffer);
587     if (FAILED(hr))
588         goto error;
589
590     LONGLONG ts = p_block->i_pts;
591     if (!ts && p_block->i_dts)
592         ts = p_block->i_dts;
593
594     /* Convert from microseconds to 100 nanoseconds unit. */
595     hr = IMFSample_SetSampleTime(input_sample, ts * 10);
596     if (FAILED(hr))
597         goto error;
598
599     hr = IMFTransform_ProcessInput(p_sys->mft, stream_id, input_sample, 0);
600     if (FAILED(hr))
601         goto error;
602
603     IMFMediaBuffer_Release(input_media_buffer);
604     IMFSample_Release(input_sample);
605
606     return VLC_SUCCESS;
607
608 error:
609     msg_Err(p_dec, "Error in ProcessInputStream()");
610     if (input_sample)
611         IMFSample_Release(input_sample);
612     return VLC_EGENERIC;
613 }
614
615 /* Copy a packed buffer (no padding) to a picture_t */
616 static void CopyPackedBufferToPicture(picture_t *p_pic, const uint8_t *p_src)
617 {
618     for (int i = 0; i < p_pic->i_planes; ++i)
619     {
620         uint8_t *p_dst = p_pic->p[i].p_pixels;
621
622         if (p_pic->p[i].i_visible_pitch == p_pic->p[i].i_pitch)
623         {
624             /* Plane is packed, only one memcpy is needed. */
625             uint32_t plane_size = p_pic->p[i].i_pitch * p_pic->p[i].i_visible_lines;
626             memcpy(p_dst, p_src, plane_size);
627             p_src += plane_size;
628             continue;
629         }
630
631         for (int i_line = 0; i_line < p_pic->p[i].i_visible_lines; i_line++)
632         {
633             memcpy(p_dst, p_src, p_pic->p[i].i_visible_pitch);
634             p_src += p_pic->p[i].i_visible_pitch;
635             p_dst += p_pic->p[i].i_pitch;
636         }
637     }
638 }
639
640 static int ProcessOutputStream(decoder_t *p_dec, DWORD stream_id, void **result)
641 {
642     decoder_sys_t *p_sys = p_dec->p_sys;
643     HRESULT hr;
644     picture_t *picture = NULL;
645     block_t *aout_buffer = NULL;
646
647     *result = NULL;
648
649     DWORD output_status = 0;
650     MFT_OUTPUT_DATA_BUFFER output_buffer = { stream_id, p_sys->output_sample, 0, NULL };
651     hr = IMFTransform_ProcessOutput(p_sys->mft, 0, 1, &output_buffer, &output_status);
652     if (output_buffer.pEvents)
653         IMFCollection_Release(output_buffer.pEvents);
654     /* Use the returned sample since it can be provided by the MFT. */
655     IMFSample *output_sample = output_buffer.pSample;
656
657     if (hr == S_OK)
658     {
659         if (!output_sample)
660             return VLC_SUCCESS;
661
662         LONGLONG sample_time;
663         hr = IMFSample_GetSampleTime(output_sample, &sample_time);
664         if (FAILED(hr))
665             goto error;
666         /* Convert from 100 nanoseconds unit to microseconds. */
667         sample_time /= 10;
668
669         DWORD total_length = 0;
670         hr = IMFSample_GetTotalLength(output_sample, &total_length);
671         if (FAILED(hr))
672             goto error;
673
674         if (p_dec->fmt_in.i_cat == VIDEO_ES)
675         {
676             picture = decoder_NewPicture(p_dec);
677             if (!picture)
678                 return VLC_SUCCESS;
679
680             UINT32 interlaced = false;
681             hr = IMFSample_GetUINT32(output_sample, &MFSampleExtension_Interlaced, &interlaced);
682             picture->b_progressive = !interlaced;
683
684             picture->date = sample_time;
685         }
686         else
687         {
688             if (p_dec->fmt_out.audio.i_bitspersample == 0 || p_dec->fmt_out.audio.i_channels == 0)
689                 goto error;
690             int samples = total_length / (p_dec->fmt_out.audio.i_bitspersample * p_dec->fmt_out.audio.i_channels / 8);
691             aout_buffer = decoder_NewAudioBuffer(p_dec, samples);
692             if (!aout_buffer)
693                 return VLC_SUCCESS;
694             if (aout_buffer->i_buffer < total_length)
695                 goto error;
696
697             aout_buffer->i_pts = sample_time;
698         }
699
700         IMFMediaBuffer *output_media_buffer = NULL;
701         hr = IMFSample_GetBufferByIndex(output_sample, 0, &output_media_buffer);
702
703         BYTE *buffer_start;
704         hr = IMFMediaBuffer_Lock(output_media_buffer, &buffer_start, NULL, NULL);
705         if (FAILED(hr))
706             goto error;
707
708         if (p_dec->fmt_in.i_cat == VIDEO_ES)
709             CopyPackedBufferToPicture(picture, buffer_start);
710         else
711             memcpy(aout_buffer->p_buffer, buffer_start, total_length);
712
713         hr = IMFMediaBuffer_Unlock(output_media_buffer);
714         IMFSample_Release(output_media_buffer);
715         if (FAILED(hr))
716             goto error;
717
718         if (p_sys->output_sample)
719         {
720             /* Sample is not provided by the MFT: clear its content. */
721             hr = IMFMediaBuffer_SetCurrentLength(output_media_buffer, 0);
722             if (FAILED(hr))
723                 goto error;
724         }
725         else
726         {
727             /* Sample is provided by the MFT: decrease refcount. */
728             IMFSample_Release(output_sample);
729         }
730     }
731     else if (hr == MF_E_TRANSFORM_STREAM_CHANGE || hr == MF_E_TRANSFORM_TYPE_NOT_SET)
732     {
733         if (p_sys->output_type)
734             IMFMediaType_Release(p_sys->output_type);
735         if (SetOutputType(p_dec, p_sys->output_stream_id, &p_sys->output_type))
736             goto error;
737
738         /* Reallocate output sample. */
739         if (p_sys->output_sample)
740             IMFSample_Release(p_sys->output_sample);
741         p_sys->output_sample = NULL;
742         if (AllocateOutputSample(p_dec, 0, &p_sys->output_sample))
743             goto error;
744         return VLC_SUCCESS;
745     }
746     else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
747     {
748         return VLC_SUCCESS;
749     }
750     else /* An error not listed above occurred */
751     {
752         msg_Err(p_dec, "Unexpected error in IMFTransform::ProcessOutput: %#lx",
753                 hr);
754         goto error;
755     }
756
757     if (p_dec->fmt_in.i_cat == VIDEO_ES)
758         *result = picture;
759     else
760         *result = aout_buffer;
761
762     return VLC_SUCCESS;
763
764 error:
765     msg_Err(p_dec, "Error in ProcessOutputStream()");
766     if (picture)
767         picture_Release(picture);
768     if (aout_buffer)
769         block_Release(aout_buffer);
770     return VLC_EGENERIC;
771 }
772
773 static void *DecodeSync(decoder_t *p_dec, block_t **pp_block)
774 {
775     decoder_sys_t *p_sys = p_dec->p_sys;
776
777     if (!pp_block || !*pp_block)
778         return NULL;
779
780     block_t *p_block = *pp_block;
781     if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED))
782     {
783         block_Release(p_block);
784         return NULL;
785     }
786
787     /* Drain the output stream before sending the input packet. */
788     void *result = NULL;
789     if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
790         goto error;
791     if (result)
792         return result;
793
794     if (ProcessInputStream(p_dec, p_sys->input_stream_id, p_block))
795         goto error;
796
797     block_Release(p_block);
798     *pp_block = NULL;
799
800     return NULL;
801
802 error:
803     msg_Err(p_dec, "Error in DecodeSync()");
804     if (p_block)
805         block_Release(p_block);
806     return NULL;
807 }
808
809 static HRESULT DequeueMediaEvent(decoder_t *p_dec)
810 {
811     decoder_sys_t *p_sys = p_dec->p_sys;
812     HRESULT hr;
813
814     IMFMediaEvent *event = NULL;
815     hr = IMFMediaEventGenerator_GetEvent(p_sys->event_generator, MF_EVENT_FLAG_NO_WAIT, &event);
816     if (FAILED(hr))
817         return hr;
818     MediaEventType event_type;
819     hr = IMFMediaEvent_GetType(event, &event_type);
820     IMFMediaEvent_Release(event);
821     if (FAILED(hr))
822         return hr;
823
824     if (event_type == VLC_METransformNeedInput)
825         p_sys->pending_input_events += 1;
826     else if (event_type == VLC_METransformHaveOutput)
827         p_sys->pending_output_events += 1;
828     else
829         msg_Err(p_dec, "Unsupported asynchronous event.");
830
831     return S_OK;
832 }
833
834 static void *DecodeAsync(decoder_t *p_dec, block_t **pp_block)
835 {
836     decoder_sys_t *p_sys = p_dec->p_sys;
837     HRESULT hr;
838
839     if (!pp_block || !*pp_block)
840         return NULL;
841
842     block_t *p_block = *pp_block;
843     if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED))
844     {
845         block_Release(p_block);
846
847         return NULL;
848     }
849
850     /* Dequeue all pending media events. */
851     while ((hr = DequeueMediaEvent(p_dec)) == S_OK)
852         continue;
853     if (hr != MF_E_NO_EVENTS_AVAILABLE && FAILED(hr))
854         goto error;
855
856     /* Drain the output stream of the MFT before sending the input packet. */
857     if (p_sys->pending_output_events > 0)
858     {
859         p_sys->pending_output_events -= 1;
860         void *result = NULL;
861         if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
862             goto error;
863         return result;
864     }
865
866     /* Poll the MFT and return decoded frames until the input stream is ready. */
867     while (p_sys->pending_input_events == 0)
868     {
869         hr = DequeueMediaEvent(p_dec);
870         if (hr == MF_E_NO_EVENTS_AVAILABLE)
871         {
872             /* Sleep for 1 ms to avoid excessive polling. */
873             Sleep(1);
874             continue;
875         }
876         if (FAILED(hr))
877             goto error;
878
879         if (p_sys->pending_output_events > 0)
880         {
881             p_sys->pending_output_events -= 1;
882             void *result = NULL;
883             if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
884                 goto error;
885             return result;
886         }
887     }
888
889     p_sys->pending_input_events -= 1;
890     if (ProcessInputStream(p_dec, p_sys->input_stream_id, p_block))
891         goto error;
892
893     block_Release(p_block);
894     *pp_block = NULL;
895
896     return NULL;
897
898 error:
899     msg_Err(p_dec, "Error in DecodeAsync()");
900     block_Release(p_block);
901     return NULL;
902 }
903
904 static void DestroyMFT(decoder_t *p_dec);
905
906 static int InitializeMFT(decoder_t *p_dec)
907 {
908     decoder_sys_t *p_sys = p_dec->p_sys;
909     HRESULT hr;
910
911     IMFAttributes *attributes = NULL;
912     hr = IMFTransform_GetAttributes(p_sys->mft, &attributes);
913     if (hr != E_NOTIMPL && FAILED(hr))
914         goto error;
915     if (SUCCEEDED(hr))
916     {
917         UINT32 is_async = false;
918         hr = IMFAttributes_GetUINT32(attributes, &MF_TRANSFORM_ASYNC, &is_async);
919         if (hr != MF_E_ATTRIBUTENOTFOUND && FAILED(hr))
920             goto error;
921         p_sys->is_async = is_async;
922         if (p_sys->is_async)
923         {
924             hr = IMFAttributes_SetUINT32(attributes, &MF_TRANSFORM_ASYNC_UNLOCK, true);
925             if (FAILED(hr))
926                 goto error;
927             hr = IMFTransform_QueryInterface(p_sys->mft, &IID_IMFMediaEventGenerator, (void**)&p_sys->event_generator);
928             if (FAILED(hr))
929                 goto error;
930         }
931     }
932
933     DWORD input_streams_count;
934     DWORD output_streams_count;
935     hr = IMFTransform_GetStreamCount(p_sys->mft, &input_streams_count, &output_streams_count);
936     if (FAILED(hr))
937         goto error;
938     if (input_streams_count != 1 || output_streams_count != 1)
939     {
940         msg_Err(p_dec, "MFT decoder should have 1 input stream and 1 output stream.");
941         goto error;
942     }
943
944     hr = IMFTransform_GetStreamIDs(p_sys->mft, 1, &p_sys->input_stream_id, 1, &p_sys->output_stream_id);
945     if (hr == E_NOTIMPL)
946     {
947         /*
948          * This is not an error, it happens if:
949          * - there is a fixed number of streams.
950          * AND
951          * - streams are numbered consecutively from 0 to N-1.
952          */
953         p_sys->input_stream_id = 0;
954         p_sys->output_stream_id = 0;
955     }
956     else if (FAILED(hr))
957         goto error;
958
959     if (SetInputType(p_dec, p_sys->input_stream_id, &p_sys->input_type))
960         goto error;
961
962     if (SetOutputType(p_dec, p_sys->output_stream_id, &p_sys->output_type))
963         goto error;
964
965     /*
966      * The input type was not set by the previous call to
967      * SetInputType, try again after setting the output type.
968      */
969     if (!p_sys->input_type)
970         if (SetInputType(p_dec, p_sys->input_stream_id, &p_sys->input_type) || !p_sys->input_type)
971             goto error;
972
973     /* This call can be a no-op for some MFT decoders, but it can potentially reduce starting time. */
974     hr = IMFTransform_ProcessMessage(p_sys->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, (ULONG_PTR)0);
975     if (FAILED(hr))
976         goto error;
977
978     /* This event is required for asynchronous MFTs, optional otherwise. */
979     hr = IMFTransform_ProcessMessage(p_sys->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, (ULONG_PTR)0);
980     if (FAILED(hr))
981         goto error;
982
983     if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
984     {
985         /* It's not an error if the following call fails. */
986         IMFAttributes_SetUINT32(attributes, &CODECAPI_AVLowLatencyMode, true);
987
988         if (p_dec->fmt_in.i_extra)
989         {
990             int buf_size = p_dec->fmt_in.i_extra + 20;
991             uint32_t size = p_dec->fmt_in.i_extra;
992             uint8_t *buf = malloc(buf_size);
993             if (((uint8_t*)p_dec->fmt_in.p_extra)[0] == 1)
994             {
995                 convert_sps_pps(p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra,
996                                 buf, buf_size,
997                                 &size, &p_sys->nal_size);
998             }
999             free(buf);
1000         }
1001     }
1002     return VLC_SUCCESS;
1003
1004 error:
1005     msg_Err(p_dec, "Error in InitializeMFT()");
1006     DestroyMFT(p_dec);
1007     return VLC_EGENERIC;
1008 }
1009
1010 static void DestroyMFT(decoder_t *p_dec)
1011 {
1012     decoder_sys_t *p_sys = p_dec->p_sys;
1013
1014     if (p_sys->event_generator)
1015         IMFMediaEventGenerator_Release(p_sys->event_generator);
1016     if (p_sys->input_type)
1017         IMFMediaType_Release(p_sys->input_type);
1018     if (p_sys->output_sample)
1019     {
1020         IMFMediaBuffer *output_media_buffer = NULL;
1021         HRESULT hr = IMFSample_GetBufferByIndex(p_sys->output_sample, 0, &output_media_buffer);
1022         if (SUCCEEDED(hr))
1023             IMFSample_Release(output_media_buffer);
1024         IMFSample_Release(p_sys->output_sample);
1025     }
1026     if (p_sys->output_type)
1027         IMFMediaType_Release(p_sys->output_type);
1028     if (p_sys->mft)
1029         IMFTransform_Release(p_sys->mft);
1030
1031     p_sys->event_generator = NULL;
1032     p_sys->input_type = NULL;
1033     p_sys->output_sample = NULL;
1034     p_sys->output_type = NULL;
1035     p_sys->mft = NULL;
1036 }
1037
1038 static int FindMFT(decoder_t *p_dec)
1039 {
1040     decoder_sys_t *p_sys = p_dec->p_sys;
1041     MFHandle *mf = &p_sys->mf_handle;
1042     HRESULT hr;
1043
1044     /* Try to create a MFT using MFTEnumEx. */
1045     GUID category;
1046     if (p_dec->fmt_in.i_cat == VIDEO_ES)
1047     {
1048         category = MFT_CATEGORY_VIDEO_DECODER;
1049         p_sys->major_type = &MFMediaType_Video;
1050         p_sys->subtype = FormatToGUID(video_format_table, p_dec->fmt_in.i_codec);
1051     }
1052     else
1053     {
1054         category = MFT_CATEGORY_AUDIO_DECODER;
1055         p_sys->major_type = &MFMediaType_Audio;
1056         p_sys->subtype = FormatToGUID(audio_format_table, p_dec->fmt_in.i_codec);
1057     }
1058     if (!p_sys->subtype)
1059         return VLC_EGENERIC;
1060
1061     UINT32 flags = MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_LOCALMFT
1062                  | MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT
1063                  | MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_TRANSCODE_ONLY;
1064     MFT_REGISTER_TYPE_INFO input_type = { *p_sys->major_type, *p_sys->subtype };
1065     IMFActivate **activate_objects = NULL;
1066     UINT32 activate_objects_count = 0;
1067     hr = mf->fptr_MFTEnumEx(category, flags, &input_type, NULL, &activate_objects, &activate_objects_count);
1068     if (FAILED(hr))
1069         return VLC_EGENERIC;
1070
1071     msg_Dbg(p_dec, "Found %d available MFT module(s)", activate_objects_count);
1072     if (activate_objects_count == 0)
1073         return VLC_EGENERIC;
1074
1075     for (UINT32 i = 0; i < activate_objects_count; ++i)
1076     {
1077         hr = IMFActivate_ActivateObject(activate_objects[i], &IID_IMFTransform, (void**)&p_sys->mft);
1078         IMFActivate_Release(activate_objects[i]);
1079         if (FAILED(hr))
1080             continue;
1081
1082         if (InitializeMFT(p_dec) == VLC_SUCCESS)
1083         {
1084             CoTaskMemFree(activate_objects);
1085             return VLC_SUCCESS;
1086         }
1087     }
1088     CoTaskMemFree(activate_objects);
1089
1090     return VLC_EGENERIC;
1091 }
1092
1093 static int LoadMFTLibrary(MFHandle *mf)
1094 {
1095 #if _WIN32_WINNT < 0x601
1096     mf->mfplat_dll = LoadLibrary(TEXT("mfplat.dll"));
1097     if (!mf->mfplat_dll)
1098         return VLC_EGENERIC;
1099
1100     mf->fptr_MFTEnumEx = (void*)GetProcAddress(mf->mfplat_dll, "MFTEnumEx");
1101     mf->fptr_MFCreateSample = (void*)GetProcAddress(mf->mfplat_dll, "MFCreateSample");
1102     mf->fptr_MFCreateMemoryBuffer = (void*)GetProcAddress(mf->mfplat_dll, "MFCreateMemoryBuffer");
1103     mf->fptr_MFCreateAlignedMemoryBuffer = (void*)GetProcAddress(mf->mfplat_dll, "MFCreateAlignedMemoryBuffer");
1104     if (!mf->fptr_MFTEnumEx || !mf->fptr_MFCreateSample || !mf->fptr_MFCreateMemoryBuffer || !mf->fptr_MFCreateAlignedMemoryBuffer)
1105         return VLC_EGENERIC;
1106 #else
1107     mf->fptr_MFTEnumEx = &MFTEnumEx;
1108     mf->fptr_MFCreateSample = &MFCreateSample;
1109     mf->fptr_MFCreateMemoryBuffer = &MFCreateMemoryBuffer;
1110     mf->fptr_MFCreateAlignedMemoryBuffer = &MFCreateAlignedMemoryBuffer;
1111 #endif
1112
1113     return VLC_SUCCESS;
1114 }
1115
1116 int Open(vlc_object_t *p_this)
1117 {
1118     decoder_t *p_dec = (decoder_t *)p_this;
1119     decoder_sys_t *p_sys;
1120
1121     if (p_dec->fmt_in.i_cat != VIDEO_ES && p_dec->fmt_in.i_cat != AUDIO_ES)
1122         return VLC_EGENERIC;
1123
1124     p_sys = p_dec->p_sys = calloc(1, sizeof(*p_sys));
1125     if (!p_sys)
1126         return VLC_ENOMEM;
1127
1128     if( FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)) )
1129         vlc_assert_unreachable();
1130
1131     if (LoadMFTLibrary(&p_sys->mf_handle))
1132     {
1133         msg_Err(p_dec, "Failed to load MFT library.");
1134         goto error;
1135     }
1136
1137     if (FindMFT(p_dec))
1138     {
1139         msg_Err(p_dec, "Could not find suitable MFT decoder");
1140         goto error;
1141     }
1142
1143     /* Only one output sample is needed, we can allocate one and reuse it. */
1144     if (AllocateOutputSample(p_dec, 0, &p_sys->output_sample))
1145         goto error;
1146
1147     if (p_sys->is_async)
1148     {
1149         p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))DecodeAsync;
1150         p_dec->pf_decode_audio = (block_t   *(*)(decoder_t *, block_t **))DecodeAsync;
1151     }
1152     else
1153     {
1154         p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))DecodeSync;
1155         p_dec->pf_decode_audio = (block_t   *(*)(decoder_t *, block_t **))DecodeSync;
1156     }
1157
1158     p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;
1159     p_dec->b_need_packetized = true;
1160
1161     return VLC_SUCCESS;
1162
1163 error:
1164     Close(p_this);
1165     return VLC_EGENERIC;
1166 }
1167
1168 void Close(vlc_object_t *p_this)
1169 {
1170     decoder_t *p_dec = (decoder_t *)p_this;
1171     decoder_sys_t *p_sys = p_dec->p_sys;
1172     MFHandle *mf = &p_sys->mf_handle;
1173
1174     DestroyMFT(p_dec);
1175
1176     if (mf->mfplat_dll)
1177         FreeLibrary(mf->mfplat_dll);
1178
1179     free(p_sys);
1180
1181     CoUninitialize();
1182 }