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