[FFmpeg-devel] [PATCH] avfilter: Added siti filter

Anton Khirnov anton at khirnov.net
Tue Feb 15 10:54:47 EET 2022


Quoting Thilo Borgmann (2022-02-12 11:55:39)
> Am 31.01.22 um 12:55 schrieb James Almer:
> +static int config_input(AVFilterLink *inlink)
> +{
> +    // Video input data avilable
> +    AVFilterContext *ctx = inlink->dst;
> +    SiTiContext *s = ctx->priv;
> +    int max_pixsteps[4];
> +    size_t pixel_sz;
> +    size_t data_sz;
> +    size_t gradient_sz;
> +    size_t motion_sz;
> +
> +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
> +    av_image_fill_max_pixsteps(max_pixsteps, NULL, desc);
> +
> +    s->pixel_depth = max_pixsteps[0];
> +    s->width = inlink->w;
> +    s->height = inlink->h;
> +    pixel_sz = s->pixel_depth == 1 ? sizeof(uint8_t) : sizeof(uint16_t);
> +    data_sz = s->width * pixel_sz * s->height;
> +
> +    s->prev_frame = av_malloc(data_sz);
> +
> +    gradient_sz = (s->width - 2) * sizeof(double) * (s->height - 2);
> +    s->gradient_matrix = (double*)av_malloc(gradient_sz);
> +
> +    motion_sz = s->width * sizeof(double) * s->height;
> +    s->motion_matrix = (double*)av_malloc(motion_sz);

useless casts

> +
> +    if (!s->prev_frame || ! s->gradient_matrix || !s->motion_matrix) {
> +        av_freep(&s->prev_frame);
> +        av_freep(&s->gradient_matrix);
> +        av_freep(&s->motion_matrix);

You don't need to free them on failure, that will be done in uninit. But
you should free them at the beginning of this function, because
config_input can be called multiple times.

> +// Applies sobel convolution
> +static void convolve_sobel(SiTiContext *s, const uint8_t *src, double *dst, int linesize)
> +{
> +    double x_conv_sum;
> +    double y_conv_sum;
> +    double gradient;
> +    int ki;
> +    int kj;
> +    int index;
> +    uint16_t data;
> +    int filter_width = 3;
> +    int filter_size = filter_width * filter_width;
> +    int stride = linesize / s->pixel_depth;
> +
> +    // Dst matrix is smaller than src since we ignore edges that can't be convolved
> +    #define CONVOLVE(bps)                                           \
> +    {                                                               \
> +        uint##bps##_t *vsrc = (uint##bps##_t*)src;                  \
> +        for (int j = 1; j < s->height - 1; j++) {                   \
> +            for (int i = 1; i < s->width - 1; i++) {                \
> +                x_conv_sum = 0.0;                                   \
> +                y_conv_sum = 0.0;                                   \
> +                for (int k = 0; k < filter_size; k++) {             \
> +                    ki = k % filter_width - 1;                      \
> +                    kj = floor(k / filter_width) - 1;               \
> +                    index = (j + kj) * stride + (i + ki);           \
> +                    data = convert_full_range(s, vsrc[index]);      \

Pass bps as a parameter to convert_full_range() instead of accessing
s->pixel_depth, so the compiler can optimize the branch away.

> +// Calculate pixel difference between current and previous frame, and update previous
> +static void calculate_motion(SiTiContext *s, const uint8_t *curr,
> +                             double *motion_matrix, int linesize)
> +{
> +    int stride = linesize / s->pixel_depth;
> +    double motion;
> +    int curr_index;
> +    int prev_index;
> +    uint16_t curr_data;
> +
> +    // Previous frame is already converted to full range
> +    #define CALCULATE(bps)                                           \
> +    {                                                                \
> +        uint##bps##_t *vsrc = (uint##bps##_t*)curr;                  \
> +        for (int j = 0; j < s->height; j++) {                        \
> +            for (int i = 0; i < s->width; i++) {                     \
> +                motion = 0;                                          \
> +                curr_index = j * stride + i;                         \
> +                prev_index = j * s->width + i;                       \
> +                curr_data = convert_full_range(s, vsrc[curr_index]); \
> +                if (s->nb_frames > 1)                                \
> +                    motion = curr_data - s->prev_frame[prev_index];  \
> +                s->prev_frame[prev_index] = curr_data;               \

previous code accessed this as uint8_t or uint16_t based on bps

-- 
Anton Khirnov


More information about the ffmpeg-devel mailing list