FFmpeg
qsvdec_other.c
Go to the documentation of this file.
1 /*
2  * Intel MediaSDK QSV based MPEG-2, VC-1 and VP8 decoders
3  *
4  * copyright (c) 2015 Anton Khirnov
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 #include <stdint.h>
25 #include <string.h>
26 
27 #include <mfx/mfxvideo.h>
28 
29 #include "libavutil/common.h"
30 #include "libavutil/fifo.h"
31 #include "libavutil/opt.h"
32 
33 #include "avcodec.h"
34 #include "internal.h"
35 #include "qsv_internal.h"
36 #include "qsvdec.h"
37 #include "qsv.h"
38 
39 typedef struct QSVOtherContext {
40  AVClass *class;
42 
44 
47 
49 {
50  AVPacket pkt;
51  while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
52  av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
54  }
55 
56  av_packet_unref(&s->input_ref);
57 }
58 
60 {
61  QSVOtherContext *s = avctx->priv_data;
62 
63 #if CONFIG_VP8_QSV_DECODER
64  if (avctx->codec_id == AV_CODEC_ID_VP8)
65  av_freep(&s->qsv.load_plugins);
66 #endif
67 
68  ff_qsv_decode_close(&s->qsv);
69 
71 
72  av_fifo_free(s->packet_fifo);
73 
74  return 0;
75 }
76 
78 {
79  QSVOtherContext *s = avctx->priv_data;
80  int ret;
81 
82 #if CONFIG_VP8_QSV_DECODER
83  if (avctx->codec_id == AV_CODEC_ID_VP8) {
84  static const char *uid_vp8dec_hw = "f622394d8d87452f878c51f2fc9b4131";
85 
86  av_freep(&s->qsv.load_plugins);
87  s->qsv.load_plugins = av_strdup(uid_vp8dec_hw);
88  if (!s->qsv.load_plugins)
89  return AVERROR(ENOMEM);
90  }
91 #endif
92 
93  s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
94  if (!s->packet_fifo) {
95  ret = AVERROR(ENOMEM);
96  goto fail;
97  }
98 
99  return 0;
100 fail:
101  qsv_decode_close(avctx);
102  return ret;
103 }
104 
105 static int qsv_decode_frame(AVCodecContext *avctx, void *data,
106  int *got_frame, AVPacket *avpkt)
107 {
108  QSVOtherContext *s = avctx->priv_data;
109  AVFrame *frame = data;
110  int ret;
111 
112  /* buffer the input packet */
113  if (avpkt->size) {
114  AVPacket input_ref = { 0 };
115 
116  if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
117  ret = av_fifo_realloc2(s->packet_fifo,
118  av_fifo_size(s->packet_fifo) + sizeof(input_ref));
119  if (ret < 0)
120  return ret;
121  }
122 
123  ret = av_packet_ref(&input_ref, avpkt);
124  if (ret < 0)
125  return ret;
126  av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
127  }
128 
129  /* process buffered data */
130  while (!*got_frame) {
131  if (s->input_ref.size <= 0) {
132  /* no more data */
133  if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
134  return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
135  /* in progress of reinit, no read from fifo and keep the buffer_pkt */
136  if (!s->qsv.reinit_flag) {
137  av_packet_unref(&s->input_ref);
138  av_fifo_generic_read(s->packet_fifo, &s->input_ref, sizeof(s->input_ref), NULL);
139  }
140  }
141 
142  ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->input_ref);
143  if (ret < 0) {
144  /* Drop input packet when failed to decode the packet. Otherwise,
145  the decoder will keep decoding the failure packet. */
146  av_packet_unref(&s->input_ref);
147 
148  return ret;
149  }
150  if (s->qsv.reinit_flag)
151  continue;
152 
153  s->input_ref.size -= ret;
154  s->input_ref.data += ret;
155  }
156 
157  return avpkt->size;
158 }
159 
160 static void qsv_decode_flush(AVCodecContext *avctx)
161 {
162  QSVOtherContext *s = avctx->priv_data;
163 
165  ff_qsv_decode_flush(avctx, &s->qsv);
166 }
167 
168 #define OFFSET(x) offsetof(QSVOtherContext, x)
169 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
170 static const AVOption options[] = {
171  { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
172  { NULL },
173 };
174 
175 #if CONFIG_MPEG2_QSV_DECODER
176 static const AVClass mpeg2_qsv_class = {
177  .class_name = "mpeg2_qsv",
178  .item_name = av_default_item_name,
179  .option = options,
180  .version = LIBAVUTIL_VERSION_INT,
181 };
182 
184  .name = "mpeg2_qsv",
185  .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video (Intel Quick Sync Video acceleration)"),
186  .priv_data_size = sizeof(QSVOtherContext),
192  .close = qsv_decode_close,
194  .priv_class = &mpeg2_qsv_class,
195  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
197  AV_PIX_FMT_NONE },
198  .hw_configs = ff_qsv_hw_configs,
199  .wrapper_name = "qsv",
200 };
201 #endif
202 
203 #if CONFIG_VC1_QSV_DECODER
204 static const AVClass vc1_qsv_class = {
205  .class_name = "vc1_qsv",
206  .item_name = av_default_item_name,
207  .option = options,
208  .version = LIBAVUTIL_VERSION_INT,
209 };
210 
212  .name = "vc1_qsv",
213  .long_name = NULL_IF_CONFIG_SMALL("VC-1 video (Intel Quick Sync Video acceleration)"),
214  .priv_data_size = sizeof(QSVOtherContext),
216  .id = AV_CODEC_ID_VC1,
220  .close = qsv_decode_close,
222  .priv_class = &vc1_qsv_class,
223  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
225  AV_PIX_FMT_NONE },
226  .hw_configs = ff_qsv_hw_configs,
227  .wrapper_name = "qsv",
228 };
229 #endif
230 
231 #if CONFIG_VP8_QSV_DECODER
232 static const AVClass vp8_qsv_class = {
233  .class_name = "vp8_qsv",
234  .item_name = av_default_item_name,
235  .option = options,
236  .version = LIBAVUTIL_VERSION_INT,
237 };
238 
240  .name = "vp8_qsv",
241  .long_name = NULL_IF_CONFIG_SMALL("VP8 video (Intel Quick Sync Video acceleration)"),
242  .priv_data_size = sizeof(QSVOtherContext),
244  .id = AV_CODEC_ID_VP8,
248  .close = qsv_decode_close,
250  .priv_class = &vp8_qsv_class,
251  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
253  AV_PIX_FMT_NONE },
254  .hw_configs = ff_qsv_hw_configs,
255  .wrapper_name = "qsv",
256 };
257 #endif
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
ff_qsv_hw_configs
const AVCodecHWConfigInternal * ff_qsv_hw_configs[]
Definition: qsvdec.c:44
AVCodec
AVCodec.
Definition: avcodec.h:3481
qsv_decode_flush
static void qsv_decode_flush(AVCodecContext *avctx)
Definition: qsvdec_other.c:160
ff_qsv_process_data
int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: qsvdec.c:524
qsv_decode_close
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition: qsvdec_other.c:59
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
OFFSET
#define OFFSET(x)
Definition: qsvdec_other.c:168
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
av_fifo_generic_write
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:122
av_fifo_free
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
internal.h
AVOption
AVOption.
Definition: opt.h:246
qsvdec.h
data
const char data[16]
Definition: mxf.c:91
av_fifo_generic_read
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:213
ff_qsv_decode_close
int ff_qsv_decode_close(QSVContext *q)
Definition: qsvdec.c:485
AVFifoBuffer
Definition: fifo.h:31
fifo.h
fail
#define fail()
Definition: checkasm.h:120
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
QSVContext
Definition: qsvdec.h:39
qsv_internal.h
ff_qsv_decode_flush
void ff_qsv_decode_flush(AVCodecContext *avctx, QSVContext *q)
Definition: qsvdec.c:622
ff_mpeg2_qsv_decoder
AVCodec ff_mpeg2_qsv_decoder
av_fifo_space
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
Definition: fifo.c:82
ASYNC_DEPTH_DEFAULT
#define ASYNC_DEPTH_DEFAULT
Definition: qsv_internal.h:33
av_cold
#define av_cold
Definition: attributes.h:84
QSVOtherContext::qsv
QSVContext qsv
Definition: qsvdec_other.c:41
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
s
#define s(width, name)
Definition: cbs_vp9.c:257
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
options
static const AVOption options[]
Definition: qsvdec_other.c:170
av_fifo_realloc2
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:87
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:1575
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:500
NULL
#define NULL
Definition: coverity.c:32
qsv.h
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:608
VD
#define VD
Definition: qsvdec_other.c:169
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
AVPacket::size
int size
Definition: avcodec.h:1478
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
qsv_clear_buffers
static void qsv_clear_buffers(QSVOtherContext *s)
Definition: qsvdec_other.c:48
QSVOtherContext
Definition: qsvdec_other.c:39
common.h
QSVOtherContext::packet_fifo
AVFifoBuffer * packet_fifo
Definition: qsvdec_other.c:43
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: avcodec.h:288
ff_vc1_qsv_decoder
AVCodec ff_vc1_qsv_decoder
avcodec.h
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
qsv_decode_init
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition: qsvdec_other.c:77
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
qsv_decode_frame
static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: qsvdec_other.c:105
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1006
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
ff_vp8_qsv_decoder
AVCodec ff_vp8_qsv_decoder
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_CODEC_CAP_HYBRID
#define AV_CODEC_CAP_HYBRID
Codec is potentially backed by a hardware implementation, but not necessarily.
Definition: avcodec.h:1085
av_fifo_size
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:77
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_fifo_alloc
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: avcodec.h:358
QSVOtherContext::input_ref
AVPacket input_ref
Definition: qsvdec_other.c:45
AV_CODEC_CAP_AVOID_PROBING
#define AV_CODEC_CAP_AVOID_PROBING
Decoder is not a preferred choice for probing.
Definition: avcodec.h:1063
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: avcodec.h:220