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 (avctx->b_frame_strategy >= 0)
518 q->extco2.BRefType = avctx->b_frame_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
519 if (q->adaptive_i >= 0)
520 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
521 if (q->adaptive_b >= 0)
522 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
525 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
527 #if QSV_VERSION_ATLEAST(1,8)
528 q->extco2.LookAheadDS = q->look_ahead_downsampling;
534 if (!rc_supported(q)) {
535 av_log(avctx, AV_LOG_ERROR,
536 "Selected ratecontrol mode is not supported by the QSV "
537 "runtime. Choose a different mode.\n");
538 return AVERROR(ENOSYS);
544 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
546 AVCPBProperties *cpb_props;
548 uint8_t sps_buf[128];
549 uint8_t pps_buf[128];
551 mfxExtCodingOptionSPSPPS extradata = {
552 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
553 .Header.BufferSz = sizeof(extradata),
554 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
555 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
558 mfxExtCodingOption co = {
559 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
560 .Header.BufferSz = sizeof(co),
563 mfxExtCodingOption2 co2 = {
564 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
565 .Header.BufferSz = sizeof(co2),
569 mfxExtCodingOption3 co3 = {
570 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
571 .Header.BufferSz = sizeof(co3),
575 mfxExtBuffer *ext_buffers[] = {
576 (mfxExtBuffer*)&extradata,
586 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
589 q->param.ExtParam = ext_buffers;
590 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
592 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
594 return ff_qsv_error(ret);
596 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
598 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
599 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
600 return AVERROR_UNKNOWN;
603 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
604 AV_INPUT_BUFFER_PADDING_SIZE);
605 if (!avctx->extradata)
606 return AVERROR(ENOMEM);
608 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
610 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
611 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
612 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
614 cpb_props = ff_add_cpb_side_data(avctx);
616 return AVERROR(ENOMEM);
617 cpb_props->max_bitrate = avctx->rc_max_rate;
618 cpb_props->min_bitrate = avctx->rc_min_rate;
619 cpb_props->avg_bitrate = avctx->bit_rate;
620 cpb_props->buffer_size = avctx->rc_buffer_size;
622 dump_video_param(avctx, q, ext_buffers + 1);
627 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
629 AVQSVContext *qsv = avctx->hwaccel_context;
630 mfxFrameSurface1 *surfaces;
633 nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
635 q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
636 if (!q->opaque_alloc_buf)
637 return AVERROR(ENOMEM);
639 q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
640 if (!q->opaque_surfaces)
641 return AVERROR(ENOMEM);
643 surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
644 for (i = 0; i < nb_surfaces; i++) {
645 surfaces[i].Info = q->req.Info;
646 q->opaque_surfaces[i] = surfaces + i;
649 q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
650 q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
651 q->opaque_alloc.In.Surfaces = q->opaque_surfaces;
652 q->opaque_alloc.In.NumSurface = nb_surfaces;
653 q->opaque_alloc.In.Type = q->req.Type;
655 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
657 qsv->nb_opaque_surfaces = nb_surfaces;
658 qsv->opaque_surfaces = q->opaque_alloc_buf;
659 qsv->opaque_alloc_type = q->req.Type;
664 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
666 int opaque_alloc = 0;
669 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
670 q->param.AsyncDepth = q->async_depth;
672 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
673 (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
675 return AVERROR(ENOMEM);
677 if (avctx->hwaccel_context) {
678 AVQSVContext *qsv = avctx->hwaccel_context;
680 q->session = qsv->session;
681 q->param.IOPattern = qsv->iopattern;
683 opaque_alloc = qsv->opaque_alloc;
687 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
692 q->session = q->internal_qs.session;
695 ret = init_video_param(avctx, q);
699 ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
700 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
701 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
702 } else if (ret < 0) {
703 av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
704 return ff_qsv_error(ret);
707 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
709 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
710 return ff_qsv_error(ret);
714 ret = qsv_init_opaque_alloc(avctx, q);
719 if (avctx->hwaccel_context) {
720 AVQSVContext *qsv = avctx->hwaccel_context;
723 q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
724 sizeof(*q->extparam));
726 return AVERROR(ENOMEM);
728 q->param.ExtParam = q->extparam;
729 for (i = 0; i < qsv->nb_ext_buffers; i++)
730 q->param.ExtParam[i] = qsv->ext_buffers[i];
731 q->param.NumExtParam = qsv->nb_ext_buffers;
733 for (i = 0; i < q->nb_extparam_internal; i++) {
734 for (j = 0; j < qsv->nb_ext_buffers; j++) {
735 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
738 if (j < qsv->nb_ext_buffers)
741 q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
744 q->param.ExtParam = q->extparam_internal;
745 q->param.NumExtParam = q->nb_extparam_internal;
748 ret = MFXVideoENCODE_Init(q->session, &q->param);
749 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
750 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
751 } else if (ret < 0) {
752 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
753 return ff_qsv_error(ret);
756 ret = qsv_retrieve_enc_params(avctx, q);
758 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
767 static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
771 for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
772 mfxPayload* pay = enc_ctrl->Payload[i];
773 av_free(enc_ctrl->Payload[i]->Data);
776 enc_ctrl->NumPayload = 0;
780 static void clear_unused_frames(QSVEncContext *q)
782 QSVFrame *cur = q->work_frames;
784 if (cur->surface && !cur->surface->Data.Locked) {
786 free_encoder_ctrl_payloads(&cur->enc_ctrl);
787 av_frame_unref(cur->frame);
793 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
795 QSVFrame *frame, **last;
797 clear_unused_frames(q);
799 frame = q->work_frames;
800 last = &q->work_frames;
802 if (!frame->surface) {
811 frame = av_mallocz(sizeof(*frame));
813 return AVERROR(ENOMEM);
814 frame->frame = av_frame_alloc();
817 return AVERROR(ENOMEM);
819 frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
820 if (!frame->enc_ctrl.Payload) {
822 return AVERROR(ENOMEM);
831 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
832 QSVFrame **new_frame)
837 ret = get_free_frame(q, &qf);
841 if (frame->format == AV_PIX_FMT_QSV) {
842 ret = av_frame_ref(qf->frame, frame);
846 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
848 /* make a copy if the input is not padded as libmfx requires */
849 if ( frame->height & (q->height_align - 1) ||
850 frame->linesize[0] & (q->width_align - 1)) {
851 qf->frame->height = FFALIGN(frame->height, q->height_align);
852 qf->frame->width = FFALIGN(frame->width, q->width_align);
854 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
858 qf->frame->height = frame->height;
859 qf->frame->width = frame->width;
860 ret = av_frame_copy(qf->frame, frame);
862 av_frame_unref(qf->frame);
866 ret = av_frame_ref(qf->frame, frame);
871 qf->surface_internal.Info = q->param.mfx.FrameInfo;
873 qf->surface_internal.Info.PicStruct =
874 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
875 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
876 MFX_PICSTRUCT_FIELD_BFF;
877 if (frame->repeat_pict == 1)
878 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
879 else if (frame->repeat_pict == 2)
880 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
881 else if (frame->repeat_pict == 4)
882 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
884 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
885 qf->surface_internal.Data.Y = qf->frame->data[0];
886 qf->surface_internal.Data.UV = qf->frame->data[1];
888 qf->surface = &qf->surface_internal;
891 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
898 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
900 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
901 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
902 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
903 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
904 av_log(avctx, AV_LOG_WARNING,
905 "Interlaced coding is supported"
906 " at Main/High Profile Level 2.1-4.1\n");
910 static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
911 const AVFrame *frame)
913 AVPacket new_pkt = { 0 };
916 mfxFrameSurface1 *surf = NULL;
917 mfxSyncPoint sync = NULL;
918 QSVFrame *qsv_frame = NULL;
919 mfxEncodeCtrl* enc_ctrl = NULL;
923 ret = submit_frame(q, frame, &qsv_frame);
925 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
930 surf = qsv_frame->surface;
931 enc_ctrl = &qsv_frame->enc_ctrl;
934 ret = av_new_packet(&new_pkt, q->packet_size);
936 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
940 bs = av_mallocz(sizeof(*bs));
942 av_packet_unref(&new_pkt);
943 return AVERROR(ENOMEM);
945 bs->Data = new_pkt.data;
946 bs->MaxLength = new_pkt.size;
948 if (q->set_encode_ctrl_cb) {
949 q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
953 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, &sync);
954 if (ret == MFX_WRN_DEVICE_BUSY) {
962 av_packet_unref(&new_pkt);
964 if (ret == MFX_ERR_MORE_DATA)
966 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
967 return ff_qsv_error(ret);
970 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
971 if (frame->interlaced_frame)
972 print_interlace_msg(avctx, q);
974 av_log(avctx, AV_LOG_WARNING,
975 "EncodeFrameAsync returned 'incompatible param' code\n");
978 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
979 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
980 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
982 av_packet_unref(&new_pkt);
989 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
990 AVPacket *pkt, const AVFrame *frame, int *got_packet)
994 ret = encode_frame(avctx, q, frame);
998 if (!av_fifo_space(q->async_fifo) ||
999 (!frame && av_fifo_size(q->async_fifo))) {
1004 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1005 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1006 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1009 ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
1010 } while (ret == MFX_WRN_IN_EXECUTION);
1012 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
1013 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
1014 new_pkt.size = bs->DataLength;
1016 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
1017 bs->FrameType & MFX_FRAMETYPE_xIDR)
1018 new_pkt.flags |= AV_PKT_FLAG_KEY;
1020 #if FF_API_CODED_FRAME
1021 FF_DISABLE_DEPRECATION_WARNINGS
1022 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
1023 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1024 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
1025 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
1026 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
1027 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1028 FF_ENABLE_DEPRECATION_WARNINGS
1034 if (pkt->size < new_pkt.size) {
1035 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1036 pkt->size, new_pkt.size);
1037 av_packet_unref(&new_pkt);
1038 return AVERROR(EINVAL);
1041 memcpy(pkt->data, new_pkt.data, new_pkt.size);
1042 pkt->size = new_pkt.size;
1044 ret = av_packet_copy_props(pkt, &new_pkt);
1045 av_packet_unref(&new_pkt);
1057 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1062 MFXVideoENCODE_Close(q->session);
1065 ff_qsv_close_internal_session(&q->internal_qs);
1067 cur = q->work_frames;
1069 q->work_frames = cur->next;
1070 av_frame_free(&cur->frame);
1071 av_free(cur->enc_ctrl.Payload);
1073 cur = q->work_frames;
1076 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1081 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
1082 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1083 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1086 av_packet_unref(&pkt);
1088 av_fifo_free(q->async_fifo);
1089 q->async_fifo = NULL;
1091 av_freep(&q->opaque_surfaces);
1092 av_buffer_unref(&q->opaque_alloc_buf);
1094 av_freep(&q->extparam);