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

Alexandre Heitor Schmidt alexandre.schmidt at gmail.com
Sun Dec 15 12:42:11 EET 2019


On 14/12/2019 23:15, Marton Balint wrote:
> 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
That's great, Marton! Thanks for the tip! I'll research on how to use 
AV_PKT_DATA_STRINGS_METADATA properly and re-submit the patch. By the 
way, how should I proceed with the patch at 
https://patchwork.ffmpeg.org/patch/16798/? I think it should be deleted 
until I have it implemented the way you suggested, right? Thanks again!

Best wishes,

Alex.
>
>>
>> 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".
> _______________________________________________
> 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