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