66 const int plane =
s->alpha ? 3 : 0;
88 (
int []) { 32, 32, 1 }, 0);
91 VK_SHADER_STAGE_COMPUTE_BIT);
95 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
96 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
100 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
101 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
113 s->black_min_duration =
s->black_min_duration_time /
av_q2d(
s->time_base);
128 if ((black_end -
s->black_start) >=
s->black_min_duration) {
130 "black_start:%s black_end:%s black_duration:%s\n",
143 uint64_t nb_black_pixels = 0;
149 ratio = (
double) nb_black_pixels / (link->
w * link->
h);
152 "frame:%"PRId64
" picture_black_ratio:%f pts:%s t:%s type:%c\n",
157 if (ratio >=
s->picture_black_ratio_th) {
159 s->black_start = in->
pts;
179 VkImageMemoryBarrier2 img_bar[4];
194 const int depth =
desc->comp[0].depth;
195 const int ymin = 16 << (depth - 8);
196 const int ymax = 235 << (depth - 8);
197 const int imax = (1 << depth) - 1;
198 push_data.
threshold = (
s->pixel_black_th * (ymax - ymin) + ymin) /
imax;
205 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
206 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
209 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
210 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
211 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
220 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
221 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
225 VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE);
228 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
229 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
230 VK_ACCESS_SHADER_READ_BIT,
231 VK_IMAGE_LAYOUT_GENERAL,
232 VK_QUEUE_FAMILY_IGNORED);
235 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
236 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
237 .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
238 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
239 .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
240 .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
241 .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
242 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
243 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
244 .buffer = sum_vk->buf,
245 .size = sum_vk->size,
248 .bufferMemoryBarrierCount = 1,
251 vk->CmdFillBuffer(exec->buf, sum_vk->buf, 0, sum_vk->size, 0x0);
253 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
254 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
255 .pImageMemoryBarriers = img_bar,
256 .imageMemoryBarrierCount = nb_img_bar,
257 .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
258 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
259 .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
260 .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
261 .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
262 .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
263 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
264 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
265 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
266 .buffer = sum_vk->buf,
267 .size = sum_vk->size,
270 .bufferMemoryBarrierCount = 1,
274 sum_vk, 0, sum_vk->size,
275 VK_FORMAT_UNDEFINED));
279 0,
sizeof(push_data), &push_data);
281 vk->CmdDispatch(exec->buf,
282 FFALIGN(in->width,
s->shd.lg_size[0]) /
s->shd.lg_size[0],
283 FFALIGN(in->height,
s->shd.lg_size[1]) /
s->shd.lg_size[1],
286 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
287 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
288 .pBufferMemoryBarriers = &(VkBufferMemoryBarrier2) {
289 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
290 .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
291 .dstStageMask = VK_PIPELINE_STAGE_2_HOST_BIT,
292 .srcAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
293 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
294 .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
295 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
296 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
297 .buffer = sum_vk->buf,
298 .size = sum_vk->size,
301 .bufferMemoryBarrierCount = 1,
307 s->last_pts = in->pts;
363#define OFFSET(x) offsetof(BlackDetectVulkanContext, x)
364#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
367 {
"black_min_duration",
"set minimum detected black duration in seconds",
OFFSET(black_min_duration_time),
AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX,
FLAGS },
368 {
"picture_black_ratio_th",
"set the picture black ratio threshold",
OFFSET(picture_black_ratio_th),
AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1,
FLAGS },
396 .p.name =
"blackdetect_vulkan",
398 .p.priv_class = &blackdetect_vulkan_class,
const FFFilter ff_vf_blackdetect_vulkan
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
#define i(width, name, range_min, range_max)
int(* init)(AVBSFContext *ctx)
#define AV_NUM_DATA_POINTERS
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
#define AV_NOPTS_VALUE
Undefined timestamp value.
static const int16_t alpha[]
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
#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...
static FilterLink * ff_filter_link(AVFilterLink *link)
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
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.
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
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_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
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.
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
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.
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
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.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
#define AV_PIX_FMT_FLAG_XYZ
The pixel format contains XYZ-like data (as opposed to YUV/RGB/grayscale).
@ AVCOL_RANGE_JPEG
Full range content.
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
#define FF_ARRAY_ELEMS(a)
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.
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
AVRational time_base
Time base for the timestamps in this frame.
AVDictionary * metadata
metadata.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
enum AVPictureType pict_type
Picture type of the frame.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint64_t flags
Combination of AV_PIX_FMT_FLAG_... flags.
Rational number (pair of numerator and denominator).
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
uint32_t slice_sum[SLICES]
int64_t black_start
pts start time of the first black picture
int64_t last_pts
pts of the last filtered frame
AVVulkanDeviceQueueFamily * qf
double black_min_duration_time
minimum duration of detected black, in seconds
double picture_black_ratio_th
AVRefStructPool * sum_buf_pool
int64_t black_min_duration
minimum duration of detected black, expressed in timebase units
enum AVPixelFormat input_format
Link properties exposed to filter code, but not external callers.
static int imax(const int a, const int b)
static AVFormatContext * ctx
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
static const AVFilterPad blackdetect_vulkan_inputs[]
const unsigned int ff_blackdetect_comp_spv_len
static av_cold int init_filter(AVFilterContext *ctx)
static const AVFilterPad blackdetect_vulkan_outputs[]
static void report_black_region(AVFilterContext *ctx, int64_t black_end)
static const AVOption blackdetect_vulkan_options[]
static void evaluate(AVFilterLink *link, AVFrame *in, const BlackDetectBuf *sum)
static int blackdetect_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
static void blackdetect_vulkan_uninit(AVFilterContext *avctx)
static int config_output(AVFilterLink *outlink)
const unsigned char ff_blackdetect_comp_spv_data[]
#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_init(AVFilterContext *avctx)
General lavfi IO functions.