2 * Intel MediaSDK QSV codec-independent code
4 * copyright (c) 2013 Luca Barbato
5 * copyright (c) 2015 Anton Khirnov <anton@khirnov.net>
7 * This file is part of FFmpeg.
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.
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.
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
25 #include <sys/types.h>
27 #include <mfx/mfxvideo.h>
29 #include "libavutil/common.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/log.h"
32 #include "libavutil/pixfmt.h"
33 #include "libavutil/time.h"
38 #include "qsv_internal.h"
41 int ff_qsv_map_pixfmt(enum AVPixelFormat format)
44 case AV_PIX_FMT_YUV420P:
45 case AV_PIX_FMT_YUVJ420P:
46 return AV_PIX_FMT_NV12;
48 return AVERROR(ENOSYS);
52 static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
54 mfxVideoParam param = { { 0 } };
55 mfxBitstream bs = { { { 0 } } };
57 enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
61 ret = ff_get_format(avctx, pix_fmts);
67 q->iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
68 if (avctx->hwaccel_context) {
69 AVQSVContext *qsv = avctx->hwaccel_context;
71 q->session = qsv->session;
72 q->iopattern = qsv->iopattern;
73 q->ext_buffers = qsv->ext_buffers;
74 q->nb_ext_buffers = qsv->nb_ext_buffers;
77 if (!q->internal_qs.session) {
78 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
84 q->session = q->internal_qs.session;
88 bs.Data = avpkt->data;
89 bs.DataLength = avpkt->size;
90 bs.MaxLength = bs.DataLength;
91 bs.TimeStamp = avpkt->pts;
93 return AVERROR_INVALIDDATA;
95 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
97 av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
101 param.mfx.CodecId = ret;
103 ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, ¶m);
104 if (MFX_ERR_MORE_DATA==ret) {
105 /* this code means that header not found so we return packet size to skip
109 } else if (ret < 0) {
110 av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
111 return ff_qsv_error(ret);
113 param.IOPattern = q->iopattern;
114 param.AsyncDepth = q->async_depth;
115 param.ExtParam = q->ext_buffers;
116 param.NumExtParam = q->nb_ext_buffers;
117 param.mfx.FrameInfo.BitDepthLuma = 8;
118 param.mfx.FrameInfo.BitDepthChroma = 8;
120 ret = MFXVideoDECODE_Init(q->session, ¶m);
122 if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
123 av_log(avctx, AV_LOG_ERROR,
124 "Error initializing the MFX video decoder, unsupported video\n");
126 av_log(avctx, AV_LOG_ERROR,
127 "Error initializing the MFX video decoder %d\n", ret);
129 return ff_qsv_error(ret);
132 avctx->profile = param.mfx.CodecProfile;
133 avctx->level = param.mfx.CodecLevel;
134 avctx->coded_width = param.mfx.FrameInfo.Width;
135 avctx->coded_height = param.mfx.FrameInfo.Height;
136 avctx->width = param.mfx.FrameInfo.CropW - param.mfx.FrameInfo.CropX;
137 avctx->height = param.mfx.FrameInfo.CropH - param.mfx.FrameInfo.CropY;
139 /* maximum decoder latency should be not exceed max DPB size for h.264 and
140 HEVC which is 16 for both cases.
141 So weare pre-allocating fifo big enough for 17 elements:
143 if (!q->async_fifo) {
144 q->async_fifo = av_fifo_alloc((1 + 16) *
145 (sizeof(mfxSyncPoint*) + sizeof(QSVFrame*)));
147 return AVERROR(ENOMEM);
150 if (!q->input_fifo) {
151 q->input_fifo = av_fifo_alloc(1024*16);
153 return AVERROR(ENOMEM);
157 q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
159 return AVERROR(ENOMEM);
166 static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
170 ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
174 if (frame->frame->format == AV_PIX_FMT_QSV) {
175 frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
177 frame->surface_internal.Info.BitDepthLuma = 8;
178 frame->surface_internal.Info.BitDepthChroma = 8;
179 frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12;
180 frame->surface_internal.Info.Width = avctx->coded_width;
181 frame->surface_internal.Info.Height = avctx->coded_height;
182 frame->surface_internal.Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
184 frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
185 frame->surface_internal.Data.Y = frame->frame->data[0];
186 frame->surface_internal.Data.UV = frame->frame->data[1];
188 frame->surface = &frame->surface_internal;
194 static void qsv_clear_unused_frames(QSVContext *q)
196 QSVFrame *cur = q->work_frames;
198 if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
200 av_frame_unref(cur->frame);
206 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
208 QSVFrame *frame, **last;
211 qsv_clear_unused_frames(q);
213 frame = q->work_frames;
214 last = &q->work_frames;
216 if (!frame->surface) {
217 ret = alloc_frame(avctx, frame);
220 *surf = frame->surface;
228 frame = av_mallocz(sizeof(*frame));
230 return AVERROR(ENOMEM);
231 frame->frame = av_frame_alloc();
234 return AVERROR(ENOMEM);
238 ret = alloc_frame(avctx, frame);
242 *surf = frame->surface;
247 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
249 QSVFrame *cur = q->work_frames;
251 if (surf == cur->surface)
258 /* This function uses for 'smart' releasing of consumed data
259 from the input bitstream fifo.
260 Since the input fifo mapped to mfxBitstream which does not understand
261 a wrapping of data over fifo end, we should also to relocate a possible
262 data rest to fifo begin. If rest of data is absent then we just reset fifo's
263 pointers to initial positions.
264 NOTE the case when fifo does contain unconsumed data is rare and typical
265 amount of such data is 1..4 bytes.
267 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
272 av_fifo_drain(f, bytes_to_free);
274 data_size = av_fifo_size(f);
276 if (f->buffer!=f->rptr) {
277 if ( (f->end - f->rptr) < data_size) {
278 data_rest = data_size - (f->end - f->rptr);
279 data_size-=data_rest;
280 memmove(f->buffer+data_size, f->buffer, data_rest);
282 memmove(f->buffer, f->rptr, data_size);
283 data_size+= data_rest;
287 f->wptr = f->buffer + data_size;
293 static void close_decoder(QSVContext *q)
298 MFXVideoDECODE_Close(q->session);
300 while (q->async_fifo && av_fifo_size(q->async_fifo)) {
304 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
305 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
310 cur = q->work_frames;
312 q->work_frames = cur->next;
313 av_frame_free(&cur->frame);
315 cur = q->work_frames;
319 q->reinit_pending = 0;
322 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
323 AVFrame *frame, int *got_frame,
327 mfxFrameSurface1 *insurf;
328 mfxFrameSurface1 *outsurf;
330 mfxBitstream bs = { { { 0 } } };
334 int flush = !avpkt->size || q->reinit_pending;
336 if (!q->engine_ready) {
337 ret = qsv_decode_init(avctx, q, avpkt);
343 if (av_fifo_size(q->input_fifo)) {
344 /* we have got rest of previous packet into buffer */
345 if (av_fifo_space(q->input_fifo) < avpkt->size) {
346 ret = av_fifo_grow(q->input_fifo, avpkt->size);
350 av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
351 bs.Data = q->input_fifo->rptr;
352 bs.DataLength = av_fifo_size(q->input_fifo);
355 bs.Data = avpkt->data;
356 bs.DataLength = avpkt->size;
358 bs.MaxLength = bs.DataLength;
359 bs.TimeStamp = avpkt->pts;
362 sync = av_mallocz(sizeof(*sync));
365 return AVERROR(ENOMEM);
369 ret = get_surface(avctx, q, &insurf);
373 ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
374 insurf, &outsurf, sync);
375 if (ret != MFX_WRN_DEVICE_BUSY)
380 if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
381 /* TODO: handle here minor sequence header changing */
382 } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
383 av_fifo_reset(q->input_fifo);
384 flush = q->reinit_pending = 1;
389 QSVFrame *out_frame = find_frame(q, outsurf);
393 av_log(avctx, AV_LOG_ERROR,
394 "The returned surface does not correspond to any frame\n");
398 out_frame->queued = 1;
399 av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
400 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
406 if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
410 /* make sure we do not enter an infinite loop if the SDK
411 * did not consume any data and did not return anything */
412 if (!*sync && !bs.DataOffset && !flush) {
413 av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
414 bs.DataOffset = avpkt->size;
418 qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
419 } else if (bs.DataOffset!=avpkt->size) {
420 /* some data of packet was not consumed. store it to local buffer */
421 av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
422 avpkt->size - bs.DataOffset, NULL);
425 if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
427 av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
428 return ff_qsv_error(ret);
430 n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
432 if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
435 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
436 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
437 out_frame->queued = 0;
440 ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
441 } while (ret == MFX_WRN_IN_EXECUTION);
445 src_frame = out_frame->frame;
447 ret = av_frame_ref(frame, src_frame);
451 outsurf = out_frame->surface;
453 frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
456 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
457 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
458 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
459 frame->top_field_first =
460 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
461 frame->interlaced_frame =
462 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
470 This function inserts a packet at fifo front.
472 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
474 int fifo_size = av_fifo_size(q->pkt_fifo);
476 /* easy case fifo is empty */
477 av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
479 /* realloc necessary */
481 AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
483 av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
485 while (av_fifo_size(q->pkt_fifo)) {
486 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
487 av_fifo_generic_write(fifo, &pkt, sizeof(pkt), NULL);
489 av_fifo_free(q->pkt_fifo);
493 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
494 AVFrame *frame, int *got_frame,
497 AVPacket pkt_ref = { 0 };
500 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
501 /* we already have got some buffered packets. so add new to tail */
502 ret = av_packet_ref(&pkt_ref, avpkt);
505 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
507 if (q->reinit_pending) {
508 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
511 /* Flushing complete, no more frames */
513 //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
516 if (!q->reinit_pending) {
517 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
518 /* process buffered packets */
519 while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
520 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
521 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
522 if (q->reinit_pending) {
524 A rare case: new reinit pending when buffering existing.
525 We should to return the pkt_ref back to same place of fifo
527 qsv_packet_push_front(q, &pkt_ref);
529 av_packet_unref(&pkt_ref);
533 /* general decoding */
534 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
535 if (q->reinit_pending) {
536 ret = av_packet_ref(&pkt_ref, avpkt);
539 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
547 This function resets decoder and corresponded buffers before seek operation
549 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
554 mfxVideoParam param = { { 0 } };
556 if (q->reinit_pending) {
558 } else if (q->engine_ready) {
559 ret = MFXVideoDECODE_GetVideoParam(q->session, ¶m);
561 av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
564 ret = MFXVideoDECODE_Reset(q->session, ¶m);
566 av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
570 cur = q->work_frames;
572 q->work_frames = cur->next;
573 av_frame_free(&cur->frame);
575 cur = q->work_frames;
579 /* Reset output surfaces */
580 av_fifo_reset(q->async_fifo);
582 /* Reset input packets fifo */
583 while (av_fifo_size(q->pkt_fifo)) {
584 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
585 av_packet_unref(&pkt);
588 /* Reset input bitstream fifo */
589 av_fifo_reset(q->input_fifo);
592 int ff_qsv_decode_close(QSVContext *q)
598 ff_qsv_close_internal_session(&q->internal_qs);
600 av_fifo_free(q->async_fifo);
601 q->async_fifo = NULL;
603 av_fifo_free(q->input_fifo);
604 q->input_fifo = NULL;
606 av_fifo_free(q->pkt_fifo);