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 "qsvdec.h"
37 
38 enum LoadPlugin {
41 };
42 
43 typedef struct QSVH2645Context {
44  AVClass *class;
46 
48 
49  // the filter for converting to Annex B
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 
65  av_bsf_free(&s->bsf);
66 
68 }
69 
71 {
72  QSVH2645Context *s = avctx->priv_data;
73 
75 
77 
79 
80  return 0;
81 }
82 
84 {
85  QSVH2645Context *s = avctx->priv_data;
86  int ret;
87 
88  if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
89  static const char *uid_hevcenc_sw = "15dd936825ad475ea34e35f3f54217a6";
90 
91  if (s->qsv.load_plugins[0]) {
92  av_log(avctx, AV_LOG_WARNING,
93  "load_plugins is not empty, but load_plugin is not set to 'none'."
94  "The load_plugin value will be ignored.\n");
95  } else {
97  s->qsv.load_plugins = av_strdup(uid_hevcenc_sw);
98  if (!s->qsv.load_plugins)
99  return AVERROR(ENOMEM);
100  }
101  }
102  s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
103  if (!s->packet_fifo) {
104  ret = AVERROR(ENOMEM);
105  goto fail;
106  }
107 
108  if (avctx->codec_id == AV_CODEC_ID_H264) {
109  //regarding ticks_per_frame description, should be 2 for h.264:
110  avctx->ticks_per_frame = 2;
111  }
112 
113  return 0;
114 fail:
115  qsv_decode_close(avctx);
116  return ret;
117 }
118 
120 {
121  const char *filter_name = avctx->codec_id == AV_CODEC_ID_HEVC ?
122  "hevc_mp4toannexb" : "h264_mp4toannexb";
123  const AVBitStreamFilter *filter;
124  int ret;
125 
126  if (s->bsf)
127  return 0;
128 
129  filter = av_bsf_get_by_name(filter_name);
130  if (!filter)
131  return AVERROR_BUG;
132 
133  ret = av_bsf_alloc(filter, &s->bsf);
134  if (ret < 0)
135  return ret;
136 
137  ret = avcodec_parameters_from_context(s->bsf->par_in, avctx);
138  if (ret < 0)
139  return ret;
140 
141  s->bsf->time_base_in = avctx->time_base;
142 
143  ret = av_bsf_init(s->bsf);
144  if (ret < 0)
145  return ret;
146 
147  return ret;
148 }
149 
150 static int qsv_decode_frame(AVCodecContext *avctx, void *data,
151  int *got_frame, AVPacket *avpkt)
152 {
153  QSVH2645Context *s = avctx->priv_data;
154  AVFrame *frame = data;
155  int ret;
156 
157  /* make sure the bitstream filter is initialized */
158  ret = qsv_init_bsf(avctx, s);
159  if (ret < 0)
160  return ret;
161 
162  /* buffer the input packet */
163  if (avpkt->size) {
164  AVPacket input_ref = { 0 };
165 
166  if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
167  ret = av_fifo_realloc2(s->packet_fifo,
168  av_fifo_size(s->packet_fifo) + sizeof(input_ref));
169  if (ret < 0)
170  return ret;
171  }
172 
173  ret = av_packet_ref(&input_ref, avpkt);
174  if (ret < 0)
175  return ret;
176  av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
177  }
178 
179  /* process buffered data */
180  while (!*got_frame) {
181  /* prepare the input data -- convert to Annex B if needed */
182  if (s->pkt_filtered.size <= 0) {
183  AVPacket input_ref;
184 
185  /* no more data */
186  if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
187  return avpkt->size ? avpkt->size : ff_qsv_decode(avctx, &s->qsv, frame, got_frame, avpkt);
188 
190 
191  av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
192  ret = av_bsf_send_packet(s->bsf, &input_ref);
193  if (ret < 0) {
194  av_packet_unref(&input_ref);
195  return ret;
196  }
197 
198  ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered);
199  if (ret < 0)
200  av_packet_move_ref(&s->pkt_filtered, &input_ref);
201  else
202  av_packet_unref(&input_ref);
203  }
204 
205  ret = ff_qsv_decode(avctx, &s->qsv, frame, got_frame, &s->pkt_filtered);
206  if (ret < 0)
207  return ret;
208 
209  s->pkt_filtered.size -= ret;
210  s->pkt_filtered.data += ret;
211  }
212 
213  return avpkt->size;
214 }
215 
216 static void qsv_decode_flush(AVCodecContext *avctx)
217 {
218  QSVH2645Context *s = avctx->priv_data;
219  ff_qsv_decode_reset(avctx, &s->qsv);
220 }
221 
222 #define OFFSET(x) offsetof(QSVH2645Context, x)
223 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
224 
225 #if CONFIG_HEVC_QSV_DECODER
226 AVHWAccel ff_hevc_qsv_hwaccel = {
227  .name = "hevc_qsv",
228  .type = AVMEDIA_TYPE_VIDEO,
229  .id = AV_CODEC_ID_HEVC,
230  .pix_fmt = AV_PIX_FMT_QSV,
231 };
232 
233 static const AVOption hevc_options[] = {
234  { "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 },
235 
236  { "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_SW, VD, "load_plugin" },
237  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" },
238  { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
239 
240  { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
241  OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
242  { NULL },
243 };
244 
245 static const AVClass hevc_class = {
246  .class_name = "hevc_qsv",
247  .item_name = av_default_item_name,
248  .option = hevc_options,
249  .version = LIBAVUTIL_VERSION_INT,
250 };
251 
252 AVCodec ff_hevc_qsv_decoder = {
253  .name = "hevc_qsv",
254  .long_name = NULL_IF_CONFIG_SMALL("HEVC (Intel Quick Sync Video acceleration)"),
255  .priv_data_size = sizeof(QSVH2645Context),
257  .id = AV_CODEC_ID_HEVC,
261  .close = qsv_decode_close,
262  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
263  .priv_class = &hevc_class,
264  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
266  AV_PIX_FMT_NONE },
267 };
268 #endif
269 
270 #if CONFIG_H264_QSV_DECODER
271 AVHWAccel ff_h264_qsv_hwaccel = {
272  .name = "h264_qsv",
273  .type = AVMEDIA_TYPE_VIDEO,
274  .id = AV_CODEC_ID_H264,
275  .pix_fmt = AV_PIX_FMT_QSV,
276 };
277 
278 static const AVOption options[] = {
279  { "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 },
280  { NULL },
281 };
282 
283 static const AVClass class = {
284  .class_name = "h264_qsv",
285  .item_name = av_default_item_name,
286  .option = options,
287  .version = LIBAVUTIL_VERSION_INT,
288 };
289 
290 AVCodec ff_h264_qsv_decoder = {
291  .name = "h264_qsv",
292  .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
293  .priv_data_size = sizeof(QSVH2645Context),
295  .id = AV_CODEC_ID_H264,
299  .close = qsv_decode_close,
300  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
301  .priv_class = &class,
302  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
304  AV_PIX_FMT_NONE },
305 };
306 #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:54
const char * s
Definition: avisynth_c.h:768
int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: qsvdec.c:491
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
AVOption.
Definition: opt.h:245
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:5731
int size
Definition: avcodec.h:1602
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:70
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3600
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:1813
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:82
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:984
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:199
void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
Definition: qsvdec.c:547
#define av_cold
Definition: attributes.h:82
AVOptions.
int ff_qsv_decode_close(QSVContext *q)
Definition: qsvdec.c:592
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:1601
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:622
#define VD
Definition: qsvdec_h2645.c:223
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
const OptionDef options[]
Definition: ffserver.c:3969
AVBSFContext * bsf
Definition: qsvdec_h2645.c:50
#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:576
AVFifoBuffer * packet_fifo
Definition: qsvdec_h2645.c:52
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:176
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:5768
const char * name
Name of the codec implementation.
Definition: avcodec.h:3607
#define fail()
Definition: checkasm.h:83
#define ASYNC_DEPTH_DEFAULT
Definition: qsv_internal.h:48
static int qsv_init_bsf(AVCodecContext *avctx, QSVH2645Context *s)
Definition: qsvdec_h2645.c:119
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3726
static void qsv_decode_flush(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:216
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:222
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:1822
QSVContext qsv
Definition: qsvdec_h2645.c:45
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:267
Libavcodec external API header.
enum AVCodecID codec_id
Definition: avcodec.h:1693
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:1676
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:567
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:4166
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:150
char * load_plugins
Definition: qsvdec.h:73
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition: qsvdec_h2645.c:83
common internal api header.
common internal and external API header
void * priv_data
Definition: avcodec.h:1718
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
#define av_freep(p)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2035
static void qsv_clear_buffers(QSVH2645Context *s)
Definition: qsvdec_h2645.c:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1578
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5757
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:959
LoadPlugin
Definition: qsvdec_h2645.c:38