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