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/hwcontext.h"
30 #include "libavutil/hwcontext_qsv.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/log.h"
33 #include "libavutil/time.h"
34 #include "libavutil/imgutils.h"
39 #include "qsv_internal.h"
46 { MFX_PROFILE_AVC_BASELINE
, "baseline" },
47 { MFX_PROFILE_AVC_MAIN
, "main" },
48 { MFX_PROFILE_AVC_EXTENDED
, "extended" },
49 { MFX_PROFILE_AVC_HIGH
, "high" },
50 #if QSV_VERSION_ATLEAST(1, 15)
51 { MFX_PROFILE_AVC_HIGH_422
, "high 422" },
53 #if QSV_VERSION_ATLEAST(1, 4)
54 { MFX_PROFILE_AVC_CONSTRAINED_BASELINE
, "constrained baseline" },
55 { MFX_PROFILE_AVC_CONSTRAINED_HIGH
, "constrained high" },
56 { MFX_PROFILE_AVC_PROGRESSIVE_HIGH
, "progressive high" },
58 { MFX_PROFILE_MPEG2_SIMPLE
, "simple" },
59 { MFX_PROFILE_MPEG2_MAIN
, "main" },
60 { MFX_PROFILE_MPEG2_HIGH
, "high" },
61 { MFX_PROFILE_VC1_SIMPLE
, "simple" },
62 { MFX_PROFILE_VC1_MAIN
, "main" },
63 { MFX_PROFILE_VC1_ADVANCED
, "advanced" },
64 #if QSV_VERSION_ATLEAST(1, 8)
65 { MFX_PROFILE_HEVC_MAIN
, "main" },
66 { MFX_PROFILE_HEVC_MAIN10
, "main10" },
67 { MFX_PROFILE_HEVC_MAINSP
, "mainsp" },
71 static const char *print_profile(mfxU16 profile
)
74 for (i
= 0; i
< FF_ARRAY_ELEMS(profile_names
); i
++)
75 if (profile
== profile_names
[i
].profile
)
76 return profile_names
[i
].name
;
84 { MFX_RATECONTROL_CBR
, "CBR" },
85 { MFX_RATECONTROL_VBR
, "VBR" },
86 { MFX_RATECONTROL_CQP
, "CQP" },
87 { MFX_RATECONTROL_AVBR
, "AVBR" },
89 { MFX_RATECONTROL_LA
, "LA" },
92 { MFX_RATECONTROL_ICQ
, "ICQ" },
93 { MFX_RATECONTROL_LA_ICQ
, "LA_ICQ" },
96 { MFX_RATECONTROL_VCM
, "VCM" },
98 #if QSV_VERSION_ATLEAST(1, 10)
99 { MFX_RATECONTROL_LA_EXT
, "LA_EXT" },
102 { MFX_RATECONTROL_LA_HRD
, "LA_HRD" },
105 { MFX_RATECONTROL_QVBR
, "QVBR" },
109 static const char *print_ratecontrol(mfxU16 rc_mode
)
112 for (i
= 0; i
< FF_ARRAY_ELEMS(rc_names
); i
++)
113 if (rc_mode
== rc_names
[i
].rc_mode
)
114 return rc_names
[i
].name
;
118 static const char *print_threestate(mfxU16 val
)
120 if (val
== MFX_CODINGOPTION_ON
)
122 else if (val
== MFX_CODINGOPTION_OFF
)
127 static void dump_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
,
128 mfxExtBuffer
**coding_opts
)
130 mfxInfoMFX
*info
= &q
->param
.mfx
;
132 mfxExtCodingOption
*co
= (mfxExtCodingOption
*)coding_opts
[0];
134 mfxExtCodingOption2
*co2
= (mfxExtCodingOption2
*)coding_opts
[1];
137 mfxExtCodingOption3
*co3
= (mfxExtCodingOption3
*)coding_opts
[2];
140 av_log(avctx
, AV_LOG_VERBOSE
, "profile: %s; level: %"PRIu16
"\n",
141 print_profile(info
->CodecProfile
), info
->CodecLevel
);
143 av_log(avctx
, AV_LOG_VERBOSE
, "GopPicSize: %"PRIu16
"; GopRefDist: %"PRIu16
"; GopOptFlag: ",
144 info
->GopPicSize
, info
->GopRefDist
);
145 if (info
->GopOptFlag
& MFX_GOP_CLOSED
)
146 av_log(avctx
, AV_LOG_VERBOSE
, "closed ");
147 if (info
->GopOptFlag
& MFX_GOP_STRICT
)
148 av_log(avctx
, AV_LOG_VERBOSE
, "strict ");
149 av_log(avctx
, AV_LOG_VERBOSE
, "; IdrInterval: %"PRIu16
"\n", info
->IdrInterval
);
151 av_log(avctx
, AV_LOG_VERBOSE
, "TargetUsage: %"PRIu16
"; RateControlMethod: %s\n",
152 info
->TargetUsage
, print_ratecontrol(info
->RateControlMethod
));
154 if (info
->RateControlMethod
== MFX_RATECONTROL_CBR
||
155 info
->RateControlMethod
== MFX_RATECONTROL_VBR
157 || info
->RateControlMethod
== MFX_RATECONTROL_VCM
160 av_log(avctx
, AV_LOG_VERBOSE
,
161 "InitialDelayInKB: %"PRIu16
"; TargetKbps: %"PRIu16
"; MaxKbps: %"PRIu16
"\n",
162 info
->InitialDelayInKB
, info
->TargetKbps
, info
->MaxKbps
);
163 } else if (info
->RateControlMethod
== MFX_RATECONTROL_CQP
) {
164 av_log(avctx
, AV_LOG_VERBOSE
, "QPI: %"PRIu16
"; QPP: %"PRIu16
"; QPB: %"PRIu16
"\n",
165 info
->QPI
, info
->QPP
, info
->QPB
);
166 } else if (info
->RateControlMethod
== MFX_RATECONTROL_AVBR
) {
167 av_log(avctx
, AV_LOG_VERBOSE
,
168 "TargetKbps: %"PRIu16
"; Accuracy: %"PRIu16
"; Convergence: %"PRIu16
"\n",
169 info
->TargetKbps
, info
->Accuracy
, info
->Convergence
);
172 else if (info
->RateControlMethod
== MFX_RATECONTROL_LA
174 || info
->RateControlMethod
== MFX_RATECONTROL_LA_HRD
177 av_log(avctx
, AV_LOG_VERBOSE
,
178 "TargetKbps: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
179 info
->TargetKbps
, co2
->LookAheadDepth
);
183 else if (info
->RateControlMethod
== MFX_RATECONTROL_ICQ
) {
184 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"\n", info
->ICQQuality
);
185 } else if (info
->RateControlMethod
== MFX_RATECONTROL_LA_ICQ
) {
186 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
187 info
->ICQQuality
, co2
->LookAheadDepth
);
191 else if (info
->RateControlMethod
== MFX_RATECONTROL_QVBR
) {
192 av_log(avctx
, AV_LOG_VERBOSE
, "QVBRQuality: %"PRIu16
"\n",
197 av_log(avctx
, AV_LOG_VERBOSE
, "NumSlice: %"PRIu16
"; NumRefFrame: %"PRIu16
"\n",
198 info
->NumSlice
, info
->NumRefFrame
);
199 av_log(avctx
, AV_LOG_VERBOSE
, "RateDistortionOpt: %s\n",
200 print_threestate(co
->RateDistortionOpt
));
203 av_log(avctx
, AV_LOG_VERBOSE
,
204 "RecoveryPointSEI: %s IntRefType: %"PRIu16
"; IntRefCycleSize: %"PRIu16
"; IntRefQPDelta: %"PRId16
"\n",
205 print_threestate(co
->RecoveryPointSEI
), co2
->IntRefType
, co2
->IntRefCycleSize
, co2
->IntRefQPDelta
);
207 av_log(avctx
, AV_LOG_VERBOSE
, "MaxFrameSize: %"PRIu16
"; ", co2
->MaxFrameSize
);
208 #if QSV_HAVE_MAX_SLICE_SIZE
209 av_log(avctx
, AV_LOG_VERBOSE
, "MaxSliceSize: %"PRIu16
"; ", co2
->MaxSliceSize
);
211 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
213 av_log(avctx
, AV_LOG_VERBOSE
,
214 "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
215 print_threestate(co2
->BitrateLimit
), print_threestate(co2
->MBBRC
),
216 print_threestate(co2
->ExtBRC
));
219 av_log(avctx
, AV_LOG_VERBOSE
, "Trellis: ");
220 if (co2
->Trellis
& MFX_TRELLIS_OFF
) {
221 av_log(avctx
, AV_LOG_VERBOSE
, "off");
222 } else if (!co2
->Trellis
) {
223 av_log(avctx
, AV_LOG_VERBOSE
, "auto");
225 if (co2
->Trellis
& MFX_TRELLIS_I
) av_log(avctx
, AV_LOG_VERBOSE
, "I");
226 if (co2
->Trellis
& MFX_TRELLIS_P
) av_log(avctx
, AV_LOG_VERBOSE
, "P");
227 if (co2
->Trellis
& MFX_TRELLIS_B
) av_log(avctx
, AV_LOG_VERBOSE
, "B");
229 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
232 #if QSV_VERSION_ATLEAST(1, 8)
233 av_log(avctx
, AV_LOG_VERBOSE
,
234 "RepeatPPS: %s; NumMbPerSlice: %"PRIu16
"; LookAheadDS: ",
235 print_threestate(co2
->RepeatPPS
), co2
->NumMbPerSlice
);
236 switch (co2
->LookAheadDS
) {
237 case MFX_LOOKAHEAD_DS_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
238 case MFX_LOOKAHEAD_DS_2x
: av_log(avctx
, AV_LOG_VERBOSE
, "2x"); break;
239 case MFX_LOOKAHEAD_DS_4x
: av_log(avctx
, AV_LOG_VERBOSE
, "4x"); break;
240 default: av_log(avctx
, AV_LOG_VERBOSE
, "unknown"); break;
242 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
244 av_log(avctx
, AV_LOG_VERBOSE
, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
245 print_threestate(co2
->AdaptiveI
), print_threestate(co2
->AdaptiveB
));
246 switch (co2
->BRefType
) {
247 case MFX_B_REF_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
248 case MFX_B_REF_PYRAMID
: av_log(avctx
, AV_LOG_VERBOSE
, "pyramid"); break;
249 default: av_log(avctx
, AV_LOG_VERBOSE
, "auto"); break;
251 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
254 #if QSV_VERSION_ATLEAST(1, 9)
255 av_log(avctx
, AV_LOG_VERBOSE
,
256 "MinQPI: %"PRIu8
"; MaxQPI: %"PRIu8
"; MinQPP: %"PRIu8
"; MaxQPP: %"PRIu8
"; MinQPB: %"PRIu8
"; MaxQPB: %"PRIu8
"\n",
257 co2
->MinQPI
, co2
->MaxQPI
, co2
->MinQPP
, co2
->MaxQPP
, co2
->MinQPB
, co2
->MaxQPB
);
261 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
262 av_log(avctx
, AV_LOG_VERBOSE
, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16
"\n",
263 co
->CAVLC
== MFX_CODINGOPTION_ON ?
"CAVLC" : "CABAC", co
->MaxDecFrameBuffering
);
264 av_log(avctx
, AV_LOG_VERBOSE
,
265 "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",
266 print_threestate(co
->NalHrdConformance
), print_threestate(co
->SingleSeiNalUnit
),
267 print_threestate(co
->VuiVclHrdParameters
), print_threestate(co
->VuiNalHrdParameters
));
271 static int select_rc_mode(AVCodecContext
*avctx
, QSVEncContext
*q
)
276 int want_la
= q
->la_depth
>= 10;
277 int want_qscale
= !!(avctx
->flags
& AV_CODEC_FLAG_QSCALE
);
278 int want_vcm
= q
->vcm
;
280 if (want_la
&& !QSV_HAVE_LA
) {
281 av_log(avctx
, AV_LOG_ERROR
,
282 "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
283 return AVERROR(ENOSYS
);
285 if (want_vcm
&& !QSV_HAVE_VCM
) {
286 av_log(avctx
, AV_LOG_ERROR
,
287 "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
288 return AVERROR(ENOSYS
);
291 if (want_la
+ want_qscale
+ want_vcm
> 1) {
292 av_log(avctx
, AV_LOG_ERROR
,
293 "More than one of: { constant qscale, lookahead, VCM } requested, "
294 "only one of them can be used at a time.\n");
295 return AVERROR(EINVAL
);
299 rc_mode
= MFX_RATECONTROL_CQP
;
300 rc_desc
= "constant quantization parameter (CQP)";
304 rc_mode
= MFX_RATECONTROL_VCM
;
305 rc_desc
= "video conferencing mode (VCM)";
310 rc_mode
= MFX_RATECONTROL_LA
;
311 rc_desc
= "VBR with lookahead (LA)";
314 if (avctx
->global_quality
> 0) {
315 rc_mode
= MFX_RATECONTROL_LA_ICQ
;
316 rc_desc
= "intelligent constant quality with lookahead (LA_ICQ)";
322 else if (avctx
->global_quality
> 0) {
323 rc_mode
= MFX_RATECONTROL_ICQ
;
324 rc_desc
= "intelligent constant quality (ICQ)";
327 else if (avctx
->rc_max_rate
== avctx
->bit_rate
) {
328 rc_mode
= MFX_RATECONTROL_CBR
;
329 rc_desc
= "constant bitrate (CBR)";
330 } else if (!avctx
->rc_max_rate
) {
331 rc_mode
= MFX_RATECONTROL_AVBR
;
332 rc_desc
= "average variable bitrate (AVBR)";
334 rc_mode
= MFX_RATECONTROL_VBR
;
335 rc_desc
= "variable bitrate (VBR)";
338 q
->param
.mfx
.RateControlMethod
= rc_mode
;
339 av_log(avctx
, AV_LOG_VERBOSE
, "Using the %s ratecontrol method\n", rc_desc
);
344 static int rc_supported(QSVEncContext
*q
)
346 mfxVideoParam param_out
= { .mfx
.CodecId
= q
->param
.mfx
.CodecId
};
349 ret
= MFXVideoENCODE_Query(q
->session
, &q
->param
, ¶m_out
);
351 param_out
.mfx
.RateControlMethod
!= q
->param
.mfx
.RateControlMethod
)
356 static int init_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
)
358 enum AVPixelFormat sw_format
= avctx
->pix_fmt
== AV_PIX_FMT_QSV ?
359 avctx
->sw_pix_fmt
: avctx
->pix_fmt
;
360 const AVPixFmtDescriptor
*desc
;
364 ret
= ff_qsv_codec_id_to_mfx(avctx
->codec_id
);
367 q
->param
.mfx
.CodecId
= ret
;
369 q
->width_align
= avctx
->codec_id
== AV_CODEC_ID_HEVC ?
32 : 16;
371 if (avctx
->level
> 0)
372 q
->param
.mfx
.CodecLevel
= avctx
->level
;
374 q
->param
.mfx
.CodecProfile
= q
->profile
;
375 q
->param
.mfx
.TargetUsage
= q
->preset
;
376 q
->param
.mfx
.GopPicSize
= FFMAX(0, avctx
->gop_size
);
377 q
->param
.mfx
.GopRefDist
= FFMAX(-1, avctx
->max_b_frames
) + 1;
378 q
->param
.mfx
.GopOptFlag
= avctx
->flags
& AV_CODEC_FLAG_CLOSED_GOP ?
380 q
->param
.mfx
.IdrInterval
= q
->idr_interval
;
381 q
->param
.mfx
.NumSlice
= avctx
->slices
;
382 q
->param
.mfx
.NumRefFrame
= FFMAX(0, avctx
->refs
);
383 q
->param
.mfx
.EncodedOrder
= 0;
384 q
->param
.mfx
.BufferSizeInKB
= 0;
386 desc
= av_pix_fmt_desc_get(sw_format
);
390 ff_qsv_map_pixfmt(sw_format
, &q
->param
.mfx
.FrameInfo
.FourCC
);
392 q
->param
.mfx
.FrameInfo
.Width
= FFALIGN(avctx
->width
, q
->width_align
);
393 q
->param
.mfx
.FrameInfo
.Height
= FFALIGN(avctx
->height
, 32);
394 q
->param
.mfx
.FrameInfo
.CropX
= 0;
395 q
->param
.mfx
.FrameInfo
.CropY
= 0;
396 q
->param
.mfx
.FrameInfo
.CropW
= avctx
->width
;
397 q
->param
.mfx
.FrameInfo
.CropH
= avctx
->height
;
398 q
->param
.mfx
.FrameInfo
.AspectRatioW
= avctx
->sample_aspect_ratio
.num
;
399 q
->param
.mfx
.FrameInfo
.AspectRatioH
= avctx
->sample_aspect_ratio
.den
;
400 q
->param
.mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_PROGRESSIVE
;
401 q
->param
.mfx
.FrameInfo
.ChromaFormat
= MFX_CHROMAFORMAT_YUV420
;
402 q
->param
.mfx
.FrameInfo
.BitDepthLuma
= desc
->comp
[0].depth
;
403 q
->param
.mfx
.FrameInfo
.BitDepthChroma
= desc
->comp
[0].depth
;
404 q
->param
.mfx
.FrameInfo
.Shift
= desc
->comp
[0].depth
> 8;
406 if (avctx
->hw_frames_ctx
) {
407 AVHWFramesContext
*frames_ctx
= (AVHWFramesContext
*)avctx
->hw_frames_ctx
->data
;
408 AVQSVFramesContext
*frames_hwctx
= frames_ctx
->hwctx
;
409 q
->param
.mfx
.FrameInfo
.Width
= frames_hwctx
->surfaces
[0].Info
.Width
;
410 q
->param
.mfx
.FrameInfo
.Height
= frames_hwctx
->surfaces
[0].Info
.Height
;
413 if (avctx
->framerate
.den
> 0 && avctx
->framerate
.num
> 0) {
414 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->framerate
.num
;
415 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->framerate
.den
;
417 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->time_base
.den
;
418 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->time_base
.num
;
421 ret
= select_rc_mode(avctx
, q
);
425 switch (q
->param
.mfx
.RateControlMethod
) {
426 case MFX_RATECONTROL_CBR
:
427 case MFX_RATECONTROL_VBR
:
429 case MFX_RATECONTROL_VCM
:
431 q
->param
.mfx
.InitialDelayInKB
= avctx
->rc_initial_buffer_occupancy
/ 1000;
432 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
433 q
->param
.mfx
.MaxKbps
= avctx
->rc_max_rate
/ 1000;
435 case MFX_RATECONTROL_CQP
:
436 quant
= avctx
->global_quality
/ FF_QP2LAMBDA
;
438 q
->param
.mfx
.QPI
= av_clip(quant
* fabs(avctx
->i_quant_factor
) + avctx
->i_quant_offset
, 0, 51);
439 q
->param
.mfx
.QPP
= av_clip(quant
, 0, 51);
440 q
->param
.mfx
.QPB
= av_clip(quant
* fabs(avctx
->b_quant_factor
) + avctx
->b_quant_offset
, 0, 51);
443 case MFX_RATECONTROL_AVBR
:
444 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
445 q
->param
.mfx
.Convergence
= q
->avbr_convergence
;
446 q
->param
.mfx
.Accuracy
= q
->avbr_accuracy
;
449 case MFX_RATECONTROL_LA
:
450 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
451 q
->extco2
.LookAheadDepth
= q
->la_depth
;
454 case MFX_RATECONTROL_LA_ICQ
:
455 q
->extco2
.LookAheadDepth
= q
->la_depth
;
456 case MFX_RATECONTROL_ICQ
:
457 q
->param
.mfx
.ICQQuality
= avctx
->global_quality
;
463 // the HEVC encoder plugin currently fails if coding options
465 if (avctx
->codec_id
!= AV_CODEC_ID_HEVC
) {
466 q
->extco
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
;
467 q
->extco
.Header
.BufferSz
= sizeof(q
->extco
);
468 #if FF_API_CODER_TYPE
469 FF_DISABLE_DEPRECATION_WARNINGS
470 if (avctx
->coder_type
!= 0)
471 q
->cavlc
= avctx
->coder_type
== FF_CODER_TYPE_VLC
;
472 FF_ENABLE_DEPRECATION_WARNINGS
474 q
->extco
.CAVLC
= q
->cavlc ? MFX_CODINGOPTION_ON
475 : MFX_CODINGOPTION_UNKNOWN
;
478 q
->extco
.RateDistortionOpt
= q
->rdo
> 0 ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
480 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
481 if (avctx
->strict_std_compliance
!= FF_COMPLIANCE_NORMAL
)
482 q
->extco
.NalHrdConformance
= avctx
->strict_std_compliance
> FF_COMPLIANCE_NORMAL ?
483 MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
485 if (q
->single_sei_nal_unit
>= 0)
486 q
->extco
.SingleSeiNalUnit
= q
->single_sei_nal_unit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
487 if (q
->recovery_point_sei
>= 0)
488 q
->extco
.RecoveryPointSEI
= q
->recovery_point_sei ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
489 q
->extco
.MaxDecFrameBuffering
= q
->max_dec_frame_buffering
;
492 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco
;
495 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
496 q
->extco2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
497 q
->extco2
.Header
.BufferSz
= sizeof(q
->extco2
);
499 if (q
->int_ref_type
>= 0)
500 q
->extco2
.IntRefType
= q
->int_ref_type
;
501 if (q
->int_ref_cycle_size
>= 0)
502 q
->extco2
.IntRefCycleSize
= q
->int_ref_cycle_size
;
503 if (q
->int_ref_qp_delta
!= INT16_MIN
)
504 q
->extco2
.IntRefQPDelta
= q
->int_ref_qp_delta
;
506 if (q
->bitrate_limit
>= 0)
507 q
->extco2
.BitrateLimit
= q
->bitrate_limit ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
509 q
->extco2
.MBBRC
= q
->mbbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
511 q
->extco2
.ExtBRC
= q
->extbrc ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
513 if (q
->max_frame_size
>= 0)
514 q
->extco2
.MaxFrameSize
= q
->max_frame_size
;
515 #if QSV_HAVE_MAX_SLICE_SIZE
516 if (q
->max_slice_size
>= 0)
517 q
->extco2
.MaxSliceSize
= q
->max_slice_size
;
521 q
->extco2
.Trellis
= q
->trellis
;
524 #if QSV_HAVE_BREF_TYPE
525 #if FF_API_PRIVATE_OPT
526 FF_DISABLE_DEPRECATION_WARNINGS
527 if (avctx
->b_frame_strategy
>= 0)
528 q
->b_strategy
= avctx
->b_frame_strategy
;
529 FF_ENABLE_DEPRECATION_WARNINGS
531 if (q
->b_strategy
>= 0)
532 q
->extco2
.BRefType
= q
->b_strategy ? MFX_B_REF_PYRAMID
: MFX_B_REF_OFF
;
533 if (q
->adaptive_i
>= 0)
534 q
->extco2
.AdaptiveI
= q
->adaptive_i ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
535 if (q
->adaptive_b
>= 0)
536 q
->extco2
.AdaptiveB
= q
->adaptive_b ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
539 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco2
;
544 if (!rc_supported(q
)) {
545 av_log(avctx
, AV_LOG_ERROR
,
546 "Selected ratecontrol mode is not supported by the QSV "
547 "runtime. Choose a different mode.\n");
548 return AVERROR(ENOSYS
);
554 static int qsv_retrieve_enc_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
556 AVCPBProperties
*cpb_props
;
558 uint8_t sps_buf
[128];
559 uint8_t pps_buf
[128];
561 mfxExtCodingOptionSPSPPS extradata
= {
562 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION_SPSPPS
,
563 .Header
.BufferSz
= sizeof(extradata
),
564 .SPSBuffer
= sps_buf
, .SPSBufSize
= sizeof(sps_buf
),
565 .PPSBuffer
= pps_buf
, .PPSBufSize
= sizeof(pps_buf
)
568 mfxExtCodingOption co
= {
569 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
,
570 .Header
.BufferSz
= sizeof(co
),
573 mfxExtCodingOption2 co2
= {
574 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
,
575 .Header
.BufferSz
= sizeof(co2
),
579 mfxExtCodingOption3 co3
= {
580 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION3
,
581 .Header
.BufferSz
= sizeof(co3
),
585 mfxExtBuffer
*ext_buffers
[] = {
586 (mfxExtBuffer
*)&extradata
,
596 int need_pps
= avctx
->codec_id
!= AV_CODEC_ID_MPEG2VIDEO
;
599 q
->param
.ExtParam
= ext_buffers
;
600 q
->param
.NumExtParam
= FF_ARRAY_ELEMS(ext_buffers
);
602 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
604 return ff_qsv_print_error(avctx
, ret
,
605 "Error calling GetVideoParam");
607 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
609 if (!extradata
.SPSBufSize
|| (need_pps
&& !extradata
.PPSBufSize
)) {
610 av_log(avctx
, AV_LOG_ERROR
, "No extradata returned from libmfx.\n");
611 return AVERROR_UNKNOWN
;
614 avctx
->extradata
= av_malloc(extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
+
615 AV_INPUT_BUFFER_PADDING_SIZE
);
616 if (!avctx
->extradata
)
617 return AVERROR(ENOMEM
);
619 memcpy(avctx
->extradata
, sps_buf
, extradata
.SPSBufSize
);
621 memcpy(avctx
->extradata
+ extradata
.SPSBufSize
, pps_buf
, extradata
.PPSBufSize
);
622 avctx
->extradata_size
= extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
;
623 memset(avctx
->extradata
+ avctx
->extradata_size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
625 cpb_props
= ff_add_cpb_side_data(avctx
);
627 return AVERROR(ENOMEM
);
628 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
629 cpb_props
->min_bitrate
= avctx
->rc_min_rate
;
630 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
631 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
633 dump_video_param(avctx
, q
, ext_buffers
+ 1);
638 static int qsv_init_opaque_alloc(AVCodecContext
*avctx
, QSVEncContext
*q
)
640 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
641 mfxFrameSurface1
*surfaces
;
644 nb_surfaces
= qsv
->nb_opaque_surfaces
+ q
->req
.NumFrameSuggested
+ q
->async_depth
;
646 q
->opaque_alloc_buf
= av_buffer_allocz(sizeof(*surfaces
) * nb_surfaces
);
647 if (!q
->opaque_alloc_buf
)
648 return AVERROR(ENOMEM
);
650 q
->opaque_surfaces
= av_malloc_array(nb_surfaces
, sizeof(*q
->opaque_surfaces
));
651 if (!q
->opaque_surfaces
)
652 return AVERROR(ENOMEM
);
654 surfaces
= (mfxFrameSurface1
*)q
->opaque_alloc_buf
->data
;
655 for (i
= 0; i
< nb_surfaces
; i
++) {
656 surfaces
[i
].Info
= q
->req
.Info
;
657 q
->opaque_surfaces
[i
] = surfaces
+ i
;
660 q
->opaque_alloc
.Header
.BufferId
= MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
661 q
->opaque_alloc
.Header
.BufferSz
= sizeof(q
->opaque_alloc
);
662 q
->opaque_alloc
.In
.Surfaces
= q
->opaque_surfaces
;
663 q
->opaque_alloc
.In
.NumSurface
= nb_surfaces
;
664 q
->opaque_alloc
.In
.Type
= q
->req
.Type
;
666 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->opaque_alloc
;
668 qsv
->nb_opaque_surfaces
= nb_surfaces
;
669 qsv
->opaque_surfaces
= q
->opaque_alloc_buf
;
670 qsv
->opaque_alloc_type
= q
->req
.Type
;
675 static int qsvenc_init_session(AVCodecContext
*avctx
, QSVEncContext
*q
)
679 if (avctx
->hwaccel_context
) {
680 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
681 q
->session
= qsv
->session
;
682 } else if (avctx
->hw_frames_ctx
) {
683 q
->frames_ctx
.hw_frames_ctx
= av_buffer_ref(avctx
->hw_frames_ctx
);
684 if (!q
->frames_ctx
.hw_frames_ctx
)
685 return AVERROR(ENOMEM
);
687 ret
= ff_qsv_init_session_frames(avctx
, &q
->internal_session
,
688 &q
->frames_ctx
, q
->load_plugins
,
689 q
->param
.IOPattern
== MFX_IOPATTERN_IN_OPAQUE_MEMORY
);
691 av_buffer_unref(&q
->frames_ctx
.hw_frames_ctx
);
695 q
->session
= q
->internal_session
;
697 ret
= ff_qsv_init_internal_session(avctx
, &q
->internal_session
,
702 q
->session
= q
->internal_session
;
708 int ff_qsv_enc_init(AVCodecContext
*avctx
, QSVEncContext
*q
)
711 int opaque_alloc
= 0;
714 q
->param
.AsyncDepth
= q
->async_depth
;
716 q
->async_fifo
= av_fifo_alloc((1 + q
->async_depth
) *
717 (sizeof(AVPacket
) + sizeof(mfxSyncPoint
*) + sizeof(mfxBitstream
*)));
719 return AVERROR(ENOMEM
);
721 if (avctx
->hwaccel_context
) {
722 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
724 iopattern
= qsv
->iopattern
;
725 opaque_alloc
= qsv
->opaque_alloc
;
728 if (avctx
->hw_frames_ctx
) {
729 AVHWFramesContext
*frames_ctx
= (AVHWFramesContext
*)avctx
->hw_frames_ctx
->data
;
730 AVQSVFramesContext
*frames_hwctx
= frames_ctx
->hwctx
;
733 if (frames_hwctx
->frame_type
& MFX_MEMTYPE_OPAQUE_FRAME
)
734 iopattern
= MFX_IOPATTERN_IN_OPAQUE_MEMORY
;
735 else if (frames_hwctx
->frame_type
&
736 (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET
| MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET
))
737 iopattern
= MFX_IOPATTERN_IN_VIDEO_MEMORY
;
742 iopattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
743 q
->param
.IOPattern
= iopattern
;
745 ret
= qsvenc_init_session(avctx
, q
);
749 ret
= init_video_param(avctx
, q
);
753 ret
= MFXVideoENCODE_QueryIOSurf(q
->session
, &q
->param
, &q
->req
);
755 return ff_qsv_print_error(avctx
, ret
,
756 "Error querying the encoding parameters");
759 ret
= qsv_init_opaque_alloc(avctx
, q
);
764 if (avctx
->hwaccel_context
) {
765 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
768 q
->extparam
= av_mallocz_array(qsv
->nb_ext_buffers
+ q
->nb_extparam_internal
,
769 sizeof(*q
->extparam
));
771 return AVERROR(ENOMEM
);
773 q
->param
.ExtParam
= q
->extparam
;
774 for (i
= 0; i
< qsv
->nb_ext_buffers
; i
++)
775 q
->param
.ExtParam
[i
] = qsv
->ext_buffers
[i
];
776 q
->param
.NumExtParam
= qsv
->nb_ext_buffers
;
778 for (i
= 0; i
< q
->nb_extparam_internal
; i
++) {
779 for (j
= 0; j
< qsv
->nb_ext_buffers
; j
++) {
780 if (qsv
->ext_buffers
[j
]->BufferId
== q
->extparam_internal
[i
]->BufferId
)
783 if (j
< qsv
->nb_ext_buffers
)
786 q
->param
.ExtParam
[q
->param
.NumExtParam
++] = q
->extparam_internal
[i
];
789 q
->param
.ExtParam
= q
->extparam_internal
;
790 q
->param
.NumExtParam
= q
->nb_extparam_internal
;
793 ret
= MFXVideoENCODE_Init(q
->session
, &q
->param
);
795 return ff_qsv_print_error(avctx
, ret
,
796 "Error initializing the encoder");
798 ff_qsv_print_warning(avctx
, ret
,
799 "Warning in encoder initialization");
801 ret
= qsv_retrieve_enc_params(avctx
, q
);
803 av_log(avctx
, AV_LOG_ERROR
, "Error retrieving encoding parameters.\n");
812 static void clear_unused_frames(QSVEncContext
*q
)
814 QSVFrame
*cur
= q
->work_frames
;
816 if (cur
->used
&& !cur
->surface
.Data
.Locked
) {
817 av_frame_unref(cur
->frame
);
824 static int get_free_frame(QSVEncContext
*q
, QSVFrame
**f
)
826 QSVFrame
*frame
, **last
;
828 clear_unused_frames(q
);
830 frame
= q
->work_frames
;
831 last
= &q
->work_frames
;
843 frame
= av_mallocz(sizeof(*frame
));
845 return AVERROR(ENOMEM
);
846 frame
->frame
= av_frame_alloc();
849 return AVERROR(ENOMEM
);
859 static int submit_frame(QSVEncContext
*q
, const AVFrame
*frame
,
860 mfxFrameSurface1
**surface
)
865 ret
= get_free_frame(q
, &qf
);
869 if (frame
->format
== AV_PIX_FMT_QSV
) {
870 ret
= av_frame_ref(qf
->frame
, frame
);
874 qf
->surface
= *(mfxFrameSurface1
*)qf
->frame
->data
[3];
876 if (q
->frames_ctx
.mids
) {
877 ret
= ff_qsv_find_surface_idx(&q
->frames_ctx
, qf
);
881 qf
->surface
.Data
.MemId
= &q
->frames_ctx
.mids
[ret
];
884 /* make a copy if the input is not padded as libmfx requires */
885 if (frame
->height
& 31 || frame
->linesize
[0] & (q
->width_align
- 1)) {
886 qf
->frame
->height
= FFALIGN(frame
->height
, 32);
887 qf
->frame
->width
= FFALIGN(frame
->width
, q
->width_align
);
889 ret
= ff_get_buffer(q
->avctx
, qf
->frame
, AV_GET_BUFFER_FLAG_REF
);
893 qf
->frame
->height
= frame
->height
;
894 qf
->frame
->width
= frame
->width
;
895 ret
= av_frame_copy(qf
->frame
, frame
);
897 av_frame_unref(qf
->frame
);
901 ret
= av_frame_ref(qf
->frame
, frame
);
906 qf
->surface
.Info
= q
->param
.mfx
.FrameInfo
;
908 qf
->surface
.Info
.PicStruct
=
909 !frame
->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE
:
910 frame
->top_field_first ? MFX_PICSTRUCT_FIELD_TFF
:
911 MFX_PICSTRUCT_FIELD_BFF
;
912 if (frame
->repeat_pict
== 1)
913 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FIELD_REPEATED
;
914 else if (frame
->repeat_pict
== 2)
915 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_DOUBLING
;
916 else if (frame
->repeat_pict
== 4)
917 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_TRIPLING
;
919 qf
->surface
.Data
.PitchLow
= qf
->frame
->linesize
[0];
920 qf
->surface
.Data
.Y
= qf
->frame
->data
[0];
921 qf
->surface
.Data
.UV
= qf
->frame
->data
[1];
924 qf
->surface
.Data
.TimeStamp
= av_rescale_q(frame
->pts
, q
->avctx
->time_base
, (AVRational
){1, 90000});
926 *surface
= &qf
->surface
;
931 static void print_interlace_msg(AVCodecContext
*avctx
, QSVEncContext
*q
)
933 if (q
->param
.mfx
.CodecId
== MFX_CODEC_AVC
) {
934 if (q
->param
.mfx
.CodecProfile
== MFX_PROFILE_AVC_BASELINE
||
935 q
->param
.mfx
.CodecLevel
< MFX_LEVEL_AVC_21
||
936 q
->param
.mfx
.CodecLevel
> MFX_LEVEL_AVC_41
)
937 av_log(avctx
, AV_LOG_WARNING
,
938 "Interlaced coding is supported"
939 " at Main/High Profile Level 2.1-4.1\n");
943 static int encode_frame(AVCodecContext
*avctx
, QSVEncContext
*q
,
944 const AVFrame
*frame
)
946 AVPacket new_pkt
= { 0 };
949 mfxFrameSurface1
*surf
= NULL
;
950 mfxSyncPoint
*sync
= NULL
;
954 ret
= submit_frame(q
, frame
, &surf
);
956 av_log(avctx
, AV_LOG_ERROR
, "Error submitting the frame for encoding.\n");
961 ret
= av_new_packet(&new_pkt
, q
->packet_size
);
963 av_log(avctx
, AV_LOG_ERROR
, "Error allocating the output packet\n");
967 bs
= av_mallocz(sizeof(*bs
));
969 av_packet_unref(&new_pkt
);
970 return AVERROR(ENOMEM
);
972 bs
->Data
= new_pkt
.data
;
973 bs
->MaxLength
= new_pkt
.size
;
975 sync
= av_mallocz(sizeof(*sync
));
978 av_packet_unref(&new_pkt
);
979 return AVERROR(ENOMEM
);
983 ret
= MFXVideoENCODE_EncodeFrameAsync(q
->session
, NULL
, surf
, bs
, sync
);
984 if (ret
== MFX_WRN_DEVICE_BUSY
)
986 } while (ret
== MFX_WRN_DEVICE_BUSY
|| ret
== MFX_WRN_IN_EXECUTION
);
989 ff_qsv_print_warning(avctx
, ret
, "Warning during encoding");
992 av_packet_unref(&new_pkt
);
995 return (ret
== MFX_ERR_MORE_DATA
) ?
996 0 : ff_qsv_print_error(avctx
, ret
, "Error during encoding");
999 if (ret
== MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
&& frame
->interlaced_frame
)
1000 print_interlace_msg(avctx
, q
);
1003 av_fifo_generic_write(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
1004 av_fifo_generic_write(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1005 av_fifo_generic_write(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1008 av_packet_unref(&new_pkt
);
1015 int ff_qsv_encode(AVCodecContext
*avctx
, QSVEncContext
*q
,
1016 AVPacket
*pkt
, const AVFrame
*frame
, int *got_packet
)
1020 ret
= encode_frame(avctx
, q
, frame
);
1024 if (!av_fifo_space(q
->async_fifo
) ||
1025 (!frame
&& av_fifo_size(q
->async_fifo
))) {
1030 av_fifo_generic_read(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
1031 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1032 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1035 ret
= MFXVideoCORE_SyncOperation(q
->session
, *sync
, 1000);
1036 } while (ret
== MFX_WRN_IN_EXECUTION
);
1038 new_pkt
.dts
= av_rescale_q(bs
->DecodeTimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
1039 new_pkt
.pts
= av_rescale_q(bs
->TimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
1040 new_pkt
.size
= bs
->DataLength
;
1042 if (bs
->FrameType
& MFX_FRAMETYPE_IDR
||
1043 bs
->FrameType
& MFX_FRAMETYPE_xIDR
)
1044 new_pkt
.flags
|= AV_PKT_FLAG_KEY
;
1046 #if FF_API_CODED_FRAME
1047 FF_DISABLE_DEPRECATION_WARNINGS
1048 if (bs
->FrameType
& MFX_FRAMETYPE_I
|| bs
->FrameType
& MFX_FRAMETYPE_xI
)
1049 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
1050 else if (bs
->FrameType
& MFX_FRAMETYPE_P
|| bs
->FrameType
& MFX_FRAMETYPE_xP
)
1051 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
1052 else if (bs
->FrameType
& MFX_FRAMETYPE_B
|| bs
->FrameType
& MFX_FRAMETYPE_xB
)
1053 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
1054 FF_ENABLE_DEPRECATION_WARNINGS
1061 if (pkt
->size
< new_pkt
.size
) {
1062 av_log(avctx
, AV_LOG_ERROR
, "Submitted buffer not large enough: %d < %d\n",
1063 pkt
->size
, new_pkt
.size
);
1064 av_packet_unref(&new_pkt
);
1065 return AVERROR(EINVAL
);
1068 memcpy(pkt
->data
, new_pkt
.data
, new_pkt
.size
);
1069 pkt
->size
= new_pkt
.size
;
1071 ret
= av_packet_copy_props(pkt
, &new_pkt
);
1072 av_packet_unref(&new_pkt
);
1084 int ff_qsv_enc_close(AVCodecContext
*avctx
, QSVEncContext
*q
)
1089 MFXVideoENCODE_Close(q
->session
);
1090 if (q
->internal_session
)
1091 MFXClose(q
->internal_session
);
1093 q
->internal_session
= NULL
;
1095 av_buffer_unref(&q
->frames_ctx
.hw_frames_ctx
);
1096 av_buffer_unref(&q
->frames_ctx
.mids_buf
);
1098 cur
= q
->work_frames
;
1100 q
->work_frames
= cur
->next
;
1101 av_frame_free(&cur
->frame
);
1103 cur
= q
->work_frames
;
1106 while (q
->async_fifo
&& av_fifo_size(q
->async_fifo
)) {
1111 av_fifo_generic_read(q
->async_fifo
, &pkt
, sizeof(pkt
), NULL
);
1112 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1113 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1117 av_packet_unref(&pkt
);
1119 av_fifo_free(q
->async_fifo
);
1120 q
->async_fifo
= NULL
;
1122 av_freep(&q
->opaque_surfaces
);
1123 av_buffer_unref(&q
->opaque_alloc_buf
);
1125 av_freep(&q
->extparam
);