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:
parent
70b0bb8772
commit
b4712e3c8b
@ -283,11 +283,6 @@ typedef struct {
|
||||
|
||||
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 ? */
|
||||
|
@ -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 */
|
||||
|
@ -41,6 +41,7 @@ typedef struct MOVIentry {
|
||||
unsigned int samplesInChunk;
|
||||
char key_frame;
|
||||
unsigned int entries;
|
||||
int64_t cts;
|
||||
} MOVIentry;
|
||||
|
||||
typedef struct MOVIndex {
|
||||
@ -54,6 +55,7 @@ typedef struct MOVIndex {
|
||||
long sampleCount;
|
||||
long sampleDuration;
|
||||
int hasKeyframes;
|
||||
int hasBframes;
|
||||
int language;
|
||||
int trackID;
|
||||
AVCodecContext *enc;
|
||||
@ -542,6 +544,41 @@ static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
|
||||
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 @@ static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)
|
||||
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 @@ 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){
|
||||
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 @@ 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");
|
||||
}
|
||||
}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 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user