Commit 166ba990 authored by bcoudurier's avatar bcoudurier

clean and simplify


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@5373 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 53eab086
...@@ -47,7 +47,6 @@ typedef struct MOVIentry { ...@@ -47,7 +47,6 @@ typedef struct MOVIentry {
typedef struct MOVIndex { typedef struct MOVIndex {
int mode; int mode;
int entry; int entry;
uint64_t mdat_size;
int ents_allocated; int ents_allocated;
long timescale; long timescale;
long time; long time;
...@@ -58,6 +57,7 @@ typedef struct MOVIndex { ...@@ -58,6 +57,7 @@ typedef struct MOVIndex {
int hasBframes; int hasBframes;
int language; int language;
int trackID; int trackID;
int tag;
AVCodecContext *enc; AVCodecContext *enc;
int vosLen; int vosLen;
...@@ -70,12 +70,11 @@ typedef struct MOVContext { ...@@ -70,12 +70,11 @@ typedef struct MOVContext {
int64_t time; int64_t time;
int nb_streams; int nb_streams;
offset_t mdat_pos; offset_t mdat_pos;
uint64_t mdat_size;
long timescale; long timescale;
MOVTrack tracks[MAX_STREAMS]; MOVTrack tracks[MAX_STREAMS];
} MOVContext; } MOVContext;
static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track);
//FIXME supprt 64bit varaint with wide placeholders //FIXME supprt 64bit varaint with wide placeholders
static offset_t updateSize (ByteIOContext *pb, offset_t pos) static offset_t updateSize (ByteIOContext *pb, offset_t pos)
{ {
...@@ -225,6 +224,111 @@ static int mov_write_damr_tag(ByteIOContext *pb) ...@@ -225,6 +224,111 @@ static int mov_write_damr_tag(ByteIOContext *pb)
return 0x11; 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) static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack* track)
{ {
offset_t pos = url_ftell(pb); offset_t pos = url_ftell(pb);
...@@ -270,21 +374,9 @@ static const CodecTag codec_movaudio_tags[] = { ...@@ -270,21 +374,9 @@ static const CodecTag codec_movaudio_tags[] = {
static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track) static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
{ {
offset_t pos = url_ftell(pb); offset_t pos = url_ftell(pb);
int tag;
put_be32(pb, 0); /* size */ put_be32(pb, 0); /* size */
put_le32(pb, track->tag); // store it byteswapped
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_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */
put_be16(pb, 0); /* Reserved */ put_be16(pb, 0); /* Reserved */
put_be16(pb, 1); /* Data-reference index, XXX == 1 */ put_be16(pb, 1); /* Data-reference index, XXX == 1 */
...@@ -303,20 +395,17 @@ static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track) ...@@ -303,20 +395,17 @@ static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
put_be16(pb, 0x10); /* Reserved */ put_be16(pb, 0x10); /* Reserved */
if(track->enc->codec_id == CODEC_ID_AAC || 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)*/ put_be16(pb, 0xfffe); /* compression ID (vbr)*/
} }
else else {
{
put_be16(pb, 0); /* compression ID (= 0) */ put_be16(pb, 0); /* compression ID (= 0) */
} }
put_be16(pb, 0); /* packet size (= 0) */ put_be16(pb, 0); /* packet size (= 0) */
put_be16(pb, track->timescale); /* Time scale */ put_be16(pb, track->timescale); /* Time scale */
put_be16(pb, 0); /* Reserved */ 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 */ /* SoundDescription V1 extended info */
put_be32(pb, track->enc->frame_size); /* Samples per packet */ put_be32(pb, track->enc->frame_size); /* Samples per packet */
put_be32(pb, 1536); /* Bytes per packet */ put_be32(pb, 1536); /* Bytes per packet */
...@@ -467,111 +556,6 @@ static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track) ...@@ -467,111 +556,6 @@ static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
return updateSize(pb, pos); 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[] = { static const CodecTag codec_movvideo_tags[] = {
{ CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },
{ CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
...@@ -587,11 +571,9 @@ static const CodecTag codec_movvideo_tags[] = { ...@@ -587,11 +571,9 @@ static const CodecTag codec_movvideo_tags[] = {
{ CODEC_ID_NONE, 0 }, { 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; int tag = track->enc->codec_tag;
tag = track->enc->codec_tag;
if (!tag) { if (!tag) {
if (track->enc->codec_id == CODEC_ID_DVVIDEO) { if (track->enc->codec_id == CODEC_ID_DVVIDEO) {
if (track->enc->height == 480) { /* NTSC */ if (track->enc->height == 480) { /* NTSC */
...@@ -612,8 +594,30 @@ static int mov_find_video_codec_tag(MOVTrack* track) ...@@ -612,8 +594,30 @@ static int mov_find_video_codec_tag(MOVTrack* track)
} }
} }
// if no mac fcc found, try with Microsoft tags // if no mac fcc found, try with Microsoft tags
if (!tag) if (!tag) {
tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id); 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); assert(tag);
return tag; return tag;
} }
...@@ -622,13 +626,9 @@ static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track) ...@@ -622,13 +626,9 @@ static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
{ {
offset_t pos = url_ftell(pb); offset_t pos = url_ftell(pb);
char compressor_name[32]; char compressor_name[32];
int tag;
put_be32(pb, 0); /* size */ put_be32(pb, 0); /* size */
put_le32(pb, track->tag); // store it byteswapped
tag = mov_find_video_codec_tag(track);
put_le32(pb, tag); // store it byteswapped
put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */
put_be16(pb, 0); /* Reserved */ put_be16(pb, 0); /* Reserved */
put_be16(pb, 1); /* Data-reference index */ put_be16(pb, 1); /* Data-reference index */
...@@ -1583,30 +1583,19 @@ static int mov_write_header(AVFormatContext *s) ...@@ -1583,30 +1583,19 @@ static int mov_write_header(AVFormatContext *s)
} }
for(i=0; i<s->nb_streams; i++){ for(i=0; i<s->nb_streams; i++){
AVCodecContext *c= s->streams[i]->codec; AVStream *st= s->streams[i];
MOVTrack *track= &mov->tracks[i];
if(c->codec_type == CODEC_TYPE_VIDEO){ track->enc = st->codec;
av_set_pts_info(s->streams[i], 64, 1, c->time_base.den); if(st->codec->codec_type == CODEC_TYPE_VIDEO){
if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){ track->tag = mov_find_video_codec_tag(s, track);
if(!codec_get_tag(codec_bmp_tags, c->codec_id)) av_set_pts_info(st, 64, 1, st->codec->time_base.den);
return -1; }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){
else track->tag = mov_find_audio_codec_tag(s, track);
av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n"); av_set_pts_info(st, 64, 1, st->codec->sample_rate);
}
}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");
}
} }
mov->tracks[i].language = ff_mov_iso639_to_lang(s->streams[i]->language, mov->mode != MODE_MOV); track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);
} track->mode = mov->mode;
for (i=0; i<MAX_STREAMS; i++) {
mov->tracks[i].mode = mov->mode;
} }
mov_write_mdat_tag(pb, mov); mov_write_mdat_tag(pb, mov);
...@@ -1621,8 +1610,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -1621,8 +1610,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
{ {
MOVContext *mov = s->priv_data; MOVContext *mov = s->priv_data;
ByteIOContext *pb = &s->pb; 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; int cl, id;
unsigned int samplesInChunk = 0; unsigned int samplesInChunk = 0;
int size= pkt->size; int size= pkt->size;
...@@ -1698,10 +1687,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -1698,10 +1687,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if(trk->cluster[cl][id].key_frame) if(trk->cluster[cl][id].key_frame)
trk->hasKeyframes++; trk->hasKeyframes++;
} }
trk->enc = enc;
trk->entry++; trk->entry++;
trk->sampleCount += samplesInChunk; trk->sampleCount += samplesInChunk;
trk->mdat_size += size; mov->mdat_size += size;
put_buffer(pb, pkt->data, size); put_buffer(pb, pkt->data, size);
...@@ -1714,26 +1702,20 @@ static int mov_write_trailer(AVFormatContext *s) ...@@ -1714,26 +1702,20 @@ static int mov_write_trailer(AVFormatContext *s)
MOVContext *mov = s->priv_data; MOVContext *mov = s->priv_data;
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
int res = 0; int res = 0;
int i; int i, j;
uint64_t j;
offset_t moov_pos = url_ftell(pb); offset_t moov_pos = url_ftell(pb);
/* Write size of mdat tag */ /* Write size of mdat tag */
for (i=0, j=0; i<MAX_STREAMS; i++) { if (mov->mdat_size+8 <= UINT32_MAX) {
if(mov->tracks[i].ents_allocated > 0) {
j += mov->tracks[i].mdat_size;
}
}
if (j+8 <= UINT32_MAX) {
url_fseek(pb, mov->mdat_pos, SEEK_SET); url_fseek(pb, mov->mdat_pos, SEEK_SET);
put_be32(pb, j+8); put_be32(pb, mov->mdat_size+8);
} else { } else {
/* overwrite 'wide' placeholder atom */ /* overwrite 'wide' placeholder atom */
url_fseek(pb, mov->mdat_pos - 8, SEEK_SET); 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_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */
put_tag(pb, "mdat"); put_tag(pb, "mdat");
put_be64(pb, j+16); put_be64(pb, mov->mdat_size+16);
} }
url_fseek(pb, moov_pos, SEEK_SET); url_fseek(pb, moov_pos, SEEK_SET);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment