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