]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvdec.c
Merge commit 'a0524d9b1e1bb0012207584f067096df7792df6c'
[ffmpeg] / libavcodec / qsvdec.c
1 /*
2  * Intel MediaSDK QSV codec-independent code
3  *
4  * copyright (c) 2013 Luca Barbato
5  * copyright (c) 2015 Anton Khirnov <anton@khirnov.net>
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
27 #include <mfx/mfxvideo.h>
28
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"
34
35 #include "avcodec.h"
36 #include "internal.h"
37 #include "qsv.h"
38 #include "qsv_internal.h"
39 #include "qsvdec.h"
40
41 int ff_qsv_map_pixfmt(enum AVPixelFormat format)
42 {
43     switch (format) {
44     case AV_PIX_FMT_YUV420P:
45     case AV_PIX_FMT_YUVJ420P:
46         return AV_PIX_FMT_NV12;
47     default:
48         return AVERROR(ENOSYS);
49     }
50 }
51
52 static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
53 {
54     if (!session) {
55         if (!q->internal_qs.session) {
56            int ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
57                                                   q->load_plugins);
58             if (ret < 0)
59                 return ret;
60         }
61
62         q->session = q->internal_qs.session;
63     } else {
64         q->session = session;
65     }
66
67    return 0;
68 }
69
70 static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
71 {
72     mfxSession session = NULL;
73     mfxVideoParam param = { { 0 } };
74     mfxBitstream bs   = { { { 0 } } };
75     int ret;
76     enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
77                                        AV_PIX_FMT_NV12,
78                                        AV_PIX_FMT_NONE };
79
80     ret = ff_get_format(avctx, pix_fmts);
81     if (ret < 0)
82         return ret;
83
84     avctx->pix_fmt      = ret;
85
86     q->iopattern  = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
87     if (avctx->hwaccel_context) {
88         AVQSVContext *qsv = avctx->hwaccel_context;
89
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;
94     }
95
96     ret = qsv_init_session(avctx, q, session);
97     if (ret < 0) {
98         av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
99         return ret;
100     }
101
102     if (avpkt->size) {
103         bs.Data       = avpkt->data;
104         bs.DataLength = avpkt->size;
105         bs.MaxLength  = bs.DataLength;
106         bs.TimeStamp  = avpkt->pts;
107     } else
108         return AVERROR_INVALIDDATA;
109
110     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
111     if (ret < 0) {
112         av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
113         return ret;
114     }
115
116     param.mfx.CodecId = ret;
117
118     ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, &param);
119     if (MFX_ERR_MORE_DATA==ret) {
120         /* this code means that header not found so we return packet size to skip
121            a current packet
122          */
123         return avpkt->size;
124     } else if (ret < 0) {
125         av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
126         return ff_qsv_error(ret);
127     }
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;
134
135     ret = MFXVideoDECODE_Init(q->session, &param);
136     if (ret < 0) {
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");
140         } else {
141             av_log(avctx, AV_LOG_ERROR,
142                    "Error initializing the MFX video decoder %d\n", ret);
143         }
144         return ff_qsv_error(ret);
145     }
146
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;
153
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:
157      */
158     if (!q->async_fifo) {
159         q->async_fifo = av_fifo_alloc((1 + 16) *
160                                       (sizeof(mfxSyncPoint) + sizeof(QSVFrame*)));
161         if (!q->async_fifo)
162             return AVERROR(ENOMEM);
163     }
164
165     if (!q->input_fifo) {
166         q->input_fifo = av_fifo_alloc(1024*16);
167         if (!q->input_fifo)
168             return AVERROR(ENOMEM);
169     }
170
171     if (!q->pkt_fifo) {
172         q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
173         if (!q->pkt_fifo)
174             return AVERROR(ENOMEM);
175     }
176     q->engine_ready = 1;
177
178     return 0;
179 }
180
181 static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
182 {
183     int ret;
184
185     ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
186     if (ret < 0)
187         return ret;
188
189     if (frame->frame->format == AV_PIX_FMT_QSV) {
190         frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
191     } else {
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;
198
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];
202
203         frame->surface = &frame->surface_internal;
204     }
205
206     return 0;
207 }
208
209 static void qsv_clear_unused_frames(QSVContext *q)
210 {
211     QSVFrame *cur = q->work_frames;
212     while (cur) {
213         if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
214             cur->surface = NULL;
215             av_frame_unref(cur->frame);
216         }
217         cur = cur->next;
218     }
219 }
220
221 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
222 {
223     QSVFrame *frame, **last;
224     int ret;
225
226     qsv_clear_unused_frames(q);
227
228     frame = q->work_frames;
229     last  = &q->work_frames;
230     while (frame) {
231         if (!frame->surface) {
232             ret = alloc_frame(avctx, frame);
233             if (ret < 0)
234                 return ret;
235             *surf = frame->surface;
236             return 0;
237         }
238
239         last  = &frame->next;
240         frame = frame->next;
241     }
242
243     frame = av_mallocz(sizeof(*frame));
244     if (!frame)
245         return AVERROR(ENOMEM);
246     frame->frame = av_frame_alloc();
247     if (!frame->frame) {
248         av_freep(&frame);
249         return AVERROR(ENOMEM);
250     }
251     *last = frame;
252
253     ret = alloc_frame(avctx, frame);
254     if (ret < 0)
255         return ret;
256
257     *surf = frame->surface;
258
259     return 0;
260 }
261
262 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
263 {
264     QSVFrame *cur = q->work_frames;
265     while (cur) {
266         if (surf == cur->surface)
267             return cur;
268         cur = cur->next;
269     }
270     return NULL;
271 }
272
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.
281 */
282 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
283 {
284     int data_size;
285     int data_rest = 0;
286
287     av_fifo_drain(f, bytes_to_free);
288
289     data_size = av_fifo_size(f);
290     if (data_size > 0) {
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);
296             }
297             memmove(f->buffer, f->rptr, data_size);
298             data_size+= data_rest;
299         }
300     }
301     f->rptr = f->buffer;
302     f->wptr = f->buffer + data_size;
303     f->wndx = data_size;
304     f->rndx = 0;
305 }
306
307
308 static void close_decoder(QSVContext *q)
309 {
310     QSVFrame *cur;
311
312     if (q->session)
313         MFXVideoDECODE_Close(q->session);
314
315     cur = q->work_frames;
316     while (cur) {
317         q->work_frames = cur->next;
318         av_frame_free(&cur->frame);
319         av_freep(&cur);
320         cur = q->work_frames;
321     }
322
323     q->engine_ready   = 0;
324     q->reinit_pending = 0;
325 }
326
327 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
328                   AVFrame *frame, int *got_frame,
329                   AVPacket *avpkt)
330 {
331     QSVFrame *out_frame;
332     mfxFrameSurface1 *insurf;
333     mfxFrameSurface1 *outsurf;
334     mfxSyncPoint sync;
335     mfxBitstream bs = { { { 0 } } };
336     int ret;
337     int n_out_frames;
338     int buffered = 0;
339     int flush    = !avpkt->size || q->reinit_pending;
340
341     if (!q->engine_ready) {
342         ret = qsv_decode_init(avctx, q, avpkt);
343         if (ret)
344             return ret;
345     }
346
347     if (!flush) {
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);
352                 if (ret < 0)
353                     return ret;
354             }
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);
358             buffered = 1;
359         } else {
360             bs.Data       = avpkt->data;
361             bs.DataLength = avpkt->size;
362         }
363         bs.MaxLength  = bs.DataLength;
364         bs.TimeStamp  = avpkt->pts;
365     }
366
367     while (1) {
368         ret = get_surface(avctx, q, &insurf);
369         if (ret < 0)
370             return ret;
371         do {
372             ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
373                                                   insurf, &outsurf, &sync);
374             if (ret != MFX_WRN_DEVICE_BUSY)
375                 break;
376             av_usleep(500);
377         } while (1);
378
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;
384             continue;
385         }
386
387         if (sync) {
388             QSVFrame *out_frame = find_frame(q, outsurf);
389
390             if (!out_frame) {
391                 av_log(avctx, AV_LOG_ERROR,
392                        "The returned surface does not correspond to any frame\n");
393                 return AVERROR_BUG;
394             }
395
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);
399
400             continue;
401         }
402         if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
403             break;
404     }
405
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;
411     }
412
413     if (buffered) {
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);
419     }
420
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);
424     }
425     n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
426
427     if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
428         AVFrame *src_frame;
429
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;
433
434         do {
435             ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
436         } while (ret == MFX_WRN_IN_EXECUTION);
437
438         src_frame = out_frame->frame;
439
440         ret = av_frame_ref(frame, src_frame);
441         if (ret < 0)
442             return ret;
443
444         outsurf = out_frame->surface;
445
446         frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
447
448         frame->repeat_pict =
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);
456
457         *got_frame = 1;
458     }
459
460     return avpkt->size;
461 }
462 /*
463  This function inserts a packet at fifo front.
464 */
465 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
466 {
467     int fifo_size = av_fifo_size(q->pkt_fifo);
468     if (!fifo_size) {
469     /* easy case fifo is empty */
470         av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
471     } else {
472     /* realloc necessary */
473         AVPacket pkt;
474         AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
475
476         av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
477
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);
481         }
482         av_fifo_free(q->pkt_fifo);
483         q->pkt_fifo = fifo;
484     }
485 }
486 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
487                   AVFrame *frame, int *got_frame,
488                   AVPacket *avpkt)
489 {
490     AVPacket pkt_ref = { 0 };
491     int ret = 0;
492
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);
496         if (ret < 0)
497             return ret;
498         av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
499     }
500     if (q->reinit_pending) {
501         ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
502
503         if (!*got_frame) {
504             /* Flushing complete, no more frames  */
505             close_decoder(q);
506             //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
507         }
508     }
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) {
516                     /*
517                        A rare case: new reinit pending when buffering existing.
518                        We should to return the pkt_ref back to same place of fifo
519                     */
520                     qsv_packet_push_front(q, &pkt_ref);
521                 } else {
522                     av_packet_unref(&pkt_ref);
523                 }
524            }
525         } else {
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);
530                 if (ret < 0)
531                     return ret;
532                 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
533             }
534         }
535     }
536
537     return ret;
538 }
539 /*
540  This function resets decoder and corresponded buffers before seek operation
541 */
542 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
543 {
544     QSVFrame *cur;
545     AVPacket pkt;
546     int ret = 0;
547     mfxVideoParam param = { { 0 } };
548
549     if (q->reinit_pending) {
550         close_decoder(q);
551     } else if (q->engine_ready) {
552         ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
553         if (ret < 0) {
554             av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
555         }
556
557         ret = MFXVideoDECODE_Reset(q->session, &param);
558         if (ret < 0) {
559             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
560         }
561
562         /* Free all frames*/
563         cur = q->work_frames;
564         while (cur) {
565             q->work_frames = cur->next;
566             av_frame_free(&cur->frame);
567             av_freep(&cur);
568             cur = q->work_frames;
569         }
570     }
571
572     /* Reset output surfaces */
573     if (q->async_fifo)
574         av_fifo_reset(q->async_fifo);
575
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);
580     }
581
582     /* Reset input bitstream fifo */
583     if (q->input_fifo)
584         av_fifo_reset(q->input_fifo);
585 }
586
587 int ff_qsv_decode_close(QSVContext *q)
588 {
589     close_decoder(q);
590
591     q->session = NULL;
592
593     ff_qsv_close_internal_session(&q->internal_qs);
594
595     av_fifo_free(q->async_fifo);
596     q->async_fifo = NULL;
597
598     av_fifo_free(q->input_fifo);
599     q->input_fifo = NULL;
600
601     av_fifo_free(q->pkt_fifo);
602     q->pkt_fifo = NULL;
603
604     return 0;
605 }