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_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
55 if (!q->internal_qs.session) {
56 int ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
62 q->session = q->internal_qs.session;
70 static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
72 mfxSession session = NULL;
73 mfxVideoParam param = { { 0 } };
74 mfxBitstream bs = { { { 0 } } };
76 enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
80 ret = ff_get_format(avctx, pix_fmts);
86 q->iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
87 if (avctx->hwaccel_context) {
88 AVQSVContext *qsv = avctx->hwaccel_context;
90 session = qsv->session;
91 q->iopattern = qsv->iopattern;
92 q->ext_buffers = qsv->ext_buffers;
93 q->nb_ext_buffers = qsv->nb_ext_buffers;
96 ret = qsv_init_session(avctx, q, session);
98 av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
103 bs.Data = avpkt->data;
104 bs.DataLength = avpkt->size;
105 bs.MaxLength = bs.DataLength;
106 bs.TimeStamp = avpkt->pts;
108 return AVERROR_INVALIDDATA;
110 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
112 av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
116 param.mfx.CodecId = ret;
118 ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, ¶m);
119 if (MFX_ERR_MORE_DATA==ret) {
120 /* this code means that header not found so we return packet size to skip
124 } else if (ret < 0) {
125 av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
126 return ff_qsv_error(ret);
128 param.IOPattern = q->iopattern;
129 param.AsyncDepth = q->async_depth;
130 param.ExtParam = q->ext_buffers;
131 param.NumExtParam = q->nb_ext_buffers;
132 param.mfx.FrameInfo.BitDepthLuma = 8;
133 param.mfx.FrameInfo.BitDepthChroma = 8;
135 ret = MFXVideoDECODE_Init(q->session, ¶m);
137 if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
138 av_log(avctx, AV_LOG_ERROR,
139 "Error initializing the MFX video decoder, unsupported video\n");
141 av_log(avctx, AV_LOG_ERROR,
142 "Error initializing the MFX video decoder %d\n", ret);
144 return ff_qsv_error(ret);
147 avctx->profile = param.mfx.CodecProfile;
148 avctx->level = param.mfx.CodecLevel;
149 avctx->coded_width = param.mfx.FrameInfo.Width;
150 avctx->coded_height = param.mfx.FrameInfo.Height;
151 avctx->width = param.mfx.FrameInfo.CropW - param.mfx.FrameInfo.CropX;
152 avctx->height = param.mfx.FrameInfo.CropH - param.mfx.FrameInfo.CropY;
154 /* maximum decoder latency should be not exceed max DPB size for h.264 and
155 HEVC which is 16 for both cases.
156 So weare pre-allocating fifo big enough for 17 elements:
158 if (!q->async_fifo) {
159 q->async_fifo = av_fifo_alloc((1 + 16) *
160 (sizeof(mfxSyncPoint) + sizeof(QSVFrame*)));
162 return AVERROR(ENOMEM);
165 if (!q->input_fifo) {
166 q->input_fifo = av_fifo_alloc(1024*16);
168 return AVERROR(ENOMEM);
172 q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
174 return AVERROR(ENOMEM);
181 static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
185 ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
189 if (frame->frame->format == AV_PIX_FMT_QSV) {
190 frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
192 frame->surface_internal.Info.BitDepthLuma = 8;
193 frame->surface_internal.Info.BitDepthChroma = 8;
194 frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12;
195 frame->surface_internal.Info.Width = avctx->coded_width;
196 frame->surface_internal.Info.Height = avctx->coded_height;
197 frame->surface_internal.Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
199 frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
200 frame->surface_internal.Data.Y = frame->frame->data[0];
201 frame->surface_internal.Data.UV = frame->frame->data[1];
203 frame->surface = &frame->surface_internal;
209 static void qsv_clear_unused_frames(QSVContext *q)
211 QSVFrame *cur = q->work_frames;
213 if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
215 av_frame_unref(cur->frame);
221 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
223 QSVFrame *frame, **last;
226 qsv_clear_unused_frames(q);
228 frame = q->work_frames;
229 last = &q->work_frames;
231 if (!frame->surface) {
232 ret = alloc_frame(avctx, frame);
235 *surf = frame->surface;
243 frame = av_mallocz(sizeof(*frame));
245 return AVERROR(ENOMEM);
246 frame->frame = av_frame_alloc();
249 return AVERROR(ENOMEM);
253 ret = alloc_frame(avctx, frame);
257 *surf = frame->surface;
262 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
264 QSVFrame *cur = q->work_frames;
266 if (surf == cur->surface)
273 /* This function uses for 'smart' releasing of consumed data
274 from the input bitstream fifo.
275 Since the input fifo mapped to mfxBitstream which does not understand
276 a wrapping of data over fifo end, we should also to relocate a possible
277 data rest to fifo begin. If rest of data is absent then we just reset fifo's
278 pointers to initial positions.
279 NOTE the case when fifo does contain unconsumed data is rare and typical
280 amount of such data is 1..4 bytes.
282 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
287 av_fifo_drain(f, bytes_to_free);
289 data_size = av_fifo_size(f);
291 if (f->buffer!=f->rptr) {
292 if ( (f->end - f->rptr) < data_size) {
293 data_rest = data_size - (f->end - f->rptr);
294 data_size-=data_rest;
295 memmove(f->buffer+data_size, f->buffer, data_rest);
297 memmove(f->buffer, f->rptr, data_size);
298 data_size+= data_rest;
302 f->wptr = f->buffer + data_size;
308 static void close_decoder(QSVContext *q)
313 MFXVideoDECODE_Close(q->session);
315 cur = q->work_frames;
317 q->work_frames = cur->next;
318 av_frame_free(&cur->frame);
320 cur = q->work_frames;
324 q->reinit_pending = 0;
327 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
328 AVFrame *frame, int *got_frame,
332 mfxFrameSurface1 *insurf;
333 mfxFrameSurface1 *outsurf;
335 mfxBitstream bs = { { { 0 } } };
339 int flush = !avpkt->size || q->reinit_pending;
341 if (!q->engine_ready) {
342 ret = qsv_decode_init(avctx, q, avpkt);
348 if (av_fifo_size(q->input_fifo)) {
349 /* we have got rest of previous packet into buffer */
350 if (av_fifo_space(q->input_fifo) < avpkt->size) {
351 ret = av_fifo_grow(q->input_fifo, avpkt->size);
355 av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
356 bs.Data = q->input_fifo->rptr;
357 bs.DataLength = av_fifo_size(q->input_fifo);
360 bs.Data = avpkt->data;
361 bs.DataLength = avpkt->size;
363 bs.MaxLength = bs.DataLength;
364 bs.TimeStamp = avpkt->pts;
368 ret = get_surface(avctx, q, &insurf);
372 ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
373 insurf, &outsurf, &sync);
374 if (ret != MFX_WRN_DEVICE_BUSY)
379 if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
380 /* TODO: handle here minor sequence header changing */
381 } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
382 av_fifo_reset(q->input_fifo);
383 flush = q->reinit_pending = 1;
388 QSVFrame *out_frame = find_frame(q, outsurf);
391 av_log(avctx, AV_LOG_ERROR,
392 "The returned surface does not correspond to any frame\n");
396 out_frame->queued = 1;
397 av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
398 av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
402 if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
406 /* make sure we do not enter an infinite loop if the SDK
407 * did not consume any data and did not return anything */
408 if (!sync && !bs.DataOffset && !flush) {
409 av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
410 bs.DataOffset = avpkt->size;
414 qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
415 } else if (bs.DataOffset!=avpkt->size) {
416 /* some data of packet was not consumed. store it to local buffer */
417 av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
418 avpkt->size - bs.DataOffset, NULL);
421 if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
422 av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
423 return ff_qsv_error(ret);
425 n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
427 if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
430 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
431 av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
432 out_frame->queued = 0;
435 ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
436 } while (ret == MFX_WRN_IN_EXECUTION);
438 src_frame = out_frame->frame;
440 ret = av_frame_ref(frame, src_frame);
444 outsurf = out_frame->surface;
446 frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
449 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
450 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
451 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
452 frame->top_field_first =
453 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
454 frame->interlaced_frame =
455 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
463 This function inserts a packet at fifo front.
465 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
467 int fifo_size = av_fifo_size(q->pkt_fifo);
469 /* easy case fifo is empty */
470 av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
472 /* realloc necessary */
474 AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
476 av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
478 while (av_fifo_size(q->pkt_fifo)) {
479 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
480 av_fifo_generic_write(fifo, &pkt, sizeof(pkt), NULL);
482 av_fifo_free(q->pkt_fifo);
486 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
487 AVFrame *frame, int *got_frame,
490 AVPacket pkt_ref = { 0 };
493 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
494 /* we already have got some buffered packets. so add new to tail */
495 ret = av_packet_ref(&pkt_ref, avpkt);
498 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
500 if (q->reinit_pending) {
501 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
504 /* Flushing complete, no more frames */
506 //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
509 if (!q->reinit_pending) {
510 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
511 /* process buffered packets */
512 while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
513 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
514 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
515 if (q->reinit_pending) {
517 A rare case: new reinit pending when buffering existing.
518 We should to return the pkt_ref back to same place of fifo
520 qsv_packet_push_front(q, &pkt_ref);
522 av_packet_unref(&pkt_ref);
526 /* general decoding */
527 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
528 if (q->reinit_pending) {
529 ret = av_packet_ref(&pkt_ref, avpkt);
532 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
540 This function resets decoder and corresponded buffers before seek operation
542 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
547 mfxVideoParam param = { { 0 } };
549 if (q->reinit_pending) {
551 } else if (q->engine_ready) {
552 ret = MFXVideoDECODE_GetVideoParam(q->session, ¶m);
554 av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
557 ret = MFXVideoDECODE_Reset(q->session, ¶m);
559 av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
563 cur = q->work_frames;
565 q->work_frames = cur->next;
566 av_frame_free(&cur->frame);
568 cur = q->work_frames;
572 /* Reset output surfaces */
574 av_fifo_reset(q->async_fifo);
576 /* Reset input packets fifo */
577 while (q->pkt_fifo && av_fifo_size(q->pkt_fifo)) {
578 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
579 av_packet_unref(&pkt);
582 /* Reset input bitstream fifo */
584 av_fifo_reset(q->input_fifo);
587 int ff_qsv_decode_close(QSVContext *q)
593 ff_qsv_close_internal_session(&q->internal_qs);
595 av_fifo_free(q->async_fifo);
596 q->async_fifo = NULL;
598 av_fifo_free(q->input_fifo);
599 q->input_fifo = NULL;
601 av_fifo_free(q->pkt_fifo);