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_VERSION_ATLEAST(1, 9)
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
;
453 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco
;
456 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
457 q
->extco2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
458 q
->extco2
.Header
.BufferSz
= sizeof(q
->extco2
);
459 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco2
;
464 if (!rc_supported(q
)) {
465 av_log(avctx
, AV_LOG_ERROR
,
466 "Selected ratecontrol mode is not supported by the QSV "
467 "runtime. Choose a different mode.\n");
468 return AVERROR(ENOSYS
);
474 static int qsv_retrieve_enc_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
476 uint8_t sps_buf
[128];
477 uint8_t pps_buf
[128];
479 mfxExtCodingOptionSPSPPS extradata
= {
480 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION_SPSPPS
,
481 .Header
.BufferSz
= sizeof(extradata
),
482 .SPSBuffer
= sps_buf
, .SPSBufSize
= sizeof(sps_buf
),
483 .PPSBuffer
= pps_buf
, .PPSBufSize
= sizeof(pps_buf
)
486 mfxExtCodingOption co
= {
487 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
,
488 .Header
.BufferSz
= sizeof(co
),
491 mfxExtCodingOption2 co2
= {
492 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
,
493 .Header
.BufferSz
= sizeof(co2
),
497 mfxExtCodingOption3 co3
= {
498 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION3
,
499 .Header
.BufferSz
= sizeof(co3
),
503 mfxExtBuffer
*ext_buffers
[] = {
504 (mfxExtBuffer
*)&extradata
,
514 int need_pps
= avctx
->codec_id
!= AV_CODEC_ID_MPEG2VIDEO
;
517 q
->param
.ExtParam
= ext_buffers
;
518 q
->param
.NumExtParam
= FF_ARRAY_ELEMS(ext_buffers
);
520 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
522 return ff_qsv_error(ret
);
524 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
526 if (!extradata
.SPSBufSize
|| (need_pps
&& !extradata
.PPSBufSize
)) {
527 av_log(avctx
, AV_LOG_ERROR
, "No extradata returned from libmfx.\n");
528 return AVERROR_UNKNOWN
;
531 avctx
->extradata
= av_malloc(extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
+
532 AV_INPUT_BUFFER_PADDING_SIZE
);
533 if (!avctx
->extradata
)
534 return AVERROR(ENOMEM
);
536 memcpy(avctx
->extradata
, sps_buf
, extradata
.SPSBufSize
);
538 memcpy(avctx
->extradata
+ extradata
.SPSBufSize
, pps_buf
, extradata
.PPSBufSize
);
539 avctx
->extradata_size
= extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
;
540 memset(avctx
->extradata
+ avctx
->extradata_size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
542 dump_video_param(avctx
, q
, ext_buffers
+ 1);
547 static int qsv_init_opaque_alloc(AVCodecContext
*avctx
, QSVEncContext
*q
)
549 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
550 mfxFrameSurface1
*surfaces
;
553 nb_surfaces
= qsv
->nb_opaque_surfaces
+ q
->req
.NumFrameSuggested
+ q
->async_depth
;
555 q
->opaque_alloc_buf
= av_buffer_allocz(sizeof(*surfaces
) * nb_surfaces
);
556 if (!q
->opaque_alloc_buf
)
557 return AVERROR(ENOMEM
);
559 q
->opaque_surfaces
= av_malloc_array(nb_surfaces
, sizeof(*q
->opaque_surfaces
));
560 if (!q
->opaque_surfaces
)
561 return AVERROR(ENOMEM
);
563 surfaces
= (mfxFrameSurface1
*)q
->opaque_alloc_buf
->data
;
564 for (i
= 0; i
< nb_surfaces
; i
++) {
565 surfaces
[i
].Info
= q
->req
.Info
;
566 q
->opaque_surfaces
[i
] = surfaces
+ i
;
569 q
->opaque_alloc
.Header
.BufferId
= MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
570 q
->opaque_alloc
.Header
.BufferSz
= sizeof(q
->opaque_alloc
);
571 q
->opaque_alloc
.In
.Surfaces
= q
->opaque_surfaces
;
572 q
->opaque_alloc
.In
.NumSurface
= nb_surfaces
;
573 q
->opaque_alloc
.In
.Type
= q
->req
.Type
;
575 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->opaque_alloc
;
577 qsv
->nb_opaque_surfaces
= nb_surfaces
;
578 qsv
->opaque_surfaces
= q
->opaque_alloc_buf
;
579 qsv
->opaque_alloc_type
= q
->req
.Type
;
584 int ff_qsv_enc_init(AVCodecContext
*avctx
, QSVEncContext
*q
)
586 int opaque_alloc
= 0;
589 q
->param
.IOPattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
590 q
->param
.AsyncDepth
= q
->async_depth
;
592 q
->async_fifo
= av_fifo_alloc((1 + q
->async_depth
) *
593 (sizeof(AVPacket
) + sizeof(mfxSyncPoint
) + sizeof(mfxBitstream
*)));
595 return AVERROR(ENOMEM
);
597 if (avctx
->hwaccel_context
) {
598 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
600 q
->session
= qsv
->session
;
601 q
->param
.IOPattern
= qsv
->iopattern
;
603 opaque_alloc
= qsv
->opaque_alloc
;
607 ret
= ff_qsv_init_internal_session(avctx
, &q
->internal_session
,
612 q
->session
= q
->internal_session
;
615 ret
= init_video_param(avctx
, q
);
619 ret
= MFXVideoENCODE_QueryIOSurf(q
->session
, &q
->param
, &q
->req
);
621 av_log(avctx
, AV_LOG_ERROR
, "Error querying the encoding parameters\n");
622 return ff_qsv_error(ret
);
626 ret
= qsv_init_opaque_alloc(avctx
, q
);
631 if (avctx
->hwaccel_context
) {
632 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
635 q
->extparam
= av_mallocz_array(qsv
->nb_ext_buffers
+ q
->nb_extparam_internal
,
636 sizeof(*q
->extparam
));
638 return AVERROR(ENOMEM
);
640 q
->param
.ExtParam
= q
->extparam
;
641 for (i
= 0; i
< qsv
->nb_ext_buffers
; i
++)
642 q
->param
.ExtParam
[i
] = qsv
->ext_buffers
[i
];
643 q
->param
.NumExtParam
= qsv
->nb_ext_buffers
;
645 for (i
= 0; i
< q
->nb_extparam_internal
; i
++) {
646 for (j
= 0; j
< qsv
->nb_ext_buffers
; j
++) {
647 if (qsv
->ext_buffers
[j
]->BufferId
== q
->extparam_internal
[i
]->BufferId
)
650 if (j
< qsv
->nb_ext_buffers
)
653 q
->param
.ExtParam
[q
->param
.NumExtParam
++] = q
->extparam_internal
[i
];
656 q
->param
.ExtParam
= q
->extparam_internal
;
657 q
->param
.NumExtParam
= q
->nb_extparam_internal
;
660 ret
= MFXVideoENCODE_Init(q
->session
, &q
->param
);
662 av_log(avctx
, AV_LOG_ERROR
, "Error initializing the encoder\n");
663 return ff_qsv_error(ret
);
666 ret
= qsv_retrieve_enc_params(avctx
, q
);
668 av_log(avctx
, AV_LOG_ERROR
, "Error retrieving encoding parameters.\n");
677 static void clear_unused_frames(QSVEncContext
*q
)
679 QSVFrame
*cur
= q
->work_frames
;
681 if (cur
->surface
&& !cur
->surface
->Data
.Locked
) {
683 av_frame_unref(cur
->frame
);
689 static int get_free_frame(QSVEncContext
*q
, QSVFrame
**f
)
691 QSVFrame
*frame
, **last
;
693 clear_unused_frames(q
);
695 frame
= q
->work_frames
;
696 last
= &q
->work_frames
;
698 if (!frame
->surface
) {
707 frame
= av_mallocz(sizeof(*frame
));
709 return AVERROR(ENOMEM
);
710 frame
->frame
= av_frame_alloc();
713 return AVERROR(ENOMEM
);
722 static int submit_frame(QSVEncContext
*q
, const AVFrame
*frame
,
723 mfxFrameSurface1
**surface
)
728 ret
= get_free_frame(q
, &qf
);
732 if (frame
->format
== AV_PIX_FMT_QSV
) {
733 ret
= av_frame_ref(qf
->frame
, frame
);
737 qf
->surface
= (mfxFrameSurface1
*)qf
->frame
->data
[3];
739 /* make a copy if the input is not padded as libmfx requires */
740 if (frame
->height
& 31 || frame
->linesize
[0] & (q
->width_align
- 1)) {
741 qf
->frame
->height
= FFALIGN(frame
->height
, 32);
742 qf
->frame
->width
= FFALIGN(frame
->width
, q
->width_align
);
744 ret
= ff_get_buffer(q
->avctx
, qf
->frame
, AV_GET_BUFFER_FLAG_REF
);
748 qf
->frame
->height
= frame
->height
;
749 qf
->frame
->width
= frame
->width
;
750 ret
= av_frame_copy(qf
->frame
, frame
);
752 av_frame_unref(qf
->frame
);
756 ret
= av_frame_ref(qf
->frame
, frame
);
761 qf
->surface_internal
.Info
= q
->param
.mfx
.FrameInfo
;
763 qf
->surface_internal
.Info
.PicStruct
=
764 !frame
->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE
:
765 frame
->top_field_first ? MFX_PICSTRUCT_FIELD_TFF
:
766 MFX_PICSTRUCT_FIELD_BFF
;
767 if (frame
->repeat_pict
== 1)
768 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FIELD_REPEATED
;
769 else if (frame
->repeat_pict
== 2)
770 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_DOUBLING
;
771 else if (frame
->repeat_pict
== 4)
772 qf
->surface_internal
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_TRIPLING
;
774 qf
->surface_internal
.Data
.PitchLow
= qf
->frame
->linesize
[0];
775 qf
->surface_internal
.Data
.Y
= qf
->frame
->data
[0];
776 qf
->surface_internal
.Data
.UV
= qf
->frame
->data
[1];
778 qf
->surface
= &qf
->surface_internal
;
781 qf
->surface
->Data
.TimeStamp
= av_rescale_q(frame
->pts
, q
->avctx
->time_base
, (AVRational
){1, 90000});
783 *surface
= qf
->surface
;
788 static void print_interlace_msg(AVCodecContext
*avctx
, QSVEncContext
*q
)
790 if (q
->param
.mfx
.CodecId
== MFX_CODEC_AVC
) {
791 if (q
->param
.mfx
.CodecProfile
== MFX_PROFILE_AVC_BASELINE
||
792 q
->param
.mfx
.CodecLevel
< MFX_LEVEL_AVC_21
||
793 q
->param
.mfx
.CodecLevel
> MFX_LEVEL_AVC_41
)
794 av_log(avctx
, AV_LOG_WARNING
,
795 "Interlaced coding is supported"
796 " at Main/High Profile Level 2.1-4.1\n");
800 int ff_qsv_encode(AVCodecContext
*avctx
, QSVEncContext
*q
,
801 AVPacket
*pkt
, const AVFrame
*frame
, int *got_packet
)
803 AVPacket new_pkt
= { 0 };
806 mfxFrameSurface1
*surf
= NULL
;
807 mfxSyncPoint sync
= NULL
;
811 ret
= submit_frame(q
, frame
, &surf
);
813 av_log(avctx
, AV_LOG_ERROR
, "Error submitting the frame for encoding.\n");
818 ret
= av_new_packet(&new_pkt
, q
->packet_size
);
820 av_log(avctx
, AV_LOG_ERROR
, "Error allocating the output packet\n");
824 bs
= av_mallocz(sizeof(*bs
));
826 av_packet_unref(&new_pkt
);
827 return AVERROR(ENOMEM
);
829 bs
->Data
= new_pkt
.data
;
830 bs
->MaxLength
= new_pkt
.size
;
833 ret
= MFXVideoENCODE_EncodeFrameAsync(q
->session
, NULL
, surf
, bs
, &sync
);
834 if (ret
== MFX_WRN_DEVICE_BUSY
)
839 av_packet_unref(&new_pkt
);
841 return (ret
== MFX_ERR_MORE_DATA
) ?
0 : ff_qsv_error(ret
);
844 if (ret
== MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
&& frame
->interlaced_frame
)
845 print_interlace_msg(avctx
, q
);
848 av_fifo_generic_write(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
849 av_fifo_generic_write(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
850 av_fifo_generic_write(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
852 av_packet_unref(&new_pkt
);
856 if (!av_fifo_space(q
->async_fifo
) ||
857 (!frame
&& av_fifo_size(q
->async_fifo
))) {
858 av_fifo_generic_read(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
859 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
860 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
862 MFXVideoCORE_SyncOperation(q
->session
, sync
, 60000);
864 new_pkt
.dts
= av_rescale_q(bs
->DecodeTimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
865 new_pkt
.pts
= av_rescale_q(bs
->TimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
866 new_pkt
.size
= bs
->DataLength
;
868 if (bs
->FrameType
& MFX_FRAMETYPE_IDR
||
869 bs
->FrameType
& MFX_FRAMETYPE_xIDR
)
870 new_pkt
.flags
|= AV_PKT_FLAG_KEY
;
872 #if FF_API_CODED_FRAME
873 FF_DISABLE_DEPRECATION_WARNINGS
874 if (bs
->FrameType
& MFX_FRAMETYPE_I
|| bs
->FrameType
& MFX_FRAMETYPE_xI
)
875 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
876 else if (bs
->FrameType
& MFX_FRAMETYPE_P
|| bs
->FrameType
& MFX_FRAMETYPE_xP
)
877 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
878 else if (bs
->FrameType
& MFX_FRAMETYPE_B
|| bs
->FrameType
& MFX_FRAMETYPE_xB
)
879 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
880 FF_ENABLE_DEPRECATION_WARNINGS
886 if (pkt
->size
< new_pkt
.size
) {
887 av_log(avctx
, AV_LOG_ERROR
, "Submitted buffer not large enough: %d < %d\n",
888 pkt
->size
, new_pkt
.size
);
889 av_packet_unref(&new_pkt
);
890 return AVERROR(EINVAL
);
893 memcpy(pkt
->data
, new_pkt
.data
, new_pkt
.size
);
894 pkt
->size
= new_pkt
.size
;
896 ret
= av_packet_copy_props(pkt
, &new_pkt
);
897 av_packet_unref(&new_pkt
);
909 int ff_qsv_enc_close(AVCodecContext
*avctx
, QSVEncContext
*q
)
914 MFXVideoENCODE_Close(q
->session
);
915 if (q
->internal_session
)
916 MFXClose(q
->internal_session
);
918 q
->internal_session
= NULL
;
920 cur
= q
->work_frames
;
922 q
->work_frames
= cur
->next
;
923 av_frame_free(&cur
->frame
);
925 cur
= q
->work_frames
;
928 while (q
->async_fifo
&& av_fifo_size(q
->async_fifo
)) {
933 av_fifo_generic_read(q
->async_fifo
, &pkt
, sizeof(pkt
), NULL
);
934 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
935 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
938 av_packet_unref(&pkt
);
940 av_fifo_free(q
->async_fifo
);
941 q
->async_fifo
= NULL
;
943 av_freep(&q
->opaque_surfaces
);
944 av_buffer_unref(&q
->opaque_alloc_buf
);
946 av_freep(&q
->extparam
);