Mercurial > libavformat.hg
changeset 971:43f85eba04c4 libavformat
CTTS support patch by (Baptiste COUDURIER <baptiste.coudurier smartjog com>)
author | michael |
---|---|
date | Wed, 22 Feb 2006 23:46:20 +0000 |
parents | 2266681a4a52 |
children | d983c2b9333e |
files | mov.c mov.h movenc.c |
diffstat | 3 files changed, 51 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mov.c Wed Feb 22 00:18:12 2006 +0000 +++ b/mov.c Wed Feb 22 23:46:20 2006 +0000 @@ -283,11 +283,6 @@ struct MOVParseTableEntry; -typedef struct Time2Sample{ - int count; - int duration; -}Time2Sample; - typedef struct MOVStreamContext { int ffindex; /* the ffmpeg stream id */ int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
--- a/mov.h Wed Feb 22 00:18:12 2006 +0000 +++ b/mov.h Wed Feb 22 23:46:20 2006 +0000 @@ -4,4 +4,9 @@ /* mov.c */ extern const CodecTag ff_mov_obj_type[]; +typedef struct Time2Sample{ + int count; + int duration; +}Time2Sample; + #endif /* FFMPEG_MOV_H */
--- a/movenc.c Wed Feb 22 00:18:12 2006 +0000 +++ b/movenc.c Wed Feb 22 23:46:20 2006 +0000 @@ -41,6 +41,7 @@ unsigned int samplesInChunk; char key_frame; unsigned int entries; + int64_t cts; } MOVIentry; typedef struct MOVIndex { @@ -54,6 +55,7 @@ long sampleCount; long sampleDuration; int hasKeyframes; + int hasBframes; int language; int trackID; AVCodecContext *enc; @@ -542,6 +544,41 @@ return updateSize(pb, pos); } +static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack* track) +{ + Time2Sample *ctts_entries; + uint32_t entries = 0; + uint32_t atom_size; + int i; + + ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */ + ctts_entries[0].count = 1; + ctts_entries[0].duration = track->cluster[0][0].cts; + for (i=1; i<track->entry; i++) { + int cl = i / MOV_INDEX_CLUSTER_SIZE; + int id = i % MOV_INDEX_CLUSTER_SIZE; + if (track->cluster[cl][id].cts == ctts_entries[entries].duration) { + ctts_entries[entries].count++; /* compress */ + } else { + entries++; + ctts_entries[entries].duration = track->cluster[cl][id].cts; + ctts_entries[entries].count = 1; + } + } + entries++; /* last one */ + atom_size = 16 + (entries * 8); + put_be32(pb, atom_size); /* size */ + put_tag(pb, "ctts"); + put_be32(pb, 0); /* version & flags */ + put_be32(pb, entries); /* entry count */ + for (i=0; i<entries; i++) { + put_be32(pb, ctts_entries[i].count); + put_be32(pb, ctts_entries[i].duration); + } + av_free(ctts_entries); + return atom_size; +} + /* TODO: */ /* Time to sample atom */ static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track) @@ -580,6 +617,9 @@ if (track->enc->codec_type == CODEC_TYPE_VIDEO && track->hasKeyframes) mov_write_stss_tag(pb, track); + if (track->enc->codec_type == CODEC_TYPE_VIDEO && + track->hasBframes) + mov_write_ctts_tag(pb, track); mov_write_stsc_tag(pb, track); mov_write_stsz_tag(pb, track); mov_write_stco_tag(pb, track); @@ -1352,7 +1392,8 @@ for(i=0; i<s->nb_streams; i++){ AVCodecContext *c= s->streams[i]->codec; - if (c->codec_type == CODEC_TYPE_VIDEO){ + 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; @@ -1360,6 +1401,7 @@ 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; @@ -1472,6 +1514,9 @@ trk->cluster[cl][id].size = size; trk->cluster[cl][id].entries = samplesInChunk; if(enc->codec_type == CODEC_TYPE_VIDEO) { + if (pkt->dts != pkt->pts) + trk->hasBframes = 1; + trk->cluster[cl][id].cts = pkt->pts - pkt->dts; trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY); if(trk->cluster[cl][id].key_frame) trk->hasKeyframes = 1;