]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvdec.c
lavc/mjpegdec: avoid unneeded allocation if the frame is to be skipped
[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     cur = q->work_frames;
301     while (cur) {
302         q->work_frames = cur->next;
303         av_frame_free(&cur->frame);
304         av_freep(&cur);
305         cur = q->work_frames;
306     }
307
308     q->engine_ready   = 0;
309     q->reinit_pending = 0;
310 }
311
312 static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
313                   AVFrame *frame, int *got_frame,
314                   AVPacket *avpkt)
315 {
316     QSVFrame *out_frame;
317     mfxFrameSurface1 *insurf;
318     mfxFrameSurface1 *outsurf;
319     mfxSyncPoint sync;
320     mfxBitstream bs = { { { 0 } } };
321     int ret;
322     int n_out_frames;
323     int buffered = 0;
324     int flush    = !avpkt->size || q->reinit_pending;
325
326     if (!q->engine_ready) {
327         ret = qsv_decode_init(avctx, q, avpkt);
328         if (ret)
329             return ret;
330     }
331
332     if (!flush) {
333         if (av_fifo_size(q->input_fifo)) {
334             /* we have got rest of previous packet into buffer */
335             if (av_fifo_space(q->input_fifo) < avpkt->size) {
336                 ret = av_fifo_grow(q->input_fifo, avpkt->size);
337                 if (ret < 0)
338                     return ret;
339             }
340             av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
341             bs.Data       = q->input_fifo->rptr;
342             bs.DataLength = av_fifo_size(q->input_fifo);
343             buffered = 1;
344         } else {
345             bs.Data       = avpkt->data;
346             bs.DataLength = avpkt->size;
347         }
348         bs.MaxLength  = bs.DataLength;
349         bs.TimeStamp  = avpkt->pts;
350     }
351
352     while (1) {
353         ret = get_surface(avctx, q, &insurf);
354         if (ret < 0)
355             return ret;
356         do {
357             ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
358                                                   insurf, &outsurf, &sync);
359             if (ret != MFX_WRN_DEVICE_BUSY)
360                 break;
361             av_usleep(500);
362         } while (1);
363
364         if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
365             /* TODO: handle here minor sequence header changing */
366         } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
367             av_fifo_reset(q->input_fifo);
368             flush = q->reinit_pending = 1;
369             continue;
370         }
371
372         if (sync) {
373             QSVFrame *out_frame = find_frame(q, outsurf);
374
375             if (!out_frame) {
376                 av_log(avctx, AV_LOG_ERROR,
377                        "The returned surface does not correspond to any frame\n");
378                 return AVERROR_BUG;
379             }
380
381             out_frame->queued = 1;
382             av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
383             av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);
384
385             continue;
386         }
387         if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
388             break;
389     }
390
391     /* make sure we do not enter an infinite loop if the SDK
392      * did not consume any data and did not return anything */
393     if (!sync && !bs.DataOffset && !flush) {
394         av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
395         bs.DataOffset = avpkt->size;
396     }
397
398     if (buffered) {
399         qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
400     } else if (bs.DataOffset!=avpkt->size) {
401         /* some data of packet was not consumed. store it to local buffer */
402         av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
403                               avpkt->size - bs.DataOffset, NULL);
404     }
405
406     if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
407         av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
408         return ff_qsv_error(ret);
409     }
410     n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
411
412     if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
413         AVFrame *src_frame;
414
415         av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
416         av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);
417         out_frame->queued = 0;
418
419         do {
420             ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
421         } while (ret == MFX_WRN_IN_EXECUTION);
422
423         src_frame = out_frame->frame;
424
425         ret = av_frame_ref(frame, src_frame);
426         if (ret < 0)
427             return ret;
428
429         outsurf = out_frame->surface;
430
431         frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
432
433         frame->repeat_pict =
434             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
435             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
436             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
437         frame->top_field_first =
438             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
439         frame->interlaced_frame =
440             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
441
442         *got_frame = 1;
443     }
444
445     return avpkt->size;
446 }
447 /*
448  This function inserts a packet at fifo front.
449 */
450 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
451 {
452     int fifo_size = av_fifo_size(q->pkt_fifo);
453     if (!fifo_size) {
454     /* easy case fifo is empty */
455         av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
456     } else {
457     /* realloc necessary */
458         AVPacket pkt;
459         AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
460
461         av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
462
463         while (av_fifo_size(q->pkt_fifo)) {
464             av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
465             av_fifo_generic_write(fifo,       &pkt, sizeof(pkt), NULL);
466         }
467         av_fifo_free(q->pkt_fifo);
468         q->pkt_fifo = fifo;
469     }
470 }
471 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
472                   AVFrame *frame, int *got_frame,
473                   AVPacket *avpkt)
474 {
475     AVPacket pkt_ref = { 0 };
476     int ret = 0;
477
478     if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
479         /* we already have got some buffered packets. so add new to tail */
480         ret = av_packet_ref(&pkt_ref, avpkt);
481         if (ret < 0)
482             return ret;
483         av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
484     }
485     if (q->reinit_pending) {
486         ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
487
488         if (!*got_frame) {
489             /* Flushing complete, no more frames  */
490             close_decoder(q);
491             //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
492         }
493     }
494     if (!q->reinit_pending) {
495         if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
496             /* process buffered packets */
497             while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
498                 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
499                 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
500                 if (q->reinit_pending) {
501                     /*
502                        A rare case: new reinit pending when buffering existing.
503                        We should to return the pkt_ref back to same place of fifo
504                     */
505                     qsv_packet_push_front(q, &pkt_ref);
506                 } else {
507                     av_packet_unref(&pkt_ref);
508                 }
509            }
510         } else {
511             /* general decoding */
512             ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
513             if (q->reinit_pending) {
514                 ret = av_packet_ref(&pkt_ref, avpkt);
515                 if (ret < 0)
516                     return ret;
517                 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
518             }
519         }
520     }
521
522     return ret;
523 }
524 /*
525  This function resets decoder and corresponded buffers before seek operation
526 */
527 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
528 {
529     QSVFrame *cur;
530     AVPacket pkt;
531     int ret = 0;
532     mfxVideoParam param = { { 0 } };
533
534     if (q->reinit_pending) {
535         close_decoder(q);
536     } else if (q->engine_ready) {
537         ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
538         if (ret < 0) {
539             av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
540         }
541
542         ret = MFXVideoDECODE_Reset(q->session, &param);
543         if (ret < 0) {
544             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
545         }
546
547         /* Free all frames*/
548         cur = q->work_frames;
549         while (cur) {
550             q->work_frames = cur->next;
551             av_frame_free(&cur->frame);
552             av_freep(&cur);
553             cur = q->work_frames;
554         }
555     }
556
557     /* Reset output surfaces */
558     av_fifo_reset(q->async_fifo);
559
560     /* Reset input packets fifo */
561     while (av_fifo_size(q->pkt_fifo)) {
562         av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
563         av_packet_unref(&pkt);
564     }
565
566     /* Reset input bitstream fifo */
567     av_fifo_reset(q->input_fifo);
568 }
569
570 int ff_qsv_decode_close(QSVContext *q)
571 {
572     close_decoder(q);
573
574     q->session = NULL;
575
576     ff_qsv_close_internal_session(&q->internal_qs);
577
578     av_fifo_free(q->async_fifo);
579     q->async_fifo = NULL;
580
581     av_fifo_free(q->input_fifo);
582     q->input_fifo = NULL;
583
584     av_fifo_free(q->pkt_fifo);
585     q->pkt_fifo = NULL;
586
587     return 0;
588 }