37typedef struct V360ulkanContext {
78 for (
int i = 0;
i < 3;
i++) {
79 for (
int j = 0; j < 3; j++) {
81 for (
int k = 0; k < 3; k++)
82 sum +=
a[
i][k] *
b[k][j];
88#define degree2radian(degree) ((degree) * M_PI / 180.f)
89#define radian2degree(radian) ((radian) * 180.f / M_PI)
137 const int rotation_order[3])
139 const float yaw_rad = yaw *
M_PI / 180.f;
140 const float pitch_rad = pitch *
M_PI / 180.f;
141 const float roll_rad = roll *
M_PI / 180.f;
143 const float sin_yaw = sinf(yaw_rad);
144 const float cos_yaw = cosf(yaw_rad);
145 const float sin_pitch = sinf(pitch_rad);
146 const float cos_pitch = cosf(pitch_rad);
147 const float sin_roll = sinf(roll_rad);
148 const float cos_roll = cosf(roll_rad);
153 m[0][0][0] = cos_yaw; m[0][0][1] = 0; m[0][0][2] = sin_yaw;
154 m[0][1][0] = 0; m[0][1][1] = 1; m[0][1][2] = 0;
155 m[0][2][0] = -sin_yaw; m[0][2][1] = 0; m[0][2][2] = cos_yaw;
157 m[1][0][0] = 1; m[1][0][1] = 0; m[1][0][2] = 0;
158 m[1][1][0] = 0; m[1][1][1] = cos_pitch; m[1][1][2] = -sin_pitch;
159 m[1][2][0] = 0; m[1][2][1] = sin_pitch; m[1][2][2] = cos_pitch;
161 m[2][0][0] = cos_roll; m[2][0][1] = -sin_roll; m[2][0][2] = 0;
162 m[2][1][0] = sin_roll; m[2][1][1] = cos_roll; m[2][1][2] = 0;
163 m[2][2][0] = 0; m[2][2][1] = 0; m[2][2][2] = 1;
177 if (
s->ih_fov == 0.f &&
s->iv_fov == 0.f) {
181 else if (
s->ih_fov == 0.f ||
s->ih_fov >= 180.f) {
182 if (
s->iv_fov >= 180.f)
183 s->ih_fov =
s->iv_fov = 180.f;
187 else if (
s->iv_fov == 0.f ||
s->iv_fov >= 180.f) {
188 if (
s->ih_fov >= 180.f)
189 s->ih_fov =
s->iv_fov = 180.f;
198 if (
s->ih_fov == 0.f)
200 if (
s->iv_fov == 0.f)
209 if (
s->ih_fov == 0.f)
211 if (
s->iv_fov == 0.f)
218 if (
s->width > 0 &&
s->height > 0 &&
219 (
s->h_fov == 0.f ||
s->h_fov >= 180.f ||
s->v_fov == 0.f ||
s->v_fov >= 180.f)) {
220 if (
s->h_fov == 0.f &&
s->v_fov == 0.f) {
224 else if (
s->h_fov == 0.f ||
s->h_fov >= 180.f) {
225 if (
s->v_fov >= 180.f)
226 s->h_fov =
s->v_fov = 180.f;
230 else if (
s->v_fov == 0.f ||
s->v_fov >= 180.f) {
231 if (
s->h_fov >= 180.f)
232 s->h_fov =
s->v_fov = 180.f;
238 if (
s->h_fov >= 180.f ||
s->v_fov >= 180.f) {
266 for (
int order = 0; order <
NB_RORDERS; order++) {
267 const char c =
s->rorder[order];
272 "Incomplete rorder option. "
273 "Direction for all 3 rotation orders should be specified. "
274 "Switching to default rorder.\n");
275 s->rotation_order[0] =
YAW;
276 s->rotation_order[1] =
PITCH;
277 s->rotation_order[2] =
ROLL;
284 "Incorrect rotation order symbol '%c' in rorder option. "
285 "Switching to default rorder.\n",
c);
286 s->rotation_order[0] =
YAW;
287 s->rotation_order[1] =
PITCH;
288 s->rotation_order[2] =
ROLL;
291 s->rotation_order[order] = rorder;
297 s->pd.rot_mat,
s->rotation_order);
310 float wf = (
float)
s->width;
312 int min_w, min_h, pw,
ph;
314 if (
s->width > 0 &&
s->height > 0) {
325 else if (
s->width > 0 &&
s->height == 0) {
336 hf = wf *
s->pd.iflat_range[1] * 2.f;
343 hf = wf * sar / 3.f * 2.f;
358 if (
s->height == 0) {
361 hf = (
float)inlink->
h /
s->pd.iflat_range[1] / 2.f;
372 hf = (
float)inlink->
h *
s->pd.flat_range[1] * 2.f;
383 wf =
hf *
s->pd.flat_range[0] * 2.f;
407 "Output dimensions %dx%d are outside the allowed range [1, %d].\n",
429 if (pw < min_w ||
ph < min_h) {
431 "Output %dx%d is too small for the output projection "
432 "(requires at least %dx%d per plane).\n", pw,
ph, min_w, min_h);
474 int cube_size = in->
height;
475 int gopro_cube_width = (in->
width - cube_size) / 2;
487 sl, (uint32_t []) { 16, 16, 1 }, 0);
490 VK_SHADER_STAGE_COMPUTE_BIT);
494 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
495 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
499 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
500 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
505 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
506 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
534 for (
int i = 0;
i <
ctx->nb_inputs;
i++) {
546 if (!
s->initialized) {
548 for (
int i = 1;
i <
ctx->nb_inputs;
i++) {
552 "from input 0\n",
i);
561 in,
ctx->nb_inputs,
s->sampler, 1,
562 &
s->pd,
sizeof(
s->pd)));
579 char *res,
int res_len,
int flags)
599 if (
s->overlap == 0) {
600 if (inlink->
h <= 960) {
603 else if (inlink->
h < 1920) {
609 if (
ctx->nb_inputs != 2) {
613 if ((inlink->
w !=
ctx->inputs[1]->w) ||
614 (inlink->
h !=
ctx->inputs[1]->h) ||
615 (inlink->
w < inlink->
h * 3) ||
616 (inlink->
w > inlink->
h * 3 +
s->overlap * 2)) {
618 inlink->
w, inlink->
h,
ctx->inputs[1]->w,
ctx->inputs[1]->h);
622 else if (
ctx->nb_inputs != 1) {
632 for (
int i = 0;
i <
ctx->nb_inputs;
i++) {
633 s->fs.in[
i].time_base =
ctx->inputs[
i]->time_base;
634 s->fs.in[
i].sync = 1;
663 pad.
name =
"default";
692#define OFFSET(x) offsetof(V360VulkanContext, x)
693#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
694#define DYNAMIC (FLAGS | AV_OPT_FLAG_RUNTIME_PARAM)
740 .p.name =
"v360_vulkan",
742 .p.priv_class = &v360_vulkan_class,
745 .
preinit = v360_vulkan_framesync_preinit,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t * hf
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
const FFFilter ff_vf_v360_vulkan
static AVFormatContext * ctx
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
Append a new input/output pad to the filter's list of such pads.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static int FUNC ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
#define fs(width, name, subs,...)
#define AV_CEIL_RSHIFT(a, b)
int(* init)(AVBSFContext *ctx)
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
#define FRAMESYNC_DEFINE_CLASS(name, context, field)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_always_inline uint32_t av_float2int(float f)
Reinterpret a float as a 32-bit integer.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
#define FILTER_OUTPUTS(array)
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt)
Create a sampler.
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
static const struct @257111027162314367033347246032313251342043035002 planes[]
@ EXT_STOP
Completely stop all streams with this one.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
static av_cold int preinit(AVBitStreamFilterContext *ctx)
void * priv
private data for use by the filter
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
A filter pad used for either input or output.
const char * name
Pad name.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
This struct describes a set or pool of "hardware" frames (i.e.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
VkDevice act_dev
Active device.
AVVulkanDeviceContext * hwctx
AVVulkanDeviceQueueFamily * qf
static int v360_vulkan_activate(AVFilterContext *ctx)
static const AVOption v360_vulkan_options[]
static const AVFilterPad v360_vulkan_outputs[]
static av_cold int v360_vulkan_config_output(AVFilterLink *outlink)
static void v360_vulkan_uninit(AVFilterContext *avctx)
#define radian2degree(radian)
const unsigned char ff_v360_comp_spv_data[]
static void calculate_iflat_range(int in, float ih_fov, float iv_fov, float *iflat_range)
static void calculate_rotation_matrix(float yaw, float pitch, float roll, float rot_mat[4][4], const int rotation_order[3])
static void config_params(AVFilterContext *ctx, AVFilterLink *inlink)
const unsigned int ff_v360_comp_spv_len
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
#define degree2radian(degree)
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
static void calculate_flat_range(int out, float h_fov, float v_fov, float *flat_range)
static int v360_vulkan_filter_frame(FFFrameSync *fs)
static av_cold int v360_vulkan_init(AVFilterContext *avctx)
static void multiply_matrix(float c[4][4], const float a[4][4], const float b[4][4])
static int get_rorder(char c)
static av_cold int calculate_output_size(AVFilterContext *ctx)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
#define FF_VK_DEFAULT_EXEC_CONTEXTS
#define SPEC_LIST_ADD(name, idx, val_bits, val)
#define SPEC_LIST_CREATE(name, max_length, max_size)
int ff_vk_filter_config_input(AVFilterLink *inlink)
int ff_vk_filter_config_output(AVFilterLink *outlink)
int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, FFVulkanShader *shd, AVFrame *out, AVFrame *in[], int nb_in, VkSampler sampler, uint32_t wgc_z, void *push_src, size_t push_size)
Up to 16 inputs, one output.
int ff_vk_filter_init(AVFilterContext *avctx)
General lavfi IO functions.