[FFmpeg-devel] [PATCH] avfilter/drawtext: special metadata fields to allow plotting source filename to output.

Marton Balint cus at passwd.hu
Sun Dec 15 01:15:00 EET 2019



On Sat, 14 Dec 2019, Alexandre Heitor Schmidt wrote:

> avfilter/drawtext: Added two special metadata tags which can, be used by
> 'drawtext' filter and others to have access to source file path, and its
> basename.
>
> The new field AVPacket->source_file will contain a path to its corresponding
> filename everytime the packet corresponds to a single file. This behavior is
> common for image2 filter. When this field is filled, frames passed to filters
> will contain two special metadata tags called source_path (the entire path to
> the file) and source_basename (only the file name). These metatags can be
> used by filters like drawtext to be able to plot the entire path or the
> basename of it respectively to the frame being processed.
>
> doc/filters: The documentation for drawtext was also updated and an usage
> example was added.
>
> Fixes #2874.

This seems like something that be done less intrusively by setting an 
AV_PKT_DATA_STRINGS_METADATA packet side data for each packet. That is 
automatically transformed to frame metadata which can be referenced by the 
drawtext filter.

Regards,
Marton

>
> Signed-off-by: Alexandre Heitor Schmidt <alexandre.schmidt at gmail.com>
> ---
> doc/filters.texi      | 13 +++++++++++++
> fftools/ffmpeg.c      | 12 ++++++++++++
> libavcodec/avcodec.h  |  8 ++++++++
> libavcodec/avpacket.c |  1 +
> libavformat/img2dec.c |  9 +++++++++
> 5 files changed, 43 insertions(+)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 93f54a2e1e..d984efb73b 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -9726,6 +9726,12 @@ printed by running @code{ffprobe -show_frames}.
> String metadata generated in filters leading to
> the drawtext filter are also available.
> 
> +There are two special metadata fields (@var{source_path} and @var{source_basename})
> +which can be used when input format has a file corresponding to each frame, such
> +as @var{image2}. @var{source_path} will output the entire path to the filename
> +which generated the frame in question, while @var{source_basename} outputs the
> +equivalent to @code{basename(source_path)}.
> +
> @item n, frame_num
> The frame number, starting from 0.
> 
> @@ -9872,6 +9878,13 @@ drawtext=fontfile=FreeSans.ttf:text=DOG:fontsize=24:x=10:y=20+24-max_glyph_a,
> drawtext=fontfile=FreeSans.ttf:text=cow:fontsize=24:x=80:y=20+24-max_glyph_a
> @end example
> 
> + at item
> +Plot special @var{source_basename} metadata, extracted from each input frame, or
> +the string "NA" if the metadata is not defined.
> + at example
> +drawtext="fontsize=20:fontcolor=white:fontfile=FreeSans.ttf:text='%{metadata\:source_basename\:NA}':x=10:y=10"
> + at end example
> +
> @end itemize
> 
> For more information about libfreetype, check:
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 27f68933f8..9285f86a81 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -2375,6 +2375,18 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
>     if (ret < 0)
>         *decode_failed = 1;
> 
> +    /**
> +     * Set filename as a frame metadata, if it's not empty. This will allow filters
> +     * like drawtext to use this information for cases like image2, where each frame
> +     * corresponds to a file.
> +     */
> +    if (pkt) {
> +        if ( pkt->source_filename != NULL ) {
> +            av_dict_set(&decoded_frame->metadata, "source_path", pkt->source_filename, 0);
> +            av_dict_set(&decoded_frame->metadata, "source_basename", av_basename(pkt->source_filename), 0);
> +        }
> +    }
> +
>     // The following line may be required in some cases where there is no parser
>     // or the parser does not has_b_frames correctly
>     if (ist->st->codecpar->video_delay < ist->dec_ctx->has_b_frames) {
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 119b32dc1f..4e285f4dd8 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -1511,6 +1511,14 @@ typedef struct AVPacket {
>     attribute_deprecated
>     int64_t convergence_duration;
> #endif
> +
> +    /**
> +     * In cases where the packet corresponds to the contents of one single
> +     * file, like when image2 is used, this is set to the source filename,
> +     * so it can be used by filters like drawtext, to plot the source
> +     * filename on the frame.
> +     */
> +    char *source_filename;
> } AVPacket;
> #define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
> #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
> index 858f827a0a..c357e2fbac 100644
> --- a/libavcodec/avpacket.c
> +++ b/libavcodec/avpacket.c
> @@ -46,6 +46,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
>     pkt->buf                  = NULL;
>     pkt->side_data            = NULL;
>     pkt->side_data_elems      = 0;
> +    pkt->source_filename      = NULL;
> }
> 
> AVPacket *av_packet_alloc(void)
> diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
> index f8b4a655a5..02119d89fc 100644
> --- a/libavformat/img2dec.c
> +++ b/libavformat/img2dec.c
> @@ -485,6 +485,15 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
>
>     if (s->is_pipe)
>         pkt->pos = avio_tell(f[0]);
> +    else {
> +        // Set the filename which corresponds to this packet.
> +        pkt->source_filename = av_malloc(strlen(filename));
> +        if (!pkt->source_filename) {
> +            av_log(NULL, AV_LOG_FATAL, "Failed to allocate source_filename\n");
> +            return AVERROR(ENOMEM);
> +        }
> +        pkt->source_filename = av_asprintf("%s", filename);
> +    }
>
>     pkt->size = 0;
>     for (i = 0; i < 3; i++) {
> -- 
> 2.17.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".


More information about the ffmpeg-devel mailing list