[FFmpeg-devel] [PATCH] [RFC] avformat/movenc: support covert images for ipod muxer

Timo Teräs timo.teras at iki.fi
Thu May 31 17:40:20 EEST 2018


Add avformat_query_codec() to special handle 'APIC' tag in
output format .codec_tag list in addition to .query_codec.

Advertise codecs for cover image with 'APIC' tag in ipod
muxer.

Signed-off-by: Timo Teräs <timo.teras at iki.fi>
---
This makes writing cover images to m4a files to work.

However, I was trying to understand how the APIC tag works. It seems
to affect mostly selection of the default input stream for given
output stream in ffmpeg_opt.c:open_output_file().

The whole APIC tag concept was implemented in mp3 muxer originally.
And there it seems to make sense since images can be as attachments
only.

However, mp4 allows video both as a main stream or as an attachment
(to be displayed as cover image), it might make more sense to check
codecs against different list when AV_DISPOSITION_ATTACHED_PIC is set.

So I am wondering if it's more sensible (instead of this patch) to
add a new avformat_query_codec2() helper that gets the stream
disposition (or perhaps modify avformat_query_codec() since it's
used exactly once in ffmpeg_opt.c; though this would be ABI change).
Additionally do one or more of the following:
- update AVOutputFormat.query_codec() to receive the stream disposition too
- add AVOutputFormat.codec_tag to have special values to indicate
  that the list applies to specific stream dispostion only

Perhaps after the above changes ffmpeg_opt.c:open_output_file() can
be updated to have logic that does not depend on APIC special tag,
but instead uses only the disposition flags of input and output streams.
This would allow to remove the APIC "kludge" tag.

Thoughts?

 libavformat/movenc.c |  9 ++++++++-
 libavformat/utils.c  | 10 +++++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 7e616e866f..0e6706555c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6769,6 +6769,13 @@ static const AVCodecTag codec_f4v_tags[] = {
     { AV_CODEC_ID_NONE, 0 },
 };
 
+static const AVCodecTag codec_cover_image_tags[] = {
+    { AV_CODEC_ID_MJPEG,  MKTAG('A','P','I','C') },
+    { AV_CODEC_ID_PNG,    MKTAG('A','P','I','C') },
+    { AV_CODEC_ID_BMP,    MKTAG('A','P','I','C') },
+    { AV_CODEC_ID_NONE, 0 },
+};
+
 #if CONFIG_MOV_MUXER
 MOV_CLASS(mov)
 AVOutputFormat ff_mov_muxer = {
@@ -6891,7 +6898,7 @@ AVOutputFormat ff_ipod_muxer = {
     .write_trailer     = mov_write_trailer,
     .deinit            = mov_free,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
-    .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
+    .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, codec_cover_image_tags, 0 },
     .check_bitstream   = mov_check_bitstream,
     .priv_class        = &ipod_muxer_class,
 };
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c9cdd2b470..ffa6eb2a8a 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -4946,9 +4946,13 @@ int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
         unsigned int codec_tag;
         if (ofmt->query_codec)
             return ofmt->query_codec(codec_id, std_compliance);
-        else if (ofmt->codec_tag)
-            return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
-        else if (codec_id == ofmt->video_codec ||
+        else if (ofmt->codec_tag) {
+            if (!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag))
+              return 0;
+            if (codec_tag == MKTAG('A','P','I','C'))
+              return codec_tag;
+            return 1;
+        } else if (codec_id == ofmt->video_codec ||
                  codec_id == ofmt->audio_codec ||
                  codec_id == ofmt->subtitle_codec ||
                  codec_id == ofmt->data_codec)
-- 
2.17.0



More information about the ffmpeg-devel mailing list