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