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;
|
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 ? */
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user