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;
53 q->param.mfx.CodecLevel = avctx->level;
55 q->param.mfx.CodecProfile = q->profile;
56 q->param.mfx.TargetUsage = q->preset;
57 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
58 q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1;
59 q->param.mfx.GopOptFlag = avctx->flags & CODEC_FLAG_CLOSED_GOP ?
61 q->param.mfx.IdrInterval = q->idr_interval;
62 q->param.mfx.NumSlice = avctx->slices;
63 q->param.mfx.NumRefFrame = FFMAX(0, avctx->refs);
64 q->param.mfx.EncodedOrder = 0;
65 q->param.mfx.BufferSizeInKB = 0;
67 q->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
68 q->param.mfx.FrameInfo.CropX = 0;
69 q->param.mfx.FrameInfo.CropY = 0;
70 q->param.mfx.FrameInfo.CropW = avctx->width;
71 q->param.mfx.FrameInfo.CropH = avctx->height;
72 q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num;
73 q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den;
74 q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
75 q->param.mfx.FrameInfo.BitDepthLuma = 8;
76 q->param.mfx.FrameInfo.BitDepthChroma = 8;
77 q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, 16);
79 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
80 /* A true field layout (TFF or BFF) is not important here,
81 it will specified later during frame encoding. But it is important
82 to specify is frame progressive or not because allowed heigh alignment
85 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
86 q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32);
88 q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
89 q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 16);
92 if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
93 q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
94 q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
96 q->param.mfx.FrameInfo.FrameRateExtN = avctx->time_base.den;
97 q->param.mfx.FrameInfo.FrameRateExtD = avctx->time_base.num;
100 if (avctx->flags & CODEC_FLAG_QSCALE) {
101 q->param.mfx.RateControlMethod = MFX_RATECONTROL_CQP;
102 ratecontrol_desc = "constant quantization parameter (CQP)";
103 } else if (avctx->rc_max_rate == avctx->bit_rate) {
104 q->param.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
105 ratecontrol_desc = "constant bitrate (CBR)";
106 } else if (!avctx->rc_max_rate) {
107 q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR;
108 ratecontrol_desc = "average variable bitrate (AVBR)";
110 q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
111 ratecontrol_desc = "variable bitrate (VBR)";
114 av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
116 switch (q->param.mfx.RateControlMethod) {
117 case MFX_RATECONTROL_CBR:
118 case MFX_RATECONTROL_VBR:
119 q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
120 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
121 q->param.mfx.MaxKbps = avctx->bit_rate / 1000;
123 case MFX_RATECONTROL_CQP:
124 quant = avctx->global_quality / FF_QP2LAMBDA;
126 q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
127 q->param.mfx.QPP = av_clip(quant, 0, 51);
128 q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
131 case MFX_RATECONTROL_AVBR:
132 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
133 q->param.mfx.Convergence = q->avbr_convergence;
134 q->param.mfx.Accuracy = q->avbr_accuracy;
138 q->extco.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
139 q->extco.Header.BufferSz = sizeof(q->extco);
140 q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ?
141 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
143 q->extparam[0] = (mfxExtBuffer *)&q->extco;
145 q->param.ExtParam = q->extparam;
146 q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
151 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
153 uint8_t sps_buf[128];
154 uint8_t pps_buf[128];
156 mfxExtCodingOptionSPSPPS extradata = {
157 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
158 .Header.BufferSz = sizeof(extradata),
159 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
160 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
163 mfxExtBuffer *ext_buffers[] = {
164 (mfxExtBuffer*)&extradata,
169 q->param.ExtParam = ext_buffers;
170 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
172 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
174 return ff_qsv_error(ret);
176 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
178 if (!extradata.SPSBufSize || !extradata.PPSBufSize) {
179 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
180 return AVERROR_UNKNOWN;
183 avctx->extradata = av_malloc(extradata.SPSBufSize + extradata.PPSBufSize +
184 FF_INPUT_BUFFER_PADDING_SIZE);
185 if (!avctx->extradata)
186 return AVERROR(ENOMEM);
188 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
189 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
190 avctx->extradata_size = extradata.SPSBufSize + extradata.PPSBufSize;
191 memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
196 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
200 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
201 q->param.AsyncDepth = q->async_depth;
203 if (avctx->hwaccel_context) {
204 AVQSVContext *qsv = avctx->hwaccel_context;
206 q->session = qsv->session;
207 q->param.IOPattern = qsv->iopattern;
211 ret = ff_qsv_init_internal_session(avctx, &q->internal_session);
215 q->session = q->internal_session;
218 ret = init_video_param(avctx, q);
222 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
224 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
225 return ff_qsv_error(ret);
228 ret = MFXVideoENCODE_Init(q->session, &q->param);
230 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
231 return ff_qsv_error(ret);
234 ret = qsv_retrieve_enc_params(avctx, q);
236 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
240 avctx->coded_frame = av_frame_alloc();
241 if (!avctx->coded_frame)
242 return AVERROR(ENOMEM);
249 static void clear_unused_frames(QSVEncContext *q)
251 QSVFrame *cur = q->work_frames;
253 if (cur->surface && !cur->surface->Data.Locked) {
255 av_frame_unref(cur->frame);
261 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
263 QSVFrame *frame, **last;
265 clear_unused_frames(q);
267 frame = q->work_frames;
268 last = &q->work_frames;
270 if (!frame->surface) {
279 frame = av_mallocz(sizeof(*frame));
281 return AVERROR(ENOMEM);
282 frame->frame = av_frame_alloc();
285 return AVERROR(ENOMEM);
294 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
295 mfxFrameSurface1 **surface)
300 ret = get_free_frame(q, &qf);
304 if (frame->format == AV_PIX_FMT_QSV) {
305 ret = av_frame_ref(qf->frame, frame);
309 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
310 *surface = qf->surface;
314 /* make a copy if the input is not padded as libmfx requires */
315 if (frame->height & 31 || frame->linesize[0] & 15) {
316 qf->frame->height = FFALIGN(frame->height, 32);
317 qf->frame->width = FFALIGN(frame->width, 16);
319 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
323 qf->frame->height = frame->height;
324 qf->frame->width = frame->width;
325 ret = av_frame_copy(qf->frame, frame);
327 av_frame_unref(qf->frame);
331 ret = av_frame_ref(qf->frame, frame);
336 qf->surface_internal.Info = q->param.mfx.FrameInfo;
338 qf->surface_internal.Info.PicStruct =
339 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
340 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
341 MFX_PICSTRUCT_FIELD_BFF;
342 if (frame->repeat_pict == 1)
343 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
344 else if (frame->repeat_pict == 2)
345 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
346 else if (frame->repeat_pict == 4)
347 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
349 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
350 qf->surface_internal.Data.Y = qf->frame->data[0];
351 qf->surface_internal.Data.UV = qf->frame->data[1];
352 qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
354 qf->surface = &qf->surface_internal;
356 *surface = qf->surface;
361 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
363 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
364 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
365 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
366 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
367 av_log(avctx, AV_LOG_WARNING,
368 "Interlaced coding is supported"
369 " at Main/High Profile Level 2.1-4.1\n");
373 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
374 AVPacket *pkt, const AVFrame *frame, int *got_packet)
376 mfxBitstream bs = { { { 0 } } };
378 mfxFrameSurface1 *surf = NULL;
379 mfxSyncPoint sync = NULL;
383 ret = submit_frame(q, frame, &surf);
385 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
390 ret = ff_alloc_packet(pkt, q->packet_size);
392 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
396 bs.MaxLength = pkt->size;
399 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync);
400 if (ret == MFX_WRN_DEVICE_BUSY)
405 return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret);
407 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
408 print_interlace_msg(avctx, q);
411 MFXVideoCORE_SyncOperation(q->session, sync, 60000);
413 if (bs.FrameType & MFX_FRAMETYPE_I || bs.FrameType & MFX_FRAMETYPE_xI)
414 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
415 else if (bs.FrameType & MFX_FRAMETYPE_P || bs.FrameType & MFX_FRAMETYPE_xP)
416 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
417 else if (bs.FrameType & MFX_FRAMETYPE_B || bs.FrameType & MFX_FRAMETYPE_xB)
418 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
420 pkt->dts = av_rescale_q(bs.DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
421 pkt->pts = av_rescale_q(bs.TimeStamp, (AVRational){1, 90000}, avctx->time_base);
422 pkt->size = bs.DataLength;
424 if (bs.FrameType & MFX_FRAMETYPE_IDR ||
425 bs.FrameType & MFX_FRAMETYPE_xIDR)
426 pkt->flags |= AV_PKT_FLAG_KEY;
434 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
438 MFXVideoENCODE_Close(q->session);
439 if (q->internal_session)
440 MFXClose(q->internal_session);
442 q->internal_session = NULL;
444 cur = q->work_frames;
446 q->work_frames = cur->next;
447 av_frame_free(&cur->frame);
449 cur = q->work_frames;
452 av_frame_free(&avctx->coded_frame);