]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
libavcodec/qsvenc.c: More correct selection of alignment of a frame height depending...
[ffmpeg] / libavcodec / qsvenc.c
1 /*
2  * Intel MediaSDK QSV encoder utility functions
3  *
4  * copyright (c) 2013 Yukinori Yamazoe
5  * copyright (c) 2015 Anton Khirnov
6  *
7  * This file is part of FFmpeg.
8  *
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.
13  *
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.
18  *
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
22  */
23
24 #include <string.h>
25 #include <sys/types.h>
26 #include <mfx/mfxvideo.h>
27
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"
33
34 #include "avcodec.h"
35 #include "internal.h"
36 #include "qsv.h"
37 #include "qsv_internal.h"
38 #include "qsvenc.h"
39
40 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
41 {
42     const char *ratecontrol_desc;
43
44     float quant;
45     int ret;
46
47     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
48     if (ret < 0)
49         return AVERROR_BUG;
50     q->param.mfx.CodecId = ret;
51
52     if (avctx->level > 0)
53         q->param.mfx.CodecLevel = avctx->level;
54
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 ?
60                                       MFX_GOP_CLOSED : 0;
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;
66
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);
78
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
83           does depend by this.
84         */
85         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
86         q->param.mfx.FrameInfo.Height    = FFALIGN(avctx->height, 32);
87     } else {
88         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
89         q->param.mfx.FrameInfo.Height    = FFALIGN(avctx->height, 16);
90     }
91
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;
95     } else {
96         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
97         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
98     }
99
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)";
109     } else {
110         q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
111         ratecontrol_desc = "variable bitrate (VBR)";
112     }
113
114     av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
115
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;
122         break;
123     case MFX_RATECONTROL_CQP:
124         quant = avctx->global_quality / FF_QP2LAMBDA;
125
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);
129
130         break;
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;
135         break;
136     }
137
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;
142
143     q->extparam[0] = (mfxExtBuffer *)&q->extco;
144
145     q->param.ExtParam    = q->extparam;
146     q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
147
148     return 0;
149 }
150
151 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
152 {
153     uint8_t sps_buf[128];
154     uint8_t pps_buf[128];
155
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)
161     };
162
163     mfxExtBuffer *ext_buffers[] = {
164         (mfxExtBuffer*)&extradata,
165     };
166
167     int ret;
168
169     q->param.ExtParam    = ext_buffers;
170     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
171
172     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
173     if (ret < 0)
174         return ff_qsv_error(ret);
175
176     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
177
178     if (!extradata.SPSBufSize || !extradata.PPSBufSize) {
179         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
180         return AVERROR_UNKNOWN;
181     }
182
183     avctx->extradata = av_malloc(extradata.SPSBufSize + extradata.PPSBufSize +
184                                  FF_INPUT_BUFFER_PADDING_SIZE);
185     if (!avctx->extradata)
186         return AVERROR(ENOMEM);
187
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);
192
193     return 0;
194 }
195
196 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
197 {
198     int ret;
199
200     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
201     q->param.AsyncDepth = q->async_depth;
202
203     if (avctx->hwaccel_context) {
204         AVQSVContext *qsv = avctx->hwaccel_context;
205
206         q->session         = qsv->session;
207         q->param.IOPattern = qsv->iopattern;
208     }
209
210     if (!q->session) {
211         ret = ff_qsv_init_internal_session(avctx, &q->internal_session);
212         if (ret < 0)
213             return ret;
214
215         q->session = q->internal_session;
216     }
217
218     ret = init_video_param(avctx, q);
219     if (ret < 0)
220         return ret;
221
222     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
223     if (ret < 0) {
224         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
225         return ff_qsv_error(ret);
226     }
227
228     ret = MFXVideoENCODE_Init(q->session, &q->param);
229     if (ret < 0) {
230         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
231         return ff_qsv_error(ret);
232     }
233
234     ret = qsv_retrieve_enc_params(avctx, q);
235     if (ret < 0) {
236         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
237         return ret;
238     }
239
240     avctx->coded_frame = av_frame_alloc();
241     if (!avctx->coded_frame)
242         return AVERROR(ENOMEM);
243
244     q->avctx = avctx;
245
246     return 0;
247 }
248
249 static void clear_unused_frames(QSVEncContext *q)
250 {
251     QSVFrame *cur = q->work_frames;
252     while (cur) {
253         if (cur->surface && !cur->surface->Data.Locked) {
254             cur->surface = NULL;
255             av_frame_unref(cur->frame);
256         }
257         cur = cur->next;
258     }
259 }
260
261 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
262 {
263     QSVFrame *frame, **last;
264
265     clear_unused_frames(q);
266
267     frame = q->work_frames;
268     last  = &q->work_frames;
269     while (frame) {
270         if (!frame->surface) {
271             *f = frame;
272             return 0;
273         }
274
275         last  = &frame->next;
276         frame = frame->next;
277     }
278
279     frame = av_mallocz(sizeof(*frame));
280     if (!frame)
281         return AVERROR(ENOMEM);
282     frame->frame = av_frame_alloc();
283     if (!frame->frame) {
284         av_freep(&frame);
285         return AVERROR(ENOMEM);
286     }
287     *last = frame;
288
289     *f = frame;
290
291     return 0;
292 }
293
294 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
295                         mfxFrameSurface1 **surface)
296 {
297     QSVFrame *qf;
298     int ret;
299
300     ret = get_free_frame(q, &qf);
301     if (ret < 0)
302         return ret;
303
304     if (frame->format == AV_PIX_FMT_QSV) {
305         ret = av_frame_ref(qf->frame, frame);
306         if (ret < 0)
307             return ret;
308
309         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
310         *surface = qf->surface;
311         return 0;
312     }
313
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);
318
319         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
320         if (ret < 0)
321             return ret;
322
323         qf->frame->height = frame->height;
324         qf->frame->width  = frame->width;
325         ret = av_frame_copy(qf->frame, frame);
326         if (ret < 0) {
327             av_frame_unref(qf->frame);
328             return ret;
329         }
330     } else {
331         ret = av_frame_ref(qf->frame, frame);
332         if (ret < 0)
333             return ret;
334     }
335
336     qf->surface_internal.Info = q->param.mfx.FrameInfo;
337
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;
348
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});
353
354     qf->surface = &qf->surface_internal;
355
356     *surface = qf->surface;
357
358     return 0;
359 }
360
361 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
362 {
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");
370     }
371 }
372
373 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
374                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
375 {
376     mfxBitstream bs = { { { 0 } } };
377
378     mfxFrameSurface1 *surf = NULL;
379     mfxSyncPoint sync      = NULL;
380     int ret;
381
382     if (frame) {
383         ret = submit_frame(q, frame, &surf);
384         if (ret < 0) {
385             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
386             return ret;
387         }
388     }
389
390     ret = ff_alloc_packet(pkt, q->packet_size);
391     if (ret < 0) {
392         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
393         return ret;
394     }
395     bs.Data      = pkt->data;
396     bs.MaxLength = pkt->size;
397
398     do {
399         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync);
400         if (ret == MFX_WRN_DEVICE_BUSY)
401             av_usleep(1);
402     } while (ret > 0);
403
404     if (ret < 0)
405         return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret);
406
407     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
408         print_interlace_msg(avctx, q);
409
410     if (sync) {
411         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
412
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;
419
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;
423
424         if (bs.FrameType & MFX_FRAMETYPE_IDR ||
425             bs.FrameType & MFX_FRAMETYPE_xIDR)
426             pkt->flags |= AV_PKT_FLAG_KEY;
427
428         *got_packet = 1;
429     }
430
431     return 0;
432 }
433
434 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
435 {
436     QSVFrame *cur;
437
438     MFXVideoENCODE_Close(q->session);
439     if (q->internal_session)
440         MFXClose(q->internal_session);
441     q->session          = NULL;
442     q->internal_session = NULL;
443
444     cur = q->work_frames;
445     while (cur) {
446         q->work_frames = cur->next;
447         av_frame_free(&cur->frame);
448         av_freep(&cur);
449         cur = q->work_frames;
450     }
451
452     av_frame_free(&avctx->coded_frame);
453
454     return 0;
455 }