FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 
52  // the filter for converting to Annex B
54 
56 
59 
61 {
62  AVPacket pkt;
63  while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
64  av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
65  av_packet_unref(&pkt);
66  }
67 
68  av_bsf_free(&s->bsf);
69 
71 }
72 
74 {
75  QSVH2645Context *s = avctx->priv_data;
76 
78 
80 
82 
83  return 0;
84 }
85 
87 {
88  QSVH2645Context *s = avctx->priv_data;
89  int ret;
90 
91  if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
92  static const char *uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
93  static const char *uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
94 
95  if (s->qsv.load_plugins[0]) {
96  av_log(avctx, AV_LOG_WARNING,
97  "load_plugins is not empty, but load_plugin is not set to 'none'."
98  "The load_plugin value will be ignored.\n");
99  } else {
101 
103  s->qsv.load_plugins = av_strdup(uid_hevcdec_sw);
104  else
105  s->qsv.load_plugins = av_strdup(uid_hevcdec_hw);
106  if (!s->qsv.load_plugins)
107  return AVERROR(ENOMEM);
108  }
109  }
110 
111  s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
112  if (!s->packet_fifo) {
113  ret = AVERROR(ENOMEM);
114  goto fail;
115  }
116 
117  return 0;
118 fail:
119  qsv_decode_close(avctx);
120  return ret;
121 }
122 
124 {
125  const char *filter_name = avctx->codec_id == AV_CODEC_ID_HEVC ?
126  "hevc_mp4toannexb" : "h264_mp4toannexb";
127  const AVBitStreamFilter *filter;
128  int ret;
129 
130  if (s->bsf)
131  return 0;
132 
133  filter = av_bsf_get_by_name(filter_name);
134  if (!filter)
135  return AVERROR_BUG;
136 
137  ret = av_bsf_alloc(filter, &s->bsf);
138  if (ret < 0)
139  return ret;
140 
141  ret = avcodec_parameters_from_context(s->bsf->par_in, avctx);
142  if (ret < 0)
143  return ret;
144 
145  s->bsf->time_base_in = avctx->time_base;
146 
147  ret = av_bsf_init(s->bsf);
148  if (ret < 0)
149  return ret;
150 
151  return ret;
152 }
153 
154 static int qsv_decode_frame(AVCodecContext *avctx, void *data,
155  int *got_frame, AVPacket *avpkt)
156 {
157  QSVH2645Context *s = avctx->priv_data;
158  AVFrame *frame = data;
159  int ret;
160 
161  /* make sure the bitstream filter is initialized */
162  ret = qsv_init_bsf(avctx, s);
163  if (ret < 0)
164  return ret;
165 
166  /* buffer the input packet */
167  if (avpkt->size) {
168  AVPacket input_ref = { 0 };
169 
170  if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
171  ret = av_fifo_realloc2(s->packet_fifo,
172  av_fifo_size(s->packet_fifo) + sizeof(input_ref));
173  if (ret < 0)
174  return ret;
175  }
176 
177  ret = av_packet_ref(&input_ref, avpkt);
178  if (ret < 0)
179  return ret;
180  av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
181  }
182 
183  /* process buffered data */
184  while (!*got_frame) {
185  /* prepare the input data -- convert to Annex B if needed */
186  if (s->pkt_filtered.size <= 0) {
187  AVPacket input_ref;
188 
189  /* no more data */
190  if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
191  return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
192 
194 
195  av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
196  ret = av_bsf_send_packet(s->bsf, &input_ref);
197  if (ret < 0) {
198  av_packet_unref(&input_ref);
199  return ret;
200  }
201 
202  ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered);
203  if (ret < 0)
204  av_packet_move_ref(&s->pkt_filtered, &input_ref);
205  else
206  av_packet_unref(&input_ref);
207  }
208 
209  ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->pkt_filtered);
210  if (ret < 0)
211  return ret;
212 
213  s->pkt_filtered.size -= ret;
214  s->pkt_filtered.data += ret;
215  }
216 
217  return avpkt->size;
218 }
219 
220 static void qsv_decode_flush(AVCodecContext *avctx)
221 {
222  QSVH2645Context *s = avctx->priv_data;
223 
225  ff_qsv_decode_flush(avctx, &s->qsv);
226 }
227 
228 #define OFFSET(x) offsetof(QSVH2645Context, x)
229 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
230 
231 #if CONFIG_HEVC_QSV_DECODER
232 AVHWAccel ff_hevc_qsv_hwaccel = {
233  .name = "hevc_qsv",
234  .type = AVMEDIA_TYPE_VIDEO,
235  .id = AV_CODEC_ID_HEVC,
236  .pix_fmt = AV_PIX_FMT_QSV,
237 };
238 
239 static const AVOption hevc_options[] = {
240  { "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 }, 0, INT_MAX, VD },
241 
242  { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_SW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" },
243  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" },
244  { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
245  { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" },
246 
247  { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
248  OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
249  { NULL },
250 };
251 
252 static const AVClass hevc_class = {
253  .class_name = "hevc_qsv",
254  .item_name = av_default_item_name,
255  .option = hevc_options,
256  .version = LIBAVUTIL_VERSION_INT,
257 };
258 
259 AVCodec ff_hevc_qsv_decoder = {
260  .name = "hevc_qsv",
261  .long_name = NULL_IF_CONFIG_SMALL("HEVC (Intel Quick Sync Video acceleration)"),
262  .priv_data_size = sizeof(QSVH2645Context),
264  .id = AV_CODEC_ID_HEVC,
268  .close = qsv_decode_close,
270  .priv_class = &hevc_class,
271  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
274  AV_PIX_FMT_NONE },
275 };
276 #endif
277 
278 #if CONFIG_H264_QSV_DECODER
279 AVHWAccel ff_h264_qsv_hwaccel = {
280  .name = "h264_qsv",
281  .type = AVMEDIA_TYPE_VIDEO,
282  .id = AV_CODEC_ID_H264,
283  .pix_fmt = AV_PIX_FMT_QSV,
284 };
285 
286 static const AVOption options[] = {
287  { "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 }, 0, INT_MAX, VD },
288  { NULL },
289 };
290 
291 static const AVClass class = {
292  .class_name = "h264_qsv",
293  .item_name = av_default_item_name,
294  .option = options,
295  .version = LIBAVUTIL_VERSION_INT,
296 };
297 
298 AVCodec ff_h264_qsv_decoder = {
299  .name = "h264_qsv",
300  .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
301  .priv_data_size = sizeof(QSVH2645Context),
303  .id = AV_CODEC_ID_H264,
307  .close = qsv_decode_close,
309  .priv_class = &class,
310  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
313  AV_PIX_FMT_NONE },
314 };
315 #endif
void av_bsf_free(AVBSFContext **ctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition: bsf.c:36
#define NULL
Definition: coverity.c:32
AVPacket pkt_filtered
Definition: qsvdec_h2645.c:57
const char * s
Definition: avisynth_c.h:768
This structure describes decoded (raw) audio or video data.
Definition: frame.h:187
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
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
The bitstream filter state.
Definition: avcodec.h:5830
int size
Definition: avcodec.h:1658
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:73
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3681
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:135
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
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1869
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:82
#define AV_PIX_FMT_P010
Definition: pixfmt.h:394
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:1019
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:199
#define av_cold
Definition: attributes.h:82
AVOptions.
int ff_qsv_decode_close(QSVContext *q)
Definition: qsvdec.c:406
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
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, uint8_t clip)
Definition: cfhd.c:80
static AVFrame * frame
uint8_t * data
Definition: avcodec.h:1657
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:644
#define VD
Definition: qsvdec_h2645.c:229
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
const OptionDef options[]
Definition: ffserver.c:3948
AVBSFContext * bsf
Definition: qsvdec_h2645.c:53
#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:598
AVFifoBuffer * packet_fifo
Definition: qsvdec_h2645.c:55
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:179
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:90
AVRational time_base_in
The timebase used for the timestamps of the input packets.
Definition: avcodec.h:5870
const char * name
Name of the codec implementation.
Definition: avcodec.h:3688
#define fail()
Definition: checkasm.h:89
void ff_qsv_decode_flush(AVCodecContext *avctx, QSVContext *q)
Definition: qsvdec.c:521
#define ASYNC_DEPTH_DEFAULT
Definition: qsv_internal.h:33
static int qsv_init_bsf(AVCodecContext *avctx, QSVH2645Context *s)
Definition: qsvdec_h2645.c:123
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3807
static void qsv_decode_flush(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:220
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:176
#define OFFSET(x)
Definition: qsvdec_h2645.c:228
QSVContext qsv
Definition: qsvdec_h2645.c:48
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:237
Libavcodec external API header.
enum AVCodecID codec_id
Definition: avcodec.h:1749
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:1732
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:589
a very simple circular buffer FIFO implementation
GLint GLenum type
Definition: opengl_enc.c:105
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context.
Definition: utils.c:4207
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:236
static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: qsvdec_h2645.c:154
char * load_plugins
Definition: qsvdec.h:67
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:86
common internal api header.
common internal and external API header
void * priv_data
Definition: avcodec.h:1774
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:1083
#define av_freep(p)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2257
int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: qsvdec.c:445
static void qsv_clear_buffers(QSVH2645Context *s)
Definition: qsvdec_h2645.c:60
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1634
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5858
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:994
LoadPlugin
Definition: qsvdec_h2645.c:40