FFmpeg
Loading...
Searching...
No Matches
vf_hwupload_cuda.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 "libavutil/buffer.h"
20#include "libavutil/hwcontext.h"
21#include "libavutil/log.h"
22#include "libavutil/opt.h"
23
24#include "avfilter.h"
25#include "filters.h"
26#include "formats.h"
27#include "video.h"
28
29enum {
33};
34
43
45{
46 CudaUploadContext *s = ctx->priv;
47 char buf[64] = { 0 };
48
49 snprintf(buf, sizeof(buf), "%d", s->device_idx);
50
51 return av_hwdevice_ctx_create(&s->hwdevice, AV_HWDEVICE_TYPE_CUDA, buf, NULL, 0);
52}
53
55{
56 CudaUploadContext *s = ctx->priv;
57
58 av_buffer_unref(&s->hwframe);
59 av_buffer_unref(&s->hwdevice);
60}
61
63 AVFilterFormatsConfig **cfg_in,
64 AVFilterFormatsConfig **cfg_out)
65{
66 const CudaUploadContext *s = ctx->priv;
67 int ret;
68
69 static const enum AVPixelFormat input_pix_fmts[] = {
76#if CONFIG_VULKAN
78#endif
80 };
81 static const enum AVPixelFormat output_cuda_fmts[] = {
83 };
84 static const enum AVPixelFormat output_cuarray_fmts[] = {
86 };
87 const enum AVPixelFormat *output_pix_fmts = s->output_format == CUDAUPLOAD_FMT_CUARRAY
88 ? output_cuarray_fmts
89 : output_cuda_fmts;
90 AVFilterFormats *in_fmts = ff_make_pixel_format_list(input_pix_fmts);
91 AVFilterFormats *out_fmts;
92
93 ret = ff_formats_ref(in_fmts, &cfg_in[0]->formats);
94 if (ret < 0)
95 return ret;
96
97 out_fmts = ff_make_pixel_format_list(output_pix_fmts);
98
99 ret = ff_formats_ref(out_fmts, &cfg_out[0]->formats);
100 if (ret < 0)
101 return ret;
102
103 return 0;
104}
105
107{
108 FilterLink *outl = ff_filter_link(outlink);
109 AVFilterContext *ctx = outlink->src;
110 AVFilterLink *inlink = ctx->inputs[0];
111 FilterLink *inl = ff_filter_link(inlink);
112 CudaUploadContext *s = ctx->priv;
113
114 AVHWFramesContext *hwframe_ctx;
115 int ret;
116
117 av_buffer_unref(&s->hwframe);
118 s->hwframe = av_hwframe_ctx_alloc(s->hwdevice);
119 if (!s->hwframe)
120 return AVERROR(ENOMEM);
121
122 hwframe_ctx = (AVHWFramesContext*)s->hwframe->data;
123 hwframe_ctx->format = s->output_format == CUDAUPLOAD_FMT_CUARRAY
125 if (inl->hw_frames_ctx) {
126 AVHWFramesContext *in_hwframe_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
127 hwframe_ctx->sw_format = in_hwframe_ctx->sw_format;
128 } else {
129 hwframe_ctx->sw_format = inlink->format;
130 }
131 hwframe_ctx->width = inlink->w;
132 hwframe_ctx->height = inlink->h;
133
134 ret = av_hwframe_ctx_init(s->hwframe);
135 if (ret < 0)
136 return ret;
137
138 outl->hw_frames_ctx = av_buffer_ref(s->hwframe);
139 if (!outl->hw_frames_ctx)
140 return AVERROR(ENOMEM);
141
142 return 0;
143}
144
146{
147 AVFilterContext *ctx = link->dst;
148 AVFilterLink *outlink = ctx->outputs[0];
149
150 AVFrame *out = NULL;
151 int ret;
152
153 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
154 if (!out) {
155 ret = AVERROR(ENOMEM);
156 goto fail;
157 }
158
159 out->width = in->width;
160 out->height = in->height;
161
162 ret = av_hwframe_transfer_data(out, in, 0);
163 if (ret < 0) {
164 av_log(ctx, AV_LOG_ERROR, "Error transferring data to the GPU\n");
165 goto fail;
166 }
167
168 ret = av_frame_copy_props(out, in);
169 if (ret < 0)
170 goto fail;
171
172 av_frame_free(&in);
173
174 return ff_filter_frame(ctx->outputs[0], out);
175fail:
176 av_frame_free(&in);
178 return ret;
179}
180
181#define OFFSET(x) offsetof(CudaUploadContext, x)
182#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
183static const AVOption cudaupload_options[] = {
184 { "device", "Number of the device to use", OFFSET(device_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
185 { "output_format", "Output frame format", OFFSET(output_format), AV_OPT_TYPE_INT, { .i64 = CUDAUPLOAD_FMT_CUDA }, 0, CUDAUPLOAD_FMT_NB - 1, FLAGS, .unit = "output_format" },
186 { "cuda", "Pitch-linear device memory (default)", 0, AV_OPT_TYPE_CONST, { .i64 = CUDAUPLOAD_FMT_CUDA }, .flags = FLAGS, .unit = "output_format" },
187 { "cuarray", "Block-linear CUDA array", 0, AV_OPT_TYPE_CONST, { .i64 = CUDAUPLOAD_FMT_CUARRAY }, .flags = FLAGS, .unit = "output_format" },
188 { NULL },
189};
190
192
194 {
195 .name = "default",
196 .type = AVMEDIA_TYPE_VIDEO,
197 .filter_frame = cudaupload_filter_frame,
198 },
199};
200
202 {
203 .name = "default",
204 .type = AVMEDIA_TYPE_VIDEO,
205 .config_props = cudaupload_config_output,
206 },
207};
208
210 .p.name = "hwupload_cuda",
211 .p.description = NULL_IF_CONFIG_SMALL("Upload a system memory frame to a CUDA device."),
212
213 .p.priv_class = &cudaupload_class,
214
215 .init = cudaupload_init,
216 .uninit = cudaupload_uninit,
217
218 .priv_size = sizeof(CudaUploadContext),
219
222
224
225 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
226};
const FFFilter ff_vf_hwupload_cuda
static FILE * out
static AVFormatContext * ctx
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
refcounted data buffer API
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
static char * output_format
Definition ffprobe.c:145
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add ref as a new reference to formats.
Definition formats.c:756
av_warn_unused_result AVFilterFormats * ff_make_pixel_format_list(const enum AVPixelFormat *fmts)
Create a list of supported pixel formats.
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
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:139
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
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:615
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition hwcontext.c:448
@ AV_HWDEVICE_TYPE_CUDA
Definition hwcontext.h:30
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition filters.h:208
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
AVOptions.
#define AV_PIX_FMT_0RGB32
Definition pixfmt.h:521
#define AV_PIX_FMT_P212
Definition pixfmt.h:624
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
#define AV_PIX_FMT_P412
Definition pixfmt.h:625
#define AV_PIX_FMT_P210
Definition pixfmt.h:622
#define AV_PIX_FMT_P216
Definition pixfmt.h:626
#define AV_PIX_FMT_P010
Definition pixfmt.h:608
#define AV_PIX_FMT_P016
Definition pixfmt.h:610
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_YUV444P12MSB
Definition pixfmt.h:561
#define AV_PIX_FMT_BGR32
Definition pixfmt.h:519
#define AV_PIX_FMT_P410
Definition pixfmt.h:623
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition pixfmt.h:260
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:371
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:198
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_CUARRAY
hardware decoding through openharmony
Definition pixfmt.h:506
#define AV_PIX_FMT_P416
Definition pixfmt.h:627
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:558
#define AV_PIX_FMT_YUV444P10MSB
Definition pixfmt.h:560
#define AV_PIX_FMT_0BGR32
Definition pixfmt.h:522
#define AV_PIX_FMT_RGB32
Definition pixfmt.h:517
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
formats
Definition signature.h:47
#define snprintf
Definition snprintf.h:34
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
Lists of formats / etc.
Definition avfilter.h:120
A list of supported formats for one end of a filter link.
Definition formats.h:64
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int width
Definition frame.h:544
int height
Definition frame.h:544
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
AVOption.
Definition opt.h:428
AVBufferRef * hwframe
AVBufferRef * hwdevice
#define av_log(a,...)
static av_cold void cudaupload_uninit(AVFilterContext *ctx)
static int cudaupload_filter_frame(AVFilterLink *link, AVFrame *in)
@ CUDAUPLOAD_FMT_CUDA
@ CUDAUPLOAD_FMT_NB
@ CUDAUPLOAD_FMT_CUARRAY
static int cudaupload_config_output(AVFilterLink *outlink)
static int cudaupload_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const AVFilterPad cudaupload_outputs[]
static const AVFilterPad cudaupload_inputs[]
static const AVOption cudaupload_options[]
static av_cold int cudaupload_init(AVFilterContext *ctx)
#define OFFSET(x)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89