2 * Intel MediaSDK QSV encoder utility functions
4 * copyright (c) 2013 Yukinori Yamazoe
5 * copyright (c) 2015 Anton Khirnov
7 * This file is part of FFmpeg.
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <sys/types.h>
26 #include <mfx/mfxvideo.h>
28 #include "libavutil/common.h"
29 #include "libavutil/mem.h"
30 #include "libavutil/log.h"
31 #include "libavutil/time.h"
32 #include "libavutil/imgutils.h"
33 #include "libavcodec/bytestream.h"
38 #include "qsv_internal.h"
45 { MFX_PROFILE_AVC_BASELINE, "baseline" },
46 { MFX_PROFILE_AVC_MAIN, "main" },
47 { MFX_PROFILE_AVC_EXTENDED, "extended" },
48 { MFX_PROFILE_AVC_HIGH, "high" },
49 #if QSV_VERSION_ATLEAST(1, 15)
50 { MFX_PROFILE_AVC_HIGH_422, "high 422" },
52 #if QSV_VERSION_ATLEAST(1, 4)
53 { MFX_PROFILE_AVC_CONSTRAINED_BASELINE, "constrained baseline" },
54 { MFX_PROFILE_AVC_CONSTRAINED_HIGH, "constrained high" },
55 { MFX_PROFILE_AVC_PROGRESSIVE_HIGH, "progressive high" },
57 { MFX_PROFILE_MPEG2_SIMPLE, "simple" },
58 { MFX_PROFILE_MPEG2_MAIN, "main" },
59 { MFX_PROFILE_MPEG2_HIGH, "high" },
60 { MFX_PROFILE_VC1_SIMPLE, "simple" },
61 { MFX_PROFILE_VC1_MAIN, "main" },
62 { MFX_PROFILE_VC1_ADVANCED, "advanced" },
63 #if QSV_VERSION_ATLEAST(1, 8)
64 { MFX_PROFILE_HEVC_MAIN, "main" },
65 { MFX_PROFILE_HEVC_MAIN10, "main10" },
66 { MFX_PROFILE_HEVC_MAINSP, "mainsp" },
70 static const char *print_profile(mfxU16 profile)
73 for (i = 0; i < FF_ARRAY_ELEMS(profile_names); i++)
74 if (profile == profile_names[i].profile)
75 return profile_names[i].name;
83 { MFX_RATECONTROL_CBR, "CBR" },
84 { MFX_RATECONTROL_VBR, "VBR" },
85 { MFX_RATECONTROL_CQP, "CQP" },
86 { MFX_RATECONTROL_AVBR, "AVBR" },
88 { MFX_RATECONTROL_LA, "LA" },
91 { MFX_RATECONTROL_ICQ, "ICQ" },
92 { MFX_RATECONTROL_LA_ICQ, "LA_ICQ" },
95 { MFX_RATECONTROL_VCM, "VCM" },
97 #if QSV_VERSION_ATLEAST(1, 10)
98 { MFX_RATECONTROL_LA_EXT, "LA_EXT" },
101 { MFX_RATECONTROL_LA_HRD, "LA_HRD" },
104 { MFX_RATECONTROL_QVBR, "QVBR" },
108 static const char *print_ratecontrol(mfxU16 rc_mode)
111 for (i = 0; i < FF_ARRAY_ELEMS(rc_names); i++)
112 if (rc_mode == rc_names[i].rc_mode)
113 return rc_names[i].name;
117 static const char *print_threestate(mfxU16 val)
119 if (val == MFX_CODINGOPTION_ON)
121 else if (val == MFX_CODINGOPTION_OFF)
126 static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
127 mfxExtBuffer **coding_opts)
129 mfxInfoMFX *info = &q->param.mfx;
131 mfxExtCodingOption *co = (mfxExtCodingOption*)coding_opts[0];
133 mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
136 mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
139 av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
140 print_profile(info->CodecProfile), info->CodecLevel);
142 av_log(avctx, AV_LOG_VERBOSE, "GopPicSize: %"PRIu16"; GopRefDist: %"PRIu16"; GopOptFlag: ",
143 info->GopPicSize, info->GopRefDist);
144 if (info->GopOptFlag & MFX_GOP_CLOSED)
145 av_log(avctx, AV_LOG_VERBOSE, "closed ");
146 if (info->GopOptFlag & MFX_GOP_STRICT)
147 av_log(avctx, AV_LOG_VERBOSE, "strict ");
148 av_log(avctx, AV_LOG_VERBOSE, "; IdrInterval: %"PRIu16"\n", info->IdrInterval);
150 av_log(avctx, AV_LOG_VERBOSE, "TargetUsage: %"PRIu16"; RateControlMethod: %s\n",
151 info->TargetUsage, print_ratecontrol(info->RateControlMethod));
153 if (info->RateControlMethod == MFX_RATECONTROL_CBR ||
154 info->RateControlMethod == MFX_RATECONTROL_VBR
156 || info->RateControlMethod == MFX_RATECONTROL_VCM
159 av_log(avctx, AV_LOG_VERBOSE,
160 "InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"\n",
161 info->InitialDelayInKB, info->TargetKbps, info->MaxKbps);
162 } else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
163 av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",
164 info->QPI, info->QPP, info->QPB);
165 } else if (info->RateControlMethod == MFX_RATECONTROL_AVBR) {
166 av_log(avctx, AV_LOG_VERBOSE,
167 "TargetKbps: %"PRIu16"; Accuracy: %"PRIu16"; Convergence: %"PRIu16"\n",
168 info->TargetKbps, info->Accuracy, info->Convergence);
171 else if (info->RateControlMethod == MFX_RATECONTROL_LA
173 || info->RateControlMethod == MFX_RATECONTROL_LA_HRD
176 av_log(avctx, AV_LOG_VERBOSE,
177 "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
178 info->TargetKbps, co2->LookAheadDepth);
182 else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
183 av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);
184 } else if (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ) {
185 av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
186 info->ICQQuality, co2->LookAheadDepth);
190 else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
191 av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
196 av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",
197 info->NumSlice, info->NumRefFrame);
198 av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
199 print_threestate(co->RateDistortionOpt));
202 av_log(avctx, AV_LOG_VERBOSE,
203 "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
204 print_threestate(co->RecoveryPointSEI), co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
206 av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %"PRIu16"; ", co2->MaxFrameSize);
207 #if QSV_HAVE_MAX_SLICE_SIZE
208 av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %"PRIu16"; ", co2->MaxSliceSize);
210 av_log(avctx, AV_LOG_VERBOSE, "\n");
212 av_log(avctx, AV_LOG_VERBOSE,
213 "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
214 print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
215 print_threestate(co2->ExtBRC));
218 av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
219 if (co2->Trellis & MFX_TRELLIS_OFF) {
220 av_log(avctx, AV_LOG_VERBOSE, "off");
221 } else if (!co2->Trellis) {
222 av_log(avctx, AV_LOG_VERBOSE, "auto");
224 if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE, "I");
225 if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE, "P");
226 if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE, "B");
228 av_log(avctx, AV_LOG_VERBOSE, "\n");
231 #if QSV_VERSION_ATLEAST(1, 8)
232 av_log(avctx, AV_LOG_VERBOSE,
233 "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
234 print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
235 switch (co2->LookAheadDS) {
236 case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off"); break;
237 case MFX_LOOKAHEAD_DS_2x: av_log(avctx, AV_LOG_VERBOSE, "2x"); break;
238 case MFX_LOOKAHEAD_DS_4x: av_log(avctx, AV_LOG_VERBOSE, "4x"); break;
239 default: av_log(avctx, AV_LOG_VERBOSE, "unknown"); break;
241 av_log(avctx, AV_LOG_VERBOSE, "\n");
243 av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
244 print_threestate(co2->AdaptiveI), print_threestate(co2->AdaptiveB));
245 switch (co2->BRefType) {
246 case MFX_B_REF_OFF: av_log(avctx, AV_LOG_VERBOSE, "off"); break;
247 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid"); break;
248 default: av_log(avctx, AV_LOG_VERBOSE, "auto"); break;
250 av_log(avctx, AV_LOG_VERBOSE, "\n");
253 #if QSV_VERSION_ATLEAST(1, 9)
254 av_log(avctx, AV_LOG_VERBOSE,
255 "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
256 co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
260 if (avctx->codec_id == AV_CODEC_ID_H264) {
261 av_log(avctx, AV_LOG_VERBOSE, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16"\n",
262 co->CAVLC == MFX_CODINGOPTION_ON ? "CAVLC" : "CABAC", co->MaxDecFrameBuffering);
263 av_log(avctx, AV_LOG_VERBOSE,
264 "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",
265 print_threestate(co->NalHrdConformance), print_threestate(co->SingleSeiNalUnit),
266 print_threestate(co->VuiVclHrdParameters), print_threestate(co->VuiNalHrdParameters));
270 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
275 int want_la = q->look_ahead;
276 int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
277 int want_vcm = q->vcm;
279 if (want_la && !QSV_HAVE_LA) {
280 av_log(avctx, AV_LOG_ERROR,
281 "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
282 return AVERROR(ENOSYS);
284 if (want_vcm && !QSV_HAVE_VCM) {
285 av_log(avctx, AV_LOG_ERROR,
286 "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
287 return AVERROR(ENOSYS);
290 if (want_la + want_qscale + want_vcm > 1) {
291 av_log(avctx, AV_LOG_ERROR,
292 "More than one of: { constant qscale, lookahead, VCM } requested, "
293 "only one of them can be used at a time.\n");
294 return AVERROR(EINVAL);
298 rc_mode = MFX_RATECONTROL_CQP;
299 rc_desc = "constant quantization parameter (CQP)";
303 rc_mode = MFX_RATECONTROL_VCM;
304 rc_desc = "video conferencing mode (VCM)";
309 rc_mode = MFX_RATECONTROL_LA;
310 rc_desc = "VBR with lookahead (LA)";
313 if (avctx->global_quality > 0) {
314 rc_mode = MFX_RATECONTROL_LA_ICQ;
315 rc_desc = "intelligent constant quality with lookahead (LA_ICQ)";
321 else if (avctx->global_quality > 0) {
322 rc_mode = MFX_RATECONTROL_ICQ;
323 rc_desc = "intelligent constant quality (ICQ)";
326 else if (avctx->rc_max_rate == avctx->bit_rate) {
327 rc_mode = MFX_RATECONTROL_CBR;
328 rc_desc = "constant bitrate (CBR)";
329 } else if (!avctx->rc_max_rate) {
330 rc_mode = MFX_RATECONTROL_AVBR;
331 rc_desc = "average variable bitrate (AVBR)";
333 rc_mode = MFX_RATECONTROL_VBR;
334 rc_desc = "variable bitrate (VBR)";
337 q->param.mfx.RateControlMethod = rc_mode;
338 av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", rc_desc);
343 static int rc_supported(QSVEncContext *q)
345 mfxVideoParam param_out = { .mfx.CodecId = q->param.mfx.CodecId };
348 ret = MFXVideoENCODE_Query(q->session, &q->param, ¶m_out);
350 param_out.mfx.RateControlMethod != q->param.mfx.RateControlMethod)
355 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
360 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
363 q->param.mfx.CodecId = ret;
365 q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
367 if (avctx->level > 0)
368 q->param.mfx.CodecLevel = avctx->level;
370 q->param.mfx.CodecProfile = q->profile;
371 q->param.mfx.TargetUsage = q->preset;
372 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
373 q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1;
374 q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
376 q->param.mfx.IdrInterval = q->idr_interval;
377 q->param.mfx.NumSlice = avctx->slices;
378 q->param.mfx.NumRefFrame = FFMAX(0, avctx->refs);
379 q->param.mfx.EncodedOrder = 0;
380 q->param.mfx.BufferSizeInKB = 0;
382 q->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
383 q->param.mfx.FrameInfo.CropX = 0;
384 q->param.mfx.FrameInfo.CropY = 0;
385 q->param.mfx.FrameInfo.CropW = avctx->width;
386 q->param.mfx.FrameInfo.CropH = avctx->height;
387 q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num;
388 q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den;
389 q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
390 q->param.mfx.FrameInfo.BitDepthLuma = 8;
391 q->param.mfx.FrameInfo.BitDepthChroma = 8;
392 q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
394 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
395 /* A true field layout (TFF or BFF) is not important here,
396 it will specified later during frame encoding. But it is important
397 to specify is frame progressive or not because allowed heigh alignment
400 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
401 q->height_align = 32;
403 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
404 q->height_align = 16;
406 q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
408 if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
409 q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
410 q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
412 q->param.mfx.FrameInfo.FrameRateExtN = avctx->time_base.den;
413 q->param.mfx.FrameInfo.FrameRateExtD = avctx->time_base.num;
416 ret = select_rc_mode(avctx, q);
420 switch (q->param.mfx.RateControlMethod) {
421 case MFX_RATECONTROL_CBR:
422 case MFX_RATECONTROL_VBR:
424 case MFX_RATECONTROL_VCM:
426 q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
427 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
428 q->param.mfx.MaxKbps = avctx->rc_max_rate / 1000;
430 case MFX_RATECONTROL_CQP:
431 quant = avctx->global_quality / FF_QP2LAMBDA;
433 q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
434 q->param.mfx.QPP = av_clip(quant, 0, 51);
435 q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
438 case MFX_RATECONTROL_AVBR:
439 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
440 q->param.mfx.Convergence = q->avbr_convergence;
441 q->param.mfx.Accuracy = q->avbr_accuracy;
444 case MFX_RATECONTROL_LA:
445 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
446 q->extco2.LookAheadDepth = q->look_ahead_depth;
449 case MFX_RATECONTROL_LA_ICQ:
450 q->extco2.LookAheadDepth = q->look_ahead_depth;
451 case MFX_RATECONTROL_ICQ:
452 q->param.mfx.ICQQuality = avctx->global_quality;
458 // the HEVC encoder plugin currently fails if coding options
460 if (avctx->codec_id != AV_CODEC_ID_HEVC) {
461 q->extco.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
462 q->extco.Header.BufferSz = sizeof(q->extco);
463 q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ?
464 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
466 q->extco.PicTimingSEI = q->pic_timing_sei ?
467 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
470 q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
472 if (avctx->codec_id == AV_CODEC_ID_H264) {
473 if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL)
474 q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ?
475 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
477 if (q->single_sei_nal_unit >= 0)
478 q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
479 if (q->recovery_point_sei >= 0)
480 q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
481 q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering;
484 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco;
487 if (avctx->codec_id == AV_CODEC_ID_H264) {
488 q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
489 q->extco2.Header.BufferSz = sizeof(q->extco2);
491 if (q->int_ref_type >= 0)
492 q->extco2.IntRefType = q->int_ref_type;
493 if (q->int_ref_cycle_size >= 0)
494 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
495 if (q->int_ref_qp_delta != INT16_MIN)
496 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
498 if (q->bitrate_limit >= 0)
499 q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
501 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
503 q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
505 if (q->max_frame_size >= 0)
506 q->extco2.MaxFrameSize = q->max_frame_size;
507 #if QSV_HAVE_MAX_SLICE_SIZE
508 if (q->max_slice_size >= 0)
509 q->extco2.MaxSliceSize = q->max_slice_size;
513 q->extco2.Trellis = q->trellis;
516 #if QSV_HAVE_BREF_TYPE
517 #if FF_API_PRIVATE_OPT
518 FF_DISABLE_DEPRECATION_WARNINGS
519 if (avctx->b_frame_strategy >= 0)
520 q->b_strategy = avctx->b_frame_strategy;
521 FF_ENABLE_DEPRECATION_WARNINGS
523 if (q->b_strategy >= 0)
524 q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
525 if (q->adaptive_i >= 0)
526 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
527 if (q->adaptive_b >= 0)
528 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
531 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
533 #if QSV_VERSION_ATLEAST(1,8)
534 q->extco2.LookAheadDS = q->look_ahead_downsampling;
540 if (!rc_supported(q)) {
541 av_log(avctx, AV_LOG_ERROR,
542 "Selected ratecontrol mode is not supported by the QSV "
543 "runtime. Choose a different mode.\n");
544 return AVERROR(ENOSYS);
550 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
552 AVCPBProperties *cpb_props;
554 uint8_t sps_buf[128];
555 uint8_t pps_buf[128];
557 mfxExtCodingOptionSPSPPS extradata = {
558 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
559 .Header.BufferSz = sizeof(extradata),
560 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
561 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
564 mfxExtCodingOption co = {
565 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
566 .Header.BufferSz = sizeof(co),
569 mfxExtCodingOption2 co2 = {
570 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
571 .Header.BufferSz = sizeof(co2),
575 mfxExtCodingOption3 co3 = {
576 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
577 .Header.BufferSz = sizeof(co3),
581 mfxExtBuffer *ext_buffers[] = {
582 (mfxExtBuffer*)&extradata,
592 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
595 q->param.ExtParam = ext_buffers;
596 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
598 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
600 return ff_qsv_error(ret);
602 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
604 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
605 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
606 return AVERROR_UNKNOWN;
609 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
610 AV_INPUT_BUFFER_PADDING_SIZE);
611 if (!avctx->extradata)
612 return AVERROR(ENOMEM);
614 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
616 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
617 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
618 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
620 cpb_props = ff_add_cpb_side_data(avctx);
622 return AVERROR(ENOMEM);
623 cpb_props->max_bitrate = avctx->rc_max_rate;
624 cpb_props->min_bitrate = avctx->rc_min_rate;
625 cpb_props->avg_bitrate = avctx->bit_rate;
626 cpb_props->buffer_size = avctx->rc_buffer_size;
628 dump_video_param(avctx, q, ext_buffers + 1);
633 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
635 AVQSVContext *qsv = avctx->hwaccel_context;
636 mfxFrameSurface1 *surfaces;
639 nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
641 q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
642 if (!q->opaque_alloc_buf)
643 return AVERROR(ENOMEM);
645 q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
646 if (!q->opaque_surfaces)
647 return AVERROR(ENOMEM);
649 surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
650 for (i = 0; i < nb_surfaces; i++) {
651 surfaces[i].Info = q->req.Info;
652 q->opaque_surfaces[i] = surfaces + i;
655 q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
656 q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
657 q->opaque_alloc.In.Surfaces = q->opaque_surfaces;
658 q->opaque_alloc.In.NumSurface = nb_surfaces;
659 q->opaque_alloc.In.Type = q->req.Type;
661 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
663 qsv->nb_opaque_surfaces = nb_surfaces;
664 qsv->opaque_surfaces = q->opaque_alloc_buf;
665 qsv->opaque_alloc_type = q->req.Type;
670 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
672 int opaque_alloc = 0;
675 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
676 q->param.AsyncDepth = q->async_depth;
678 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
679 (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
681 return AVERROR(ENOMEM);
683 if (avctx->hwaccel_context) {
684 AVQSVContext *qsv = avctx->hwaccel_context;
686 q->session = qsv->session;
687 q->param.IOPattern = qsv->iopattern;
689 opaque_alloc = qsv->opaque_alloc;
693 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
698 q->session = q->internal_qs.session;
701 ret = init_video_param(avctx, q);
705 ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
706 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
707 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
708 } else if (ret < 0) {
709 av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
710 return ff_qsv_error(ret);
713 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
715 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
716 return ff_qsv_error(ret);
720 ret = qsv_init_opaque_alloc(avctx, q);
725 if (avctx->hwaccel_context) {
726 AVQSVContext *qsv = avctx->hwaccel_context;
729 q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
730 sizeof(*q->extparam));
732 return AVERROR(ENOMEM);
734 q->param.ExtParam = q->extparam;
735 for (i = 0; i < qsv->nb_ext_buffers; i++)
736 q->param.ExtParam[i] = qsv->ext_buffers[i];
737 q->param.NumExtParam = qsv->nb_ext_buffers;
739 for (i = 0; i < q->nb_extparam_internal; i++) {
740 for (j = 0; j < qsv->nb_ext_buffers; j++) {
741 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
744 if (j < qsv->nb_ext_buffers)
747 q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
750 q->param.ExtParam = q->extparam_internal;
751 q->param.NumExtParam = q->nb_extparam_internal;
754 ret = MFXVideoENCODE_Init(q->session, &q->param);
755 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
756 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
757 } else if (ret < 0) {
758 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
759 return ff_qsv_error(ret);
762 ret = qsv_retrieve_enc_params(avctx, q);
764 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
773 static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
777 for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
778 mfxPayload* pay = enc_ctrl->Payload[i];
779 av_free(enc_ctrl->Payload[i]->Data);
782 enc_ctrl->NumPayload = 0;
786 static void clear_unused_frames(QSVEncContext *q)
788 QSVFrame *cur = q->work_frames;
790 if (cur->surface && !cur->surface->Data.Locked) {
792 free_encoder_ctrl_payloads(&cur->enc_ctrl);
793 av_frame_unref(cur->frame);
799 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
801 QSVFrame *frame, **last;
803 clear_unused_frames(q);
805 frame = q->work_frames;
806 last = &q->work_frames;
808 if (!frame->surface) {
817 frame = av_mallocz(sizeof(*frame));
819 return AVERROR(ENOMEM);
820 frame->frame = av_frame_alloc();
823 return AVERROR(ENOMEM);
825 frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
826 if (!frame->enc_ctrl.Payload) {
828 return AVERROR(ENOMEM);
837 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
838 QSVFrame **new_frame)
843 ret = get_free_frame(q, &qf);
847 if (frame->format == AV_PIX_FMT_QSV) {
848 ret = av_frame_ref(qf->frame, frame);
852 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
854 /* make a copy if the input is not padded as libmfx requires */
855 if ( frame->height & (q->height_align - 1) ||
856 frame->linesize[0] & (q->width_align - 1)) {
857 qf->frame->height = FFALIGN(frame->height, q->height_align);
858 qf->frame->width = FFALIGN(frame->width, q->width_align);
860 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
864 qf->frame->height = frame->height;
865 qf->frame->width = frame->width;
866 ret = av_frame_copy(qf->frame, frame);
868 av_frame_unref(qf->frame);
872 ret = av_frame_ref(qf->frame, frame);
877 qf->surface_internal.Info = q->param.mfx.FrameInfo;
879 qf->surface_internal.Info.PicStruct =
880 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
881 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
882 MFX_PICSTRUCT_FIELD_BFF;
883 if (frame->repeat_pict == 1)
884 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
885 else if (frame->repeat_pict == 2)
886 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
887 else if (frame->repeat_pict == 4)
888 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
890 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
891 qf->surface_internal.Data.Y = qf->frame->data[0];
892 qf->surface_internal.Data.UV = qf->frame->data[1];
894 qf->surface = &qf->surface_internal;
897 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
904 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
906 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
907 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
908 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
909 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
910 av_log(avctx, AV_LOG_WARNING,
911 "Interlaced coding is supported"
912 " at Main/High Profile Level 2.1-4.1\n");
916 static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
917 const AVFrame *frame)
919 AVPacket new_pkt = { 0 };
922 mfxFrameSurface1 *surf = NULL;
923 mfxSyncPoint sync = NULL;
924 QSVFrame *qsv_frame = NULL;
925 mfxEncodeCtrl* enc_ctrl = NULL;
929 ret = submit_frame(q, frame, &qsv_frame);
931 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
936 surf = qsv_frame->surface;
937 enc_ctrl = &qsv_frame->enc_ctrl;
940 ret = av_new_packet(&new_pkt, q->packet_size);
942 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
946 bs = av_mallocz(sizeof(*bs));
948 av_packet_unref(&new_pkt);
949 return AVERROR(ENOMEM);
951 bs->Data = new_pkt.data;
952 bs->MaxLength = new_pkt.size;
954 if (q->set_encode_ctrl_cb) {
955 q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
959 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, &sync);
960 if (ret == MFX_WRN_DEVICE_BUSY) {
968 av_packet_unref(&new_pkt);
970 if (ret == MFX_ERR_MORE_DATA)
972 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
973 return ff_qsv_error(ret);
976 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
977 if (frame->interlaced_frame)
978 print_interlace_msg(avctx, q);
980 av_log(avctx, AV_LOG_WARNING,
981 "EncodeFrameAsync returned 'incompatible param' code\n");
984 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
985 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
986 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
988 av_packet_unref(&new_pkt);
995 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
996 AVPacket *pkt, const AVFrame *frame, int *got_packet)
1000 ret = encode_frame(avctx, q, frame);
1004 if (!av_fifo_space(q->async_fifo) ||
1005 (!frame && av_fifo_size(q->async_fifo))) {
1010 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1011 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1012 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1015 ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
1016 } while (ret == MFX_WRN_IN_EXECUTION);
1018 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
1019 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
1020 new_pkt.size = bs->DataLength;
1022 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
1023 bs->FrameType & MFX_FRAMETYPE_xIDR)
1024 new_pkt.flags |= AV_PKT_FLAG_KEY;
1026 #if FF_API_CODED_FRAME
1027 FF_DISABLE_DEPRECATION_WARNINGS
1028 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
1029 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1030 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
1031 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
1032 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
1033 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1034 FF_ENABLE_DEPRECATION_WARNINGS
1040 if (pkt->size < new_pkt.size) {
1041 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1042 pkt->size, new_pkt.size);
1043 av_packet_unref(&new_pkt);
1044 return AVERROR(EINVAL);
1047 memcpy(pkt->data, new_pkt.data, new_pkt.size);
1048 pkt->size = new_pkt.size;
1050 ret = av_packet_copy_props(pkt, &new_pkt);
1051 av_packet_unref(&new_pkt);
1063 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1068 MFXVideoENCODE_Close(q->session);
1071 ff_qsv_close_internal_session(&q->internal_qs);
1073 cur = q->work_frames;
1075 q->work_frames = cur->next;
1076 av_frame_free(&cur->frame);
1077 av_free(cur->enc_ctrl.Payload);
1079 cur = q->work_frames;
1082 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1087 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
1088 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1089 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1092 av_packet_unref(&pkt);
1094 av_fifo_free(q->async_fifo);
1095 q->async_fifo = NULL;
1097 av_freep(&q->opaque_surfaces);
1098 av_buffer_unref(&q->opaque_alloc_buf);
1100 av_freep(&q->extparam);