1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

CTTS support patch by (Baptiste COUDURIER <baptiste.coudurier smartjog com>)

Originally committed as revision 5051 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Baptiste Coudurier 2006-02-22 23:46:20 +00:00 committed by Michael Niedermayer
parent 70b0bb8772
commit b4712e3c8b
3 changed files with 51 additions and 6 deletions

View File

@ -283,11 +283,6 @@ typedef struct {
struct MOVParseTableEntry; struct MOVParseTableEntry;
typedef struct Time2Sample{
int count;
int duration;
}Time2Sample;
typedef struct MOVStreamContext { typedef struct MOVStreamContext {
int ffindex; /* the ffmpeg stream id */ 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 ? */ int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */

View File

@ -4,4 +4,9 @@
/* mov.c */ /* mov.c */
extern const CodecTag ff_mov_obj_type[]; extern const CodecTag ff_mov_obj_type[];
typedef struct Time2Sample{
int count;
int duration;
}Time2Sample;
#endif /* FFMPEG_MOV_H */ #endif /* FFMPEG_MOV_H */

View File

@ -41,6 +41,7 @@ typedef struct MOVIentry {
unsigned int samplesInChunk; unsigned int samplesInChunk;
char key_frame; char key_frame;
unsigned int entries; unsigned int entries;
int64_t cts;
} MOVIentry; } MOVIentry;
typedef struct MOVIndex { typedef struct MOVIndex {
@ -54,6 +55,7 @@ typedef struct MOVIndex {
long sampleCount; long sampleCount;
long sampleDuration; long sampleDuration;
int hasKeyframes; int hasKeyframes;
int hasBframes;
int language; int language;
int trackID; int trackID;
AVCodecContext *enc; AVCodecContext *enc;
@ -542,6 +544,41 @@ static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
return updateSize(pb, pos); 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: */ /* TODO: */
/* Time to sample atom */ /* Time to sample atom */
static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track) static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
@ -580,6 +617,9 @@ static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)
if (track->enc->codec_type == CODEC_TYPE_VIDEO && if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
track->hasKeyframes) track->hasKeyframes)
mov_write_stss_tag(pb, track); 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_stsc_tag(pb, track);
mov_write_stsz_tag(pb, track); mov_write_stsz_tag(pb, track);
mov_write_stco_tag(pb, track); mov_write_stco_tag(pb, track);
@ -1352,7 +1392,8 @@ 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; 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_movvideo_tags, c->codec_id)){
if(!codec_get_tag(codec_bmp_tags, c->codec_id)) if(!codec_get_tag(codec_bmp_tags, c->codec_id))
return -1; return -1;
@ -1360,6 +1401,7 @@ static int mov_write_header(AVFormatContext *s)
av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n"); 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){ }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_movaudio_tags, c->codec_id)){
if(!codec_get_tag(codec_wav_tags, c->codec_id)) if(!codec_get_tag(codec_wav_tags, c->codec_id))
return -1; return -1;
@ -1472,6 +1514,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
trk->cluster[cl][id].size = size; trk->cluster[cl][id].size = size;
trk->cluster[cl][id].entries = samplesInChunk; trk->cluster[cl][id].entries = samplesInChunk;
if(enc->codec_type == CODEC_TYPE_VIDEO) { 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); trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
if(trk->cluster[cl][id].key_frame) if(trk->cluster[cl][id].key_frame)
trk->hasKeyframes = 1; trk->hasKeyframes = 1;