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 #if FF_API_CODER_TYPE
464 FF_DISABLE_DEPRECATION_WARNINGS
465 if (avctx->coder_type != 0)
466 q->cavlc = avctx->coder_type == FF_CODER_TYPE_VLC;
467 FF_ENABLE_DEPRECATION_WARNINGS
469 q->extco.CAVLC = q->cavlc ? MFX_CODINGOPTION_ON
470 : MFX_CODINGOPTION_UNKNOWN;
472 q->extco.PicTimingSEI = q->pic_timing_sei ?
473 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
476 q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
478 if (avctx->codec_id == AV_CODEC_ID_H264) {
479 if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL)
480 q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ?
481 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
483 if (q->single_sei_nal_unit >= 0)
484 q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
485 if (q->recovery_point_sei >= 0)
486 q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
487 q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering;
490 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco;
493 if (avctx->codec_id == AV_CODEC_ID_H264) {
494 q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
495 q->extco2.Header.BufferSz = sizeof(q->extco2);
497 if (q->int_ref_type >= 0)
498 q->extco2.IntRefType = q->int_ref_type;
499 if (q->int_ref_cycle_size >= 0)
500 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
501 if (q->int_ref_qp_delta != INT16_MIN)
502 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
504 if (q->bitrate_limit >= 0)
505 q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
507 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
509 q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
511 if (q->max_frame_size >= 0)
512 q->extco2.MaxFrameSize = q->max_frame_size;
513 #if QSV_HAVE_MAX_SLICE_SIZE
514 if (q->max_slice_size >= 0)
515 q->extco2.MaxSliceSize = q->max_slice_size;
519 q->extco2.Trellis = q->trellis;
522 #if QSV_HAVE_BREF_TYPE
523 #if FF_API_PRIVATE_OPT
524 FF_DISABLE_DEPRECATION_WARNINGS
525 if (avctx->b_frame_strategy >= 0)
526 q->b_strategy = avctx->b_frame_strategy;
527 FF_ENABLE_DEPRECATION_WARNINGS
529 if (q->b_strategy >= 0)
530 q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
531 if (q->adaptive_i >= 0)
532 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
533 if (q->adaptive_b >= 0)
534 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
537 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
539 #if QSV_VERSION_ATLEAST(1,8)
540 q->extco2.LookAheadDS = q->look_ahead_downsampling;
546 if (!rc_supported(q)) {
547 av_log(avctx, AV_LOG_ERROR,
548 "Selected ratecontrol mode is not supported by the QSV "
549 "runtime. Choose a different mode.\n");
550 return AVERROR(ENOSYS);
556 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
558 AVCPBProperties *cpb_props;
560 uint8_t sps_buf[128];
561 uint8_t pps_buf[128];
563 mfxExtCodingOptionSPSPPS extradata = {
564 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
565 .Header.BufferSz = sizeof(extradata),
566 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
567 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
570 mfxExtCodingOption co = {
571 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
572 .Header.BufferSz = sizeof(co),
575 mfxExtCodingOption2 co2 = {
576 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
577 .Header.BufferSz = sizeof(co2),
581 mfxExtCodingOption3 co3 = {
582 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
583 .Header.BufferSz = sizeof(co3),
587 mfxExtBuffer *ext_buffers[] = {
588 (mfxExtBuffer*)&extradata,
598 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
601 q->param.ExtParam = ext_buffers;
602 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
604 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
606 return ff_qsv_error(ret);
608 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
610 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
611 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
612 return AVERROR_UNKNOWN;
615 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
616 AV_INPUT_BUFFER_PADDING_SIZE);
617 if (!avctx->extradata)
618 return AVERROR(ENOMEM);
620 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
622 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
623 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
624 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
626 cpb_props = ff_add_cpb_side_data(avctx);
628 return AVERROR(ENOMEM);
629 cpb_props->max_bitrate = avctx->rc_max_rate;
630 cpb_props->min_bitrate = avctx->rc_min_rate;
631 cpb_props->avg_bitrate = avctx->bit_rate;
632 cpb_props->buffer_size = avctx->rc_buffer_size;
634 dump_video_param(avctx, q, ext_buffers + 1);
639 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
641 AVQSVContext *qsv = avctx->hwaccel_context;
642 mfxFrameSurface1 *surfaces;
645 nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
647 q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
648 if (!q->opaque_alloc_buf)
649 return AVERROR(ENOMEM);
651 q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
652 if (!q->opaque_surfaces)
653 return AVERROR(ENOMEM);
655 surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
656 for (i = 0; i < nb_surfaces; i++) {
657 surfaces[i].Info = q->req.Info;
658 q->opaque_surfaces[i] = surfaces + i;
661 q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
662 q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
663 q->opaque_alloc.In.Surfaces = q->opaque_surfaces;
664 q->opaque_alloc.In.NumSurface = nb_surfaces;
665 q->opaque_alloc.In.Type = q->req.Type;
667 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
669 qsv->nb_opaque_surfaces = nb_surfaces;
670 qsv->opaque_surfaces = q->opaque_alloc_buf;
671 qsv->opaque_alloc_type = q->req.Type;
676 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
678 int opaque_alloc = 0;
681 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
682 q->param.AsyncDepth = q->async_depth;
684 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
685 (sizeof(AVPacket) + sizeof(mfxSyncPoint*) + sizeof(mfxBitstream*)));
687 return AVERROR(ENOMEM);
689 if (avctx->hwaccel_context) {
690 AVQSVContext *qsv = avctx->hwaccel_context;
692 q->session = qsv->session;
693 q->param.IOPattern = qsv->iopattern;
695 opaque_alloc = qsv->opaque_alloc;
699 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
704 q->session = q->internal_qs.session;
707 ret = init_video_param(avctx, q);
711 ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
712 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
713 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
714 } else if (ret < 0) {
715 av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
716 return ff_qsv_error(ret);
719 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
721 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
722 return ff_qsv_error(ret);
726 ret = qsv_init_opaque_alloc(avctx, q);
731 if (avctx->hwaccel_context) {
732 AVQSVContext *qsv = avctx->hwaccel_context;
735 q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
736 sizeof(*q->extparam));
738 return AVERROR(ENOMEM);
740 q->param.ExtParam = q->extparam;
741 for (i = 0; i < qsv->nb_ext_buffers; i++)
742 q->param.ExtParam[i] = qsv->ext_buffers[i];
743 q->param.NumExtParam = qsv->nb_ext_buffers;
745 for (i = 0; i < q->nb_extparam_internal; i++) {
746 for (j = 0; j < qsv->nb_ext_buffers; j++) {
747 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
750 if (j < qsv->nb_ext_buffers)
753 q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
756 q->param.ExtParam = q->extparam_internal;
757 q->param.NumExtParam = q->nb_extparam_internal;
760 ret = MFXVideoENCODE_Init(q->session, &q->param);
761 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
762 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
763 } else if (ret < 0) {
764 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
765 return ff_qsv_error(ret);
768 ret = qsv_retrieve_enc_params(avctx, q);
770 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
779 static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
783 for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
784 av_free(enc_ctrl->Payload[i]);
786 enc_ctrl->NumPayload = 0;
790 static void clear_unused_frames(QSVEncContext *q)
792 QSVFrame *cur = q->work_frames;
794 if (cur->surface && !cur->surface->Data.Locked) {
796 free_encoder_ctrl_payloads(&cur->enc_ctrl);
797 av_frame_unref(cur->frame);
803 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
805 QSVFrame *frame, **last;
807 clear_unused_frames(q);
809 frame = q->work_frames;
810 last = &q->work_frames;
812 if (!frame->surface) {
821 frame = av_mallocz(sizeof(*frame));
823 return AVERROR(ENOMEM);
824 frame->frame = av_frame_alloc();
827 return AVERROR(ENOMEM);
829 frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
830 if (!frame->enc_ctrl.Payload) {
832 return AVERROR(ENOMEM);
841 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
842 QSVFrame **new_frame)
847 ret = get_free_frame(q, &qf);
851 if (frame->format == AV_PIX_FMT_QSV) {
852 ret = av_frame_ref(qf->frame, frame);
856 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
858 /* make a copy if the input is not padded as libmfx requires */
859 if ( frame->height & (q->height_align - 1) ||
860 frame->linesize[0] & (q->width_align - 1)) {
861 qf->frame->height = FFALIGN(frame->height, q->height_align);
862 qf->frame->width = FFALIGN(frame->width, q->width_align);
864 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
868 qf->frame->height = frame->height;
869 qf->frame->width = frame->width;
870 ret = av_frame_copy(qf->frame, frame);
872 av_frame_unref(qf->frame);
876 ret = av_frame_ref(qf->frame, frame);
881 qf->surface_internal.Info = q->param.mfx.FrameInfo;
883 qf->surface_internal.Info.PicStruct =
884 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
885 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
886 MFX_PICSTRUCT_FIELD_BFF;
887 if (frame->repeat_pict == 1)
888 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
889 else if (frame->repeat_pict == 2)
890 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
891 else if (frame->repeat_pict == 4)
892 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
894 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
895 qf->surface_internal.Data.Y = qf->frame->data[0];
896 qf->surface_internal.Data.UV = qf->frame->data[1];
898 qf->surface = &qf->surface_internal;
901 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
908 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
910 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
911 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
912 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
913 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
914 av_log(avctx, AV_LOG_WARNING,
915 "Interlaced coding is supported"
916 " at Main/High Profile Level 2.1-4.1\n");
920 static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
921 const AVFrame *frame)
923 AVPacket new_pkt = { 0 };
926 mfxFrameSurface1 *surf = NULL;
927 mfxSyncPoint *sync = NULL;
928 QSVFrame *qsv_frame = NULL;
929 mfxEncodeCtrl* enc_ctrl = NULL;
933 ret = submit_frame(q, frame, &qsv_frame);
935 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
940 surf = qsv_frame->surface;
941 enc_ctrl = &qsv_frame->enc_ctrl;
944 ret = av_new_packet(&new_pkt, q->packet_size);
946 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
950 bs = av_mallocz(sizeof(*bs));
952 av_packet_unref(&new_pkt);
953 return AVERROR(ENOMEM);
955 bs->Data = new_pkt.data;
956 bs->MaxLength = new_pkt.size;
958 if (q->set_encode_ctrl_cb) {
959 q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
962 sync = av_mallocz(sizeof(*sync));
965 av_packet_unref(&new_pkt);
966 return AVERROR(ENOMEM);
970 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, sync);
971 if (ret == MFX_WRN_DEVICE_BUSY) {
979 av_packet_unref(&new_pkt);
981 if (ret == MFX_ERR_MORE_DATA)
983 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
984 return ff_qsv_error(ret);
987 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
988 if (frame->interlaced_frame)
989 print_interlace_msg(avctx, q);
991 av_log(avctx, AV_LOG_WARNING,
992 "EncodeFrameAsync returned 'incompatible param' code\n");
995 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
996 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
997 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
1000 av_packet_unref(&new_pkt);
1007 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
1008 AVPacket *pkt, const AVFrame *frame, int *got_packet)
1012 ret = encode_frame(avctx, q, frame);
1016 if (!av_fifo_space(q->async_fifo) ||
1017 (!frame && av_fifo_size(q->async_fifo))) {
1022 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1023 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1024 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1027 ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
1028 } while (ret == MFX_WRN_IN_EXECUTION);
1030 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
1031 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
1032 new_pkt.size = bs->DataLength;
1034 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
1035 bs->FrameType & MFX_FRAMETYPE_xIDR)
1036 new_pkt.flags |= AV_PKT_FLAG_KEY;
1038 #if FF_API_CODED_FRAME
1039 FF_DISABLE_DEPRECATION_WARNINGS
1040 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
1041 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1042 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
1043 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
1044 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
1045 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1046 FF_ENABLE_DEPRECATION_WARNINGS
1053 if (pkt->size < new_pkt.size) {
1054 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1055 pkt->size, new_pkt.size);
1056 av_packet_unref(&new_pkt);
1057 return AVERROR(EINVAL);
1060 memcpy(pkt->data, new_pkt.data, new_pkt.size);
1061 pkt->size = new_pkt.size;
1063 ret = av_packet_copy_props(pkt, &new_pkt);
1064 av_packet_unref(&new_pkt);
1076 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1081 MFXVideoENCODE_Close(q->session);
1084 ff_qsv_close_internal_session(&q->internal_qs);
1086 cur = q->work_frames;
1088 q->work_frames = cur->next;
1089 av_frame_free(&cur->frame);
1090 av_free(cur->enc_ctrl.Payload);
1092 cur = q->work_frames;
1095 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1100 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
1101 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1102 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1106 av_packet_unref(&pkt);
1108 av_fifo_free(q->async_fifo);
1109 q->async_fifo = NULL;
1111 av_freep(&q->opaque_surfaces);
1112 av_buffer_unref(&q->opaque_alloc_buf);
1114 av_freep(&q->extparam);