[01/11] movenc: Add an F4V muxer

Message ID 1381320210-79941-1-git-send-email-martin@martin.st
State Committed
Headers show

Commit Message

Martin Storsjö Oct. 9, 2013, 12:03 p.m.
From: Clément Bœsch <clement.boesch@smartjog.com>

F4V is Adobe's mp4/iso media variant, with the most significant
addition/change being supporting other flash codecs than just
aac/h264.
---
 Changelog                |    1 +
 configure                |    1 +
 libavformat/allformats.c |    1 +
 libavformat/movenc.c     |   38 +++++++++++++++++++++++++++++++++++++-
 libavformat/movenc.h     |    1 +
 libavformat/version.h    |    4 ++--
 6 files changed, 43 insertions(+), 3 deletions(-)

Comments

Martin Storsjö Oct. 22, 2013, 12:49 p.m. | #1
On Wed, 9 Oct 2013, Martin Storsjö wrote:

> From: Clément Bœsch <clement.boesch@smartjog.com>
>
> F4V is Adobe's mp4/iso media variant, with the most significant
> addition/change being supporting other flash codecs than just
> aac/h264.
> ---
> Changelog                |    1 +
> configure                |    1 +
> libavformat/allformats.c |    1 +
> libavformat/movenc.c     |   38 +++++++++++++++++++++++++++++++++++++-
> libavformat/movenc.h     |    1 +
> libavformat/version.h    |    4 ++--
> 6 files changed, 43 insertions(+), 3 deletions(-)

OK'd by Luca on irc.

// Martin
Luca Barbato Oct. 22, 2013, 1:09 p.m. | #2
On 09/10/13 14:03, Martin Storsjö wrote:
> +    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
> +             track->enc->codec_id == AV_CODEC_ID_VP6A) {
> +        /* Don't write any potential extradata here - the cropping
> +         * is signalled via the normal width/height fields. */
> +    } else if (track->vos_len > 0)
>          mov_write_glbl_tag(pb, track);

Not sure if having the condition merged below is nicer, beside that
doesn't look wrong.

lu
Martin Storsjö Oct. 22, 2013, 1:16 p.m. | #3
On Tue, 22 Oct 2013, Luca Barbato wrote:

> On 09/10/13 14:03, Martin Storsjö wrote:
>> +    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
>> +             track->enc->codec_id == AV_CODEC_ID_VP6A) {
>> +        /* Don't write any potential extradata here - the cropping
>> +         * is signalled via the normal width/height fields. */
>> +    } else if (track->vos_len > 0)
>>          mov_write_glbl_tag(pb, track);
>
> Not sure if having the condition merged below is nicer, beside that
> doesn't look wrong.

No you can't move it below the existing one, since track->vos_len > 0 can 
be true for VP6 as well, but we intentionally should not write it to the 
file. The track->vos_len > 0 case is a catch-all case for writing 
"generic" extradata for codecs that don't need any special handling.

// Martin
Luca Barbato Oct. 22, 2013, 1:35 p.m. | #4
On 22/10/13 15:16, Martin Storsjö wrote:
> On Tue, 22 Oct 2013, Luca Barbato wrote:
> 
>> On 09/10/13 14:03, Martin Storsjö wrote:
>>> +    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
>>> +             track->enc->codec_id == AV_CODEC_ID_VP6A) {
>>> +        /* Don't write any potential extradata here - the cropping
>>> +         * is signalled via the normal width/height fields. */
>>> +    } else if (track->vos_len > 0)
>>>          mov_write_glbl_tag(pb, track);
>>
>> Not sure if having the condition merged below is nicer, beside that
>> doesn't look wrong.
> 
> No you can't move it below the existing one, since track->vos_len > 0
> can be true for VP6 as well, but we intentionally should not write it to
> the file. The track->vos_len > 0 case is a catch-all case for writing
> "generic" extradata for codecs that don't need any special handling.
> 
> // Martin
> _______________________________________________
> libav-devel mailing list
> libav-devel@libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel

I meant if (track->vos_tag > 0 && codec_id != AV_CODEC_ID_VP6F)

as said not sure which is the nicer.

lu
Martin Storsjö Oct. 22, 2013, 1:37 p.m. | #5
On Tue, 22 Oct 2013, Luca Barbato wrote:

> On 22/10/13 15:16, Martin Storsjö wrote:
>> On Tue, 22 Oct 2013, Luca Barbato wrote:
>> 
>>> On 09/10/13 14:03, Martin Storsjö wrote:
>>>> +    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
>>>> +             track->enc->codec_id == AV_CODEC_ID_VP6A) {
>>>> +        /* Don't write any potential extradata here - the cropping
>>>> +         * is signalled via the normal width/height fields. */
>>>> +    } else if (track->vos_len > 0)
>>>>          mov_write_glbl_tag(pb, track);
>>>
>>> Not sure if having the condition merged below is nicer, beside that
>>> doesn't look wrong.
>> 
>> No you can't move it below the existing one, since track->vos_len > 0
>> can be true for VP6 as well, but we intentionally should not write it to
>> the file. The track->vos_len > 0 case is a catch-all case for writing
>> "generic" extradata for codecs that don't need any special handling.
>> 
>> // Martin
>> _______________________________________________
>> libav-devel mailing list
>> libav-devel@libav.org
>> https://lists.libav.org/mailman/listinfo/libav-devel
>
> I meant if (track->vos_tag > 0 && codec_id != AV_CODEC_ID_VP6F)
>
> as said not sure which is the nicer.

