libavcodec/qsvenc.c: A warning message when library will work at partial hardware...
[ffmpeg.git] / 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 (MFX_WRN_PARTIAL_ACCELERATION==ret) {
230         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
231     } else if (ret < 0) {
232         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
233         return ff_qsv_error(ret);
234     }
235
236     ret = qsv_retrieve_enc_params(avctx, q);
237     if (ret < 0) {
238         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
239         return ret;
240     }
241
242     avctx->coded_frame = av_frame_alloc();
243     if (!avctx->coded_frame)
244         return AVERROR(ENOMEM);
245
246     q->avctx = avctx;
247
248     return 0;
249 }
250
251 static void clear_unused_frames(QSVEncContext *q)
252 {
253     QSVFrame *cur = q->work_frames;
254     while (cur) {
255         if (cur->surface && !cur->surface->Data.Locked) {
256             cur->surface = NULL;
257             av_frame_unref(cur->frame);
258         }
259         cur = cur->next;
260     }
261 }
262
263 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
264 {
265     QSVFrame *frame, **last;
266
267     clear_unused_frames(q);
268
269     frame = q->work_frames;
270     last  = &q->work_frames;
271     while (frame) {
272         if (!frame->surface) {
273             *f = frame;
274             return 0;
275         }
276
277         last  = &frame->next;
278         frame = frame->next;
279     }
280
281     frame = av_mallocz(sizeof(*frame));
282     if (!frame)
283         return AVERROR(ENOMEM);
284     frame->frame = av_frame_alloc();
285     if (!frame->frame) {
286         av_freep(&frame);
287         return AVERROR(ENOMEM);
288     }
289     *last = frame;
290
291     *f = frame;
292
293     return 0;
294 }
295
296 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
297                         mfxFrameSurface1 **surface)
298 {
299     QSVFrame *qf;
300     int ret;
301
302     ret = get_free_frame(q, &qf);
303     if (ret < 0)
304         return ret;
305
306     if (frame->format == AV_PIX_FMT_QSV) {
307         ret = av_frame_ref(qf->frame, frame);
308         if (ret < 0)
309             return ret;
310
311         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
312         *surface = qf->surface;
313         return 0;
314     }
315
316     /* make a copy if the input is not padded as libmfx requires */
317     if (frame->height & 31 || frame->linesize[0] & 15) {
318         qf->frame->height = FFALIGN(frame->height, 32);
319         qf->frame->width  = FFALIGN(frame->width, 16);
320
321         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
322         if (ret < 0)
323             return ret;
324
325         qf->frame->height = frame->height;
326         qf->frame->width  = frame->width;
327         ret = av_frame_copy(qf->frame, frame);
328         if (ret < 0) {
329             av_frame_unref(qf->frame);
330             return ret;
331         }
332     } else {
333         ret = av_frame_ref(qf->frame, frame);
334         if (ret < 0)
335             return ret;
336     }
337
338     qf->surface_internal.Info = q->param.mfx.FrameInfo;
339
340     qf->surface_internal.Info.PicStruct =
341         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
342         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
343                                    MFX_PICSTRUCT_FIELD_BFF;
344     if (frame->repeat_pict == 1)
345         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
346     else if (frame->repeat_pict == 2)
347         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
348     else if (frame->repeat_pict == 4)
349         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
350
351     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
352     qf->surface_internal.Data.Y         = qf->frame->data[0];
353     qf->surface_internal.Data.UV        = qf->frame->data[1];
354     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
355
356     qf->surface = &qf->surface_internal;
357
358     *surface = qf->surface;
359
360     return 0;
361 }
362
363 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
364 {
365     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
366         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
367             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
368             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
369             av_log(avctx, AV_LOG_WARNING,
370                    "Interlaced coding is supported"
371                    " at Main/High Profile Level 2.1-4.1\n");
372     }
373 }
374
375 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
376                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
377 {
378     mfxBitstream bs = { { { 0 } } };
379
380     mfxFrameSurface1 *surf = NULL;
381     mfxSyncPoint sync      = NULL;
382     int ret;
383
384     if (frame) {
385         ret = submit_frame(q, frame, &surf);
386         if (ret < 0) {
387             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
388             return ret;
389         }
390     }
391
392     ret = ff_alloc_packet(pkt, q->packet_size);
393     if (ret < 0) {
394         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
395         return ret;
396     }
397     bs.Data      = pkt->data;
398     bs.MaxLength = pkt->size;
399
400     do {
401         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync);
402         if (ret == MFX_WRN_DEVICE_BUSY)
403             av_usleep(1);
404     } while (ret > 0);
405
406     if (ret < 0)
407         return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret);
408
409     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
410         print_interlace_msg(avctx, q);
411
412     if (sync) {
413         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
414
415         if (bs.FrameType & MFX_FRAMETYPE_I || bs.FrameType & MFX_FRAMETYPE_xI)
416             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
417         else if (bs.FrameType & MFX_FRAMETYPE_P || bs.FrameType & MFX_FRAMETYPE_xP)
418             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
419         else if (bs.FrameType & MFX_FRAMETYPE_B || bs.FrameType & MFX_FRAMETYPE_xB)
420             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
421
422         pkt->dts  = av_rescale_q(bs.DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
423         pkt->pts  = av_rescale_q(bs.TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
424         pkt->size = bs.DataLength;
425
426         if (bs.FrameType & MFX_FRAMETYPE_IDR ||
427             bs.FrameType & MFX_FRAMETYPE_xIDR)
428             pkt->flags |= AV_PKT_FLAG_KEY;
429
430         *got_packet = 1;
431     }
432
433     return 0;
434 }
435
436 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
437 {
438     QSVFrame *cur;
439
440     MFXVideoENCODE_Close(q->session);
441     if (q->internal_session)
442         MFXClose(q->internal_session);
443     q->session          = NULL;
444     q->internal_session = NULL;
445
446     cur = q->work_frames;
447     while (cur) {
448         q->work_frames = cur->next;
449         av_frame_free(&cur->frame);
450         av_freep(&cur);
451         cur = q->work_frames;
452     }
453
454     av_frame_free(&avctx->coded_frame);
455
456     return 0;
457 }