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 uint8_t sps_buf[128];
547 uint8_t pps_buf[128];
549 mfxExtCodingOptionSPSPPS extradata = {
550 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
551 .Header.BufferSz = sizeof(extradata),
552 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
553 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
556 mfxExtCodingOption co = {
557 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
558 .Header.BufferSz = sizeof(co),
561 mfxExtCodingOption2 co2 = {
562 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
563 .Header.BufferSz = sizeof(co2),
567 mfxExtCodingOption3 co3 = {
568 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
569 .Header.BufferSz = sizeof(co3),
573 mfxExtBuffer *ext_buffers[] = {
574 (mfxExtBuffer*)&extradata,
584 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
587 q->param.ExtParam = ext_buffers;
588 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
590 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
592 return ff_qsv_error(ret);
594 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
596 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
597 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
598 return AVERROR_UNKNOWN;
601 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
602 AV_INPUT_BUFFER_PADDING_SIZE);
603 if (!avctx->extradata)
604 return AVERROR(ENOMEM);
606 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
608 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
609 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
610 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
612 dump_video_param(avctx, q, ext_buffers + 1);
617 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
619 AVQSVContext *qsv = avctx->hwaccel_context;
620 mfxFrameSurface1 *surfaces;
623 nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
625 q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
626 if (!q->opaque_alloc_buf)
627 return AVERROR(ENOMEM);
629 q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
630 if (!q->opaque_surfaces)
631 return AVERROR(ENOMEM);
633 surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
634 for (i = 0; i < nb_surfaces; i++) {
635 surfaces[i].Info = q->req.Info;
636 q->opaque_surfaces[i] = surfaces + i;
639 q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
640 q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
641 q->opaque_alloc.In.Surfaces = q->opaque_surfaces;
642 q->opaque_alloc.In.NumSurface = nb_surfaces;
643 q->opaque_alloc.In.Type = q->req.Type;
645 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
647 qsv->nb_opaque_surfaces = nb_surfaces;
648 qsv->opaque_surfaces = q->opaque_alloc_buf;
649 qsv->opaque_alloc_type = q->req.Type;
654 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
656 int opaque_alloc = 0;
659 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
660 q->param.AsyncDepth = q->async_depth;
662 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
663 (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
665 return AVERROR(ENOMEM);
667 if (avctx->hwaccel_context) {
668 AVQSVContext *qsv = avctx->hwaccel_context;
670 q->session = qsv->session;
671 q->param.IOPattern = qsv->iopattern;
673 opaque_alloc = qsv->opaque_alloc;
677 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
682 q->session = q->internal_qs.session;
685 ret = init_video_param(avctx, q);
689 ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
690 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
691 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
692 } else if (ret < 0) {
693 av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
694 return ff_qsv_error(ret);
697 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
699 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
700 return ff_qsv_error(ret);
704 ret = qsv_init_opaque_alloc(avctx, q);
709 if (avctx->hwaccel_context) {
710 AVQSVContext *qsv = avctx->hwaccel_context;
713 q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
714 sizeof(*q->extparam));
716 return AVERROR(ENOMEM);
718 q->param.ExtParam = q->extparam;
719 for (i = 0; i < qsv->nb_ext_buffers; i++)
720 q->param.ExtParam[i] = qsv->ext_buffers[i];
721 q->param.NumExtParam = qsv->nb_ext_buffers;
723 for (i = 0; i < q->nb_extparam_internal; i++) {
724 for (j = 0; j < qsv->nb_ext_buffers; j++) {
725 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
728 if (j < qsv->nb_ext_buffers)
731 q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
734 q->param.ExtParam = q->extparam_internal;
735 q->param.NumExtParam = q->nb_extparam_internal;
738 ret = MFXVideoENCODE_Init(q->session, &q->param);
739 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
740 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
741 } else if (ret < 0) {
742 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
743 return ff_qsv_error(ret);
746 ret = qsv_retrieve_enc_params(avctx, q);
748 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
757 static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
761 for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
762 mfxPayload* pay = enc_ctrl->Payload[i];
763 av_free(enc_ctrl->Payload[i]->Data);
766 enc_ctrl->NumPayload = 0;
770 static void clear_unused_frames(QSVEncContext *q)
772 QSVFrame *cur = q->work_frames;
774 if (cur->surface && !cur->surface->Data.Locked) {
776 free_encoder_ctrl_payloads(&cur->enc_ctrl);
777 av_frame_unref(cur->frame);
783 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
785 QSVFrame *frame, **last;
787 clear_unused_frames(q);
789 frame = q->work_frames;
790 last = &q->work_frames;
792 if (!frame->surface) {
801 frame = av_mallocz(sizeof(*frame));
803 return AVERROR(ENOMEM);
804 frame->frame = av_frame_alloc();
807 return AVERROR(ENOMEM);
809 frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
810 if (!frame->enc_ctrl.Payload) {
812 return AVERROR(ENOMEM);
821 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
822 QSVFrame **new_frame)
827 ret = get_free_frame(q, &qf);
831 if (frame->format == AV_PIX_FMT_QSV) {
832 ret = av_frame_ref(qf->frame, frame);
836 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
838 /* make a copy if the input is not padded as libmfx requires */
839 if ( frame->height & (q->height_align - 1) ||
840 frame->linesize[0] & (q->width_align - 1)) {
841 qf->frame->height = FFALIGN(frame->height, q->height_align);
842 qf->frame->width = FFALIGN(frame->width, q->width_align);
844 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
848 qf->frame->height = frame->height;
849 qf->frame->width = frame->width;
850 ret = av_frame_copy(qf->frame, frame);
852 av_frame_unref(qf->frame);
856 ret = av_frame_ref(qf->frame, frame);
861 qf->surface_internal.Info = q->param.mfx.FrameInfo;
863 qf->surface_internal.Info.PicStruct =
864 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
865 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
866 MFX_PICSTRUCT_FIELD_BFF;
867 if (frame->repeat_pict == 1)
868 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
869 else if (frame->repeat_pict == 2)
870 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
871 else if (frame->repeat_pict == 4)
872 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
874 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
875 qf->surface_internal.Data.Y = qf->frame->data[0];
876 qf->surface_internal.Data.UV = qf->frame->data[1];
878 qf->surface = &qf->surface_internal;
881 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
888 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
890 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
891 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
892 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
893 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
894 av_log(avctx, AV_LOG_WARNING,
895 "Interlaced coding is supported"
896 " at Main/High Profile Level 2.1-4.1\n");
900 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
901 AVPacket *pkt, const AVFrame *frame, int *got_packet)
903 AVPacket new_pkt = { 0 };
906 mfxFrameSurface1 *surf = NULL;
907 mfxSyncPoint sync = NULL;
908 QSVFrame *qsv_frame = NULL;
909 mfxEncodeCtrl* enc_ctrl = NULL;
913 ret = submit_frame(q, frame, &qsv_frame);
915 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
920 surf = qsv_frame->surface;
921 enc_ctrl = &qsv_frame->enc_ctrl;
924 ret = av_new_packet(&new_pkt, q->packet_size);
926 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
930 bs = av_mallocz(sizeof(*bs));
932 av_packet_unref(&new_pkt);
933 return AVERROR(ENOMEM);
935 bs->Data = new_pkt.data;
936 bs->MaxLength = new_pkt.size;
938 if (q->set_encode_ctrl_cb) {
939 q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
943 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, &sync);
944 if (ret == MFX_WRN_DEVICE_BUSY) {
952 av_packet_unref(&new_pkt);
954 if (ret == MFX_ERR_MORE_DATA)
956 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
957 return ff_qsv_error(ret);
960 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
961 if (frame->interlaced_frame)
962 print_interlace_msg(avctx, q);
964 av_log(avctx, AV_LOG_WARNING,
965 "EncodeFrameAsync returned 'incompatible param' code\n");
968 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
969 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
970 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
972 av_packet_unref(&new_pkt);
976 if (!av_fifo_space(q->async_fifo) ||
977 (!frame && av_fifo_size(q->async_fifo))) {
978 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
979 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
980 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
982 MFXVideoCORE_SyncOperation(q->session, sync, 60000);
984 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
985 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
986 new_pkt.size = bs->DataLength;
988 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
989 bs->FrameType & MFX_FRAMETYPE_xIDR)
990 new_pkt.flags |= AV_PKT_FLAG_KEY;
992 #if FF_API_CODED_FRAME
993 FF_DISABLE_DEPRECATION_WARNINGS
994 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
995 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
996 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
997 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
998 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
999 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1000 FF_ENABLE_DEPRECATION_WARNINGS
1006 if (pkt->size < new_pkt.size) {
1007 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1008 pkt->size, new_pkt.size);
1009 av_packet_unref(&new_pkt);
1010 return AVERROR(EINVAL);
1013 memcpy(pkt->data, new_pkt.data, new_pkt.size);
1014 pkt->size = new_pkt.size;
1016 ret = av_packet_copy_props(pkt, &new_pkt);
1017 av_packet_unref(&new_pkt);
1029 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1034 MFXVideoENCODE_Close(q->session);
1037 ff_qsv_close_internal_session(&q->internal_qs);
1039 cur = q->work_frames;
1041 q->work_frames = cur->next;
1042 av_frame_free(&cur->frame);
1043 av_free(cur->enc_ctrl.Payload);
1045 cur = q->work_frames;
1048 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1053 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
1054 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1055 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
1058 av_packet_unref(&pkt);
1060 av_fifo_free(q->async_fifo);
1061 q->async_fifo = NULL;
1063 av_freep(&q->opaque_surfaces);
1064 av_buffer_unref(&q->opaque_alloc_buf);
1066 av_freep(&q->extparam);