diff mbox series

[FFmpeg-devel] avformat/image2: Upon request, make available extra metadata, fields related to input path to be used by filters.

Message ID a034d66f-9c85-96ea-93f6-c1300ce39a3a@gmail.com
State New
Headers show
Series [FFmpeg-devel] avformat/image2: Upon request, make available extra metadata, fields related to input path to be used by filters.
Related show

Checks

Context Check Description
andriy/ffmpeg-patchwork pending
andriy/ffmpeg-patchwork success Applied patch
andriy/ffmpeg-patchwork success Configure finished
andriy/ffmpeg-patchwork success Make finished
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Alexandre Heitor Schmidt Jan. 1, 2020, 5:17 p.m. UTC
The patch follows attached, to avoid formatting issues. The
commit message is as follows:

avformat/image2: Upon request, make available extra metadata
  fields related to input path to be used by filters.

libavformat/img2.h: New field export_path_metadata to
VideoDemuxData to only allow the use of the extra metadata
upon explicit user request, for security reasons.

libavformat/img2dec.c: Modify image2 demuxer to make available
two special metadata entries called lavf.image2dec.source_path
and lavf.image2dec.source_basename, which represents, respectively,
the complete path to the source image for the current frame and
the basename i.e. the file name related to the current frame.
These can then be used by filters like drawtext and others. The
metadata fields will only be available when explicitly enabled
with image2 option -export_path_metadata 1.

doc/demuxers.texi: Documented the new metadata fields available
for image2 and how to use them.

doc/filters.texi: Added an example on how to use the new metadata
fields with drawtext filter, in order to plot the input file path
to each output frame.

Usage example:

ffmpeg -f image2 -export_path_metadata 1 -pattern_type glob
  -framerate 18 -i '/path/to/input/files/*.jpg'
  -filter_complex drawtext="fontsize=40:fontcolor=white:
  fontfile=FreeSans.ttf:borderw=2:bordercolor=black:
  text='%{metadata\:lavf.image2dec.source_basename\:NA}':x=5:y=50"
  output.avi

Fixes #2874.

Signed-off-by: Alexandre Heitor Schmidt <alexandre.schmidt@gmail.com>

Comments

Alexandre Heitor Schmidt Jan. 4, 2020, 3:19 p.m. UTC | #1
Hi there! I'm just writing to make sure this patch wasn't forgotten. :)

Best wishes to you all!

Alex.

On 01/01/2020 17:17, Alexandre Heitor Schmidt wrote:
> The patch follows attached, to avoid formatting issues. The
> commit message is as follows:
>
> avformat/image2: Upon request, make available extra metadata
>  fields related to input path to be used by filters.
>
> libavformat/img2.h: New field export_path_metadata to
> VideoDemuxData to only allow the use of the extra metadata
> upon explicit user request, for security reasons.
>
> libavformat/img2dec.c: Modify image2 demuxer to make available
> two special metadata entries called lavf.image2dec.source_path
> and lavf.image2dec.source_basename, which represents, respectively,
> the complete path to the source image for the current frame and
> the basename i.e. the file name related to the current frame.
> These can then be used by filters like drawtext and others. The
> metadata fields will only be available when explicitly enabled
> with image2 option -export_path_metadata 1.
>
> doc/demuxers.texi: Documented the new metadata fields available
> for image2 and how to use them.
>
> doc/filters.texi: Added an example on how to use the new metadata
> fields with drawtext filter, in order to plot the input file path
> to each output frame.
>
> Usage example:
>
> ffmpeg -f image2 -export_path_metadata 1 -pattern_type glob
>  -framerate 18 -i '/path/to/input/files/*.jpg'
>  -filter_complex drawtext="fontsize=40:fontcolor=white:
>  fontfile=FreeSans.ttf:borderw=2:bordercolor=black:
>  text='%{metadata\:lavf.image2dec.source_basename\:NA}':x=5:y=50"
>  output.avi
>
> Fixes #2874.
>
> Signed-off-by: Alexandre Heitor Schmidt <alexandre.schmidt@gmail.com>
>
Marton Balint Jan. 9, 2020, 9:39 p.m. UTC | #2
On Sat, 4 Jan 2020, Alexandre Heitor Schmidt wrote:

> Hi there! I'm just writing to make sure this patch wasn't forgotten. :)

Thanks, I think the patch is fine now, I will apply it tomorrow if there 
are no further comments.

Regards,
Marton

