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 q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR;
111 ratecontrol_desc = "average variable bitrate (AVBR)";
113 q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
114 ratecontrol_desc = "variable bitrate (VBR)";
117 av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
119 switch (q->param.mfx.RateControlMethod) {
120 case MFX_RATECONTROL_CBR:
121 case MFX_RATECONTROL_VBR:
122 q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
123 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
124 q->param.mfx.MaxKbps = avctx->rc_max_rate / 1000;
126 case MFX_RATECONTROL_CQP:
127 quant = avctx->global_quality / FF_QP2LAMBDA;
129 q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
130 q->param.mfx.QPP = av_clip(quant, 0, 51);
131 q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
134 case MFX_RATECONTROL_AVBR:
135 q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
136 q->param.mfx.Convergence = q->avbr_convergence;
137 q->param.mfx.Accuracy = q->avbr_accuracy;
141 // the HEVC encoder plugin currently fails if coding options
143 if (avctx->codec_id != AV_CODEC_ID_HEVC) {
144 q->extco.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
145 q->extco.Header.BufferSz = sizeof(q->extco);
146 q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ?
147 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
149 q->extco.PicTimingSEI = q->pic_timing_sei ?
150 MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
152 q->extparam[0] = (mfxExtBuffer *)&q->extco;
154 q->param.ExtParam = q->extparam;
155 q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
161 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
163 uint8_t sps_buf[128];
164 uint8_t pps_buf[128];
166 mfxExtCodingOptionSPSPPS extradata = {
167 .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
168 .Header.BufferSz = sizeof(extradata),
169 .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
170 .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
173 mfxExtBuffer *ext_buffers[] = {
174 (mfxExtBuffer*)&extradata,
177 int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
180 q->param.ExtParam = ext_buffers;
181 q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
183 ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
185 return ff_qsv_error(ret);
187 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
189 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
190 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
191 return AVERROR_UNKNOWN;
194 avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
195 AV_INPUT_BUFFER_PADDING_SIZE);
196 if (!avctx->extradata)
197 return AVERROR(ENOMEM);
199 memcpy(avctx->extradata, sps_buf, extradata.SPSBufSize);
201 memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
202 avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
203 memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
208 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
212 q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
213 q->param.AsyncDepth = q->async_depth;
215 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
216 (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
218 return AVERROR(ENOMEM);
220 if (avctx->hwaccel_context) {
221 AVQSVContext *qsv = avctx->hwaccel_context;
223 q->session = qsv->session;
224 q->param.IOPattern = qsv->iopattern;
228 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
233 q->session = q->internal_qs.session;
236 ret = init_video_param(avctx, q);
240 ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
242 av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
243 return ff_qsv_error(ret);
246 ret = MFXVideoENCODE_Init(q->session, &q->param);
247 if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
248 av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
249 } else if (ret < 0) {
250 av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
251 return ff_qsv_error(ret);
254 ret = qsv_retrieve_enc_params(avctx, q);
256 av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
265 static void clear_unused_frames(QSVEncContext *q)
267 QSVFrame *cur = q->work_frames;
269 if (cur->surface && !cur->surface->Data.Locked) {
271 av_frame_unref(cur->frame);
277 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
279 QSVFrame *frame, **last;
281 clear_unused_frames(q);
283 frame = q->work_frames;
284 last = &q->work_frames;
286 if (!frame->surface) {
295 frame = av_mallocz(sizeof(*frame));
297 return AVERROR(ENOMEM);
298 frame->frame = av_frame_alloc();
301 return AVERROR(ENOMEM);
310 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
311 mfxFrameSurface1 **surface)
316 ret = get_free_frame(q, &qf);
320 if (frame->format == AV_PIX_FMT_QSV) {
321 ret = av_frame_ref(qf->frame, frame);
325 qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
326 *surface = qf->surface;
330 /* make a copy if the input is not padded as libmfx requires */
331 if ( frame->height & (q->height_align - 1) ||
332 frame->linesize[0] & (q->width_align - 1)) {
333 qf->frame->height = FFALIGN(frame->height, q->height_align);
334 qf->frame->width = FFALIGN(frame->width, q->width_align);
336 ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
340 qf->frame->height = frame->height;
341 qf->frame->width = frame->width;
342 ret = av_frame_copy(qf->frame, frame);
344 av_frame_unref(qf->frame);
348 ret = av_frame_ref(qf->frame, frame);
353 qf->surface_internal.Info = q->param.mfx.FrameInfo;
355 qf->surface_internal.Info.PicStruct =
356 !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
357 frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
358 MFX_PICSTRUCT_FIELD_BFF;
359 if (frame->repeat_pict == 1)
360 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
361 else if (frame->repeat_pict == 2)
362 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
363 else if (frame->repeat_pict == 4)
364 qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
366 qf->surface_internal.Data.PitchLow = qf->frame->linesize[0];
367 qf->surface_internal.Data.Y = qf->frame->data[0];
368 qf->surface_internal.Data.UV = qf->frame->data[1];
369 qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
371 qf->surface = &qf->surface_internal;
373 *surface = qf->surface;
378 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
380 if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
381 if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
382 q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
383 q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
384 av_log(avctx, AV_LOG_WARNING,
385 "Interlaced coding is supported"
386 " at Main/High Profile Level 2.1-4.1\n");
390 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
391 AVPacket *pkt, const AVFrame *frame, int *got_packet)
393 AVPacket new_pkt = { 0 };
396 mfxFrameSurface1 *surf = NULL;
397 mfxSyncPoint sync = NULL;
401 ret = submit_frame(q, frame, &surf);
403 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
408 ret = av_new_packet(&new_pkt, q->packet_size);
410 av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
414 bs = av_mallocz(sizeof(*bs));
416 av_packet_unref(&new_pkt);
417 return AVERROR(ENOMEM);
419 bs->Data = new_pkt.data;
420 bs->MaxLength = new_pkt.size;
423 ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
424 if (ret == MFX_WRN_DEVICE_BUSY) {
432 av_packet_unref(&new_pkt);
434 if (ret == MFX_ERR_MORE_DATA)
436 av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
437 return ff_qsv_error(ret);
440 if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
441 if (frame->interlaced_frame)
442 print_interlace_msg(avctx, q);
444 av_log(avctx, AV_LOG_WARNING,
445 "EncodeFrameAsync returned 'incompatible param' code\n");
448 av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
449 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
450 av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
452 av_packet_unref(&new_pkt);
456 if (!av_fifo_space(q->async_fifo) ||
457 (!frame && av_fifo_size(q->async_fifo))) {
458 av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
459 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
460 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
462 MFXVideoCORE_SyncOperation(q->session, sync, 60000);
464 new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
465 new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
466 new_pkt.size = bs->DataLength;
468 if (bs->FrameType & MFX_FRAMETYPE_IDR ||
469 bs->FrameType & MFX_FRAMETYPE_xIDR)
470 new_pkt.flags |= AV_PKT_FLAG_KEY;
472 #if FF_API_CODED_FRAME
473 FF_DISABLE_DEPRECATION_WARNINGS
474 if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
475 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
476 else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
477 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
478 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
479 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
480 FF_ENABLE_DEPRECATION_WARNINGS
486 if (pkt->size < new_pkt.size) {
487 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
488 pkt->size, new_pkt.size);
489 av_packet_unref(&new_pkt);
490 return AVERROR(EINVAL);
493 memcpy(pkt->data, new_pkt.data, new_pkt.size);
494 pkt->size = new_pkt.size;
496 ret = av_packet_copy_props(pkt, &new_pkt);
497 av_packet_unref(&new_pkt);
509 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
513 MFXVideoENCODE_Close(q->session);
516 ff_qsv_close_internal_session(&q->internal_qs);
518 cur = q->work_frames;
520 q->work_frames = cur->next;
521 av_frame_free(&cur->frame);
523 cur = q->work_frames;
526 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
531 av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
532 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
533 av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
536 av_packet_unref(&pkt);
538 av_fifo_free(q->async_fifo);
539 q->async_fifo = NULL;