]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
Merge commit '342b0ba5f93b09b1d0c2597db44605300e6fcc53'
[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     q->avctx = avctx;
258
259     return 0;
260 }
261
262 static void clear_unused_frames(QSVEncContext *q)
263 {
264     QSVFrame *cur = q->work_frames;
265     while (cur) {
266         if (cur->surface && !cur->surface->Data.Locked) {
267             cur->surface = NULL;
268             av_frame_unref(cur->frame);
269         }
270         cur = cur->next;
271     }
272 }
273
274 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
275 {
276     QSVFrame *frame, **last;
277
278     clear_unused_frames(q);
279
280     frame = q->work_frames;
281     last  = &q->work_frames;
282     while (frame) {
283         if (!frame->surface) {
284             *f = frame;
285             return 0;
286         }
287
288         last  = &frame->next;
289         frame = frame->next;
290     }
291
292     frame = av_mallocz(sizeof(*frame));
293     if (!frame)
294         return AVERROR(ENOMEM);
295     frame->frame = av_frame_alloc();
296     if (!frame->frame) {
297         av_freep(&frame);
298         return AVERROR(ENOMEM);
299     }
300     *last = frame;
301
302     *f = frame;
303
304     return 0;
305 }
306
307 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
308                         mfxFrameSurface1 **surface)
309 {
310     QSVFrame *qf;
311     int ret;
312
313     ret = get_free_frame(q, &qf);
314     if (ret < 0)
315         return ret;
316
317     if (frame->format == AV_PIX_FMT_QSV) {
318         ret = av_frame_ref(qf->frame, frame);
319         if (ret < 0)
320             return ret;
321
322         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
323         *surface = qf->surface;
324         return 0;
325     }
326
327     /* make a copy if the input is not padded as libmfx requires */
328     if (     frame->height & (q->height_align - 1) ||
329         frame->linesize[0] & (q->width_align - 1)) {
330         qf->frame->height = FFALIGN(frame->height, q->height_align);
331         qf->frame->width  = FFALIGN(frame->width, q->width_align);
332
333         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
334         if (ret < 0)
335             return ret;
336
337         qf->frame->height = frame->height;
338         qf->frame->width  = frame->width;
339         ret = av_frame_copy(qf->frame, frame);
340         if (ret < 0) {
341             av_frame_unref(qf->frame);
342             return ret;
343         }
344     } else {
345         ret = av_frame_ref(qf->frame, frame);
346         if (ret < 0)
347             return ret;
348     }
349
350     qf->surface_internal.Info = q->param.mfx.FrameInfo;
351
352     qf->surface_internal.Info.PicStruct =
353         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
354         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
355                                    MFX_PICSTRUCT_FIELD_BFF;
356     if (frame->repeat_pict == 1)
357         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
358     else if (frame->repeat_pict == 2)
359         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
360     else if (frame->repeat_pict == 4)
361         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
362
363     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
364     qf->surface_internal.Data.Y         = qf->frame->data[0];
365     qf->surface_internal.Data.UV        = qf->frame->data[1];
366     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
367
368     qf->surface = &qf->surface_internal;
369
370     *surface = qf->surface;
371
372     return 0;
373 }
374
375 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
376 {
377     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
378         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
379             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
380             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
381             av_log(avctx, AV_LOG_WARNING,
382                    "Interlaced coding is supported"
383                    " at Main/High Profile Level 2.1-4.1\n");
384     }
385 }
386
387 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
388                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
389 {
390     AVPacket new_pkt = { 0 };
391     mfxBitstream *bs;
392
393     mfxFrameSurface1 *surf = NULL;
394     mfxSyncPoint sync      = NULL;
395     int ret;
396
397     if (frame) {
398         ret = submit_frame(q, frame, &surf);
399         if (ret < 0) {
400             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
401             return ret;
402         }
403     }
404
405     ret = av_new_packet(&new_pkt, q->packet_size);
406     if (ret < 0) {
407         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
408         return ret;
409     }
410
411     bs = av_mallocz(sizeof(*bs));
412     if (!bs) {
413         av_packet_unref(&new_pkt);
414         return AVERROR(ENOMEM);
415     }
416     bs->Data      = new_pkt.data;
417     bs->MaxLength = new_pkt.size;
418
419     do {
420         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
421         if (ret == MFX_WRN_DEVICE_BUSY) {
422             av_usleep(1);
423             continue;
424         }
425         break;
426     } while ( 1 );
427
428     if (ret < 0) {
429         av_packet_unref(&new_pkt);
430         av_freep(&bs);
431         if (ret == MFX_ERR_MORE_DATA)
432             return 0;
433         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
434         return ff_qsv_error(ret);
435     }
436
437     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
438         if (frame->interlaced_frame)
439             print_interlace_msg(avctx, q);
440         else
441             av_log(avctx, AV_LOG_WARNING,
442                    "EncodeFrameAsync returned 'incompatible param' code\n");
443     }
444     if (sync) {
445         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
446         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
447         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
448     } else {
449         av_packet_unref(&new_pkt);
450         av_freep(&bs);
451     }
452
453     if (!av_fifo_space(q->async_fifo) ||
454         (!frame && av_fifo_size(q->async_fifo))) {
455         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
456         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
457         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
458
459         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
460
461         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
462         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
463         new_pkt.size = bs->DataLength;
464
465         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
466             bs->FrameType & MFX_FRAMETYPE_xIDR)
467             new_pkt.flags |= AV_PKT_FLAG_KEY;
468
469 #if FF_API_CODED_FRAME
470 FF_DISABLE_DEPRECATION_WARNINGS
471         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
472             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
473         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
474             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
475         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
476             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
477 FF_ENABLE_DEPRECATION_WARNINGS
478 #endif
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     return 0;
539 }