]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvdec.c
Merge commit '8c3c7b8920033d61c7aa15a4465b759c84e5958f'
[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 #if FF_API_PKT_PTS
447 FF_DISABLE_DEPRECATION_WARNINGS
448         frame->pkt_pts = outsurf->Data.TimeStamp;
449 FF_ENABLE_DEPRECATION_WARNINGS
450 #endif
451         frame->pts = outsurf->Data.TimeStamp;
452
453         frame->repeat_pict =
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);
461
462         *got_frame = 1;
463     }
464
465     return avpkt->size;
466 }
467 /*
468  This function inserts a packet at fifo front.
469 */
470 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
471 {
472     int fifo_size = av_fifo_size(q->pkt_fifo);
473     if (!fifo_size) {
474     /* easy case fifo is empty */
475         av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
476     } else {
477     /* realloc necessary */
478         AVPacket pkt;
479         AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
480
481         av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
482
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);
486         }
487         av_fifo_free(q->pkt_fifo);
488         q->pkt_fifo = fifo;
489     }
490 }
491 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
492                   AVFrame *frame, int *got_frame,
493                   AVPacket *avpkt)
494 {
495     AVPacket pkt_ref = { 0 };
496     int ret = 0;
497
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);
501         if (ret < 0)
502             return ret;
503         av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
504     }
505     if (q->reinit_pending) {
506         ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
507
508         if (!*got_frame) {
509             /* Flushing complete, no more frames  */
510             close_decoder(q);
511             //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
512         }
513     }
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) {
521                     /*
522                        A rare case: new reinit pending when buffering existing.
523                        We should to return the pkt_ref back to same place of fifo
524                     */
525                     qsv_packet_push_front(q, &pkt_ref);
526                 } else {
527                     av_packet_unref(&pkt_ref);
528                 }
529            }
530         } else {
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);
535                 if (ret < 0)
536                     return ret;
537                 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
538             }
539         }
540     }
541
542     return ret;
543 }
544 /*
545  This function resets decoder and corresponded buffers before seek operation
546 */
547 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
548 {
549     QSVFrame *cur;
550     AVPacket pkt;
551     int ret = 0;
552     mfxVideoParam param = { { 0 } };
553
554     if (q->reinit_pending) {
555         close_decoder(q);
556     } else if (q->engine_ready) {
557         ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
558         if (ret < 0) {
559             av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
560         }
561
562         ret = MFXVideoDECODE_Reset(q->session, &param);
563         if (ret < 0) {
564             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
565         }
566
567         /* Free all frames*/
568         cur = q->work_frames;
569         while (cur) {
570             q->work_frames = cur->next;
571             av_frame_free(&cur->frame);
572             av_freep(&cur);
573             cur = q->work_frames;
574         }
575     }
576
577     /* Reset output surfaces */
578     if (q->async_fifo)
579         av_fifo_reset(q->async_fifo);
580
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);
585     }
586
587     /* Reset input bitstream fifo */
588     if (q->input_fifo)
589         av_fifo_reset(q->input_fifo);
590 }
591
592 int ff_qsv_decode_close(QSVContext *q)
593 {
594     close_decoder(q);
595
596     q->session = NULL;
597
598     ff_qsv_close_internal_session(&q->internal_qs);
599
600     av_fifo_free(q->async_fifo);
601     q->async_fifo = NULL;
602
603     av_fifo_free(q->input_fifo);
604     q->input_fifo = NULL;
605
606     av_fifo_free(q->pkt_fifo);
607     q->pkt_fifo = NULL;
608
609     return 0;
610 }