FFmpeg
mfenc.c
Go to the documentation of this file.
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 {
38  IMFTransform *mft;
39  IMFMediaEventGenerator *async_events;
41  MFT_INPUT_STREAM_INFO in_info;
42  MFT_OUTPUT_STREAM_INFO out_info;
47  int64_t reorder_delay;
48  ICodecAPI *codec_api;
49  // set by AVOption
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) {
82  if (!c->draining)
83  c->async_need_input = 1;
84  break;
86  c->async_have_output = 1;
87  break;
89  c->draining_done = 1;
90  break;
92  c->async_marker = 1;
93  break;
94  default: ;
95  }
96  IMFMediaEvent_Release(ev);
97  }
98 
99  return 0;
100 }
101 
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) {
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 
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 
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) {
354  } else {
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
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));
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;
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) {
663  switch (avctx->profile) {
666  break;
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 
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));
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));
807  }
808  }
809 
810 done:
811  if (out_type)
812  IMFMediaType_Release(out_type);
813  return ret;
814 }
815 
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));
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));
895  }
896  }
897 
898 done:
899  if (in_type)
900  IMFMediaType_Release(in_type);
901  return ret;
902 }
903 
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 
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);
AVCodec
AVCodec.
Definition: codec.h:196
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
need_output
static int need_output(void)
Definition: ffmpeg.c:3512
ff_hr_str
#define ff_hr_str(hr)
Definition: mf_utils.h:145
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:428
FF_VAL_VT_UI4
#define FF_VAL_VT_UI4(v)
Definition: mf_utils.h:150
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:998
venc_opts
static const AVOption venc_opts[]
Definition: mfenc.c:1180
ff_METransformHaveOutput
@ ff_METransformHaveOutput
Definition: mf_utils.h:129
mf_v_avframe_to_sample
static IMFSample * mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:301
mf_choose_input_type
static int mf_choose_input_type(AVCodecContext *avctx)
Definition: mfenc.c:816
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ff_codec_to_mf_subtype
const CLSID * ff_codec_to_mf_subtype(enum AVCodecID codec)
Definition: mf_utils.c:539
mf_enca_output_score
static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:527
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
MFContext::opt_enc_hw
int opt_enc_hw
Definition: mfenc.c:53
MFContext::av_class
AVClass * av_class
Definition: mfenc.c:34
mf_receive_sample
static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
Definition: mfenc.c:402
mf_enca_output_type_get
static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:137
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
MFContext::sample_sent
int sample_sent
Definition: mfenc.c:45
ff_eAVEncCommonRateControlMode_Quality
@ ff_eAVEncCommonRateControlMode_Quality
Definition: mf_utils.h:107
MF_ENCODER
#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA)
Definition: mfenc.c:1147
ff_eAVEncCommonRateControlMode_CBR
@ ff_eAVEncCommonRateControlMode_CBR
Definition: mf_utils.h:104
AVOption
AVOption.
Definition: opt.h:251
encode.h
data
const char data[16]
Definition: mxf.c:143
mf_encv_output_score
static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:627
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
category
category
Definition: openal-dec.c:248
MFContext::draining_done
int draining_done
Definition: mfenc.c:44
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:300
ff_MFSetAttributeSize
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid, UINT32 uw, UINT32 uh)
Definition: mf_utils.c:40
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:429
ff_eAVEncH264VProfile_High
@ ff_eAVEncH264VProfile_High
Definition: mf_utils.h:141
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:274
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1733
framerate
int framerate
Definition: h264_levels.c:65
MFContext::out_stream_id
DWORD out_stream_id
Definition: mfenc.c:40
MFContext::async_marker
int async_marker
Definition: mfenc.c:46
mf_avframe_to_sample
static IMFSample * mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:347
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:398
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:2057
ff_METransformNeedInput
@ ff_METransformNeedInput
Definition: mf_utils.h:128
ff_media_type_to_sample_fmt
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
Definition: mf_utils.c:146
MFContext::async_need_input
int async_need_input
Definition: mfenc.c:46
OFFSET
#define OFFSET(x)
Definition: mfenc.c:1145
mf_receive_packet
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Definition: mfenc.c:482
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:469
MFContext::is_audio
int is_audio
Definition: mfenc.c:36
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1591
mf_utils.h
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
VFMTS
#define VFMTS
Definition: mfenc.c:1206
pts
static int64_t pts
Definition: transcode_aac.c:654
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:426
ff_eAVEncCommonRateControlMode_GlobalVBR
@ ff_eAVEncCommonRateControlMode_GlobalVBR
Definition: mf_utils.h:109
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:99
mf_setup_context
static int mf_setup_context(AVCodecContext *avctx)
Definition: mfenc.c:931
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:491
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:685
MFContext::opt_enc_rc
int opt_enc_rc
Definition: mfenc.c:50
mf_create
static int mf_create(void *log, IMFTransform **mft, const AVCodec *codec, int use_hw)
Definition: mfenc.c:1008
MFContext::reorder_delay
int64_t reorder_delay
Definition: mfenc.c:47
ff_instantiate_mf
int ff_instantiate_mf(void *log, GUID category, MFT_REGISTER_TYPE_INFO *in_type, MFT_REGISTER_TYPE_INFO *out_type, int use_hw, IMFTransform **res)
Definition: mf_utils.c:582
mf_encv_output_adjust
static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:643
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecContext::ticks_per_frame
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:521
MFContext::opt_enc_scenario
int opt_enc_scenario
Definition: mfenc.c:52
ff_METransformDrainComplete
@ ff_METransformDrainComplete
Definition: mf_utils.h:130
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:41
MFContext::codec_api
ICodecAPI * codec_api
Definition: mfenc.c:48
MFContext::in_info
MFT_INPUT_STREAM_INFO in_info
Definition: mfenc.c:41
MFContext::out_stream_provides_samples
int out_stream_provides_samples
Definition: mfenc.c:43
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:399
MFContext::frame
AVFrame * frame
Definition: mfenc.c:35
if
if(ret)
Definition: filter_design.txt:179
ff_eAVScenarioInfo_LiveStreaming
@ ff_eAVScenarioInfo_LiveStreaming
Definition: mf_utils.h:118
ff_MFSetAttributeRatio
#define ff_MFSetAttributeRatio
Definition: mf_utils.c:47
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
ff_eAVEncCommonRateControlMode_PeakConstrainedVBR
@ ff_eAVEncCommonRateControlMode_PeakConstrainedVBR
Definition: mf_utils.h:105
AVCodec::type
enum AVMediaType type
Definition: codec.h:209
mf_enca_input_score
static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:577
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
MF_INVALID_TIME
#define MF_INVALID_TIME
Definition: mfenc.c:61
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:439
ff_free_mf
void ff_free_mf(IMFTransform **mft)
Definition: mf_utils.c:674
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
mf_enca_input_adjust
static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:601
time.h
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:427
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:512
ff_media_type_to_pix_fmt
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
Definition: mf_utils.c:190
mf_a_avframe_to_sample
static IMFSample * mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:285
ff_eAVScenarioInfo_Archive
@ ff_eAVScenarioInfo_Archive
Definition: mf_utils.h:117
codec_internal.h
ff_METransformMarker
@ ff_METransformMarker
Definition: mf_utils.h:131
bps
unsigned bps
Definition: movenc.c:1631
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1014
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
sample
#define sample
Definition: flacdsp_template.c:44
MFContext::is_video
int is_video
Definition: mfenc.c:36
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
ff_eAVEncH264VProfile_Base
@ ff_eAVEncH264VProfile_Base
Definition: mf_utils.h:139
ff_eAVScenarioInfo_DisplayRemoting
@ ff_eAVScenarioInfo_DisplayRemoting
Definition: mf_utils.h:115
MFContext::opt_enc_quality
int opt_enc_quality
Definition: mfenc.c:51
MFContext::async_events
IMFMediaEventGenerator * async_events
Definition: mfenc.c:39
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:373
ff_eAVEncCommonRateControlMode_UnconstrainedVBR
@ ff_eAVEncCommonRateControlMode_UnconstrainedVBR
Definition: mf_utils.h:106
MF_TIMEBASE
#define MF_TIMEBASE
Definition: mfenc.c:59
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap
@ ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap
Definition: mf_utils.h:120
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:380
tg
#define tg
Definition: regdef.h:74
AVCodec::id
enum AVCodecID id
Definition: codec.h:210
mf_get_tb
static AVRational mf_get_tb(AVCodecContext *avctx)
Definition: mfenc.c:102
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:367
mf_send_sample
static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:364
MFContext::in_stream_id
DWORD in_stream_id
Definition: mfenc.c:40
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:490
MFContext::async_have_output
int async_have_output
Definition: mfenc.c:46
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
VE
#define VE
Definition: mfenc.c:1179
MFContext::out_info
MFT_OUTPUT_STREAM_INFO out_info
Definition: mfenc.c:42
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:477
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2005
MFContext
Definition: mfenc.c:33
AVCodecContext::height
int height
Definition: avcodec.h:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
mf_negotiate_types
static int mf_negotiate_types(AVCodecContext *avctx)
Definition: mfenc.c:904
mf_enca_output_adjust
static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:567
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
mf_sample_set_pts
static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
Definition: mfenc.c:116
mf_to_mf_time
static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
Definition: mfenc.c:109
mf_from_mf_time
static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
Definition: mfenc.c:123
mf_init
static int mf_init(AVCodecContext *avctx)
Definition: mfenc.c:1037
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:389
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:79
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1548
mf_close
static int mf_close(AVCodecContext *avctx)
Definition: mfenc.c:1125
mf_encv_input_adjust
static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:714
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1589
MFContext::draining
int draining
Definition: mfenc.c:44
ff_eAVScenarioInfo_CameraRecord
@ ff_eAVScenarioInfo_CameraRecord
Definition: mf_utils.h:119
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:397
FF_VAL_VT_BOOL
#define FF_VAL_VT_BOOL(v)
Definition: mf_utils.h:151
AVCodecContext::max_b_frames
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:661
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:160
mf_choose_output_type
static int mf_choose_output_type(AVCodecContext *avctx)
Definition: mfenc.c:727
ff_eAVScenarioInfo_VideoConference
@ ff_eAVScenarioInfo_VideoConference
Definition: mf_utils.h:116
AFMTS
#define AFMTS
Definition: mfenc.c:1171
ff_media_type_dump
void ff_media_type_dump(void *log, IMFMediaType *type)
Definition: mf_utils.c:534
mf_encv_input_score
static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:705
mf_output_type_get
static int mf_output_type_get(AVCodecContext *avctx)
Definition: mfenc.c:200
diff
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Definition: vf_palettegen.c:139
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_image_copy_to_buffer
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
Definition: imgutils.c:501
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
mf_sample_to_avpacket
static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
Definition: mfenc.c:230
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
imgutils.h
MFContext::mft
IMFTransform * mft
Definition: mfenc.c:38
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
mf_unlock_async
static int mf_unlock_async(AVCodecContext *avctx)
Definition: mfenc.c:959
ff_create_memory_sample
IMFSample * ff_create_memory_sample(void *fill_data, size_t size, size_t align)
Definition: mf_utils.c:109
ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR
@ ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR
Definition: mf_utils.h:110
int
int
Definition: ffmpeg_filter.c:153
mf_wait_events
static int mf_wait_events(AVCodecContext *avctx)
Definition: mfenc.c:63
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
ff_eAVEncH264VProfile_Main
@ ff_eAVEncH264VProfile_Main
Definition: mf_utils.h:140
mf_sample_get_pts
static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:128
MFContext::main_subtype
GUID main_subtype
Definition: mfenc.c:37
ff_eAVEncCommonRateControlMode_LowDelayVBR
@ ff_eAVEncCommonRateControlMode_LowDelayVBR
Definition: mf_utils.h:108
mf_encv_output_type_get
static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:177