History

lavu: add a framework for handling hwaccel frames

Anton Khirnov committed 10 years ago

Commit 89923e41 parent 721a4ef7 files · +834 −0Browse files

Unified · Split

7 files
  1. doc/APIchanges +2 −0
  2. libavutil/Makefile +2 −0
  3. libavutil/frame.c +11 −0
  4. libavutil/frame.h +6 −0
  5. libavutil/hwcontext.c +396 −0
  6. libavutil/hwcontext.h +328 −0
  7. libavutil/hwcontext_internal.h +89 −0
doc/APIchanges+2−0
@@ -15,6 +15,8 @@ API changes, most recent first: · 14 unmodified lines
15 15
162016-xx-xx - lavu 55.6.0162016-xx-xx - lavu 55.6.0
17 xxxxxxx buffer.h - Add av_buffer_pool_init2().17 xxxxxxx buffer.h - Add av_buffer_pool_init2().
18 xxxxxxx hwcontext.h - Add a new installed header hwcontext.h with a new API
19 for handling hwaccel frames.
18 20
192016-xx-xx - xxxxxxx - lavf 57.3.0 - avformat.h212016-xx-xx - xxxxxxx - lavf 57.3.0 - avformat.h
20 Add AVFormatContext.opaque, io_open and io_close, allowing custom IO22 Add AVFormatContext.opaque, io_open and io_close, allowing custom IO
libavutil/Makefile+2−0
@@ -23,6 +23,7 @@ HEADERS = adler32.h \ · 22 unmodified lines
23 file.h \23 file.h \
24 frame.h \24 frame.h \
25 hmac.h \25 hmac.h \
26 hwcontext.h \
26 imgutils.h \27 imgutils.h \
27 intfloat.h \28 intfloat.h \
28 intreadwrite.h \29 intreadwrite.h \
@@ -78,6 +79,7 @@ OBJS = adler32.o \ · 49 unmodified lines
78 float_dsp.o \79 float_dsp.o \
79 frame.o \80 frame.o \
80 hmac.o \81 hmac.o \
82 hwcontext.o \
81 imgutils.o \83 imgutils.o \
82 intmath.o \84 intmath.o \
83 lfg.o \85 lfg.o \
libavutil/frame.c+11−0
@@ -251,6 +251,14 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) · 250 unmodified lines
251 }251 }
252 }252 }
253 253
254 if (src->hw_frames_ctx) {
255 dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
256 if (!dst->hw_frames_ctx) {
257 ret = AVERROR(ENOMEM);
258 goto fail;
259 }
260 }
261
254 /* duplicate extended data */262 /* duplicate extended data */
255 if (src->extended_data != src->data) {263 if (src->extended_data != src->data) {
256 int ch = av_get_channel_layout_nb_channels(src->channel_layout);264 int ch = av_get_channel_layout_nb_channels(src->channel_layout);
@@ -303,6 +311,9 @@ void av_frame_unref(AVFrame *frame) · 46 unmodified lines
303 for (i = 0; i < frame->nb_extended_buf; i++)311 for (i = 0; i < frame->nb_extended_buf; i++)
304 av_buffer_unref(&frame->extended_buf[i]);312 av_buffer_unref(&frame->extended_buf[i]);
305 av_freep(&frame->extended_buf);313 av_freep(&frame->extended_buf);
314
315 av_buffer_unref(&frame->hw_frames_ctx);
316
306 get_frame_defaults(frame);317 get_frame_defaults(frame);
307}318}
308 319
libavutil/frame.h+6−0
@@ -354,6 +354,12 @@ typedef struct AVFrame { · 353 unmodified lines
354 enum AVColorSpace colorspace;354 enum AVColorSpace colorspace;
355 355
356 enum AVChromaLocation chroma_location;356 enum AVChromaLocation chroma_location;
357
358 /**
359 * For hwaccel-format frames, this should be a reference to the
360 * AVHWFramesContext describing the frame.
361 */
362 AVBufferRef *hw_frames_ctx;
357} AVFrame;363} AVFrame;
358 364
359/**365/**
libavutil/hwcontext.c+396−0
@@ -0,0 +1,396 @@
1/*
2 * This file is part of Libav.
3 *
4 * Libav 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 * Libav 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 Libav; 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
31static const HWContextType *hw_table[] = {
32 NULL,
33};
34
35static const AVClass hwdevice_ctx_class = {
36 .class_name = "AVHWDeviceContext",
37 .item_name = av_default_item_name,
38 .version = LIBAVUTIL_VERSION_INT,
39};
40
41static void hwdevice_ctx_free(void *opaque, uint8_t *data)
42{
43 AVHWDeviceContext *ctx = (AVHWDeviceContext*)data;
44
45 /* uninit might still want access the hw context and the user
46 * free() callback might destroy it, so uninit has to be called first */
47 if (ctx->internal->hw_type->device_uninit)
48 ctx->internal->hw_type->device_uninit(ctx);
49
50 if (ctx->free)
51 ctx->free(ctx);
52
53 av_freep(&ctx->hwctx);
54 av_freep(&ctx->internal->priv);
55 av_freep(&ctx->internal);
56 av_freep(&ctx);
57}
58
59AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
60{
61 AVHWDeviceContext *ctx;
62 AVBufferRef *buf;
63 const HWContextType *hw_type = NULL;
64 int i;
65
66 for (i = 0; hw_table[i]; i++) {
67 if (hw_table[i]->type == type) {
68 hw_type = hw_table[i];
69 break;
70 }
71 }
72 if (!hw_type)
73 return NULL;
74
75 ctx = av_mallocz(sizeof(*ctx));
76 if (!ctx)
77 return NULL;
78
79 ctx->internal = av_mallocz(sizeof(*ctx->internal));
80 if (!ctx->internal)
81 goto fail;
82
83 if (hw_type->device_priv_size) {
84 ctx->internal->priv = av_mallocz(hw_type->device_priv_size);
85 if (!ctx->internal->priv)
86 goto fail;
87 }
88
89 if (hw_type->device_hwctx_size) {
90 ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
91 if (!ctx->hwctx)
92 goto fail;
93 }
94
95 buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
96 hwdevice_ctx_free, NULL,
97 AV_BUFFER_FLAG_READONLY);
98 if (!buf)
99 goto fail;
100
101 ctx->type = type;
102 ctx->av_class = &hwdevice_ctx_class;
103
104 ctx->internal->hw_type = hw_type;
105
106 return buf;
107
108fail:
109 if (ctx->internal)
110 av_freep(&ctx->internal->priv);
111 av_freep(&ctx->internal);
112 av_freep(&ctx->hwctx);
113 av_freep(&ctx);
114 return NULL;
115}
116
117int av_hwdevice_ctx_init(AVBufferRef *ref)
118{
119 AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
120 int ret;
121
122 if (ctx->internal->hw_type->device_init) {
123 ret = ctx->internal->hw_type->device_init(ctx);
124 if (ret < 0)
125 goto fail;
126 }
127
128 return 0;
129fail:
130 if (ctx->internal->hw_type->device_uninit)
131 ctx->internal->hw_type->device_uninit(ctx);
132 return ret;
133}
134
135static const AVClass hwframe_ctx_class = {
136 .class_name = "AVHWFramesContext",
137 .item_name = av_default_item_name,
138 .version = LIBAVUTIL_VERSION_INT,
139};
140
141static void hwframe_ctx_free(void *opaque, uint8_t *data)
142{
143 AVHWFramesContext *ctx = (AVHWFramesContext*)data;
144
145 if (ctx->internal->pool_internal)
146 av_buffer_pool_uninit(&ctx->internal->pool_internal);
147
148 if (ctx->internal->hw_type->frames_uninit)
149 ctx->internal->hw_type->frames_uninit(ctx);
150
151 if (ctx->free)
152 ctx->free(ctx);
153
154 av_buffer_unref(&ctx->device_ref);
155
156 av_freep(&ctx->hwctx);
157 av_freep(&ctx->internal->priv);
158 av_freep(&ctx->internal);
159 av_freep(&ctx);
160}
161
162AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
163{
164 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
165 const HWContextType *hw_type = device_ctx->internal->hw_type;
166 AVHWFramesContext *ctx;
167 AVBufferRef *buf, *device_ref = NULL;;
168
169 ctx = av_mallocz(sizeof(*ctx));
170 if (!ctx)
171 return NULL;
172
173 ctx->internal = av_mallocz(sizeof(*ctx->internal));
174 if (!ctx->internal)
175 goto fail;
176
177 if (hw_type->frames_priv_size) {
178 ctx->internal->priv = av_mallocz(hw_type->frames_priv_size);
179 if (!ctx->internal->priv)
180 goto fail;
181 }
182
183 if (hw_type->frames_hwctx_size) {
184 ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
185 if (!ctx->hwctx)
186 goto fail;
187 }
188
189 device_ref = av_buffer_ref(device_ref_in);
190 if (!device_ref)
191 goto fail;
192
193 buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
194 hwframe_ctx_free, NULL,
195 AV_BUFFER_FLAG_READONLY);
196 if (!buf)
197 goto fail;
198
199 ctx->av_class = &hwframe_ctx_class;
200 ctx->device_ref = device_ref;
201 ctx->device_ctx = device_ctx;
202 ctx->format = AV_PIX_FMT_NONE;
203
204 ctx->internal->hw_type = hw_type;
205
206 return buf;
207
208fail:
209 if (device_ref)
210 av_buffer_unref(&device_ref);
211 if (ctx->internal)
212 av_freep(&ctx->internal->priv);
213 av_freep(&ctx->internal);
214 av_freep(&ctx->hwctx);
215 av_freep(&ctx);
216 return NULL;
217}
218
219static int hwframe_pool_prealloc(AVBufferRef *ref)
220{
221 AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
222 AVFrame **frames;
223 int i, ret = 0;
224
225 frames = av_mallocz_array(ctx->initial_pool_size, sizeof(*frames));
226 if (!frames)
227 return AVERROR(ENOMEM);
228
229 for (i = 0; i < ctx->initial_pool_size; i++) {
230 frames[i] = av_frame_alloc();
231 if (!frames[i])
232 goto fail;
233
234 ret = av_hwframe_get_buffer(ref, frames[i], 0);
235 if (ret < 0)
236 goto fail;
237 }
238
239fail:
240 for (i = 0; i < ctx->initial_pool_size; i++)
241 av_frame_free(&frames[i]);
242 av_freep(&frames);
243
244 return ret;
245}
246
247int av_hwframe_ctx_init(AVBufferRef *ref)
248{
249 AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
250 const enum AVPixelFormat *pix_fmt;
251 int ret;
252
253 /* validate the pixel format */
254 for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
255 if (*pix_fmt == ctx->format)
256 break;
257 }
258 if (*pix_fmt == AV_PIX_FMT_NONE) {
259 av_log(ctx, AV_LOG_ERROR,
260 "The hardware pixel format '%s' is not supported by the device type '%s'\n",
261 av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name);
262 return AVERROR(ENOSYS);
263 }
264
265 /* validate the dimensions */
266 ret = av_image_check_size(ctx->width, ctx->height, 0, ctx);
267 if (ret < 0)
268 return ret;
269
270 /* format-specific init */
271 if (ctx->internal->hw_type->frames_init) {
272 ret = ctx->internal->hw_type->frames_init(ctx);
273 if (ret < 0)
274 goto fail;
275 }
276
277 if (ctx->internal->pool_internal && !ctx->pool)
278 ctx->pool = ctx->internal->pool_internal;
279
280 /* preallocate the frames in the pool, if requested */
281 if (ctx->initial_pool_size > 0) {
282 ret = hwframe_pool_prealloc(ref);
283 if (ret < 0)
284 goto fail;
285 }
286
287 return 0;
288fail:
289 if (ctx->internal->hw_type->frames_uninit)
290 ctx->internal->hw_type->frames_uninit(ctx);
291 return ret;
292}
293
294int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
295 enum AVHWFrameTransferDirection dir,
296 enum AVPixelFormat **formats, int flags)
297{
298 AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
299
300 if (!ctx->internal->hw_type->transfer_get_formats)
301 return AVERROR(ENOSYS);
302
303 return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
304}
305
306static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
307{
308 AVFrame *frame_tmp;
309 int ret = 0;
310
311 frame_tmp = av_frame_alloc();
312 if (!frame_tmp)
313 return AVERROR(ENOMEM);
314
315 /* if the format is set, use that
316 * otherwise pick the first supported one */
317 if (dst->format >= 0) {
318 frame_tmp->format = dst->format;
319 } else {
320 enum AVPixelFormat *formats;
321
322 ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx,
323 AV_HWFRAME_TRANSFER_DIRECTION_FROM,
324 &formats, 0);
325 if (ret < 0)
326 goto fail;
327 frame_tmp->format = formats[0];
328 av_freep(&formats);
329 }
330 frame_tmp->width = src->width;
331 frame_tmp->height = src->height;
332
333 ret = av_frame_get_buffer(frame_tmp, 32);
334 if (ret < 0)
335 goto fail;
336
337 ret = av_hwframe_transfer_data(frame_tmp, src, flags);
338 if (ret < 0)
339 goto fail;
340
341 av_frame_move_ref(dst, frame_tmp);
342
343fail:
344 av_frame_free(&frame_tmp);
345 return ret;
346}
347
348int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
349{
350 AVHWFramesContext *ctx;
351 int ret;
352
353 if (!dst->buf[0])
354 return transfer_data_alloc(dst, src, flags);
355
356 if (src->hw_frames_ctx) {
357 ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
358
359 ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
360 if (ret < 0)
361 return ret;
362 } else if (dst->hw_frames_ctx) {
363 ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
364
365 ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
366 if (ret < 0)
367 return ret;
368 } else
369 return AVERROR(ENOSYS);
370
371 return 0;
372}
373
374int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
375{
376 AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
377 int ret;
378
379 if (!ctx->internal->hw_type->frames_get_buffer)
380 return AVERROR(ENOSYS);
381
382 if (!ctx->pool)
383 return AVERROR(EINVAL);
384
385 frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
386 if (!frame->hw_frames_ctx)
387 return AVERROR(ENOMEM);
388
389 ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
390 if (ret < 0) {
391 av_buffer_unref(&frame->hw_frames_ctx);
392 return ret;
393 }
394
395 return 0;
396}
libavutil/hwcontext.h+328−0
@@ -0,0 +1,328 @@
1/*
2 * This file is part of Libav.
3 *
4 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef AVUTIL_HWCONTEXT_H
20#define AVUTIL_HWCONTEXT_H
21
22#include "buffer.h"
23#include "frame.h"
24#include "log.h"
25#include "pixfmt.h"
26
27enum AVHWDeviceType {
28 AV_HWDEVICE_TYPE_VDPAU,
29};
30
31typedef struct AVHWDeviceInternal AVHWDeviceInternal;
32
33/**
34 * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
35 * i.e. state that is not tied to a concrete processing configuration.
36 * E.g., in an API that supports hardware-accelerated encoding and decoding,
37 * this struct will (if possible) wrap the state that is common to both encoding
38 * and decoding and from which specific instances of encoders or decoders can be
39 * derived.
40 *
41 * This struct is reference-counted with the AVBuffer mechanism. The
42 * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
43 * points to the actual AVHWDeviceContext. Further objects derived from
44 * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with
45 * specific properties) will hold an internal reference to it. After all the
46 * references are released, the AVHWDeviceContext itself will be freed,
47 * optionally invoking a user-specified callback for uninitializing the hardware
48 * state.
49 */
50typedef struct AVHWDeviceContext {
51 /**
52 * A class for logging. Set by av_hwdevice_ctx_alloc().
53 */
54 const AVClass *av_class;
55
56 /**
57 * Private data used internally by libavutil. Must not be accessed in any
58 * way by the caller.
59 */
60 AVHWDeviceInternal *internal;
61
62 /**
63 * This field identifies the underlying API used for hardware access.
64 *
65 * This field is set when this struct is allocated and never changed
66 * afterwards.
67 */
68 enum AVHWDeviceType type;
69
70 /**
71 * The format-specific data, allocated and freed by libavutil along with
72 * this context.
73 *
74 * Should be cast by the user to the format-specific context defined in the
75 * corresponding header (hwcontext_*.h) and filled as described in the
76 * documentation before calling av_hwdevice_ctx_init().
77 *
78 * After calling av_hwdevice_ctx_init() this struct should not be modified
79 * by the caller.
80 */
81 void *hwctx;
82
83 /**
84 * This field may be set by the caller before calling av_hwdevice_ctx_init().
85 *
86 * If non-NULL, this callback will be called when the last reference to
87 * this context is unreferenced, immediately before it is freed.
88 *
89 * @note when other objects (e.g an AVHWFramesContext) are derived from this
90 * struct, this callback will be invoked after all such child objects
91 * are fully uninitialized and their respective destructors invoked.
92 */
93 void (*free)(struct AVHWDeviceContext *ctx);
94
95 /**
96 * Arbitrary user data, to be used e.g. by the free() callback.
97 */
98 void *user_opaque;
99} AVHWDeviceContext;
100
101typedef struct AVHWFramesInternal AVHWFramesInternal;
102
103/**
104 * This struct describes a set or pool of "hardware" frames (i.e. those with
105 * data not located in normal system memory). All the frames in the pool are
106 * assumed to be allocated in the same way and interchangeable.
107 *
108 * This struct is reference-counted with the AVBuffer mechanism and tied to a
109 * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
110 * yields a reference, whose data field points to the actual AVHWFramesContext
111 * struct.
112 */
113typedef struct AVHWFramesContext {
114 /**
115 * A class for logging.
116 */
117 const AVClass *av_class;
118
119 /**
120 * Private data used internally by libavutil. Must not be accessed in any
121 * way by the caller.
122 */
123 AVHWFramesInternal *internal;
124
125 /**
126 * A reference to the parent AVHWDeviceContext. This reference is owned and
127 * managed by the enclosing AVHWFramesContext, but the caller may derive
128 * additional references from it.
129 */
130 AVBufferRef *device_ref;
131
132 /**
133 * The parent AVHWDeviceContext. This is simply a pointer to
134 * device_ref->data provided for convenience.
135 *
136 * Set by libavutil in av_hwframe_ctx_init().
137 */
138 AVHWDeviceContext *device_ctx;
139
140 /**
141 * The format-specific data, allocated and freed automatically along with
142 * this context.
143 *
144 * Should be cast by the user to the format-specific context defined in the
145 * corresponding header (hwframe_*.h) and filled as described in the
146 * documentation before calling av_hwframe_ctx_init().
147 *
148 * After any frames using this context are created, the contents of this
149 * struct should not be modified by the caller.
150 */
151 void *hwctx;
152
153 /**
154 * This field may be set by the caller before calling av_hwframe_ctx_init().
155 *
156 * If non-NULL, this callback will be called when the last reference to
157 * this context is unreferenced, immediately before it is freed.
158 */
159 void (*free)(struct AVHWFramesContext *ctx);
160
161 /**
162 * Arbitrary user data, to be used e.g. by the free() callback.
163 */
164 void *user_opaque;
165
166 /**
167 * A pool from which the frames are allocated by av_hwframe_get_buffer().
168 * This field may be set by the caller before calling av_hwframe_ctx_init().
169 * The buffers returned by calling av_buffer_pool_get() on this pool must
170 * have the properties described in the documentation in the correponding hw
171 * type's header (hwcontext_*.h). The pool will be freed strictly before
172 * this struct's free() callback is invoked.
173 *
174 * This field may be NULL, then libavutil will attempt to allocate a pool
175 * internally. Note that certain device types enforce pools allocated at
176 * fixed size (frame count), which cannot be extended dynamically. In such a
177 * case, initial_pool_size must be set appropriately.
178 */
179 AVBufferPool *pool;
180
181 /**
182 * Initial size of the frame pool. If a device type does not support
183 * dynamically resizing the pool, then this is also the maximum pool size.
184 *
185 * May be set by the caller before calling av_hwframe_ctx_init(). Must be
186 * set if pool is NULL and the device type does not support dynamic pools.
187 */
188 int initial_pool_size;
189
190 /**
191 * The pixel format identifying the underlying HW surface type.
192 *
193 * Must be a hwaccel format, i.e. the corresponding descriptor must have the
194 * AV_PIX_FMT_FLAG_HWACCEL flag set.
195 *
196 * Must be set by the user before calling av_hwframe_ctx_init().
197 */
198 enum AVPixelFormat format;
199
200 /**
201 * The pixel format identifying the actual data layout of the hardware
202 * frames.
203 *
204 * Must be set by the caller before calling av_hwframe_ctx_init().
205 *
206 * @note when the underlying API does not provide the exact data layout, but
207 * only the colorspace/bit depth, this field should be set to the fully
208 * planar version of that format (e.g. for 8-bit 420 YUV it should be
209 * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else).
210 */
211 enum AVPixelFormat sw_format;
212
213 /**
214 * The allocated dimensions of the frames in this pool.
215 *
216 * Must be set by the user before calling av_hwframe_ctx_init().
217 */
218 int width, height;
219} AVHWFramesContext;
220
221/**
222 * Allocate an AVHWDeviceContext for a given pixel format.
223 *
224 * @param format a hwaccel pixel format (AV_PIX_FMT_FLAG_HWACCEL must be set
225 * on the corresponding format descriptor)
226 * @return a reference to the newly created AVHWDeviceContext on success or NULL
227 * on failure.
228 */
229AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type);
230
231/**
232 * Finalize the device context before use. This function must be called after
233 * the context is filled with all the required information and before it is
234 * used in any way.
235 *
236 * @param ref a reference to the AVHWDeviceContext
237 * @return 0 on success, a negative AVERROR code on failure
238 */
239int av_hwdevice_ctx_init(AVBufferRef *ref);
240
241/**
242 * Allocate an AVHWFramesContext tied to a given device context.
243 *
244 * @param device_ctx a reference to a AVHWDeviceContext. This function will make
245 * a new reference for internal use, the one passed to the
246 * function remains owned by the caller.
247 * @return a reference to the newly created AVHWFramesContext on success or NULL
248 * on failure.
249 */
250AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ctx);
251
252/**
253 * Finalize the context before use. This function must be called after the
254 * context is filled with all the required information and before it is attached
255 * to any frames.
256 *
257 * @param ref a reference to the AVHWFramesContext
258 * @return 0 on success, a negative AVERROR code on failure
259 */
260int av_hwframe_ctx_init(AVBufferRef *ref);
261
262/**
263 * Allocate a new frame attached to the given AVHWFramesContext.
264 *
265 * @param hwframe_ctx a reference to an AVHWFramesContext
266 * @param frame an empty (freshly allocated or unreffed) frame to be filled with
267 * newly allocated buffers.
268 * @param flags currently unused, should be set to zero
269 * @return 0 on success, a negative AVERROR code on failure
270 */
271int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags);
272
273/**
274 * Copy data to or from a hw surface. At least one of dst/src must have an
275 * AVHWFramesContext attached.
276 *
277 * If src has an AVHWFramesContext attached, then the format of dst (if set)
278 * must use one of the formats returned by av_hwframe_transfer_get_formats(src,
279 * AV_HWFRAME_TRANSFER_DIRECTION_FROM).
280 * If dst has an AVHWFramesContext attached, then the format of src must use one
281 * of the formats returned by av_hwframe_transfer_get_formats(dst,
282 * AV_HWFRAME_TRANSFER_DIRECTION_TO)
283 *
284 * dst may be "clean" (i.e. with data/buf pointers unset), in which case the
285 * data buffers will be allocated by this function using av_frame_get_buffer().
286 * If dst->format is set, then this format will be used, otherwise (when
287 * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen.
288 *
289 * @param dst the destination frame. dst is not touched on failure.
290 * @param src the source frame.
291 * @param flags currently unused, should be set to zero
292 * @return 0 on success, a negative AVERROR error code on failure.
293 */
294int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags);
295
296enum AVHWFrameTransferDirection {
297 /**
298 * Transfer the data from the queried hw frame.
299 */
300 AV_HWFRAME_TRANSFER_DIRECTION_FROM,
301
302 /**
303 * Transfer the data to the queried hw frame.
304 */
305 AV_HWFRAME_TRANSFER_DIRECTION_TO,
306};
307
308/**
309 * Get a list of possible source or target formats usable in
310 * av_hwframe_transfer_data().
311 *
312 * @param hwframe_ctx the frame context to obtain the information for
313 * @param dir the direction of the transfer
314 * @param formats the pointer to the output format list will be written here.
315 * The list is terminated with AV_PIX_FMT_NONE and must be freed
316 * by the caller when no longer needed using av_free().
317 * If this function returns successfully, the format list will
318 * have at least one item (not counting the terminator).
319 * On failure, the contents of this pointer are unspecified.
320 * @param flags currently unused, should be set to zero
321 * @return 0 on success, a negative AVERROR code on failure.
322 */
323int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ctx,
324 enum AVHWFrameTransferDirection dir,
325 enum AVPixelFormat **formats, int flags);
326
327
328#endif /* AVUTIL_HWCONTEXT_H */
libavutil/hwcontext_internal.h+89−0
@@ -0,0 +1,89 @@
1/*
2 * This file is part of Libav.
3 *
4 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef AVUTIL_HWCONTEXT_INTERNAL_H
20#define AVUTIL_HWCONTEXT_INTERNAL_H
21
22#include <stddef.h>
23
24#include "buffer.h"
25#include "hwcontext.h"
26#include "frame.h"
27#include "pixfmt.h"
28
29typedef struct HWContextType {
30 enum AVHWDeviceType type;
31 const char *name;
32
33 /**
34 * An array of pixel formats supported by the AVHWFramesContext instances
35 * Terminated by AV_PIX_FMT_NONE.
36 */
37 const enum AVPixelFormat *pix_fmts;
38
39 /**
40 * size of the public hardware-specific context,
41 * i.e. AVHWDeviceContext.hwctx
42 */
43 size_t device_hwctx_size;
44 /**
45 * size of the private data, i.e.
46 * AVHWDeviceInternal.priv
47 */
48 size_t device_priv_size;
49
50 /**
51 * size of the public frame pool hardware-specific context,
52 * i.e. AVHWFramesContext.hwctx
53 */
54 size_t frames_hwctx_size;
55 /**
56 * size of the private data, i.e.
57 * AVHWFramesInternal.priv
58 */
59 size_t frames_priv_size;
60
61 int (*device_init)(AVHWDeviceContext *ctx);
62 void (*device_uninit)(AVHWDeviceContext *ctx);
63
64 int (*frames_init)(AVHWFramesContext *ctx);
65 void (*frames_uninit)(AVHWFramesContext *ctx);
66
67 int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame);
68 int (*transfer_get_formats)(AVHWFramesContext *ctx,
69 enum AVHWFrameTransferDirection dir,
70 enum AVPixelFormat **formats);
71 int (*transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst,
72 const AVFrame *src);
73 int (*transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst,
74 const AVFrame *src);
75} HWContextType;
76
77struct AVHWDeviceInternal {
78 const HWContextType *hw_type;
79 void *priv;
80};
81
82struct AVHWFramesInternal {
83 const HWContextType *hw_type;
84 void *priv;
85
86 AVBufferPool *pool_internal;
87};
88
89#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t