summaryrefslogtreecommitdiff
path: root/libavformat/movenc.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2006-05-13 18:01:16 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2006-05-13 18:01:16 +0000
commit039627cf487a950f0c76d0d7a26aacae3ec3552d (patch)
tree3e0b9ff7bd492cb1cd50b012955efda275a97a80 /libavformat/movenc.c
parent307eb248794057e86028a6468ddf257c915151cc (diff)
clean and simplify
Originally committed as revision 5373 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r--libavformat/movenc.c330
1 files changed, 156 insertions, 174 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 26ee17115f..b4d2267fac 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -47,7 +47,6 @@ typedef struct MOVIentry {
typedef struct MOVIndex {
int mode;
int entry;
- uint64_t mdat_size;
int ents_allocated;
long timescale;
long time;
@@ -58,6 +57,7 @@ typedef struct MOVIndex {
int hasBframes;
int language;
int trackID;
+ int tag;
AVCodecContext *enc;
int vosLen;
@@ -70,12 +70,11 @@ typedef struct MOVContext {
int64_t time;
int nb_streams;
offset_t mdat_pos;
+ uint64_t mdat_size;
long timescale;
MOVTrack tracks[MAX_STREAMS];
} MOVContext;
-static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track);
-
//FIXME supprt 64bit varaint with wide placeholders
static offset_t updateSize (ByteIOContext *pb, offset_t pos)
{
@@ -225,6 +224,111 @@ static int mov_write_damr_tag(ByteIOContext *pb)
return 0x11;
}
+static unsigned int descrLength(unsigned int len)
+{
+ if (len < 0x00000080)
+ return 2 + len;
+ else if (len < 0x00004000)
+ return 3 + len;
+ else if(len < 0x00200000)
+ return 4 + len;
+ else
+ return 5 + len;
+}
+
+static void putDescr(ByteIOContext *pb, int tag, int size)
+{
+ uint32_t len;
+ uint8_t vals[4];
+
+ len = size;
+ vals[3] = (uint8_t)(len & 0x7f);
+ len >>= 7;
+ vals[2] = (uint8_t)((len & 0x7f) | 0x80);
+ len >>= 7;
+ vals[1] = (uint8_t)((len & 0x7f) | 0x80);
+ len >>= 7;
+ vals[0] = (uint8_t)((len & 0x7f) | 0x80);
+
+ put_byte(pb, tag); // DescriptorTag
+
+ if (size < 0x00000080)
+ {
+ put_byte(pb, vals[3]);
+ }
+ else if (size < 0x00004000)
+ {
+ put_byte(pb, vals[2]);
+ put_byte(pb, vals[3]);
+ }
+ else if (size < 0x00200000)
+ {
+ put_byte(pb, vals[1]);
+ put_byte(pb, vals[2]);
+ put_byte(pb, vals[3]);
+ }
+ else if (size < 0x10000000)
+ {
+ put_byte(pb, vals[0]);
+ put_byte(pb, vals[1]);
+ put_byte(pb, vals[2]);
+ put_byte(pb, vals[3]);
+ }
+}
+
+static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
+{
+ int decoderSpecificInfoLen;
+ offset_t pos = url_ftell(pb);
+
+ decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
+
+ put_be32(pb, 0); // size
+ put_tag(pb, "esds");
+ put_be32(pb, 0); // Version
+
+ // ES descriptor
+ putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
+ descrLength(1));
+ put_be16(pb, track->trackID);
+ put_byte(pb, 0x00); // flags (= no flags)
+
+ // DecoderConfig descriptor
+ putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
+
+ // Object type indication
+ put_byte(pb, codec_get_tag(ff_mov_obj_type, track->enc->codec_id));
+
+ // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
+ // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
+ if(track->enc->codec_type == CODEC_TYPE_AUDIO)
+ put_byte(pb, 0x15); // flags (= Audiostream)
+ else
+ put_byte(pb, 0x11); // flags (= Visualstream)
+
+ put_byte(pb, track->enc->rc_buffer_size>>(3+16)); // Buffersize DB (24 bits)
+ put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
+
+ put_be32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window)
+ if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
+ put_be32(pb, 0); // vbr
+ else
+ put_be32(pb, track->enc->rc_max_rate); // avg bitrate
+
+ if (track->vosLen)
+ {
+ // DecoderSpecific info descriptor
+ putDescr(pb, 0x05, track->vosLen);
+ put_buffer(pb, track->vosData, track->vosLen);
+ }
+
+
+ // SL descriptor
+ putDescr(pb, 0x06, 1);
+ put_byte(pb, 0x02);
+ return updateSize (pb, pos);
+}
+
static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack* track)
{
offset_t pos = url_ftell(pb);
@@ -270,21 +374,9 @@ static const CodecTag codec_movaudio_tags[] = {
static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
{
offset_t pos = url_ftell(pb);
- int tag;
put_be32(pb, 0); /* size */
-
- tag = track->enc->codec_tag;
- if (!tag)
- tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
- // if no mac fcc found, try with Microsoft tags
- if (!tag)
- {
- int tmp = codec_get_tag(codec_wav_tags, track->enc->codec_id);
- tag = MKTAG('m', 's', ((tmp >> 8) & 0xff), (tmp & 0xff));
- }
- put_le32(pb, tag); // store it byteswapped
-
+ put_le32(pb, track->tag); // store it byteswapped
put_be32(pb, 0); /* Reserved */
put_be16(pb, 0); /* Reserved */
put_be16(pb, 1); /* Data-reference index, XXX == 1 */
@@ -303,20 +395,17 @@ static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
put_be16(pb, 0x10); /* Reserved */
if(track->enc->codec_id == CODEC_ID_AAC ||
- track->enc->codec_id == CODEC_ID_MP3)
- {
+ track->enc->codec_id == CODEC_ID_MP3) {
put_be16(pb, 0xfffe); /* compression ID (vbr)*/
}
- else
- {
+ else {
put_be16(pb, 0); /* compression ID (= 0) */
}
put_be16(pb, 0); /* packet size (= 0) */
put_be16(pb, track->timescale); /* Time scale */
put_be16(pb, 0); /* Reserved */
- if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC)
- {
+ if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC) {
/* SoundDescription V1 extended info */
put_be32(pb, track->enc->frame_size); /* Samples per packet */
put_be32(pb, 1536); /* Bytes per packet */
@@ -467,111 +556,6 @@ static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
return updateSize(pb, pos);
}
-static unsigned int descrLength(unsigned int len)
-{
- if (len < 0x00000080)
- return 2 + len;
- else if (len < 0x00004000)
- return 3 + len;
- else if(len < 0x00200000)
- return 4 + len;
- else
- return 5 + len;
-}
-
-static void putDescr(ByteIOContext *pb, int tag, int size)
-{
- uint32_t len;
- uint8_t vals[4];
-
- len = size;
- vals[3] = (uint8_t)(len & 0x7f);
- len >>= 7;
- vals[2] = (uint8_t)((len & 0x7f) | 0x80);
- len >>= 7;
- vals[1] = (uint8_t)((len & 0x7f) | 0x80);
- len >>= 7;
- vals[0] = (uint8_t)((len & 0x7f) | 0x80);
-
- put_byte(pb, tag); // DescriptorTag
-
- if (size < 0x00000080)
- {
- put_byte(pb, vals[3]);
- }
- else if (size < 0x00004000)
- {
- put_byte(pb, vals[2]);
- put_byte(pb, vals[3]);
- }
- else if (size < 0x00200000)
- {
- put_byte(pb, vals[1]);
- put_byte(pb, vals[2]);
- put_byte(pb, vals[3]);
- }
- else if (size < 0x10000000)
- {
- put_byte(pb, vals[0]);
- put_byte(pb, vals[1]);
- put_byte(pb, vals[2]);
- put_byte(pb, vals[3]);
- }
-}
-
-static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
-{
- int decoderSpecificInfoLen;
- offset_t pos = url_ftell(pb);
-
- decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
-
- put_be32(pb, 0); // size
- put_tag(pb, "esds");
- put_be32(pb, 0); // Version
-
- // ES descriptor
- putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
- descrLength(1));
- put_be16(pb, track->trackID);
- put_byte(pb, 0x00); // flags (= no flags)
-
- // DecoderConfig descriptor
- putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
-
- // Object type indication
- put_byte(pb, codec_get_tag(ff_mov_obj_type, track->enc->codec_id));
-
- // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
- // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
- if(track->enc->codec_type == CODEC_TYPE_AUDIO)
- put_byte(pb, 0x15); // flags (= Audiostream)
- else
- put_byte(pb, 0x11); // flags (= Visualstream)
-
- put_byte(pb, track->enc->rc_buffer_size>>(3+16)); // Buffersize DB (24 bits)
- put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
-
- put_be32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window)
- if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
- put_be32(pb, 0); // vbr
- else
- put_be32(pb, track->enc->rc_max_rate); // avg bitrate
-
- if (track->vosLen)
- {
- // DecoderSpecific info descriptor
- putDescr(pb, 0x05, track->vosLen);
- put_buffer(pb, track->vosData, track->vosLen);
- }
-
-
- // SL descriptor
- putDescr(pb, 0x06, 1);
- put_byte(pb, 0x02);
- return updateSize (pb, pos);
-}
-
static const CodecTag codec_movvideo_tags[] = {
{ CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },
{ CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
@@ -587,11 +571,9 @@ static const CodecTag codec_movvideo_tags[] = {
{ CODEC_ID_NONE, 0 },
};
-static int mov_find_video_codec_tag(MOVTrack* track)
+static int mov_find_video_codec_tag(AVFormatContext *s, MOVTrack *track)
{
- int tag;
-
- tag = track->enc->codec_tag;
+ int tag = track->enc->codec_tag;
if (!tag) {
if (track->enc->codec_id == CODEC_ID_DVVIDEO) {
if (track->enc->height == 480) { /* NTSC */
@@ -612,8 +594,30 @@ static int mov_find_video_codec_tag(MOVTrack* track)
}
}
// if no mac fcc found, try with Microsoft tags
- if (!tag)
+ if (!tag) {
tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);
+ if (tag) {
+ av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");
+ }
+ }
+ assert(tag);
+ return tag;
+}
+
+static int mov_find_audio_codec_tag(AVFormatContext *s, MOVTrack *track)
+{
+ int tag = track->enc->codec_tag;
+ if (!tag) {
+ tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
+ }
+ // if no mac fcc found, try with Microsoft tags
+ if (!tag) {
+ int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id);
+ if (ms_tag) {
+ tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
+ av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");
+ }
+ }
assert(tag);
return tag;
}
@@ -622,13 +626,9 @@ static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
{
offset_t pos = url_ftell(pb);
char compressor_name[32];
- int tag;
put_be32(pb, 0); /* size */
-
- tag = mov_find_video_codec_tag(track);
- put_le32(pb, tag); // store it byteswapped
-
+ put_le32(pb, track->tag); // store it byteswapped
put_be32(pb, 0); /* Reserved */
put_be16(pb, 0); /* Reserved */
put_be16(pb, 1); /* Data-reference index */
@@ -1583,30 +1583,19 @@ static int mov_write_header(AVFormatContext *s)
}
for(i=0; i<s->nb_streams; i++){
- AVCodecContext *c= s->streams[i]->codec;
-
- if(c->codec_type == CODEC_TYPE_VIDEO){
- av_set_pts_info(s->streams[i], 64, 1, c->time_base.den);
- if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){
- if(!codec_get_tag(codec_bmp_tags, c->codec_id))
- return -1;
- else
- av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");
- }
- }else if(c->codec_type == CODEC_TYPE_AUDIO){
- av_set_pts_info(s->streams[i], 64, 1, c->sample_rate);
- if (!codec_get_tag(codec_movaudio_tags, c->codec_id)){
- if(!codec_get_tag(codec_wav_tags, c->codec_id))
- return -1;
- else
- av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");
- }
+ AVStream *st= s->streams[i];
+ MOVTrack *track= &mov->tracks[i];
+
+ track->enc = st->codec;
+ if(st->codec->codec_type == CODEC_TYPE_VIDEO){
+ track->tag = mov_find_video_codec_tag(s, track);
+ av_set_pts_info(st, 64, 1, st->codec->time_base.den);
+ }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){
+ track->tag = mov_find_audio_codec_tag(s, track);
+ av_set_pts_info(st, 64, 1, st->codec->sample_rate);
}
- mov->tracks[i].language = ff_mov_iso639_to_lang(s->streams[i]->language, mov->mode != MODE_MOV);
- }
-
- for (i=0; i<MAX_STREAMS; i++) {
- mov->tracks[i].mode = mov->mode;
+ track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);
+ track->mode = mov->mode;
}
mov_write_mdat_tag(pb, mov);
@@ -1621,8 +1610,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
{
MOVContext *mov = s->priv_data;
ByteIOContext *pb = &s->pb;
- AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
- MOVTrack* trk = &mov->tracks[pkt->stream_index];
+ MOVTrack *trk = &mov->tracks[pkt->stream_index];
+ AVCodecContext *enc = trk->enc;
int cl, id;
unsigned int samplesInChunk = 0;
int size= pkt->size;
@@ -1698,10 +1687,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if(trk->cluster[cl][id].key_frame)
trk->hasKeyframes++;
}
- trk->enc = enc;
trk->entry++;
trk->sampleCount += samplesInChunk;
- trk->mdat_size += size;
+ mov->mdat_size += size;
put_buffer(pb, pkt->data, size);
@@ -1714,26 +1702,20 @@ static int mov_write_trailer(AVFormatContext *s)
MOVContext *mov = s->priv_data;
ByteIOContext *pb = &s->pb;
int res = 0;
- int i;
- uint64_t j;
+ int i, j;
offset_t moov_pos = url_ftell(pb);
/* Write size of mdat tag */
- for (i=0, j=0; i<MAX_STREAMS; i++) {
- if(mov->tracks[i].ents_allocated > 0) {
- j += mov->tracks[i].mdat_size;
- }
- }
- if (j+8 <= UINT32_MAX) {
+ if (mov->mdat_size+8 <= UINT32_MAX) {
url_fseek(pb, mov->mdat_pos, SEEK_SET);
- put_be32(pb, j+8);
+ put_be32(pb, mov->mdat_size+8);
} else {
/* overwrite 'wide' placeholder atom */
url_fseek(pb, mov->mdat_pos - 8, SEEK_SET);
put_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */
put_tag(pb, "mdat");
- put_be64(pb, j+16);
+ put_be64(pb, mov->mdat_size+16);
}
url_fseek(pb, moov_pos, SEEK_SET);