]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
Merge commit 'f5ee23004d1177ca6dd99b92cb4ff4b94b2eae09'
[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     q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
53
54     if (avctx->level > 0)
55         q->param.mfx.CodecLevel = avctx->level;
56
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 & CODEC_FLAG_CLOSED_GOP ?
62                                       MFX_GOP_CLOSED : 0;
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;
68
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);
80
81     if (avctx->flags & 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
85           does depend by this.
86         */
87         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
88         q->height_align = 32;
89     } else {
90         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
91         q->height_align = 16;
92     }
93    q->param.mfx.FrameInfo.Height    = FFALIGN(avctx->height, q->height_align);
94
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;
98     } else {
99         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
100         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
101     }
102
103     if (avctx->flags & 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)";
112     } else {
113         q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
114         ratecontrol_desc = "variable bitrate (VBR)";
115     }
116
117     av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
118
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->bit_rate / 1000;
125         break;
126     case MFX_RATECONTROL_CQP:
127         quant = avctx->global_quality / FF_QP2LAMBDA;
128
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);
132
133         break;
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;
138         break;
139     }
140
141     // the HEVC encoder plugin currently fails if coding options
142     // are provided
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;
148
149         q->extparam[0] = (mfxExtBuffer *)&q->extco;
150
151         q->param.ExtParam    = q->extparam;
152         q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
153     }
154
155     return 0;
156 }
157
158 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
159 {
160     uint8_t sps_buf[128];
161     uint8_t pps_buf[128];
162
163     mfxExtCodingOptionSPSPPS extradata = {
164         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
165         .Header.BufferSz = sizeof(extradata),
166         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
167         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
168     };
169
170     mfxExtBuffer *ext_buffers[] = {
171         (mfxExtBuffer*)&extradata,
172     };
173
174     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
175     int ret;
176
177     q->param.ExtParam    = ext_buffers;
178     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
179
180     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
181     if (ret < 0)
182         return ff_qsv_error(ret);
183
184     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
185
186     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
187         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
188         return AVERROR_UNKNOWN;
189     }
190
191     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
192                                  FF_INPUT_BUFFER_PADDING_SIZE);
193     if (!avctx->extradata)
194         return AVERROR(ENOMEM);
195
196     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
197     if (need_pps)
198         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
199     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
200     memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
201
202     return 0;
203 }
204
205 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
206 {
207     int ret;
208
209     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
210     q->param.AsyncDepth = q->async_depth;
211
212     if (avctx->hwaccel_context) {
213         AVQSVContext *qsv = avctx->hwaccel_context;
214
215         q->session         = qsv->session;
216         q->param.IOPattern = qsv->iopattern;
217     }
218
219     if (!q->session) {
220         ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
221                                            q->load_plugins);
222         if (ret < 0)
223             return ret;
224
225         q->session = q->internal_qs.session;
226     }
227
228     ret = init_video_param(avctx, q);
229     if (ret < 0)
230         return ret;
231
232     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
233     if (ret < 0) {
234         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
235         return ff_qsv_error(ret);
236     }
237
238     ret = MFXVideoENCODE_Init(q->session, &q->param);
239     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
240         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
241     } else if (ret < 0) {
242         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
243         return ff_qsv_error(ret);
244     }
245
246     ret = qsv_retrieve_enc_params(avctx, q);
247     if (ret < 0) {
248         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
249         return ret;
250     }
251
252     avctx->coded_frame = av_frame_alloc();
253     if (!avctx->coded_frame)
254         return AVERROR(ENOMEM);
255
256     q->avctx = avctx;
257
258     return 0;
259 }
260
261 static void clear_unused_frames(QSVEncContext *q)
262 {
263     QSVFrame *cur = q->work_frames;
264     while (cur) {
265         if (cur->surface && !cur->surface->Data.Locked) {
266             cur->surface = NULL;
267             av_frame_unref(cur->frame);
268         }
269         cur = cur->next;
270     }
271 }
272
273 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
274 {
275     QSVFrame *frame, **last;
276
277     clear_unused_frames(q);
278
279     frame = q->work_frames;
280     last  = &q->work_frames;
281     while (frame) {
282         if (!frame->surface) {
283             *f = frame;
284             return 0;
285         }
286
287         last  = &frame->next;
288         frame = frame->next;
289     }
290
291     frame = av_mallocz(sizeof(*frame));
292     if (!frame)
293         return AVERROR(ENOMEM);
294     frame->frame = av_frame_alloc();
295     if (!frame->frame) {
296         av_freep(&frame);
297         return AVERROR(ENOMEM);
298     }
299     *last = frame;
300
301     *f = frame;
302
303     return 0;
304 }
305
306 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
307                         mfxFrameSurface1 **surface)
308 {
309     QSVFrame *qf;
310     int ret;
311
312     ret = get_free_frame(q, &qf);
313     if (ret < 0)
314         return ret;
315
316     if (frame->format == AV_PIX_FMT_QSV) {
317         ret = av_frame_ref(qf->frame, frame);
318         if (ret < 0)
319             return ret;
320
321         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
322         *surface = qf->surface;
323         return 0;
324     }
325
326     /* make a copy if the input is not padded as libmfx requires */
327     if (     frame->height & (q->height_align - 1) ||
328         frame->linesize[0] & (q->width_align - 1)) {
329         qf->frame->height = FFALIGN(frame->height, q->height_align);
330         qf->frame->width  = FFALIGN(frame->width, q->width_align);
331
332         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
333         if (ret < 0)
334             return ret;
335
336         qf->frame->height = frame->height;
337         qf->frame->width  = frame->width;
338         ret = av_frame_copy(qf->frame, frame);
339         if (ret < 0) {
340             av_frame_unref(qf->frame);
341             return ret;
342         }
343     } else {
344         ret = av_frame_ref(qf->frame, frame);
345         if (ret < 0)
346             return ret;
347     }
348
349     qf->surface_internal.Info = q->param.mfx.FrameInfo;
350
351     qf->surface_internal.Info.PicStruct =
352         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
353         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
354                                    MFX_PICSTRUCT_FIELD_BFF;
355     if (frame->repeat_pict == 1)
356         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
357     else if (frame->repeat_pict == 2)
358         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
359     else if (frame->repeat_pict == 4)
360         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
361
362     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
363     qf->surface_internal.Data.Y         = qf->frame->data[0];
364     qf->surface_internal.Data.UV        = qf->frame->data[1];
365     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
366
367     qf->surface = &qf->surface_internal;
368
369     *surface = qf->surface;
370
371     return 0;
372 }
373
374 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
375 {
376     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
377         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
378             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
379             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
380             av_log(avctx, AV_LOG_WARNING,
381                    "Interlaced coding is supported"
382                    " at Main/High Profile Level 2.1-4.1\n");
383     }
384 }
385
386 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
387                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
388 {
389     mfxBitstream bs = { { { 0 } } };
390
391     mfxFrameSurface1 *surf = NULL;
392     mfxSyncPoint sync      = NULL;
393     int ret;
394
395     if (frame) {
396         ret = submit_frame(q, frame, &surf);
397         if (ret < 0) {
398             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
399             return ret;
400         }
401     }
402
403     ret = ff_alloc_packet(pkt, q->packet_size);
404     if (ret < 0) {
405         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
406         return ret;
407     }
408     bs.Data      = pkt->data;
409     bs.MaxLength = pkt->size;
410
411     do {
412         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync);
413         if (ret == MFX_WRN_DEVICE_BUSY) {
414             av_usleep(1);
415             continue;
416         }
417         break;
418     } while ( 1 );
419
420     if (ret < 0) {
421         if (ret == MFX_ERR_MORE_DATA)
422             return 0;
423         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
424         return ff_qsv_error(ret);
425     }
426
427     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
428         if (frame->interlaced_frame)
429             print_interlace_msg(avctx, q);
430         else
431             av_log(avctx, AV_LOG_WARNING,
432                    "EncodeFrameAsync returned 'incompatible param' code\n");
433     }
434     if (sync) {
435         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
436
437         if (bs.FrameType & MFX_FRAMETYPE_I || bs.FrameType & MFX_FRAMETYPE_xI)
438             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
439         else if (bs.FrameType & MFX_FRAMETYPE_P || bs.FrameType & MFX_FRAMETYPE_xP)
440             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
441         else if (bs.FrameType & MFX_FRAMETYPE_B || bs.FrameType & MFX_FRAMETYPE_xB)
442             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
443
444         pkt->dts  = av_rescale_q(bs.DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
445         pkt->pts  = av_rescale_q(bs.TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
446         pkt->size = bs.DataLength;
447
448         if (bs.FrameType & MFX_FRAMETYPE_IDR ||
449             bs.FrameType & MFX_FRAMETYPE_xIDR)
450             pkt->flags |= AV_PKT_FLAG_KEY;
451
452         *got_packet = 1;
453     }
454
455     return 0;
456 }
457
458 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
459 {
460     QSVFrame *cur;
461
462     MFXVideoENCODE_Close(q->session);
463     q->session = NULL;
464
465     ff_qsv_close_internal_session(&q->internal_qs);
466
467     cur = q->work_frames;
468     while (cur) {
469         q->work_frames = cur->next;
470         av_frame_free(&cur->frame);
471         av_freep(&cur);
472         cur = q->work_frames;
473     }
474
475     av_frame_free(&avctx->coded_frame);
476
477     return 0;
478 }