changeset 3143:7f0f50bbfe23 libavformat

ipod/iphone compatible mp4 muxer
author bcoudurier
date Sun, 16 Mar 2008 13:36:36 +0000
parents 8891d470ada3
children e74ef245c78d
files Makefile allformats.c avformat.h movenc.c
diffstat 4 files changed, 44 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sat Mar 15 16:15:47 2008 +0000
+++ b/Makefile	Sun Mar 16 13:36:36 2008 +0000
@@ -63,6 +63,7 @@
 OBJS-$(CONFIG_H264_DEMUXER)              += raw.o
 OBJS-$(CONFIG_H264_MUXER)                += raw.o
 OBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.o
+OBJS-$(CONFIG_IPOD_MUXER)                += movenc.o riff.o isom.o avc.o
 OBJS-$(CONFIG_IMAGE2_DEMUXER)            += img2.o
 OBJS-$(CONFIG_IMAGE2_MUXER)              += img2.o
 OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER)        += img2.o
--- a/allformats.c	Sat Mar 15 16:15:47 2008 +0000
+++ b/allformats.c	Sun Mar 16 13:36:36 2008 +0000
@@ -90,6 +90,7 @@
     REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
     REGISTER_DEMUXER  (INGENIENT, ingenient);
     REGISTER_DEMUXER  (IPMOVIE, ipmovie);
+    REGISTER_MUXER    (IPOD, ipod);
     REGISTER_DEMUXER  (LMLM4, lmlm4);
     REGISTER_MUXDEMUX (M4V, m4v);
     REGISTER_MUXDEMUX (MATROSKA, matroska);
--- a/avformat.h	Sat Mar 15 16:15:47 2008 +0000
+++ b/avformat.h	Sun Mar 16 13:36:36 2008 +0000
@@ -22,7 +22,7 @@
 #define FFMPEG_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR  9
+#define LIBAVFORMAT_VERSION_MINOR 10
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
--- a/movenc.c	Sat Mar 15 16:15:47 2008 +0000
+++ b/movenc.c	Sun Mar 16 13:36:36 2008 +0000
@@ -37,6 +37,7 @@
 #define MODE_PSP 3 // example working PSP command line:
 // ffmpeg -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
 #define MODE_3G2 4
+#define MODE_IPOD 5
 
 typedef struct MOVIentry {
     unsigned int flags, size;
@@ -494,7 +495,7 @@
 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
 {
     int tag = track->enc->codec_tag;
-    if (track->mode == MODE_MP4 || track->mode == MODE_PSP) {
+    if (track->mode == MODE_MP4 || track->mode == MODE_PSP || track->mode == MODE_IPOD) {
         if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
             return 0;
         if (track->enc->codec_id == CODEC_ID_H264)           tag = MKTAG('a','v','c','1');
@@ -541,6 +542,22 @@
     return tag;
 }
 
+/** Write uuid atom.
+ * Needed to make file play in iPods running newest firmware
+ * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
+ */
+static int mov_write_uuid_tag_ipod(ByteIOContext *pb)
+{
+    put_be32(pb, 28);
+    put_tag(pb, "uuid");
+    put_be32(pb, 0x6b6840f2);
+    put_be32(pb, 0x5f244fc5);
+    put_be32(pb, 0xba39a51b);
+    put_be32(pb, 0xcf0323f3);
+    put_be32(pb, 0x0);
+    return 28;
+}
+
 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
 {
     offset_t pos = url_ftell(pb);
@@ -593,8 +610,11 @@
         mov_write_d263_tag(pb);
     else if(track->enc->codec_id == CODEC_ID_SVQ3)
         mov_write_svq3_tag(pb);
-    else if(track->enc->codec_id == CODEC_ID_H264)
+    else if(track->enc->codec_id == CODEC_ID_H264) {
         mov_write_avcc_tag(pb, track);
+        if(track->mode == MODE_IPOD)
+            mov_write_uuid_tag_ipod(pb);
+    }
     else if(track->enc->codec_id == CODEC_ID_DNXHD)
         mov_write_avid_tag(pb, track);
     else if(track->vosLen > 0)
@@ -1355,7 +1375,7 @@
         put_tag(pb, "3g2a");
     else if (mov->mode == MODE_PSP)
         put_tag(pb, "MSNV");
-    else if (mov->mode == MODE_MP4)
+    else if (mov->mode == MODE_MP4 || mov->mode == MODE_IPOD)
         put_tag(pb, "isom");
     else
         put_tag(pb, "qt  ");
@@ -1368,7 +1388,7 @@
         put_tag(pb, "3g2a");
     else if (mov->mode == MODE_PSP)
         put_tag(pb, "MSNV");
-    else if (mov->mode == MODE_MP4)
+    else if (mov->mode == MODE_MP4 || mov->mode == MODE_IPOD)
         put_tag(pb, "mp41");
     else
         put_tag(pb, "qt  ");
@@ -1454,6 +1474,7 @@
         else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2;
         else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
         else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
+        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
 
         mov_write_ftyp_tag(pb,s);
         if (mov->mode == MODE_PSP) {
@@ -1710,3 +1731,19 @@
     .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},
 };
 #endif
+#ifdef CONFIG_IPOD_MUXER
+AVOutputFormat ipod_muxer = {
+    "ipod",
+    "iPod H.264 mp4 format",
+    "application/mp4",
+    NULL,
+    sizeof(MOVContext),
+    CODEC_ID_AAC,
+    CODEC_ID_H264,
+    mov_write_header,
+    mov_write_packet,
+    mov_write_trailer,
+    .flags = AVFMT_GLOBALHEADER,
+    .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},
+};
+#endif