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 #if FF_API_CODER_TYPE
451 FF_DISABLE_DEPRECATION_WARNINGS
452 if (avctx
->coder_type
!= 0)
453 q
->cavlc
= avctx
->coder_type
== FF_CODER_TYPE_VLC
;
454 FF_ENABLE_DEPRECATION_WARNINGS
456 q
->extco
.CAVLC
= q
->cavlc ? MFX_CODINGOPTION_ON
457 : MFX_CODINGOPTION_UNKNOWN
;
460 q
->extco
.RateDistortionOpt
= q
->rdo
> 0 ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
462 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
463 if (avctx
->strict_std_compliance
!= FF_COMPLIANCE_NORMAL
)
464 q
->extco
.NalHrdConformance
= avctx
->strict_std_compliance
> FF_COMPLIANCE_NORMAL ?
465 MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
467 if (q
->single_sei_nal_unit
>= 0)
468 q
->extco
.SingleSeiNalUnit
= q
->single_sei_nal_unit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
469 if (q
->recovery_point_sei
>= 0)
470 q
->extco
.RecoveryPointSEI
= q
->recovery_point_sei ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
471 q
->extco
.MaxDecFrameBuffering
= q
->max_dec_frame_buffering
;
474 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco
;
477 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
478 q
->extco2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
479 q
->extco2
.Header
.BufferSz
= sizeof(q
->extco2
);
481 if (q
->int_ref_type
>= 0)
482 q
->extco2
.IntRefType
= q
->int_ref_type
;
483 if (q
->int_ref_cycle_size
>= 0)
484 q
->extco2
.IntRefCycleSize
= q
->int_ref_cycle_size
;
485 if (q
->int_ref_qp_delta
!= INT16_MIN
)
486 q
->extco2
.IntRefQPDelta
= q
->int_ref_qp_delta
;
488 if (q
->bitrate_limit
>= 0)
489 q
->extco2
.BitrateLimit
= q
->bitrate_limit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
491 q
->extco2
.MBBRC
= q
->mbbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
493 q
->extco2
.ExtBRC
= q
->extbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
495 if (q
->max_frame_size
>= 0)
496 q
->extco2
.MaxFrameSize
= q
->max_frame_size
;
497 #if QSV_HAVE_MAX_SLICE_SIZE
498 if (q
->max_slice_size
>= 0)
499 q
->extco2
.MaxSliceSize
= q
->max_slice_size
;
503 q
->extco2
.Trellis
= q
->trellis
;
506 #if QSV_HAVE_BREF_TYPE
507 #if FF_API_PRIVATE_OPT
508 FF_DISABLE_DEPRECATION_WARNINGS
509 if (avctx
->b_frame_strategy
>= 0)
510 q
->b_strategy
= avctx
->b_frame_strategy
;
511 FF_ENABLE_DEPRECATION_WARNINGS
513 if (q
->b_strategy
>= 0)
514 q
->extco2
.BRefType
= q
->b_strategy ? MFX_B_REF_PYRAMID
: MFX_B_REF_OFF
;
515 if (q
->adaptive_i
>= 0)
516 q
->extco2
.AdaptiveI
= q
->adaptive_i ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
517 if (q
->adaptive_b
>= 0)
518 q
->extco2
.AdaptiveB
= q
->adaptive_b ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
521 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco2
;
526 if (!rc_supported(q
)) {
527 av_log(avctx
, AV_LOG_ERROR
,
528 "Selected ratecontrol mode is not supported by the QSV "
529 "runtime. Choose a different mode.\n");
530 return AVERROR(ENOSYS
);
536 static int qsv_retrieve_enc_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
538 AVCPBProperties
*cpb_props
;
540 uint8_t sps_buf
[128];
541 uint8_t pps_buf
[128];
543 mfxExtCodingOptionSPSPPS extradata
= {
544 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION_SPSPPS
,
545 .Header
.BufferSz
= sizeof(extradata
),
546 .SPSBuffer
= sps_buf
, .SPSBufSize
= sizeof(sps_buf
),
547 .PPSBuffer
= pps_buf
, .PPSBufSize
= sizeof(pps_buf
)
550 mfxExtCodingOption co
= {
551 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
,
552 .Header
.BufferSz
= sizeof(co
),
555 mfxExtCodingOption2 co2
= {
556 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
,
557 .Header
.BufferSz
= sizeof(co2
),
561 mfxExtCodingOption3 co3
= {
562 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION3
,
563 .Header
.BufferSz
= sizeof(co3
),
567 mfxExtBuffer
*ext_buffers
[] = {
568 (mfxExtBuffer
*)&extradata
,
578 int need_pps
= avctx
->codec_id
!= AV_CODEC_ID_MPEG2VIDEO
;
581 q
->param
.ExtParam
= ext_buffers
;
582 q
->param
.NumExtParam
= FF_ARRAY_ELEMS(ext_buffers
);
584 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
586 return ff_qsv_error(ret
);
588 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
590 if (!extradata
.SPSBufSize
|| (need_pps
&& !extradata
.PPSBufSize
)) {
591 av_log(avctx
, AV_LOG_ERROR
, "No extradata returned from libmfx.\n");
592 return AVERROR_UNKNOWN
;
595 avctx
->extradata
= av_malloc(extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
+
596 AV_INPUT_BUFFER_PADDING_SIZE
);
597 if (!avctx
->extradata
)
598 return AVERROR(ENOMEM
);
600 memcpy(avctx
->extradata
, sps_buf
, extradata
.SPSBufSize
);
602 memcpy(avctx
->extradata
+ extradata
.SPSBufSize
, pps_buf
, extradata
.PPSBufSize
);
603 avctx
->extradata_size
= extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
;
604 memset(avctx
->extradata
+ avctx
->extradata_size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
606 cpb_props
= ff_add_cpb_side_data(avctx
);
608 return AVERROR(ENOMEM
);
609 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
610 cpb_props
->min_bitrate
= avctx
->rc_min_rate
;
611 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
612 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
614 dump_video_param(avctx
, q
, ext_buffers
+ 1);
619 static int qsv_init_opaque_alloc(AVCodecContext
*avctx
, QSVEncContext
*q
)
621 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
622 mfxFrameSurface1
*surfaces
;
625 nb_surfaces
= qsv
->nb_opaque_surfaces
+ q
->req
.NumFrameSuggested
+ q
->async_depth
;
627 q
->opaque_alloc_buf
= av_buffer_allocz(sizeof(*surfaces
) * nb_surfaces
);
628 if (!q
->opaque_alloc_buf
)
629 return AVERROR(ENOMEM
);
631 q
->opaque_surfaces
= av_malloc_array(nb_surfaces
, sizeof(*q
->opaque_surfaces
));
632 if (!q
->opaque_surfaces
)
633 return AVERROR(ENOMEM
);
635 surfaces
= (mfxFrameSurface1
*)q
->opaque_alloc_buf
->data
;
636 for (i
= 0; i
< nb_surfaces
; i
++) {
637 surfaces
[i
].Info
= q
->req
.Info
;
638 q
->opaque_surfaces
[i
] = surfaces
+ i
;
641 q
->opaque_alloc
.Header
.BufferId
= MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
642 q
->opaque_alloc
.Header
.BufferSz
= sizeof(q
->opaque_alloc
);
643 q
->opaque_alloc
.In
.Surfaces
= q
->opaque_surfaces
;
644 q
->opaque_alloc
.In
.NumSurface
= nb_surfaces
;
645 q
->opaque_alloc
.In
.Type
= q
->req
.Type
;
647 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->opaque_alloc
;
649 qsv
->nb_opaque_surfaces
= nb_surfaces
;
650 qsv
->opaque_surfaces
= q
->opaque_alloc_buf
;
651 qsv
->opaque_alloc_type
= q
->req
.Type
;
656 int ff_qsv_enc_init(AVCodecContext
*avctx
, QSVEncContext
*q
)
658 int opaque_alloc
= 0;
661 q
->param
.IOPattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
662 q
->param
.AsyncDepth
= q
->async_depth
;
664 q
->async_fifo
= av_fifo_alloc((1 + q
->async_depth
) *
665 (sizeof(AVPacket
) + sizeof(mfxSyncPoint
) + sizeof(mfxBitstream
*)));
667 return AVERROR(ENOMEM
);
669 if (avctx
->hwaccel_context
) {
670 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
672 q
->session
= qsv
->session
;
673 q
->param
.IOPattern
= qsv
->iopattern
;
675 opaque_alloc
= qsv
->opaque_alloc
;
679 ret
= ff_qsv_init_internal_session(avctx
, &q
->internal_session
,
684 q
->session
= q
->internal_session
;
687 ret
= init_video_param(avctx
, q
);
691 ret
= MFXVideoENCODE_QueryIOSurf(q
->session
, &q
->param
, &q
->req
);
693 av_log(avctx
, AV_LOG_ERROR
, "Error querying the encoding parameters\n");
694 return ff_qsv_error(ret
);
698 ret
= qsv_init_opaque_alloc(avctx
, q
);
703 if (avctx
->hwaccel_context
) {
704 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
707 q
->extparam
= av_mallocz_array(qsv
->nb_ext_buffers
+ q
->nb_extparam_internal
,
708 sizeof(*q
->extparam
));
710 return AVERROR(ENOMEM
);
712 q
->param
.ExtParam
= q
->extparam
;
713 for (i
= 0; i
< qsv
->nb_ext_buffers
; i
++)
714 q
->param
.ExtParam
[i
] = qsv
->ext_buffers
[i
];
715 q
->param
.NumExtParam
= qsv
->nb_ext_buffers
;
717 for (i
= 0; i
< q
->nb_extparam_internal
; i
++) {
718 for (j
= 0; j
< qsv
->nb_ext_buffers
; j
++) {
719 if (qsv
->ext_buffers
[j
]->BufferId
== q
->extparam_internal
[i
]->BufferId
)
722 if (j
< qsv
->nb_ext_buffers
)
725 q
->param
.ExtParam
[q
->param
.NumExtParam
++] = q
->extparam_internal
[i
];
728 q
->param
.ExtParam
= q
->extparam_internal
;
729 q
->param
.NumExtParam
= q
->nb_extparam_internal
;
732 ret
= MFXVideoENCODE_Init(q
->session
, &q
->param
);
734 av_log(avctx
, AV_LOG_ERROR
, "Error initializing the encoder\n");
735 return ff_qsv_error(ret
);
738 ret
= qsv_retrieve_enc_params(avctx
, q
);
740 av_log(avctx
, AV_LOG_ERROR
, "Error retrieving encoding parameters.\n");
749 static void clear_unused_frames(QSVEncContext
*q
)
751 QSVFrame
*cur
= q
->work_frames
;
753 if (cur
->surface
&& !cur
->surface
->Data
.Locked
) {
755 av_frame_unref(cur
->frame
);
761 static int get_free_frame(QSVEncContext
*q
, QSVFrame
**f
)
763 QSVFrame
*frame
, **last
;
765 clear_unused_frames(q
);
767 frame
= q
->work_frames
;
768 last
= &q
->work_frames
;
770 if (!frame
->surface
) {
779 frame
= av_mallocz(sizeof(*frame
));
781 return AVERROR(ENOMEM
);
782 frame
->frame
= av_frame_alloc();
785 return AVERROR(ENOMEM
);
794 static int submit_frame(QSVEncContext
*q
, const AVFrame
*frame
,
795 mfxFrameSurface1
**surface
)
800 ret
= get_free_frame(q
, &qf
);
804 if (frame
->format
== AV_PIX_FMT_QSV
) {
805 ret
= av_frame_ref(qf
->frame
, frame
);
809 qf
->surface
= (mfxFrameSurface1
*)qf
->frame
->data
[3];
811 /* make a copy if the input is not padded as libmfx requires */
812 if (frame
->height
& 31 || frame
->linesize
[0] & (q
->width_align
- 1)) {
813 qf
->frame
->height
= FFALIGN(frame
->height
, 32);
814 qf
->frame
->width
= FFALIGN(frame
->width
, q
->width_align
);
816 ret
= ff_get_buffer(q
->avctx
, qf
->frame
, AV_GET_BUFFER_FLAG_REF
);
820 qf
->frame
->height
= frame
->height
;
821 qf
->frame
->width
= frame
->width
;
822 ret
= av_frame_copy(qf
->frame
, frame
);
824 av_frame_unref(qf
->frame
);
828 ret
= av_frame_ref(qf
->frame
, frame
);
833 qf
->surface_internal
.Info
= q
->param
.mfx
.FrameInfo
;
835 qf
->surface_internal
.Info
.PicStruct
=
836 !frame
->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE
:
837 frame
->top_field_first ? MFX_PICSTRUCT_FIELD_TFF
:
838 MFX_PICSTRUCT_FIELD_BFF
;
839 if (frame
->repeat_pict
== 1)
840 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FIELD_REPEATED
;
841 else if (frame
->repeat_pict
== 2)
842 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_DOUBLING
;
843 else if (frame
->repeat_pict
== 4)
844 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_TRIPLING
;
846 qf
->surface_internal
.Data
.PitchLow
= qf
->frame
->linesize
[0];
847 qf
->surface_internal
.Data
.Y
= qf
->frame
->data
[0];
848 qf
->surface_internal
.Data
.UV
= qf
->frame
->data
[1];
850 qf
->surface
= &qf
->surface_internal
;
853 qf
->surface
->Data
.TimeStamp
= av_rescale_q(frame
->pts
, q
->avctx
->time_base
, (AVRational
){1, 90000});
855 *surface
= qf
->surface
;
860 static void print_interlace_msg(AVCodecContext
*avctx
, QSVEncContext
*q
)
862 if (q
->param
.mfx
.CodecId
== MFX_CODEC_AVC
) {
863 if (q
->param
.mfx
.CodecProfile
== MFX_PROFILE_AVC_BASELINE
||
864 q
->param
.mfx
.CodecLevel
< MFX_LEVEL_AVC_21
||
865 q
->param
.mfx
.CodecLevel
> MFX_LEVEL_AVC_41
)
866 av_log(avctx
, AV_LOG_WARNING
,
867 "Interlaced coding is supported"
868 " at Main/High Profile Level 2.1-4.1\n");
872 static int encode_frame(AVCodecContext
*avctx
, QSVEncContext
*q
,
873 const AVFrame
*frame
)
875 AVPacket new_pkt
= { 0 };
878 mfxFrameSurface1
*surf
= NULL
;
879 mfxSyncPoint sync
= NULL
;
883 ret
= submit_frame(q
, frame
, &surf
);
885 av_log(avctx
, AV_LOG_ERROR
, "Error submitting the frame for encoding.\n");
890 ret
= av_new_packet(&new_pkt
, q
->packet_size
);
892 av_log(avctx
, AV_LOG_ERROR
, "Error allocating the output packet\n");
896 bs
= av_mallocz(sizeof(*bs
));
898 av_packet_unref(&new_pkt
);
899 return AVERROR(ENOMEM
);
901 bs
->Data
= new_pkt
.data
;
902 bs
->MaxLength
= new_pkt
.size
;
905 ret
= MFXVideoENCODE_EncodeFrameAsync(q
->session
, NULL
, surf
, bs
, &sync
);
906 if (ret
== MFX_WRN_DEVICE_BUSY
)
911 av_packet_unref(&new_pkt
);
913 return (ret
== MFX_ERR_MORE_DATA
) ?
0 : ff_qsv_error(ret
);
916 if (ret
== MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
&& frame
->interlaced_frame
)
917 print_interlace_msg(avctx
, q
);
920 av_fifo_generic_write(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
921 av_fifo_generic_write(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
922 av_fifo_generic_write(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
924 av_packet_unref(&new_pkt
);
931 int ff_qsv_encode(AVCodecContext
*avctx
, QSVEncContext
*q
,
932 AVPacket
*pkt
, const AVFrame
*frame
, int *got_packet
)
936 ret
= encode_frame(avctx
, q
, frame
);
940 if (!av_fifo_space(q
->async_fifo
) ||
941 (!frame
&& av_fifo_size(q
->async_fifo
))) {
946 av_fifo_generic_read(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
947 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
948 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
951 ret
= MFXVideoCORE_SyncOperation(q
->session
, sync
, 1000);
952 } while (ret
== MFX_WRN_IN_EXECUTION
);
954 new_pkt
.dts
= av_rescale_q(bs
->DecodeTimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
955 new_pkt
.pts
= av_rescale_q(bs
->TimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
956 new_pkt
.size
= bs
->DataLength
;
958 if (bs
->FrameType
& MFX_FRAMETYPE_IDR
||
959 bs
->FrameType
& MFX_FRAMETYPE_xIDR
)
960 new_pkt
.flags
|= AV_PKT_FLAG_KEY
;
962 #if FF_API_CODED_FRAME
963 FF_DISABLE_DEPRECATION_WARNINGS
964 if (bs
->FrameType
& MFX_FRAMETYPE_I
|| bs
->FrameType
& MFX_FRAMETYPE_xI
)
965 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
966 else if (bs
->FrameType
& MFX_FRAMETYPE_P
|| bs
->FrameType
& MFX_FRAMETYPE_xP
)
967 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
968 else if (bs
->FrameType
& MFX_FRAMETYPE_B
|| bs
->FrameType
& MFX_FRAMETYPE_xB
)
969 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
970 FF_ENABLE_DEPRECATION_WARNINGS
976 if (pkt
->size
< new_pkt
.size
) {
977 av_log(avctx
, AV_LOG_ERROR
, "Submitted buffer not large enough: %d < %d\n",
978 pkt
->size
, new_pkt
.size
);
979 av_packet_unref(&new_pkt
);
980 return AVERROR(EINVAL
);
983 memcpy(pkt
->data
, new_pkt
.data
, new_pkt
.size
);
984 pkt
->size
= new_pkt
.size
;
986 ret
= av_packet_copy_props(pkt
, &new_pkt
);
987 av_packet_unref(&new_pkt
);
999 int ff_qsv_enc_close(AVCodecContext
*avctx
, QSVEncContext
*q
)
1004 MFXVideoENCODE_Close(q
->session
);
1005 if (q
->internal_session
)
1006 MFXClose(q
->internal_session
);
1008 q
->internal_session
= NULL
;
1010 cur
= q
->work_frames
;
1012 q
->work_frames
= cur
->next
;
1013 av_frame_free(&cur
->frame
);
1015 cur
= q
->work_frames
;
1018 while (q
->async_fifo
&& av_fifo_size(q
->async_fifo
)) {
1023 av_fifo_generic_read(q
->async_fifo
, &pkt
, sizeof(pkt
), NULL
);
1024 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1025 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1028 av_packet_unref(&pkt
);
1030 av_fifo_free(q
->async_fifo
);
1031 q
->async_fifo
= NULL
;
1033 av_freep(&q
->opaque_surfaces
);
1034 av_buffer_unref(&q
->opaque_alloc_buf
);
1036 av_freep(&q
->extparam
);