Mercurial > libavformat.hg
changeset 911:343ddd5b793c libavformat
Fix for title field in PSP compatible mp4 files. Patch by
Olivier, oandrieu <at> gmail.com.
author | banan |
---|---|
date | Tue, 24 Jan 2006 08:03:42 +0000 |
parents | d92e6d673ef5 |
children | 844bc9093aa3 |
files | movenc.c |
diffstat | 1 files changed, 84 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/movenc.c Mon Jan 23 14:28:50 2006 +0000 +++ b/movenc.c Tue Jan 24 08:03:42 2006 +0000 @@ -433,28 +433,6 @@ { 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 @@ put_buffer(pb, track->vosData, track->vosLen); } - track->vosData = vosDataBackup; - track->vosLen = vosLenBackup; // SL descriptor putDescr(pb, 0x06, 1); @@ -1182,6 +1158,68 @@ 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 @@ } } + 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 @@ } /* 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 @@ 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 @@ 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 @@ mov_write_header, mov_write_packet, mov_write_trailer, -// .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER, }; static AVOutputFormat _3g2_oformat = {