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