[FFmpeg-devel] [PATCH v2 7/8] avfilter/sleet: Add sleet filter

Mapul Bhola ffmpegandmahanstreamer at e.email
Wed Sep 1 00:39:05 EEST 2021


August 30, 2021 4:17 AM, "Soft Works" <softworkz at hotmail.com> wrote:

> Signed-off-by: softworkz <softworkz at hotmail.com>
> ---
> v2 Update:
> 
> - Implemented Andreas' suggestions
> - overlay_subs filter:
> - removed duplicated code
> - implemented direct (no pre-conversion) blending of graphical
> subtitle rects
> - Supported input formats:
> - all packed RGB formats (with and without alpha)
> - yuv420p, yuv422p, yuv444p
> 
> libavfilter/Makefile | 3 +
> libavfilter/allfilters.c | 1 +
> libavfilter/sf_sleet.c | 209 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 213 insertions(+)
> create mode 100644 libavfilter/sf_sleet.c
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index e38c6b6f6d..25dd1276de 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -526,6 +526,9 @@ OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o
> 
> OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
> 
> +# subtitle filters
> +OBJS-$(CONFIG_SLEET_FILTER) += sf_sleet.o
> +
> # multimedia filters
> OBJS-$(CONFIG_ABITSCOPE_FILTER) += avf_abitscope.o
> OBJS-$(CONFIG_ADRAWGRAPH_FILTER) += f_drawgraph.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index 5bd54db2c8..efe16b8e1b 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -519,6 +519,7 @@ extern const AVFilter ff_avf_showwaves;
> extern const AVFilter ff_avf_showwavespic;
> extern const AVFilter ff_vaf_spectrumsynth;
> extern const AVFilter ff_svf_sub2video;
> +extern const AVFilter ff_sf_sleet;
> 
> /* multimedia sources */
> extern const AVFilter ff_avsrc_amovie;
> diff --git a/libavfilter/sf_sleet.c b/libavfilter/sf_sleet.c
> new file mode 100644
> index 0000000000..cf7701c01f
> --- /dev/null
> +++ b/libavfilter/sf_sleet.c
> @@ -0,0 +1,209 @@
> +/*
> + * Copyright (c) 2021 softworkz
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * text subtitle filter which translates to 'leet speak'
> + */
> +
> +#include "libavutil/avassert.h"
> +#include "libavutil/avstring.h"
> +#include "libavutil/opt.h"
> +#include "avfilter.h"
> +#include "internal.h"
> +#include "libavcodec/avcodec.h"
> +
> +static const char* alphabet_src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
> +static const char* alphabet_dst = "abcd3f6#1jklmn0pq257uvwxyzAB(D3F6#1JKLMN0PQ257UVWXYZ";
> +
> +
> +typedef struct LeetContext {
> + const AVClass *class;
> + enum AVSubtitleType format;
> +} LeetContext;
> +
> +static const AVOption sleet_options[] = {
> + { NULL }
> +};
> +
> +AVFILTER_DEFINE_CLASS(sleet);
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> + AVFilterFormats *formats = NULL;
> + AVFilterLink *inlink = ctx->inputs[0];
> + AVFilterLink *outlink = ctx->outputs[0];
> + static const enum AVSubtitleType subtitle_fmts[] = { SUBTITLE_ASS, SUBTITLE_NONE };
> + static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE };
> + int ret;
> +
> + /* set input subtitle format */
> + formats = ff_make_format_list(subtitle_fmts);
> + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
> + return ret;
> +
> + /* set output video format */
> + formats = ff_make_format_list(pix_fmts);
> + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int config_input(AVFilterLink *inlink)
> +{
> + AVFilterContext *ctx = inlink->dst;
> + LeetContext *s = ctx->priv;
> +
> + s->format = inlink->format;
> + return 0;
> +}
> +
> +static int config_output(AVFilterLink *outlink)
> +{
> + LeetContext *s = outlink->src->priv;
> +
> + outlink->format = s->format;
> +
> + return 0;
> +}
> +
> +static void avsubtitle_free_ref(void *opaque, uint8_t *data)
> +{
> + avsubtitle_free((AVSubtitle *)data);
> +}
> +
> +static int filter_frame(AVFilterLink *inlink, AVFrame *src_frame)
> +{
> + LeetContext *s = inlink->dst->priv;
> + AVFilterLink *outlink = inlink->dst->outputs[0];
> + AVSubtitle *sub;
> + int ret;
> + AVFrame *out;
> + unsigned int num_rects;
> + uint8_t *dst;
> +
> + outlink->format = inlink->format;
> +
> + out = av_frame_alloc();
> + if (!out) {
> + av_frame_free(&src_frame);
> + return AVERROR(ENOMEM);
> + }
> +
> + out->format = outlink->format;
> +
> + if ((ret = av_frame_get_buffer2(out, AVMEDIA_TYPE_SUBTITLE, 0)) < 0)
> + return ret;
> +
> + out->pts = src_frame->pts;
> + out->repeat_pict = src_frame->repeat_pict;
> + out->pkt_dts = src_frame->pkt_dts;
> + out->pkt_pos = src_frame->pkt_pos;
> + out->pkt_size = src_frame->pkt_size;
> + out->pkt_duration = src_frame->pkt_duration;
> + out->reordered_opaque = src_frame->reordered_opaque;
> + out->best_effort_timestamp = src_frame->best_effort_timestamp;
> + out->flags = src_frame->flags;
> +
> + sub = (AVSubtitle *)src_frame->data[0];
> +
> + if (sub) {
> + AVSubtitle *out_sub = av_memdup(sub, sizeof(*out_sub));
> + if (!out_sub)
> + return AVERROR(ENOMEM);
> +
> + out->buf[0] = av_buffer_create((uint8_t*)out_sub, sizeof(*out_sub), avsubtitle_free_ref, NULL,
> AV_BUFFER_FLAG_READONLY);
> + out->data[0] = (uint8_t*)out_sub;
> +
> + if (sub->num_rects) {
> + out_sub->rects = av_malloc_array(sub->num_rects, sizeof(AVSubtitleRect *));
> + }
> +
> + for (unsigned i = 0; i < sub->num_rects; i++) {
> +
> + AVSubtitleRect *src_rect = sub->rects[i];
> + AVSubtitleRect *dst_rect = av_memdup(src_rect, sizeof(*dst_rect));
> + out_sub->rects[i] = dst_rect;
> +
> + if (src_rect->text) {
> + dst_rect->text = av_strdup(src_rect->text);
> + if (!dst_rect->text)
> + return AVERROR(ENOMEM);
> +
> + for (size_t n = 0; n < strlen(dst_rect->text); n++) {
> + for (size_t t = 0; t < FF_ARRAY_ELEMS(alphabet_src); t++) {
> + if (dst_rect->text[n] == alphabet_src[t]) {
> + dst_rect->text[n] = alphabet_dst[t];
> + break;
> + }
> + }
> + }
> + }
> +
> + if (src_rect->ass) {
> + dst_rect->ass = av_strdup(src_rect->ass);
> + if (!dst_rect->ass)
> + return AVERROR(ENOMEM);
> +
> + for (size_t n = 0; n < strlen(dst_rect->ass); n++) {
> + for (size_t t = 0; t < FF_ARRAY_ELEMS(alphabet_src); t++) {
> + if (dst_rect->ass[n] == alphabet_src[t]) {
> + dst_rect->ass[n] = alphabet_dst[t];
> + break;
> + }
> + }
> + }
> + }
> + }
> + }
> +
> + av_frame_free(&src_frame);
> + return ff_filter_frame(outlink, out);
> +}
> +
> +static const AVFilterPad sleet_inputs[] = {
> + {
> + .name = "default",
> + .type = AVMEDIA_TYPE_SUBTITLE,
> + .filter_frame = filter_frame,
> + .config_props = config_input,
> + },
> + { NULL }
> +};
> +
> +static const AVFilterPad sleet_outputs[] = {
> + {
> + .name = "default",
> + .type = AVMEDIA_TYPE_SUBTITLE,
> + .config_props = config_output,
> + },
> + { NULL }
> +};
> +
> +const AVFilter ff_sf_sleet = {
> + .name = "sleet",
> + .description = NULL_IF_CONFIG_SMALL("Translate text subtitles to 'leet speak'"),
> + .query_formats = query_formats,
> + .priv_size = sizeof(LeetContext),
> + .priv_class = &sleet_class,
> + .inputs = sleet_inputs,
> + .outputs = sleet_outputs,
> +};
> -- 
> 2.30.2.windows.1
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".

Softworkz, I like ya, I like ya patches, and the effort your putting into the FFMpeg project, but I just don't think this is necessary. Contributes to overhead/maintence for what is essentially a gimmick feature.

Code itself loks good to me


More information about the ffmpeg-devel mailing list