mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
clean and simplify
Originally committed as revision 5373 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
307eb24879
commit
039627cf48
@ -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;
|
||||
AVStream *st= s->streams[i];
|
||||
MOVTrack *track= &mov->tracks[i];
|
||||
|
||||
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");
|
||||
}
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user