2 * This file is part of Libav.
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.
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.
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
23 #include "hwcontext.h"
24 #include "hwcontext_internal.h"
31 static const HWContextType
*hw_table
[] = {
33 &ff_hwcontext_type_cuda
,
36 &ff_hwcontext_type_dxva2
,
39 &ff_hwcontext_type_qsv
,
42 &ff_hwcontext_type_vaapi
,
45 &ff_hwcontext_type_vdpau
,
50 static const AVClass hwdevice_ctx_class
= {
51 .class_name
= "AVHWDeviceContext",
52 .item_name
= av_default_item_name
,
53 .version
= LIBAVUTIL_VERSION_INT
,
56 static void hwdevice_ctx_free(void *opaque
, uint8_t *data
)
58 AVHWDeviceContext
*ctx
= (AVHWDeviceContext
*)data
;
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
);
68 av_freep(&ctx
->hwctx
);
69 av_freep(&ctx
->internal
->priv
);
70 av_freep(&ctx
->internal
);
74 AVBufferRef
*av_hwdevice_ctx_alloc(enum AVHWDeviceType type
)
76 AVHWDeviceContext
*ctx
;
78 const HWContextType
*hw_type
= NULL
;
81 for (i
= 0; hw_table
[i
]; i
++) {
82 if (hw_table
[i
]->type
== type
) {
83 hw_type
= hw_table
[i
];
90 ctx
= av_mallocz(sizeof(*ctx
));
94 ctx
->internal
= av_mallocz(sizeof(*ctx
->internal
));
98 if (hw_type
->device_priv_size
) {
99 ctx
->internal
->priv
= av_mallocz(hw_type
->device_priv_size
);
100 if (!ctx
->internal
->priv
)
104 if (hw_type
->device_hwctx_size
) {
105 ctx
->hwctx
= av_mallocz(hw_type
->device_hwctx_size
);
110 buf
= av_buffer_create((uint8_t*)ctx
, sizeof(*ctx
),
111 hwdevice_ctx_free
, NULL
,
112 AV_BUFFER_FLAG_READONLY
);
117 ctx
->av_class
= &hwdevice_ctx_class
;
119 ctx
->internal
->hw_type
= hw_type
;
125 av_freep(&ctx
->internal
->priv
);
126 av_freep(&ctx
->internal
);
127 av_freep(&ctx
->hwctx
);
132 int av_hwdevice_ctx_init(AVBufferRef
*ref
)
134 AVHWDeviceContext
*ctx
= (AVHWDeviceContext
*)ref
->data
;
137 if (ctx
->internal
->hw_type
->device_init
) {
138 ret
= ctx
->internal
->hw_type
->device_init(ctx
);
145 if (ctx
->internal
->hw_type
->device_uninit
)
146 ctx
->internal
->hw_type
->device_uninit(ctx
);
150 static const AVClass hwframe_ctx_class
= {
151 .class_name
= "AVHWFramesContext",
152 .item_name
= av_default_item_name
,
153 .version
= LIBAVUTIL_VERSION_INT
,
156 static void hwframe_ctx_free(void *opaque
, uint8_t *data
)
158 AVHWFramesContext
*ctx
= (AVHWFramesContext
*)data
;
160 if (ctx
->internal
->pool_internal
)
161 av_buffer_pool_uninit(&ctx
->internal
->pool_internal
);
163 if (ctx
->internal
->hw_type
->frames_uninit
)
164 ctx
->internal
->hw_type
->frames_uninit(ctx
);
169 av_buffer_unref(&ctx
->device_ref
);
171 av_freep(&ctx
->hwctx
);
172 av_freep(&ctx
->internal
->priv
);
173 av_freep(&ctx
->internal
);
177 AVBufferRef
*av_hwframe_ctx_alloc(AVBufferRef
*device_ref_in
)
179 AVHWDeviceContext
*device_ctx
= (AVHWDeviceContext
*)device_ref_in
->data
;
180 const HWContextType
*hw_type
= device_ctx
->internal
->hw_type
;
181 AVHWFramesContext
*ctx
;
182 AVBufferRef
*buf
, *device_ref
= NULL
;;
184 ctx
= av_mallocz(sizeof(*ctx
));
188 ctx
->internal
= av_mallocz(sizeof(*ctx
->internal
));
192 if (hw_type
->frames_priv_size
) {
193 ctx
->internal
->priv
= av_mallocz(hw_type
->frames_priv_size
);
194 if (!ctx
->internal
->priv
)
198 if (hw_type
->frames_hwctx_size
) {
199 ctx
->hwctx
= av_mallocz(hw_type
->frames_hwctx_size
);
204 device_ref
= av_buffer_ref(device_ref_in
);
208 buf
= av_buffer_create((uint8_t*)ctx
, sizeof(*ctx
),
209 hwframe_ctx_free
, NULL
,
210 AV_BUFFER_FLAG_READONLY
);
214 ctx
->av_class
= &hwframe_ctx_class
;
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
;
220 ctx
->internal
->hw_type
= hw_type
;
226 av_buffer_unref(&device_ref
);
228 av_freep(&ctx
->internal
->priv
);
229 av_freep(&ctx
->internal
);
230 av_freep(&ctx
->hwctx
);
235 static int hwframe_pool_prealloc(AVBufferRef
*ref
)
237 AVHWFramesContext
*ctx
= (AVHWFramesContext
*)ref
->data
;
241 frames
= av_mallocz_array(ctx
->initial_pool_size
, sizeof(*frames
));
243 return AVERROR(ENOMEM
);
245 for (i
= 0; i
< ctx
->initial_pool_size
; i
++) {
246 frames
[i
] = av_frame_alloc();
250 ret
= av_hwframe_get_buffer(ref
, frames
[i
], 0);
256 for (i
= 0; i
< ctx
->initial_pool_size
; i
++)
257 av_frame_free(&frames
[i
]);
263 int av_hwframe_ctx_init(AVBufferRef
*ref
)
265 AVHWFramesContext
*ctx
= (AVHWFramesContext
*)ref
->data
;
266 const enum AVPixelFormat
*pix_fmt
;
269 /* validate the pixel format */
270 for (pix_fmt
= ctx
->internal
->hw_type
->pix_fmts
; *pix_fmt
!= AV_PIX_FMT_NONE
; pix_fmt
++) {
271 if (*pix_fmt
== ctx
->format
)
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",
277 av_get_pix_fmt_name(ctx
->format
), ctx
->internal
->hw_type
->name
);
278 return AVERROR(ENOSYS
);
281 /* validate the dimensions */
282 ret
= av_image_check_size(ctx
->width
, ctx
->height
, 0, ctx
);
286 /* format-specific init */
287 if (ctx
->internal
->hw_type
->frames_init
) {
288 ret
= ctx
->internal
->hw_type
->frames_init(ctx
);
293 if (ctx
->internal
->pool_internal
&& !ctx
->pool
)
294 ctx
->pool
= ctx
->internal
->pool_internal
;
296 /* preallocate the frames in the pool, if requested */
297 if (ctx
->initial_pool_size
> 0) {
298 ret
= hwframe_pool_prealloc(ref
);
305 if (ctx
->internal
->hw_type
->frames_uninit
)
306 ctx
->internal
->hw_type
->frames_uninit(ctx
);
310 int av_hwframe_transfer_get_formats(AVBufferRef
*hwframe_ref
,
311 enum AVHWFrameTransferDirection dir
,
312 enum AVPixelFormat
**formats
, int flags
)
314 AVHWFramesContext
*ctx
= (AVHWFramesContext
*)hwframe_ref
->data
;
316 if (!ctx
->internal
->hw_type
->transfer_get_formats
)
317 return AVERROR(ENOSYS
);
319 return ctx
->internal
->hw_type
->transfer_get_formats(ctx
, dir
, formats
);
322 static int transfer_data_alloc(AVFrame
*dst
, const AVFrame
*src
, int flags
)
327 frame_tmp
= av_frame_alloc();
329 return AVERROR(ENOMEM
);
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
;
336 enum AVPixelFormat
*formats
;
338 ret
= av_hwframe_transfer_get_formats(src
->hw_frames_ctx
,
339 AV_HWFRAME_TRANSFER_DIRECTION_FROM
,
343 frame_tmp
->format
= formats
[0];
346 frame_tmp
->width
= src
->width
;
347 frame_tmp
->height
= src
->height
;
349 ret
= av_frame_get_buffer(frame_tmp
, 32);
353 ret
= av_hwframe_transfer_data(frame_tmp
, src
, flags
);
357 av_frame_move_ref(dst
, frame_tmp
);
360 av_frame_free(&frame_tmp
);
364 int av_hwframe_transfer_data(AVFrame
*dst
, const AVFrame
*src
, int flags
)
366 AVHWFramesContext
*ctx
;
370 return transfer_data_alloc(dst
, src
, flags
);
372 if (src
->hw_frames_ctx
) {
373 ctx
= (AVHWFramesContext
*)src
->hw_frames_ctx
->data
;
375 ret
= ctx
->internal
->hw_type
->transfer_data_from(ctx
, dst
, src
);
378 } else if (dst
->hw_frames_ctx
) {
379 ctx
= (AVHWFramesContext
*)dst
->hw_frames_ctx
->data
;
381 ret
= ctx
->internal
->hw_type
->transfer_data_to(ctx
, dst
, src
);
385 return AVERROR(ENOSYS
);
390 int av_hwframe_get_buffer(AVBufferRef
*hwframe_ref
, AVFrame
*frame
, int flags
)
392 AVHWFramesContext
*ctx
= (AVHWFramesContext
*)hwframe_ref
->data
;
395 if (!ctx
->internal
->hw_type
->frames_get_buffer
)
396 return AVERROR(ENOSYS
);
399 return AVERROR(EINVAL
);
401 frame
->hw_frames_ctx
= av_buffer_ref(hwframe_ref
);
402 if (!frame
->hw_frames_ctx
)
403 return AVERROR(ENOMEM
);
405 ret
= ctx
->internal
->hw_type
->frames_get_buffer(ctx
, frame
);
407 av_buffer_unref(&frame
->hw_frames_ctx
);
414 void *av_hwdevice_hwconfig_alloc(AVBufferRef
*ref
)
416 AVHWDeviceContext
*ctx
= (AVHWDeviceContext
*)ref
->data
;
417 const HWContextType
*hw_type
= ctx
->internal
->hw_type
;
419 if (hw_type
->device_hwconfig_size
== 0)
422 return av_mallocz(hw_type
->device_hwconfig_size
);
425 AVHWFramesConstraints
*av_hwdevice_get_hwframe_constraints(AVBufferRef
*ref
,
426 const void *hwconfig
)
428 AVHWDeviceContext
*ctx
= (AVHWDeviceContext
*)ref
->data
;
429 const HWContextType
*hw_type
= ctx
->internal
->hw_type
;
430 AVHWFramesConstraints
*constraints
;
432 if (!hw_type
->frames_get_constraints
)
435 constraints
= av_mallocz(sizeof(*constraints
));
439 constraints
->min_width
= constraints
->min_height
= 0;
440 constraints
->max_width
= constraints
->max_height
= INT_MAX
;
442 if (hw_type
->frames_get_constraints(ctx
, hwconfig
, constraints
) >= 0) {
445 av_hwframe_constraints_free(&constraints
);
450 void av_hwframe_constraints_free(AVHWFramesConstraints
**constraints
)
453 av_freep(&(*constraints
)->valid_hw_formats
);
454 av_freep(&(*constraints
)->valid_sw_formats
);
456 av_freep(constraints
);
459 int av_hwdevice_ctx_create(AVBufferRef
**pdevice_ref
, enum AVHWDeviceType type
,
460 const char *device
, AVDictionary
*opts
, int flags
)
462 AVBufferRef
*device_ref
= NULL
;
463 AVHWDeviceContext
*device_ctx
;
466 device_ref
= av_hwdevice_ctx_alloc(type
);
468 ret
= AVERROR(ENOMEM
);
471 device_ctx
= (AVHWDeviceContext
*)device_ref
->data
;
473 if (!device_ctx
->internal
->hw_type
->device_create
) {
474 ret
= AVERROR(ENOSYS
);
478 ret
= device_ctx
->internal
->hw_type
->device_create(device_ctx
, device
,
483 ret
= av_hwdevice_ctx_init(device_ref
);
487 *pdevice_ref
= device_ref
;
490 av_buffer_unref(&device_ref
);