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