summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorBenjamin Larsson <banan@ludd.ltu.se>2006-01-24 08:03:42 +0000
committerBenjamin Larsson <banan@ludd.ltu.se>2006-01-24 08:03:42 +0000
commitdcfdb046eec3e72457311721a09404c3fd724609 (patch)
treea30a296478dcdbb8bcdcf52851504289730f0d07 /libavformat
parent29f7ae79e739b70a70cf1931a8bdf9224859d539 (diff)
Fix for title field in PSP compatible mp4 files. Patch by
Olivier, oandrieu <at> gmail.com. Originally committed as revision 4889 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/movenc.c130
1 files changed, 84 insertions, 46 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index f58d764f73..8aed24857e 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -433,28 +433,6 @@ static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
{
int decoderSpecificInfoLen;
offset_t pos = url_ftell(pb);
- void *vosDataBackup=track->vosData;
- int vosLenBackup=track->vosLen;
-
- // we should be able to have these passed in, via vosData, then we wouldn't need to attack this routine at all
- static const char PSPAACData[]={0x13,0x10};
- static const char PSPMP4Data[]={0x00,0x00,0x01,0xB0,0x03,0x00,0x00,0x01,0xB5,0x09,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x20,0x00,0x84,0x5D,0x4C,0x28,0x50,0x20,0xF0,0xA3,0x1F };
-
-
- if (track->mode == MODE_PSP) // fails on psp if this is not here
- {
- if (track->enc->codec_id == CODEC_ID_AAC)
- {
- track->vosLen = 2;
- track->vosData = (uint8_t *) PSPAACData;
- }
-
- if (track->enc->codec_id == CODEC_ID_MPEG4)
- {
- track->vosLen = 28;
- track->vosData = (uint8_t *) PSPMP4Data;
- }
- }
decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
@@ -497,8 +475,6 @@ static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
put_buffer(pb, track->vosData, track->vosLen);
}
- track->vosData = vosDataBackup;
- track->vosLen = vosLenBackup;
// SL descriptor
putDescr(pb, 0x06, 1);
@@ -1182,6 +1158,68 @@ static int mov_write_udta_tag(ByteIOContext *pb, MOVContext* mov,
return updateSize(pb, pos);
}
+
+static size_t ascii_to_wc (ByteIOContext *pb, char *b, size_t n)
+{
+ size_t i;
+ unsigned char c;
+ for (i = 0; i < n - 1; i++) {
+ c = b[i];
+ if (! (0x20 <= c && c <= 0x7f ))
+ c = 0x3f; /* '?' */
+ put_be16(pb, c);
+ }
+ put_be16(pb, 0x00);
+ return 2*n;
+}
+
+static uint16_t language_code (char *str)
+{
+ return ((((str[0]-'a') & 0x1F)<<10) + (((str[1]-'a') & 0x1F)<<5) + ((str[2]-'a') & 0x1F));
+}
+
+static int mov_write_uuidusmt_tag (ByteIOContext *pb, AVFormatContext *s)
+{
+ size_t len, size;
+ offset_t pos, curpos;
+
+ size = 0;
+ if (s->title[0]) {
+ pos = url_ftell(pb);
+ put_be32(pb, 0); /* size placeholder*/
+ put_tag(pb, "uuid");
+ put_tag(pb, "USMT");
+ put_be32(pb, 0x21d24fce ); /* 96 bit UUID */
+ put_be32(pb, 0xbb88695c );
+ put_be32(pb, 0xfac9c740 );
+ size += 24;
+
+ put_be32(pb, 0); /* size placeholder*/
+ put_tag(pb, "MTDT");
+ put_be16(pb, 1);
+ size += 10;
+
+ // Title
+ len = strlen(s->title)+1;
+ put_be16(pb, len*2+10); /* size */
+ put_be32(pb, 0x01); /* type */
+ put_be16(pb, language_code("und")); /* language */
+ put_be16(pb, 0x01); /* ? */
+ ascii_to_wc (pb, s->title, len);
+ size += len*2+10;
+
+ // size
+ curpos = url_ftell(pb);
+ url_fseek(pb, pos, SEEK_SET);
+ put_be32(pb, size);
+ url_fseek(pb, pos+24, SEEK_SET);
+ put_be32(pb, size-24);
+ url_fseek(pb, curpos, SEEK_SET);
+ }
+
+ return size;
+}
+
static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
AVFormatContext *s)
{
@@ -1224,6 +1262,9 @@ static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
}
}
+ if (mov->mode == MODE_PSP)
+ mov_write_uuidusmt_tag(pb, s);
+ else
mov_write_udta_tag(pb, mov, s);
return updateSize(pb, pos);
@@ -1241,7 +1282,7 @@ int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov)
}
/* TODO: This needs to be more general */
-int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
+static void mov_write_ftyp_tag (ByteIOContext *pb, AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
@@ -1267,17 +1308,14 @@ int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
put_tag(pb, "MSNV");
else
put_tag(pb, "mp41");
-
- return 0x14;
}
static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
{
- int AudioRate = s->streams[1]->codec->sample_rate;
- int FrameRate = ((s->streams[0]->codec->time_base.den) * (0x10000))/ (s->streams[0]->codec->time_base.num);
-
- //printf("audiorate = %d\n",AudioRate);
- //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec->time_base.den,s->streams[0]->codec->time_base.num,FrameRate);
+ AVCodecContext *VideoCodec = s->streams[0]->codec;
+ AVCodecContext *AudioCodec = s->streams[1]->codec;
+ int AudioRate = AudioCodec->sample_rate;
+ int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);
put_be32(pb, 0x94 ); /* size */
put_tag(pb, "uuid");
@@ -1299,29 +1337,29 @@ static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
put_be32(pb, 0x2c ); /* size */
put_tag(pb, "APRF"); /* audio */
put_be32(pb, 0x0 );
- put_be32(pb, 0x2 );
+ put_be32(pb, 0x2 ); /* TrackID */
put_tag(pb, "mp4a");
put_be32(pb, 0x20f );
put_be32(pb, 0x0 );
- put_be32(pb, 0x40 );
- put_be32(pb, 0x40 );
- put_be32(pb, AudioRate ); //24000 ... audio rate?
- put_be32(pb, 0x2 );
+ put_be32(pb, AudioCodec->bit_rate / 1000);
+ put_be32(pb, AudioCodec->bit_rate / 1000);
+ put_be32(pb, AudioRate );
+ put_be32(pb, AudioCodec->channels );
put_be32(pb, 0x34 ); /* size */
put_tag(pb, "VPRF"); /* video */
put_be32(pb, 0x0 );
- put_be32(pb, 0x1 );
+ put_be32(pb, 0x1 ); /* TrackID */
put_tag(pb, "mp4v");
put_be32(pb, 0x103 );
put_be32(pb, 0x0 );
- put_be32(pb, 0xc0 );
- put_be32(pb, 0xc0 );
- put_be32(pb, FrameRate); // was 0xefc29
- put_be32(pb, FrameRate ); // was 0xefc29
- put_be16(pb, s->streams[0]->codec->width);
- put_be16(pb, s->streams[0]->codec->height);
- put_be32(pb, 0x010001 );
+ put_be32(pb, VideoCodec->bit_rate / 1000);
+ put_be32(pb, VideoCodec->bit_rate / 1000);
+ put_be32(pb, FrameRate);
+ put_be32(pb, FrameRate);
+ put_be16(pb, VideoCodec->width);
+ put_be16(pb, VideoCodec->height);
+ put_be32(pb, 0x010001); /* ? */
}
static int mov_write_header(AVFormatContext *s)
@@ -1567,7 +1605,7 @@ static AVOutputFormat psp_oformat = {
mov_write_header,
mov_write_packet,
mov_write_trailer,
-// .flags = AVFMT_GLOBALHEADER,
+ .flags = AVFMT_GLOBALHEADER,
};
static AVOutputFormat _3g2_oformat = {