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 q->iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
63 if (avctx->hwaccel_context) {
64 AVQSVContext *qsv = avctx->hwaccel_context;
66 q->session = qsv->session;
67 q->iopattern = qsv->iopattern;
68 q->ext_buffers = qsv->ext_buffers;
69 q->nb_ext_buffers = qsv->nb_ext_buffers;
72 ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
77 q->session = q->internal_qs.session;
82 bs.Data = avpkt->data;
83 bs.DataLength = avpkt->size;
84 bs.MaxLength = bs.DataLength;
85 bs.TimeStamp = avpkt->pts;
87 return AVERROR_INVALIDDATA;
89 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
91 av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
95 param.mfx.CodecId = ret;
97 ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, ¶m);
98 if (MFX_ERR_MORE_DATA==ret) {
99 /* this code means that header not found so we return packet size to skip
103 } else if (ret < 0) {
104 av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
105 return ff_qsv_error(ret);
107 param.IOPattern = q->iopattern;
108 param.AsyncDepth = q->async_depth;
109 param.ExtParam = q->ext_buffers;
110 param.NumExtParam = q->nb_ext_buffers;
111 param.mfx.FrameInfo.BitDepthLuma = 8;
112 param.mfx.FrameInfo.BitDepthChroma = 8;
114 ret = MFXVideoDECODE_Init(q->session, ¶m);
116 if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
117 av_log(avctx, AV_LOG_ERROR,
118 "Error initializing the MFX video decoder, unsupported video\n");
120 av_log(avctx, AV_LOG_ERROR,
121 "Error initializing the MFX video decoder %d\n", ret);
123 return ff_qsv_error(ret);
126 ret = ff_get_format(avctx, pix_fmts);
130 avctx->pix_fmt = ret;
131 avctx->profile = param.mfx.CodecProfile;
132 avctx->level = param.mfx.CodecLevel;
133 avctx->coded_width = param.mfx.FrameInfo.Width;
134 avctx->coded_height = param.mfx.FrameInfo.Height;
135 avctx->width = param.mfx.FrameInfo.CropW - param.mfx.FrameInfo.CropX;
136 avctx->height = param.mfx.FrameInfo.CropH - param.mfx.FrameInfo.CropY;
138 /* maximum decoder latency should be not exceed max DPB size for h.264 and
139 HEVC which is 16 for both cases.
140 So weare pre-allocating fifo big enough for 17 elements:
142 if (!q->async_fifo) {
143 q->async_fifo = av_fifo_alloc((1 + 16) *
144 (sizeof(mfxSyncPoint) + sizeof(QSVFrame*)));
146 return AVERROR(ENOMEM);
149 if (!q->input_fifo) {
150 q->input_fifo = av_fifo_alloc(1024*16);
152 return AVERROR(ENOMEM);
156 q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
158 return AVERROR(ENOMEM);
165 static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
169 ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
173 if (frame->frame->format == AV_PIX_FMT_QSV) {
174 frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
176 frame->surface_internal.Info.BitDepthLuma = 8;
177 frame->surface_internal.Info.BitDepthChroma = 8;
178 frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12;
179 frame->surface_internal.Info.Width = avctx->coded_width;
180 frame->surface_internal.Info.Height = avctx->coded_height;
181 frame->surface_internal.Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
183 frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
184 frame->surface_internal.Data.Y = frame->frame->data[0];
185 frame->surface_internal.Data.UV = frame->frame->data[1];
187 frame->surface = &frame->surface_internal;
193 static void qsv_clear_unused_frames(QSVContext *q)
195 QSVFrame *cur = q->work_frames;
197 if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
199 av_frame_unref(cur->frame);
205 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
207 QSVFrame *frame, **last;
210 qsv_clear_unused_frames(q);
212 frame = q->work_frames;
213 last = &q->work_frames;
215 if (!frame->surface) {
216 ret = alloc_frame(avctx, frame);
219 *surf = frame->surface;
227 frame = av_mallocz(sizeof(*frame));
229 return AVERROR(ENOMEM);
230 frame->frame = av_frame_alloc();
233 return AVERROR(ENOMEM);
237 ret = alloc_frame(avctx, frame);
241 *surf = frame->surface;
246 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
248 QSVFrame *cur = q->work_frames;
250 if (surf == cur->surface)
257 /* This function uses for 'smart' releasing of consumed data
258 from the input bitstream fifo.
259 Since the input fifo mapped to mfxBitstream which does not understand
260 a wrapping of data over fifo end, we should also to relocate a possible
261 data rest to fifo begin. If rest of data is absent then we just reset fifo's
262 pointers to initial positions.
263 NOTE the case when fifo does contain unconsumed data is rare and typical
264 amount of such data is 1..4 bytes.
266 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
271 av_fifo_drain(f, bytes_to_free);
273 data_size = av_fifo_size(f);
275 if (f->buffer!=f->rptr) {
276 if ( (f->end - f->rptr) < data_size) {
277 data_rest = data_size - (f->end - f->rptr);
278 data_size-=data_rest;
279 memmove(f->buffer+data_size, f->buffer, data_rest);
281 memmove(f->buffer, f->rptr, data_size);
282 data_size+= data_rest;
286 f->wptr = f->buffer + data_size;
292 static void close_decoder(QSVContext *q)
297 MFXVideoDECODE_Close(q->session);
299 cur = q->work_frames;
301 q->work_frames = cur->next;
302 av_frame_free(&cur->frame);
304 cur = q->work_frames;
308 q->reinit_pending = 0;
311 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
312 AVFrame *frame, int *got_frame,
316 mfxFrameSurface1 *insurf;
317 mfxFrameSurface1 *outsurf;
319 mfxBitstream bs = { { { 0 } } };
323 int flush = !avpkt->size || q->reinit_pending;
325 if (!q->engine_ready) {
326 ret = qsv_decode_init(avctx, q, avpkt);
332 if (av_fifo_size(q->input_fifo)) {
333 /* we have got rest of previous packet into buffer */
334 if (av_fifo_space(q->input_fifo) < avpkt->size) {
335 ret = av_fifo_grow(q->input_fifo, avpkt->size);
339 av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
340 bs.Data = q->input_fifo->rptr;
341 bs.DataLength = av_fifo_size(q->input_fifo);
344 bs.Data = avpkt->data;
345 bs.DataLength = avpkt->size;
347 bs.MaxLength = bs.DataLength;
348 bs.TimeStamp = avpkt->pts;
352 ret = get_surface(avctx, q, &insurf);
356 ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
357 insurf, &outsurf, &sync);
358 if (ret != MFX_WRN_DEVICE_BUSY)
363 if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
364 /* TODO: handle here minor sequence header changing */
365 } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
366 av_fifo_reset(q->input_fifo);
367 flush = q->reinit_pending = 1;
372 QSVFrame *out_frame = find_frame(q, outsurf);
375 av_log(avctx, AV_LOG_ERROR,
376 "The returned surface does not correspond to any frame\n");
380 out_frame->queued = 1;
381 av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
382 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
386 if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
390 /* make sure we do not enter an infinite loop if the SDK
391 * did not consume any data and did not return anything */
392 if (!sync && !bs.DataOffset && !flush) {
393 av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
394 bs.DataOffset = avpkt->size;
398 qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
399 } else if (bs.DataOffset!=avpkt->size) {
400 /* some data of packet was not consumed. store it to local buffer */
401 av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
402 avpkt->size - bs.DataOffset, NULL);
405 if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
406 av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
407 return ff_qsv_error(ret);
409 n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
411 if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
414 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
415 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
416 out_frame->queued = 0;
418 MFXVideoCORE_SyncOperation(q->session, sync, 60000);
420 src_frame = out_frame->frame;
422 ret = av_frame_ref(frame, src_frame);
426 outsurf = out_frame->surface;
428 frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
431 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
432 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
433 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
434 frame->top_field_first =
435 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
436 frame->interlaced_frame =
437 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
445 This function inserts a packet at fifo front.
447 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
449 int fifo_size = av_fifo_size(q->pkt_fifo);
451 /* easy case fifo is empty */
452 av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
454 /* realloc necessary */
456 AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
458 av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
460 while (av_fifo_size(q->pkt_fifo)) {
461 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
462 av_fifo_generic_write(fifo, &pkt, sizeof(pkt), NULL);
464 av_fifo_free(q->pkt_fifo);
468 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
469 AVFrame *frame, int *got_frame,
472 AVPacket pkt_ref = { 0 };
475 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
476 /* we already have got some buffered packets. so add new to tail */
477 ret = av_packet_ref(&pkt_ref, avpkt);
480 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
482 if (q->reinit_pending) {
483 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
486 /* Flushing complete, no more frames */
488 //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
491 if (!q->reinit_pending) {
492 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
493 /* process buffered packets */
494 while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
495 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
496 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
497 if (q->reinit_pending) {
499 A rare case: new reinit pending when buffering existing.
500 We should to return the pkt_ref back to same place of fifo
502 qsv_packet_push_front(q, &pkt_ref);
504 av_packet_unref(&pkt_ref);
508 /* general decoding */
509 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
510 if (q->reinit_pending) {
511 ret = av_packet_ref(&pkt_ref, avpkt);
514 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
522 This function resets decoder and corresponded buffers before seek operation
524 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
529 mfxVideoParam param = { { 0 } };
531 if (q->reinit_pending) {
533 } else if (q->engine_ready) {
534 ret = MFXVideoDECODE_GetVideoParam(q->session, ¶m);
536 av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
539 ret = MFXVideoDECODE_Reset(q->session, ¶m);
541 av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
545 cur = q->work_frames;
547 q->work_frames = cur->next;
548 av_frame_free(&cur->frame);
550 cur = q->work_frames;
554 /* Reset output surfaces */
555 av_fifo_reset(q->async_fifo);
557 /* Reset input packets fifo */
558 while (av_fifo_size(q->pkt_fifo)) {
559 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
560 av_packet_unref(&pkt);
563 /* Reset input bitstream fifo */
564 av_fifo_reset(q->input_fifo);
567 int ff_qsv_decode_close(QSVContext *q)
573 ff_qsv_close_internal_session(&q->internal_qs);
575 av_fifo_free(q->async_fifo);
576 q->async_fifo = NULL;
578 av_fifo_free(q->input_fifo);
579 q->input_fifo = NULL;
581 av_fifo_free(q->pkt_fifo);