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
20
30
32 #if CONFIG_CUDA
34 #endif
35 #if CONFIG_D3D11VA
37 #endif
38 #if CONFIG_LIBDRM
40 #endif
41 #if CONFIG_DXVA2
43 #endif
44 #if CONFIG_OPENCL
46 #endif
47 #if CONFIG_QSV
49 #endif
50 #if CONFIG_VAAPI
52 #endif
53 #if CONFIG_VDPAU
55 #endif
56 #if CONFIG_VIDEOTOOLBOX
58 #endif
59 #if CONFIG_MEDIACODEC
61 #endif
63 };
64
76 };
77
79 {
83 return type;
84 }
86 }
87
89 {
93 else
95 }
96
98 {
101 for (i = 0; hw_table[i]; i++) {
103 continue;
104 if (!set || hw_table[i]->
type < next) {
105 next = hw_table[i]->
type;
106 set = 1;
107 }
108 }
110 }
111
116 };
117
119 {
121
122 /* uninit might still want access the hw context and the user
123 * free() callback might destroy it, so uninit has to be called first */
126
129
131
136 }
137
139 {
143 int i;
144
145 for (i = 0; hw_table[i]; i++) {
146 if (hw_table[i]->type == type) {
147 hw_type = hw_table[i];
148 break;
149 }
150 }
151 if (!hw_type)
153
155 if (!ctx)
157
161
166 }
167
172 }
173
177 if (!buf)
179
182
184
186
194 }
195
197 {
199 int ret;
200
203 if (ret < 0)
205 }
206
207 return 0;
211 return ret;
212 }
213
218 };
219
221 {
223
226
229
232
234
236
241 }
242
244 {
249
253
257
258 if (hw_type->frames_priv_size) {
262 }
263
264 if (hw_type->frames_hwctx_size) {
268 }
269
271 if (!device_ref)
273
277 if (!buf)
279
281 ctx->device_ref = device_ref;
282 ctx->device_ctx = device_ctx;
285
287
289
291 if (device_ref)
299 }
300
302 {
305 int i, ret = 0;
306
310
315
317 if (ret < 0)
319 }
320
325
326 return ret;
327 }
328
330 {
333 int ret;
334
336 /* A derived frame context is already initialised. */
337 return 0;
338 }
339
340 /* validate the pixel format */
343 break;
344 }
347 "The hardware pixel format '%s' is not supported by the device type '%s'\n",
350 }
351
352 /* validate the dimensions */
354 if (ret < 0)
355 return ret;
356
357 /* format-specific init */
360 if (ret < 0)
362 }
363
366
367 /* preallocate the frames in the pool, if requested */
370 if (ret < 0)
372 }
373
374 return 0;
378 return ret;
379 }
380
384 {
386
389
391 }
392
394 {
397 int ret = 0;
398
400 if (!frame_tmp)
402
403 /* if the format is set, use that
404 * otherwise pick the first supported one */
406 frame_tmp->format = dst->
format;
407 } else {
409
412 &formats, 0);
413 if (ret < 0)
415 frame_tmp->format = formats[0];
417 }
418 frame_tmp->width = ctx->
width;
419 frame_tmp->height = ctx->
height;
420
422 if (ret < 0)
424
426 if (ret < 0)
428
429 frame_tmp->width = src->
width;
430 frame_tmp->height = src->
height;
431
433
436 return ret;
437 }
438
440 {
442 int ret;
443
446
449
451 if (ret < 0)
452 return ret;
455
457 if (ret < 0)
458 return ret;
459 } else
461
462 return 0;
463 }
464
466 {
468 int ret;
469
471 // This is a derived frame context, so we allocate in the source
472 // and map the frame immediately.
474
479
481 if (!src_frame)
483
485 src_frame, 0);
486 if (ret < 0) {
488 return ret;
489 }
490
493 if (ret) {
495 "frame context: %d.\n", ret);
497 return ret;
498 }
499
500 // Free the source frame immediately - the mapped frame still
501 // contains a reference to it.
503
504 return 0;
505 }
506
509
512
516
518 if (ret < 0) {
520 return ret;
521 }
522
523 return 0;
524 }
525
527 {
530
531 if (hw_type->device_hwconfig_size == 0)
533
534 return av_mallocz(hw_type->device_hwconfig_size);
535 }
536
538 const void *hwconfig)
539 {
543
544 if (!hw_type->frames_get_constraints)
546
547 constraints =
av_mallocz(
sizeof(*constraints));
548 if (!constraints)
550
551 constraints->min_width = constraints->min_height = 0;
552 constraints->max_width = constraints->max_height = INT_MAX;
553
554 if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) {
555 return constraints;
556 } else {
559 }
560 }
561
563 {
564 if (*constraints) {
565 av_freep(&(*constraints)->valid_hw_formats);
566 av_freep(&(*constraints)->valid_sw_formats);
567 }
569 }
570
573 {
576 int ret = 0;
577
579 if (!device_ref) {
582 }
584
588 }
589
591 opts, flags);
592 if (ret < 0)
594
596 if (ret < 0)
598
599 *pdevice_ref = device_ref;
600 return 0;
604 return ret;
605 }
606
610 {
613 int ret = 0;
614
615 tmp_ref = src_ref;
616 while (tmp_ref) {
618 if (tmp_ctx->
type == type) {
620 if (!dst_ref) {
623 }
624 goto done;
625 }
627 }
628
630 if (!dst_ref) {
633 }
635
636 tmp_ref = src_ref;
637 while (tmp_ref) {
641 tmp_ctx,
642 flags);
643 if (ret == 0) {
648 }
649 goto done;
650 }
653 }
655 }
656
659
660 done:
662 if (ret < 0)
664
665 *dst_ref_ptr = dst_ref;
666 return 0;
667
671 return ret;
672 }
673
675 {
678
680 hwmap->
unmap(ctx, hwmap);
681
683
685
687 }
688
693 void *priv)
694 {
697 int ret;
698
700 if (!hwmap) {
703 }
704
709 }
711 if (ret < 0)
713
718 }
719
720 hwmap->
unmap = unmap;
722
728 }
729
730 return 0;
731
733 if (hwmap) {
736 }
738 return ret;
739 }
740
742 {
745 int ret;
746
750
751 if ((src_frames == dst_frames &&
757 // This is an unmap operation. We don't need to directly
758 // do anything here other than fill in the original frame,
759 // because the real unmap will be invoked when the last
760 // reference to the mapped frame disappears.
763 "found when attempting unmap.\n");
765 }
769 }
770 }
771
774
778 dst, src, flags);
780 return ret;
781 }
782 }
783
786
790 dst, src, flags);
792 return ret;
793 }
794 }
795
797 }
798
804 {
808 int ret;
809
815
817 // This is actually an unmapping, so we just return a
818 // reference to the source frame context.
819 *derived_frame_ctx =
821 if (!*derived_frame_ctx) {
824 }
825 return 0;
826 }
827 }
828
830 if (!dst_ref) {
833 }
834
836
841
846 }
847
853
861 ret = 0;
862 if (ret)
864
865 *derived_frame_ctx = dst_ref;
866 return 0;
867
869 if (dst)
872 return ret;
873 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
static enum AVPixelFormat pix_fmt
static void hwdevice_ctx_free(void *opaque, uint8_t *data)
static const char * format[]
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
void(* frames_uninit)(AVHWFramesContext *ctx)
#define LIBAVUTIL_VERSION_INT
Memory handling functions.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
const HWContextType ff_hwcontext_type_vdpau
const char * av_default_item_name(void *ptr)
Return the context name.
AVFormatInternal * internal
An opaque field for libavformat internal usage.
int width
The allocated dimensions of the frames in this pool.
const HWContextType ff_hwcontext_type_mediacodec
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
int(* frames_derive_to)(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
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...
const HWContextType * hw_type
static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v)
int(* map_to)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
static const char *const hw_type_names[]
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
int(* device_derive)(AVHWDeviceContext *dst_ctx, AVHWDeviceContext *src_ctx, int flags)
AVBufferPool * pool_internal
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...
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static int hwframe_pool_prealloc(AVBufferRef *ref)
size_t device_hwctx_size
size of the public hardware-specific context, i.e.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
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.
static void hwframe_ctx_free(void *opaque, uint8_t *data)
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
static const AVClass hwframe_ctx_class
The mapped frame will be overwritten completely in subsequent operations, so the current frame data n...
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
int(* map_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
The mapping must be direct.
AVBufferRef * source_frames
For a derived context, a reference to the original frames context it was derived from.
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.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
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_videotoolbox
static const HWContextType *const hw_table[]
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.
int initial_pool_size
Initial size of the frame pool.
Transfer the data from the queried hw frame.
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...
AVFrame * source
A reference to the original source of the mapping.
enum AVPixelFormat * pix_fmts
An array of pixel formats supported by the AVHWFramesContext instances Terminated by AV_PIX_FMT_NONE...
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
The mapping must be readable.
void(* unmap)(AVHWFramesContext *ctx, struct HWMapDescriptor *hwmap)
Unmap function.
The mapping must be writeable.
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.
#define FF_ARRAY_ELEMS(a)
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
const HWContextType ff_hwcontext_type_drm
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
void * priv
Hardware-specific private data associated with the mapping.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
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...
uint8_t * data
The data buffer.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
const AVClass * av_class
A class for logging.
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
Describe the class of an AVClass context structure.
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
int source_allocation_map_flags
Flags to apply to the mapping from the source to the derived frame context when trying to allocate in...
int(* frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame)
This struct describes a set or pool of "hardware" frames (i.e.
const AVClass * av_class
A class for logging and AVOptions.
refcounted data buffer API
AVBufferRef * hw_frames_ctx
A reference to the hardware frames context in which this mapping was made.
static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
int(* frames_derive_from)(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
AVHWFramesInternal * internal
Private data used internally by libavutil.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int(* transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
static void ff_hwframe_unmap(void *opaque, uint8_t *data)
int(* transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
A reference to a data buffer.
const HWContextType * hw_type
common internal and external API header
static int ref[MAX_W *MAX_W]
const HWContextType ff_hwcontext_type_opencl
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
AVHWFrameTransferDirection
enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev)
Iterate over supported device types.
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
int(* transfer_get_formats)(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
AVBufferRef * source_device
For a derived device, a reference to the original device context it was derived from.
int(* device_init)(AVHWDeviceContext *ctx)
AVHWDeviceInternal * internal
Private data used internally by libavutil.
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.
static const AVClass hwdevice_ctx_class
int(* frames_init)(AVHWFramesContext *ctx)
const HWContextType ff_hwcontext_type_d3d11va
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
const HWContextType ff_hwcontext_type_dxva2
AVPixelFormat
Pixel format.
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().
void * av_mallocz_array(size_t nmemb, size_t size)
const HWContextType ff_hwcontext_type_vaapi