>
> Best wishes to you all!
>
> Alex.
>
> On 01/01/2020 17:17, Alexandre Heitor Schmidt wrote:
>> The patch follows attached, to avoid formatting issues. The
>> commit message is as follows:
>>
>> avformat/image2: Upon request, make available extra metadata
>>  fields related to input path to be used by filters.
>>
>> libavformat/img2.h: New field export_path_metadata to
>> VideoDemuxData to only allow the use of the extra metadata
>> upon explicit user request, for security reasons.
>>
>> libavformat/img2dec.c: Modify image2 demuxer to make available
>> two special metadata entries called lavf.image2dec.source_path
>> and lavf.image2dec.source_basename, which represents, respectively,
>> the complete path to the source image for the current frame and
>> the basename i.e. the file name related to the current frame.
>> These can then be used by filters like drawtext and others. The
>> metadata fields will only be available when explicitly enabled
>> with image2 option -export_path_metadata 1.
>>
>> doc/demuxers.texi: Documented the new metadata fields available
>> for image2 and how to use them.
>>
>> doc/filters.texi: Added an example on how to use the new metadata
>> fields with drawtext filter, in order to plot the input file path
>> to each output frame.
>>
>> Usage example:
>>
>> ffmpeg -f image2 -export_path_metadata 1 -pattern_type glob
>>  -framerate 18 -i '/path/to/input/files/*.jpg'
>>  -filter_complex drawtext="fontsize=40:fontcolor=white:
>>  fontfile=FreeSans.ttf:borderw=2:bordercolor=black:
>>  text='%{metadata\:lavf.image2dec.source_basename\:NA}':x=5:y=50"
>>  output.avi
>>
>> Fixes #2874.
>>
>> Signed-off-by: Alexandre Heitor Schmidt <alexandre.schmidt@gmail.com>
>>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Alexandre Heitor Schmidt Jan. 10, 2020, 9:10 p.m. UTC | #3
On 09/01/2020 21:39, Marton Balint wrote:
 >
 >
 > On Sat, 4 Jan 2020, Alexandre Heitor Schmidt wrote:
 >
 >> Hi there! I'm just writing to make sure this patch wasn't forgotten. :)
 >
 > Thanks, I think the patch is fine now, I will apply it tomorrow if 
there are no further comments.
 >
 > Regards,
 > Marton

Awesome!

Thank you, Marton!

Alex.
Marton Balint Jan. 10, 2020, 10:21 p.m. UTC | #4
On Fri, 10 Jan 2020, Alexandre Heitor Schmidt wrote:

> On 09/01/2020 21:39, Marton Balint wrote:
> >
> >
> > On Sat, 4 Jan 2020, Alexandre Heitor Schmidt wrote:
> >
> >> Hi there! I'm just writing to make sure this patch wasn't forgotten. :)
> >
> > Thanks, I think the patch is fine now, I will apply it tomorrow if 
> there are no further comments.
> >
> > Regards,
> > Marton
>
> Awesome!

Thanks, applied with some minor changes:
- move option from common opts to the image2 demuxer opts
- use av_dict_free to free the metadata dictionary
- bump avformat micro version

Regards,
Marton
diff mbox series

Patch

From 6294e556c63b99f9b58494fb8013e9c616444ab0 Mon Sep 17 00:00:00 2001
From: Alexandre Heitor Schmidt <alexandre.schmidt@gmail.com>
Date: Wed, 1 Jan 2020 16:57:02 +0000
Subject: [PATCH] avformat/image2: Upon request, make available extra metadata
 fields related to input path to be used by filters.

libavformat/img2.h: New field export_path_metadata to
VideoDemuxData to only allow the use of the extra metadata
upon explicit user request, for security reasons.

libavformat/img2dec.c: Modify image2 demuxer to make available
two special metadata entries called lavf.image2dec.source_path
and lavf.image2dec.source_basename, which represents, respectively,
the complete path to the source image for the current frame and
the basename i.e. the file name related to the current frame.
These can then be used by filters like drawtext and others. The
metadata fields will only be available when explicitly enabled
with image2 option -export_path_metadata 1.

doc/demuxers.texi: Documented the new metadata fields available
for image2 and how to use them.

doc/filters.texi: Added an example on how to use the new metadata
fields with drawtext filter, in order to plot the input file path
to each output frame.

Usage example:

ffmpeg -f image2 -export_path_metadata 1 -pattern_type glob
 -framerate 18 -i '/path/to/input/files/*.jpg'
 -filter_complex drawtext="fontsize=40:fontcolor=white:
 fontfile=FreeSans.ttf:borderw=2:bordercolor=black:
 text='%{metadata\:lavf.image2dec.source_basename\:NA}':x=5:y=50"
 output.avi

