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