@ -24,7 +24,12 @@
# define CGS 32
typedef struct HFlipVulkanContext {
enum FlipType {
FLIP_VERTICAL ,
FLIP_HORIZONTAL
} ;
typedef struct FlipVulkanContext {
FFVulkanContext vkctx ;
FFVkQueueFamilyCtx qf ;
FFVkExecContext * exec ;
@ -34,13 +39,13 @@ typedef struct HFlipVulkanContext {
VkDescriptorImageInfo output_images [ 3 ] ;
int initialized ;
} H FlipVulkanContext;
} FlipVulkanContext ;
static av_cold int init_filter ( AVFilterContext * av ctx, AVFrame * in )
static av_cold int init_filter ( AVFilterContext * ctx , AVFrame * in , enum FlipType type )
{
int err = 0 ;
FFVkSPIRVShader * shd ;
H FlipVulkanContext * s = av ctx- > priv ;
FlipVulkanContext * s = ctx - > priv ;
FFVulkanContext * vkctx = & s - > vkctx ;
const int planes = av_pix_fmt_count_planes ( s - > vkctx . output_format ) ;
@ -76,26 +81,37 @@ static av_cold int init_filter(AVFilterContext *avctx, AVFrame *in)
if ( ! s - > pl )
return AVERROR ( ENOMEM ) ;
shd = ff_vk_init_shader ( s - > pl , " h flip_compute" , image_descs [ 0 ] . stages ) ;
shd = ff_vk_init_shader ( s - > pl , " flip_compute " , image_descs [ 0 ] . stages ) ;
if ( ! shd )
return AVERROR ( ENOMEM ) ;
ff_vk_set_compute_shader_sizes ( shd , ( int [ 3 ] ) { CGS , 1 , 1 } ) ;
RET ( ff_vk_add_descriptor_set ( vkctx , s - > pl , shd , image_descs , FF_ARRAY_ELEMS ( image_descs ) , 0 ) ) ;
GLSLC ( 0 , void main ( ) ) ;
GLSLC ( 0 , { ) ;
GLSLC ( 1 , ivec2 size ; ) ;
GLSLC ( 1 , const ivec2 pos = ivec2 ( gl_GlobalInvocationID . xy ) ; ) ;
GLSLC ( 0 , void main ( ) ) ;
GLSLC ( 0 , { ) ;
GLSLC ( 1 , ivec2 size ; ) ;
GLSLC ( 1 , const ivec2 pos = ivec2 ( gl_GlobalInvocationID . xy ) ; ) ;
for ( int i = 0 ; i < planes ; i + + ) {
GLSLC ( 0 , ) ;
GLSLF ( 1 , size = imageSize ( output_image [ % i ] ) ; , i ) ;
GLSLC ( 1 , if ( IS_WITHIN ( pos , size ) ) { ) ;
GLSLF ( 2 , vec4 res = texture ( input_image [ % i ] , ivec2 ( size . x - pos . x , pos . y ) ) ; , i ) ;
GLSLF ( 2 , imageStore ( output_image [ % i ] , pos , res ) ; , i ) ;
GLSLC ( 1 , } ) ;
GLSLC ( 0 , ) ;
GLSLF ( 1 , size = imageSize ( output_image [ % i ] ) ; , i ) ;
GLSLC ( 1 , if ( IS_WITHIN ( pos , size ) ) { ) ;
switch ( type )
{
case FLIP_HORIZONTAL :
GLSLF ( 2 , vec4 res = texture ( input_image [ % i ] , ivec2 ( size . x - pos . x , pos . y ) ) ; , i ) ;
break ;
case FLIP_VERTICAL :
GLSLF ( 2 , vec4 res = texture ( input_image [ % i ] , ivec2 ( pos . x , size . y - pos . y ) ) ; , i ) ;
break ;
default :
GLSLF ( 2 , vec4 res = texture ( input_image [ % i ] , pos ) ; , i ) ;
break ;
}
GLSLF ( 2 , imageStore ( output_image [ % i ] , pos , res ) ; , i ) ;
GLSLC ( 1 , } ) ;
}
GLSLC ( 0 , } ) ;
GLSLC ( 0 , } ) ;
RET ( ff_vk_compile_shader ( vkctx , shd , " main " ) ) ;
RET ( ff_vk_init_pipeline_layout ( vkctx , s - > pl ) ) ;
@ -109,9 +125,9 @@ fail:
return err ;
}
static av_cold void h flip_vulkan_uninit( AVFilterContext * avctx )
static av_cold void flip_vulkan_uninit ( AVFilterContext * avctx )
{
H FlipVulkanContext * s = avctx - > priv ;
FlipVulkanContext * s = avctx - > priv ;
ff_vk_uninit ( & s - > vkctx ) ;
s - > initialized = 0 ;
@ -121,7 +137,7 @@ static int process_frames(AVFilterContext *avctx, AVFrame *outframe, AVFrame *in
{
int err = 0 ;
VkCommandBuffer cmd_buf ;
H FlipVulkanContext * s = avctx - > priv ;
FlipVulkanContext * s = avctx - > priv ;
FFVulkanContext * vkctx = & s - > vkctx ;
FFVulkanFunctions * vk = & s - > vkctx . vkfn ;
AVVkFrame * in = ( AVVkFrame * ) inframe - > data [ 0 ] ;
@ -210,12 +226,12 @@ fail:
return err ;
}
static int h flip_vulkan_filter_frame( AVFilterLink * link , AVFrame * in )
static int flip_vulkan_filter_frame ( AVFilterLink * link , AVFrame * in , enum FlipType type )
{
int err ;
AVFrame * out = NULL ;
AVFilterContext * ctx = link - > dst ;
H FlipVulkanContext * s = ctx - > priv ;
FlipVulkanContext * s = ctx - > priv ;
AVFilterLink * outlink = ctx - > outputs [ 0 ] ;
out = ff_get_video_buffer ( outlink , outlink - > w , outlink - > h ) ;
@ -225,7 +241,7 @@ static int hflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
}
if ( ! s - > initialized )
RET ( init_filter ( ctx , in ) ) ;
RET ( init_filter ( ctx , in , type ) ) ;
RET ( process_frames ( ctx , out , in ) ) ;
@ -241,6 +257,16 @@ fail:
return err ;
}
static int hflip_vulkan_filter_frame ( AVFilterLink * link , AVFrame * in )
{
return flip_vulkan_filter_frame ( link , in , FLIP_HORIZONTAL ) ;
}
static int vflip_vulkan_filter_frame ( AVFilterLink * link , AVFrame * in )
{
return flip_vulkan_filter_frame ( link , in , FLIP_VERTICAL ) ;
}
static const AVOption hflip_vulkan_options [ ] = {
{ NULL } ,
} ;
@ -256,7 +282,7 @@ static const AVFilterPad hflip_vulkan_inputs[] = {
}
} ;
static const AVFilterPad h flip_vulkan_outputs[ ] = {
static const AVFilterPad flip_vulkan_outputs [ ] = {
{
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
@ -267,12 +293,40 @@ static const AVFilterPad hflip_vulkan_outputs[] = {
const AVFilter ff_vf_hflip_vulkan = {
. name = " hflip_vulkan " ,
. description = NULL_IF_CONFIG_SMALL ( " Horizontally flip the input video in Vulkan " ) ,
. priv_size = sizeof ( H FlipVulkanContext) ,
. priv_size = sizeof ( FlipVulkanContext ) ,
. init = & ff_vk_filter_init ,
. uninit = & h flip_vulkan_uninit,
. uninit = & flip_vulkan_uninit ,
FILTER_INPUTS ( hflip_vulkan_inputs ) ,
FILTER_OUTPUTS ( h flip_vulkan_outputs) ,
FILTER_OUTPUTS ( flip_vulkan_outputs ) ,
FILTER_SINGLE_PIXFMT ( AV_PIX_FMT_VULKAN ) ,
. priv_class = & hflip_vulkan_class ,
. flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE ,
} ;
static const AVOption vflip_vulkan_options [ ] = {
{ NULL } ,
} ;
AVFILTER_DEFINE_CLASS ( vflip_vulkan ) ;
static const AVFilterPad vflip_vulkan_inputs [ ] = {
{
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
. filter_frame = & vflip_vulkan_filter_frame ,
. config_props = & ff_vk_filter_config_input ,
}
} ;
const AVFilter ff_vf_vflip_vulkan = {
. name = " vflip_vulkan " ,
. description = NULL_IF_CONFIG_SMALL ( " Vertically flip the input video in Vulkan " ) ,
. priv_size = sizeof ( FlipVulkanContext ) ,
. init = & ff_vk_filter_init ,
. uninit = & flip_vulkan_uninit ,
FILTER_INPUTS ( vflip_vulkan_inputs ) ,
FILTER_OUTPUTS ( flip_vulkan_outputs ) ,
FILTER_SINGLE_PIXFMT ( AV_PIX_FMT_VULKAN ) ,
. priv_class = & vflip_vulkan_class ,
. flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE ,
} ;