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 FFmpeg.
9 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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"
40 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
42 const char *ratecontrol_desc;
47 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
50 q->param.mfx.CodecId = ret;
52 q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
55 q->param.mfx.CodecLevel = avctx->level;
57 q->param.mfx.CodecProfile = q->profile;
58 q->param.mfx.TargetUsage = q->preset;
59 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
60 q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1;
61 q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
63 q->param.mfx.IdrInterval = q->idr_interval;
64 q->param.mfx.NumSlice = avctx->slices;
65 q->param.mfx.NumRefFrame = FFMAX(0, avctx->refs);
66 q->param.mfx.EncodedOrder = 0;
67 q->param.mfx.BufferSizeInKB = 0;
69 q->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
70 q->param.mfx.FrameInfo.CropX = 0;
71 q->param.mfx.FrameInfo.CropY = 0;
72 q->param.mfx.FrameInfo.CropW = avctx->width;
73 q->param.mfx.FrameInfo.CropH = avctx->height;
74 q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num;
75 q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den;
76 q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
77 q->param.mfx.FrameInfo.BitDepthLuma = 8;
78 q->param.mfx.FrameInfo.BitDepthChroma = 8;
79 q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
81 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
82 /* A true field layout (TFF or BFF) is not important here,
83 it will specified later during frame encoding. But it is important
84 to specify is frame progressive or not because allowed heigh alignment
87 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
90 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
93 q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
95 if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
96 q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
97 q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
99 q->param.mfx.FrameInfo.FrameRateExtN = avctx->time_base.den;
100 q->param.mfx.FrameInfo.FrameRateExtD = avctx->time_base.num;
103 if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
104 q->param.mfx.RateControlMethod = MFX_RATECONTROL_CQP;
105 ratecontrol_desc = "constant quantization parameter (CQP)";
106 } else if (avctx->rc_max_rate == avctx->bit_rate) {
107 q->param.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
108 ratecontrol_desc = "constant bitrate (CBR)";
109 } else if (!avctx->rc_max_rate) {
110 #if QSV_VERSION_ATLEAST(1,7)
112 q->param.mfx.RateControlMethod = MFX_RATECONTROL_LA;
113 ratecontrol_desc = "lookahead (LA)";
117 q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR;
118 ratecontrol_desc = "average variable bitrate (AVBR)";
121 q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
122 ratecontrol_desc = "variable bitrate (VBR)";
125 av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
127 switch (q->param.mfx.RateControlMethod) {
128 case MFX_RATECONTROL_CBR:
129 case MFX_RATECONTROL_VBR:
130 q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
131 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
132 q->param.mfx.MaxKbps = avctx->rc_max_rate / 1000;
134 case MFX_RATECONTROL_CQP:
135 quant = avctx->global_quality / FF_QP2LAMBDA;
137 q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
138 q->param.mfx.QPP = av_clip(quant, 0, 51);
139 q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
142 case MFX_RATECONTROL_AVBR:
143 #if QSV_VERSION_ATLEAST(1,7)
144 case MFX_RATECONTROL_LA:
146 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
147 q->param.mfx.Convergence = q->avbr_convergence;
148 q->param.mfx.Accuracy = q->avbr_accuracy;
152 // the HEVC encoder plugin currently fails if coding options
154 if (avctx->codec_id != AV_CODEC_ID_HEVC) {
155 q->extco.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
156 q->extco.Header.BufferSz = sizeof(q->extco);
157 q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ?
158 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
160 q->extco.PicTimingSEI = q->pic_timing_sei ?
161 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
163 q->extparam[0] = (mfxExtBuffer *)&q->extco;
165 #if QSV_VERSION_ATLEAST(1,6)
166 q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
167 q->extco2.Header.BufferSz = sizeof(q->extco2);
169 #if QSV_VERSION_ATLEAST(1,7)
170 // valid value range is from 10 to 100 inclusive
171 // to instruct the encoder to use the default value this should be set to zero
172 q->extco2.LookAheadDepth = q->look_ahead_depth != 0 ? FFMAX(10, q->look_ahead_depth) : 0;
174 #if QSV_VERSION_ATLEAST(1,8)
175 q->extco2.LookAheadDS = q->look_ahead_downsampling;
178 q->extparam[1] = (mfxExtBuffer *)&q->extco2;
181 q->param.ExtParam = q->extparam;
182 q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
188 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
190 uint8_t sps_buf[128];
191 uint8_t pps_buf[128];
193 mfxExtCodingOptionSPSPPS extradata = {
194 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
195 .Header.BufferSz = sizeof(extradata),
196 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
197 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
200 mfxExtBuffer *ext_buffers[] = {
201 (mfxExtBuffer*)&extradata,
204 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
207 q->param.ExtParam = ext_buffers;
208 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
210 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
212 return ff_qsv_error(ret);
214 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
216 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
217 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
218 return AVERROR_UNKNOWN;
221 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
222 AV_INPUT_BUFFER_PADDING_SIZE);
223 if (!avctx->extradata)
224 return AVERROR(ENOMEM);
226 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
228 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
229 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
230 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
235 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
239 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
240 q->param.AsyncDepth = q->async_depth;
242 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
243 (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
245 return AVERROR(ENOMEM);
247 if (avctx->hwaccel_context) {
248 AVQSVContext *qsv = avctx->hwaccel_context;
250 q->session = qsv->session;
251 q->param.IOPattern = qsv->iopattern;
255 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
260 q->session = q->internal_qs.session;
263 ret = init_video_param(avctx, q);
267 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
269 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
270 return ff_qsv_error(ret);
273 ret = MFXVideoENCODE_Init(q->session, &q->param);
274 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
275 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
276 } else if (ret < 0) {
277 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
278 return ff_qsv_error(ret);
281 ret = qsv_retrieve_enc_params(avctx, q);
283 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
292 static void clear_unused_frames(QSVEncContext *q)
294 QSVFrame *cur = q->work_frames;
296 if (cur->surface && !cur->surface->Data.Locked) {
298 av_frame_unref(cur->frame);
304 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
306 QSVFrame *frame, **last;
308 clear_unused_frames(q);
310 frame = q->work_frames;
311 last = &q->work_frames;
313 if (!frame->surface) {
322 frame = av_mallocz(sizeof(*frame));
324 return AVERROR(ENOMEM);
325 frame->frame = av_frame_alloc();
328 return AVERROR(ENOMEM);
337 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
338 mfxFrameSurface1 **surface)
343 ret = get_free_frame(q, &qf);
347 if (frame->format == AV_PIX_FMT_QSV) {
348 ret = av_frame_ref(qf->frame, frame);
352 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
353 *surface = qf->surface;
357 /* make a copy if the input is not padded as libmfx requires */
358 if ( frame->height & (q->height_align - 1) ||
359 frame->linesize[0] & (q->width_align - 1)) {
360 qf->frame->height = FFALIGN(frame->height, q->height_align);
361 qf->frame->width = FFALIGN(frame->width, q->width_align);
363 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
367 qf->frame->height = frame->height;
368 qf->frame->width = frame->width;
369 ret = av_frame_copy(qf->frame, frame);
371 av_frame_unref(qf->frame);
375 ret = av_frame_ref(qf->frame, frame);
380 qf->surface_internal.Info = q->param.mfx.FrameInfo;
382 qf->surface_internal.Info.PicStruct =
383 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
384 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
385 MFX_PICSTRUCT_FIELD_BFF;
386 if (frame->repeat_pict == 1)
387 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
388 else if (frame->repeat_pict == 2)
389 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
390 else if (frame->repeat_pict == 4)
391 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
393 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
394 qf->surface_internal.Data.Y = qf->frame->data[0];
395 qf->surface_internal.Data.UV = qf->frame->data[1];
396 qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
398 qf->surface = &qf->surface_internal;
400 *surface = qf->surface;
405 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
407 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
408 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
409 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
410 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
411 av_log(avctx, AV_LOG_WARNING,
412 "Interlaced coding is supported"
413 " at Main/High Profile Level 2.1-4.1\n");
417 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
418 AVPacket *pkt, const AVFrame *frame, int *got_packet)
420 AVPacket new_pkt = { 0 };
423 mfxFrameSurface1 *surf = NULL;
424 mfxSyncPoint sync = NULL;
428 ret = submit_frame(q, frame, &surf);
430 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
435 ret = av_new_packet(&new_pkt, q->packet_size);
437 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
441 bs = av_mallocz(sizeof(*bs));
443 av_packet_unref(&new_pkt);
444 return AVERROR(ENOMEM);
446 bs->Data = new_pkt.data;
447 bs->MaxLength = new_pkt.size;
450 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
451 if (ret == MFX_WRN_DEVICE_BUSY) {
459 av_packet_unref(&new_pkt);
461 if (ret == MFX_ERR_MORE_DATA)
463 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
464 return ff_qsv_error(ret);
467 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
468 if (frame->interlaced_frame)
469 print_interlace_msg(avctx, q);
471 av_log(avctx, AV_LOG_WARNING,
472 "EncodeFrameAsync returned 'incompatible param' code\n");
475 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
476 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
477 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
479 av_packet_unref(&new_pkt);
483 if (!av_fifo_space(q->async_fifo) ||
484 (!frame && av_fifo_size(q->async_fifo))) {
485 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
486 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
487 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
489 MFXVideoCORE_SyncOperation(q->session, sync, 60000);
491 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
492 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
493 new_pkt.size = bs->DataLength;
495 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
496 bs->FrameType & MFX_FRAMETYPE_xIDR)
497 new_pkt.flags |= AV_PKT_FLAG_KEY;
499 #if FF_API_CODED_FRAME
500 FF_DISABLE_DEPRECATION_WARNINGS
501 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
502 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
503 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
504 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
505 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
506 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
507 FF_ENABLE_DEPRECATION_WARNINGS
513 if (pkt->size < new_pkt.size) {
514 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
515 pkt->size, new_pkt.size);
516 av_packet_unref(&new_pkt);
517 return AVERROR(EINVAL);
520 memcpy(pkt->data, new_pkt.data, new_pkt.size);
521 pkt->size = new_pkt.size;
523 ret = av_packet_copy_props(pkt, &new_pkt);
524 av_packet_unref(&new_pkt);
536 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
540 MFXVideoENCODE_Close(q->session);
543 ff_qsv_close_internal_session(&q->internal_qs);
545 cur = q->work_frames;
547 q->work_frames = cur->next;
548 av_frame_free(&cur->frame);
550 cur = q->work_frames;
553 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
558 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
559 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
560 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
563 av_packet_unref(&pkt);
565 av_fifo_free(q->async_fifo);
566 q->async_fifo = NULL;