[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