]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvdec.c
lavfi/curves: remove pointless logging since the addition of plot option
[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_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
53 {
54     mfxVideoParam param = { { 0 } };
55     mfxBitstream bs   = { { { 0 } } };
56     int ret;
57     enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
58                                        AV_PIX_FMT_NV12,
59                                        AV_PIX_FMT_NONE };
60
61     ret = ff_get_format(avctx, pix_fmts);
62     if (ret < 0)
63         return ret;
64
65     avctx->pix_fmt      = ret;
66
67     q->iopattern  = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
68     if (avctx->hwaccel_context) {
69         AVQSVContext *qsv = avctx->hwaccel_context;
70
71         q->session        = qsv->session;
72         q->iopattern      = qsv->iopattern;
73         q->ext_buffers    = qsv->ext_buffers;
74         q->nb_ext_buffers = qsv->nb_ext_buffers;
75     }
76     if (!q->session) {
77         if (!q->internal_qs.session) {
78             ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
79                                                q->load_plugins);
80             if (ret < 0)
81                 return ret;
82         }
83
84         q->session = q->internal_qs.session;
85     }
86
87     if (avpkt->size) {
88         bs.Data       = avpkt->data;
89         bs.DataLength = avpkt->size;
90         bs.MaxLength  = bs.DataLength;
91         bs.TimeStamp  = avpkt->pts;
92     } else
93         return AVERROR_INVALIDDATA;
94
95     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
96     if (ret < 0) {
97         av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
98         return ret;
99     }
100
101     param.mfx.CodecId = ret;
102
103     ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, &param);
104     if (MFX_ERR_MORE_DATA==ret) {
105         /* this code means that header not found so we return packet size to skip
106            a current packet
107          */
108         return avpkt->size;
109     } else if (ret < 0) {
110         av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
111         return ff_qsv_error(ret);
112     }
113     param.IOPattern   = q->iopattern;
114     param.AsyncDepth  = q->async_depth;
115     param.ExtParam    = q->ext_buffers;
116     param.NumExtParam = q->nb_ext_buffers;
117     param.mfx.FrameInfo.BitDepthLuma   = 8;
118     param.mfx.FrameInfo.BitDepthChroma = 8;
119
120     ret = MFXVideoDECODE_Init(q->session, &param);
121     if (ret < 0) {
122         if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
123             av_log(avctx, AV_LOG_ERROR,
124                    "Error initializing the MFX video decoder, unsupported video\n");
125         } else {
126             av_log(avctx, AV_LOG_ERROR,
127                    "Error initializing the MFX video decoder %d\n", ret);
128         }
129         return ff_qsv_error(ret);
130     }
131
132     avctx->profile      = param.mfx.CodecProfile;
133     avctx->level        = param.mfx.CodecLevel;
134     avctx->coded_width  = param.mfx.FrameInfo.Width;
135     avctx->coded_height = param.mfx.FrameInfo.Height;
136     avctx->width        = param.mfx.FrameInfo.CropW - param.mfx.FrameInfo.CropX;
137     avctx->height       = param.mfx.FrameInfo.CropH - param.mfx.FrameInfo.CropY;
138
139     /* maximum decoder latency should be not exceed max DPB size for h.264 and
140        HEVC which is 16 for both cases.
141        So weare  pre-allocating fifo big enough for 17 elements:
142      */
143     if (!q->async_fifo) {
144         q->async_fifo = av_fifo_alloc((1 + 16) *
145                                       (sizeof(mfxSyncPoint*) + sizeof(QSVFrame*)));
146         if (!q->async_fifo)
147             return AVERROR(ENOMEM);
148     }
149
150     if (!q->input_fifo) {
151         q->input_fifo = av_fifo_alloc(1024*16);
152         if (!q->input_fifo)
153             return AVERROR(ENOMEM);
154     }
155
156     if (!q->pkt_fifo) {
157         q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
158         if (!q->pkt_fifo)
159             return AVERROR(ENOMEM);
160     }
161     q->engine_ready = 1;
162
163     return 0;
164 }
165
166 static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
167 {
168     int ret;
169
170     ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
171     if (ret < 0)
172         return ret;
173
174     if (frame->frame->format == AV_PIX_FMT_QSV) {
175         frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
176     } else {
177         frame->surface_internal.Info.BitDepthLuma   = 8;
178         frame->surface_internal.Info.BitDepthChroma = 8;
179         frame->surface_internal.Info.FourCC         = MFX_FOURCC_NV12;
180         frame->surface_internal.Info.Width          = avctx->coded_width;
181         frame->surface_internal.Info.Height         = avctx->coded_height;
182         frame->surface_internal.Info.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
183
184         frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
185         frame->surface_internal.Data.Y        = frame->frame->data[0];
186         frame->surface_internal.Data.UV       = frame->frame->data[1];
187
188         frame->surface = &frame->surface_internal;
189     }
190
191     return 0;
192 }
193
194 static void qsv_clear_unused_frames(QSVContext *q)
195 {
196     QSVFrame *cur = q->work_frames;
197     while (cur) {
198         if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
199             cur->surface = NULL;
200             av_frame_unref(cur->frame);
201         }
202         cur = cur->next;
203     }
204 }
205
206 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
207 {
208     QSVFrame *frame, **last;
209     int ret;
210
211     qsv_clear_unused_frames(q);
212
213     frame = q->work_frames;
214     last  = &q->work_frames;
215     while (frame) {
216         if (!frame->surface) {
217             ret = alloc_frame(avctx, frame);
218             if (ret < 0)
219                 return ret;
220             *surf = frame->surface;
221             return 0;
222         }
223
224         last  = &frame->next;
225         frame = frame->next;
226     }
227
228     frame = av_mallocz(sizeof(*frame));
229     if (!frame)
230         return AVERROR(ENOMEM);
231     frame->frame = av_frame_alloc();
232     if (!frame->frame) {
233         av_freep(&frame);
234         return AVERROR(ENOMEM);
235     }
236     *last = frame;
237
238     ret = alloc_frame(avctx, frame);
239     if (ret < 0)
240         return ret;
241
242     *surf = frame->surface;
243
244     return 0;
245 }
246
247 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
248 {
249     QSVFrame *cur = q->work_frames;
250     while (cur) {
251         if (surf == cur->surface)
252             return cur;
253         cur = cur->next;
254     }
255     return NULL;
256 }
257
258 /*  This function uses for 'smart' releasing of consumed data
259     from the input bitstream fifo.
260     Since the input fifo mapped to mfxBitstream which does not understand
261     a wrapping of data over fifo end, we should also to relocate a possible
262     data rest to fifo begin. If rest of data is absent then we just reset fifo's
263     pointers to initial positions.
264     NOTE the case when fifo does contain unconsumed data is rare and typical
265     amount of such data is 1..4 bytes.
266 */
267 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
268 {
269     int data_size;
270     int data_rest = 0;
271
272     av_fifo_drain(f, bytes_to_free);
273
274     data_size = av_fifo_size(f);
275     if (data_size > 0) {
276         if (f->buffer!=f->rptr) {
277             if ( (f->end - f->rptr) < data_size) {
278                 data_rest = data_size - (f->end - f->rptr);
279                 data_size-=data_rest;
280                 memmove(f->buffer+data_size, f->buffer, data_rest);
281             }
282             memmove(f->buffer, f->rptr, data_size);
283             data_size+= data_rest;
284         }
285     }
286     f->rptr = f->buffer;
287     f->wptr = f->buffer + data_size;
288     f->wndx = data_size;
289     f->rndx = 0;
290 }
291
292
293 static void close_decoder(QSVContext *q)
294 {
295     QSVFrame *cur;
296
297     if (q->session)
298         MFXVideoDECODE_Close(q->session);
299
300     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
301         QSVFrame *out_frame;
302         mfxSyncPoint *sync;
303
304         av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
305         av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);
306
307         av_freep(&sync);
308     }
309
310     cur = q->work_frames;
311     while (cur) {
312         q->work_frames = cur->next;
313         av_frame_free(&cur->frame);
314         av_freep(&cur);
315         cur = q->work_frames;
316     }
317
318     q->engine_ready   = 0;
319     q->reinit_pending = 0;
320 }
321
322 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
323                   AVFrame *frame, int *got_frame,
324                   AVPacket *avpkt)
325 {
326     QSVFrame *out_frame;
327     mfxFrameSurface1 *insurf;
328     mfxFrameSurface1 *outsurf;
329     mfxSyncPoint *sync;
330     mfxBitstream bs = { { { 0 } } };
331     int ret;
332     int n_out_frames;
333     int buffered = 0;
334     int flush    = !avpkt->size || q->reinit_pending;
335
336     if (!q->engine_ready) {
337         ret = qsv_decode_init(avctx, q, avpkt);
338         if (ret)
339             return ret;
340     }
341
342     if (!flush) {
343         if (av_fifo_size(q->input_fifo)) {
344             /* we have got rest of previous packet into buffer */
345             if (av_fifo_space(q->input_fifo) < avpkt->size) {
346                 ret = av_fifo_grow(q->input_fifo, avpkt->size);
347                 if (ret < 0)
348                     return ret;
349             }
350             av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
351             bs.Data       = q->input_fifo->rptr;
352             bs.DataLength = av_fifo_size(q->input_fifo);
353             buffered = 1;
354         } else {
355             bs.Data       = avpkt->data;
356             bs.DataLength = avpkt->size;
357         }
358         bs.MaxLength  = bs.DataLength;
359         bs.TimeStamp  = avpkt->pts;
360     }
361
362     sync = av_mallocz(sizeof(*sync));
363     if (!sync) {
364         av_freep(&sync);
365         return AVERROR(ENOMEM);
366     }
367
368     while (1) {
369         ret = get_surface(avctx, q, &insurf);
370         if (ret < 0)
371             return ret;
372         do {
373             ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
374                                                   insurf, &outsurf, sync);
375             if (ret != MFX_WRN_DEVICE_BUSY)
376                 break;
377             av_usleep(500);
378         } while (1);
379
380         if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
381             /* TODO: handle here minor sequence header changing */
382         } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
383             av_fifo_reset(q->input_fifo);
384             flush = q->reinit_pending = 1;
385             continue;
386         }
387
388         if (*sync) {
389             QSVFrame *out_frame = find_frame(q, outsurf);
390
391             if (!out_frame) {
392                 av_freep(&sync);
393                 av_log(avctx, AV_LOG_ERROR,
394                        "The returned surface does not correspond to any frame\n");
395                 return AVERROR_BUG;
396             }
397
398             out_frame->queued = 1;
399             av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
400             av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);
401
402             continue;
403         } else {
404             av_freep(&sync);
405         }
406         if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
407             break;
408     }
409
410     /* make sure we do not enter an infinite loop if the SDK
411      * did not consume any data and did not return anything */
412     if (!*sync && !bs.DataOffset && !flush) {
413         av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
414         bs.DataOffset = avpkt->size;
415     }
416
417     if (buffered) {
418         qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
419     } else if (bs.DataOffset!=avpkt->size) {
420         /* some data of packet was not consumed. store it to local buffer */
421         av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
422                               avpkt->size - bs.DataOffset, NULL);
423     }
424
425     if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
426         av_freep(&sync);
427         av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
428         return ff_qsv_error(ret);
429     }
430     n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
431
432     if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
433         AVFrame *src_frame;
434
435         av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
436         av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);
437         out_frame->queued = 0;
438
439         do {
440             ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
441         } while (ret == MFX_WRN_IN_EXECUTION);
442
443         av_freep(&sync);
444
445         src_frame = out_frame->frame;
446
447         ret = av_frame_ref(frame, src_frame);
448         if (ret < 0)
449             return ret;
450
451         outsurf = out_frame->surface;
452
453         frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
454
455         frame->repeat_pict =
456             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
457             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
458             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
459         frame->top_field_first =
460             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
461         frame->interlaced_frame =
462             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
463
464         *got_frame = 1;
465     }
466
467     return avpkt->size;
468 }
469 /*
470  This function inserts a packet at fifo front.
471 */
472 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
473 {
474     int fifo_size = av_fifo_size(q->pkt_fifo);
475     if (!fifo_size) {
476     /* easy case fifo is empty */
477         av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
478     } else {
479     /* realloc necessary */
480         AVPacket pkt;
481         AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
482
483         av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
484
485         while (av_fifo_size(q->pkt_fifo)) {
486             av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
487             av_fifo_generic_write(fifo,       &pkt, sizeof(pkt), NULL);
488         }
489         av_fifo_free(q->pkt_fifo);
490         q->pkt_fifo = fifo;
491     }
492 }
493 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
494                   AVFrame *frame, int *got_frame,
495                   AVPacket *avpkt)
496 {
497     AVPacket pkt_ref = { 0 };
498     int ret = 0;
499
500     if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
501         /* we already have got some buffered packets. so add new to tail */
502         ret = av_packet_ref(&pkt_ref, avpkt);
503         if (ret < 0)
504             return ret;
505         av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
506     }
507     if (q->reinit_pending) {
508         ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
509
510         if (!*got_frame) {
511             /* Flushing complete, no more frames  */
512             close_decoder(q);
513             //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
514         }
515     }
516     if (!q->reinit_pending) {
517         if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
518             /* process buffered packets */
519             while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
520                 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
521                 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
522                 if (q->reinit_pending) {
523                     /*
524                        A rare case: new reinit pending when buffering existing.
525                        We should to return the pkt_ref back to same place of fifo
526                     */
527                     qsv_packet_push_front(q, &pkt_ref);
528                 } else {
529                     av_packet_unref(&pkt_ref);
530                 }
531            }
532         } else {
533             /* general decoding */
534             ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
535             if (q->reinit_pending) {
536                 ret = av_packet_ref(&pkt_ref, avpkt);
537                 if (ret < 0)
538                     return ret;
539                 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
540             }
541         }
542     }
543
544     return ret;
545 }
546 /*
547  This function resets decoder and corresponded buffers before seek operation
548 */
549 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
550 {
551     QSVFrame *cur;
552     AVPacket pkt;
553     int ret = 0;
554     mfxVideoParam param = { { 0 } };
555
556     if (q->reinit_pending) {
557         close_decoder(q);
558     } else if (q->engine_ready) {
559         ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
560         if (ret < 0) {
561             av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
562         }
563
564         ret = MFXVideoDECODE_Reset(q->session, &param);
565         if (ret < 0) {
566             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
567         }
568
569         /* Free all frames*/
570         cur = q->work_frames;
571         while (cur) {
572             q->work_frames = cur->next;
573             av_frame_free(&cur->frame);
574             av_freep(&cur);
575             cur = q->work_frames;
576         }
577     }
578
579     /* Reset output surfaces */
580     av_fifo_reset(q->async_fifo);
581
582     /* Reset input packets fifo */
583     while (av_fifo_size(q->pkt_fifo)) {
584         av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
585         av_packet_unref(&pkt);
586     }
587
588     /* Reset input bitstream 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 }