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 
151 static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
152 {
153  MFContext *c = avctx->priv_data;
154  HRESULT hr;
155  UINT32 sz;
156 
157  if (avctx->codec_id != AV_CODEC_ID_MP3 && avctx->codec_id != AV_CODEC_ID_AC3) {
158  hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
159  if (!FAILED(hr) && sz > 0) {
161  if (!avctx->extradata)
162  return AVERROR(ENOMEM);
163  avctx->extradata_size = sz;
164  hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->extradata, sz, NULL);
165  if (FAILED(hr))
166  return AVERROR_EXTERNAL;
167 
168  if (avctx->codec_id == AV_CODEC_ID_AAC && avctx->extradata_size >= 12) {
169  // Get rid of HEAACWAVEINFO (after wfx field, 12 bytes).
170  avctx->extradata_size = avctx->extradata_size - 12;
171  memmove(avctx->extradata, avctx->extradata + 12, avctx->extradata_size);
172  }
173  }
174  }
175 
176  // I don't know where it's documented that we need this. It happens with the
177  // MS mp3 encoder MFT. The idea for the workaround is taken from NAudio.
178  // (Certainly any lossy codec will have frames much smaller than 1 second.)
179  if (!c->out_info.cbSize && !c->out_stream_provides_samples) {
180  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
181  if (!FAILED(hr)) {
182  av_log(avctx, AV_LOG_VERBOSE, "MFT_OUTPUT_STREAM_INFO.cbSize set to 0, "
183  "assuming %d bytes instead.\n", (int)sz);
184  c->out_info.cbSize = sz;
185  }
186  }
187 
188  return 0;
189 }
190 
191 static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
192 {
193  HRESULT hr;
194  UINT32 sz;
195 
196  hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
197  if (!FAILED(hr) && sz > 0) {
198  uint8_t *extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
199  if (!extradata)
200  return AVERROR(ENOMEM);
201  hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz, NULL);
202  if (FAILED(hr)) {
203  av_free(extradata);
204  return AVERROR_EXTERNAL;
205  }
206  av_freep(&avctx->extradata);
207  avctx->extradata = extradata;
208  avctx->extradata_size = sz;
209  }
210 
211  return 0;
212 }
213 
215 {
216  MFContext *c = avctx->priv_data;
217  HRESULT hr;
218  IMFMediaType *type;
219  int ret;
220 
221  hr = IMFTransform_GetOutputCurrentType(c->mft, c->out_stream_id, &type);
222  if (FAILED(hr)) {
223  av_log(avctx, AV_LOG_ERROR, "could not get output type\n");
224  return AVERROR_EXTERNAL;
225  }
226 
227  av_log(avctx, AV_LOG_VERBOSE, "final output type:\n");
228  ff_media_type_dump(avctx, type);
229 
230  ret = 0;
231  if (c->is_video) {
232  ret = mf_encv_output_type_get(avctx, type);
233  } else if (c->is_audio) {
234  ret = mf_enca_output_type_get(avctx, type);
235  }
236 
237  if (ret < 0)
238  av_log(avctx, AV_LOG_ERROR, "output type not supported\n");
239 
240  IMFMediaType_Release(type);
241  return ret;
242 }
243 
244 static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
245 {
246  MFContext *c = avctx->priv_data;
247  HRESULT hr;
248  int ret;
249  DWORD len;
250  IMFMediaBuffer *buffer;
251  BYTE *data;
252  UINT64 t;
253  UINT32 t32;
254 
255  hr = IMFSample_GetTotalLength(sample, &len);
256  if (FAILED(hr))
257  return AVERROR_EXTERNAL;
258 
259  if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0)
260  return ret;
261 
262  hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
263  if (FAILED(hr))
264  return AVERROR_EXTERNAL;
265 
266  hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
267  if (FAILED(hr)) {
268  IMFMediaBuffer_Release(buffer);
269  return AVERROR_EXTERNAL;
270  }
271 
272  memcpy(avpkt->data, data, len);
273 
274  IMFMediaBuffer_Unlock(buffer);
275  IMFMediaBuffer_Release(buffer);
276 
277  avpkt->pts = avpkt->dts = mf_sample_get_pts(avctx, sample);
278 
279  hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
280  if (c->is_audio || (!FAILED(hr) && t32 != 0))
281  avpkt->flags |= AV_PKT_FLAG_KEY;
282 
283  hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
284  if (!FAILED(hr)) {
285  avpkt->dts = mf_from_mf_time(avctx, t);
286  // At least on Qualcomm's HEVC encoder on SD 835, the output dts
287  // starts from the input pts of the first frame, while the output pts
288  // is shifted forward. Therefore, shift the output values back so that
289  // the output pts matches the input.
290  if (c->reorder_delay == AV_NOPTS_VALUE)
291  c->reorder_delay = avpkt->pts - avpkt->dts;
292  avpkt->dts -= c->reorder_delay;
293  avpkt->pts -= c->reorder_delay;
294  }
295 
296  return 0;
297 }
298 
299 static int mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
300 {
301  MFContext *c = avctx->priv_data;
302  size_t len;
303  size_t bps;
304  IMFSample *sample;
305 
307  len = frame->nb_samples * bps;
308 
309  sample = ff_create_memory_sample(&c->functions, frame->data[0], len,
310  c->in_info.cbAlignment);
311  if (!sample)
312  return AVERROR(ENOMEM);
313 
314  IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->nb_samples));
315 
316  *out_sample = sample;
317  return 0;
318 }
319 
321 {
322  MFContext *c = avctx->priv_data;
323  MFFunctions *func = &c->functions;
324  HRESULT hr;
325 
326  hr = func->MFCreateDXGIDeviceManager(&c->resetToken, &c->dxgiManager);
327  if (FAILED(hr)) {
328  av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI device manager: %s\n", ff_hr_str(hr));
329  return AVERROR_EXTERNAL;
330  }
331 
332  hr = IMFDXGIDeviceManager_ResetDevice(c->dxgiManager, (IUnknown*)c->device_hwctx->device, c->resetToken);
333  if (FAILED(hr)) {
334  av_log(avctx, AV_LOG_ERROR, "Failed to reset device: %s\n", ff_hr_str(hr));
335  return AVERROR_EXTERNAL;
336  }
337 
338  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)c->dxgiManager);
339  if (FAILED(hr)) {
340  av_log(avctx, AV_LOG_ERROR, "Failed to set D3D manager: %s\n", ff_hr_str(hr));
341  return AVERROR_EXTERNAL;
342  }
343 
344  return 0;
345 }
346 
347 static int process_d3d11_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
348 {
349  MFContext *c = avctx->priv_data;
350  MFFunctions *func = &c->functions;
351  AVHWFramesContext *frames_ctx = NULL;
352  ID3D11Texture2D *d3d11_texture = NULL;
353  IMFSample *sample = NULL;
354  IMFMediaBuffer *buffer = NULL;
355  int subIdx = 0;
356  HRESULT hr;
357 
358  frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
359  c->device_hwctx = (AVD3D11VADeviceContext*)frames_ctx->device_ctx->hwctx;
360 
361  if (!c->dxgiManager) {
362  hr = initialize_dxgi_manager(avctx);
363  if (FAILED(hr)) {
364  return AVERROR_EXTERNAL;
365  }
366  }
367 
368  d3d11_texture = (ID3D11Texture2D*)frame->data[0];
369  subIdx = (int)(intptr_t)frame->data[1];
370 
371  if (!d3d11_texture) {
372  av_log(avctx, AV_LOG_ERROR, "D3D11 texture not found\n");
373  return AVERROR(EINVAL);
374  }
375 
376  hr = func->MFCreateSample(&sample);
377  if (FAILED(hr)) {
378  av_log(avctx, AV_LOG_ERROR, "Failed to create MF sample: %s\n", ff_hr_str(hr));
379  return AVERROR_EXTERNAL;
380  }
381 
382  hr = func->MFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown*)d3d11_texture, subIdx, 0, &buffer);
383  if (FAILED(hr)) {
384  av_log(avctx, AV_LOG_ERROR, "Failed to create DXGI surface buffer: %s\n", ff_hr_str(hr));
385  IMFSample_Release(sample);
386  return AVERROR_EXTERNAL;
387  }
388 
389  hr = IMFSample_AddBuffer(sample, buffer);
390  if (FAILED(hr)) {
391  av_log(avctx, AV_LOG_ERROR, "Failed to add buffer to sample: %s\n", ff_hr_str(hr));
392  IMFMediaBuffer_Release(buffer);
393  IMFSample_Release(sample);
394  return AVERROR_EXTERNAL;
395  }
396 
397  IMFMediaBuffer_Release(buffer);
398 
399  *out_sample = sample;
400  return 0;
401 }
402 
403 static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
404 {
405  MFContext *c = avctx->priv_data;
406  IMFSample *sample = NULL;
407  IMFMediaBuffer *buffer = NULL;
408  BYTE *data = NULL;
409  HRESULT hr;
410  int size, ret;
411 
412  size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
413  if (size < 0)
414  return size;
415 
416  sample = ff_create_memory_sample(&c->functions, NULL, size,
417  c->in_info.cbAlignment);
418  if (!sample)
419  return AVERROR_EXTERNAL;
420 
421  hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
422  if (FAILED(hr)) {
423  IMFSample_Release(sample);
424  return AVERROR_EXTERNAL;
425  }
426 
427  hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
428  if (FAILED(hr)) {
429  IMFMediaBuffer_Release(buffer);
430  IMFSample_Release(sample);
431  return AVERROR_EXTERNAL;
432  }
433 
434  ret = av_image_copy_to_buffer((uint8_t *)data, size, (void *)frame->data, frame->linesize,
435  avctx->pix_fmt, avctx->width, avctx->height, 1);
436  IMFMediaBuffer_SetCurrentLength(buffer, size);
437  IMFMediaBuffer_Unlock(buffer);
438  IMFMediaBuffer_Release(buffer);
439  if (ret < 0) {
440  IMFSample_Release(sample);
441  return ret;
442  }
443 
444  IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration));
445  *out_sample = sample;
446 
447  return 0;
448 }
449 
450 static int mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
451 {
452  IMFSample *sample = NULL;
453  HRESULT hr;
454  int ret;
455 
456  if (frame->format == AV_PIX_FMT_D3D11) {
457  // Handle D3D11 hardware frames
458  ret = process_d3d11_frame(avctx, frame, &sample);
459  if (ret < 0) {
460  return ret;
461  }
462  } else {
463  // Handle software frames
465  if (ret < 0) {
466  return ret;
467  }
468  }
469 
470  // Set sample duration
471  hr = IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->duration));
472  if (FAILED(hr)) {
473  av_log(avctx, AV_LOG_WARNING, "Failed to set sample duration: %s\n", ff_hr_str(hr));
474  }
475 
476  *out_sample = sample;
477  return 0;
478 }
479 
480 static int mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
481 {
482  MFContext *c = avctx->priv_data;
483  IMFSample *sample;
484  int ret;
485 
486  if (c->is_audio) {
488  } else {
490  }
491 
492  if (ret < 0)
493  return ret;
494 
495  mf_sample_set_pts(avctx, sample, frame->pts);
496  *out_sample = sample;
497  return 0;
498 }
499 
500 static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
501 {
502  MFContext *c = avctx->priv_data;
503  HRESULT hr;
504  int ret;
505 
506  if (sample) {
507  if (c->async_events) {
508  if ((ret = mf_wait_events(avctx)) < 0)
509  return ret;
510  if (!c->async_need_input)
511  return AVERROR(EAGAIN);
512  }
513  if (!c->sample_sent)
514  IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
515  c->sample_sent = 1;
516  hr = IMFTransform_ProcessInput(c->mft, c->in_stream_id, sample, 0);
517  if (hr == MF_E_NOTACCEPTING) {
518  return AVERROR(EAGAIN);
519  } else if (FAILED(hr)) {
520  av_log(avctx, AV_LOG_ERROR, "failed processing input: %s\n", ff_hr_str(hr));
521  return AVERROR_EXTERNAL;
522  }
523  c->async_need_input = 0;
524  } else if (!c->draining) {
525  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
526  if (FAILED(hr))
527  av_log(avctx, AV_LOG_ERROR, "failed draining: %s\n", ff_hr_str(hr));
528  // Some MFTs (AC3) will send a frame after each drain command (???), so
529  // this is required to make draining actually terminate.
530  c->draining = 1;
531  c->async_need_input = 0;
532  } else {
533  return AVERROR_EOF;
534  }
535  return 0;
536 }
537 
538 static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
539 {
540  MFContext *c = avctx->priv_data;
541  HRESULT hr;
542  DWORD st;
543  MFT_OUTPUT_DATA_BUFFER out_buffers;
544  IMFSample *sample;
545  int ret = 0;
546 
547  while (1) {
548  *out_sample = NULL;
549  sample = NULL;
550 
551  if (c->async_events) {
552  if ((ret = mf_wait_events(avctx)) < 0)
553  return ret;
554  if (!c->async_have_output || c->draining_done) {
555  ret = 0;
556  break;
557  }
558  }
559 
560  if (!c->out_stream_provides_samples) {
561  sample = ff_create_memory_sample(&c->functions, NULL,
562  c->out_info.cbSize,
563  c->out_info.cbAlignment);
564  if (!sample)
565  return AVERROR(ENOMEM);
566  }
567 
568  out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
569  .dwStreamID = c->out_stream_id,
570  .pSample = sample,
571  };
572 
573  st = 0;
574  hr = IMFTransform_ProcessOutput(c->mft, 0, 1, &out_buffers, &st);
575 
576  if (out_buffers.pEvents)
577  IMFCollection_Release(out_buffers.pEvents);
578 
579  if (!FAILED(hr)) {
580  *out_sample = out_buffers.pSample;
581  ret = 0;
582  break;
583  }
584 
585  if (out_buffers.pSample)
586  IMFSample_Release(out_buffers.pSample);
587 
588  if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
589  if (c->draining)
590  c->draining_done = 1;
591  ret = 0;
592  } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
593  av_log(avctx, AV_LOG_WARNING, "stream format change\n");
594  ret = mf_choose_output_type(avctx);
595  if (ret == 0) // we don't expect renegotiating the input type
597  if (ret > 0) {
598  ret = mf_setup_context(avctx);
599  if (ret >= 0) {
600  c->async_have_output = 0;
601  continue;
602  }
603  }
604  } else {
605  av_log(avctx, AV_LOG_ERROR, "failed processing output: %s\n", ff_hr_str(hr));
607  }
608 
609  break;
610  }
611 
612  c->async_have_output = 0;
613 
614  if (ret >= 0 && !*out_sample)
615  ret = c->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
616 
617  return ret;
618 }
619 
620 static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
621 {
622  MFContext *c = avctx->priv_data;
623  IMFSample *sample = NULL;
624  int ret;
625 
626  if (!c->frame->buf[0]) {
627  ret = ff_encode_get_frame(avctx, c->frame);
628  if (ret < 0 && ret != AVERROR_EOF)
629  return ret;
630  }
631 
632  if (c->frame->buf[0]) {
633  ret = mf_avframe_to_sample(avctx, c->frame, &sample);
634  if (ret < 0) {
635  av_frame_unref(c->frame);
636  return ret;
637  }
638  if (c->is_video && c->codec_api) {
639  if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
640  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
641  }
642  }
643 
644  if(!c->stream_started)
645  {
646  HRESULT hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
647  if (FAILED(hr)) {
648  av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr));
649  return AVERROR(EBADMSG);
650  }
651 
652  hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
653  if (FAILED(hr)) {
654  av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr));
655  return AVERROR(EBADMSG);
656  }
657 
658  c->stream_started = 1;
659  }
660 
661  ret = mf_send_sample(avctx, sample);
662  if (sample)
663  IMFSample_Release(sample);
664  if (ret != AVERROR(EAGAIN))
665  av_frame_unref(c->frame);
666  if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
667  return ret;
668 
669  ret = mf_receive_sample(avctx, &sample);
670  if (ret < 0)
671  return ret;
672 
673  ret = mf_sample_to_avpacket(avctx, sample, avpkt);
674  IMFSample_Release(sample);
675 
676  return ret;
677 }
678 
679 // Most encoders seem to enumerate supported audio formats on the output types,
680 // at least as far as channel configuration and sample rate is concerned. Pick
681 // the one which seems to match best.
682 static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
683 {
684  MFContext *c = avctx->priv_data;
685  HRESULT hr;
686  UINT32 t;
687  GUID tg;
688  int64_t score = 0;
689 
690  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
691  if (!FAILED(hr) && t == avctx->sample_rate)
692  score |= 1LL << 32;
693 
694  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
695  if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
696  score |= 2LL << 32;
697 
698  hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
699  if (!FAILED(hr)) {
700  if (IsEqualGUID(&c->main_subtype, &tg))
701  score |= 4LL << 32;
702  }
703 
704  // Select the bitrate (lowest priority).
705  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
706  if (!FAILED(hr)) {
707  int diff = (int)t - avctx->bit_rate / 8;
708  if (diff >= 0) {
709  score |= (1LL << 31) - diff; // prefer lower bitrate
710  } else {
711  score |= (1LL << 30) + diff; // prefer higher bitrate
712  }
713  }
714 
715  hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
716  if (!FAILED(hr) && t != 0)
717  return -1;
718 
719  return score;
720 }
721 
722 static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
723 {
724  // (some decoders allow adjusting this freely, but it can also cause failure
725  // to set the output type - so it's commented for being too fragile)
726  //IMFAttributes_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avctx->bit_rate / 8);
727  //IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
728 
729  return 0;
730 }
731 
732 static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
733 {
734  HRESULT hr;
735  UINT32 t;
736  int64_t score = 0;
737 
738  enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
739  if (sformat == AV_SAMPLE_FMT_NONE)
740  return -1; // can not use
741 
742  if (sformat == avctx->sample_fmt)
743  score |= 1;
744 
745  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
746  if (!FAILED(hr) && t == avctx->sample_rate)
747  score |= 2;
748 
749  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
750  if (!FAILED(hr) && t == avctx->ch_layout.nb_channels)
751  score |= 4;
752 
753  return score;
754 }
755 
756 static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
757 {
758  HRESULT hr;
759  UINT32 t;
760 
761  enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
762  if (sformat != avctx->sample_fmt) {
763  av_log(avctx, AV_LOG_ERROR, "unsupported input sample format set\n");
764  return AVERROR(EINVAL);
765  }
766 
767  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
768  if (FAILED(hr) || t != avctx->sample_rate) {
769  av_log(avctx, AV_LOG_ERROR, "unsupported input sample rate set\n");
770  return AVERROR(EINVAL);
771  }
772 
773  hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
774  if (FAILED(hr) || t != avctx->ch_layout.nb_channels) {
775  av_log(avctx, AV_LOG_ERROR, "unsupported input channel number set\n");
776  return AVERROR(EINVAL);
777  }
778 
779  return 0;
780 }
781 
782 static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
783 {
784  MFContext *c = avctx->priv_data;
785  GUID tg;
786  HRESULT hr;
787  int score = -1;
788 
789  hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
790  if (!FAILED(hr)) {
791  if (IsEqualGUID(&c->main_subtype, &tg))
792  score = 1;
793  }
794 
795  return score;
796 }
797 
798 static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
799 {
800  MFContext *c = avctx->priv_data;
802 
803  ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
804  IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
805 
806  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
807  framerate = avctx->framerate;
808  } else {
809  framerate = av_inv_q(avctx->time_base);
810  }
811 
812  ff_MFSetAttributeRatio((IMFAttributes *)type, &MF_MT_FRAME_RATE, framerate.num, framerate.den);
813 
814  // (MS HEVC supports eAVEncH265VProfile_Main_420_8 only.)
815  if (avctx->codec_id == AV_CODEC_ID_H264) {
817  switch (avctx->profile) {
820  break;
823  break;
824  }
825  IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
826  }
827 
828  IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
829 
830  // Note that some of the ICodecAPI options must be set before SetOutputType.
831  if (c->codec_api) {
832  if (avctx->bit_rate)
833  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMeanBitRate, FF_VAL_VT_UI4(avctx->bit_rate));
834 
835  if (c->opt_enc_rc >= 0)
836  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonRateControlMode, FF_VAL_VT_UI4(c->opt_enc_rc));
837 
838  if (c->opt_enc_quality >= 0)
839  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQuality, FF_VAL_VT_UI4(c->opt_enc_quality));
840 
841  if (avctx->rc_max_rate > 0)
842  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMaxBitRate, FF_VAL_VT_UI4(avctx->rc_max_rate));
843 
844  if (avctx->gop_size > 0)
845  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVGOPSize, FF_VAL_VT_UI4(avctx->gop_size));
846 
847  if(avctx->rc_buffer_size > 0)
848  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonBufferSize, FF_VAL_VT_UI4(avctx->rc_buffer_size));
849 
850  if(avctx->compression_level >= 0)
851  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQualityVsSpeed, FF_VAL_VT_UI4(avctx->compression_level));
852 
853  if(avctx->global_quality > 0)
854  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoEncodeQP, FF_VAL_VT_UI4(avctx->global_quality ));
855 
856  // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
857  // defaults this to 1, and that setting is buggy with many of the
858  // rate control modes. (0 or 2 b-frames works fine with most rate
859  // control modes, but 2 seems buggy with the u_vbr mode.) Setting
860  // "scenario" to "camera_record" sets it in CFR mode (where the default
861  // is VFR), which makes the encoder avoid dropping frames.
862  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVDefaultBPictureCount, FF_VAL_VT_UI4(avctx->max_b_frames));
863  avctx->has_b_frames = avctx->max_b_frames > 0;
864 
865  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncH264CABACEnable, FF_VAL_VT_BOOL(1));
866 
867  if (c->opt_enc_scenario >= 0)
868  ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVScenarioInfo, FF_VAL_VT_UI4(c->opt_enc_scenario));
869  }
870 
871  return 0;
872 }
873 
874 static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
875 {
876  enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
877 
878  if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
879  if (pix_fmt != AV_PIX_FMT_NV12) {
880  return -1; // can not use
881  }
882  }
883  else {
884  if (pix_fmt != avctx->pix_fmt)
885  return -1; // can not use
886  }
887 
888  return 0;
889 }
890 
891 static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
892 {
893  enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
894  if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
896  av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
897  return AVERROR(EINVAL);
898  }
899  } else {
900  if (pix_fmt != avctx->pix_fmt) {
901  av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
902  return AVERROR(EINVAL);
903  }
904  }
905 
906  //ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
907 
908  return 0;
909 }
910 
912 {
913  MFContext *c = avctx->priv_data;
914  HRESULT hr;
915  int ret;
916  IMFMediaType *out_type = NULL;
917  int64_t out_type_score = -1;
918  int out_type_index = -1;
919  int n;
920 
921  av_log(avctx, AV_LOG_VERBOSE, "output types:\n");
922  for (n = 0; ; n++) {
923  IMFMediaType *type;
924  int64_t score = -1;
925 
926  hr = IMFTransform_GetOutputAvailableType(c->mft, c->out_stream_id, n, &type);
927  if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
928  break;
929  if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
930  av_log(avctx, AV_LOG_VERBOSE, "(need to set input type)\n");
931  ret = 0;
932  goto done;
933  }
934  if (FAILED(hr)) {
935  av_log(avctx, AV_LOG_ERROR, "error getting output type: %s\n", ff_hr_str(hr));
937  goto done;
938  }
939 
940  av_log(avctx, AV_LOG_VERBOSE, "output type %d:\n", n);
941  ff_media_type_dump(avctx, type);
942 
943  if (c->is_video) {
944  score = mf_encv_output_score(avctx, type);
945  } else if (c->is_audio) {
946  score = mf_enca_output_score(avctx, type);
947  }
948 
949  if (score > out_type_score) {
950  if (out_type)
951  IMFMediaType_Release(out_type);
952  out_type = type;
953  out_type_score = score;
954  out_type_index = n;
955  IMFMediaType_AddRef(out_type);
956  }
957 
958  IMFMediaType_Release(type);
959  }
960 
961  if (out_type) {
962  av_log(avctx, AV_LOG_VERBOSE, "picking output type %d.\n", out_type_index);
963  } else {
964  hr = c->functions.MFCreateMediaType(&out_type);
965  if (FAILED(hr)) {
966  ret = AVERROR(ENOMEM);
967  goto done;
968  }
969  }
970 
971  ret = 0;
972  if (c->is_video) {
973  ret = mf_encv_output_adjust(avctx, out_type);
974  } else if (c->is_audio) {
975  ret = mf_enca_output_adjust(avctx, out_type);
976  }
977 
978  if (ret >= 0) {
979  av_log(avctx, AV_LOG_VERBOSE, "setting output type:\n");
980  ff_media_type_dump(avctx, out_type);
981 
982  hr = IMFTransform_SetOutputType(c->mft, c->out_stream_id, out_type, 0);
983  if (!FAILED(hr)) {
984  ret = 1;
985  } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
986  av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set input type\n");
987  ret = 0;
988  } else {
989  av_log(avctx, AV_LOG_ERROR, "could not set output type (%s)\n", ff_hr_str(hr));
991  }
992  }
993 
994 done:
995  if (out_type)
996  IMFMediaType_Release(out_type);
997  return ret;
998 }
999 
1001 {
1002  MFContext *c = avctx->priv_data;
1003  HRESULT hr;
1004  int ret;
1005  IMFMediaType *in_type = NULL;
1006  int64_t in_type_score = -1;
1007  int in_type_index = -1;
1008  int n;
1009 
1010  av_log(avctx, AV_LOG_VERBOSE, "input types:\n");
1011  for (n = 0; ; n++) {
1012  IMFMediaType *type = NULL;
1013  int64_t score = -1;
1014 
1015  hr = IMFTransform_GetInputAvailableType(c->mft, c->in_stream_id, n, &type);
1016  if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
1017  break;
1018  if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
1019  av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 1)\n");
1020  ret = 0;
1021  goto done;
1022  }
1023  if (FAILED(hr)) {
1024  av_log(avctx, AV_LOG_ERROR, "error getting input type: %s\n", ff_hr_str(hr));
1026  goto done;
1027  }
1028 
1029  av_log(avctx, AV_LOG_VERBOSE, "input type %d:\n", n);
1030  ff_media_type_dump(avctx, type);
1031 
1032  if (c->is_video) {
1033  score = mf_encv_input_score(avctx, type);
1034  } else if (c->is_audio) {
1035  score = mf_enca_input_score(avctx, type);
1036  }
1037 
1038  if (score > in_type_score) {
1039  if (in_type)
1040  IMFMediaType_Release(in_type);
1041  in_type = type;
1042  in_type_score = score;
1043  in_type_index = n;
1044  IMFMediaType_AddRef(in_type);
1045  }
1046 
1047  IMFMediaType_Release(type);
1048  }
1049 
1050  if (in_type) {
1051  av_log(avctx, AV_LOG_VERBOSE, "picking input type %d.\n", in_type_index);
1052  } else {
1053  // Some buggy MFTs (WMA encoder) fail to return MF_E_TRANSFORM_TYPE_NOT_SET.
1054  av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 2)\n");
1055  ret = 0;
1056  goto done;
1057  }
1058 
1059  ret = 0;
1060  if (c->is_video) {
1061  ret = mf_encv_input_adjust(avctx, in_type);
1062  } else if (c->is_audio) {
1063  ret = mf_enca_input_adjust(avctx, in_type);
1064  }
1065 
1066  if (ret >= 0) {
1067  av_log(avctx, AV_LOG_VERBOSE, "setting input type:\n");
1068  ff_media_type_dump(avctx, in_type);
1069 
1070  hr = IMFTransform_SetInputType(c->mft, c->in_stream_id, in_type, 0);
1071  if (!FAILED(hr)) {
1072  ret = 1;
1073  } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
1074  av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set output type\n");
1075  ret = 0;
1076  } else {
1077  av_log(avctx, AV_LOG_ERROR, "could not set input type (%s)\n", ff_hr_str(hr));
1079  }
1080  }
1081 
1082 done:
1083  if (in_type)
1084  IMFMediaType_Release(in_type);
1085  return ret;
1086 }
1087 
1089 {
1090  // This follows steps 1-5 on:
1091  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa965264(v=vs.85).aspx
1092  // If every MFT implementer does this correctly, this loop should at worst
1093  // be repeated once.
1094  int need_input = 1, need_output = 1;
1095  int n;
1096  for (n = 0; n < 2 && (need_input || need_output); n++) {
1097  int ret;
1098  ret = mf_choose_input_type(avctx);
1099  if (ret < 0)
1100  return ret;
1101  need_input = ret < 1;
1102  ret = mf_choose_output_type(avctx);
1103  if (ret < 0)
1104  return ret;
1105  need_output = ret < 1;
1106  }
1107  if (need_input || need_output) {
1108  av_log(avctx, AV_LOG_ERROR, "format negotiation failed (%d/%d)\n",
1109  need_input, need_output);
1110  return AVERROR_EXTERNAL;
1111  }
1112  return 0;
1113 }
1114 
1116 {
1117  MFContext *c = avctx->priv_data;
1118  HRESULT hr;
1119  int ret;
1120 
1121  hr = IMFTransform_GetInputStreamInfo(c->mft, c->in_stream_id, &c->in_info);
1122  if (FAILED(hr))
1123  return AVERROR_EXTERNAL;
1124  av_log(avctx, AV_LOG_VERBOSE, "in_info: size=%d, align=%d\n",
1125  (int)c->in_info.cbSize, (int)c->in_info.cbAlignment);
1126 
1127  hr = IMFTransform_GetOutputStreamInfo(c->mft, c->out_stream_id, &c->out_info);
1128  if (FAILED(hr))
1129  return AVERROR_EXTERNAL;
1130  c->out_stream_provides_samples =
1131  (c->out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
1132  (c->out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
1133  av_log(avctx, AV_LOG_VERBOSE, "out_info: size=%d, align=%d%s\n",
1134  (int)c->out_info.cbSize, (int)c->out_info.cbAlignment,
1135  c->out_stream_provides_samples ? " (provides samples)" : "");
1136 
1137  if ((ret = mf_output_type_get(avctx)) < 0)
1138  return ret;
1139 
1140  return 0;
1141 }
1142 
1144 {
1145  MFContext *c = avctx->priv_data;
1146  HRESULT hr;
1147  IMFAttributes *attrs;
1148  UINT32 v;
1149  int res = AVERROR_EXTERNAL;
1150 
1151  // For hw encoding we unfortunately need to use async mode, otherwise
1152  // play it safe and avoid it.
1153  if (!(c->is_video && c->opt_enc_hw))
1154  return 0;
1155 
1156  hr = IMFTransform_GetAttributes(c->mft, &attrs);
1157  if (FAILED(hr)) {
1158  av_log(avctx, AV_LOG_ERROR, "error retrieving MFT attributes: %s\n", ff_hr_str(hr));
1159  goto err;
1160  }
1161 
1162  hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
1163  if (FAILED(hr)) {
1164  av_log(avctx, AV_LOG_ERROR, "error querying async: %s\n", ff_hr_str(hr));
1165  goto err;
1166  }
1167 
1168  if (!v) {
1169  av_log(avctx, AV_LOG_ERROR, "hardware MFT is not async\n");
1170  goto err;
1171  }
1172 
1173  hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
1174  if (FAILED(hr)) {
1175  av_log(avctx, AV_LOG_ERROR, "could not set async unlock: %s\n", ff_hr_str(hr));
1176  goto err;
1177  }
1178 
1179  hr = IMFTransform_QueryInterface(c->mft, &IID_IMFMediaEventGenerator, (void **)&c->async_events);
1180  if (FAILED(hr)) {
1181  av_log(avctx, AV_LOG_ERROR, "could not get async interface\n");
1182  goto err;
1183  }
1184 
1185  res = 0;
1186 
1187 err:
1188  IMFAttributes_Release(attrs);
1189  return res;
1190 }
1191 
1192 static int mf_create(void *log, MFFunctions *f, IMFTransform **mft,
1193  const AVCodec *codec, int use_hw)
1194 {
1195  int is_audio = codec->type == AVMEDIA_TYPE_AUDIO;
1196  const CLSID *subtype = ff_codec_to_mf_subtype(codec->id);
1197  MFT_REGISTER_TYPE_INFO reg = {0};
1198  GUID category;
1199  int ret;
1200 
1201  *mft = NULL;
1202 
1203  if (!subtype)
1204  return AVERROR(ENOSYS);
1205 
1206  reg.guidSubtype = *subtype;
1207 
1208  if (is_audio) {
1209  reg.guidMajorType = MFMediaType_Audio;
1210  category = MFT_CATEGORY_AUDIO_ENCODER;
1211  } else {
1212  reg.guidMajorType = MFMediaType_Video;
1213  category = MFT_CATEGORY_VIDEO_ENCODER;
1214  }
1215 
1216  if ((ret = ff_instantiate_mf(log, f, category, NULL, &reg, use_hw, mft)) < 0)
1217  return ret;
1218 
1219  return 0;
1220 }
1221 
1223 {
1224  MFContext *c = avctx->priv_data;
1225  HRESULT hr;
1226  int ret;
1227  const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id);
1228  int use_hw = 0;
1229 
1230  c->frame = av_frame_alloc();
1231  if (!c->frame)
1232  return AVERROR(ENOMEM);
1233 
1234  c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO;
1235  c->is_video = !c->is_audio;
1236  c->reorder_delay = AV_NOPTS_VALUE;
1237 
1238  if (c->is_video && c->opt_enc_hw)
1239  use_hw = 1;
1240 
1241  if (!subtype)
1242  return AVERROR(ENOSYS);
1243 
1244  c->main_subtype = *subtype;
1245 
1246  if ((ret = mf_create(avctx, &c->functions, &c->mft, avctx->codec, use_hw)) < 0)
1247  return ret;
1248 
1249  if ((ret = mf_unlock_async(avctx)) < 0)
1250  return ret;
1251 
1252  hr = IMFTransform_QueryInterface(c->mft, &IID_ICodecAPI, (void **)&c->codec_api);
1253  if (!FAILED(hr))
1254  av_log(avctx, AV_LOG_VERBOSE, "MFT supports ICodecAPI.\n");
1255 
1256 
1257  hr = IMFTransform_GetStreamIDs(c->mft, 1, &c->in_stream_id, 1, &c->out_stream_id);
1258  if (hr == E_NOTIMPL) {
1259  c->in_stream_id = c->out_stream_id = 0;
1260  } else if (FAILED(hr)) {
1261  av_log(avctx, AV_LOG_ERROR, "could not get stream IDs (%s)\n", ff_hr_str(hr));
1262  return AVERROR_EXTERNAL;
1263  }
1264 
1265  if ((ret = mf_negotiate_types(avctx)) < 0)
1266  return ret;
1267 
1268  if ((ret = mf_setup_context(avctx)) < 0)
1269  return ret;
1270 
1271  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER && c->async_events &&
1272  c->is_video && !avctx->extradata) {
1273  int sleep = 10000, total = 0;
1274  av_log(avctx, AV_LOG_VERBOSE, "Awaiting extradata\n");
1275  while (total < 70*1000) {
1276  // The Qualcomm H264 encoder on SD835 doesn't provide extradata
1277  // immediately, but it becomes available soon after init (without
1278  // any waitable event). In practice, it's available after less
1279  // than 10 ms, but wait for up to 70 ms before giving up.
1280  // Some encoders (Qualcomm's HEVC encoder on SD835, some versions
1281  // of the QSV H264 encoder at least) don't provide extradata this
1282  // way at all, not even after encoding a frame - it's only
1283  // available prepended to frames.
1284  av_usleep(sleep);
1285  total += sleep;
1286  mf_output_type_get(avctx);
1287  if (avctx->extradata)
1288  break;
1289  sleep *= 2;
1290  }
1291  av_log(avctx, AV_LOG_VERBOSE, "%s extradata in %d ms\n",
1292  avctx->extradata ? "Got" : "Didn't get", total / 1000);
1293  }
1294 
1295  return 0;
1296 }
1297 
1298 #if !HAVE_UWP
1299 #define LOAD_MF_FUNCTION(context, func_name) \
1300  context->functions.func_name = (void *)dlsym(context->library, #func_name); \
1301  if (!context->functions.func_name) { \
1302  av_log(context, AV_LOG_ERROR, "DLL mfplat.dll failed to find function "\
1303  #func_name "\n"); \
1304  return AVERROR_UNKNOWN; \
1305  }
1306 #else
1307 // In UWP (which lacks LoadLibrary), just link directly against
1308 // the functions - this requires building with new/complete enough
1309 // import libraries.
1310 #define LOAD_MF_FUNCTION(context, func_name) \
1311  context->functions.func_name = func_name; \
1312  if (!context->functions.func_name) { \
1313  av_log(context, AV_LOG_ERROR, "Failed to find function " #func_name \
1314  "\n"); \
1315  return AVERROR_UNKNOWN; \
1316  }
1317 #endif
1318 
1319 // Windows N editions does not provide MediaFoundation by default.
1320 // So to avoid DLL loading error, MediaFoundation is dynamically loaded except
1321 // on UWP build since LoadLibrary is not available on it.
1323 {
1324  MFContext *c = avctx->priv_data;
1325 
1326 #if !HAVE_UWP
1327  c->library = dlopen("mfplat.dll", 0);
1328  c->d3d_dll = dlopen("D3D11.dll", 0);
1329 
1330  if (!c->library) {
1331  av_log(c, AV_LOG_ERROR, "DLL mfplat.dll failed to open\n");
1332  return AVERROR_UNKNOWN;
1333  }
1334 #endif
1335 
1336  LOAD_MF_FUNCTION(c, MFStartup);
1337  LOAD_MF_FUNCTION(c, MFShutdown);
1338  LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer);
1339  LOAD_MF_FUNCTION(c, MFCreateSample);
1340  LOAD_MF_FUNCTION(c, MFCreateMediaType);
1341  LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer);
1342  LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager);
1343  // MFTEnumEx is missing in Windows Vista's mfplat.dll.
1344  LOAD_MF_FUNCTION(c, MFTEnumEx);
1345 
1346  return 0;
1347 }
1348 
1349 static int mf_close(AVCodecContext *avctx)
1350 {
1351  MFContext *c = avctx->priv_data;
1352 
1353  if (c->codec_api)
1354  ICodecAPI_Release(c->codec_api);
1355 
1356  if (c->async_events)
1357  IMFMediaEventGenerator_Release(c->async_events);
1358 
1359 #if !HAVE_UWP
1360  if (c->library)
1361  ff_free_mf(&c->functions, &c->mft);
1362 
1363  dlclose(c->library);
1364  dlclose(c->d3d_dll);
1365  c->library = NULL;
1366 #else
1367  ff_free_mf(&c->functions, &c->mft);
1368 #endif
1369 
1370  av_frame_free(&c->frame);
1371 
1372  av_freep(&avctx->extradata);
1373  avctx->extradata_size = 0;
1374 
1375  return 0;
1376 }
1377 
1378 static av_cold int mf_init(AVCodecContext *avctx)
1379 {
1380  int ret;
1381  if ((ret = mf_load_library(avctx)) == 0) {
1382  if ((ret = mf_init_encoder(avctx)) == 0) {
1383  return 0;
1384  }
1385  }
1386  return ret;
1387 }
1388 
1389 #define OFFSET(x) offsetof(MFContext, x)
1390 
1391 #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS) \
1392  static const AVClass ff_ ## NAME ## _mf_encoder_class = { \
1393  .class_name = #NAME "_mf", \
1394  .item_name = av_default_item_name, \
1395  .option = OPTS, \
1396  .version = LIBAVUTIL_VERSION_INT, \
1397  }; \
1398  const FFCodec ff_ ## NAME ## _mf_encoder = { \
1399  .p.priv_class = &ff_ ## NAME ## _mf_encoder_class, \
1400  .p.name = #NAME "_mf", \
1401  CODEC_LONG_NAME(#ID " via MediaFoundation"), \
1402  .p.type = AVMEDIA_TYPE_ ## MEDIATYPE, \
1403  .p.id = AV_CODEC_ID_ ## ID, \
1404  .priv_data_size = sizeof(MFContext), \
1405  .init = mf_init, \
1406  .close = mf_close, \
1407  FF_CODEC_RECEIVE_PACKET_CB(mf_receive_packet), \
1408  FMTS \
1409  CAPS \
1410  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
1411  .defaults = DEFAULTS, \
1412  };
1413 
1414 #define AFMTS \
1415  CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16),
1416 #define ACAPS \
1417  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
1418  AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
1419 
1420 MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL);
1421 MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL);
1422 MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL);
1423 
1424 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1425 static const AVOption venc_opts[] = {
1426  {"rate_control", "Select rate control mode", OFFSET(opt_enc_rc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "rate_control"},
1427  { "default", "Default mode", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, .unit = "rate_control"},
1428  { "cbr", "CBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_CBR}, 0, 0, VE, .unit = "rate_control"},
1429  { "pc_vbr", "Peak constrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_PeakConstrainedVBR}, 0, 0, VE, .unit = "rate_control"},
1430  { "u_vbr", "Unconstrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_UnconstrainedVBR}, 0, 0, VE, .unit = "rate_control"},
1431  { "quality", "Quality mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_Quality}, 0, 0, VE, .unit = "rate_control" },
1432  // The following rate_control modes require Windows 8.
1433  { "ld_vbr", "Low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_LowDelayVBR}, 0, 0, VE, .unit = "rate_control"},
1434  { "g_vbr", "Global VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalVBR}, 0, 0, VE, .unit = "rate_control" },
1435  { "gld_vbr", "Global low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR}, 0, 0, VE, .unit = "rate_control"},
1436 
1437  {"scenario", "Select usage scenario", OFFSET(opt_enc_scenario), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "scenario"},
1438  { "default", "Default scenario", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, .unit = "scenario"},
1439  { "display_remoting", "Display remoting", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemoting}, 0, 0, VE, .unit = "scenario"},
1440  { "video_conference", "Video conference", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_VideoConference}, 0, 0, VE, .unit = "scenario"},
1441  { "archive", "Archive", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_Archive}, 0, 0, VE, .unit = "scenario"},
1442  { "live_streaming", "Live streaming", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_LiveStreaming}, 0, 0, VE, .unit = "scenario"},
1443  { "camera_record", "Camera record", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_CameraRecord}, 0, 0, VE, .unit = "scenario"},
1444  { "display_remoting_with_feature_map", "Display remoting with feature map", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap}, 0, 0, VE, .unit = "scenario"},
1445 
1446  {"quality", "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
1447  {"hw_encoding", "Force hardware encoding", OFFSET(opt_enc_hw), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE},
1448  {NULL}
1449 };
1450 
1451 static const FFCodecDefault defaults[] = {
1452  { "g", "0" },
1453  { NULL },
1454 };
1455 
1456 #define VFMTS \
1457  CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_D3D11),
1458 #define VCAPS \
1459  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
1460  AV_CODEC_CAP_DR1,
1461 
1462 MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS, VCAPS, defaults);
1463 MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS, VCAPS, defaults);
1464 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:347
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:1458
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:453
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:1425
mf_choose_input_type
static int mf_choose_input_type(AVCodecContext *avctx)
Definition: mfenc.c:1000
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:1299
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:682
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:421
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:538
MF_ENCODER
#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS)
Definition: mfenc.c:1391
mf_enca_output_type_get
static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:151
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
ff_METransformDrainComplete
@ ff_METransformDrainComplete
Definition: mf_utils.h:154
mf_encv_output_score
static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:782
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
category
category
Definition: openal-dec.c:249
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:1389
mf_receive_packet
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Definition: mfenc.c:620
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:1456
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:451
ff_METransformNeedInput
@ ff_METransformNeedInput
Definition: mf_utils.h:152
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:1115
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
mf_avframe_to_sample
static int mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:480
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:798
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_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:732
ff_METransformMarker
@ ff_METransformMarker
Definition: mf_utils.h:155
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
ff_METransformHaveOutput
@ ff_METransformHaveOutput
Definition: mf_utils.h:153
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:756
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:320
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:452
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:1416
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:403
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:1322
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:500
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:1424
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:2276
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:1088
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
mf_enca_output_adjust
static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:722
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:1192
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:450
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:1378
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:1222
mf_close
static int mf_close(AVCodecContext *avctx)
Definition: mfenc.c:1349
mf_encv_input_adjust
static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:891
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:911
ff_eAVScenarioInfo_VideoConference
@ ff_eAVScenarioInfo_VideoConference
Definition: mf_utils.h:140
AFMTS
#define AFMTS
Definition: mfenc.c:1414
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:1451
mf_encv_input_score
static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
Definition: mfenc.c:874
mf_output_type_get
static int mf_output_type_get(AVCodecContext *avctx)
Definition: mfenc.c:214
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:244
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:1143
mf_a_avframe_to_sample
static int mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
Definition: mfenc.c:299
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:191
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