You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
avformat/concatdec: add fallback for calculating file duration
If a file does not have a known duration, this leads to the timestamps starting over for the next file, causing non-monotonic timestamps. To prevent this, track the duration during demuxing and use it to determine the current file duration before opening the next file. Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
committed by
Derek Buitenhuis
parent
1291a6d0ff
commit
1a0d9b503d
@@ -44,6 +44,7 @@ typedef struct {
|
|||||||
int64_t file_start_time;
|
int64_t file_start_time;
|
||||||
int64_t file_inpoint;
|
int64_t file_inpoint;
|
||||||
int64_t duration;
|
int64_t duration;
|
||||||
|
int64_t next_dts;
|
||||||
ConcatStream *streams;
|
ConcatStream *streams;
|
||||||
int64_t inpoint;
|
int64_t inpoint;
|
||||||
int64_t outpoint;
|
int64_t outpoint;
|
||||||
@@ -149,6 +150,7 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
|
|||||||
file->url = url;
|
file->url = url;
|
||||||
file->start_time = AV_NOPTS_VALUE;
|
file->start_time = AV_NOPTS_VALUE;
|
||||||
file->duration = AV_NOPTS_VALUE;
|
file->duration = AV_NOPTS_VALUE;
|
||||||
|
file->next_dts = AV_NOPTS_VALUE;
|
||||||
file->inpoint = AV_NOPTS_VALUE;
|
file->inpoint = AV_NOPTS_VALUE;
|
||||||
file->outpoint = AV_NOPTS_VALUE;
|
file->outpoint = AV_NOPTS_VALUE;
|
||||||
|
|
||||||
@@ -509,8 +511,14 @@ static int open_next_file(AVFormatContext *avf)
|
|||||||
ConcatContext *cat = avf->priv_data;
|
ConcatContext *cat = avf->priv_data;
|
||||||
unsigned fileno = cat->cur_file - cat->files;
|
unsigned fileno = cat->cur_file - cat->files;
|
||||||
|
|
||||||
if (cat->cur_file->duration == AV_NOPTS_VALUE)
|
if (cat->cur_file->duration == AV_NOPTS_VALUE) {
|
||||||
cat->cur_file->duration = cat->avf->duration - (cat->cur_file->file_inpoint - cat->cur_file->file_start_time);
|
if (cat->avf->duration > 0 || cat->cur_file->next_dts == AV_NOPTS_VALUE) {
|
||||||
|
cat->cur_file->duration = cat->avf->duration;
|
||||||
|
} else {
|
||||||
|
cat->cur_file->duration = cat->cur_file->next_dts;
|
||||||
|
}
|
||||||
|
cat->cur_file->duration -= (cat->cur_file->file_inpoint - cat->cur_file->file_start_time);
|
||||||
|
}
|
||||||
|
|
||||||
if (++fileno >= cat->nb_files) {
|
if (++fileno >= cat->nb_files) {
|
||||||
cat->eof = 1;
|
cat->eof = 1;
|
||||||
@@ -627,6 +635,14 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
|
|||||||
memcpy(metadata, packed_metadata, metadata_len);
|
memcpy(metadata, packed_metadata, metadata_len);
|
||||||
av_freep(&packed_metadata);
|
av_freep(&packed_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cat->cur_file->duration == AV_NOPTS_VALUE && st->cur_dts != AV_NOPTS_VALUE) {
|
||||||
|
int64_t next_dts = av_rescale_q(st->cur_dts, st->time_base, AV_TIME_BASE_Q);
|
||||||
|
if (cat->cur_file->next_dts == AV_NOPTS_VALUE || next_dts > cat->cur_file->next_dts) {
|
||||||
|
cat->cur_file->next_dts = next_dts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user