Ah, I see. I think I prefer the current one though, which is clearer if 
there's many different similar cases (although not sure if there will be 
many others).

// Martin

Patch

diff --git a/Changelog b/Changelog
index b0ff897..17b95d8 100644
--- a/Changelog
+++ b/Changelog
@@ -37,6 +37,7 @@  version 10:
 - Error Resilient AAC syntax (ER AAC LC) decoding
 - Low Delay AAC (ER AAC LD) decoding
 - mux chapters in ASF files
+- F4V muxer
 
 
 version 9:
diff --git a/configure b/configure
index 167f4ee..3bb86e9 100755
--- a/configure
+++ b/configure
@@ -1814,6 +1814,7 @@  caf_demuxer_select="riffdec"
 dirac_demuxer_select="dirac_parser"
 dxa_demuxer_select="riffdec"
 eac3_demuxer_select="ac3_parser"
+f4v_muxer_select="mov_muxer"
 flac_demuxer_select="flac_parser"
 hls_muxer_select="mpegts_muxer"
 ipod_muxer_select="mov_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 585cf43..36a782b 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -100,6 +100,7 @@  void av_register_all(void)
     REGISTER_DEMUXER (EA,               ea);
     REGISTER_DEMUXER (EA_CDATA,         ea_cdata);
     REGISTER_MUXDEMUX(EAC3,             eac3);
+    REGISTER_MUXER   (F4V,              f4v);
     REGISTER_MUXDEMUX(FFM,              ffm);
     REGISTER_MUXDEMUX(FFMETADATA,       ffmetadata);
     REGISTER_MUXDEMUX(FILMSTRIP,        filmstrip);
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 1fe850b..8f7153a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -888,6 +888,15 @@  static const AVCodecTag codec_3gp_tags[] = {
     { AV_CODEC_ID_NONE, 0 },
 };
 
+static const AVCodecTag codec_f4v_tags[] = {
+    { AV_CODEC_ID_MP3,    MKTAG('.','m','p','3') },
+    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_VP6A,   MKTAG('V','P','6','A') },
+    { AV_CODEC_ID_VP6F,   MKTAG('V','P','6','F') },
+    { AV_CODEC_ID_NONE, 0 },
+};
+
 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
 {
     int tag;
@@ -902,6 +911,8 @@  static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
         tag = ipod_get_codec_tag(s, track);
     else if (track->mode & MODE_3GP)
         tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
+    else if (track->mode == MODE_F4V)
+        tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
     else
         tag = mov_get_codec_tag(s, track);
 
@@ -1030,7 +1041,11 @@  static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
         mov_write_fiel_tag(pb, track);
     else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
         mov_write_dvc1_tag(pb, track);
-    else if (track->vos_len > 0)
+    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
+             track->enc->codec_id == AV_CODEC_ID_VP6A) {
+        /* Don't write any potential extradata here - the cropping
+         * is signalled via the normal width/height fields. */
+    } else if (track->vos_len > 0)
         mov_write_glbl_tag(pb, track);
 
     if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
@@ -2546,6 +2561,8 @@  static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
         ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
     else if (mov->mode == MODE_ISM)
         ffio_wfourcc(pb, "isml");
+    else if (mov->mode == MODE_F4V)
+        ffio_wfourcc(pb, "f4v ");
     else
         ffio_wfourcc(pb, "qt  ");
 
@@ -3149,6 +3166,7 @@  static int mov_write_header(AVFormatContext *s)
         else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
         else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
         else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
+        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
     }
 
     /* Set the FRAGMENT flag if any of the fragmentation methods are
@@ -3650,3 +3668,21 @@  AVOutputFormat ff_ismv_muxer = {
     .priv_class        = &ismv_muxer_class,
 };
 #endif
+#if CONFIG_F4V_MUXER
+MOV_CLASS(f4v)
+AVOutputFormat ff_f4v_muxer = {
+    .name              = "f4v",
+    .long_name         = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
+    .mime_type         = "application/f4v",
+    .extensions        = "f4v",
+    .priv_data_size    = sizeof(MOVMuxContext),
+    .audio_codec       = AV_CODEC_ID_AAC,
+    .video_codec       = AV_CODEC_ID_H264,
+    .write_header      = mov_write_header,
+    .write_packet      = mov_write_packet,
+    .write_trailer     = mov_write_trailer,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
+    .codec_tag         = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
+    .priv_class        = &f4v_muxer_class,
+};
+#endif
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index fefb20b..1b669e8 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -40,6 +40,7 @@ 
 #define MODE_3G2  0x10
 #define MODE_IPOD 0x20
 #define MODE_ISM  0x40
+#define MODE_F4V  0x80
 
 typedef struct MOVIentry {
     uint64_t     pos;
diff --git a/libavformat/version.h b/libavformat/version.h
index b4031ea..7a01f06 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@ 
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR  5
-#define LIBAVFORMAT_VERSION_MICRO  3
+#define LIBAVFORMAT_VERSION_MINOR  6
+#define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \