FFmpeg  4.3.9
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;
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  hr = 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) {
352  sample = mf_a_avframe_to_sample(avctx, frame);
353  } else {
354  sample = mf_v_avframe_to_sample(avctx, frame);
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) {
407  sample = mf_avframe_to_sample(avctx, 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
477  ret = AVERROR_EXTERNAL;
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));
487  ret = AVERROR_EXTERNAL;
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) {
657  profile = ff_eAVEncH264VProfile_Main;
658  break;
660  profile = ff_eAVEncH264VProfile_High;
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));
744  ret = AVERROR_EXTERNAL;
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));
798  ret = AVERROR_EXTERNAL;
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));
833  ret = AVERROR_EXTERNAL;
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));
886  ret = AVERROR_EXTERNAL;
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;
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;
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);
category
Definition: openal-dec.c:248
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1904
#define NULL
Definition: coverity.c:32
const struct AVCodec * codec
Definition: avcodec.h:535
AVRational framerate
Definition: avcodec.h:2073
void ff_media_type_dump(void *log, IMFMediaType *type)
Definition: mf_utils.c:534
static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:593
static enum AVPixelFormat pix_fmt
static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
Definition: mfenc.c:108
int size
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
Definition: mfenc.c:115
int is_video
Definition: mfenc.c:33
AVOption.
Definition: opt.h:246
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
DWORD in_stream_id
Definition: mfenc.c:37
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:576
static const AVOption venc_opts[]
Definition: mfenc.c:1166
static int mf_choose_input_type(AVCodecContext *avctx)
Definition: mfenc.c:808
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
int num
Numerator.
Definition: rational.h:59
static int mf_close(AVCodecContext *avctx)
Definition: mfenc.c:1113
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
Definition: mf_utils.c:190
static int mf_choose_output_type(AVCodecContext *avctx)
Definition: mfenc.c:719
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
enum AVMediaType type
Definition: codec.h:203
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
#define ff_hr_str(hr)
Definition: mf_utils.h:145
#define OFFSET(x)
Definition: mfenc.c:1131
static int mf_create(void *log, IMFTransform **mft, const AVCodec *codec, int use_hw)
Definition: mfenc.c:1000
static IMFSample * mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:300
int profile
profile
Definition: avcodec.h:1863
#define sample
#define FF_VAL_VT_UI4(v)
Definition: mf_utils.h:150
AVCodec.
Definition: codec.h:190
int framerate
Definition: h264_levels.c:65
static int mf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:401
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:649
static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:519
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
int draining
Definition: mfenc.c:41
static char buffer[20]
Definition: seek.c:32
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1194
uint8_t
AVOptions.
MFT_OUTPUT_STREAM_INFO out_info
Definition: mfenc.c:39
static int mf_init(AVCodecContext *avctx)
Definition: mfenc.c:1029
int opt_enc_quality
Definition: mfenc.c:48
int async_have_output
Definition: mfenc.c:43
static IMFSample * mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:284
static int need_output(void)
Definition: ffmpeg.c:3799
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:627
#define tg
Definition: regdef.h:74
static AVFrame * frame
const char data[16]
Definition: mxf.c:91
uint8_t * data
Definition: packet.h:355
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:619
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:388
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
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
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
Definition: avcodec.h:2087
static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:569
enum AVCodecID id
Definition: codec.h:204
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
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:816
#define AVERROR(e)
Definition: error.h:43
static int mf_unlock_async(AVCodecContext *avctx)
Definition: mfenc.c:951
static AVRational mf_get_tb(AVCodecContext *avctx)
Definition: mfenc.c:99
static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:127
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:411
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:606
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1906
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
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:361
IMFTransform * mft
Definition: mfenc.c:35
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:383
static int mf_wait_events(AVCodecContext *avctx)
Definition: mfenc.c:60
int width
picture width / height.
Definition: avcodec.h:699
int draining_done
Definition: mfenc.c:41
static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:706
#define ff_MFSetAttributeRatio
Definition: mf_utils.c:47
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:658
static int mf_setup_context(AVCodecContext *avctx)
Definition: mfenc.c:923
int opt_enc_hw
Definition: mfenc.c:50
int sample_sent
Definition: mfenc.c:42
static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:363
static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:697
IMFSample * ff_create_memory_sample(void *fill_data, size_t size, size_t align)
Definition: mf_utils.c:109
int async_need_input
Definition: mfenc.c:43
GUID main_subtype
Definition: mfenc.c:34
static int mf_output_type_get(AVCodecContext *avctx)
Definition: mfenc.c:199
enum AVMediaType codec_type
Definition: avcodec.h:534
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown...
Definition: frame.h:579
static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:635
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
enum AVCodecID codec_id
Definition: avcodec.h:536
#define MF_TIMEBASE
Definition: mfenc.c:56
int sample_rate
samples per second
Definition: avcodec.h:1186
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
Definition: mfenc.c:421
static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:136
main external API structure.
Definition: avcodec.h:526
long long int64_t
Definition: coverity.c:34
int async_marker
Definition: mfenc.c:43
#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA)
Definition: mfenc.c:1133
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
Definition: mf_utils.c:146
int extradata_size
Definition: avcodec.h:628
Describe the class of an AVClass context structure.
Definition: log.h:67
void ff_free_mf(IMFTransform **mft)
Definition: mf_utils.c:674
Rational number (pair of numerator and denominator).
Definition: rational.h:58
static IMFSample * mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
Definition: mfenc.c:346
cl_device_type type
static int mf_negotiate_types(AVCodecContext *avctx)
Definition: mfenc.c:896
#define MF_INVALID_TIME
Definition: mfenc.c:58
#define FF_VAL_VT_BOOL(v)
Definition: mf_utils.h:151
int is_audio
Definition: mfenc.c:33
int opt_enc_scenario
Definition: mfenc.c:49
mfxU16 profile
Definition: qsvenc.c:45
static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
Definition: mfenc.c:122
static int64_t pts
AVClass * av_class
Definition: mfenc.c:32
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:329
#define AFMTS
Definition: mfenc.c:1157
DWORD out_stream_id
Definition: mfenc.c:37
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int
common internal api header.
#define VE
Definition: mfenc.c:1165
if(ret< 0)
Definition: vf_mcdeint.c:279
static double c[64]
int den
Denominator.
Definition: rational.h:60
unsigned bps
Definition: movenc.c:1533
MFT_INPUT_STREAM_INFO in_info
Definition: mfenc.c:38
int out_stream_provides_samples
Definition: mfenc.c:40
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:215
ICodecAPI * codec_api
Definition: mfenc.c:45
void * priv_data
Definition: avcodec.h:553
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid, UINT32 uw, UINT32 uh)
Definition: mf_utils.c:40
static av_always_inline int diff(const uint32_t a, const uint32_t b)
#define av_free(p)
int len
int opt_enc_rc
Definition: mfenc.c:47
int channels
number of audio channels
Definition: avcodec.h:1187
const CLSID * ff_codec_to_mf_subtype(enum AVCodecID codec)
Definition: mf_utils.c:539
static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:176
static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
Definition: mfenc.c:229
int64_t reorder_delay
Definition: mfenc.c:44
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: packet.h:354
#define av_freep(p)
static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:559
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: packet.h:332
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:366
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
IMFMediaEventGenerator * async_events
Definition: mfenc.c:36
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Definition: mfenc.c:501
#define VFMTS
Definition: mfenc.c:1192