FFmpeg
vulkan_filter.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 "vulkan_filter.h"
20 
22  AVBufferRef *device)
23 {
24  FFVulkanContext *s = avctx->priv;
25 
26  av_buffer_unref(&s->device_ref);
27 
28  s->device_ref = av_buffer_ref(device);
29  if (!s->device_ref)
30  return AVERROR(ENOMEM);
31 
32  s->device = (AVHWDeviceContext*)s->device_ref->data;
33  s->hwctx = s->device->hwctx;
34 
35  return 0;
36 }
37 
40 {
41  FFVulkanContext *s = avctx->priv;
42 
43  av_buffer_unref(&s->frames_ref);
44 
45  s->frames_ref = av_buffer_ref(frames);
46  if (!s->frames_ref)
47  return AVERROR(ENOMEM);
48 
49  return 0;
50 }
51 
53 {
54  int err;
55  AVFilterContext *avctx = inlink->dst;
56  FFVulkanContext *s = avctx->priv;
57  FFVulkanFunctions *vk = &s->vkfn;
58  AVHWFramesContext *input_frames;
59 
60  if (!inlink->hw_frames_ctx) {
61  av_log(avctx, AV_LOG_ERROR, "Vulkan filtering requires a "
62  "hardware frames context on the input.\n");
63  return AVERROR(EINVAL);
64  }
65 
66  /* Extract the device and default output format from the first input. */
67  if (avctx->inputs[0] != inlink)
68  return 0;
69 
70  input_frames = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
71  if (input_frames->format != AV_PIX_FMT_VULKAN)
72  return AVERROR(EINVAL);
73 
74  err = vulkan_filter_set_device(avctx, input_frames->device_ref);
75  if (err < 0)
76  return err;
77  err = vulkan_filter_set_frames(avctx, inlink->hw_frames_ctx);
78  if (err < 0)
79  return err;
80 
81  s->extensions = ff_vk_extensions_to_mask(s->hwctx->enabled_dev_extensions,
82  s->hwctx->nb_enabled_dev_extensions);
83 
84  err = ff_vk_load_functions(s->device, &s->vkfn, s->extensions, 1, 1);
85  if (err < 0)
86  return err;
87 
88  vk->GetPhysicalDeviceProperties(s->hwctx->phys_dev, &s->props);
89  vk->GetPhysicalDeviceMemoryProperties(s->hwctx->phys_dev, &s->mprops);
90 
91  /* Default output parameters match input parameters. */
92  s->input_format = input_frames->sw_format;
93  if (s->output_format == AV_PIX_FMT_NONE)
94  s->output_format = input_frames->sw_format;
95  if (!s->output_width)
96  s->output_width = inlink->w;
97  if (!s->output_height)
98  s->output_height = inlink->h;
99 
100  return 0;
101 }
102 
104 {
105  int err;
106  AVFilterContext *avctx = outlink->src;
107  FFVulkanContext *s = avctx->priv;
108 
109  av_buffer_unref(&outlink->hw_frames_ctx);
110 
111  if (!s->device_ref) {
112  if (!avctx->hw_device_ctx) {
113  av_log(avctx, AV_LOG_ERROR, "Vulkan filtering requires a "
114  "Vulkan device.\n");
115  return AVERROR(EINVAL);
116  }
117 
118  err = vulkan_filter_set_device(avctx, avctx->hw_device_ctx);
119  if (err < 0)
120  return err;
121  }
122 
123  outlink->hw_frames_ctx = av_buffer_ref(s->frames_ref);
124  if (!outlink->hw_frames_ctx)
125  return AVERROR(ENOMEM);
126 
127  outlink->w = s->output_width;
128  outlink->h = s->output_height;
129 
130  return 0;
131 }
132 
134 {
135  int err;
136  AVFilterContext *avctx = outlink->src;
137  FFVulkanContext *s = avctx->priv;
138  AVBufferRef *output_frames_ref;
139  AVHWFramesContext *output_frames;
140 
141  av_buffer_unref(&outlink->hw_frames_ctx);
142 
143  if (!s->device_ref) {
144  if (!avctx->hw_device_ctx) {
145  av_log(avctx, AV_LOG_ERROR, "Vulkan filtering requires a "
146  "Vulkan device.\n");
147  return AVERROR(EINVAL);
148  }
149 
150  err = vulkan_filter_set_device(avctx, avctx->hw_device_ctx);
151  if (err < 0)
152  return err;
153  }
154 
155  output_frames_ref = av_hwframe_ctx_alloc(s->device_ref);
156  if (!output_frames_ref) {
157  err = AVERROR(ENOMEM);
158  goto fail;
159  }
160  output_frames = (AVHWFramesContext*)output_frames_ref->data;
161 
162  output_frames->format = AV_PIX_FMT_VULKAN;
163  output_frames->sw_format = s->output_format;
164  output_frames->width = s->output_width;
165  output_frames->height = s->output_height;
166 
167  err = av_hwframe_ctx_init(output_frames_ref);
168  if (err < 0) {
169  av_log(avctx, AV_LOG_ERROR, "Failed to initialise output "
170  "frames: %d.\n", err);
171  goto fail;
172  }
173 
174  outlink->hw_frames_ctx = output_frames_ref;
175  outlink->w = s->output_width;
176  outlink->h = s->output_height;
177 
178  return 0;
179 fail:
180  av_buffer_unref(&output_frames_ref);
181  return err;
182 }
183 
185 {
186  FFVulkanContext *s = avctx->priv;
187 
188  s->output_format = AV_PIX_FMT_NONE;
189 
190  return 0;
191 }
AVERROR
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
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:333
ff_vk_filter_init
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.
Definition: vulkan_filter.c:184
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:247
AVFilterContext::hw_device_ctx
AVBufferRef * hw_device_ctx
For filters which will create hardware frames, sets the device the filter should create them in.
Definition: avfilter.h:458
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:229
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:346
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:417
fail
#define fail()
Definition: checkasm.h:127
vulkan_filter.h
frames
if it could not because there are no more frames
Definition: filter_design.txt:266
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVHWFramesContext::height
int height
Definition: hwcontext.h:229
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_vk_load_functions
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
Definition: vulkan_loader.h:80
if
if(ret)
Definition: filter_design.txt:179
vulkan_filter_set_device
static int vulkan_filter_set_device(AVFilterContext *avctx, AVBufferRef *device)
Definition: vulkan_filter.c:21
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
av_buffer_unref
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
ff_vk_filter_config_output_inplace
int ff_vk_filter_config_output_inplace(AVFilterLink *outlink)
Definition: vulkan_filter.c:103
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:410
ff_vk_filter_config_output
int ff_vk_filter_config_output(AVFilterLink *outlink)
Definition: vulkan_filter.c:133
FFVulkanContext
Definition: vulkan.h:188
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
ff_vk_filter_config_input
int ff_vk_filter_config_input(AVFilterLink *inlink)
Definition: vulkan_filter.c:52
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
ff_vk_extensions_to_mask
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
Definition: vulkan_loader.h:34
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
vulkan_filter_set_frames
static int vulkan_filter_set_frames(AVFilterContext *avctx, AVBufferRef *frames)
Definition: vulkan_filter.c:38
FFVulkanFunctions
Definition: vulkan_functions.h:175