[FFmpeg-devel] [PATCH v20 10/20] avfilter/avfilter: Handle subtitle frames
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Sun Dec 5 19:45:49 EET 2021
Soft Works:
> Signed-off-by: softworkz <softworkz at hotmail.com>
> ---
> doc/APIchanges | 3 +++
> libavfilter/avfilter.c | 8 +++++---
> libavfilter/avfilter.h | 11 +++++++++++
> libavfilter/avfiltergraph.c | 5 +++++
> libavfilter/formats.c | 22 ++++++++++++++++++++++
> libavfilter/formats.h | 3 +++
> libavfilter/internal.h | 18 +++++++++++++++---
> 7 files changed, 64 insertions(+), 6 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 83ac64c3f1..f695efe9ab 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,9 @@ libavutil: 2021-04-27
>
> API changes, most recent first:
>
> +2021-12-05 - xxxxxxxxxx - lavc 9.1.100 - avfilter.h
> + Add fields subs_list and sub_fmt to AVFilter struct
> +
This is not public API, so don't make an APIchanges entry.
> 2021-12-05 - xxxxxxxxxx - lavc 60.1.100 - avcodec.h
> Deprecate avcodec_encode_subtitle(), use regular encode api now
>
> diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
> index df5b8f483c..75d5e86539 100644
> --- a/libavfilter/avfilter.c
> +++ b/libavfilter/avfilter.c
> @@ -56,7 +56,8 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
> ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
> ref->pts, ref->pkt_pos);
>
> - if (ref->width) {
> + switch(ref->type) {
> + case AVMEDIA_TYPE_VIDEO:
> ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
> ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
> ref->width, ref->height,
> @@ -64,12 +65,13 @@ static void tlog_ref(void *ctx, AVFrame *ref, int end)
> ref->top_field_first ? 'T' : 'B', /* Top / Bottom */
> ref->key_frame,
> av_get_picture_type_char(ref->pict_type));
> - }
> - if (ref->nb_samples) {
> + break;
> + case AVMEDIA_TYPE_AUDIO:
> ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
> ref->channel_layout,
> ref->nb_samples,
> ref->sample_rate);
> + break;
> }
>
> ff_tlog(ctx, "]%s", end ? "\n" : "");
> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> index b105dc3159..9f917deb41 100644
> --- a/libavfilter/avfilter.h
> +++ b/libavfilter/avfilter.h
> @@ -45,6 +45,7 @@
> #include "libavutil/log.h"
> #include "libavutil/samplefmt.h"
> #include "libavutil/pixfmt.h"
> +#include "libavutil/subfmt.h"
> #include "libavutil/rational.h"
>
> #include "libavfilter/version.h"
> @@ -343,6 +344,12 @@ typedef struct AVFilter {
> * and outputs use the same sample rate and channel count/layout.
> */
> const enum AVSampleFormat *samples_list;
> + /**
> + * Analogous to pixels, but delimited by AV_SUBTITLE_FMT_NONE
> + * and restricted to filters that only have AVMEDIA_TYPE_SUBTITLE
> + * inputs and outputs.
> + */
> + const enum AVSubtitleType *subs_list;
> /**
> * Equivalent to { pix_fmt, AV_PIX_FMT_NONE } as pixels_list.
> */
> @@ -351,6 +358,10 @@ typedef struct AVFilter {
> * Equivalent to { sample_fmt, AV_SAMPLE_FMT_NONE } as samples_list.
> */
> enum AVSampleFormat sample_fmt;
> + /**
> + * Equivalent to { sub_fmt, AV_SUBTITLE_FMT_NONE } as subs_list.
> + */
> + enum AVSubtitleType sub_fmt;
> } formats;
>
> int priv_size; ///< size of private data to allocate for the filter
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index b8b432e98b..f4987654af 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -311,6 +311,8 @@ static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterForm
> return ret;
> break;
>
> + case AVMEDIA_TYPE_SUBTITLE:
> + return 0;
> default:
> av_assert0(!"reached");
> }
> @@ -441,6 +443,9 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
> if (!link)
> continue;
>
> + if (link->type == AVMEDIA_TYPE_SUBTITLE)
> + continue;
> +
> neg = ff_filter_get_negotiation(link);
> av_assert0(neg);
> for (neg_step = 1; neg_step < neg->nb_mergers; neg_step++) {
> diff --git a/libavfilter/formats.c b/libavfilter/formats.c
> index ba62f73248..46dbbd2975 100644
> --- a/libavfilter/formats.c
> +++ b/libavfilter/formats.c
> @@ -19,6 +19,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> +#include "libavcodec/avcodec.h"
libavutil/subfmt.h, I presume?
> #include "libavutil/avassert.h"
> #include "libavutil/channel_layout.h"
> #include "libavutil/common.h"
> @@ -431,6 +432,12 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
> return 0;
> }
>
> +int ff_add_subtitle_type(AVFilterFormats **avff, int64_t fmt)
> +{
> + ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
> + return 0;
> +}
> +
> AVFilterFormats *ff_make_formats_list_singleton(int fmt)
> {
> int fmts[2] = { fmt, -1 };
> @@ -450,6 +457,13 @@ AVFilterFormats *ff_all_formats(enum AVMediaType type)
> return NULL;
> fmt++;
> }
> + } else if (type == AVMEDIA_TYPE_SUBTITLE) {
> + if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_BITMAP) < 0)
> + return NULL;
> + if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_ASS) < 0)
> + return NULL;
> + if (ff_add_subtitle_type(&ret, AV_SUBTITLE_FMT_TEXT) < 0)
> + return NULL;
> }
>
> return ret;
> @@ -724,6 +738,10 @@ int ff_default_query_formats(AVFilterContext *ctx)
> type = AVMEDIA_TYPE_AUDIO;
> formats = ff_make_format_list(f->formats.samples_list);
> break;
> + case FF_FILTER_FORMATS_SUBFMTS_LIST:
> + type = AVMEDIA_TYPE_SUBTITLE;
> + formats = ff_make_format_list(f->formats.subs_list);
> + break;
> case FF_FILTER_FORMATS_SINGLE_PIXFMT:
> type = AVMEDIA_TYPE_VIDEO;
> formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
> @@ -732,6 +750,10 @@ int ff_default_query_formats(AVFilterContext *ctx)
> type = AVMEDIA_TYPE_AUDIO;
> formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
> break;
> + case FF_FILTER_FORMATS_SINGLE_SUBFMT:
> + type = AVMEDIA_TYPE_SUBTITLE;
> + formats = ff_make_formats_list_singleton(f->formats.sub_fmt);
> + break;
> default:
> av_assert2(!"Unreachable");
> /* Intended fallthrough */
> diff --git a/libavfilter/formats.h b/libavfilter/formats.h
> index a884d15213..94754ebd88 100644
> --- a/libavfilter/formats.h
> +++ b/libavfilter/formats.h
> @@ -180,6 +180,9 @@ int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts);
> av_warn_unused_result
> int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout);
>
> +av_warn_unused_result
> +int ff_add_subtitle_type(AVFilterFormats **avff, int64_t fmt);
> +
> /**
> * Add *ref as a new reference to f.
> */
> diff --git a/libavfilter/internal.h b/libavfilter/internal.h
> index fc09ef574c..192b0ae196 100644
> --- a/libavfilter/internal.h
> +++ b/libavfilter/internal.h
> @@ -149,9 +149,11 @@ static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_act
>
> enum FilterFormatsState {
> /**
> - * The default value meaning that this filter supports all formats
> - * and (for audio) sample rates and channel layouts/counts as long
> - * as these properties agree for all inputs and outputs.
> + * The default value meaning that this filter supports
> + * - For video: all formats
> + * - For audio: all sample rates and channel layouts/counts
> + * - For subtitles: all subtitle formats
> + * as long as these properties agree for all inputs and outputs.
> * This state is only allowed in case all inputs and outputs actually
> * have the same type.
> * The union is unused in this state.
> @@ -162,8 +164,10 @@ enum FilterFormatsState {
> FF_FILTER_FORMATS_QUERY_FUNC, ///< formats.query active.
> FF_FILTER_FORMATS_PIXFMT_LIST, ///< formats.pixels_list active.
> FF_FILTER_FORMATS_SAMPLEFMTS_LIST, ///< formats.samples_list active.
> + FF_FILTER_FORMATS_SUBFMTS_LIST, ///< formats.subs_list active.
> FF_FILTER_FORMATS_SINGLE_PIXFMT, ///< formats.pix_fmt active
> FF_FILTER_FORMATS_SINGLE_SAMPLEFMT, ///< formats.sample_fmt active.
> + FF_FILTER_FORMATS_SINGLE_SUBFMT, ///< formats.sub_fmt active.
> };
>
> #define FILTER_QUERY_FUNC(func) \
> @@ -175,16 +179,24 @@ enum FilterFormatsState {
> #define FILTER_SAMPLEFMTS_ARRAY(array) \
> .formats.samples_list = array, \
> .formats_state = FF_FILTER_FORMATS_SAMPLEFMTS_LIST
> +#define FILTER_SUBFMTS_ARRAY(array) \
> + .formats.subs_list = array, \
> + .formats_state = FF_FILTER_FORMATS_SUBFMTS_LIST
> #define FILTER_PIXFMTS(...) \
> FILTER_PIXFMTS_ARRAY(((const enum AVPixelFormat []) { __VA_ARGS__, AV_PIX_FMT_NONE }))
> #define FILTER_SAMPLEFMTS(...) \
> FILTER_SAMPLEFMTS_ARRAY(((const enum AVSampleFormat[]) { __VA_ARGS__, AV_SAMPLE_FMT_NONE }))
> +#define FILTER_SUBFMTS(...) \
> + FILTER_SUBFMTS_ARRAY(((const enum AVSubtitleType[]) { __VA_ARGS__, AV_SUBTITLE_FMT_NONE }))
> #define FILTER_SINGLE_PIXFMT(pix_fmt_) \
> .formats.pix_fmt = pix_fmt_, \
> .formats_state = FF_FILTER_FORMATS_SINGLE_PIXFMT
> #define FILTER_SINGLE_SAMPLEFMT(sample_fmt_) \
> .formats.sample_fmt = sample_fmt_, \
> .formats_state = FF_FILTER_FORMATS_SINGLE_SAMPLEFMT
> +#define FILTER_SINGLE_SUBFMT(sub_fmt_) \
> + .formats.sub_fmt = sub_fmt_, \
> + .formats_state = FF_FILTER_FORMATS_SINGLE_SUBFMT
>
> #define FILTER_INOUTPADS(inout, array) \
> .inout = array, \
>
More information about the ffmpeg-devel
mailing list