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/mem.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/time.h"
31 #include "codec_internal.h"
32 #include "internal.h"
33 #include "compat/w32dlfcn.h"
34 #if CONFIG_D3D11VA
36 #endif
37 
38 typedef struct MFContext {
40  HMODULE library;
41  HMODULE d3d_dll;
42  ID3D11DeviceContext* d3d_context;
43  IMFDXGIDeviceManager *dxgiManager;
45 
50  IMFTransform *mft;
51  IMFMediaEventGenerator *async_events;
53  MFT_INPUT_STREAM_INFO in_info;
54  MFT_OUTPUT_STREAM_INFO out_info;
61  ICodecAPI *codec_api;
62  // set by AVOption
68 } MFContext;
69 
70 static int mf_choose_output_type(AVCodecContext *avctx);
71 static int mf_setup_context(AVCodecContext *avctx);
72 
73 #define MF_TIMEBASE (AVRational){1, 10000000}
74 // Sentinel value only used by us.
75 #define MF_INVALID_TIME AV_NOPTS_VALUE
76 
77 static int mf_wait_events(AVCodecContext *avctx)
78 {
79  MFContext *c = avctx->priv_data;
80 
81  if (!c->async_events)
82  return 0;
83 
84  while (!(c->async_need_input || c->async_have_output || c->draining_done || c->async_marker)) {
85  IMFMediaEvent *ev = NULL;
86  MediaEventType ev_id = 0;
87  HRESULT hr = IMFMediaEventGenerator_GetEvent(c->async_events, 0, &ev);
88  if (FAILED(hr)) {
89  av_log(avctx, AV_LOG_ERROR, "IMFMediaEventGenerator_GetEvent() failed: %s\n",
90  ff_hr_str(hr));
91  return AVERROR_EXTERNAL;
92  }
93  IMFMediaEvent_GetType(ev, &ev_id);
94  switch (ev_id) {
96  if (!c->draining)
97  c->async_need_input = 1;
98  break;
100  c->async_have_output = 1;
101  break;
103  c->draining_done = 1;
104  break;
106  c->async_marker = 1;
107  break;
108  default: ;
109  }
110  IMFMediaEvent_Release(ev);
111  }
112 
113  return 0;
114 }
115 
117 {
118  if (avctx->time_base.num > 0 && avctx->time_base.den > 0)
119  return avctx->time_base;
120  return MF_TIMEBASE;
121 }
122 
123 static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
124 {
125  if (av_pts == AV_NOPTS_VALUE)
126  return MF_INVALID_TIME;
127  return av_rescale_q(av_pts, mf_get_tb(avctx), MF_TIMEBASE);
128 }
129 
130 static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
131 {
132  LONGLONG stime = mf_to_mf_time(avctx, av_pts);
133  if (stime != MF_INVALID_TIME)
134  IMFSample_SetSampleTime(sample, stime);
135 }
136 
137 static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
138 {
139  return av_rescale_q(stime, MF_TIMEBASE, mf_get_tb(avctx));
140 }
141 
142 static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
143 {
144  LONGLONG pts;
145  HRESULT hr = IMFSample_GetSampleTime(sample, &pts);
146  if (FAILED(hr))
147  return AV_NOPTS_VALUE;
148  return mf_from_mf_time(avctx, pts);
149 }
150 
152 {
153  LONGLONG duration;
154  HRESULT hr = IMFSample_GetSampleDuration(sample, &duration);
155  if (FAILED(hr))
156  return 0;
157  return mf_from_mf_time(avctx, duration);
158 }
159 
160 static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
161 {
162  MFContext *c = avctx->priv_data;
163  HRESULT hr;
164  UINT32 sz;
165 
166  if (avctx->codec_id != AV_CODEC_ID_MP3 && avctx->codec_id != AV_CODEC_ID_AC3) {
167  hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
168  if (!FAILED(hr) && sz > 0) {
170  if (!avctx->extradata)
171  return AVERROR(ENOMEM);
172  avctx->extradata_size = sz;
173  hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->extradata, sz, NULL);
174  if (FAILED(hr))
175  return AVERROR_EXTERNAL;
176 
177  if (avctx->codec_id == AV_CODEC_ID_AAC && avctx->extradata_size >= 12) {
178  // Get rid of HEAACWAVEINFO (after wfx field, 12 bytes).
179  avctx->extradata_size = avctx->extradata_size - 12;
180  memmove(avctx->extradata, avctx->extradata + 12, avctx->extradata_size);
181  }
182  }
183  }
184 
185  // I don't know where it's documented that we need this. It happens with the
186  // MS mp3 encoder MFT. The idea for the workaround is taken from NAudio.
187  // (Certainly any lossy codec will have frames much smaller than 1 second.)
188  if (!c->out_info.cbSize && !c->out_stream_provides_samples) {
189  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
190  if (!FAILED(hr)) {
191  av_log(avctx, AV_LOG_VERBOSE, "MFT_OUTPUT_STREAM_INFO.cbSize set to 0, "
192  "assuming %d bytes instead.\n", (int)sz);
193  c->out_info.cbSize = sz;
194  }
195  }
196 
197  return 0;
198 }
199 
200 static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
201 {
202  HRESULT hr;
203  UINT32 sz;
204 
205  hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
206  if (!FAILED(hr) && sz > 0) {
207  uint8_t *extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
208  if (!extradata)
209  return AVERROR(ENOMEM);
210  hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz, NULL);
211  if (FAILED(hr)) {
212  av_free(extradata);
213  return AVERROR_EXTERNAL;
214  }
215  av_freep(&avctx->extradata);
216  avctx->extradata = extradata;
217  avctx->extradata_size = sz;
218  }
219 
220  return 0;
221 }
222 
224 {
225  MFContext *c = avctx->priv_data;
226  HRESULT hr;
227  IMFMediaType *type;
228  int ret;
229 
230  hr = IMFTransform_GetOutputCurrentType(c->mft, c->out_stream_id, &type);
231  if (FAILED(hr)) {
232  av_log(avctx, AV_LOG_ERROR, "could not get output type\n");
233  return AVERROR_EXTERNAL;
234  }
235 
236  av_log(avctx, AV_LOG_VERBOSE, "final output type:\n");
237  ff_media_type_dump(avctx, type);
238 
239  ret = 0;
240  if (c->is_video) {
241  ret = mf_encv_output_type_get(avctx, type);
242  } else if (c->is_audio) {
243  ret = mf_enca_output_type_get(avctx, type);
244  }
245 
246  if (ret < 0)
247  av_log(avctx, AV_LOG_ERROR, "output type not supported\n");
248 
249  IMFMediaType_Release(type);
250  return ret;
251 }
252 
253 static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
254 {
255  MFContext *c = avctx->priv_data;
256  HRESULT hr;
257  int ret;
258  DWORD len;
259  IMFMediaBuffer *buffer;
260  BYTE *data;
261  UINT64 t;
262  UINT32 t32;
263 
264  hr = IMFSample_GetTotalLength(sample, &len);
265  if (FAILED(hr))
266  return AVERROR_EXTERNAL;
267 
268  if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0)
269  return ret;
270 
271  hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
272  if (FAILED(hr))
273  return AVERROR_EXTERNAL;
274 
275  hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
276  if (FAILED(hr)) {
277  IMFMediaBuffer_Release(buffer);
278  return AVERROR_EXTERNAL;
279  }
280 
281  memcpy(avpkt->data, data, len);
282 
283  IMFMediaBuffer_Unlock(buffer);
284  IMFMediaBuffer_Release(buffer);
285 
286  avpkt->pts = avpkt->dts = mf_sample_get_pts(avctx, sample);
287  avpkt->duration = mf_sample_get_duration(avctx, sample);
288 
289  hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
290  if (c->is_audio || (!FAILED(hr) && t32 != 0))
291  avpkt->flags |= AV_PKT_FLAG_KEY;
292 
293  hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
294  if (!FAILED(hr)) {
295  avpkt->dts = mf_from_mf_time(avctx, t);
296  // At least on Qualcomm's HEVC encoder on SD 835, the output dts
297  // starts from the input pts of the first frame, while the output pts
298  // is shifted forward. Therefore, shift the output values back so that
299  // the output pts matches the input.
300  if (c->reorder_delay == AV_NOPTS_VALUE)
301  c->reorder_delay = avpkt->pts - avpkt->dts;
302  avpkt->dts -= c->reorder_delay;
303  avpkt->pts -= c->reorder_delay;
304  }
305 
306  return 0;
307 }
308 
309 static int mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
310 {
311  MFContext *c = avctx->priv_data;
312  size_t len;
313  size_t bps;
314  IMFSample *sample;
315 
317  len = frame->nb_samples * bps;
318 
319  sample = ff_create_memory_sample(&c->functions, frame->data[0], len,
320  c->in_info.cbAlignment);
321  if (!sample)
322  return AVERROR(ENOMEM);
323 
324  IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->nb_samples));
325 
326  *out_sample = sample;
327  return 0;
328 }
329 
331 {
332  MFContext *c = avctx->priv_data;
333  MFFunctions *func = &c->functions;
334  HRESULT hr;
335 
336  hr = func->MFCreateDXGIDeviceManager(&c->resetToken, &c->dxgiManager);
337  if (FAILED(hr)) {
338  av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI device manager: %s\n", ff_hr_str(hr));
339  return AVERROR_EXTERNAL;
340  }
341 
342  hr = IMFDXGIDeviceManager_ResetDevice(c->dxgiManager, (IUnknown*)c->device_hwctx->device, c->resetToken);
343  if (FAILED(hr)) {
344  av_log(avctx, AV_LOG_ERROR, "Failed to reset device: %s\n", ff_hr_str(hr));
345  return AVERROR_EXTERNAL;
346  }
347 
348  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)c->dxgiManager);
349  if (FAILED(hr)) {
350  av_log(avctx, AV_LOG_ERROR, "Failed to set D3D manager: %s\n", ff_hr_str(hr));
351  return AVERROR_EXTERNAL;
352  }
353 
354  return 0;
355 }
356 
357 static int process_d3d11_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
358 {
359  MFContext *c = avctx->priv_data;
360  MFFunctions *func = &c->functions;
361  AVHWFramesContext *frames_ctx = NULL;
362  ID3D11Texture2D *d3d11_texture = NULL;
363  IMFSample *sample = NULL;
364  IMFMediaBuffer *buffer = NULL;
365  int subIdx = 0;
366  HRESULT hr;
367 
368  frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
369  c->device_hwctx = (AVD3D11VADeviceContext*)frames_ctx->device_ctx->hwctx;
370 
371  if (!c->dxgiManager) {
372  hr = initialize_dxgi_manager(avctx);
373  if (FAILED(hr)) {
374  return AVERROR_EXTERNAL;
375  }
376  }
377 
378  d3d11_texture = (ID3D11Texture2D*)frame->data[0];
379  subIdx = (int)(intptr_t)frame->data[1];
380 
381  if (!d3d11_texture) {
382  av_log(avctx, AV_LOG_ERROR, "D3D11 texture not found\n");
383  return AVERROR(EINVAL);
384  }
385 
386  hr = func->MFCreateSample(&sample);
387  if (FAILED(hr)) {
388  av_log(avctx, AV_LOG_ERROR, "Failed to create MF sample: %s\n", ff_hr_str(hr));
389  return AVERROR_EXTERNAL;
390  }
391 
392  hr = func->MFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown*)d3d11_texture, subIdx, 0, &buffer);
393  if (FAILED(hr)) {
394  av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI surface buffer: %s\n", ff_hr_str(hr));
395  IMFSample_Release(sample);
396  return AVERROR_EXTERNAL;
397  }
398 
399  hr = IMFSample_AddBuffer(sample, buffer);
400  if (FAILED(hr)) {
401  av_log(avctx, AV_LOG_ERROR, "Failed to add buffer to sample: %s\n", ff_hr_str(hr));
402  IMFMediaBuffer_Release(buffer);
403  IMFSample_Release(sample);
404  return AVERROR_EXTERNAL;
405  }
406 
407  IMFMediaBuffer_Release(buffer);
408 
409  *out_sample = sample;
410  return 0;
411 }
412 
413 static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
414 {
415  MFContext *c = avctx->priv_data;
416  IMFSample *sample = NULL;
417  IMFMediaBuffer *buffer = NULL;
418  BYTE *data = NULL;
419  HRESULT hr;
420  int size, ret;
421 
422  size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
423  if (size < 0)
424  return size;
425 
426  sample = ff_create_memory_sample(&c->functions, NULL, size,
427  c->in_info.cbAlignment);
428  if (!sample)
429  return AVERROR_EXTERNAL;
430 
431  hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
432  if (FAILED(hr)) {
433  IMFSample_Release(sample);
434  return AVERROR_EXTERNAL;
435  }
436 
437  hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
438  if (FAILED(hr)) {
439  IMFMediaBuffer_Release(buffer);
440  IMFSample_Release(sample);
441  return AVERROR_EXTERNAL;
442  }
443 
444  ret = av_image_copy_to_buffer((uint8_t *)data, size, (void *)frame->data, frame->linesize,
445  avctx->pix_fmt, avctx->width, avctx->height, 1);
446  IMFMediaBuffer_SetCurrentLength(buffer, size);
447  IMFMediaBuffer_Unlock(buffer);
448  IMFMediaBuffer_Release(buffer);
449  if (ret < 0) {
450  IMFSample_Release(sample);
451  return ret;
452  }
453 
454  IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration));
455  *out_sample = sample;
456 
457  return 0;
458 }
459 
460 static int mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
461 {
462  IMFSample *sample = NULL;
463  HRESULT hr;
464  int ret;
465 
466  if (frame->format == AV_PIX_FMT_D3D11) {
467  // Handle D3D11 hardware frames
468  ret = process_d3d11_frame(avctx, frame, &sample);
469  if (ret < 0) {
470  return ret;
471  }
472  } else {
473  // Handle software frames
475  if (ret < 0) {
476  return ret;
477  }
478  }
479 
480  // Set sample duration
481  hr = IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration));
482  if (FAILED(hr)) {
483  av_log(avctx, AV_LOG_WARNING, "Failed to set sample duration: %s\n", ff_hr_str(hr));
484  }
485 
486  *out_sample = sample;
487  return 0;
488 }
489 
490 static int mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
491 {
492  MFContext *c = avctx->priv_data;
493  IMFSample *sample;
494  int ret;
495 
496  if (c->is_audio) {
498  } else {
500  }
501 
502  if (ret < 0)
503  return ret;
504 
505  mf_sample_set_pts(avctx, sample, frame->pts);
506  *out_sample = sample;
507  return 0;
508 }
509 
510 static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
511 {
512  MFContext *c = avctx->priv_data;
513  HRESULT hr;
514  int ret;
515 
516  if (sample) {
517  if (c->async_events) {
518  if ((ret = mf_wait_events(avctx)) < 0)
519  return ret;
520  if (!c->async_need_input)
521  return AVERROR(EAGAIN);
522  }
523  if (!c->sample_sent)
524  IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
525  c->sample_sent = 1;
526  hr = IMFTransform_ProcessInput(c->mft, c->in_stream_id, sample, 0);
527  if (hr == MF_E_NOTACCEPTING) {
528  return AVERROR(EAGAIN);
529  } else if (FAILED(hr)) {
530  av_log(avctx, AV_LOG_ERROR, "failed processing input: %s\n", ff_hr_str(hr));
531  return AVERROR_EXTERNAL;
532  }
533  c->async_need_input = 0;
534  } else if (!c->draining) {
535  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
536  if (FAILED(hr))
537  av_log(avctx, AV_LOG_ERROR, "failed draining: %s\n", ff_hr_str(hr));
538  // Some MFTs (AC3) will send a frame after each drain command (???), so
539  // this is required to make draining actually terminate.
540  c->draining = 1;
541  c->async_need_input = 0;
542  } else {
543  return AVERROR_EOF;
544  }
545  return 0;
546 }
547 
548 static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
549 {
550  MFContext *c = avctx->priv_data;
551  HRESULT hr;
552  DWORD st;
553  MFT_OUTPUT_DATA_BUFFER out_buffers;
554  IMFSample *sample;
555  int ret = 0;
556 
557  while (1) {
558  *out_sample = NULL;
559  sample = NULL;
560 
561  if (c->async_events) {
562  if ((ret = mf_wait_events(avctx)) < 0)
563  return ret;
564  if (!c->async_have_output || c->draining_done) {
565  ret = 0;
566  break;
567  }
568  }
569 
570  if (!c->out_stream_provides_samples) {
571  sample = ff_create_memory_sample(&c->functions, NULL,
572  c->out_info.cbSize,
573  c->out_info.cbAlignment);
574  if (!sample)
575  return AVERROR(ENOMEM);
576  }
577 
578  out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
579  .dwStreamID = c->out_stream_id,
580  .pSample = sample,
581  };
582 
583  st = 0;
584  hr = IMFTransform_ProcessOutput(c->mft, 0, 1, &out_buffers, &st);
585 
586  if (out_buffers.pEvents)
587  IMFCollection_Release(out_buffers.pEvents);
588 
589  if (!FAILED(hr)) {
590  *out_sample = out_buffers.pSample;
591  ret = 0;
592  break;
593  }
594 
595  if (out_buffers.pSample)
596  IMFSample_Release(out_buffers.pSample);
597 
598  if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
599  if (c->draining)
600  c->draining_done = 1;
601  ret = 0;
602  } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
603  av_log(avctx, AV_LOG_WARNING, "stream format change\n");
604  ret = mf_choose_output_type(avctx);
605  if (ret == 0) // we don't expect renegotiating the input type
607  if (ret > 0) {
608  ret = mf_setup_context(avctx);
609  if (ret >= 0) {
610  c->async_have_output = 0;
611  continue;
612  }
613  }
614  } else {
615  av_log(avctx, AV_LOG_ERROR, "failed processing output: %s\n", ff_hr_str(hr));
617  }
618 
619  break;
620  }
621 
622  c->async_have_output = 0;
623 
624  if (ret >= 0 && !*out_sample)
625  ret = c->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
626 
627  return ret;
628 }
629 
630 static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
631 {
632  MFContext *c = avctx->priv_data;
633  IMFSample *sample = NULL;
634  int ret;
635 
636  if (!c->frame->buf[0]) {
637  ret = ff_encode_get_frame(avctx, c->frame);
638  if (ret < 0 && ret != AVERROR_EOF)
639  return ret;
640  }
641 
642  if (c->frame->buf[0]) {
643  ret = mf_avframe_to_sample(avctx, c->frame, &sample);
644  if (ret < 0) {
645  av_frame_unref(c->frame);
646  return ret;
647  }
648  if (c->is_video && c->codec_api) {
649  if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
650  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
651  }
652  }
653 
654  if(!c->stream_started)
655  {
656  HRESULT hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
657  if (FAILED(hr)) {
658  av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr));
659  return AVERROR(EBADMSG);
660  }
661 
662  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
663  if (FAILED(hr)) {
664  av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr));
665  return AVERROR(EBADMSG);
666  }
667 
668  c->stream_started = 1;
669  }
670 
671  ret = mf_send_sample(avctx, sample);
672  if (sample)
673  IMFSample_Release(sample);
674  if (ret != AVERROR(EAGAIN))
675  av_frame_unref(c->frame);
676  if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
677  return ret;
678 
679  ret = mf_receive_sample(avctx, &sample);
680  if (ret < 0)
681  return ret;
682 
683  ret = mf_sample_to_avpacket(avctx, sample, avpkt);
684  IMFSample_Release(sample);
685 
686  return ret;
687 }
688 
689 // Most encoders seem to enumerate supported audio formats on the output types,
690 // at least as far as channel configuration and sample rate is concerned. Pick
691 // the one which seems to match best.
692 static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
693 {
694  MFContext *c = avctx->priv_data;
695  HRESULT hr;
696  UINT32 t;
697  GUID tg;
698  int64_t score = 0;
699 
700  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
701  if (!FAILED(hr) && t == avctx->sample_rate)
702  score |= 1LL << 32;
703 
704  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
705  if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
706  score |= 2LL << 32;
707 
708  hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
709  if (!FAILED(hr)) {
710  if (IsEqualGUID(&c->main_subtype, &tg))
711  score |= 4LL << 32;
712  }
713 
714  // Select the bitrate (lowest priority).
715  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
716  if (!FAILED(hr)) {
717  int diff = (int)t - avctx->bit_rate / 8;
718  if (diff >= 0) {
719  score |= (1LL << 31) - diff; // prefer lower bitrate
720  } else {
721  score |= (1LL << 30) + diff; // prefer higher bitrate
722  }
723  }
724 
725  hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
726  if (!FAILED(hr) && t != 0)
727  return -1;
728 
729  return score;
730 }
731 
732 static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
733 {
734  // (some decoders allow adjusting this freely, but it can also cause failure
735  // to set the output type - so it's commented for being too fragile)
736  //IMFAttributes_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avctx->bit_rate / 8);
737  //IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
738 
739  return 0;
740 }
741 
742 static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
743 {
744  HRESULT hr;
745  UINT32 t;
746  int64_t score = 0;
747 
748  enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
749  if (sformat == AV_SAMPLE_FMT_NONE)
750  return -1; // can not use
751 
752  if (sformat == avctx->sample_fmt)
753  score |= 1;
754 
755  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
756  if (!FAILED(hr) && t == avctx->sample_rate)
757  score |= 2;
758 
759  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
760  if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
761  score |= 4;
762 
763  return score;
764 }
765 
766 static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
767 {
768  HRESULT hr;
769  UINT32 t;
770 
771  enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
772  if (sformat != avctx->sample_fmt) {
773  av_log(avctx, AV_LOG_ERROR, "unsupported input sample format set\n");
774  return AVERROR(EINVAL);
775  }
776 
777  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
778  if (FAILED(hr) || t != avctx->sample_rate) {
779  av_log(avctx, AV_LOG_ERROR, "unsupported input sample rate set\n");
780  return AVERROR(EINVAL);
781  }
782 
783  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
784  if (FAILED(hr) || t != avctx->ch_layout.nb_channels) {
785  av_log(avctx, AV_LOG_ERROR, "unsupported input channel number set\n");
786  return AVERROR(EINVAL);
787  }
788 
789  return 0;
790 }
791 
792 static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
793 {
794  MFContext *c = avctx->priv_data;
795  GUID tg;
796  HRESULT hr;
797  int score = -1;
798 
799  hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
800  if (!FAILED(hr)) {
801  if (IsEqualGUID(&c->main_subtype, &tg))
802  score = 1;
803  }
804 
805  return score;
806 }
807 
808 static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
809 {
810  MFContext *c = avctx->priv_data;
812 
813  ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
814  IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
815 
816  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
817  framerate = avctx->framerate;
818  } else {
819  framerate = av_inv_q(avctx->time_base);
820  }
821 
822  ff_MFSetAttributeRatio((IMFAttributes *)type, &MF_MT_FRAME_RATE, framerate.num, framerate.den);
823 
824  // (MS HEVC supports eAVEncH265VProfile_Main_420_8 only.)
825  if (avctx->codec_id == AV_CODEC_ID_H264) {
827  switch (avctx->profile) {
830  break;
833  break;
834  }
835  IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
836  }
837 
838  IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
839 
840  // Note that some of the ICodecAPI options must be set before SetOutputType.
841  if (c->codec_api) {
842  if (avctx->bit_rate)
843  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMeanBitRate, FF_VAL_VT_UI4(avctx->bit_rate));
844 
845  if (c->opt_enc_rc >= 0)
846  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonRateControlMode, FF_VAL_VT_UI4(c->opt_enc_rc));
847 
848  if (c->opt_enc_quality >= 0)
849  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQuality, FF_VAL_VT_UI4(c->opt_enc_quality));
850 
851  if (avctx->rc_max_rate > 0)
852  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMaxBitRate, FF_VAL_VT_UI4(avctx->rc_max_rate));
853 
854  if (avctx->gop_size > 0)
855  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVGOPSize, FF_VAL_VT_UI4(avctx->gop_size));
856 
857  if(avctx->rc_buffer_size > 0)
858  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonBufferSize, FF_VAL_VT_UI4(avctx->rc_buffer_size));
859 
860  if(avctx->compression_level >= 0)
861  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQualityVsSpeed, FF_VAL_VT_UI4(avctx->compression_level));
862 
863  if(avctx->global_quality > 0)
864  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoEncodeQP, FF_VAL_VT_UI4(avctx->global_quality ));
865 
866  // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
867  // defaults this to 1, and that setting is buggy with many of the
868  // rate control modes. (0 or 2 b-frames works fine with most rate
869  // control modes, but 2 seems buggy with the u_vbr mode.) Setting
870  // "scenario" to "camera_record" sets it in CFR mode (where the default
871  // is VFR), which makes the encoder avoid dropping frames.
872  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVDefaultBPictureCount, FF_VAL_VT_UI4(avctx->max_b_frames));
873  avctx->has_b_frames = avctx->max_b_frames > 0;
874 
875  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncH264CABACEnable, FF_VAL_VT_BOOL(1));
876 
877  if (c->opt_enc_scenario >= 0)
878  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVScenarioInfo, FF_VAL_VT_UI4(c->opt_enc_scenario));
879  }
880 
881  return 0;
882 }
883 
884 static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
885 {
886  enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
887 
888  if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
889  if (pix_fmt != AV_PIX_FMT_NV12) {
890  return -1; // can not use
891  }
892  }
893  else {
894  if (pix_fmt != avctx->pix_fmt)
895  return -1; // can not use
896  }
897 
898  return 0;
899 }
900 
901 static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
902 {
903  enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
904  if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
906  av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
907  return AVERROR(EINVAL);
908  }
909  } else {
910  if (pix_fmt != avctx->pix_fmt) {
911  av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
912  return AVERROR(EINVAL);
913  }
914  }
915 
916  //ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
917 
918  return 0;
919 }
920 
922 {
923  MFContext *c = avctx->priv_data;
924  HRESULT hr;
925  int ret;
926  IMFMediaType *out_type = NULL;
927  int64_t out_type_score = -1;
928  int out_type_index = -1;
929  int n;
930 
931  av_log(avctx, AV_LOG_VERBOSE, "output types:\n");
932  for (n = 0; ; n++) {
933  IMFMediaType *type;
934  int64_t score = -1;
935 
936  hr = IMFTransform_GetOutputAvailableType(c->mft, c->out_stream_id, n, &type);
937  if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
938  break;
939  if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
940  av_log(avctx, AV_LOG_VERBOSE, "(need to set input type)\n");
941  ret = 0;
942  goto done;
943  }
944  if (FAILED(hr)) {
945  av_log(avctx, AV_LOG_ERROR, "error getting output type: %s\n", ff_hr_str(hr));
947  goto done;
948  }
949 
950  av_log(avctx, AV_LOG_VERBOSE, "output type %d:\n", n);
951  ff_media_type_dump(avctx, type);
952 
953  if (c->is_video) {
954  score = mf_encv_output_score(avctx, type);
955  } else if (c->is_audio) {
956  score = mf_enca_output_score(avctx, type);
957  }
958 
959  if (score > out_type_score) {
960  if (out_type)
961  IMFMediaType_Release(out_type);
962  out_type = type;
963  out_type_score = score;
964  out_type_index = n;
965  IMFMediaType_AddRef(out_type);
966  }
967 
968  IMFMediaType_Release(type);
969  }
970 
971  if (out_type) {
972  av_log(avctx, AV_LOG_VERBOSE, "picking output type %d.\n", out_type_index);
973  } else {
974  hr = c->functions.MFCreateMediaType(&out_type);
975  if (FAILED(hr)) {
976  ret = AVERROR(ENOMEM);
977  goto done;
978  }
979  }
980 
981  ret = 0;
982  if (c->is_video) {
983  ret = mf_encv_output_adjust(avctx, out_type);
984  } else if (c->is_audio) {
985  ret = mf_enca_output_adjust(avctx, out_type);
986  }
987 
988  if (ret >= 0) {
989  av_log(avctx, AV_LOG_VERBOSE, "setting output type:\n");
990  ff_media_type_dump(avctx, out_type);
991 
992  hr = IMFTransform_SetOutputType(c->mft, c->out_stream_id, out_type, 0);
993  if (!FAILED(hr)) {
994  ret = 1;
995  } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
996  av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set input type\n");
997  ret = 0;
998  } else {
999  av_log(avctx, AV_LOG_ERROR, "could not set output type (%s)\n", ff_hr_str(hr));
1001  }
1002  }
1003 
1004 done:
1005  if (out_type)
1006  IMFMediaType_Release(out_type);
1007  return ret;
1008 }
1009 
1011 {
1012  MFContext *c = avctx->priv_data;
1013  HRESULT hr;
1014  int ret;
1015  IMFMediaType *in_type = NULL;
1016  int64_t in_type_score = -1;
1017  int in_type_index = -1;
1018  int n;
1019 
1020  av_log(avctx, AV_LOG_VERBOSE, "input types:\n");
1021  for (n = 0; ; n++) {
1022  IMFMediaType *type = NULL;
1023  int64_t score = -1;
1024 
1025  hr = IMFTransform_GetInputAvailableType(c->mft, c->in_stream_id, n, &type);
1026  if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
1027  break;
1028  if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
1029  av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 1)\n");
1030  ret = 0;
1031  goto done;
1032  }
1033  if (FAILED(hr)) {
1034  av_log(avctx, AV_LOG_ERROR, "error getting input type: %s\n", ff_hr_str(hr));
1036  goto done;
1037  }
1038 
1039  av_log(avctx, AV_LOG_VERBOSE, "input type %d:\n", n);
1040  ff_media_type_dump(avctx, type);
1041 
1042  if (c->is_video) {
1043  score = mf_encv_input_score(avctx, type);
1044  } else if (c->is_audio) {
1045  score = mf_enca_input_score(avctx, type);
1046  }
1047 
1048  if (score > in_type_score) {
1049  if (in_type)
1050  IMFMediaType_Release(in_type);
1051  in_type = type;
1052  in_type_score = score;
1053  in_type_index = n;
1054  IMFMediaType_AddRef(in_type);
1055  }
1056 
1057  IMFMediaType_Release(type);
1058  }
1059 
1060  if (in_type) {
1061  av_log(avctx, AV_LOG_VERBOSE, "picking input type %d.\n", in_type_index);
1062  } else {
1063  // Some buggy MFTs (WMA encoder) fail to return MF_E_TRANSFORM_TYPE_NOT_SET.
1064  av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 2)\n");
1065  ret = 0;
1066  goto done;
1067  }
1068 
1069  ret = 0;
1070  if (c->is_video) {
1071  ret = mf_encv_input_adjust(avctx, in_type);
1072  } else if (c->is_audio) {
1073  ret = mf_enca_input_adjust(avctx, in_type);
1074  }
1075 
1076  if (ret >= 0) {
1077  av_log(avctx, AV_LOG_VERBOSE, "setting input type:\n");
1078  ff_media_type_dump(avctx, in_type);
1079 
1080  hr = IMFTransform_SetInputType(c->mft, c->in_stream_id, in_type, 0);
1081  if (!FAILED(hr)) {
1082  ret = 1;
1083  } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
1084  av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set output type\n");
1085  ret = 0;
1086  } else {
1087  av_log(avctx, AV_LOG_ERROR, "could not set input type (%s)\n", ff_hr_str(hr));
1089  }
1090  }
1091 
1092 done:
1093  if (in_type)
1094  IMFMediaType_Release(in_type);
1095  return ret;
1096 }
1097 
1099 {
1100  // This follows steps 1-5 on:
1101  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa965264(v=vs.85).aspx
1102  // If every MFT implementer does this correctly, this loop should at worst
1103  // be repeated once.
1104  int need_input = 1, need_output = 1;
1105  int n;
1106  for (n = 0; n < 2 && (need_input || need_output); n++) {
1107  int ret;
1108  ret = mf_choose_input_type(avctx);
1109  if (ret < 0)
1110  return ret;
1111  need_input = ret < 1;
1112  ret = mf_choose_output_type(avctx);
1113  if (ret < 0)
1114  return ret;
1115  need_output = ret < 1;
1116  }
1117  if (need_input || need_output) {
1118  av_log(avctx, AV_LOG_ERROR, "format negotiation failed (%d/%d)\n",
1119  need_input, need_output);
1120  return AVERROR_EXTERNAL;
1121  }
1122  return 0;
1123 }
1124 
1126 {
1127  MFContext *c = avctx->priv_data;
1128  HRESULT hr;
1129  int ret;
1130 
1131  hr = IMFTransform_GetInputStreamInfo(c->mft, c->in_stream_id, &c->in_info);
1132  if (FAILED(hr))
1133  return AVERROR_EXTERNAL;
1134  av_log(avctx, AV_LOG_VERBOSE, "in_info: size=%d, align=%d\n",
1135  (int)c->in_info.cbSize, (int)c->in_info.cbAlignment);
1136 
1137  hr = IMFTransform_GetOutputStreamInfo(c->mft, c->out_stream_id, &c->out_info);
1138  if (FAILED(hr))
1139  return AVERROR_EXTERNAL;
1140  c->out_stream_provides_samples =
1141  (c->out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
1142  (c->out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
1143  av_log(avctx, AV_LOG_VERBOSE, "out_info: size=%d, align=%d%s\n",
1144  (int)c->out_info.cbSize, (int)c->out_info.cbAlignment,
1145  c->out_stream_provides_samples ? " (provides samples)" : "");
1146 
1147  if ((ret = mf_output_type_get(avctx)) < 0)
1148  return ret;
1149 
1150  return 0;
1151 }
1152 
1154 {
1155  MFContext *c = avctx->priv_data;
1156  HRESULT hr;
1157  IMFAttributes *attrs;
1158  UINT32 v;
1159  int res = AVERROR_EXTERNAL;
1160 
1161  // For hw encoding we unfortunately need to use async mode, otherwise
1162  // play it safe and avoid it.
1163  if (!(c->is_video && c->opt_enc_hw))
1164  return 0;
1165 
1166  hr = IMFTransform_GetAttributes(c->mft, &attrs);
1167  if (FAILED(hr)) {
1168  av_log(avctx, AV_LOG_ERROR, "error retrieving MFT attributes: %s\n", ff_hr_str(hr));
1169  goto err;
1170  }
1171 
1172  hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
1173  if (FAILED(hr)) {
1174  av_log(avctx, AV_LOG_ERROR, "error querying async: %s\n", ff_hr_str(hr));
1175  goto err;
1176  }
1177 
1178  if (!v) {
1179  av_log(avctx, AV_LOG_ERROR, "hardware MFT is not async\n");
1180  goto err;
1181  }
1182 
1183  hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
1184  if (FAILED(hr)) {
1185  av_log(avctx, AV_LOG_ERROR, "could not set async unlock: %s\n", ff_hr_str(hr));
1186  goto err;
1187  }
1188 
1189  hr = IMFTransform_QueryInterface(c->mft, &IID_IMFMediaEventGenerator, (void **)&c->async_events);
1190  if (FAILED(hr)) {
1191  av_log(avctx, AV_LOG_ERROR, "could not get async interface\n");
1192  goto err;
1193  }
1194 
1195  res = 0;
1196 
1197 err:
1198  IMFAttributes_Release(attrs);
1199  return res;
1200 }
1201 
1202 static int mf_create(void *log, MFFunctions *f, IMFTransform **mft,
1203  const AVCodec *codec, int use_hw)
1204 {
1205  int is_audio = codec->type == AVMEDIA_TYPE_AUDIO;
1206  const CLSID *subtype = ff_codec_to_mf_subtype(codec->id);
1207  MFT_REGISTER_TYPE_INFO reg = {0};
1208  GUID category;
1209  int ret;
1210 
1211  *mft = NULL;
1212 
1213  if (!subtype)
1214  return AVERROR(ENOSYS);
1215 
1216  reg.guidSubtype = *subtype;
1217 
1218  if (is_audio) {
1219  reg.guidMajorType = MFMediaType_Audio;
1220  category = MFT_CATEGORY_AUDIO_ENCODER;
1221  } else {
1222  reg.guidMajorType = MFMediaType_Video;
1223  category = MFT_CATEGORY_VIDEO_ENCODER;
1224  }
1225 
1226  if ((ret = ff_instantiate_mf(log, f, category, NULL, &reg, use_hw, mft)) < 0)
1227  return ret;
1228 
1229  return 0;
1230 }
1231 
1233 {
1234  MFContext *c = avctx->priv_data;
1235  HRESULT hr;
1236  int ret;
1237  const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id);
1238  int use_hw = 0;
1239 
1240  c->frame = av_frame_alloc();
1241  if (!c->frame)
1242  return AVERROR(ENOMEM);
1243 
1244  c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO;
1245  c->is_video = !c->is_audio;
1246  c->reorder_delay = AV_NOPTS_VALUE;
1247 
1248  if (c->is_video && c->opt_enc_hw)
1249  use_hw = 1;
1250 
1251  if (!subtype)
1252  return AVERROR(ENOSYS);
1253 
1254  c->main_subtype = *subtype;
1255 
1256  if ((ret = mf_create(avctx, &c->functions, &c->mft, avctx->codec, use_hw)) < 0)
1257  return ret;
1258 
1259  if ((ret = mf_unlock_async(avctx)) < 0)
1260  return ret;
1261 
1262  hr = IMFTransform_QueryInterface(c->mft, &IID_ICodecAPI, (void **)&c->codec_api);
1263  if (!FAILED(hr))
1264  av_log(avctx, AV_LOG_VERBOSE, "MFT supports ICodecAPI.\n");
1265 
1266 
1267  hr = IMFTransform_GetStreamIDs(c->mft, 1, &c->in_stream_id, 1, &c->out_stream_id);
1268  if (hr == E_NOTIMPL) {
1269  c->in_stream_id = c->out_stream_id = 0;
1270  } else if (FAILED(hr)) {
1271  av_log(avctx, AV_LOG_ERROR, "could not get stream IDs (%s)\n", ff_hr_str(hr));
1272  return AVERROR_EXTERNAL;
1273  }
1274 
1275  if ((ret = mf_negotiate_types(avctx)) < 0)
1276  return ret;
1277 
1278  if ((ret = mf_setup_context(avctx)) < 0)
1279  return ret;
1280 
1281  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER && c->async_events &&
1282  c->is_video && !avctx->extradata) {
1283  int sleep = 10000, total = 0;
1284  av_log(avctx, AV_LOG_VERBOSE, "Awaiting extradata\n");
1285  while (total < 70*1000) {
1286  // The Qualcomm H264 encoder on SD835 doesn't provide extradata
1287  // immediately, but it becomes available soon after init (without
1288  // any waitable event). In practice, it's available after less
1289  // than 10 ms, but wait for up to 70 ms before giving up.
1290  // Some encoders (Qualcomm's HEVC encoder on SD835, some versions
1291  // of the QSV H264 encoder at least) don't provide extradata this
1292  // way at all, not even after encoding a frame - it's only
1293  // available prepended to frames.
1294  av_usleep(sleep);
1295  total += sleep;
1296  mf_output_type_get(avctx);
1297  if (avctx->extradata)
1298  break;
1299  sleep *= 2;
1300  }
1301  av_log(avctx, AV_LOG_VERBOSE, "%s extradata in %d ms\n",
1302  avctx->extradata ? "Got" : "Didn't get", total / 1000);
1303  }
1304 
1305  return 0;
1306 }
1307 
1308 #if !HAVE_UWP
1309 #define LOAD_MF_FUNCTION(context, func_name) \
1310  context->functions.func_name = (void *)dlsym(context->library, #func_name); \
1311  if (!context->functions.func_name) { \
1312  av_log(context, AV_LOG_ERROR, "DLL mfplat.dll failed to find function "\
1313  #func_name "\n"); \
1314  return AVERROR_UNKNOWN; \
1315  }
1316 #else
1317 // In UWP (which lacks LoadLibrary), just link directly against
1318 // the functions - this requires building with new/complete enough
1319 // import libraries.
1320 #define LOAD_MF_FUNCTION(context, func_name) \
1321  context->functions.func_name = func_name; \
1322  if (!context->functions.func_name) { \
1323  av_log(context, AV_LOG_ERROR, "Failed to find function " #func_name \
1324  "\n"); \
1325  return AVERROR_UNKNOWN; \
1326  }
1327 #endif
1328 
1329 // Windows N editions does not provide MediaFoundation by default.
1330 // So to avoid DLL loading error, MediaFoundation is dynamically loaded except
1331 // on UWP build since LoadLibrary is not available on it.
1333 {
1334  MFContext *c = avctx->priv_data;
1335 
1336 #if !HAVE_UWP
1337  c->library = dlopen("mfplat.dll", 0);
1338  c->d3d_dll = dlopen("D3D11.dll", 0);
1339 
1340  if (!c->library) {
1341  av_log(c, AV_LOG_ERROR, "DLL mfplat.dll failed to open\n");
1342  return AVERROR_UNKNOWN;
1343  }
1344 #endif
1345 
1346  LOAD_MF_FUNCTION(c, MFStartup);
1347  LOAD_MF_FUNCTION(c, MFShutdown);
1348  LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer);
1349  LOAD_MF_FUNCTION(c, MFCreateSample);
1350  LOAD_MF_FUNCTION(c, MFCreateMediaType);
1351  LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer);
1352  LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager);
1353  // MFTEnumEx is missing in Windows Vista's mfplat.dll.
1354  LOAD_MF_FUNCTION(c, MFTEnumEx);
1355 
1356  return 0;
1357 }
1358 
1359 static int mf_close(AVCodecContext *avctx)
1360 {
1361  MFContext *c = avctx->priv_data;
1362 
1363  if (c->codec_api)
1364  ICodecAPI_Release(c->codec_api);
1365 
1366  if (c->async_events)
1367  IMFMediaEventGenerator_Release(c->async_events);
1368 
1369 #if !HAVE_UWP
1370  if (c->library)
1371  ff_free_mf(&c->functions, &c->mft);
1372 
1373  dlclose(c->library);
1374  dlclose(c->d3d_dll);
1375  c->library = NULL;
1376 #else
1377  ff_free_mf(&c->functions, &c->mft);
1378 #endif
1379 
1380  av_frame_free(&c->frame);
1381 
1382  av_freep(&avctx->extradata);
1383  avctx->extradata_size = 0;
1384 
1385  return 0;
1386 }
1387 
1388 static av_cold int mf_init(AVCodecContext *avctx)
1389 {
1390  int ret;
1391  if ((ret = mf_load_library(avctx)) == 0) {
1392  if ((ret = mf_init_encoder(avctx)) == 0) {
1393  return 0;
1394  }
1395  }
1396  return ret;
1397 }
1398 
1399 #define OFFSET(x) offsetof(MFContext, x)
1400 
1401 #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS) \
1402  static const AVClass ff_ ## NAME ## _mf_encoder_class = { \
1403  .class_name = #NAME "_mf", \
1404  .item_name = av_default_item_name, \
1405  .option = OPTS, \
1406  .version = LIBAVUTIL_VERSION_INT, \
1407  }; \
1408  const FFCodec ff_ ## NAME ## _mf_encoder = { \
1409  .p.priv_class = &ff_ ## NAME ## _mf_encoder_class, \
1410  .p.name = #NAME "_mf", \
1411  CODEC_LONG_NAME(#ID " via MediaFoundation"), \
1412  .p.type = AVMEDIA_TYPE_ ## MEDIATYPE, \
1413  .p.id = AV_CODEC_ID_ ## ID, \
1414  .priv_data_size = sizeof(MFContext), \
1415  .init = mf_init, \
1416  .close = mf_close, \
1417  FF_CODEC_RECEIVE_PACKET_CB(mf_receive_packet), \
1418  FMTS \
1419  CAPS \
1420  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
1421  .defaults = DEFAULTS, \
1422  };
1423 
1424 #define AFMTS \
1425  CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
1426 #define ACAPS \
1427  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
1428  AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
1429 
1430 MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL);
1431 MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL);
1432 MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL);
1433 
1434 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1435 static const AVOption venc_opts[] = {
1436  {"rate_control", "Select rate control mode", OFFSET(opt_enc_rc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "rate_control"},
1437  { "default", "Default mode", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, .unit = "rate_control"},
1438  { "cbr", "CBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_CBR}, 0, 0, VE, .unit = "rate_control"},
1439  { "pc_vbr", "Peak constrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_PeakConstrainedVBR}, 0, 0, VE, .unit = "rate_control"},
1440  { "u_vbr", "Unconstrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_UnconstrainedVBR}, 0, 0, VE, .unit = "rate_control"},
1441  { "quality", "Quality mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_Quality}, 0, 0, VE, .unit = "rate_control" },
1442  // The following rate_control modes require Windows 8.
1443  { "ld_vbr", "Low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_LowDelayVBR}, 0, 0, VE, .unit = "rate_control"},
1444  { "g_vbr", "Global VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalVBR}, 0, 0, VE, .unit = "rate_control" },
1445  { "gld_vbr", "Global low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR}, 0, 0, VE, .unit = "rate_control"},
1446 
1447  {"scenario", "Select usage scenario", OFFSET(opt_enc_scenario), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "scenario"},
1448  { "default", "Default scenario", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, .unit = "scenario"},
1449  { "display_remoting", "Display remoting", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemoting}, 0, 0, VE, .unit = "scenario"},
1450  { "video_conference", "Video conference", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_VideoConference}, 0, 0, VE, .unit = "scenario"},
1451  { "archive", "Archive", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_Archive}, 0, 0, VE, .unit = "scenario"},
1452  { "live_streaming", "Live streaming", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_LiveStreaming}, 0, 0, VE, .unit = "scenario"},
1453  { "camera_record", "Camera record", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_CameraRecord}, 0, 0, VE, .unit = "scenario"},
1454  { "display_remoting_with_feature_map", "Display remoting with feature map", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap}, 0, 0, VE, .unit = "scenario"},
1455 
1456  {"quality", "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
1457  {"hw_encoding", "Force hardware encoding", OFFSET(opt_enc_hw), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE},
1458  {NULL}
1459 };
1460 
1461 static const FFCodecDefault defaults[] = {
1462  { "g", "0" },
1463  { NULL },
1464 };
1465 
1466 #define VFMTS \
1467  CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_D3D11),
1468 #define VCAPS \
1469  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
1470  AV_CODEC_CAP_DR1,
1471 
1472 MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS, VCAPS, defaults);
1473 MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS, VCAPS, defaults);
1474 MF_ENCODER(VIDEO, av1, AV1, venc_opts, VFMTS, VCAPS, defaults);
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
MFContext::resetToken
int resetToken
Definition: mfenc.c:44
AVCodec
AVCodec.
Definition: codec.h:172
process_d3d11_frame
static int process_d3d11_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:357
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
ff_hr_str
#define ff_hr_str(hr)
Definition: mf_utils.h:169
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
VCAPS
#define VCAPS
Definition: mfenc.c:1468
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:454
FF_VAL_VT_UI4
#define FF_VAL_VT_UI4(v)
Definition: mf_utils.h:174
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1024
venc_opts
static const AVOption venc_opts[]
Definition: mfenc.c:1435
mf_choose_input_type
static int mf_choose_input_type(AVCodecContext *avctx)
Definition: mfenc.c:1010
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
LOAD_MF_FUNCTION
#define LOAD_MF_FUNCTION(context, func_name)
Definition: mfenc.c:1309
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:112
int64_t
long long int64_t
Definition: coverity.c:34
normalize.log
log
Definition: normalize.py:21
ff_codec_to_mf_subtype
const CLSID * ff_codec_to_mf_subtype(enum AVCodecID codec)
Definition: mf_utils.c:508
mf_enca_output_score
static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:692
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
MFContext::opt_enc_hw
int opt_enc_hw
Definition: mfenc.c:66
MFContext::av_class
AVClass * av_class
Definition: mfenc.c:39
mf_receive_sample
static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
Definition: mfenc.c:548
MF_ENCODER
#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS)
Definition: mfenc.c:1401
mf_enca_output_type_get
static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:160
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:552
MFContext::sample_sent
int sample_sent
Definition: mfenc.c:57
ff_eAVEncCommonRateControlMode_Quality
@ ff_eAVEncCommonRateControlMode_Quality
Definition: mf_utils.h:131
ff_eAVEncCommonRateControlMode_CBR
@ ff_eAVEncCommonRateControlMode_CBR
Definition: mf_utils.h:128
AVOption
AVOption.
Definition: opt.h:429
encode.h
data
const char data[16]
Definition: mxf.c:149
mf_encv_output_score
static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:792
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
category
category
Definition: openal-dec.c:249
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:570
MFContext::draining_done
int draining_done
Definition: mfenc.c:56
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
ff_MFSetAttributeSize
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid, UINT32 uw, UINT32 uh)
Definition: mf_utils.c:40
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:607
MFContext::functions
MFFunctions functions
Definition: mfenc.c:46
ff_eAVEncH264VProfile_High
@ ff_eAVEncH264VProfile_High
Definition: mf_utils.h:165
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:318
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:551
MFContext::out_stream_id
DWORD out_stream_id
Definition: mfenc.c:52
MFContext::async_marker
int async_marker
Definition: mfenc.c:59
FFCodecDefault
Definition: codec_internal.h:96
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:440
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1039
ff_media_type_to_sample_fmt
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
Definition: mf_utils.c:114
MFContext::async_need_input
int async_need_input
Definition: mfenc.c:59
OFFSET
#define OFFSET(x)
Definition: mfenc.c:1399
mf_receive_packet
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Definition: mfenc.c:630
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
MFContext::is_audio
int is_audio
Definition: mfenc.c:48
mf_utils.h
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
VFMTS
#define VFMTS
Definition: mfenc.c:1466
pts
static int64_t pts
Definition: transcode_aac.c:644
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:452
ff_eAVEncCommonRateControlMode_GlobalVBR
@ ff_eAVEncCommonRateControlMode_GlobalVBR
Definition: mf_utils.h:133
AVRational::num
int num
Numerator.
Definition: rational.h:59
ff_instantiate_mf
int ff_instantiate_mf(void *log, MFFunctions *f, GUID category, MFT_REGISTER_TYPE_INFO *in_type, MFT_REGISTER_TYPE_INFO *out_type, int use_hw, IMFTransform **res)
Definition: mf_utils.c:552
ff_free_mf
void ff_free_mf(MFFunctions *f, IMFTransform **mft)
Definition: mf_utils.c:645
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
mf_setup_context
static int mf_setup_context(AVCodecContext *avctx)
Definition: mfenc.c:1125
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:90
duration
int64_t duration
Definition: movenc.c:65
mf_avframe_to_sample
static int mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:490
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:515
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:697
MFContext::opt_enc_rc
int opt_enc_rc
Definition: mfenc.c:63
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1217
MFContext::reorder_delay
int64_t reorder_delay
Definition: mfenc.c:60
mf_encv_output_adjust
static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:808
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
MFContext::opt_enc_scenario
int opt_enc_scenario
Definition: mfenc.c:65
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
MFContext::codec_api
ICodecAPI * codec_api
Definition: mfenc.c:61
MFContext::in_info
MFT_INPUT_STREAM_INFO in_info
Definition: mfenc.c:53
MFContext::out_stream_provides_samples
int out_stream_provides_samples
Definition: mfenc.c:55
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1270
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
MFContext::library
HMODULE library
Definition: mfenc.c:40
MFContext::frame
AVFrame * frame
Definition: mfenc.c:47
if
if(ret)
Definition: filter_design.txt:179
ff_eAVScenarioInfo_LiveStreaming
@ ff_eAVScenarioInfo_LiveStreaming
Definition: mf_utils.h:142
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1255
ff_METransformMarker
@ ff_METransformMarker
Definition: mf_utils.h:155
ff_MFSetAttributeRatio
#define ff_MFSetAttributeRatio
Definition: mf_utils.c:47
framerate
float framerate
Definition: av1_levels.c:29
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
ff_eAVEncCommonRateControlMode_PeakConstrainedVBR
@ ff_eAVEncCommonRateControlMode_PeakConstrainedVBR
Definition: mf_utils.h:129
AVCodec::type
enum AVMediaType type
Definition: codec.h:185
mf_enca_input_score
static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:742
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
MF_INVALID_TIME
#define MF_INVALID_TIME
Definition: mfenc.c:75
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:481
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
mf_enca_input_adjust
static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:766
time.h
MFContext::dxgiManager
IMFDXGIDeviceManager * dxgiManager
Definition: mfenc.c:43
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
initialize_dxgi_manager
static int initialize_dxgi_manager(AVCodecContext *avctx)
Definition: mfenc.c:330
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:453
ff_METransformDrainComplete
@ ff_METransformDrainComplete
Definition: mf_utils.h:154
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:535
ff_media_type_to_pix_fmt
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
Definition: mf_utils.c:158
MFFunctions
Definition: mf_utils.h:48
f
f
Definition: af_crystalizer.c:122
ff_eAVScenarioInfo_Archive
@ ff_eAVScenarioInfo_Archive
Definition: mf_utils.h:141
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1005
codec_internal.h
bps
unsigned bps
Definition: movenc.c:1958
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1031
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
sample
#define sample
Definition: flacdsp_template.c:44
MFContext::is_video
int is_video
Definition: mfenc.c:48
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MFContext::stream_started
int stream_started
Definition: mfenc.c:58
ff_eAVEncH264VProfile_Base
@ ff_eAVEncH264VProfile_Base
Definition: mf_utils.h:163
ff_eAVScenarioInfo_DisplayRemoting
@ ff_eAVScenarioInfo_DisplayRemoting
Definition: mf_utils.h:139
ACAPS
#define ACAPS
Definition: mfenc.c:1426
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
MFContext::d3d_context
ID3D11DeviceContext * d3d_context
Definition: mfenc.c:42
MFContext::opt_enc_quality
int opt_enc_quality
Definition: mfenc.c:64
MFContext::async_events
IMFMediaEventGenerator * async_events
Definition: mfenc.c:51
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:551
ff_eAVEncCommonRateControlMode_UnconstrainedVBR
@ ff_eAVEncCommonRateControlMode_UnconstrainedVBR
Definition: mf_utils.h:130
MF_TIMEBASE
#define MF_TIMEBASE
Definition: mfenc.c:73
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap
@ ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap
Definition: mf_utils.h:144
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:558
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:336
process_software_frame
static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:413
AVCodec::id
enum AVCodecID id
Definition: codec.h:186
mf_get_tb
static AVRational mf_get_tb(AVCodecContext *avctx)
Definition: mfenc.c:116
mf_load_library
static int mf_load_library(AVCodecContext *avctx)
Definition: mfenc.c:1332
MFContext::d3d_dll
HMODULE d3d_dll
Definition: mfenc.c:41
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:545
mf_send_sample
static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:510
MFContext::in_stream_id
DWORD in_stream_id
Definition: mfenc.c:52
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:514
MFContext::async_have_output
int async_have_output
Definition: mfenc.c:59
AVD3D11VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d11va.h:45
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
VE
#define VE
Definition: mfenc.c:1434
MFContext::out_info
MFT_OUTPUT_STREAM_INFO out_info
Definition: mfenc.c:54
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:494
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2278
MFContext
Definition: mfenc.c:38
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
mf_negotiate_types
static int mf_negotiate_types(AVCodecContext *avctx)
Definition: mfenc.c:1098
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
ff_METransformNeedInput
@ ff_METransformNeedInput
Definition: mf_utils.h:152
ff_METransformHaveOutput
@ ff_METransformHaveOutput
Definition: mf_utils.h:153
mf_enca_output_adjust
static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:732
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
mf_sample_set_pts
static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
Definition: mfenc.c:130
mf_to_mf_time
static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
Definition: mfenc.c:123
mf_create
static int mf_create(void *log, MFFunctions *f, IMFTransform **mft, const AVCodec *codec, int use_hw)
Definition: mfenc.c:1202
mf_from_mf_time
static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
Definition: mfenc.c:137
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
mf_v_avframe_to_sample
static int mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:460
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:114
mf_init
static av_cold int mf_init(AVCodecContext *avctx)
Definition: mfenc.c:1388
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:106
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1618
mf_init_encoder
static int mf_init_encoder(AVCodecContext *avctx)
Definition: mfenc.c:1232
mf_close
static int mf_close(AVCodecContext *avctx)
Definition: mfenc.c:1359
mf_encv_input_adjust
static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:901
MFContext::device_hwctx
AVD3D11VADeviceContext * device_hwctx
Definition: mfenc.c:67
MFContext::draining
int draining
Definition: mfenc.c:56
ff_eAVScenarioInfo_CameraRecord
@ ff_eAVScenarioInfo_CameraRecord
Definition: mf_utils.h:143
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:439
FF_VAL_VT_BOOL
#define FF_VAL_VT_BOOL(v)
Definition: mf_utils.h:175
mem.h
AVCodecContext::max_b_frames
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:769
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:205
mf_choose_output_type
static int mf_choose_output_type(AVCodecContext *avctx)
Definition: mfenc.c:921
ff_eAVScenarioInfo_VideoConference
@ ff_eAVScenarioInfo_VideoConference
Definition: mf_utils.h:140
AFMTS
#define AFMTS
Definition: mfenc.c:1424
ff_media_type_dump
void ff_media_type_dump(void *log, IMFMediaType *type)
Definition: mf_utils.c:503
defaults
static const FFCodecDefault defaults[]
Definition: mfenc.c:1461
mf_encv_input_score
static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:884
mf_output_type_get
static int mf_output_type_get(AVCodecContext *avctx)
Definition: mfenc.c:223
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_image_copy_to_buffer
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
Definition: imgutils.c:501
AVPacket
This structure stores compressed data.
Definition: packet.h:529
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
mf_sample_to_avpacket
static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
Definition: mfenc.c:253
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
imgutils.h
MFContext::mft
IMFTransform * mft
Definition: mfenc.c:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
mf_unlock_async
static int mf_unlock_async(AVCodecContext *avctx)
Definition: mfenc.c:1153
mf_a_avframe_to_sample
static int mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:309
mf_sample_get_duration
static int64_t mf_sample_get_duration(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:151
ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR
@ ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR
Definition: mf_utils.h:134
mf_wait_events
static int mf_wait_events(AVCodecContext *avctx)
Definition: mfenc.c:77
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
hwcontext_d3d11va.h
ff_eAVEncH264VProfile_Main
@ ff_eAVEncH264VProfile_Main
Definition: mf_utils.h:164
mf_sample_get_pts
static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
Definition: mfenc.c:142
MFContext::main_subtype
GUID main_subtype
Definition: mfenc.c:49
ff_eAVEncCommonRateControlMode_LowDelayVBR
@ ff_eAVEncCommonRateControlMode_LowDelayVBR
Definition: mf_utils.h:132
w32dlfcn.h
mf_encv_output_type_get
static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:200
AVCodecContext::compression_level
int compression_level
Definition: avcodec.h:1223
ff_create_memory_sample
IMFSample * ff_create_memory_sample(MFFunctions *f, void *fill_data, size_t size, size_t align)
Definition: mf_utils.c:76