]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
Merge commit '95e2317ed85502dd8d96bcd9b12084dbfb8f9e8e'
[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     q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
213                                   (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
214     if (!q->async_fifo)
215         return AVERROR(ENOMEM);
216
217     if (avctx->hwaccel_context) {
218         AVQSVContext *qsv = avctx->hwaccel_context;
219
220         q->session         = qsv->session;
221         q->param.IOPattern = qsv->iopattern;
222     }
223
224     if (!q->session) {
225         ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
226                                            q->load_plugins);
227         if (ret < 0)
228             return ret;
229
230         q->session = q->internal_qs.session;
231     }
232
233     ret = init_video_param(avctx, q);
234     if (ret < 0)
235         return ret;
236
237     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
238     if (ret < 0) {
239         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
240         return ff_qsv_error(ret);
241     }
242
243     ret = MFXVideoENCODE_Init(q->session, &q->param);
244     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
245         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
246     } else if (ret < 0) {
247         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
248         return ff_qsv_error(ret);
249     }
250
251     ret = qsv_retrieve_enc_params(avctx, q);
252     if (ret < 0) {
253         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
254         return ret;
255     }
256
257     avctx->coded_frame = av_frame_alloc();
258     if (!avctx->coded_frame)
259         return AVERROR(ENOMEM);
260
261     q->avctx = avctx;
262
263     return 0;
264 }
265
266 static void clear_unused_frames(QSVEncContext *q)
267 {
268     QSVFrame *cur = q->work_frames;
269     while (cur) {
270         if (cur->surface && !cur->surface->Data.Locked) {
271             cur->surface = NULL;
272             av_frame_unref(cur->frame);
273         }
274         cur = cur->next;
275     }
276 }
277
278 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
279 {
280     QSVFrame *frame, **last;
281
282     clear_unused_frames(q);
283
284     frame = q->work_frames;
285     last  = &q->work_frames;
286     while (frame) {
287         if (!frame->surface) {
288             *f = frame;
289             return 0;
290         }
291
292         last  = &frame->next;
293         frame = frame->next;
294     }
295
296     frame = av_mallocz(sizeof(*frame));
297     if (!frame)
298         return AVERROR(ENOMEM);
299     frame->frame = av_frame_alloc();
300     if (!frame->frame) {
301         av_freep(&frame);
302         return AVERROR(ENOMEM);
303     }
304     *last = frame;
305
306     *f = frame;
307
308     return 0;
309 }
310
311 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
312                         mfxFrameSurface1 **surface)
313 {
314     QSVFrame *qf;
315     int ret;
316
317     ret = get_free_frame(q, &qf);
318     if (ret < 0)
319         return ret;
320
321     if (frame->format == AV_PIX_FMT_QSV) {
322         ret = av_frame_ref(qf->frame, frame);
323         if (ret < 0)
324             return ret;
325
326         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
327         *surface = qf->surface;
328         return 0;
329     }
330
331     /* make a copy if the input is not padded as libmfx requires */
332     if (     frame->height & (q->height_align - 1) ||
333         frame->linesize[0] & (q->width_align - 1)) {
334         qf->frame->height = FFALIGN(frame->height, q->height_align);
335         qf->frame->width  = FFALIGN(frame->width, q->width_align);
336
337         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
338         if (ret < 0)
339             return ret;
340
341         qf->frame->height = frame->height;
342         qf->frame->width  = frame->width;
343         ret = av_frame_copy(qf->frame, frame);
344         if (ret < 0) {
345             av_frame_unref(qf->frame);
346             return ret;
347         }
348     } else {
349         ret = av_frame_ref(qf->frame, frame);
350         if (ret < 0)
351             return ret;
352     }
353
354     qf->surface_internal.Info = q->param.mfx.FrameInfo;
355
356     qf->surface_internal.Info.PicStruct =
357         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
358         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
359                                    MFX_PICSTRUCT_FIELD_BFF;
360     if (frame->repeat_pict == 1)
361         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
362     else if (frame->repeat_pict == 2)
363         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
364     else if (frame->repeat_pict == 4)
365         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
366
367     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
368     qf->surface_internal.Data.Y         = qf->frame->data[0];
369     qf->surface_internal.Data.UV        = qf->frame->data[1];
370     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
371
372     qf->surface = &qf->surface_internal;
373
374     *surface = qf->surface;
375
376     return 0;
377 }
378
379 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
380 {
381     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
382         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
383             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
384             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
385             av_log(avctx, AV_LOG_WARNING,
386                    "Interlaced coding is supported"
387                    " at Main/High Profile Level 2.1-4.1\n");
388     }
389 }
390
391 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
392                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
393 {
394     AVPacket new_pkt = { 0 };
395     mfxBitstream *bs;
396
397     mfxFrameSurface1 *surf = NULL;
398     mfxSyncPoint sync      = NULL;
399     int ret;
400
401     if (frame) {
402         ret = submit_frame(q, frame, &surf);
403         if (ret < 0) {
404             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
405             return ret;
406         }
407     }
408
409     ret = av_new_packet(&new_pkt, q->packet_size);
410     if (ret < 0) {
411         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
412         return ret;
413     }
414
415     bs = av_mallocz(sizeof(*bs));
416     if (!bs) {
417         av_packet_unref(&new_pkt);
418         return AVERROR(ENOMEM);
419     }
420     bs->Data      = new_pkt.data;
421     bs->MaxLength = new_pkt.size;
422
423     do {
424         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
425         if (ret == MFX_WRN_DEVICE_BUSY) {
426             av_usleep(1);
427             continue;
428         }
429         break;
430     } while ( 1 );
431
432     if (ret < 0) {
433         av_packet_unref(&new_pkt);
434         av_freep(&bs);
435         if (ret == MFX_ERR_MORE_DATA)
436             return 0;
437         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
438         return ff_qsv_error(ret);
439     }
440
441     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
442         if (frame->interlaced_frame)
443             print_interlace_msg(avctx, q);
444         else
445             av_log(avctx, AV_LOG_WARNING,
446                    "EncodeFrameAsync returned 'incompatible param' code\n");
447     }
448     if (sync) {
449         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
450         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
451         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
452     } else {
453         av_packet_unref(&new_pkt);
454         av_freep(&bs);
455     }
456
457     if (!av_fifo_space(q->async_fifo) ||
458         (!frame && av_fifo_size(q->async_fifo))) {
459         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
460         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
461         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
462
463         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
464
465         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
466         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
467         new_pkt.size = bs->DataLength;
468
469         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
470             bs->FrameType & MFX_FRAMETYPE_xIDR)
471             new_pkt.flags |= AV_PKT_FLAG_KEY;
472
473         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
474             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
475         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
476             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
477         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
478             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
479
480         av_freep(&bs);
481
482         if (pkt->data) {
483             if (pkt->size < new_pkt.size) {
484                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
485                        pkt->size, new_pkt.size);
486                 av_packet_unref(&new_pkt);
487                 return AVERROR(EINVAL);
488             }
489
490             memcpy(pkt->data, new_pkt.data, new_pkt.size);
491             pkt->size = new_pkt.size;
492
493             ret = av_packet_copy_props(pkt, &new_pkt);
494             av_packet_unref(&new_pkt);
495             if (ret < 0)
496                 return ret;
497         } else
498             *pkt = new_pkt;
499
500         *got_packet = 1;
501     }
502
503     return 0;
504 }
505
506 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
507 {
508     QSVFrame *cur;
509
510     MFXVideoENCODE_Close(q->session);
511     q->session = NULL;
512
513     ff_qsv_close_internal_session(&q->internal_qs);
514
515     cur = q->work_frames;
516     while (cur) {
517         q->work_frames = cur->next;
518         av_frame_free(&cur->frame);
519         av_freep(&cur);
520         cur = q->work_frames;
521     }
522
523     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
524         AVPacket pkt;
525         mfxSyncPoint sync;
526         mfxBitstream *bs;
527
528         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
529         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
530         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
531
532         av_freep(&bs);
533         av_packet_unref(&pkt);
534     }
535     av_fifo_free(q->async_fifo);
536     q->async_fifo = NULL;
537
538     av_frame_free(&avctx->coded_frame);
539
540     return 0;
541 }