summaryrefslogtreecommitdiff
path: root/libavformat/concatdec.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2017-08-28 22:45:20 -0400
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2017-08-31 15:33:52 +0100
commit1a0d9b503d2e9c4278d6e93d40873dff9d191a25 (patch)
tree6761751ecc86a810e447b6e7dccd5f21597a6b1b /libavformat/concatdec.c
parent1291a6d0ff9afb61100f5da46c65360418a4a8ef (diff)
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>
Diffstat (limited to 'libavformat/concatdec.c')
-rw-r--r--libavformat/concatdec.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index e8b37d6a08..0e189012ad 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -44,6 +44,7 @@ typedef struct {
int64_t file_start_time;
int64_t file_inpoint;
int64_t duration;
+ int64_t next_dts;
ConcatStream *streams;
int64_t inpoint;
int64_t outpoint;
@@ -149,6 +150,7 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
file->url = url;
file->start_time = AV_NOPTS_VALUE;
file->duration = AV_NOPTS_VALUE;
+ file->next_dts = AV_NOPTS_VALUE;
file->inpoint = AV_NOPTS_VALUE;
file->outpoint = AV_NOPTS_VALUE;
@@ -509,8 +511,14 @@ static int open_next_file(AVFormatContext *avf)
ConcatContext *cat = avf->priv_data;
unsigned fileno = cat->cur_file - cat->files;
- 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->cur_file->duration == AV_NOPTS_VALUE) {
+ 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) {
cat->eof = 1;
@@ -627,6 +635,14 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
memcpy(metadata, packed_metadata, metadata_len);
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;
}