Fixes #2874.

Signed-off-by: Alexandre Heitor Schmidt <alexandre.schmidt@gmail.com>
---
 doc/demuxers.texi     | 11 +++++++++++
 doc/filters.texi      |  9 +++++++++
 libavformat/img2.h    |  1 +
 libavformat/img2dec.c | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 0d13bdd1b3..2de14b68d3 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -456,6 +456,17 @@  nanosecond precision.
 @item video_size
 Set the video size of the images to read. If not specified the video
 size is guessed from the first image file in the sequence.
+@item export_path_metadata
+If set to 1, will add two extra fields to the metadata found in input, making them
+also available for other filters (see @var{drawtext} filter for examples). Default
+value is 0. The extra fields are described below:
+@table @option
+@item lavf.image2dec.source_path
+Corresponds to the full path to the input file being read.
+@item lavf.image2dec.source_basename
+Corresponds to the name of the file being read.
+@end table
+
 @end table
 
 @subsection Examples
diff --git a/doc/filters.texi b/doc/filters.texi
index ba00989987..85b55be1bb 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9888,6 +9888,15 @@  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
 
+@item
+Plot special @var{lavf.image2dec.source_basename} metadata onto each frame if
+such metadata exists. Otherwise, plot the string "NA". Note that image2 demuxer
+must have option @option{-export_path_metadata 1} for the special metadata fields
+to be available for filters.
+@example
+drawtext="fontsize=20:fontcolor=white:fontfile=FreeSans.ttf:text='%@{metadata\:lavf.image2dec.source_basename\:NA@}':x=10:y=10"
+@end example
+
 @end itemize
 
 For more information about libfreetype, check:
diff --git a/libavformat/img2.h b/libavformat/img2.h
index 0e5b374a6b..5fd8ff77fc 100644
--- a/libavformat/img2.h
+++ b/libavformat/img2.h
@@ -61,6 +61,7 @@  typedef struct VideoDemuxData {
     int start_number_range;
     int frame_size;
     int ts_from_file;
+    int export_path_metadata; /**< enabled when set to 1. */
 } VideoDemuxData;
 
 typedef struct IdStrMap {
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index f8b4a655a5..4eb554debe 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -374,6 +374,32 @@  int ff_img_read_header(AVFormatContext *s1)
     return 0;
 }
 
+/**
+ * Add this frame's source path and basename to packet's sidedata
+ * as a dictionary, so it can be used by filters like 'drawtext'.
+ */
+static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) {
+    uint8_t* metadata;
+    int metadata_len;
+    AVDictionary *d = NULL;
+    char *packed_metadata = NULL;
+
+    av_dict_set(&d, "lavf.image2dec.source_path", filename, 0);
+    av_dict_set(&d, "lavf.image2dec.source_basename", av_basename(filename), 0);
+
+    packed_metadata = av_packet_pack_dictionary(d, &metadata_len);
+    if (!packed_metadata)
+        return AVERROR(ENOMEM);
+    if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
+        av_freep(&packed_metadata);
+        return AVERROR(ENOMEM);
+    }
+    memcpy(metadata, packed_metadata, metadata_len);
+    av_freep(&packed_metadata);
+
+    return 0;
+}
+
 int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     VideoDemuxData *s = s1->priv_data;
@@ -486,6 +512,17 @@  int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
     if (s->is_pipe)
         pkt->pos = avio_tell(f[0]);
 
+    /*
+     * export_path_metadata must be explicitly enabled via
+     * command line options for path metadata to be exported
+     * as packet side_data.
+     */
+    if (!s->is_pipe && s->export_path_metadata == 1) {
+        res = add_filename_as_pkt_side_data(filename, pkt);
+        if (res < 0)
+            goto fail;
+    }
+
     pkt->size = 0;
     for (i = 0; i < 3; i++) {
         if (f[i]) {
@@ -570,6 +607,7 @@  static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
     { "pixel_format", "set video pixel format",  OFFSET(pixel_format), AV_OPT_TYPE_STRING,     {.str = NULL}, 0, 0,       DEC }, \
     { "video_size",   "set video size",          OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0,       DEC }, \
     { "loop",         "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL,   {.i64 = 0   }, 0, 1,       DEC }, \
+    { "export_path_metadata", "enable metadata containing input path information", OFFSET(export_path_metadata), AV_OPT_TYPE_BOOL,   {.i64 = 0   }, 0, 1,       DEC }, \
     { NULL },
 
 #if CONFIG_IMAGE2_DEMUXER
-- 
2.17.1