FFmpeg: libavutil/hwcontext.c Source File
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
31
33 #if CONFIG_CUDA
35 #endif
36 #if CONFIG_D3D11VA
38 #endif
39 #if CONFIG_D3D12VA
41 #endif
42 #if CONFIG_LIBDRM
44 #endif
45 #if CONFIG_DXVA2
47 #endif
48 #if CONFIG_OPENCL
50 #endif
51 #if CONFIG_QSV
53 #endif
54 #if CONFIG_VAAPI
56 #endif
57 #if CONFIG_VDPAU
59 #endif
60 #if CONFIG_VIDEOTOOLBOX
62 #endif
63 #if CONFIG_MEDIACODEC
65 #endif
66 #if CONFIG_VULKAN
68 #endif
70 };
71
85 };
86
88 /**
89 * The public AVHWDeviceContext. See hwcontext.h for it.
90 */
92
94
95 /**
96 * For a derived device, a reference to the original device
97 * context it was derived from.
98 */
101
103 {
108 }
110 }
111
113 {
117 else
119 }
120
122 {
127 continue;
131 }
132 }
134 }
135
140 };
141
143 {
146
147 /* uninit might still want access the hw context and the user
148 * free() callback might destroy it, so uninit has to be called first */
151
154
156
159 }
160
162 {
168
172 break;
173 }
174 }
175 if (!hw_type)
177
179 if (!ctxi)
182
187 }
188
192 if (!buf)
194
197
199
200 return buf;
201
206 }
207
209 {
213
216
218 }
219
224 };
225
227 {
230
233
236
239
241
243
246 }
247
249 {
255
257 if (!ctxi)
260
261 if (hw_type->frames_hwctx_size) {
265 }
266
268 if (!device_ref)
270
274 if (!buf)
276
278 ctx->device_ref = device_ref;
279 ctx->device_ctx = &device_ctx->
p;
282
283 ctxi->hw_type = hw_type;
284
285 return buf;
286
292 }
293
295 {
299
303
304 for (
i = 0;
i <
ctx->initial_pool_size;
i++) {
308
312 }
313
315 for (
i = 0;
i <
ctx->initial_pool_size;
i++)
318
320 }
321
323 {
328
330 /* A derived frame context is already initialised. */
331 return 0;
332 }
333
334 /* validate the pixel format */
337 break;
338 }
341 "The hardware pixel format '%s' is not supported by the device type '%s'\n",
344 }
345
346 /* validate the dimensions */
350
351 /* format-specific init */
356 }
357
360
361 /* preallocate the frames in the pool, if requested */
362 if (
ctx->initial_pool_size > 0) {
366 }
367
368 return 0;
369 }
370
374 {
376
379
381 }
382
384 {
388
389 if (!
src->hw_frames_ctx)
392
394 if (!frame_tmp)
396
397 /* if the format is set, use that
398 * otherwise pick the first supported one */
401 } else {
403
411 }
414
418
422
425
427
431 }
432
434 {
436
439
440 /*
441 * Hardware -> Hardware Transfer.
442 * Unlike Software -> Hardware or Hardware -> Software, the transfer
443 * function could be provided by either the src or dst, depending on
444 * the specific combination of hardware.
445 */
451
454 "A device with a derived frame context cannot be used as "
455 "the source of a HW -> HW transfer.");
457 }
458
459 if (dst_ctx->source_frames) {
461 "A device with a derived frame context cannot be used as "
462 "the destination of a HW -> HW transfer.");
464 }
465
468 ret = dst_ctx->hw_type->transfer_data_to(&dst_ctx->p, dst,
src);
471 } else {
472 if (
src->hw_frames_ctx) {
474
475 ret =
ctx->hw_type->transfer_data_from(&
ctx->p, dst,
src);
480
481 ret =
ctx->hw_type->transfer_data_to(&
ctx->p, dst,
src);
484 } else {
486 }
487 }
488 return 0;
489 }
490
492 {
496
498 // This is a derived frame context, so we allocate in the source
499 // and map the frame immediately.
501
506
508 if (!src_frame)
510
512 src_frame, 0);
516 }
517
522 "frame context: %d.\n",
ret);
525 }
526
527 // Free the source frame immediately - the mapped frame still
528 // contains a reference to it.
530
531 return 0;
532 }
533
536
539
543
548 }
549
551
552 return 0;
553 }
554
556 {
559
560 if (hw_type->device_hwconfig_size == 0)
562
563 return av_mallocz(hw_type->device_hwconfig_size);
564 }
565
567 const void *hwconfig)
568 {
572
573 if (!hw_type->frames_get_constraints)
575
576 constraints =
av_mallocz(
sizeof(*constraints));
577 if (!constraints)
579
580 constraints->min_width = constraints->min_height = 0;
581 constraints->max_width = constraints->max_height = INT_MAX;
582
583 if (hw_type->frames_get_constraints(&
ctx->p, hwconfig, constraints) >= 0) {
584 return constraints;
585 } else {
588 }
589 }
590
592 {
593 if (*constraints) {
594 av_freep(&(*constraints)->valid_hw_formats);
595 av_freep(&(*constraints)->valid_sw_formats);
596 }
598 }
599
602 {
606
608 if (!device_ref) {
611 }
613
617 }
618
623
627
628 *pdevice_ref = device_ref;
629 return 0;
634 }
635
640 {
644
645 tmp_ref = src_ref;
646 while (tmp_ref) {
650 if (!dst_ref) {
653 }
654 goto done;
655 }
657 }
658
660 if (!dst_ref) {
663 }
665
666 tmp_ref = src_ref;
667 while (tmp_ref) {
678 }
682 goto done;
683 }
686 }
688 }
689
692
693 done:
694 *dst_ref_ptr = dst_ref;
695 return 0;
696
701 }
702
706 {
709 }
710
712 {
715
718
720
722
724 }
725
730 void *priv)
731 {
735
737 if (!hwmap) {
740 }
741
746 }
750
755 }
756
757 hwmap->
unmap = unmap;
759
765 }
766
767 return 0;
768
770 if (hwmap) {
773 }
776 }
777
779 {
784
788
789 if ((src_frames == dst_frames &&
790 src->format == dst_frames->p.sw_format &&
791 dst->
format == dst_frames->p.format) ||
794 (uint8_t*)dst_frames)) {
795 // This is an unmap operation. We don't need to directly
796 // do anything here other than fill in the original frame,
797 // because the real unmap will be invoked when the last
798 // reference to the mapped frame disappears.
801 "found when attempting unmap.\n");
803 }
806 }
807 }
808
809 if (
src->hw_frames_ctx) {
811
820 }
821 }
822
825
834 }
835 }
836
838
840 // if the caller provided dst frames context, it should be preserved
841 // by this function
844
845 // preserve user-provided dst frame fields, but clean
846 // anything we might have set
849
851 dst->
format = orig_dst_fmt;
852
854 }
855
861 {
867
873
875 // This is actually an unmapping, so we just return a
876 // reference to the source frame context.
878 if (!*derived_frame_ctx) {
881 }
882 return 0;
883 }
884 }
885
887 if (!dst_ref) {
890 }
891
894
899
904 }
905
911
922
923 *derived_frame_ctx = dst_ref;
924 return 0;
925
927 if (dsti)
931 }
932
934 {
937 }
AVBufferPool * pool_internal
static void hwframe_ctx_free(void *opaque, uint8_t *data)
AVPixelFormat
Pixel format.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
void(* device_uninit)(AVHWDeviceContext *ctx)
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
@ AV_HWFRAME_TRANSFER_DIRECTION_FROM
Transfer the data from the queried hw frame.
int(* frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame)
AVFrame * source
A reference to the original source of the mapping.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
uint8_t * data
The data buffer.
static void ff_hwframe_unmap(void *opaque, uint8_t *data)
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
static void hwdevice_ctx_free(void *opaque, uint8_t *data)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
This structure describes decoded (raw) audio or video data.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
const HWContextType ff_hwcontext_type_qsv
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
const HWContextType ff_hwcontext_type_drm
@ AV_HWDEVICE_TYPE_MEDIACODEC
int(* map_to)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
const HWContextType ff_hwcontext_type_vdpau
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
int(* frames_init)(AVHWFramesContext *ctx)
const HWContextType ff_hwcontext_type_vaapi
int(* map_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev)
Iterate over supported device types.
AVBufferRef * hw_frames_ctx
A reference to the hardware frames context in which this mapping was made.
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
@ AV_HWDEVICE_TYPE_VIDEOTOOLBOX
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
void * priv
Hardware-specific private data associated with the mapping.
int width
The allocated dimensions of the frames in this pool.
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...
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
@ AV_HWFRAME_MAP_OVERWRITE
The mapped frame will be overwritten completely in subsequent operations, so the current frame data n...
@ AV_HWDEVICE_TYPE_VULKAN
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
const HWContextType ff_hwcontext_type_d3d11va
int(* device_derive)(AVHWDeviceContext *dst_ctx, AVHWDeviceContext *src_ctx, AVDictionary *opts, int flags)
if it could not because there are no more frames
@ AV_HWDEVICE_TYPE_D3D11VA
int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr, enum AVHWDeviceType type, AVBufferRef *src_ref, AVDictionary *options, int flags)
Create a new device of the specified type from an existing device.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
const HWContextType ff_hwcontext_type_mediacodec
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static int hwframe_pool_prealloc(AVBufferRef *ref)
const HWContextType * hw_type
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const HWContextType ff_hwcontext_type_dxva2
#define FF_ARRAY_ELEMS(a)
static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v)
static const char *const hw_type_names[]
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
static const HWContextType *const hw_table[]
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
static enum AVPixelFormat pix_fmt
void(* frames_uninit)(AVHWFramesContext *ctx)
int source_allocation_map_flags
Flags to apply to the mapping from the source to the derived frame context when trying to allocate in...
@ AV_HWFRAME_MAP_DIRECT
The mapping must be direct.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int(* device_create)(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
AVHWFramesContext p
The public AVHWFramesContext.
const HWContextType ff_hwcontext_type_videotoolbox
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int(* transfer_get_formats)(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
const char * av_default_item_name(void *ptr)
Return the context name.
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, enum AVPixelFormat format, AVBufferRef *derived_device_ctx, AVBufferRef *source_frame_ctx, int flags)
Create and initialise an AVHWFramesContext as a mapping of another existing AVHWFramesContext on a di...
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
const OptionDef options[]
int(* frames_derive_to)(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
@ AV_HWDEVICE_TYPE_D3D12VA
@ AV_HWDEVICE_TYPE_OPENCL
const HWContextType * hw_type
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
AVBufferRef * source_frames
For a derived context, a reference to the original frames context it was derived from.
const HWContextType ff_hwcontext_type_cuda
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
int(* frames_derive_from)(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
static const AVClass hwframe_ctx_class
static const AVClass hwdevice_ctx_class
const HWContextType ff_hwcontext_type_vulkan
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, enum AVHWDeviceType type, AVBufferRef *src_ref, int flags)
Create a new device of the specified type from an existing device.
size_t device_hwctx_size
size of the public hardware-specific context, i.e.
#define i(width, name, range_min, range_max)
AVBufferRef * source_device
For a derived device, a reference to the original device context it was derived from.
uint8_t ** extended_data
pointers to the data planes/channels.
void(* unmap)(AVHWFramesContext *ctx, struct HWMapDescriptor *hwmap)
Unmap function.
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src)
Replace the current hwmap of dst with the one from src, used for indirect mappings like VAAPI->(DRM)-...
void * av_calloc(size_t nmemb, size_t size)
AVHWFrameTransferDirection
This struct describes a set or pool of "hardware" frames (i.e.
@ AV_HWFRAME_MAP_READ
The mapping must be readable.
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
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.
const AVClass * av_class
A class for logging and AVOptions.
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
int(* device_init)(AVHWDeviceContext *ctx)
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
int av_frame_replace(AVFrame *dst, const AVFrame *src)
Ensure the destination frame refers to the same data described by the source frame,...
const HWContextType ff_hwcontext_type_d3d12va
static int ref[MAX_W *MAX_W]
enum AVPixelFormat * pix_fmts
An array of pixel formats supported by the AVHWFramesContext instances Terminated by AV_PIX_FMT_NONE.
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().
AVHWDeviceContext p
The public AVHWDeviceContext.
A reference to a data buffer.
#define flags(name, subs,...)
int(* transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
@ AV_HWFRAME_MAP_WRITE
The mapping must be writeable.
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...
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
const HWContextType ff_hwcontext_type_opencl
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.
Generated on Thu Sep 26 2024 23:15:54 for FFmpeg by
doxygen
1.8.17