280941cf2e75c2c312c8cac77e060a0e81e405ff
[ffmpeg.git] / libavcodec / mfenc.c
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #define COBJMACROS
20 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
21 #undef _WIN32_WINNT
22 #define _WIN32_WINNT 0x0602
23 #endif
24
25 #include "encode.h"
26 #include "mf_utils.h"
27 #include "libavutil/imgutils.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/time.h"
30 #include "codec_internal.h"
31 #include "internal.h"
32
33 typedef struct MFContext {
34     AVClass *av_class;
35     AVFrame *frame;
36     int is_video, is_audio;
37     GUID main_subtype;
38     IMFTransform *mft;
39     IMFMediaEventGenerator *async_events;
40     DWORD in_stream_id, out_stream_id;
41     MFT_INPUT_STREAM_INFO in_info;
42     MFT_OUTPUT_STREAM_INFO out_info;
43     int out_stream_provides_samples;
44     int draining, draining_done;
45     int sample_sent;
46     int async_need_input, async_have_output, async_marker;
47     int64_t reorder_delay;
48     ICodecAPI *codec_api;
49     // set by AVOption
50     int opt_enc_rc;
51     int opt_enc_quality;
52     int opt_enc_scenario;
53     int opt_enc_hw;
54 } MFContext;
55
56 static int mf_choose_output_type(AVCodecContext *avctx);
57 static int mf_setup_context(AVCodecContext *avctx);
58
59 #define MF_TIMEBASE (AVRational){1, 10000000}
60 // Sentinel value only used by us.
61 #define MF_INVALID_TIME AV_NOPTS_VALUE
62
63 static int mf_wait_events(AVCodecContext *avctx)
64 {
65     MFContext *c = avctx->priv_data;
66
67     if (!c->async_events)
68         return 0;
69
70     while (!(c->async_need_input || c->async_have_output || c->draining_done || c->async_marker)) {
71         IMFMediaEvent *ev = NULL;
72         MediaEventType ev_id = 0;
73         HRESULT hr = IMFMediaEventGenerator_GetEvent(c->async_events, 0, &ev);
74         if (FAILED(hr)) {
75             av_log(avctx, AV_LOG_ERROR, "IMFMediaEventGenerator_GetEvent() failed: %s\n",
76                    ff_hr_str(hr));
77             return AVERROR_EXTERNAL;
78         }
79         IMFMediaEvent_GetType(ev, &ev_id);
80         switch (ev_id) {
81         case ff_METransformNeedInput:
82             if (!c->draining)
83                 c->async_need_input = 1;
84             break;
85         case ff_METransformHaveOutput:
86             c->async_have_output = 1;
87             break;
88         case ff_METransformDrainComplete:
89             c->draining_done = 1;
90             break;
91         case ff_METransformMarker:
92             c->async_marker = 1;
93             break;
94         default: ;
95         }
96         IMFMediaEvent_Release(ev);
97     }
98
99     return 0;
100 }
101
102 static AVRational mf_get_tb(AVCodecContext *avctx)
103 {
104     if (avctx->time_base.num > 0 && avctx->time_base.den > 0)
105         return avctx->time_base;
106     return MF_TIMEBASE;
107 }
108
109 static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
110 {
111     if (av_pts == AV_NOPTS_VALUE)
112         return MF_INVALID_TIME;
113     return av_rescale_q(av_pts, mf_get_tb(avctx), MF_TIMEBASE);
114 }
115
116 static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
117 {
118     LONGLONG stime = mf_to_mf_time(avctx, av_pts);
119     if (stime != MF_INVALID_TIME)
120         IMFSample_SetSampleTime(sample, stime);
121 }
122
123 static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
124 {
125     return av_rescale_q(stime, MF_TIMEBASE, mf_get_tb(avctx));
126 }
127
128 static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
129 {
130     LONGLONG pts;
131     HRESULT hr = IMFSample_GetSampleTime(sample, &pts);
132     if (FAILED(hr))
133         return AV_NOPTS_VALUE;
134     return mf_from_mf_time(avctx, pts);
135 }
136
137 static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
138 {
139     MFContext *c = avctx->priv_data;
140     HRESULT hr;
141     UINT32 sz;
142
143     if (avctx->codec_id != AV_CODEC_ID_MP3 && avctx->codec_id != AV_CODEC_ID_AC3) {
144         hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
145         if (!FAILED(hr) && sz > 0) {
146             avctx->extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
147             if (!avctx->extradata)
148                 return AVERROR(ENOMEM);
149             avctx->extradata_size = sz;
150             hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->extradata, sz, NULL);
151             if (FAILED(hr))
152                 return AVERROR_EXTERNAL;
153
154             if (avctx->codec_id == AV_CODEC_ID_AAC && avctx->extradata_size >= 12) {
155                 // Get rid of HEAACWAVEINFO (after wfx field, 12 bytes).
156                 avctx->extradata_size = avctx->extradata_size - 12;
157                 memmove(avctx->extradata, avctx->extradata + 12, avctx->extradata_size);
158             }
159         }
160     }
161
162     // I don't know where it's documented that we need this. It happens with the
163     // MS mp3 encoder MFT. The idea for the workaround is taken from NAudio.
164     // (Certainly any lossy codec will have frames much smaller than 1 second.)
165     if (!c->out_info.cbSize && !c->out_stream_provides_samples) {
166         hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
167         if (!FAILED(hr)) {
168             av_log(avctx, AV_LOG_VERBOSE, "MFT_OUTPUT_STREAM_INFO.cbSize set to 0, "
169                    "assuming %d bytes instead.\n", (int)sz);
170             c->out_info.cbSize = sz;
171         }
172     }
173
174     return 0;
175 }
176
177 static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
178 {
179     HRESULT hr;
180     UINT32 sz;
181
182     hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
183     if (!FAILED(hr) && sz > 0) {
184         uint8_t *extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
185         if (!extradata)
186             return AVERROR(ENOMEM);
187         hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz, NULL);
188         if (FAILED(hr)) {
189             av_free(extradata);
190             return AVERROR_EXTERNAL;
191         }
192         av_freep(&avctx->extradata);
193         avctx->extradata = extradata;
194         avctx->extradata_size = sz;
195     }
196
197     return 0;
198 }
199
200 static int mf_output_type_get(AVCodecContext *avctx)
201 {
202     MFContext *c = avctx->priv_data;
203     HRESULT hr;
204     IMFMediaType *type;
205     int ret;
206
207     hr = IMFTransform_GetOutputCurrentType(c->mft, c->out_stream_id, &type);
208     if (FAILED(hr)) {
209         av_log(avctx, AV_LOG_ERROR, "could not get output type\n");
210         return AVERROR_EXTERNAL;
211     }
212
213     av_log(avctx, AV_LOG_VERBOSE, "final output type:\n");
214     ff_media_type_dump(avctx, type);
215
216     ret = 0;
217     if (c->is_video) {
218         ret = mf_encv_output_type_get(avctx, type);
219     } else if (c->is_audio) {
220         ret = mf_enca_output_type_get(avctx, type);
221     }
222
223     if (ret < 0)
224         av_log(avctx, AV_LOG_ERROR, "output type not supported\n");
225
226     IMFMediaType_Release(type);
227     return ret;
228 }
229
230 static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
231 {
232     MFContext *c = avctx->priv_data;
233     HRESULT hr;
234     int ret;
235     DWORD len;
236     IMFMediaBuffer *buffer;
237     BYTE *data;
238     UINT64 t;
239     UINT32 t32;
240
241     hr = IMFSample_GetTotalLength(sample, &len);
242     if (FAILED(hr))
243         return AVERROR_EXTERNAL;
244
245     if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0)
246         return ret;
247
248     IMFSample_ConvertToContiguousBuffer(sample, &buffer);
249     if (FAILED(hr))
250         return AVERROR_EXTERNAL;
251
252     hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
253     if (FAILED(hr)) {
254         IMFMediaBuffer_Release(buffer);
255         return AVERROR_EXTERNAL;
256     }
257
258     memcpy(avpkt->data, data, len);
259
260     IMFMediaBuffer_Unlock(buffer);
261     IMFMediaBuffer_Release(buffer);
262
263     avpkt->pts = avpkt->dts = mf_sample_get_pts(avctx, sample);
264
265     hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
266     if (c->is_audio || (!FAILED(hr) && t32 != 0))
267         avpkt->flags |= AV_PKT_FLAG_KEY;
268
269     hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
270     if (!FAILED(hr)) {
271         avpkt->dts = mf_from_mf_time(avctx, t);
272         // At least on Qualcomm's HEVC encoder on SD 835, the output dts
273         // starts from the input pts of the first frame, while the output pts
274         // is shifted forward. Therefore, shift the output values back so that
275         // the output pts matches the input.
276         if (c->reorder_delay == AV_NOPTS_VALUE)
277             c->reorder_delay = avpkt->pts - avpkt->dts;
278         avpkt->dts -= c->reorder_delay;
279         avpkt->pts -= c->reorder_delay;
280     }
281
282     return 0;
283 }
284
285 static IMFSample *mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
286 {
287     MFContext *c = avctx->priv_data;
288     size_t len;
289     size_t bps;
290     IMFSample *sample;
291
292     bps = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels;
293     len = frame->nb_samples * bps;
294
295     sample = ff_create_memory_sample(frame->data[0], len, c->in_info.cbAlignment);
296     if (sample)
297         IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->nb_samples));
298     return sample;
299 }
300
301 static IMFSample *mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
302 {
303     MFContext *c = avctx->priv_data;
304     IMFSample *sample;
305     IMFMediaBuffer *buffer;
306     BYTE *data;
307     HRESULT hr;
308     int ret;
309     int size;
310
311     size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
312     if (size < 0)
313         return NULL;
314
315     sample = ff_create_memory_sample(NULL, size, c->in_info.cbAlignment);
316     if (!sample)
317         return NULL;
318
319     hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
320     if (FAILED(hr)) {
321         IMFSample_Release(sample);
322         return NULL;
323     }
324
325     hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
326     if (FAILED(hr)) {
327         IMFMediaBuffer_Release(buffer);
328         IMFSample_Release(sample);
329         return NULL;
330     }
331
332     ret = av_image_copy_to_buffer((uint8_t *)data, size, (void *)frame->data, frame->linesize,
333                                   avctx->pix_fmt, avctx->width, avctx->height, 1);
334     IMFMediaBuffer_SetCurrentLength(buffer, size);
335     IMFMediaBuffer_Unlock(buffer);
336     IMFMediaBuffer_Release(buffer);
337     if (ret < 0) {
338         IMFSample_Release(sample);
339         return NULL;
340     }
341
342     IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->pkt_duration));
343
344     return sample;
345 }
346
347 static IMFSample *mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
348 {
349     MFContext *c = avctx->priv_data;
350     IMFSample *sample;
351
352     if (c->is_audio) {
353         sample = mf_a_avframe_to_sample(avctx, frame);
354     } else {
355         sample = mf_v_avframe_to_sample(avctx, frame);
356     }
357
358     if (sample)
359         mf_sample_set_pts(avctx, sample, frame->pts);
360
361     return sample;
362 }
363
364 static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
365 {
366     MFContext *c = avctx->priv_data;
367     HRESULT hr;
368     int ret;
369
370     if (sample) {
371         if (c->async_events) {
372             if ((ret = mf_wait_events(avctx)) < 0)
373                 return ret;
374             if (!c->async_need_input)
375                 return AVERROR(EAGAIN);
376         }
377         if (!c->sample_sent)
378             IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
379         c->sample_sent = 1;
380         hr = IMFTransform_ProcessInput(c->mft, c->in_stream_id, sample, 0);
381         if (hr == MF_E_NOTACCEPTING) {
382             return AVERROR(EAGAIN);
383         } else if (FAILED(hr)) {
384             av_log(avctx, AV_LOG_ERROR, "failed processing input: %s\n", ff_hr_str(hr));
385             return AVERROR_EXTERNAL;
386         }
387         c->async_need_input = 0;
388     } else if (!c->draining) {
389         hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
390         if (FAILED(hr))
391             av_log(avctx, AV_LOG_ERROR, "failed draining: %s\n", ff_hr_str(hr));
392         // Some MFTs (AC3) will send a frame after each drain command (???), so
393         // this is required to make draining actually terminate.
394         c->draining = 1;
395         c->async_need_input = 0;
396     } else {
397         return AVERROR_EOF;
398     }
399     return 0;
400 }
401
402 static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
403 {
404     MFContext *c = avctx->priv_data;
405     HRESULT hr;
406     DWORD st;
407     MFT_OUTPUT_DATA_BUFFER out_buffers;
408     IMFSample *sample;
409     int ret = 0;
410
411     while (1) {
412         *out_sample = NULL;
413         sample = NULL;
414
415         if (c->async_events) {
416             if ((ret = mf_wait_events(avctx)) < 0)
417                 return ret;
418             if (!c->async_have_output || c->draining_done) {
419                 ret = 0;
420                 break;
421             }
422         }
423
424         if (!c->out_stream_provides_samples) {
425             sample = ff_create_memory_sample(NULL, c->out_info.cbSize, c->out_info.cbAlignment);
426             if (!sample)
427                 return AVERROR(ENOMEM);
428         }
429
430         out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
431             .dwStreamID = c->out_stream_id,
432             .pSample = sample,
433         };
434
435         st = 0;
436         hr = IMFTransform_ProcessOutput(c->mft, 0, 1, &out_buffers, &st);
437
438         if (out_buffers.pEvents)
439             IMFCollection_Release(out_buffers.pEvents);
440
441         if (!FAILED(hr)) {
442             *out_sample = out_buffers.pSample;
443             ret = 0;
444             break;
445         }
446
447         if (out_buffers.pSample)
448             IMFSample_Release(out_buffers.pSample);
449
450         if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
451             if (c->draining)
452                 c->draining_done = 1;
453             ret = 0;
454         } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
455             av_log(avctx, AV_LOG_WARNING, "stream format change\n");
456             ret = mf_choose_output_type(avctx);
457             if (ret == 0) // we don't expect renegotiating the input type
458                 ret = AVERROR_EXTERNAL;
459             if (ret > 0) {
460                 ret = mf_setup_context(avctx);
461                 if (ret >= 0) {
462                     c->async_have_output = 0;
463                     continue;
464                 }
465             }
466         } else {
467             av_log(avctx, AV_LOG_ERROR, "failed processing output: %s\n", ff_hr_str(hr));
468             ret = AVERROR_EXTERNAL;
469         }
470
471         break;
472     }
473
474     c->async_have_output = 0;
475
476     if (ret >= 0 && !*out_sample)
477         ret = c->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
478
479     return ret;
480 }
481
482 static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
483 {
484     MFContext *c = avctx->priv_data;
485     IMFSample *sample = NULL;
486     int ret;
487
488     if (!c->frame->buf[0]) {
489         ret = ff_encode_get_frame(avctx, c->frame);
490         if (ret < 0 && ret != AVERROR_EOF)
491             return ret;
492     }
493
494     if (c->frame->buf[0]) {
495         sample = mf_avframe_to_sample(avctx, c->frame);
496         if (!sample) {
497             av_frame_unref(c->frame);
498             return AVERROR(ENOMEM);
499         }
500         if (c->is_video && c->codec_api) {
501             if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
502                 ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
503         }
504     }
505
506     ret = mf_send_sample(avctx, sample);
507     if (sample)
508         IMFSample_Release(sample);
509     if (ret != AVERROR(EAGAIN))
510         av_frame_unref(c->frame);
511     if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
512         return ret;
513
514     ret = mf_receive_sample(avctx, &sample);
515     if (ret < 0)
516         return ret;
517
518     ret = mf_sample_to_avpacket(avctx, sample, avpkt);
519     IMFSample_Release(sample);
520
521     return ret;
522 }
523
524 // Most encoders seem to enumerate supported audio formats on the output types,
525 // at least as far as channel configuration and sample rate is concerned. Pick
526 // the one which seems to match best.
527 static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
528 {
529     MFContext *c = avctx->priv_data;
530     HRESULT hr;
531     UINT32 t;
532     GUID tg;
533     int64_t score = 0;
534
535     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
536     if (!FAILED(hr) && t == avctx->sample_rate)
537         score |= 1LL << 32;
538
539     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
540     if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
541         score |= 2LL << 32;
542
543     hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
544     if (!FAILED(hr)) {
545         if (IsEqualGUID(&c->main_subtype, &tg))
546             score |= 4LL << 32;
547     }
548
549     // Select the bitrate (lowest priority).
550     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
551     if (!FAILED(hr)) {
552         int diff = (int)t - avctx->bit_rate / 8;
553         if (diff >= 0) {
554             score |= (1LL << 31) - diff; // prefer lower bitrate
555         } else {
556             score |= (1LL << 30) + diff; // prefer higher bitrate
557         }
558     }
559
560     hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
561     if (!FAILED(hr) && t != 0)
562         return -1;
563
564     return score;
565 }
566
567 static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
568 {
569     // (some decoders allow adjusting this freely, but it can also cause failure
570     //  to set the output type - so it's commented for being too fragile)
571     //IMFAttributes_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avctx->bit_rate / 8);
572     //IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
573
574     return 0;
575 }
576
577 static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
578 {
579     HRESULT hr;
580     UINT32 t;
581     int64_t score = 0;
582
583     enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
584     if (sformat == AV_SAMPLE_FMT_NONE)
585         return -1; // can not use
586
587     if (sformat == avctx->sample_fmt)
588         score |= 1;
589
590     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
591     if (!FAILED(hr) && t == avctx->sample_rate)
592         score |= 2;
593
594     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
595     if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
596         score |= 4;
597
598     return score;
599 }
600
601 static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
602 {
603     HRESULT hr;
604     UINT32 t;
605
606     enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
607     if (sformat != avctx->sample_fmt) {
608         av_log(avctx, AV_LOG_ERROR, "unsupported input sample format set\n");
609         return AVERROR(EINVAL);
610     }
611
612     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
613     if (FAILED(hr) || t != avctx->sample_rate) {
614         av_log(avctx, AV_LOG_ERROR, "unsupported input sample rate set\n");
615         return AVERROR(EINVAL);
616     }
617
618     hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
619     if (FAILED(hr) || t != avctx->ch_layout.nb_channels) {
620         av_log(avctx, AV_LOG_ERROR, "unsupported input channel number set\n");
621         return AVERROR(EINVAL);
622     }
623
624     return 0;
625 }
626
627 static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
628 {
629     MFContext *c = avctx->priv_data;
630     GUID tg;
631     HRESULT hr;
632     int score = -1;
633
634     hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
635     if (!FAILED(hr)) {
636         if (IsEqualGUID(&c->main_subtype, &tg))
637             score = 1;
638     }
639
640     return score;
641 }
642
643 static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
644 {
645     MFContext *c = avctx->priv_data;
646     AVRational framerate;
647
648     ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
649     IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
650
651     if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
652         framerate = avctx->framerate;
653     } else {
654         framerate = av_inv_q(avctx->time_base);
655         framerate.den *= avctx->ticks_per_frame;
656     }
657
658     ff_MFSetAttributeRatio((IMFAttributes *)type, &MF_MT_FRAME_RATE, framerate.num, framerate.den);
659
660     // (MS HEVC supports eAVEncH265VProfile_Main_420_8 only.)
661     if (avctx->codec_id == AV_CODEC_ID_H264) {
662         UINT32 profile = ff_eAVEncH264VProfile_Base;
663         switch (avctx->profile) {
664         case FF_PROFILE_H264_MAIN:
665             profile = ff_eAVEncH264VProfile_Main;
666             break;
667         case FF_PROFILE_H264_HIGH:
668             profile = ff_eAVEncH264VProfile_High;
669             break;
670         }
671         IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
672     }
673
674     IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
675
676     // Note that some of the ICodecAPI options must be set before SetOutputType.
677     if (c->codec_api) {
678         if (avctx->bit_rate)
679             ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMeanBitRate, FF_VAL_VT_UI4(avctx->bit_rate));
680
681         if (c->opt_enc_rc >= 0)
682             ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonRateControlMode, FF_VAL_VT_UI4(c->opt_enc_rc));
683
684         if (c->opt_enc_quality >= 0)
685             ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQuality, FF_VAL_VT_UI4(c->opt_enc_quality));
686
687         // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
688         // defaults this to 1, and that setting is buggy with many of the
689         // rate control modes. (0 or 2 b-frames works fine with most rate
690         // control modes, but 2 seems buggy with the u_vbr mode.) Setting
691         // "scenario" to "camera_record" sets it in CFR mode (where the default
692         // is VFR), which makes the encoder avoid dropping frames.
693         ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVDefaultBPictureCount, FF_VAL_VT_UI4(avctx->max_b_frames));
694         avctx->has_b_frames = avctx->max_b_frames > 0;
695
696         ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncH264CABACEnable, FF_VAL_VT_BOOL(1));
697
698         if (c->opt_enc_scenario >= 0)
699             ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVScenarioInfo, FF_VAL_VT_UI4(c->opt_enc_scenario));
700     }
701
702     return 0;
703 }
704
705 static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
706 {
707     enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
708     if (pix_fmt != avctx->pix_fmt)
709         return -1; // can not use
710
711     return 0;
712 }
713
714 static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
715 {
716     enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
717     if (pix_fmt != avctx->pix_fmt) {
718         av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
719         return AVERROR(EINVAL);
720     }
721
722     //ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
723
724     return 0;
725 }
726
727 static int mf_choose_output_type(AVCodecContext *avctx)
728 {
729     MFContext *c = avctx->priv_data;
730     HRESULT hr;
731     int ret;
732     IMFMediaType *out_type = NULL;
733     int64_t out_type_score = -1;
734     int out_type_index = -1;
735     int n;
736
737     av_log(avctx, AV_LOG_VERBOSE, "output types:\n");
738     for (n = 0; ; n++) {
739         IMFMediaType *type;
740         int64_t score = -1;
741
742         hr = IMFTransform_GetOutputAvailableType(c->mft, c->out_stream_id, n, &type);
743         if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
744             break;
745         if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
746             av_log(avctx, AV_LOG_VERBOSE, "(need to set input type)\n");
747             ret = 0;
748             goto done;
749         }
750         if (FAILED(hr)) {
751             av_log(avctx, AV_LOG_ERROR, "error getting output type: %s\n", ff_hr_str(hr));
752             ret = AVERROR_EXTERNAL;
753             goto done;
754         }
755
756         av_log(avctx, AV_LOG_VERBOSE, "output type %d:\n", n);
757         ff_media_type_dump(avctx, type);
758
759         if (c->is_video) {
760             score = mf_encv_output_score(avctx, type);
761         } else if (c->is_audio) {
762             score = mf_enca_output_score(avctx, type);
763         }
764
765         if (score > out_type_score) {
766             if (out_type)
767                 IMFMediaType_Release(out_type);
768             out_type = type;
769             out_type_score = score;
770             out_type_index = n;
771             IMFMediaType_AddRef(out_type);
772         }
773
774         IMFMediaType_Release(type);
775     }
776
777     if (out_type) {
778         av_log(avctx, AV_LOG_VERBOSE, "picking output type %d.\n", out_type_index);
779     } else {
780         hr = MFCreateMediaType(&out_type);
781         if (FAILED(hr)) {
782             ret = AVERROR(ENOMEM);
783             goto done;
784         }
785     }
786
787     ret = 0;
788     if (c->is_video) {
789         ret = mf_encv_output_adjust(avctx, out_type);
790     } else if (c->is_audio) {
791         ret = mf_enca_output_adjust(avctx, out_type);
792     }
793
794     if (ret >= 0) {
795         av_log(avctx, AV_LOG_VERBOSE, "setting output type:\n");
796         ff_media_type_dump(avctx, out_type);
797
798         hr = IMFTransform_SetOutputType(c->mft, c->out_stream_id, out_type, 0);
799         if (!FAILED(hr)) {
800             ret = 1;
801         } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
802             av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set input type\n");
803             ret = 0;
804         } else {
805             av_log(avctx, AV_LOG_ERROR, "could not set output type (%s)\n", ff_hr_str(hr));
806             ret = AVERROR_EXTERNAL;
807         }
808     }
809
810 done:
811     if (out_type)
812         IMFMediaType_Release(out_type);
813     return ret;
814 }
815
816 static int mf_choose_input_type(AVCodecContext *avctx)
817 {
818     MFContext *c = avctx->priv_data;
819     HRESULT hr;
820     int ret;
821     IMFMediaType *in_type = NULL;
822     int64_t in_type_score = -1;
823     int in_type_index = -1;
824     int n;
825
826     av_log(avctx, AV_LOG_VERBOSE, "input types:\n");
827     for (n = 0; ; n++) {
828         IMFMediaType *type = NULL;
829         int64_t score = -1;
830
831         hr = IMFTransform_GetInputAvailableType(c->mft, c->in_stream_id, n, &type);
832         if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
833             break;
834         if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
835             av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 1)\n");
836             ret = 0;
837             goto done;
838         }
839         if (FAILED(hr)) {
840             av_log(avctx, AV_LOG_ERROR, "error getting input type: %s\n", ff_hr_str(hr));
841             ret = AVERROR_EXTERNAL;
842             goto done;
843         }
844
845         av_log(avctx, AV_LOG_VERBOSE, "input type %d:\n", n);
846         ff_media_type_dump(avctx, type);
847
848         if (c->is_video) {
849             score = mf_encv_input_score(avctx, type);
850         } else if (c->is_audio) {
851             score = mf_enca_input_score(avctx, type);
852         }
853
854         if (score > in_type_score) {
855             if (in_type)
856                 IMFMediaType_Release(in_type);
857             in_type = type;
858             in_type_score = score;
859             in_type_index = n;
860             IMFMediaType_AddRef(in_type);
861         }
862
863         IMFMediaType_Release(type);
864     }
865
866     if (in_type) {
867         av_log(avctx, AV_LOG_VERBOSE, "picking input type %d.\n", in_type_index);
868     } else {
869         // Some buggy MFTs (WMA encoder) fail to return MF_E_TRANSFORM_TYPE_NOT_SET.
870         av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 2)\n");
871         ret = 0;
872         goto done;
873     }
874
875     ret = 0;
876     if (c->is_video) {
877         ret = mf_encv_input_adjust(avctx, in_type);
878     } else if (c->is_audio) {
879         ret = mf_enca_input_adjust(avctx, in_type);
880     }
881
882     if (ret >= 0) {
883         av_log(avctx, AV_LOG_VERBOSE, "setting input type:\n");
884         ff_media_type_dump(avctx, in_type);
885
886         hr = IMFTransform_SetInputType(c->mft, c->in_stream_id, in_type, 0);
887         if (!FAILED(hr)) {
888             ret = 1;
889         } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
890             av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set output type\n");
891             ret = 0;
892         } else {
893             av_log(avctx, AV_LOG_ERROR, "could not set input type (%s)\n", ff_hr_str(hr));
894             ret = AVERROR_EXTERNAL;
895         }
896     }
897
898 done:
899     if (in_type)
900         IMFMediaType_Release(in_type);
901     return ret;
902 }
903
904 static int mf_negotiate_types(AVCodecContext *avctx)
905 {
906     // This follows steps 1-5 on:
907     //  https://msdn.microsoft.com/en-us/library/windows/desktop/aa965264(v=vs.85).aspx
908     // If every MFT implementer does this correctly, this loop should at worst
909     // be repeated once.
910     int need_input = 1, need_output = 1;
911     int n;
912     for (n = 0; n < 2 && (need_input || need_output); n++) {
913         int ret;
914         ret = mf_choose_input_type(avctx);
915         if (ret < 0)
916             return ret;
917         need_input = ret < 1;
918         ret = mf_choose_output_type(avctx);
919         if (ret < 0)
920             return ret;
921         need_output = ret < 1;
922     }
923     if (need_input || need_output) {
924         av_log(avctx, AV_LOG_ERROR, "format negotiation failed (%d/%d)\n",
925                need_input, need_output);
926         return AVERROR_EXTERNAL;
927     }
928     return 0;
929 }
930
931 static int mf_setup_context(AVCodecContext *avctx)
932 {
933     MFContext *c = avctx->priv_data;
934     HRESULT hr;
935     int ret;
936
937     hr = IMFTransform_GetInputStreamInfo(c->mft, c->in_stream_id, &c->in_info);
938     if (FAILED(hr))
939         return AVERROR_EXTERNAL;
940     av_log(avctx, AV_LOG_VERBOSE, "in_info: size=%d, align=%d\n",
941            (int)c->in_info.cbSize, (int)c->in_info.cbAlignment);
942
943     hr = IMFTransform_GetOutputStreamInfo(c->mft, c->out_stream_id, &c->out_info);
944     if (FAILED(hr))
945         return AVERROR_EXTERNAL;
946     c->out_stream_provides_samples =
947         (c->out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
948         (c->out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
949     av_log(avctx, AV_LOG_VERBOSE, "out_info: size=%d, align=%d%s\n",
950            (int)c->out_info.cbSize, (int)c->out_info.cbAlignment,
951            c->out_stream_provides_samples ? " (provides samples)" : "");
952
953     if ((ret = mf_output_type_get(avctx)) < 0)
954         return ret;
955
956     return 0;
957 }
958
959 static int mf_unlock_async(AVCodecContext *avctx)
960 {
961     MFContext *c = avctx->priv_data;
962     HRESULT hr;
963     IMFAttributes *attrs;
964     UINT32 v;
965     int res = AVERROR_EXTERNAL;
966
967     // For hw encoding we unfortunately need to use async mode, otherwise
968     // play it safe and avoid it.
969     if (!(c->is_video && c->opt_enc_hw))
970         return 0;
971
972     hr = IMFTransform_GetAttributes(c->mft, &attrs);
973     if (FAILED(hr)) {
974         av_log(avctx, AV_LOG_ERROR, "error retrieving MFT attributes: %s\n", ff_hr_str(hr));
975         goto err;
976     }
977
978     hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
979     if (FAILED(hr)) {
980         av_log(avctx, AV_LOG_ERROR, "error querying async: %s\n", ff_hr_str(hr));
981         goto err;
982     }
983
984     if (!v) {
985         av_log(avctx, AV_LOG_ERROR, "hardware MFT is not async\n");
986         goto err;
987     }
988
989     hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
990     if (FAILED(hr)) {
991         av_log(avctx, AV_LOG_ERROR, "could not set async unlock: %s\n", ff_hr_str(hr));
992         goto err;
993     }
994
995     hr = IMFTransform_QueryInterface(c->mft, &IID_IMFMediaEventGenerator, (void **)&c->async_events);
996     if (FAILED(hr)) {
997         av_log(avctx, AV_LOG_ERROR, "could not get async interface\n");
998         goto err;
999     }
1000
1001     res = 0;
1002
1003 err:
1004     IMFAttributes_Release(attrs);
1005     return res;
1006 }
1007
1008 static int mf_create(void *log, IMFTransform **mft, const AVCodec *codec, int use_hw)
1009 {
1010     int is_audio = codec->type == AVMEDIA_TYPE_AUDIO;
1011     const CLSID *subtype = ff_codec_to_mf_subtype(codec->id);
1012     MFT_REGISTER_TYPE_INFO reg = {0};
1013     GUID category;
1014     int ret;
1015
1016     *mft = NULL;
1017
1018     if (!subtype)
1019         return AVERROR(ENOSYS);
1020
1021     reg.guidSubtype = *subtype;
1022
1023     if (is_audio) {
1024         reg.guidMajorType = MFMediaType_Audio;
1025         category = MFT_CATEGORY_AUDIO_ENCODER;
1026     } else {
1027         reg.guidMajorType = MFMediaType_Video;
1028         category = MFT_CATEGORY_VIDEO_ENCODER;
1029     }
1030
1031     if ((ret = ff_instantiate_mf(log, category, NULL, &reg, use_hw, mft)) < 0)
1032         return ret;
1033
1034     return 0;
1035 }
1036
1037 static int mf_init(AVCodecContext *avctx)
1038 {
1039     MFContext *c = avctx->priv_data;
1040     HRESULT hr;
1041     int ret;
1042     const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id);
1043     int use_hw = 0;
1044
1045     c->frame = av_frame_alloc();
1046     if (!c->frame)
1047         return AVERROR(ENOMEM);
1048
1049     c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO;
1050     c->is_video = !c->is_audio;
1051     c->reorder_delay = AV_NOPTS_VALUE;
1052
1053     if (c->is_video && c->opt_enc_hw)
1054         use_hw = 1;
1055
1056     if (!subtype)
1057         return AVERROR(ENOSYS);
1058
1059     c->main_subtype = *subtype;
1060
1061     if ((ret = mf_create(avctx, &c->mft, avctx->codec, use_hw)) < 0)
1062         return ret;
1063
1064     if ((ret = mf_unlock_async(avctx)) < 0)
1065         return ret;
1066
1067     hr = IMFTransform_QueryInterface(c->mft, &IID_ICodecAPI, (void **)&c->codec_api);
1068     if (!FAILED(hr))
1069         av_log(avctx, AV_LOG_VERBOSE, "MFT supports ICodecAPI.\n");
1070
1071
1072     hr = IMFTransform_GetStreamIDs(c->mft, 1, &c->in_stream_id, 1, &c->out_stream_id);
1073     if (hr == E_NOTIMPL) {
1074         c->in_stream_id = c->out_stream_id = 0;
1075     } else if (FAILED(hr)) {
1076         av_log(avctx, AV_LOG_ERROR, "could not get stream IDs (%s)\n", ff_hr_str(hr));
1077         return AVERROR_EXTERNAL;
1078     }
1079
1080     if ((ret = mf_negotiate_types(avctx)) < 0)
1081         return ret;
1082
1083     if ((ret = mf_setup_context(avctx)) < 0)
1084         return ret;
1085
1086     hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
1087     if (FAILED(hr)) {
1088         av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr));
1089         return AVERROR_EXTERNAL;
1090     }
1091
1092     hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
1093     if (FAILED(hr)) {
1094         av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr));
1095         return AVERROR_EXTERNAL;
1096     }
1097
1098     if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER && c->async_events &&
1099         c->is_video && !avctx->extradata) {
1100         int sleep = 10000, total = 0;
1101         av_log(avctx, AV_LOG_VERBOSE, "Awaiting extradata\n");
1102         while (total < 70*1000) {
1103             // The Qualcomm H264 encoder on SD835 doesn't provide extradata
1104             // immediately, but it becomes available soon after init (without
1105             // any waitable event). In practice, it's available after less
1106             // than 10 ms, but wait for up to 70 ms before giving up.
1107             // Some encoders (Qualcomm's HEVC encoder on SD835, some versions
1108             // of the QSV H264 encoder at least) don't provide extradata this
1109             // way at all, not even after encoding a frame - it's only
1110             // available prepended to frames.
1111             av_usleep(sleep);
1112             total += sleep;
1113             mf_output_type_get(avctx);
1114             if (avctx->extradata)
1115                 break;
1116             sleep *= 2;
1117         }
1118         av_log(avctx, AV_LOG_VERBOSE, "%s extradata in %d ms\n",
1119                avctx->extradata ? "Got" : "Didn't get", total / 1000);
1120     }
1121
1122     return 0;
1123 }
1124
1125 static int mf_close(AVCodecContext *avctx)
1126 {
1127     MFContext *c = avctx->priv_data;
1128
1129     if (c->codec_api)
1130         ICodecAPI_Release(c->codec_api);
1131
1132     if (c->async_events)
1133         IMFMediaEventGenerator_Release(c->async_events);
1134
1135     ff_free_mf(&c->mft);
1136
1137     av_frame_free(&c->frame);
1138
1139     av_freep(&avctx->extradata);
1140     avctx->extradata_size = 0;
1141
1142     return 0;
1143 }
1144
1145 #define OFFSET(x) offsetof(MFContext, x)
1146
1147 #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA) \
1148     static const AVClass ff_ ## NAME ## _mf_encoder_class = {                  \
1149         .class_name = #NAME "_mf",                                             \
1150         .item_name  = av_default_item_name,                                    \
1151         .option     = OPTS,                                                    \
1152         .version    = LIBAVUTIL_VERSION_INT,                                   \
1153     };                                                                         \
1154     const FFCodec ff_ ## NAME ## _mf_encoder = {                               \
1155         .p.priv_class   = &ff_ ## NAME ## _mf_encoder_class,                   \
1156         .p.name         = #NAME "_mf",                                         \
1157         .p.long_name    = NULL_IF_CONFIG_SMALL(#ID " via MediaFoundation"),    \
1158         .p.type         = AVMEDIA_TYPE_ ## MEDIATYPE,                          \
1159         .p.id           = AV_CODEC_ID_ ## ID,                                  \
1160         .priv_data_size = sizeof(MFContext),                                   \
1161         .init           = mf_init,                                             \
1162         .close          = mf_close,                                            \
1163         FF_CODEC_RECEIVE_PACKET_CB(mf_receive_packet),                         \
1164         EXTRA                                                                  \
1165         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID |           \
1166                           AV_CODEC_CAP_DR1,                                    \
1167         .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |                       \
1168                           FF_CODEC_CAP_INIT_CLEANUP,                           \
1169     };
1170
1171 #define AFMTS \
1172         .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,    \
1173                                                          AV_SAMPLE_FMT_NONE },
1174
1175 MF_ENCODER(AUDIO, aac,         AAC, NULL, AFMTS);
1176 MF_ENCODER(AUDIO, ac3,         AC3, NULL, AFMTS);
1177 MF_ENCODER(AUDIO, mp3,         MP3, NULL, AFMTS);
1178
1179 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1180 static const AVOption venc_opts[] = {
1181     {"rate_control",  "Select rate control mode", OFFSET(opt_enc_rc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "rate_control"},
1182     { "default",      "Default mode", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, "rate_control"},
1183     { "cbr",          "CBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_CBR}, 0, 0, VE, "rate_control"},
1184     { "pc_vbr",       "Peak constrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_PeakConstrainedVBR}, 0, 0, VE, "rate_control"},
1185     { "u_vbr",        "Unconstrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_UnconstrainedVBR}, 0, 0, VE, "rate_control"},
1186     { "quality",      "Quality mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_Quality}, 0, 0, VE, "rate_control" },
1187     // The following rate_control modes require Windows 8.
1188     { "ld_vbr",       "Low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_LowDelayVBR}, 0, 0, VE, "rate_control"},
1189     { "g_vbr",        "Global VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalVBR}, 0, 0, VE, "rate_control" },
1190     { "gld_vbr",      "Global low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR}, 0, 0, VE, "rate_control"},
1191
1192     {"scenario",          "Select usage scenario", OFFSET(opt_enc_scenario), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "scenario"},
1193     { "default",          "Default scenario", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, "scenario"},
1194     { "display_remoting", "Display remoting", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemoting}, 0, 0, VE, "scenario"},
1195     { "video_conference", "Video conference", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_VideoConference}, 0, 0, VE, "scenario"},
1196     { "archive",          "Archive", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_Archive}, 0, 0, VE, "scenario"},
1197     { "live_streaming",   "Live streaming", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_LiveStreaming}, 0, 0, VE, "scenario"},
1198     { "camera_record",    "Camera record", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_CameraRecord}, 0, 0, VE, "scenario"},
1199     { "display_remoting_with_feature_map", "Display remoting with feature map", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap}, 0, 0, VE, "scenario"},
1200
1201     {"quality",       "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
1202     {"hw_encoding",   "Force hardware encoding", OFFSET(opt_enc_hw), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE},
1203     {NULL}
1204 };
1205
1206 #define VFMTS \
1207         .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,       \
1208                                                         AV_PIX_FMT_YUV420P,    \
1209                                                         AV_PIX_FMT_NONE },
1210
1211 MF_ENCODER(VIDEO, h264,        H264, venc_opts, VFMTS);
1212 MF_ENCODER(VIDEO, hevc,        HEVC, venc_opts, VFMTS);