Soft Works: > Signed-off-by: softworkz <softwo...@hotmail.com> > --- > configure | 2 +- > libavfilter/allfilters.c | 2 ++ > libavfilter/buffersink.c | 63 +++++++++++++++++++++++++++++++++++ > libavfilter/buffersink.h | 15 +++++++++ > libavfilter/buffersrc.c | 72 ++++++++++++++++++++++++++++++++++++++++ > libavfilter/buffersrc.h | 1 + > 6 files changed, 154 insertions(+), 1 deletion(-) > > diff --git a/configure b/configure > index d068b11073..e4d1443237 100755 > --- a/configure > +++ b/configure > @@ -7758,7 +7758,7 @@ print_enabled_components(){ > fi > done > if [ "$name" = "filter_list" ]; then > - for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do > + for c in asrc_abuffer vsrc_buffer ssrc_sbuffer asink_abuffer > vsink_buffer ssink_sbuffer; do > printf " &ff_%s,\n" $c >> $TMPH > done > fi > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 4bf17ef292..4072f08385 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -550,8 +550,10 @@ extern const AVFilter ff_avsrc_movie; > * being the same while having different 'types'). */ > extern const AVFilter ff_asrc_abuffer; > extern const AVFilter ff_vsrc_buffer; > +extern const AVFilter ff_ssrc_sbuffer; > extern const AVFilter ff_asink_abuffer; > extern const AVFilter ff_vsink_buffer; > +extern const AVFilter ff_ssink_sbuffer; > extern const AVFilter ff_af_afifo; > extern const AVFilter ff_vf_fifo; > > diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c > index b8ddafec35..8306312acc 100644 > --- a/libavfilter/buffersink.c > +++ b/libavfilter/buffersink.c > @@ -29,6 +29,8 @@ > #include "libavutil/internal.h" > #include "libavutil/opt.h" > > +#include "libavcodec/avcodec.h" > + > #define FF_INTERNAL_FIELDS 1 > #include "framequeue.h" > > @@ -57,6 +59,10 @@ typedef struct BufferSinkContext { > int *sample_rates; ///< list of accepted sample > rates, terminated by -1 > int sample_rates_size; > > + /* only used for subtitles */ > + enum AVSubtitleType *subtitle_types; ///< list of accepted subtitle > types, must be terminated with -1
subtitle_types is not terminated by -1 at all; it uses the size field below instead of a sentinel. The same is true for the other arrays. > + int subtitle_types_size; > + > AVFrame *peeked_frame; > } BufferSinkContext; > > @@ -168,6 +174,15 @@ AVABufferSinkParams *av_abuffersink_params_alloc(void) > return NULL; > return params; > } > + > +AVSBufferSinkParams *av_sbuffersink_params_alloc(void) > +{ > + AVSBufferSinkParams *params = av_mallocz(sizeof(AVSBufferSinkParams)); > + > + if (!params) > + return NULL; > + return params; > +} > #endif > > static av_cold int common_init(AVFilterContext *ctx) > @@ -305,6 +320,28 @@ static int asink_query_formats(AVFilterContext *ctx) > return 0; > } > > +static int ssink_query_formats(AVFilterContext *ctx) > +{ > + BufferSinkContext *buf = ctx->priv; > + AVFilterFormats *formats = NULL; > + unsigned i; > + int ret; > + > + CHECK_LIST_SIZE(subtitle_types) > + if (buf->subtitle_types_size) { > + for (i = 0; i < NB_ITEMS(buf->subtitle_types); i++) > + if ((ret = ff_add_subtitle_type(&formats, > buf->subtitle_types[i])) < 0) > + return ret; > + if ((ret = ff_set_common_formats(ctx, formats)) < 0) > + return ret; > + } else { > + if ((ret = ff_default_query_formats(ctx)) < 0) > + return ret; > + } > + > + return 0; > +} > + > #define OFFSET(x) offsetof(BufferSinkContext, x) > #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > static const AVOption buffersink_options[] = { > @@ -322,9 +359,16 @@ static const AVOption abuffersink_options[] = { > { NULL }, > }; > #undef FLAGS > +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM > +static const AVOption sbuffersink_options[] = { > + { "subtitle_types", "set the supported subtitle formats", > OFFSET(subtitle_types), AV_OPT_TYPE_BINARY, .flags = FLAGS }, > + { NULL }, > +}; > +#undef FLAGS > > AVFILTER_DEFINE_CLASS(buffersink); > AVFILTER_DEFINE_CLASS(abuffersink); > +AVFILTER_DEFINE_CLASS(sbuffersink); > > static const AVFilterPad avfilter_vsink_buffer_inputs[] = { > { > @@ -363,3 +407,22 @@ const AVFilter ff_asink_abuffer = { > .outputs = NULL, > FILTER_QUERY_FUNC(asink_query_formats), > }; > + > +static const AVFilterPad avfilter_ssink_sbuffer_inputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_SUBTITLE, > + }, > +}; > + > +const AVFilter ff_ssink_sbuffer = { > + .name = "sbuffersink", > + .description = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make > them available to the end of the filter graph."), > + .priv_class = &sbuffersink_class, > + .priv_size = sizeof(BufferSinkContext), > + .init = common_init, > + .activate = activate, > + FILTER_INPUTS(avfilter_ssink_sbuffer_inputs), > + .outputs = NULL, > + FILTER_QUERY_FUNC(ssink_query_formats), > +}; > diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h > index 69ed0f29a8..b439b586c5 100644 > --- a/libavfilter/buffersink.h > +++ b/libavfilter/buffersink.h > @@ -129,6 +129,21 @@ typedef struct AVABufferSinkParams { > */ > attribute_deprecated > AVABufferSinkParams *av_abuffersink_params_alloc(void); > + > +/** > + * Deprecated and unused struct to use for initializing an sbuffersink > context. > + */ > +typedef struct AVSBufferSinkParams { > + const int *subtitle_type; > +} AVSBufferSinkParams; > + > +/** > + * Create an AVSBufferSinkParams structure. > + * > + * Must be freed with av_free(). > + */ > +attribute_deprecated > +AVSBufferSinkParams *av_sbuffersink_params_alloc(void); > #endif Just don't add it. > > /** > diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c > index b0611872f1..8f22587f42 100644 > --- a/libavfilter/buffersrc.c > +++ b/libavfilter/buffersrc.c > @@ -39,6 +39,7 @@ > #include "formats.h" > #include "internal.h" > #include "video.h" > +#include "libavcodec/avcodec.h" > > typedef struct BufferSourceContext { > const AVClass *class; > @@ -63,6 +64,9 @@ typedef struct BufferSourceContext { > uint64_t channel_layout; > char *channel_layout_str; > > + /* subtitle only */ > + enum AVSubtitleType subtitle_type; > + > int eof; > } BufferSourceContext; > > @@ -130,6 +134,13 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx, > AVBufferSrcParameters *par > if (param->channel_layout) > s->channel_layout = param->channel_layout; > break; > + case AVMEDIA_TYPE_SUBTITLE: > + s->subtitle_type = param->format; > + if (param->width > 0) > + s->w = param->width; > + if (param->height > 0) > + s->h = param->height; > + break; > default: > return AVERROR_BUG; > } > @@ -197,6 +208,8 @@ int attribute_align_arg > av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFra > CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, > frame->channel_layout, > frame->channels, frame->format, > frame->pts); > break; > + case AVMEDIA_TYPE_SUBTITLE: > + break; > default: > return AVERROR(EINVAL); > } > @@ -269,6 +282,7 @@ unsigned > av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) > #define OFFSET(x) offsetof(BufferSourceContext, x) > #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM > #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > +#define S AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM > > static const AVOption buffer_options[] = { > { "width", NULL, OFFSET(w), > AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, > @@ -298,6 +312,16 @@ static const AVOption abuffer_options[] = { > > AVFILTER_DEFINE_CLASS(abuffer); > > +static const AVOption sbuffer_options[] = { > + { "time_base", NULL, OFFSET(time_base), > AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, S }, > + { "subtitle_type", NULL, OFFSET(subtitle_type), AV_OPT_TYPE_INT, > { .i64 = 0 }, 0, INT_MAX, S }, > + { "width", NULL, OFFSET(w), AV_OPT_TYPE_INT, > { .i64 = 0 }, 0, INT_MAX, V }, > + { "height", NULL, OFFSET(h), AV_OPT_TYPE_INT, > { .i64 = 0 }, 0, INT_MAX, V }, > + { NULL }, > +}; > + > +AVFILTER_DEFINE_CLASS(sbuffer); > + > static av_cold int init_audio(AVFilterContext *ctx) > { > BufferSourceContext *s = ctx->priv; > @@ -347,6 +371,21 @@ static av_cold int init_audio(AVFilterContext *ctx) > return ret; > } > > +static av_cold int init_subtitle(AVFilterContext *ctx) > +{ > + BufferSourceContext *c = ctx->priv; > + > + if (c->subtitle_type == AV_SUBTITLE_FMT_BITMAP) > + av_log(ctx, AV_LOG_VERBOSE, "graphical subtitles - w:%d h:%d > tb:%d/%d\n", > + c->w, c->h, c->time_base.num, c->time_base.den); > + else > + av_log(ctx, AV_LOG_VERBOSE, "text subtitles - w:%d h:%d tb:%d/%d\n", > + c->w, c->h, c->time_base.num, c->time_base.den); > + > + return 0; > +} > + > + > static av_cold void uninit(AVFilterContext *ctx) > { > BufferSourceContext *s = ctx->priv; > @@ -381,6 +420,11 @@ static int query_formats(AVFilterContext *ctx) > if ((ret = ff_set_common_channel_layouts(ctx, channel_layouts)) < 0) > return ret; > break; > + case AVMEDIA_TYPE_SUBTITLE: > + if ((ret = ff_add_format (&formats, c->subtitle_type)) < 0 || > + (ret = ff_set_common_formats (ctx , formats )) < 0) > + return ret; > + break; > default: > return AVERROR(EINVAL); > } > @@ -408,6 +452,11 @@ static int config_props(AVFilterLink *link) > if (!c->channel_layout) > c->channel_layout = link->channel_layout; > break; > + case AVMEDIA_TYPE_SUBTITLE: > + link->format = c->subtitle_type; > + link->w = c->w; > + link->h = c->h; > + break; > default: > return AVERROR(EINVAL); > } > @@ -472,3 +521,26 @@ const AVFilter ff_asrc_abuffer = { > FILTER_QUERY_FUNC(query_formats), > .priv_class = &abuffer_class, > }; > + > +static const AVFilterPad avfilter_ssrc_sbuffer_outputs[] = { Can you avoid the avfilter prefix (which violates our typical naming conventions notwithstanding then fact that other parts of this file also do it)? > + { > + .name = "default", > + .type = AVMEDIA_TYPE_SUBTITLE, > + .request_frame = request_frame, > + .config_props = config_props, > + }, > +}; > + > +const AVFilter ff_ssrc_sbuffer = { > + .name = "sbuffer", > + .description = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make > them accessible to the filterchain."), > + .priv_size = sizeof(BufferSourceContext), > + > + .init = init_subtitle, > + .uninit = uninit, > + > + .inputs = NULL, > + FILTER_OUTPUTS(avfilter_ssrc_sbuffer_outputs), > + FILTER_QUERY_FUNC(query_formats), > + .priv_class = &sbuffer_class, > +}; > diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h > index 08fbd18a47..929a2fa249 100644 > --- a/libavfilter/buffersrc.h > +++ b/libavfilter/buffersrc.h > @@ -74,6 +74,7 @@ typedef struct AVBufferSrcParameters { > /** > * video: the pixel format, value corresponds to enum AVPixelFormat > * audio: the sample format, value corresponds to enum AVSampleFormat > + * subtitles: the subtitle format, value corresponds to enum > AVSubtitleType > */ > int format; > /** > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".