FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwcontext.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "config.h"
20 
21 #include "buffer.h"
22 #include "common.h"
23 #include "hwcontext.h"
24 #include "hwcontext_internal.h"
25 #include "imgutils.h"
26 #include "log.h"
27 #include "mem.h"
28 #include "pixdesc.h"
29 #include "pixfmt.h"
30 
31 static const HWContextType *hw_table[] = {
32 #if CONFIG_CUDA
34 #endif
35 #if CONFIG_DXVA2
37 #endif
38 #if CONFIG_QSV
40 #endif
41 #if CONFIG_VAAPI
43 #endif
44 #if CONFIG_VDPAU
46 #endif
47  NULL,
48 };
49 
50 static const AVClass hwdevice_ctx_class = {
51  .class_name = "AVHWDeviceContext",
52  .item_name = av_default_item_name,
53  .version = LIBAVUTIL_VERSION_INT,
54 };
55 
56 static void hwdevice_ctx_free(void *opaque, uint8_t *data)
57 {
59 
60  /* uninit might still want access the hw context and the user
61  * free() callback might destroy it, so uninit has to be called first */
62  if (ctx->internal->hw_type->device_uninit)
63  ctx->internal->hw_type->device_uninit(ctx);
64 
65  if (ctx->free)
66  ctx->free(ctx);
67 
68  av_freep(&ctx->hwctx);
69  av_freep(&ctx->internal->priv);
70  av_freep(&ctx->internal);
71  av_freep(&ctx);
72 }
73 
75 {
78  const HWContextType *hw_type = NULL;
79  int i;
80 
81  for (i = 0; hw_table[i]; i++) {
82  if (hw_table[i]->type == type) {
83  hw_type = hw_table[i];
84  break;
85  }
86  }
87  if (!hw_type)
88  return NULL;
89 
90  ctx = av_mallocz(sizeof(*ctx));
91  if (!ctx)
92  return NULL;
93 
94  ctx->internal = av_mallocz(sizeof(*ctx->internal));
95  if (!ctx->internal)
96  goto fail;
97 
98  if (hw_type->device_priv_size) {
99  ctx->internal->priv = av_mallocz(hw_type->device_priv_size);
100  if (!ctx->internal->priv)
101  goto fail;
102  }
103 
104  if (hw_type->device_hwctx_size) {
105  ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
106  if (!ctx->hwctx)
107  goto fail;
108  }
109 
110  buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
113  if (!buf)
114  goto fail;
115 
116  ctx->type = type;
118 
119  ctx->internal->hw_type = hw_type;
120 
121  return buf;
122 
123 fail:
124  if (ctx->internal)
125  av_freep(&ctx->internal->priv);
126  av_freep(&ctx->internal);
127  av_freep(&ctx->hwctx);
128  av_freep(&ctx);
129  return NULL;
130 }
131 
133 {
135  int ret;
136 
137  if (ctx->internal->hw_type->device_init) {
138  ret = ctx->internal->hw_type->device_init(ctx);
139  if (ret < 0)
140  goto fail;
141  }
142 
143  return 0;
144 fail:
145  if (ctx->internal->hw_type->device_uninit)
146  ctx->internal->hw_type->device_uninit(ctx);
147  return ret;
148 }
149 
150 static const AVClass hwframe_ctx_class = {
151  .class_name = "AVHWFramesContext",
152  .item_name = av_default_item_name,
153  .version = LIBAVUTIL_VERSION_INT,
154 };
155 
156 static void hwframe_ctx_free(void *opaque, uint8_t *data)
157 {
159 
160  if (ctx->internal->pool_internal)
162 
163  if (ctx->internal->hw_type->frames_uninit)
164  ctx->internal->hw_type->frames_uninit(ctx);
165 
166  if (ctx->free)
167  ctx->free(ctx);
168 
170 
171  av_freep(&ctx->hwctx);
172  av_freep(&ctx->internal->priv);
173  av_freep(&ctx->internal);
174  av_freep(&ctx);
175 }
176 
178 {
179  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
180  const HWContextType *hw_type = device_ctx->internal->hw_type;
182  AVBufferRef *buf, *device_ref = NULL;
183 
184  ctx = av_mallocz(sizeof(*ctx));
185  if (!ctx)
186  return NULL;
187 
188  ctx->internal = av_mallocz(sizeof(*ctx->internal));
189  if (!ctx->internal)
190  goto fail;
191 
192  if (hw_type->frames_priv_size) {
193  ctx->internal->priv = av_mallocz(hw_type->frames_priv_size);
194  if (!ctx->internal->priv)
195  goto fail;
196  }
197 
198  if (hw_type->frames_hwctx_size) {
199  ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
200  if (!ctx->hwctx)
201  goto fail;
202  }
203 
204  device_ref = av_buffer_ref(device_ref_in);
205  if (!device_ref)
206  goto fail;
207 
208  buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
211  if (!buf)
212  goto fail;
213 
215  ctx->device_ref = device_ref;
216  ctx->device_ctx = device_ctx;
217  ctx->format = AV_PIX_FMT_NONE;
218  ctx->sw_format = AV_PIX_FMT_NONE;
219 
220  ctx->internal->hw_type = hw_type;
221 
222  return buf;
223 
224 fail:
225  if (device_ref)
226  av_buffer_unref(&device_ref);
227  if (ctx->internal)
228  av_freep(&ctx->internal->priv);
229  av_freep(&ctx->internal);
230  av_freep(&ctx->hwctx);
231  av_freep(&ctx);
232  return NULL;
233 }
234 
236 {
238  AVFrame **frames;
239  int i, ret = 0;
240 
242  if (!frames)
243  return AVERROR(ENOMEM);
244 
245  for (i = 0; i < ctx->initial_pool_size; i++) {
246  frames[i] = av_frame_alloc();
247  if (!frames[i])
248  goto fail;
249 
250  ret = av_hwframe_get_buffer(ref, frames[i], 0);
251  if (ret < 0)
252  goto fail;
253  }
254 
255 fail:
256  for (i = 0; i < ctx->initial_pool_size; i++)
257  av_frame_free(&frames[i]);
258  av_freep(&frames);
259 
260  return ret;
261 }
262 
264 {
266  const enum AVPixelFormat *pix_fmt;
267  int ret;
268 
269  /* validate the pixel format */
271  if (*pix_fmt == ctx->format)
272  break;
273  }
274  if (*pix_fmt == AV_PIX_FMT_NONE) {
275  av_log(ctx, AV_LOG_ERROR,
276  "The hardware pixel format '%s' is not supported by the device type '%s'\n",
278  return AVERROR(ENOSYS);
279  }
280 
281  /* validate the dimensions */
282  ret = av_image_check_size(ctx->width, ctx->height, 0, ctx);
283  if (ret < 0)
284  return ret;
285 
286  /* format-specific init */
287  if (ctx->internal->hw_type->frames_init) {
288  ret = ctx->internal->hw_type->frames_init(ctx);
289  if (ret < 0)
290  goto fail;
291  }
292 
293  if (ctx->internal->pool_internal && !ctx->pool)
294  ctx->pool = ctx->internal->pool_internal;
295 
296  /* preallocate the frames in the pool, if requested */
297  if (ctx->initial_pool_size > 0) {
298  ret = hwframe_pool_prealloc(ref);
299  if (ret < 0)
300  goto fail;
301  }
302 
303  return 0;
304 fail:
305  if (ctx->internal->hw_type->frames_uninit)
306  ctx->internal->hw_type->frames_uninit(ctx);
307  return ret;
308 }
309 
312  enum AVPixelFormat **formats, int flags)
313 {
314  AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
315 
317  return AVERROR(ENOSYS);
318 
319  return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
320 }
321 
322 static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
323 {
324  AVFrame *frame_tmp;
325  int ret = 0;
326 
327  frame_tmp = av_frame_alloc();
328  if (!frame_tmp)
329  return AVERROR(ENOMEM);
330 
331  /* if the format is set, use that
332  * otherwise pick the first supported one */
333  if (dst->format >= 0) {
334  frame_tmp->format = dst->format;
335  } else {
336  enum AVPixelFormat *formats;
337 
340  &formats, 0);
341  if (ret < 0)
342  goto fail;
343  frame_tmp->format = formats[0];
344  av_freep(&formats);
345  }
346  frame_tmp->width = src->width;
347  frame_tmp->height = src->height;
348 
349  ret = av_frame_get_buffer(frame_tmp, 32);
350  if (ret < 0)
351  goto fail;
352 
353  ret = av_hwframe_transfer_data(frame_tmp, src, flags);
354  if (ret < 0)
355  goto fail;
356 
357  av_frame_move_ref(dst, frame_tmp);
358 
359 fail:
360  av_frame_free(&frame_tmp);
361  return ret;
362 }
363 
365 {
367  int ret;
368 
369  if (!dst->buf[0])
370  return transfer_data_alloc(dst, src, flags);
371 
372  if (src->hw_frames_ctx) {
373  ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
374 
375  ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
376  if (ret < 0)
377  return ret;
378  } else if (dst->hw_frames_ctx) {
379  ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
380 
381  ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
382  if (ret < 0)
383  return ret;
384  } else
385  return AVERROR(ENOSYS);
386 
387  return 0;
388 }
389 
391 {
392  AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
393  int ret;
394 
396  return AVERROR(ENOSYS);
397 
398  if (!ctx->pool)
399  return AVERROR(EINVAL);
400 
401  frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
402  if (!frame->hw_frames_ctx)
403  return AVERROR(ENOMEM);
404 
405  ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
406  if (ret < 0) {
408  return ret;
409  }
410 
411  return 0;
412 }
413 
415 {
417  const HWContextType *hw_type = ctx->internal->hw_type;
418 
419  if (hw_type->device_hwconfig_size == 0)
420  return NULL;
421 
422  return av_mallocz(hw_type->device_hwconfig_size);
423 }
424 
426  const void *hwconfig)
427 {
429  const HWContextType *hw_type = ctx->internal->hw_type;
430  AVHWFramesConstraints *constraints;
431 
432  if (!hw_type->frames_get_constraints)
433  return NULL;
434 
435  constraints = av_mallocz(sizeof(*constraints));
436  if (!constraints)
437  return NULL;
438 
439  constraints->min_width = constraints->min_height = 0;
440  constraints->max_width = constraints->max_height = INT_MAX;
441 
442  if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) {
443  return constraints;
444  } else {
445  av_hwframe_constraints_free(&constraints);
446  return NULL;
447  }
448 }
449 
451 {
452  if (*constraints) {
453  av_freep(&(*constraints)->valid_hw_formats);
454  av_freep(&(*constraints)->valid_sw_formats);
455  }
456  av_freep(constraints);
457 }
458 
460  const char *device, AVDictionary *opts, int flags)
461 {
462  AVBufferRef *device_ref = NULL;
463  AVHWDeviceContext *device_ctx;
464  int ret = 0;
465 
466  device_ref = av_hwdevice_ctx_alloc(type);
467  if (!device_ref) {
468  ret = AVERROR(ENOMEM);
469  goto fail;
470  }
471  device_ctx = (AVHWDeviceContext*)device_ref->data;
472 
473  if (!device_ctx->internal->hw_type->device_create) {
474  ret = AVERROR(ENOSYS);
475  goto fail;
476  }
477 
478  ret = device_ctx->internal->hw_type->device_create(device_ctx, device,
479  opts, flags);
480  if (ret < 0)
481  goto fail;
482 
483  ret = av_hwdevice_ctx_init(device_ref);
484  if (ret < 0)
485  goto fail;
486 
487  *pdevice_ref = device_ref;
488  return 0;
489 fail:
490  av_buffer_unref(&device_ref);
491  *pdevice_ref = NULL;
492  return ret;
493 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:54
#define NULL
Definition: coverity.c:32
static enum AVPixelFormat pix_fmt
static void hwdevice_ctx_free(void *opaque, uint8_t *data)
Definition: hwcontext.c:56
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
Definition: buffer.c:124
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
misc image utilities
void(* frames_uninit)(AVHWFramesContext *ctx)
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Memory handling functions.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:367
const HWContextType ff_hwcontext_type_vdpau
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1767
static enum AVSampleFormat formats[]
Definition: avresample.c:163
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:222
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:414
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:202
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:517
size_t device_priv_size
size of the private data, i.e.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:252
const HWContextType * hw_type
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:450
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:534
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
AVBufferPool * pool_internal
uint8_t
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:145
static int hwframe_pool_prealloc(AVBufferRef *ref)
Definition: hwcontext.c:235
size_t device_hwctx_size
size of the public hardware-specific context, i.e.
static AVFrame * frame
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
const HWContextType ff_hwcontext_type_qsv
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition: hwcontext.c:459
static void hwframe_ctx_free(void *opaque, uint8_t *data)
Definition: hwcontext.c:156
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:113
static const AVClass hwframe_ctx_class
Definition: hwcontext.c:150
#define av_log(a,...)
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
Definition: hwcontext.h:163
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
Definition: hwcontext.h:97
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:158
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:28
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:263
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:72
static void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.h:226
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:390
#define fail()
Definition: checkasm.h:83
void(* device_uninit)(AVHWDeviceContext *ctx)
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition: hwcontext.c:364
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:192
AVDictionary * opts
Definition: movenc.c:50
Transfer the data from the queried hw frame.
Definition: hwcontext.h:332
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:251
enum AVPixelFormat * pix_fmts
An array of pixel formats supported by the AVHWFramesContext instances Terminated by AV_PIX_FMT_NONE...
const char * name
AVFormatContext * ctx
Definition: movenc.c:48
int frames
Definition: movenc.c:65
#define src
Definition: vp9dsp.c:530
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given pixel format.
Definition: hwcontext.c:74
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:366
int(* device_create)(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
const HWContextType ff_hwcontext_type_cuda
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
Definition: hwcontext.c:425
uint8_t * data
The data buffer.
Definition: buffer.h:89
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:155
const AVClass * av_class
A class for logging.
Definition: hwcontext.h:58
void * buf
Definition: avisynth_c.h:690
GLint GLenum type
Definition: opengl_enc.c:105
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:132
Describe the class of an AVClass context structure.
Definition: log.h:67
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:274
int(* frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame)
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:117
const AVClass * av_class
A class for logging and AVOptions.
Definition: avformat.h:1343
refcounted data buffer API
static const HWContextType * hw_table[]
Definition: hwcontext.c:31
static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
Definition: hwcontext.c:322
AVHWFramesInternal * internal
Private data used internally by libavutil.
Definition: hwcontext.h:127
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:275
int(* transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
static int flags
Definition: cpu.c:47
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:134
int(* transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
A reference to a data buffer.
Definition: buffer.h:81
const HWContextType * hw_type
common internal and external API header
if(ret< 0)
Definition: vf_mcdeint.c:282
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:177
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:92
AVHWFrameTransferDirection
Definition: hwcontext.h:328
pixel format definitions
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:183
AVHWDeviceType
Definition: hwcontext.h:27
int(* transfer_get_formats)(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
int height
Definition: frame.h:236
#define av_freep(p)
int(* device_init)(AVHWDeviceContext *ctx)
AVHWDeviceInternal * internal
Private data used internally by libavutil.
Definition: hwcontext.h:64
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2182
static const AVClass hwdevice_ctx_class
Definition: hwcontext.c:50
int(* frames_init)(AVHWFramesContext *ctx)
const HWContextType ff_hwcontext_type_dxva2
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
for(j=16;j >0;--j)
int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats, int flags)
Get a list of possible source or target formats usable in av_hwframe_transfer_data().
Definition: hwcontext.c:310
const HWContextType ff_hwcontext_type_vaapi