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 Libav.
9 * Libav 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 * Libav 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 Libav; 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"
37 #include "qsv_internal.h"
44 { MFX_PROFILE_AVC_BASELINE
, "baseline" },
45 { MFX_PROFILE_AVC_MAIN
, "main" },
46 { MFX_PROFILE_AVC_EXTENDED
, "extended" },
47 { MFX_PROFILE_AVC_HIGH
, "high" },
48 #if QSV_VERSION_ATLEAST(1, 15)
49 { MFX_PROFILE_AVC_HIGH_422
, "high 422" },
51 #if QSV_VERSION_ATLEAST(1, 4)
52 { MFX_PROFILE_AVC_CONSTRAINED_BASELINE
, "constrained baseline" },
53 { MFX_PROFILE_AVC_CONSTRAINED_HIGH
, "constrained high" },
54 { MFX_PROFILE_AVC_PROGRESSIVE_HIGH
, "progressive high" },
56 { MFX_PROFILE_MPEG2_SIMPLE
, "simple" },
57 { MFX_PROFILE_MPEG2_MAIN
, "main" },
58 { MFX_PROFILE_MPEG2_HIGH
, "high" },
59 { MFX_PROFILE_VC1_SIMPLE
, "simple" },
60 { MFX_PROFILE_VC1_MAIN
, "main" },
61 { MFX_PROFILE_VC1_ADVANCED
, "advanced" },
62 #if QSV_VERSION_ATLEAST(1, 8)
63 { MFX_PROFILE_HEVC_MAIN
, "main" },
64 { MFX_PROFILE_HEVC_MAIN10
, "main10" },
65 { MFX_PROFILE_HEVC_MAINSP
, "mainsp" },
69 static const char *print_profile(mfxU16 profile
)
72 for (i
= 0; i
< FF_ARRAY_ELEMS(profile_names
); i
++)
73 if (profile
== profile_names
[i
].profile
)
74 return profile_names
[i
].name
;
82 { MFX_RATECONTROL_CBR
, "CBR" },
83 { MFX_RATECONTROL_VBR
, "VBR" },
84 { MFX_RATECONTROL_CQP
, "CQP" },
85 { MFX_RATECONTROL_AVBR
, "AVBR" },
87 { MFX_RATECONTROL_LA
, "LA" },
90 { MFX_RATECONTROL_ICQ
, "ICQ" },
91 { MFX_RATECONTROL_LA_ICQ
, "LA_ICQ" },
94 { MFX_RATECONTROL_VCM
, "VCM" },
96 #if QSV_VERSION_ATLEAST(1, 10)
97 { MFX_RATECONTROL_LA_EXT
, "LA_EXT" },
100 { MFX_RATECONTROL_LA_HRD
, "LA_HRD" },
103 { MFX_RATECONTROL_QVBR
, "QVBR" },
107 static const char *print_ratecontrol(mfxU16 rc_mode
)
110 for (i
= 0; i
< FF_ARRAY_ELEMS(rc_names
); i
++)
111 if (rc_mode
== rc_names
[i
].rc_mode
)
112 return rc_names
[i
].name
;
116 static const char *print_threestate(mfxU16 val
)
118 if (val
== MFX_CODINGOPTION_ON
)
120 else if (val
== MFX_CODINGOPTION_OFF
)
125 static void dump_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
,
126 mfxExtBuffer
**coding_opts
)
128 mfxInfoMFX
*info
= &q
->param
.mfx
;
130 mfxExtCodingOption
*co
= (mfxExtCodingOption
*)coding_opts
[0];
132 mfxExtCodingOption2
*co2
= (mfxExtCodingOption2
*)coding_opts
[1];
135 mfxExtCodingOption3
*co3
= (mfxExtCodingOption3
*)coding_opts
[2];
138 av_log(avctx
, AV_LOG_VERBOSE
, "profile: %s; level: %"PRIu16
"\n",
139 print_profile(info
->CodecProfile
), info
->CodecLevel
);
141 av_log(avctx
, AV_LOG_VERBOSE
, "GopPicSize: %"PRIu16
"; GopRefDist: %"PRIu16
"; GopOptFlag: ",
142 info
->GopPicSize
, info
->GopRefDist
);
143 if (info
->GopOptFlag
& MFX_GOP_CLOSED
)
144 av_log(avctx
, AV_LOG_VERBOSE
, "closed ");
145 if (info
->GopOptFlag
& MFX_GOP_STRICT
)
146 av_log(avctx
, AV_LOG_VERBOSE
, "strict ");
147 av_log(avctx
, AV_LOG_VERBOSE
, "; IdrInterval: %"PRIu16
"\n", info
->IdrInterval
);
149 av_log(avctx
, AV_LOG_VERBOSE
, "TargetUsage: %"PRIu16
"; RateControlMethod: %s\n",
150 info
->TargetUsage
, print_ratecontrol(info
->RateControlMethod
));
152 if (info
->RateControlMethod
== MFX_RATECONTROL_CBR
||
153 info
->RateControlMethod
== MFX_RATECONTROL_VBR
155 || info
->RateControlMethod
== MFX_RATECONTROL_VCM
158 av_log(avctx
, AV_LOG_VERBOSE
,
159 "InitialDelayInKB: %"PRIu16
"; TargetKbps: %"PRIu16
"; MaxKbps: %"PRIu16
"\n",
160 info
->InitialDelayInKB
, info
->TargetKbps
, info
->MaxKbps
);
161 } else if (info
->RateControlMethod
== MFX_RATECONTROL_CQP
) {
162 av_log(avctx
, AV_LOG_VERBOSE
, "QPI: %"PRIu16
"; QPP: %"PRIu16
"; QPB: %"PRIu16
"\n",
163 info
->QPI
, info
->QPP
, info
->QPB
);
164 } else if (info
->RateControlMethod
== MFX_RATECONTROL_AVBR
) {
165 av_log(avctx
, AV_LOG_VERBOSE
,
166 "TargetKbps: %"PRIu16
"; Accuracy: %"PRIu16
"; Convergence: %"PRIu16
"\n",
167 info
->TargetKbps
, info
->Accuracy
, info
->Convergence
);
170 else if (info
->RateControlMethod
== MFX_RATECONTROL_LA
172 || info
->RateControlMethod
== MFX_RATECONTROL_LA_HRD
175 av_log(avctx
, AV_LOG_VERBOSE
,
176 "TargetKbps: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
177 info
->TargetKbps
, co2
->LookAheadDepth
);
181 else if (info
->RateControlMethod
== MFX_RATECONTROL_ICQ
) {
182 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"\n", info
->ICQQuality
);
183 } else if (info
->RateControlMethod
== MFX_RATECONTROL_LA_ICQ
) {
184 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
185 info
->ICQQuality
, co2
->LookAheadDepth
);
189 else if (info
->RateControlMethod
== MFX_RATECONTROL_QVBR
) {
190 av_log(avctx
, AV_LOG_VERBOSE
, "QVBRQuality: %"PRIu16
"\n",
195 av_log(avctx
, AV_LOG_VERBOSE
, "NumSlice: %"PRIu16
"; NumRefFrame: %"PRIu16
"\n",
196 info
->NumSlice
, info
->NumRefFrame
);
197 av_log(avctx
, AV_LOG_VERBOSE
, "RateDistortionOpt: %s\n",
198 print_threestate(co
->RateDistortionOpt
));
201 av_log(avctx
, AV_LOG_VERBOSE
,
202 "RecoveryPointSEI: %s IntRefType: %"PRIu16
"; IntRefCycleSize: %"PRIu16
"; IntRefQPDelta: %"PRId16
"\n",
203 print_threestate(co
->RecoveryPointSEI
), co2
->IntRefType
, co2
->IntRefCycleSize
, co2
->IntRefQPDelta
);
205 av_log(avctx
, AV_LOG_VERBOSE
, "MaxFrameSize: %"PRIu16
"; ", co2
->MaxFrameSize
);
206 #if QSV_HAVE_MAX_SLICE_SIZE
207 av_log(avctx
, AV_LOG_VERBOSE
, "MaxSliceSize: %"PRIu16
"; ", co2
->MaxSliceSize
);
209 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
211 av_log(avctx
, AV_LOG_VERBOSE
,
212 "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
213 print_threestate(co2
->BitrateLimit
), print_threestate(co2
->MBBRC
),
214 print_threestate(co2
->ExtBRC
));
217 av_log(avctx
, AV_LOG_VERBOSE
, "Trellis: ");
218 if (co2
->Trellis
& MFX_TRELLIS_OFF
) {
219 av_log(avctx
, AV_LOG_VERBOSE
, "off");
220 } else if (!co2
->Trellis
) {
221 av_log(avctx
, AV_LOG_VERBOSE
, "auto");
223 if (co2
->Trellis
& MFX_TRELLIS_I
) av_log(avctx
, AV_LOG_VERBOSE
, "I");
224 if (co2
->Trellis
& MFX_TRELLIS_P
) av_log(avctx
, AV_LOG_VERBOSE
, "P");
225 if (co2
->Trellis
& MFX_TRELLIS_B
) av_log(avctx
, AV_LOG_VERBOSE
, "B");
227 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
230 #if QSV_VERSION_ATLEAST(1, 8)
231 av_log(avctx
, AV_LOG_VERBOSE
,
232 "RepeatPPS: %s; NumMbPerSlice: %"PRIu16
"; LookAheadDS: ",
233 print_threestate(co2
->RepeatPPS
), co2
->NumMbPerSlice
);
234 switch (co2
->LookAheadDS
) {
235 case MFX_LOOKAHEAD_DS_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
236 case MFX_LOOKAHEAD_DS_2x
: av_log(avctx
, AV_LOG_VERBOSE
, "2x"); break;
237 case MFX_LOOKAHEAD_DS_4x
: av_log(avctx
, AV_LOG_VERBOSE
, "4x"); break;
238 default: av_log(avctx
, AV_LOG_VERBOSE
, "unknown"); break;
240 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
242 av_log(avctx
, AV_LOG_VERBOSE
, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
243 print_threestate(co2
->AdaptiveI
), print_threestate(co2
->AdaptiveB
));
244 switch (co2
->BRefType
) {
245 case MFX_B_REF_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
246 case MFX_B_REF_PYRAMID
: av_log(avctx
, AV_LOG_VERBOSE
, "pyramid"); break;
247 default: av_log(avctx
, AV_LOG_VERBOSE
, "auto"); break;
249 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
252 #if QSV_VERSION_ATLEAST(1, 9)
253 av_log(avctx
, AV_LOG_VERBOSE
,
254 "MinQPI: %"PRIu8
"; MaxQPI: %"PRIu8
"; MinQPP: %"PRIu8
"; MaxQPP: %"PRIu8
"; MinQPB: %"PRIu8
"; MaxQPB: %"PRIu8
"\n",
255 co2
->MinQPI
, co2
->MaxQPI
, co2
->MinQPP
, co2
->MaxQPP
, co2
->MinQPB
, co2
->MaxQPB
);
259 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
260 av_log(avctx
, AV_LOG_VERBOSE
, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16
"\n",
261 co
->CAVLC
== MFX_CODINGOPTION_ON ?
"CAVLC" : "CABAC", co
->MaxDecFrameBuffering
);
262 av_log(avctx
, AV_LOG_VERBOSE
,
263 "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",
264 print_threestate(co
->NalHrdConformance
), print_threestate(co
->SingleSeiNalUnit
),
265 print_threestate(co
->VuiVclHrdParameters
), print_threestate(co
->VuiNalHrdParameters
));
269 static int select_rc_mode(AVCodecContext
*avctx
, QSVEncContext
*q
)
274 int want_la
= q
->la_depth
>= 0;
275 int want_qscale
= !!(avctx
->flags
& AV_CODEC_FLAG_QSCALE
);
276 int want_vcm
= q
->vcm
;
278 if (want_la
&& !QSV_HAVE_LA
) {
279 av_log(avctx
, AV_LOG_ERROR
,
280 "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
281 return AVERROR(ENOSYS
);
283 if (want_vcm
&& !QSV_HAVE_VCM
) {
284 av_log(avctx
, AV_LOG_ERROR
,
285 "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
286 return AVERROR(ENOSYS
);
289 if (want_la
+ want_qscale
+ want_vcm
> 1) {
290 av_log(avctx
, AV_LOG_ERROR
,
291 "More than one of: { constant qscale, lookahead, VCM } requested, "
292 "only one of them can be used at a time.\n");
293 return AVERROR(EINVAL
);
297 rc_mode
= MFX_RATECONTROL_CQP
;
298 rc_desc
= "constant quantization parameter (CQP)";
302 rc_mode
= MFX_RATECONTROL_VCM
;
303 rc_desc
= "video conferencing mode (VCM)";
308 rc_mode
= MFX_RATECONTROL_LA
;
309 rc_desc
= "VBR with lookahead (LA)";
312 if (avctx
->global_quality
> 0) {
313 rc_mode
= MFX_RATECONTROL_LA_ICQ
;
314 rc_desc
= "intelligent constant quality with lookahead (LA_ICQ)";
320 else if (avctx
->global_quality
> 0) {
321 rc_mode
= MFX_RATECONTROL_ICQ
;
322 rc_desc
= "intelligent constant quality (ICQ)";
325 else if (avctx
->rc_max_rate
== avctx
->bit_rate
) {
326 rc_mode
= MFX_RATECONTROL_CBR
;
327 rc_desc
= "constant bitrate (CBR)";
328 } else if (!avctx
->rc_max_rate
) {
329 rc_mode
= MFX_RATECONTROL_AVBR
;
330 rc_desc
= "average variable bitrate (AVBR)";
332 rc_mode
= MFX_RATECONTROL_VBR
;
333 rc_desc
= "variable bitrate (VBR)";
336 q
->param
.mfx
.RateControlMethod
= rc_mode
;
337 av_log(avctx
, AV_LOG_VERBOSE
, "Using the %s ratecontrol method\n", rc_desc
);
342 static int rc_supported(QSVEncContext
*q
)
344 mfxVideoParam param_out
= { .mfx
.CodecId
= q
->param
.mfx
.CodecId
};
347 ret
= MFXVideoENCODE_Query(q
->session
, &q
->param
, ¶m_out
);
349 param_out
.mfx
.RateControlMethod
!= q
->param
.mfx
.RateControlMethod
)
354 static int init_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
)
359 ret
= ff_qsv_codec_id_to_mfx(avctx
->codec_id
);
362 q
->param
.mfx
.CodecId
= ret
;
364 q
->width_align
= avctx
->codec_id
== AV_CODEC_ID_HEVC ?
32 : 16;
366 if (avctx
->level
> 0)
367 q
->param
.mfx
.CodecLevel
= avctx
->level
;
369 q
->param
.mfx
.CodecProfile
= q
->profile
;
370 q
->param
.mfx
.TargetUsage
= q
->preset
;
371 q
->param
.mfx
.GopPicSize
= FFMAX(0, avctx
->gop_size
);
372 q
->param
.mfx
.GopRefDist
= FFMAX(-1, avctx
->max_b_frames
) + 1;
373 q
->param
.mfx
.GopOptFlag
= avctx
->flags
& AV_CODEC_FLAG_CLOSED_GOP ?
375 q
->param
.mfx
.IdrInterval
= q
->idr_interval
;
376 q
->param
.mfx
.NumSlice
= avctx
->slices
;
377 q
->param
.mfx
.NumRefFrame
= FFMAX(0, avctx
->refs
);
378 q
->param
.mfx
.EncodedOrder
= 0;
379 q
->param
.mfx
.BufferSizeInKB
= 0;
381 q
->param
.mfx
.FrameInfo
.FourCC
= MFX_FOURCC_NV12
;
382 q
->param
.mfx
.FrameInfo
.Width
= FFALIGN(avctx
->width
, q
->width_align
);
383 q
->param
.mfx
.FrameInfo
.Height
= FFALIGN(avctx
->height
, 32);
384 q
->param
.mfx
.FrameInfo
.CropX
= 0;
385 q
->param
.mfx
.FrameInfo
.CropY
= 0;
386 q
->param
.mfx
.FrameInfo
.CropW
= avctx
->width
;
387 q
->param
.mfx
.FrameInfo
.CropH
= avctx
->height
;
388 q
->param
.mfx
.FrameInfo
.AspectRatioW
= avctx
->sample_aspect_ratio
.num
;
389 q
->param
.mfx
.FrameInfo
.AspectRatioH
= avctx
->sample_aspect_ratio
.den
;
390 q
->param
.mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_PROGRESSIVE
;
391 q
->param
.mfx
.FrameInfo
.ChromaFormat
= MFX_CHROMAFORMAT_YUV420
;
392 q
->param
.mfx
.FrameInfo
.BitDepthLuma
= 8;
393 q
->param
.mfx
.FrameInfo
.BitDepthChroma
= 8;
395 if (avctx
->framerate
.den
> 0 && avctx
->framerate
.num
> 0) {
396 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->framerate
.num
;
397 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->framerate
.den
;
399 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->time_base
.den
;
400 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->time_base
.num
;
403 ret
= select_rc_mode(avctx
, q
);
407 switch (q
->param
.mfx
.RateControlMethod
) {
408 case MFX_RATECONTROL_CBR
:
409 case MFX_RATECONTROL_VBR
:
411 case MFX_RATECONTROL_VCM
:
413 q
->param
.mfx
.InitialDelayInKB
= avctx
->rc_initial_buffer_occupancy
/ 1000;
414 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
415 q
->param
.mfx
.MaxKbps
= avctx
->rc_max_rate
/ 1000;
417 case MFX_RATECONTROL_CQP
:
418 quant
= avctx
->global_quality
/ FF_QP2LAMBDA
;
420 q
->param
.mfx
.QPI
= av_clip(quant
* fabs(avctx
->i_quant_factor
) + avctx
->i_quant_offset
, 0, 51);
421 q
->param
.mfx
.QPP
= av_clip(quant
, 0, 51);
422 q
->param
.mfx
.QPB
= av_clip(quant
* fabs(avctx
->b_quant_factor
) + avctx
->b_quant_offset
, 0, 51);
425 case MFX_RATECONTROL_AVBR
:
426 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
427 q
->param
.mfx
.Convergence
= q
->avbr_convergence
;
428 q
->param
.mfx
.Accuracy
= q
->avbr_accuracy
;
431 case MFX_RATECONTROL_LA
:
432 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
433 q
->extco2
.LookAheadDepth
= q
->la_depth
;
436 case MFX_RATECONTROL_LA_ICQ
:
437 q
->extco2
.LookAheadDepth
= q
->la_depth
;
438 case MFX_RATECONTROL_ICQ
:
439 q
->param
.mfx
.ICQQuality
= avctx
->global_quality
;
445 // the HEVC encoder plugin currently fails if coding options
447 if (avctx
->codec_id
!= AV_CODEC_ID_HEVC
) {
448 q
->extco
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
;
449 q
->extco
.Header
.BufferSz
= sizeof(q
->extco
);
450 q
->extco
.CAVLC
= avctx
->coder_type
== FF_CODER_TYPE_VLC ?
451 MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_UNKNOWN
;
454 q
->extco
.RateDistortionOpt
= q
->rdo
> 0 ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
456 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
457 if (avctx
->strict_std_compliance
!= FF_COMPLIANCE_NORMAL
)
458 q
->extco
.NalHrdConformance
= avctx
->strict_std_compliance
> FF_COMPLIANCE_NORMAL ?
459 MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
461 if (q
->single_sei_nal_unit
>= 0)
462 q
->extco
.SingleSeiNalUnit
= q
->single_sei_nal_unit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
463 if (q
->recovery_point_sei
>= 0)
464 q
->extco
.RecoveryPointSEI
= q
->recovery_point_sei ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
465 q
->extco
.MaxDecFrameBuffering
= q
->max_dec_frame_buffering
;
468 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco
;
471 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
472 q
->extco2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
473 q
->extco2
.Header
.BufferSz
= sizeof(q
->extco2
);
475 if (q
->int_ref_type
>= 0)
476 q
->extco2
.IntRefType
= q
->int_ref_type
;
477 if (q
->int_ref_cycle_size
>= 0)
478 q
->extco2
.IntRefCycleSize
= q
->int_ref_cycle_size
;
479 if (q
->int_ref_qp_delta
!= INT16_MIN
)
480 q
->extco2
.IntRefQPDelta
= q
->int_ref_qp_delta
;
482 if (q
->bitrate_limit
>= 0)
483 q
->extco2
.BitrateLimit
= q
->bitrate_limit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
485 q
->extco2
.MBBRC
= q
->mbbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
487 q
->extco2
.ExtBRC
= q
->extbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
489 if (q
->max_frame_size
>= 0)
490 q
->extco2
.MaxFrameSize
= q
->max_frame_size
;
491 #if QSV_HAVE_MAX_SLICE_SIZE
492 if (q
->max_slice_size
>= 0)
493 q
->extco2
.MaxSliceSize
= q
->max_slice_size
;
497 q
->extco2
.Trellis
= q
->trellis
;
500 #if QSV_HAVE_BREF_TYPE
501 if (avctx
->b_frame_strategy
>= 0)
502 q
->extco2
.BRefType
= avctx
->b_frame_strategy ? MFX_B_REF_PYRAMID
: MFX_B_REF_OFF
;
503 if (q
->adaptive_i
>= 0)
504 q
->extco2
.AdaptiveI
= q
->adaptive_i ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
505 if (q
->adaptive_b
>= 0)
506 q
->extco2
.AdaptiveB
= q
->adaptive_b ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
509 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco2
;
514 if (!rc_supported(q
)) {
515 av_log(avctx
, AV_LOG_ERROR
,
516 "Selected ratecontrol mode is not supported by the QSV "
517 "runtime. Choose a different mode.\n");
518 return AVERROR(ENOSYS
);
524 static int qsv_retrieve_enc_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
526 AVCPBProperties
*cpb_props
;
528 uint8_t sps_buf
[128];
529 uint8_t pps_buf
[128];
531 mfxExtCodingOptionSPSPPS extradata
= {
532 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION_SPSPPS
,
533 .Header
.BufferSz
= sizeof(extradata
),
534 .SPSBuffer
= sps_buf
, .SPSBufSize
= sizeof(sps_buf
),
535 .PPSBuffer
= pps_buf
, .PPSBufSize
= sizeof(pps_buf
)
538 mfxExtCodingOption co
= {
539 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
,
540 .Header
.BufferSz
= sizeof(co
),
543 mfxExtCodingOption2 co2
= {
544 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
,
545 .Header
.BufferSz
= sizeof(co2
),
549 mfxExtCodingOption3 co3
= {
550 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION3
,
551 .Header
.BufferSz
= sizeof(co3
),
555 mfxExtBuffer
*ext_buffers
[] = {
556 (mfxExtBuffer
*)&extradata
,
566 int need_pps
= avctx
->codec_id
!= AV_CODEC_ID_MPEG2VIDEO
;
569 q
->param
.ExtParam
= ext_buffers
;
570 q
->param
.NumExtParam
= FF_ARRAY_ELEMS(ext_buffers
);
572 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
574 return ff_qsv_error(ret
);
576 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
578 if (!extradata
.SPSBufSize
|| (need_pps
&& !extradata
.PPSBufSize
)) {
579 av_log(avctx
, AV_LOG_ERROR
, "No extradata returned from libmfx.\n");
580 return AVERROR_UNKNOWN
;
583 avctx
->extradata
= av_malloc(extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
+
584 AV_INPUT_BUFFER_PADDING_SIZE
);
585 if (!avctx
->extradata
)
586 return AVERROR(ENOMEM
);
588 memcpy(avctx
->extradata
, sps_buf
, extradata
.SPSBufSize
);
590 memcpy(avctx
->extradata
+ extradata
.SPSBufSize
, pps_buf
, extradata
.PPSBufSize
);
591 avctx
->extradata_size
= extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
;
592 memset(avctx
->extradata
+ avctx
->extradata_size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
594 cpb_props
= ff_add_cpb_side_data(avctx
);
596 return AVERROR(ENOMEM
);
597 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
598 cpb_props
->min_bitrate
= avctx
->rc_min_rate
;
599 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
600 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
602 dump_video_param(avctx
, q
, ext_buffers
+ 1);
607 static int qsv_init_opaque_alloc(AVCodecContext
*avctx
, QSVEncContext
*q
)
609 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
610 mfxFrameSurface1
*surfaces
;
613 nb_surfaces
= qsv
->nb_opaque_surfaces
+ q
->req
.NumFrameSuggested
+ q
->async_depth
;
615 q
->opaque_alloc_buf
= av_buffer_allocz(sizeof(*surfaces
) * nb_surfaces
);
616 if (!q
->opaque_alloc_buf
)
617 return AVERROR(ENOMEM
);
619 q
->opaque_surfaces
= av_malloc_array(nb_surfaces
, sizeof(*q
->opaque_surfaces
));
620 if (!q
->opaque_surfaces
)
621 return AVERROR(ENOMEM
);
623 surfaces
= (mfxFrameSurface1
*)q
->opaque_alloc_buf
->data
;
624 for (i
= 0; i
< nb_surfaces
; i
++) {
625 surfaces
[i
].Info
= q
->req
.Info
;
626 q
->opaque_surfaces
[i
] = surfaces
+ i
;
629 q
->opaque_alloc
.Header
.BufferId
= MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
630 q
->opaque_alloc
.Header
.BufferSz
= sizeof(q
->opaque_alloc
);
631 q
->opaque_alloc
.In
.Surfaces
= q
->opaque_surfaces
;
632 q
->opaque_alloc
.In
.NumSurface
= nb_surfaces
;
633 q
->opaque_alloc
.In
.Type
= q
->req
.Type
;
635 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->opaque_alloc
;
637 qsv
->nb_opaque_surfaces
= nb_surfaces
;
638 qsv
->opaque_surfaces
= q
->opaque_alloc_buf
;
639 qsv
->opaque_alloc_type
= q
->req
.Type
;
644 int ff_qsv_enc_init(AVCodecContext
*avctx
, QSVEncContext
*q
)
646 int opaque_alloc
= 0;
649 q
->param
.IOPattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
650 q
->param
.AsyncDepth
= q
->async_depth
;
652 q
->async_fifo
= av_fifo_alloc((1 + q
->async_depth
) *
653 (sizeof(AVPacket
) + sizeof(mfxSyncPoint
) + sizeof(mfxBitstream
*)));
655 return AVERROR(ENOMEM
);
657 if (avctx
->hwaccel_context
) {
658 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
660 q
->session
= qsv
->session
;
661 q
->param
.IOPattern
= qsv
->iopattern
;
663 opaque_alloc
= qsv
->opaque_alloc
;
667 ret
= ff_qsv_init_internal_session(avctx
, &q
->internal_session
,
672 q
->session
= q
->internal_session
;
675 ret
= init_video_param(avctx
, q
);
679 ret
= MFXVideoENCODE_QueryIOSurf(q
->session
, &q
->param
, &q
->req
);
681 av_log(avctx
, AV_LOG_ERROR
, "Error querying the encoding parameters\n");
682 return ff_qsv_error(ret
);
686 ret
= qsv_init_opaque_alloc(avctx
, q
);
691 if (avctx
->hwaccel_context
) {
692 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
695 q
->extparam
= av_mallocz_array(qsv
->nb_ext_buffers
+ q
->nb_extparam_internal
,
696 sizeof(*q
->extparam
));
698 return AVERROR(ENOMEM
);
700 q
->param
.ExtParam
= q
->extparam
;
701 for (i
= 0; i
< qsv
->nb_ext_buffers
; i
++)
702 q
->param
.ExtParam
[i
] = qsv
->ext_buffers
[i
];
703 q
->param
.NumExtParam
= qsv
->nb_ext_buffers
;
705 for (i
= 0; i
< q
->nb_extparam_internal
; i
++) {
706 for (j
= 0; j
< qsv
->nb_ext_buffers
; j
++) {
707 if (qsv
->ext_buffers
[j
]->BufferId
== q
->extparam_internal
[i
]->BufferId
)
710 if (j
< qsv
->nb_ext_buffers
)
713 q
->param
.ExtParam
[q
->param
.NumExtParam
++] = q
->extparam_internal
[i
];
716 q
->param
.ExtParam
= q
->extparam_internal
;
717 q
->param
.NumExtParam
= q
->nb_extparam_internal
;
720 ret
= MFXVideoENCODE_Init(q
->session
, &q
->param
);
722 av_log(avctx
, AV_LOG_ERROR
, "Error initializing the encoder\n");
723 return ff_qsv_error(ret
);
726 ret
= qsv_retrieve_enc_params(avctx
, q
);
728 av_log(avctx
, AV_LOG_ERROR
, "Error retrieving encoding parameters.\n");
737 static void clear_unused_frames(QSVEncContext
*q
)
739 QSVFrame
*cur
= q
->work_frames
;
741 if (cur
->surface
&& !cur
->surface
->Data
.Locked
) {
743 av_frame_unref(cur
->frame
);
749 static int get_free_frame(QSVEncContext
*q
, QSVFrame
**f
)
751 QSVFrame
*frame
, **last
;
753 clear_unused_frames(q
);
755 frame
= q
->work_frames
;
756 last
= &q
->work_frames
;
758 if (!frame
->surface
) {
767 frame
= av_mallocz(sizeof(*frame
));
769 return AVERROR(ENOMEM
);
770 frame
->frame
= av_frame_alloc();
773 return AVERROR(ENOMEM
);
782 static int submit_frame(QSVEncContext
*q
, const AVFrame
*frame
,
783 mfxFrameSurface1
**surface
)
788 ret
= get_free_frame(q
, &qf
);
792 if (frame
->format
== AV_PIX_FMT_QSV
) {
793 ret
= av_frame_ref(qf
->frame
, frame
);
797 qf
->surface
= (mfxFrameSurface1
*)qf
->frame
->data
[3];
799 /* make a copy if the input is not padded as libmfx requires */
800 if (frame
->height
& 31 || frame
->linesize
[0] & (q
->width_align
- 1)) {
801 qf
->frame
->height
= FFALIGN(frame
->height
, 32);
802 qf
->frame
->width
= FFALIGN(frame
->width
, q
->width_align
);
804 ret
= ff_get_buffer(q
->avctx
, qf
->frame
, AV_GET_BUFFER_FLAG_REF
);
808 qf
->frame
->height
= frame
->height
;
809 qf
->frame
->width
= frame
->width
;
810 ret
= av_frame_copy(qf
->frame
, frame
);
812 av_frame_unref(qf
->frame
);
816 ret
= av_frame_ref(qf
->frame
, frame
);
821 qf
->surface_internal
.Info
= q
->param
.mfx
.FrameInfo
;
823 qf
->surface_internal
.Info
.PicStruct
=
824 !frame
->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE
:
825 frame
->top_field_first ? MFX_PICSTRUCT_FIELD_TFF
:
826 MFX_PICSTRUCT_FIELD_BFF
;
827 if (frame
->repeat_pict
== 1)
828 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FIELD_REPEATED
;
829 else if (frame
->repeat_pict
== 2)
830 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_DOUBLING
;
831 else if (frame
->repeat_pict
== 4)
832 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_TRIPLING
;
834 qf
->surface_internal
.Data
.PitchLow
= qf
->frame
->linesize
[0];
835 qf
->surface_internal
.Data
.Y
= qf
->frame
->data
[0];
836 qf
->surface_internal
.Data
.UV
= qf
->frame
->data
[1];
838 qf
->surface
= &qf
->surface_internal
;
841 qf
->surface
->Data
.TimeStamp
= av_rescale_q(frame
->pts
, q
->avctx
->time_base
, (AVRational
){1, 90000});
843 *surface
= qf
->surface
;
848 static void print_interlace_msg(AVCodecContext
*avctx
, QSVEncContext
*q
)
850 if (q
->param
.mfx
.CodecId
== MFX_CODEC_AVC
) {
851 if (q
->param
.mfx
.CodecProfile
== MFX_PROFILE_AVC_BASELINE
||
852 q
->param
.mfx
.CodecLevel
< MFX_LEVEL_AVC_21
||
853 q
->param
.mfx
.CodecLevel
> MFX_LEVEL_AVC_41
)
854 av_log(avctx
, AV_LOG_WARNING
,
855 "Interlaced coding is supported"
856 " at Main/High Profile Level 2.1-4.1\n");
860 int ff_qsv_encode(AVCodecContext
*avctx
, QSVEncContext
*q
,
861 AVPacket
*pkt
, const AVFrame
*frame
, int *got_packet
)
863 AVPacket new_pkt
= { 0 };
866 mfxFrameSurface1
*surf
= NULL
;
867 mfxSyncPoint sync
= NULL
;
871 ret
= submit_frame(q
, frame
, &surf
);
873 av_log(avctx
, AV_LOG_ERROR
, "Error submitting the frame for encoding.\n");
878 ret
= av_new_packet(&new_pkt
, q
->packet_size
);
880 av_log(avctx
, AV_LOG_ERROR
, "Error allocating the output packet\n");
884 bs
= av_mallocz(sizeof(*bs
));
886 av_packet_unref(&new_pkt
);
887 return AVERROR(ENOMEM
);
889 bs
->Data
= new_pkt
.data
;
890 bs
->MaxLength
= new_pkt
.size
;
893 ret
= MFXVideoENCODE_EncodeFrameAsync(q
->session
, NULL
, surf
, bs
, &sync
);
894 if (ret
== MFX_WRN_DEVICE_BUSY
)
899 av_packet_unref(&new_pkt
);
901 return (ret
== MFX_ERR_MORE_DATA
) ?
0 : ff_qsv_error(ret
);
904 if (ret
== MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
&& frame
->interlaced_frame
)
905 print_interlace_msg(avctx
, q
);
908 av_fifo_generic_write(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
909 av_fifo_generic_write(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
910 av_fifo_generic_write(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
912 av_packet_unref(&new_pkt
);
916 if (!av_fifo_space(q
->async_fifo
) ||
917 (!frame
&& av_fifo_size(q
->async_fifo
))) {
918 av_fifo_generic_read(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
919 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
920 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
922 MFXVideoCORE_SyncOperation(q
->session
, sync
, 60000);
924 new_pkt
.dts
= av_rescale_q(bs
->DecodeTimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
925 new_pkt
.pts
= av_rescale_q(bs
->TimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
926 new_pkt
.size
= bs
->DataLength
;
928 if (bs
->FrameType
& MFX_FRAMETYPE_IDR
||
929 bs
->FrameType
& MFX_FRAMETYPE_xIDR
)
930 new_pkt
.flags
|= AV_PKT_FLAG_KEY
;
932 #if FF_API_CODED_FRAME
933 FF_DISABLE_DEPRECATION_WARNINGS
934 if (bs
->FrameType
& MFX_FRAMETYPE_I
|| bs
->FrameType
& MFX_FRAMETYPE_xI
)
935 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
936 else if (bs
->FrameType
& MFX_FRAMETYPE_P
|| bs
->FrameType
& MFX_FRAMETYPE_xP
)
937 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
938 else if (bs
->FrameType
& MFX_FRAMETYPE_B
|| bs
->FrameType
& MFX_FRAMETYPE_xB
)
939 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
940 FF_ENABLE_DEPRECATION_WARNINGS
946 if (pkt
->size
< new_pkt
.size
) {
947 av_log(avctx
, AV_LOG_ERROR
, "Submitted buffer not large enough: %d < %d\n",
948 pkt
->size
, new_pkt
.size
);
949 av_packet_unref(&new_pkt
);
950 return AVERROR(EINVAL
);
953 memcpy(pkt
->data
, new_pkt
.data
, new_pkt
.size
);
954 pkt
->size
= new_pkt
.size
;
956 ret
= av_packet_copy_props(pkt
, &new_pkt
);
957 av_packet_unref(&new_pkt
);
969 int ff_qsv_enc_close(AVCodecContext
*avctx
, QSVEncContext
*q
)
974 MFXVideoENCODE_Close(q
->session
);
975 if (q
->internal_session
)
976 MFXClose(q
->internal_session
);
978 q
->internal_session
= NULL
;
980 cur
= q
->work_frames
;
982 q
->work_frames
= cur
->next
;
983 av_frame_free(&cur
->frame
);
985 cur
= q
->work_frames
;
988 while (q
->async_fifo
&& av_fifo_size(q
->async_fifo
)) {
993 av_fifo_generic_read(q
->async_fifo
, &pkt
, sizeof(pkt
), NULL
);
994 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
995 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
998 av_packet_unref(&pkt
);
1000 av_fifo_free(q
->async_fifo
);
1001 q
->async_fifo
= NULL
;
1003 av_freep(&q
->opaque_surfaces
);
1004 av_buffer_unref(&q
->opaque_alloc_buf
);
1006 av_freep(&q
->extparam
);