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;
447 FF_DISABLE_DEPRECATION_WARNINGS
448 frame->pkt_pts = outsurf->Data.TimeStamp;
449 FF_ENABLE_DEPRECATION_WARNINGS
451 frame->pts = outsurf->Data.TimeStamp;
454 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
455 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
456 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
457 frame->top_field_first =
458 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
459 frame->interlaced_frame =
460 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
468 This function inserts a packet at fifo front.
470 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
472 int fifo_size = av_fifo_size(q->pkt_fifo);
474 /* easy case fifo is empty */
475 av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
477 /* realloc necessary */
479 AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
481 av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
483 while (av_fifo_size(q->pkt_fifo)) {
484 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
485 av_fifo_generic_write(fifo, &pkt, sizeof(pkt), NULL);
487 av_fifo_free(q->pkt_fifo);
491 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
492 AVFrame *frame, int *got_frame,
495 AVPacket pkt_ref = { 0 };
498 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
499 /* we already have got some buffered packets. so add new to tail */
500 ret = av_packet_ref(&pkt_ref, avpkt);
503 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
505 if (q->reinit_pending) {
506 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
509 /* Flushing complete, no more frames */
511 //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
514 if (!q->reinit_pending) {
515 if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
516 /* process buffered packets */
517 while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
518 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
519 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
520 if (q->reinit_pending) {
522 A rare case: new reinit pending when buffering existing.
523 We should to return the pkt_ref back to same place of fifo
525 qsv_packet_push_front(q, &pkt_ref);
527 av_packet_unref(&pkt_ref);
531 /* general decoding */
532 ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
533 if (q->reinit_pending) {
534 ret = av_packet_ref(&pkt_ref, avpkt);
537 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
545 This function resets decoder and corresponded buffers before seek operation
547 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
552 mfxVideoParam param = { { 0 } };
554 if (q->reinit_pending) {
556 } else if (q->engine_ready) {
557 ret = MFXVideoDECODE_GetVideoParam(q->session, ¶m);
559 av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
562 ret = MFXVideoDECODE_Reset(q->session, ¶m);
564 av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
568 cur = q->work_frames;
570 q->work_frames = cur->next;
571 av_frame_free(&cur->frame);
573 cur = q->work_frames;
577 /* Reset output surfaces */
579 av_fifo_reset(q->async_fifo);
581 /* Reset input packets fifo */
582 while (q->pkt_fifo && av_fifo_size(q->pkt_fifo)) {
583 av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
584 av_packet_unref(&pkt);
587 /* 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);