FFmpeg
qsvdec_h2645.c
Go to the documentation of this file.
1 /*
2  * Intel MediaSDK QSV based H.264 / HEVC decoder
3  *
4  * copyright (c) 2013 Luca Barbato
5  * copyright (c) 2015 Anton Khirnov
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 
25 #include <stdint.h>
26 #include <string.h>
27 
28 #include <mfx/mfxvideo.h>
29 
30 #include "libavutil/common.h"
31 #include "libavutil/fifo.h"
32 #include "libavutil/opt.h"
33 
34 #include "avcodec.h"
35 #include "internal.h"
36 #include "qsv_internal.h"
37 #include "qsvdec.h"
38 #include "qsv.h"
39 
40 enum LoadPlugin {
44 };
45 
46 typedef struct QSVH2645Context {
47  AVClass *class;
49 
51 
53 
56 
58 {
59  AVPacket pkt;
60  while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
61  av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
62  av_packet_unref(&pkt);
63  }
64 
66 }
67 
69 {
70  QSVH2645Context *s = avctx->priv_data;
71 
73 
75 
77 
78  return 0;
79 }
80 
82 {
83  QSVH2645Context *s = avctx->priv_data;
84  int ret;
85 
86  if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
87  static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
88  static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
89 
90  if (s->qsv.load_plugins[0]) {
91  av_log(avctx, AV_LOG_WARNING,
92  "load_plugins is not empty, but load_plugin is not set to 'none'."
93  "The load_plugin value will be ignored.\n");
94  } else {
96 
98  s->qsv.load_plugins = av_strdup(uid_hevcdec_sw);
99  else
100  s->qsv.load_plugins = av_strdup(uid_hevcdec_hw);
101  if (!s->qsv.load_plugins)
102  return AVERROR(ENOMEM);
103  }
104  }
105 
106  s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
107  if (!s->packet_fifo) {
108  ret = AVERROR(ENOMEM);
109  goto fail;
110  }
111 
112  return 0;
113 fail:
114  qsv_decode_close(avctx);
115  return ret;
116 }
117 
118 static int qsv_decode_frame(AVCodecContext *avctx, void *data,
119  int *got_frame, AVPacket *avpkt)
120 {
121  QSVH2645Context *s = avctx->priv_data;
122  AVFrame *frame = data;
123  int ret;
124 
125  /* buffer the input packet */
126  if (avpkt->size) {
127  AVPacket input_ref = { 0 };
128 
129  if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
130  ret = av_fifo_realloc2(s->packet_fifo,
131  av_fifo_size(s->packet_fifo) + sizeof(input_ref));
132  if (ret < 0)
133  return ret;
134  }
135 
136  ret = av_packet_ref(&input_ref, avpkt);
137  if (ret < 0)
138  return ret;
139  av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
140  }
141 
142  /* process buffered data */
143  while (!*got_frame) {
144  /* prepare the input data */
145  if (s->buffer_pkt.size <= 0) {
146  /* no more data */
147  if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
148  return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
149  /* in progress of reinit, no read from fifo and keep the buffer_pkt */
150  if (!s->qsv.reinit_flag) {
153  }
154  }
155 
156  ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt);
157  if (ret < 0){
158  /* Drop buffer_pkt when failed to decode the packet. Otherwise,
159  the decoder will keep decoding the failure packet. */
161  return ret;
162  }
163  if (s->qsv.reinit_flag)
164  continue;
165 
166  s->buffer_pkt.size -= ret;
167  s->buffer_pkt.data += ret;
168  }
169 
170  return avpkt->size;
171 }
172 
173 static void qsv_decode_flush(AVCodecContext *avctx)
174 {
175  QSVH2645Context *s = avctx->priv_data;
176 
178  ff_qsv_decode_flush(avctx, &s->qsv);
179 }
180 
181 #define OFFSET(x) offsetof(QSVH2645Context, x)
182 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
183 
184 #if CONFIG_HEVC_QSV_DECODER
185 static const AVOption hevc_options[] = {
186  { "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 },
187 
188  { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" },
189  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" },
190  { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
191  { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" },
192 
193  { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
194  OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
195  { NULL },
196 };
197 
198 static const AVClass hevc_class = {
199  .class_name = "hevc_qsv",
200  .item_name = av_default_item_name,
201  .option = hevc_options,
202  .version = LIBAVUTIL_VERSION_INT,
203 };
204 
206  .name = "hevc_qsv",
207  .long_name = NULL_IF_CONFIG_SMALL("HEVC (Intel Quick Sync Video acceleration)"),
208  .priv_data_size = sizeof(QSVH2645Context),
210  .id = AV_CODEC_ID_HEVC,
214  .close = qsv_decode_close,
216  .priv_class = &hevc_class,
217  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
220  AV_PIX_FMT_NONE },
221  .hw_configs = ff_qsv_hw_configs,
222  .bsfs = "hevc_mp4toannexb",
223  .wrapper_name = "qsv",
224 };
225 #endif
226 
227 #if CONFIG_H264_QSV_DECODER
228 static const AVOption options[] = {
229  { "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 },
230  { NULL },
231 };
232 
233 static const AVClass class = {
234  .class_name = "h264_qsv",
235  .item_name = av_default_item_name,
236  .option = options,
237  .version = LIBAVUTIL_VERSION_INT,
238 };
239 
241  .name = "h264_qsv",
242  .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
243  .priv_data_size = sizeof(QSVH2645Context),
245  .id = AV_CODEC_ID_H264,
249  .close = qsv_decode_close,
251  .priv_class = &class,
252  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
255  AV_PIX_FMT_NONE },
256  .hw_configs = ff_qsv_hw_configs,
257  .bsfs = "h264_mp4toannexb",
258  .wrapper_name = "qsv",
259 };
260 #endif
#define NULL
Definition: coverity.c:32
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void flush(AVCodecContext *avctx)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1478
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
GLint GLenum type
Definition: opengl_enc.c:104
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:68
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3477
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
AVPacket buffer_pkt
Definition: qsvdec_h2645.c:54
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
#define AV_PIX_FMT_P010
Definition: pixfmt.h:436
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
#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
#define av_cold
Definition: attributes.h:82
AVOptions.
int ff_qsv_decode_close(QSVContext *q)
Definition: qsvdec.c:485
static const AVOption hevc_options[]
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
uint8_t * data
Definition: avcodec.h:1477
#define VD
Definition: qsvdec_h2645.c:182
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
#define av_log(a,...)
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
AVFifoBuffer * packet_fifo
Definition: qsvdec_h2645.c:52
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
int reinit_flag
Definition: qsvdec.h:57
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
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
const char * name
Name of the codec implementation.
Definition: avcodec.h:3484
#define fail()
Definition: checkasm.h:120
void ff_qsv_decode_flush(AVCodecContext *avctx, QSVContext *q)
Definition: qsvdec.c:622
#define ASYNC_DEPTH_DEFAULT
Definition: qsv_internal.h:33
static void qsv_decode_flush(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:173
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
#define s(width, name)
Definition: cbs_vp9.c:257
#define OFFSET(x)
Definition: qsvdec_h2645.c:181
QSVContext qsv
Definition: qsvdec_h2645.c:48
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
Libavcodec external API header.
enum AVCodecID codec_id
Definition: avcodec.h:1575
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
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:87
main external API structure.
Definition: avcodec.h:1565
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
a very simple circular buffer FIFO implementation
#define AV_CODEC_CAP_HYBRID
Codec is potentially backed by a hardware implementation, but not necessarily.
Definition: avcodec.h:1085
Describe the class of an AVClass context structure.
Definition: log.h:67
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: qsvdec_h2645.c:118
char * load_plugins
Definition: qsvdec.h:70
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:81
const OptionDef options[]
Definition: ffmpeg_opt.c:3362
common internal api header.
common internal and external API header
AVCodec ff_h264_qsv_decoder
void * priv_data
Definition: avcodec.h:1592
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
#define AV_CODEC_CAP_AVOID_PROBING
Decoder is not a preferred choice for probing.
Definition: avcodec.h:1063
AVCodec ff_hevc_qsv_decoder
#define av_freep(p)
const AVCodecHWConfigInternal * ff_qsv_hw_configs[]
Definition: qsvdec.c:44
int async_depth
Definition: qsvdec.h:67
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
int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: qsvdec.c:524
static void qsv_clear_buffers(QSVH2645Context *s)
Definition: qsvdec_h2645.c:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1454
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
LoadPlugin
Definition: qsvdec_h2645.c:40