]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvdec.c
Merge commit 'be00ec832c519427cd92218abac77dafdc1d5487'
[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         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
420
421         src_frame = out_frame->frame;
422
423         ret = av_frame_ref(frame, src_frame);
424         if (ret < 0)
425             return ret;
426
427         outsurf = out_frame->surface;
428
429         frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
430
431         frame->repeat_pict =
432             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
433             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
434             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
435         frame->top_field_first =
436             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
437         frame->interlaced_frame =
438             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
439
440         *got_frame = 1;
441     }
442
443     return avpkt->size;
444 }
445 /*
446  This function inserts a packet at fifo front.
447 */
448 static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
449 {
450     int fifo_size = av_fifo_size(q->pkt_fifo);
451     if (!fifo_size) {
452     /* easy case fifo is empty */
453         av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
454     } else {
455     /* realloc necessary */
456         AVPacket pkt;
457         AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
458
459         av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
460
461         while (av_fifo_size(q->pkt_fifo)) {
462             av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
463             av_fifo_generic_write(fifo,       &pkt, sizeof(pkt), NULL);
464         }
465         av_fifo_free(q->pkt_fifo);
466         q->pkt_fifo = fifo;
467     }
468 }
469 int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
470                   AVFrame *frame, int *got_frame,
471                   AVPacket *avpkt)
472 {
473     AVPacket pkt_ref = { 0 };
474     int ret = 0;
475
476     if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
477         /* we already have got some buffered packets. so add new to tail */
478         ret = av_packet_ref(&pkt_ref, avpkt);
479         if (ret < 0)
480             return ret;
481         av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
482     }
483     if (q->reinit_pending) {
484         ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
485
486         if (!*got_frame) {
487             /* Flushing complete, no more frames  */
488             close_decoder(q);
489             //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
490         }
491     }
492     if (!q->reinit_pending) {
493         if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
494             /* process buffered packets */
495             while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
496                 av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
497                 ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
498                 if (q->reinit_pending) {
499                     /*
500                        A rare case: new reinit pending when buffering existing.
501                        We should to return the pkt_ref back to same place of fifo
502                     */
503                     qsv_packet_push_front(q, &pkt_ref);
504                 } else {
505                     av_packet_unref(&pkt_ref);
506                 }
507            }
508         } else {
509             /* general decoding */
510             ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
511             if (q->reinit_pending) {
512                 ret = av_packet_ref(&pkt_ref, avpkt);
513                 if (ret < 0)
514                     return ret;
515                 av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
516             }
517         }
518     }
519
520     return ret;
521 }
522 /*
523  This function resets decoder and corresponded buffers before seek operation
524 */
525 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
526 {
527     QSVFrame *cur;
528     AVPacket pkt;
529     int ret = 0;
530     mfxVideoParam param = { { 0 } };
531
532     if (q->reinit_pending) {
533         close_decoder(q);
534     } else if (q->engine_ready) {
535         ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
536         if (ret < 0) {
537             av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
538         }
539
540         ret = MFXVideoDECODE_Reset(q->session, &param);
541         if (ret < 0) {
542             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
543         }
544
545         /* Free all frames*/
546         cur = q->work_frames;
547         while (cur) {
548             q->work_frames = cur->next;
549             av_frame_free(&cur->frame);
550             av_freep(&cur);
551             cur = q->work_frames;
552         }
553     }
554
555     /* Reset output surfaces */
556     av_fifo_reset(q->async_fifo);
557
558     /* Reset input packets fifo */
559     while (av_fifo_size(q->pkt_fifo)) {
560         av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
561         av_packet_unref(&pkt);
562     }
563
564     /* Reset input bitstream fifo */
565     av_fifo_reset(q->input_fifo);
566 }
567
568 int ff_qsv_decode_close(QSVContext *q)
569 {
570     close_decoder(q);
571
572     q->session = NULL;
573
574     ff_qsv_close_internal_session(&q->internal_qs);
575
576     av_fifo_free(q->async_fifo);
577     q->async_fifo = NULL;
578
579     av_fifo_free(q->input_fifo);
580     q->input_fifo = NULL;
581
582     av_fifo_free(q->pkt_fifo);
583     q->pkt_fifo = NULL;
584
585     return 0;
586 }