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" },
88 { MFX_RATECONTROL_AVBR
, "AVBR" },
91 { MFX_RATECONTROL_LA
, "LA" },
94 { MFX_RATECONTROL_ICQ
, "ICQ" },
95 { MFX_RATECONTROL_LA_ICQ
, "LA_ICQ" },
98 { MFX_RATECONTROL_VCM
, "VCM" },
100 #if QSV_VERSION_ATLEAST(1, 10)
101 { MFX_RATECONTROL_LA_EXT
, "LA_EXT" },
104 { MFX_RATECONTROL_LA_HRD
, "LA_HRD" },
107 { MFX_RATECONTROL_QVBR
, "QVBR" },
111 static const char *print_ratecontrol(mfxU16 rc_mode
)
114 for (i
= 0; i
< FF_ARRAY_ELEMS(rc_names
); i
++)
115 if (rc_mode
== rc_names
[i
].rc_mode
)
116 return rc_names
[i
].name
;
120 static const char *print_threestate(mfxU16 val
)
122 if (val
== MFX_CODINGOPTION_ON
)
124 else if (val
== MFX_CODINGOPTION_OFF
)
129 static void dump_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
,
130 mfxExtBuffer
**coding_opts
)
132 mfxInfoMFX
*info
= &q
->param
.mfx
;
134 mfxExtCodingOption
*co
= (mfxExtCodingOption
*)coding_opts
[0];
136 mfxExtCodingOption2
*co2
= (mfxExtCodingOption2
*)coding_opts
[1];
138 #if QSV_HAVE_CO3 && QSV_HAVE_QVBR
139 mfxExtCodingOption3
*co3
= (mfxExtCodingOption3
*)coding_opts
[2];
142 av_log(avctx
, AV_LOG_VERBOSE
, "profile: %s; level: %"PRIu16
"\n",
143 print_profile(info
->CodecProfile
), info
->CodecLevel
);
145 av_log(avctx
, AV_LOG_VERBOSE
, "GopPicSize: %"PRIu16
"; GopRefDist: %"PRIu16
"; GopOptFlag: ",
146 info
->GopPicSize
, info
->GopRefDist
);
147 if (info
->GopOptFlag
& MFX_GOP_CLOSED
)
148 av_log(avctx
, AV_LOG_VERBOSE
, "closed ");
149 if (info
->GopOptFlag
& MFX_GOP_STRICT
)
150 av_log(avctx
, AV_LOG_VERBOSE
, "strict ");
151 av_log(avctx
, AV_LOG_VERBOSE
, "; IdrInterval: %"PRIu16
"\n", info
->IdrInterval
);
153 av_log(avctx
, AV_LOG_VERBOSE
, "TargetUsage: %"PRIu16
"; RateControlMethod: %s\n",
154 info
->TargetUsage
, print_ratecontrol(info
->RateControlMethod
));
156 if (info
->RateControlMethod
== MFX_RATECONTROL_CBR
||
157 info
->RateControlMethod
== MFX_RATECONTROL_VBR
159 || info
->RateControlMethod
== MFX_RATECONTROL_VCM
162 av_log(avctx
, AV_LOG_VERBOSE
,
163 "BufferSizeInKB: %"PRIu16
"; InitialDelayInKB: %"PRIu16
"; TargetKbps: %"PRIu16
"; MaxKbps: %"PRIu16
"\n",
164 info
->BufferSizeInKB
, info
->InitialDelayInKB
, info
->TargetKbps
, info
->MaxKbps
);
165 } else if (info
->RateControlMethod
== MFX_RATECONTROL_CQP
) {
166 av_log(avctx
, AV_LOG_VERBOSE
, "QPI: %"PRIu16
"; QPP: %"PRIu16
"; QPB: %"PRIu16
"\n",
167 info
->QPI
, info
->QPP
, info
->QPB
);
170 else if (info
->RateControlMethod
== MFX_RATECONTROL_AVBR
) {
171 av_log(avctx
, AV_LOG_VERBOSE
,
172 "TargetKbps: %"PRIu16
"; Accuracy: %"PRIu16
"; Convergence: %"PRIu16
"\n",
173 info
->TargetKbps
, info
->Accuracy
, info
->Convergence
);
177 else if (info
->RateControlMethod
== MFX_RATECONTROL_LA
179 || info
->RateControlMethod
== MFX_RATECONTROL_LA_HRD
182 av_log(avctx
, AV_LOG_VERBOSE
,
183 "TargetKbps: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
184 info
->TargetKbps
, co2
->LookAheadDepth
);
188 else if (info
->RateControlMethod
== MFX_RATECONTROL_ICQ
) {
189 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"\n", info
->ICQQuality
);
190 } else if (info
->RateControlMethod
== MFX_RATECONTROL_LA_ICQ
) {
191 av_log(avctx
, AV_LOG_VERBOSE
, "ICQQuality: %"PRIu16
"; LookAheadDepth: %"PRIu16
"\n",
192 info
->ICQQuality
, co2
->LookAheadDepth
);
196 else if (info
->RateControlMethod
== MFX_RATECONTROL_QVBR
) {
197 av_log(avctx
, AV_LOG_VERBOSE
, "QVBRQuality: %"PRIu16
"\n",
202 av_log(avctx
, AV_LOG_VERBOSE
, "NumSlice: %"PRIu16
"; NumRefFrame: %"PRIu16
"\n",
203 info
->NumSlice
, info
->NumRefFrame
);
204 av_log(avctx
, AV_LOG_VERBOSE
, "RateDistortionOpt: %s\n",
205 print_threestate(co
->RateDistortionOpt
));
208 av_log(avctx
, AV_LOG_VERBOSE
,
209 "RecoveryPointSEI: %s IntRefType: %"PRIu16
"; IntRefCycleSize: %"PRIu16
"; IntRefQPDelta: %"PRId16
"\n",
210 print_threestate(co
->RecoveryPointSEI
), co2
->IntRefType
, co2
->IntRefCycleSize
, co2
->IntRefQPDelta
);
212 av_log(avctx
, AV_LOG_VERBOSE
, "MaxFrameSize: %"PRIu16
"; ", co2
->MaxFrameSize
);
213 #if QSV_HAVE_MAX_SLICE_SIZE
214 av_log(avctx
, AV_LOG_VERBOSE
, "MaxSliceSize: %"PRIu16
"; ", co2
->MaxSliceSize
);
216 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
218 av_log(avctx
, AV_LOG_VERBOSE
,
219 "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
220 print_threestate(co2
->BitrateLimit
), print_threestate(co2
->MBBRC
),
221 print_threestate(co2
->ExtBRC
));
224 av_log(avctx
, AV_LOG_VERBOSE
, "Trellis: ");
225 if (co2
->Trellis
& MFX_TRELLIS_OFF
) {
226 av_log(avctx
, AV_LOG_VERBOSE
, "off");
227 } else if (!co2
->Trellis
) {
228 av_log(avctx
, AV_LOG_VERBOSE
, "auto");
230 if (co2
->Trellis
& MFX_TRELLIS_I
) av_log(avctx
, AV_LOG_VERBOSE
, "I");
231 if (co2
->Trellis
& MFX_TRELLIS_P
) av_log(avctx
, AV_LOG_VERBOSE
, "P");
232 if (co2
->Trellis
& MFX_TRELLIS_B
) av_log(avctx
, AV_LOG_VERBOSE
, "B");
234 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
237 #if QSV_VERSION_ATLEAST(1, 8)
238 av_log(avctx
, AV_LOG_VERBOSE
,
239 "RepeatPPS: %s; NumMbPerSlice: %"PRIu16
"; LookAheadDS: ",
240 print_threestate(co2
->RepeatPPS
), co2
->NumMbPerSlice
);
241 switch (co2
->LookAheadDS
) {
242 case MFX_LOOKAHEAD_DS_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
243 case MFX_LOOKAHEAD_DS_2x
: av_log(avctx
, AV_LOG_VERBOSE
, "2x"); break;
244 case MFX_LOOKAHEAD_DS_4x
: av_log(avctx
, AV_LOG_VERBOSE
, "4x"); break;
245 default: av_log(avctx
, AV_LOG_VERBOSE
, "unknown"); break;
247 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
249 av_log(avctx
, AV_LOG_VERBOSE
, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
250 print_threestate(co2
->AdaptiveI
), print_threestate(co2
->AdaptiveB
));
251 switch (co2
->BRefType
) {
252 case MFX_B_REF_OFF
: av_log(avctx
, AV_LOG_VERBOSE
, "off"); break;
253 case MFX_B_REF_PYRAMID
: av_log(avctx
, AV_LOG_VERBOSE
, "pyramid"); break;
254 default: av_log(avctx
, AV_LOG_VERBOSE
, "auto"); break;
256 av_log(avctx
, AV_LOG_VERBOSE
, "\n");
259 #if QSV_VERSION_ATLEAST(1, 9)
260 av_log(avctx
, AV_LOG_VERBOSE
,
261 "MinQPI: %"PRIu8
"; MaxQPI: %"PRIu8
"; MinQPP: %"PRIu8
"; MaxQPP: %"PRIu8
"; MinQPB: %"PRIu8
"; MaxQPB: %"PRIu8
"\n",
262 co2
->MinQPI
, co2
->MaxQPI
, co2
->MinQPP
, co2
->MaxQPP
, co2
->MinQPB
, co2
->MaxQPB
);
266 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
267 av_log(avctx
, AV_LOG_VERBOSE
, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16
"\n",
268 co
->CAVLC
== MFX_CODINGOPTION_ON
? "CAVLC" : "CABAC", co
->MaxDecFrameBuffering
);
269 av_log(avctx
, AV_LOG_VERBOSE
,
270 "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",
271 print_threestate(co
->NalHrdConformance
), print_threestate(co
->SingleSeiNalUnit
),
272 print_threestate(co
->VuiVclHrdParameters
), print_threestate(co
->VuiNalHrdParameters
));
276 static int select_rc_mode(AVCodecContext
*avctx
, QSVEncContext
*q
)
281 int want_la
= q
->la_depth
>= 10;
282 int want_qscale
= !!(avctx
->flags
& AV_CODEC_FLAG_QSCALE
);
283 int want_vcm
= q
->vcm
;
285 if (want_la
&& !QSV_HAVE_LA
) {
286 av_log(avctx
, AV_LOG_ERROR
,
287 "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
288 return AVERROR(ENOSYS
);
290 if (want_vcm
&& !QSV_HAVE_VCM
) {
291 av_log(avctx
, AV_LOG_ERROR
,
292 "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
293 return AVERROR(ENOSYS
);
296 if (want_la
+ want_qscale
+ want_vcm
> 1) {
297 av_log(avctx
, AV_LOG_ERROR
,
298 "More than one of: { constant qscale, lookahead, VCM } requested, "
299 "only one of them can be used at a time.\n");
300 return AVERROR(EINVAL
);
303 if (!want_qscale
&& avctx
->global_quality
> 0 && !QSV_HAVE_ICQ
){
304 av_log(avctx
, AV_LOG_ERROR
,
305 "ICQ ratecontrol mode requested, but is not supported by this SDK version\n");
306 return AVERROR(ENOSYS
);
310 rc_mode
= MFX_RATECONTROL_CQP
;
311 rc_desc
= "constant quantization parameter (CQP)";
315 rc_mode
= MFX_RATECONTROL_VCM
;
316 rc_desc
= "video conferencing mode (VCM)";
321 rc_mode
= MFX_RATECONTROL_LA
;
322 rc_desc
= "VBR with lookahead (LA)";
325 if (avctx
->global_quality
> 0) {
326 rc_mode
= MFX_RATECONTROL_LA_ICQ
;
327 rc_desc
= "intelligent constant quality with lookahead (LA_ICQ)";
333 else if (avctx
->global_quality
> 0) {
334 rc_mode
= MFX_RATECONTROL_ICQ
;
335 rc_desc
= "intelligent constant quality (ICQ)";
338 else if (avctx
->rc_max_rate
== avctx
->bit_rate
) {
339 rc_mode
= MFX_RATECONTROL_CBR
;
340 rc_desc
= "constant bitrate (CBR)";
343 else if (!avctx
->rc_max_rate
) {
344 rc_mode
= MFX_RATECONTROL_AVBR
;
345 rc_desc
= "average variable bitrate (AVBR)";
349 rc_mode
= MFX_RATECONTROL_VBR
;
350 rc_desc
= "variable bitrate (VBR)";
353 q
->param
.mfx
.RateControlMethod
= rc_mode
;
354 av_log(avctx
, AV_LOG_VERBOSE
, "Using the %s ratecontrol method\n", rc_desc
);
359 static int check_enc_param(AVCodecContext
*avctx
, QSVEncContext
*q
)
361 mfxVideoParam param_out
= { .mfx
.CodecId
= q
->param
.mfx
.CodecId
};
364 #define UNMATCH(x) (param_out.mfx.x != q->param.mfx.x)
366 ret
= MFXVideoENCODE_Query(q
->session
, &q
->param
, ¶m_out
);
369 if (UNMATCH(CodecId
))
370 av_log(avctx
, AV_LOG_ERROR
, "Current codec type is unsupported\n");
371 if (UNMATCH(CodecProfile
))
372 av_log(avctx
, AV_LOG_ERROR
, "Current profile is unsupported\n");
373 if (UNMATCH(RateControlMethod
))
374 av_log(avctx
, AV_LOG_ERROR
, "Selected ratecontrol mode is unsupported\n");
375 if (UNMATCH(LowPower
))
376 av_log(avctx
, AV_LOG_ERROR
, "Low power mode is unsupported\n");
377 if (UNMATCH(FrameInfo
.FrameRateExtN
) || UNMATCH(FrameInfo
.FrameRateExtD
))
378 av_log(avctx
, AV_LOG_ERROR
, "Current frame rate is unsupported\n");
379 if (UNMATCH(FrameInfo
.PicStruct
))
380 av_log(avctx
, AV_LOG_ERROR
, "Current picture structure is unsupported\n");
381 if (UNMATCH(FrameInfo
.Width
) || UNMATCH(FrameInfo
.Height
))
382 av_log(avctx
, AV_LOG_ERROR
, "Current resolution is unsupported\n");
383 if (UNMATCH(FrameInfo
.FourCC
))
384 av_log(avctx
, AV_LOG_ERROR
, "Current pixel format is unsupported\n");
390 static int init_video_param_jpeg(AVCodecContext
*avctx
, QSVEncContext
*q
)
392 enum AVPixelFormat sw_format
= avctx
->pix_fmt
== AV_PIX_FMT_QSV
?
393 avctx
->sw_pix_fmt
: avctx
->pix_fmt
;
394 const AVPixFmtDescriptor
*desc
;
397 ret
= ff_qsv_codec_id_to_mfx(avctx
->codec_id
);
400 q
->param
.mfx
.CodecId
= ret
;
402 if (avctx
->level
> 0)
403 q
->param
.mfx
.CodecLevel
= avctx
->level
;
404 q
->param
.mfx
.CodecProfile
= q
->profile
;
406 desc
= av_pix_fmt_desc_get(sw_format
);
410 ff_qsv_map_pixfmt(sw_format
, &q
->param
.mfx
.FrameInfo
.FourCC
);
412 q
->param
.mfx
.FrameInfo
.CropX
= 0;
413 q
->param
.mfx
.FrameInfo
.CropY
= 0;
414 q
->param
.mfx
.FrameInfo
.CropW
= avctx
->width
;
415 q
->param
.mfx
.FrameInfo
.CropH
= avctx
->height
;
416 q
->param
.mfx
.FrameInfo
.AspectRatioW
= avctx
->sample_aspect_ratio
.num
;
417 q
->param
.mfx
.FrameInfo
.AspectRatioH
= avctx
->sample_aspect_ratio
.den
;
418 q
->param
.mfx
.FrameInfo
.ChromaFormat
= MFX_CHROMAFORMAT_YUV420
;
419 q
->param
.mfx
.FrameInfo
.BitDepthLuma
= desc
->comp
[0].depth
;
420 q
->param
.mfx
.FrameInfo
.BitDepthChroma
= desc
->comp
[0].depth
;
421 q
->param
.mfx
.FrameInfo
.Shift
= desc
->comp
[0].depth
> 8;
423 q
->param
.mfx
.FrameInfo
.Width
= FFALIGN(avctx
->width
, 16);
424 q
->param
.mfx
.FrameInfo
.Height
= FFALIGN(avctx
->height
, 16);
426 if (avctx
->hw_frames_ctx
) {
427 AVHWFramesContext
*frames_ctx
= (AVHWFramesContext
*)avctx
->hw_frames_ctx
->data
;
428 AVQSVFramesContext
*frames_hwctx
= frames_ctx
->hwctx
;
429 q
->param
.mfx
.FrameInfo
.Width
= frames_hwctx
->surfaces
[0].Info
.Width
;
430 q
->param
.mfx
.FrameInfo
.Height
= frames_hwctx
->surfaces
[0].Info
.Height
;
433 if (avctx
->framerate
.den
> 0 && avctx
->framerate
.num
> 0) {
434 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->framerate
.num
;
435 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->framerate
.den
;
437 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->time_base
.den
;
438 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->time_base
.num
;
441 q
->param
.mfx
.Interleaved
= 1;
442 q
->param
.mfx
.Quality
= av_clip(avctx
->global_quality
, 1, 100);
443 q
->param
.mfx
.RestartInterval
= 0;
448 static int init_video_param(AVCodecContext
*avctx
, QSVEncContext
*q
)
450 enum AVPixelFormat sw_format
= avctx
->pix_fmt
== AV_PIX_FMT_QSV
?
451 avctx
->sw_pix_fmt
: avctx
->pix_fmt
;
452 const AVPixFmtDescriptor
*desc
;
456 ret
= ff_qsv_codec_id_to_mfx(avctx
->codec_id
);
459 q
->param
.mfx
.CodecId
= ret
;
461 if (avctx
->level
> 0)
462 q
->param
.mfx
.CodecLevel
= avctx
->level
;
464 if (avctx
->compression_level
== FF_COMPRESSION_DEFAULT
) {
465 avctx
->compression_level
= q
->preset
;
466 } else if (avctx
->compression_level
>= 0) {
467 if (avctx
->compression_level
> MFX_TARGETUSAGE_BEST_SPEED
) {
468 av_log(avctx
, AV_LOG_WARNING
, "Invalid compression level: "
469 "valid range is 0-%d, using %d instead\n",
470 MFX_TARGETUSAGE_BEST_SPEED
, MFX_TARGETUSAGE_BEST_SPEED
);
471 avctx
->compression_level
= MFX_TARGETUSAGE_BEST_SPEED
;
476 q
->param
.mfx
.LowPower
= q
->low_power
? MFX_CODINGOPTION_ON
:MFX_CODINGOPTION_OFF
;
478 q
->param
.mfx
.CodecProfile
= q
->profile
;
479 q
->param
.mfx
.TargetUsage
= avctx
->compression_level
;
480 q
->param
.mfx
.GopPicSize
= FFMAX(0, avctx
->gop_size
);
481 q
->param
.mfx
.GopRefDist
= FFMAX(-1, avctx
->max_b_frames
) + 1;
482 q
->param
.mfx
.GopOptFlag
= avctx
->flags
& AV_CODEC_FLAG_CLOSED_GOP
?
484 q
->param
.mfx
.IdrInterval
= q
->idr_interval
;
485 q
->param
.mfx
.NumSlice
= avctx
->slices
;
486 q
->param
.mfx
.NumRefFrame
= FFMAX(0, avctx
->refs
);
487 q
->param
.mfx
.EncodedOrder
= 0;
488 q
->param
.mfx
.BufferSizeInKB
= 0;
490 desc
= av_pix_fmt_desc_get(sw_format
);
494 ff_qsv_map_pixfmt(sw_format
, &q
->param
.mfx
.FrameInfo
.FourCC
);
496 q
->param
.mfx
.FrameInfo
.CropX
= 0;
497 q
->param
.mfx
.FrameInfo
.CropY
= 0;
498 q
->param
.mfx
.FrameInfo
.CropW
= avctx
->width
;
499 q
->param
.mfx
.FrameInfo
.CropH
= avctx
->height
;
500 q
->param
.mfx
.FrameInfo
.AspectRatioW
= avctx
->sample_aspect_ratio
.num
;
501 q
->param
.mfx
.FrameInfo
.AspectRatioH
= avctx
->sample_aspect_ratio
.den
;
502 q
->param
.mfx
.FrameInfo
.ChromaFormat
= MFX_CHROMAFORMAT_YUV420
;
503 q
->param
.mfx
.FrameInfo
.BitDepthLuma
= desc
->comp
[0].depth
;
504 q
->param
.mfx
.FrameInfo
.BitDepthChroma
= desc
->comp
[0].depth
;
505 q
->param
.mfx
.FrameInfo
.Shift
= desc
->comp
[0].depth
> 8;
507 // TODO: detect version of MFX--if the minor version is greater than
508 // or equal to 19, then can use the same alignment settings as H.264
510 q
->width_align
= avctx
->codec_id
== AV_CODEC_ID_HEVC
? 32 : 16;
511 q
->param
.mfx
.FrameInfo
.Width
= FFALIGN(avctx
->width
, q
->width_align
);
513 if (avctx
->flags
& AV_CODEC_FLAG_INTERLACED_DCT
) {
514 // it is important that PicStruct be setup correctly from the
515 // start--otherwise, encoding doesn't work and results in a bunch
516 // of incompatible video parameter errors
517 q
->param
.mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_FIELD_TFF
;
518 // height alignment always must be 32 for interlaced video
519 q
->height_align
= 32;
521 q
->param
.mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_PROGRESSIVE
;
522 // for progressive video, the height should be aligned to 16 for
523 // H.264. For HEVC, depending on the version of MFX, it should be
524 // either 32 or 16. The lower number is better if possible.
525 q
->height_align
= avctx
->codec_id
== AV_CODEC_ID_HEVC
? 32 : 16;
527 q
->param
.mfx
.FrameInfo
.Height
= FFALIGN(avctx
->height
, q
->height_align
);
529 if (avctx
->hw_frames_ctx
) {
530 AVHWFramesContext
*frames_ctx
= (AVHWFramesContext
*)avctx
->hw_frames_ctx
->data
;
531 AVQSVFramesContext
*frames_hwctx
= frames_ctx
->hwctx
;
532 q
->param
.mfx
.FrameInfo
.Width
= frames_hwctx
->surfaces
[0].Info
.Width
;
533 q
->param
.mfx
.FrameInfo
.Height
= frames_hwctx
->surfaces
[0].Info
.Height
;
536 if (avctx
->framerate
.den
> 0 && avctx
->framerate
.num
> 0) {
537 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->framerate
.num
;
538 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->framerate
.den
;
540 q
->param
.mfx
.FrameInfo
.FrameRateExtN
= avctx
->time_base
.den
;
541 q
->param
.mfx
.FrameInfo
.FrameRateExtD
= avctx
->time_base
.num
;
544 ret
= select_rc_mode(avctx
, q
);
548 switch (q
->param
.mfx
.RateControlMethod
) {
549 case MFX_RATECONTROL_CBR
:
550 case MFX_RATECONTROL_VBR
:
552 case MFX_RATECONTROL_VCM
:
554 q
->param
.mfx
.BufferSizeInKB
= avctx
->rc_buffer_size
/ 8000;
555 q
->param
.mfx
.InitialDelayInKB
= avctx
->rc_initial_buffer_occupancy
/ 1000;
556 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
557 q
->param
.mfx
.MaxKbps
= avctx
->rc_max_rate
/ 1000;
559 case MFX_RATECONTROL_CQP
:
560 quant
= avctx
->global_quality
/ FF_QP2LAMBDA
;
562 q
->param
.mfx
.QPI
= av_clip(quant
* fabs(avctx
->i_quant_factor
) + avctx
->i_quant_offset
, 0, 51);
563 q
->param
.mfx
.QPP
= av_clip(quant
, 0, 51);
564 q
->param
.mfx
.QPB
= av_clip(quant
* fabs(avctx
->b_quant_factor
) + avctx
->b_quant_offset
, 0, 51);
568 case MFX_RATECONTROL_AVBR
:
569 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
570 q
->param
.mfx
.Convergence
= q
->avbr_convergence
;
571 q
->param
.mfx
.Accuracy
= q
->avbr_accuracy
;
575 case MFX_RATECONTROL_LA
:
576 q
->param
.mfx
.TargetKbps
= avctx
->bit_rate
/ 1000;
577 q
->extco2
.LookAheadDepth
= q
->la_depth
;
580 case MFX_RATECONTROL_LA_ICQ
:
581 q
->extco2
.LookAheadDepth
= q
->la_depth
;
582 case MFX_RATECONTROL_ICQ
:
583 q
->param
.mfx
.ICQQuality
= avctx
->global_quality
;
589 // the HEVC encoder plugin currently fails if coding options
591 if (avctx
->codec_id
!= AV_CODEC_ID_HEVC
) {
592 q
->extco
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
;
593 q
->extco
.Header
.BufferSz
= sizeof(q
->extco
);
596 q
->extco
.RateDistortionOpt
= q
->rdo
> 0 ? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
598 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
599 #if FF_API_CODER_TYPE
600 FF_DISABLE_DEPRECATION_WARNINGS
601 if (avctx
->coder_type
>= 0)
602 q
->cavlc
= avctx
->coder_type
== FF_CODER_TYPE_VLC
;
603 FF_ENABLE_DEPRECATION_WARNINGS
605 q
->extco
.CAVLC
= q
->cavlc
? MFX_CODINGOPTION_ON
606 : MFX_CODINGOPTION_UNKNOWN
;
608 if (avctx
->strict_std_compliance
!= FF_COMPLIANCE_NORMAL
)
609 q
->extco
.NalHrdConformance
= avctx
->strict_std_compliance
> FF_COMPLIANCE_NORMAL
?
610 MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
612 if (q
->single_sei_nal_unit
>= 0)
613 q
->extco
.SingleSeiNalUnit
= q
->single_sei_nal_unit
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
614 if (q
->recovery_point_sei
>= 0)
615 q
->extco
.RecoveryPointSEI
= q
->recovery_point_sei
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
616 q
->extco
.MaxDecFrameBuffering
= q
->max_dec_frame_buffering
;
617 q
->extco
.AUDelimiter
= q
->aud
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
620 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco
;
623 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
624 q
->extco2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
625 q
->extco2
.Header
.BufferSz
= sizeof(q
->extco2
);
627 if (q
->int_ref_type
>= 0)
628 q
->extco2
.IntRefType
= q
->int_ref_type
;
629 if (q
->int_ref_cycle_size
>= 0)
630 q
->extco2
.IntRefCycleSize
= q
->int_ref_cycle_size
;
631 if (q
->int_ref_qp_delta
!= INT16_MIN
)
632 q
->extco2
.IntRefQPDelta
= q
->int_ref_qp_delta
;
634 if (q
->bitrate_limit
>= 0)
635 q
->extco2
.BitrateLimit
= q
->bitrate_limit
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
637 q
->extco2
.MBBRC
= q
->mbbrc
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
639 q
->extco2
.ExtBRC
= q
->extbrc
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
641 if (q
->max_frame_size
>= 0)
642 q
->extco2
.MaxFrameSize
= q
->max_frame_size
;
643 #if QSV_HAVE_MAX_SLICE_SIZE
644 if (q
->max_slice_size
>= 0)
645 q
->extco2
.MaxSliceSize
= q
->max_slice_size
;
649 q
->extco2
.Trellis
= q
->trellis
;
653 q
->extco2
.LookAheadDS
= q
->la_ds
;
656 #if QSV_HAVE_BREF_TYPE
657 #if FF_API_PRIVATE_OPT
658 FF_DISABLE_DEPRECATION_WARNINGS
659 if (avctx
->b_frame_strategy
>= 0)
660 q
->b_strategy
= avctx
->b_frame_strategy
;
661 FF_ENABLE_DEPRECATION_WARNINGS
663 if (q
->b_strategy
>= 0)
664 q
->extco2
.BRefType
= q
->b_strategy
? MFX_B_REF_PYRAMID
: MFX_B_REF_OFF
;
665 if (q
->adaptive_i
>= 0)
666 q
->extco2
.AdaptiveI
= q
->adaptive_i
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
667 if (q
->adaptive_b
>= 0)
668 q
->extco2
.AdaptiveB
= q
->adaptive_b
? MFX_CODINGOPTION_ON
: MFX_CODINGOPTION_OFF
;
671 #if QSV_VERSION_ATLEAST(1, 9)
672 if (avctx
->qmin
>= 0 && avctx
->qmax
>= 0 && avctx
->qmin
> avctx
->qmax
) {
673 av_log(avctx
, AV_LOG_ERROR
, "qmin and or qmax are set but invalid, please make sure min <= max\n");
674 return AVERROR(EINVAL
);
676 if (avctx
->qmin
>= 0) {
677 q
->extco2
.MinQPI
= avctx
->qmin
> 51 ? 51 : avctx
->qmin
;
678 q
->extco2
.MinQPP
= q
->extco2
.MinQPB
= q
->extco2
.MinQPI
;
680 if (avctx
->qmax
>= 0) {
681 q
->extco2
.MaxQPI
= avctx
->qmax
> 51 ? 51 : avctx
->qmax
;
682 q
->extco2
.MaxQPP
= q
->extco2
.MaxQPB
= q
->extco2
.MaxQPI
;
685 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extco2
;
689 if (avctx
->codec_id
== AV_CODEC_ID_H264
) {
691 ret
= MFXQueryVersion(q
->session
,&ver
);
692 if (ret
>= MFX_ERR_NONE
&& QSV_RUNTIME_VERSION_ATLEAST(ver
, 1, 25)) {
693 q
->extmfp
.Header
.BufferId
= MFX_EXTBUFF_MULTI_FRAME_PARAM
;
694 q
->extmfp
.Header
.BufferSz
= sizeof(q
->extmfp
);
696 q
->extmfp
.MFMode
= q
->mfmode
;
697 av_log(avctx
,AV_LOG_VERBOSE
,"MFMode:%d\n", q
->extmfp
.MFMode
);
698 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->extmfp
;
704 if (!check_enc_param(avctx
,q
)) {
705 av_log(avctx
, AV_LOG_ERROR
,
706 "some encoding parameters are not supported by the QSV "
707 "runtime. Please double check the input parameters.\n");
708 return AVERROR(ENOSYS
);
714 static int qsv_retrieve_enc_jpeg_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
718 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
720 return ff_qsv_print_error(avctx
, ret
,
721 "Error calling GetVideoParam");
723 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
725 // for qsv mjpeg the return value maybe 0 so alloc the buffer
726 if (q
->packet_size
== 0)
727 q
->packet_size
= q
->param
.mfx
.FrameInfo
.Height
* q
->param
.mfx
.FrameInfo
.Width
* 4;
732 static int qsv_retrieve_enc_params(AVCodecContext
*avctx
, QSVEncContext
*q
)
734 AVCPBProperties
*cpb_props
;
736 uint8_t sps_buf
[128];
737 uint8_t pps_buf
[128];
739 mfxExtCodingOptionSPSPPS extradata
= {
740 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION_SPSPPS
,
741 .Header
.BufferSz
= sizeof(extradata
),
742 .SPSBuffer
= sps_buf
, .SPSBufSize
= sizeof(sps_buf
),
743 .PPSBuffer
= pps_buf
, .PPSBufSize
= sizeof(pps_buf
)
746 mfxExtCodingOption co
= {
747 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
,
748 .Header
.BufferSz
= sizeof(co
),
751 mfxExtCodingOption2 co2
= {
752 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
,
753 .Header
.BufferSz
= sizeof(co2
),
757 mfxExtCodingOption3 co3
= {
758 .Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION3
,
759 .Header
.BufferSz
= sizeof(co3
),
763 mfxExtBuffer
*ext_buffers
[] = {
764 (mfxExtBuffer
*)&extradata
,
774 int need_pps
= avctx
->codec_id
!= AV_CODEC_ID_MPEG2VIDEO
;
777 q
->param
.ExtParam
= ext_buffers
;
778 q
->param
.NumExtParam
= FF_ARRAY_ELEMS(ext_buffers
);
780 ret
= MFXVideoENCODE_GetVideoParam(q
->session
, &q
->param
);
782 return ff_qsv_print_error(avctx
, ret
,
783 "Error calling GetVideoParam");
785 q
->packet_size
= q
->param
.mfx
.BufferSizeInKB
* 1000;
787 if (!extradata
.SPSBufSize
|| (need_pps
&& !extradata
.PPSBufSize
)) {
788 av_log(avctx
, AV_LOG_ERROR
, "No extradata returned from libmfx.\n");
789 return AVERROR_UNKNOWN
;
792 avctx
->extradata
= av_malloc(extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
+
793 AV_INPUT_BUFFER_PADDING_SIZE
);
794 if (!avctx
->extradata
)
795 return AVERROR(ENOMEM
);
797 memcpy(avctx
->extradata
, sps_buf
, extradata
.SPSBufSize
);
799 memcpy(avctx
->extradata
+ extradata
.SPSBufSize
, pps_buf
, extradata
.PPSBufSize
);
800 avctx
->extradata_size
= extradata
.SPSBufSize
+ need_pps
* extradata
.PPSBufSize
;
801 memset(avctx
->extradata
+ avctx
->extradata_size
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
803 cpb_props
= ff_add_cpb_side_data(avctx
);
805 return AVERROR(ENOMEM
);
806 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
807 cpb_props
->min_bitrate
= avctx
->rc_min_rate
;
808 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
809 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
811 dump_video_param(avctx
, q
, ext_buffers
+ 1);
816 static int qsv_init_opaque_alloc(AVCodecContext
*avctx
, QSVEncContext
*q
)
818 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
819 mfxFrameSurface1
*surfaces
;
822 nb_surfaces
= qsv
->nb_opaque_surfaces
+ q
->req
.NumFrameSuggested
;
824 q
->opaque_alloc_buf
= av_buffer_allocz(sizeof(*surfaces
) * nb_surfaces
);
825 if (!q
->opaque_alloc_buf
)
826 return AVERROR(ENOMEM
);
828 q
->opaque_surfaces
= av_malloc_array(nb_surfaces
, sizeof(*q
->opaque_surfaces
));
829 if (!q
->opaque_surfaces
)
830 return AVERROR(ENOMEM
);
832 surfaces
= (mfxFrameSurface1
*)q
->opaque_alloc_buf
->data
;
833 for (i
= 0; i
< nb_surfaces
; i
++) {
834 surfaces
[i
].Info
= q
->req
.Info
;
835 q
->opaque_surfaces
[i
] = surfaces
+ i
;
838 q
->opaque_alloc
.Header
.BufferId
= MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
839 q
->opaque_alloc
.Header
.BufferSz
= sizeof(q
->opaque_alloc
);
840 q
->opaque_alloc
.In
.Surfaces
= q
->opaque_surfaces
;
841 q
->opaque_alloc
.In
.NumSurface
= nb_surfaces
;
842 q
->opaque_alloc
.In
.Type
= q
->req
.Type
;
844 q
->extparam_internal
[q
->nb_extparam_internal
++] = (mfxExtBuffer
*)&q
->opaque_alloc
;
846 qsv
->nb_opaque_surfaces
= nb_surfaces
;
847 qsv
->opaque_surfaces
= q
->opaque_alloc_buf
;
848 qsv
->opaque_alloc_type
= q
->req
.Type
;
853 static int qsvenc_init_session(AVCodecContext
*avctx
, QSVEncContext
*q
)
857 if (avctx
->hwaccel_context
) {
858 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
859 q
->session
= qsv
->session
;
860 } else if (avctx
->hw_frames_ctx
) {
861 q
->frames_ctx
.hw_frames_ctx
= av_buffer_ref(avctx
->hw_frames_ctx
);
862 if (!q
->frames_ctx
.hw_frames_ctx
)
863 return AVERROR(ENOMEM
);
865 ret
= ff_qsv_init_session_frames(avctx
, &q
->internal_session
,
866 &q
->frames_ctx
, q
->load_plugins
,
867 q
->param
.IOPattern
== MFX_IOPATTERN_IN_OPAQUE_MEMORY
);
869 av_buffer_unref(&q
->frames_ctx
.hw_frames_ctx
);
873 q
->session
= q
->internal_session
;
874 } else if (avctx
->hw_device_ctx
) {
875 ret
= ff_qsv_init_session_device(avctx
, &q
->internal_session
,
876 avctx
->hw_device_ctx
, q
->load_plugins
);
880 q
->session
= q
->internal_session
;
882 ret
= ff_qsv_init_internal_session(avctx
, &q
->internal_session
,
887 q
->session
= q
->internal_session
;
893 static inline unsigned int qsv_fifo_item_size(void)
895 return sizeof(AVPacket
) + sizeof(mfxSyncPoint
*) + sizeof(mfxBitstream
*);
898 static inline unsigned int qsv_fifo_size(const AVFifoBuffer
* fifo
)
900 return av_fifo_size(fifo
)/qsv_fifo_item_size();
903 int ff_qsv_enc_init(AVCodecContext
*avctx
, QSVEncContext
*q
)
906 int opaque_alloc
= 0;
909 q
->param
.AsyncDepth
= q
->async_depth
;
911 q
->async_fifo
= av_fifo_alloc(q
->async_depth
* qsv_fifo_item_size());
913 return AVERROR(ENOMEM
);
915 if (avctx
->hwaccel_context
) {
916 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
918 iopattern
= qsv
->iopattern
;
919 opaque_alloc
= qsv
->opaque_alloc
;
922 if (avctx
->hw_frames_ctx
) {
923 AVHWFramesContext
*frames_ctx
= (AVHWFramesContext
*)avctx
->hw_frames_ctx
->data
;
924 AVQSVFramesContext
*frames_hwctx
= frames_ctx
->hwctx
;
927 if (frames_hwctx
->frame_type
& MFX_MEMTYPE_OPAQUE_FRAME
)
928 iopattern
= MFX_IOPATTERN_IN_OPAQUE_MEMORY
;
929 else if (frames_hwctx
->frame_type
&
930 (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET
| MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET
))
931 iopattern
= MFX_IOPATTERN_IN_VIDEO_MEMORY
;
936 iopattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
937 q
->param
.IOPattern
= iopattern
;
939 ret
= qsvenc_init_session(avctx
, q
);
943 // in the mfxInfoMFX struct, JPEG is different from other codecs
944 switch (avctx
->codec_id
) {
945 case AV_CODEC_ID_MJPEG
:
946 ret
= init_video_param_jpeg(avctx
, q
);
949 ret
= init_video_param(avctx
, q
);
955 ret
= MFXVideoENCODE_Query(q
->session
, &q
->param
, &q
->param
);
956 if (ret
== MFX_WRN_PARTIAL_ACCELERATION
) {
957 av_log(avctx
, AV_LOG_WARNING
, "Encoder will work with partial HW acceleration\n");
958 } else if (ret
< 0) {
959 return ff_qsv_print_error(avctx
, ret
,
960 "Error querying encoder params");
963 ret
= MFXVideoENCODE_QueryIOSurf(q
->session
, &q
->param
, &q
->req
);
965 return ff_qsv_print_error(avctx
, ret
,
966 "Error querying (IOSurf) the encoding parameters");
969 ret
= qsv_init_opaque_alloc(avctx
, q
);
974 if (avctx
->hwaccel_context
) {
975 AVQSVContext
*qsv
= avctx
->hwaccel_context
;
978 q
->extparam
= av_mallocz_array(qsv
->nb_ext_buffers
+ q
->nb_extparam_internal
,
979 sizeof(*q
->extparam
));
981 return AVERROR(ENOMEM
);
983 q
->param
.ExtParam
= q
->extparam
;
984 for (i
= 0; i
< qsv
->nb_ext_buffers
; i
++)
985 q
->param
.ExtParam
[i
] = qsv
->ext_buffers
[i
];
986 q
->param
.NumExtParam
= qsv
->nb_ext_buffers
;
988 for (i
= 0; i
< q
->nb_extparam_internal
; i
++) {
989 for (j
= 0; j
< qsv
->nb_ext_buffers
; j
++) {
990 if (qsv
->ext_buffers
[j
]->BufferId
== q
->extparam_internal
[i
]->BufferId
)
993 if (j
< qsv
->nb_ext_buffers
)
996 q
->param
.ExtParam
[q
->param
.NumExtParam
++] = q
->extparam_internal
[i
];
999 q
->param
.ExtParam
= q
->extparam_internal
;
1000 q
->param
.NumExtParam
= q
->nb_extparam_internal
;
1003 ret
= MFXVideoENCODE_Init(q
->session
, &q
->param
);
1005 return ff_qsv_print_error(avctx
, ret
,
1006 "Error initializing the encoder");
1008 ff_qsv_print_warning(avctx
, ret
,
1009 "Warning in encoder initialization");
1011 switch (avctx
->codec_id
) {
1012 case AV_CODEC_ID_MJPEG
:
1013 ret
= qsv_retrieve_enc_jpeg_params(avctx
, q
);
1016 ret
= qsv_retrieve_enc_params(avctx
, q
);
1020 av_log(avctx
, AV_LOG_ERROR
, "Error retrieving encoding parameters.\n");
1029 static void clear_unused_frames(QSVEncContext
*q
)
1031 QSVFrame
*cur
= q
->work_frames
;
1033 if (cur
->used
&& !cur
->surface
.Data
.Locked
) {
1034 if (cur
->frame
->format
== AV_PIX_FMT_QSV
) {
1035 av_frame_unref(cur
->frame
);
1043 static int get_free_frame(QSVEncContext
*q
, QSVFrame
**f
)
1045 QSVFrame
*frame
, **last
;
1047 clear_unused_frames(q
);
1049 frame
= q
->work_frames
;
1050 last
= &q
->work_frames
;
1058 last
= &frame
->next
;
1059 frame
= frame
->next
;
1062 frame
= av_mallocz(sizeof(*frame
));
1064 return AVERROR(ENOMEM
);
1065 frame
->frame
= av_frame_alloc();
1066 if (!frame
->frame
) {
1068 return AVERROR(ENOMEM
);
1078 static int submit_frame(QSVEncContext
*q
, const AVFrame
*frame
,
1079 mfxFrameSurface1
**surface
)
1084 ret
= get_free_frame(q
, &qf
);
1088 if (frame
->format
== AV_PIX_FMT_QSV
) {
1089 ret
= av_frame_ref(qf
->frame
, frame
);
1093 qf
->surface
= *(mfxFrameSurface1
*)qf
->frame
->data
[3];
1095 if (q
->frames_ctx
.mids
) {
1096 ret
= ff_qsv_find_surface_idx(&q
->frames_ctx
, qf
);
1100 qf
->surface
.Data
.MemId
= &q
->frames_ctx
.mids
[ret
];
1103 /* make a copy if the input is not padded as libmfx requires */
1104 /* and to make allocation continious for data[0]/data[1] */
1105 if ((frame
->height
& 31 || frame
->linesize
[0] & (q
->width_align
- 1)) ||
1106 (frame
->data
[1] - frame
->data
[0] != frame
->linesize
[0] * FFALIGN(qf
->frame
->height
, q
->height_align
))) {
1107 qf
->frame
->height
= FFALIGN(frame
->height
, q
->height_align
);
1108 qf
->frame
->width
= FFALIGN(frame
->width
, q
->width_align
);
1110 qf
->frame
->format
= frame
->format
;
1112 if (!qf
->frame
->data
[0]) {
1113 ret
= av_frame_get_buffer(qf
->frame
, q
->width_align
);
1118 qf
->frame
->height
= frame
->height
;
1119 qf
->frame
->width
= frame
->width
;
1121 ret
= av_frame_copy(qf
->frame
, frame
);
1123 av_frame_unref(qf
->frame
);
1127 ret
= av_frame_ref(qf
->frame
, frame
);
1132 qf
->surface
.Info
= q
->param
.mfx
.FrameInfo
;
1134 qf
->surface
.Info
.PicStruct
=
1135 !frame
->interlaced_frame
? MFX_PICSTRUCT_PROGRESSIVE
:
1136 frame
->top_field_first
? MFX_PICSTRUCT_FIELD_TFF
:
1137 MFX_PICSTRUCT_FIELD_BFF
;
1138 if (frame
->repeat_pict
== 1)
1139 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FIELD_REPEATED
;
1140 else if (frame
->repeat_pict
== 2)
1141 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_DOUBLING
;
1142 else if (frame
->repeat_pict
== 4)
1143 qf
->surface
.Info
.PicStruct
|= MFX_PICSTRUCT_FRAME_TRIPLING
;
1145 qf
->surface
.Data
.PitchLow
= qf
->frame
->linesize
[0];
1146 qf
->surface
.Data
.Y
= qf
->frame
->data
[0];
1147 qf
->surface
.Data
.UV
= qf
->frame
->data
[1];
1150 qf
->surface
.Data
.TimeStamp
= av_rescale_q(frame
->pts
, q
->avctx
->time_base
, (AVRational
){1, 90000});
1152 *surface
= &qf
->surface
;
1157 static void print_interlace_msg(AVCodecContext
*avctx
, QSVEncContext
*q
)
1159 if (q
->param
.mfx
.CodecId
== MFX_CODEC_AVC
) {
1160 if (q
->param
.mfx
.CodecProfile
== MFX_PROFILE_AVC_BASELINE
||
1161 q
->param
.mfx
.CodecLevel
< MFX_LEVEL_AVC_21
||
1162 q
->param
.mfx
.CodecLevel
> MFX_LEVEL_AVC_41
)
1163 av_log(avctx
, AV_LOG_WARNING
,
1164 "Interlaced coding is supported"
1165 " at Main/High Profile Level 2.2-4.0\n");
1169 static int encode_frame(AVCodecContext
*avctx
, QSVEncContext
*q
,
1170 const AVFrame
*frame
)
1172 AVPacket new_pkt
= { 0 };
1175 mfxFrameSurface1
*surf
= NULL
;
1176 mfxSyncPoint
*sync
= NULL
;
1180 ret
= submit_frame(q
, frame
, &surf
);
1182 av_log(avctx
, AV_LOG_ERROR
, "Error submitting the frame for encoding.\n");
1187 ret
= av_new_packet(&new_pkt
, q
->packet_size
);
1189 av_log(avctx
, AV_LOG_ERROR
, "Error allocating the output packet\n");
1193 bs
= av_mallocz(sizeof(*bs
));
1195 av_packet_unref(&new_pkt
);
1196 return AVERROR(ENOMEM
);
1198 bs
->Data
= new_pkt
.data
;
1199 bs
->MaxLength
= new_pkt
.size
;
1201 sync
= av_mallocz(sizeof(*sync
));
1204 av_packet_unref(&new_pkt
);
1205 return AVERROR(ENOMEM
);
1209 ret
= MFXVideoENCODE_EncodeFrameAsync(q
->session
, NULL
, surf
, bs
, sync
);
1210 if (ret
== MFX_WRN_DEVICE_BUSY
)
1212 } while (ret
== MFX_WRN_DEVICE_BUSY
|| ret
== MFX_WRN_IN_EXECUTION
);
1215 ff_qsv_print_warning(avctx
, ret
, "Warning during encoding");
1218 av_packet_unref(&new_pkt
);
1221 return (ret
== MFX_ERR_MORE_DATA
) ?
1222 0 : ff_qsv_print_error(avctx
, ret
, "Error during encoding");
1225 if (ret
== MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
&& frame
->interlaced_frame
)
1226 print_interlace_msg(avctx
, q
);
1229 av_fifo_generic_write(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
1230 av_fifo_generic_write(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1231 av_fifo_generic_write(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1234 av_packet_unref(&new_pkt
);
1241 int ff_qsv_encode(AVCodecContext
*avctx
, QSVEncContext
*q
,
1242 AVPacket
*pkt
, const AVFrame
*frame
, int *got_packet
)
1246 ret
= encode_frame(avctx
, q
, frame
);
1250 if ((qsv_fifo_size(q
->async_fifo
) >= q
->async_depth
) ||
1251 (!frame
&& av_fifo_size(q
->async_fifo
))) {
1256 av_fifo_generic_read(q
->async_fifo
, &new_pkt
, sizeof(new_pkt
), NULL
);
1257 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1258 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1261 ret
= MFXVideoCORE_SyncOperation(q
->session
, *sync
, 1000);
1262 } while (ret
== MFX_WRN_IN_EXECUTION
);
1264 new_pkt
.dts
= av_rescale_q(bs
->DecodeTimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
1265 new_pkt
.pts
= av_rescale_q(bs
->TimeStamp
, (AVRational
){1, 90000}, avctx
->time_base
);
1266 new_pkt
.size
= bs
->DataLength
;
1268 if (bs
->FrameType
& MFX_FRAMETYPE_IDR
||
1269 bs
->FrameType
& MFX_FRAMETYPE_xIDR
)
1270 new_pkt
.flags
|= AV_PKT_FLAG_KEY
;
1272 #if FF_API_CODED_FRAME
1273 FF_DISABLE_DEPRECATION_WARNINGS
1274 if (bs
->FrameType
& MFX_FRAMETYPE_I
|| bs
->FrameType
& MFX_FRAMETYPE_xI
)
1275 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
1276 else if (bs
->FrameType
& MFX_FRAMETYPE_P
|| bs
->FrameType
& MFX_FRAMETYPE_xP
)
1277 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
1278 else if (bs
->FrameType
& MFX_FRAMETYPE_B
|| bs
->FrameType
& MFX_FRAMETYPE_xB
)
1279 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
1280 FF_ENABLE_DEPRECATION_WARNINGS
1287 if (pkt
->size
< new_pkt
.size
) {
1288 av_log(avctx
, AV_LOG_ERROR
, "Submitted buffer not large enough: %d < %d\n",
1289 pkt
->size
, new_pkt
.size
);
1290 av_packet_unref(&new_pkt
);
1291 return AVERROR(EINVAL
);
1294 memcpy(pkt
->data
, new_pkt
.data
, new_pkt
.size
);
1295 pkt
->size
= new_pkt
.size
;
1297 ret
= av_packet_copy_props(pkt
, &new_pkt
);
1298 av_packet_unref(&new_pkt
);
1310 int ff_qsv_enc_close(AVCodecContext
*avctx
, QSVEncContext
*q
)
1315 MFXVideoENCODE_Close(q
->session
);
1316 if (q
->internal_session
)
1317 MFXClose(q
->internal_session
);
1319 q
->internal_session
= NULL
;
1321 av_buffer_unref(&q
->frames_ctx
.hw_frames_ctx
);
1322 av_buffer_unref(&q
->frames_ctx
.mids_buf
);
1324 cur
= q
->work_frames
;
1326 q
->work_frames
= cur
->next
;
1327 av_frame_free(&cur
->frame
);
1329 cur
= q
->work_frames
;
1332 while (q
->async_fifo
&& av_fifo_size(q
->async_fifo
)) {
1337 av_fifo_generic_read(q
->async_fifo
, &pkt
, sizeof(pkt
), NULL
);
1338 av_fifo_generic_read(q
->async_fifo
, &sync
, sizeof(sync
), NULL
);
1339 av_fifo_generic_read(q
->async_fifo
, &bs
, sizeof(bs
), NULL
);
1343 av_packet_unref(&pkt
);
1345 av_fifo_free(q
->async_fifo
);
1346 q
->async_fifo
= NULL
;
1348 av_freep(&q
->opaque_surfaces
);
1349 av_buffer_unref(&q
->opaque_alloc_buf
);
1351 av_freep(&q
->extparam
);