diff mbox

[FFmpeg-devel] avformat/concatdec: add fallback for calculating file duration

Message ID 20170829024520.5048-1-justin.ruggles@gmail.com
State Accepted
Commit 1a0d9b503d2e9c4278d6e93d40873dff9d191a25
Headers show

Commit Message

Justin Ruggles Aug. 29, 2017, 2:45 a.m. UTC
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.
---
 libavformat/concatdec.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

Comments

Paul B Mahol Aug. 30, 2017, 2:30 p.m. UTC | #1
On 8/29/17, Justin Ruggles <justin.ruggles@gmail.com> wrote:
> 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.
> ---
>  libavformat/concatdec.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
>

LGTM, but I'm not maintainer of that demuxer.
Nicolas George Aug. 30, 2017, 2:51 p.m. UTC | #2
Le primidi 11 fructidor, an CCXXV, Justin Ruggles a écrit :
> 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.
> ---
>  libavformat/concatdec.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)

Looks ok.

I wonder if it would not be better to do that in the common code. I
think I assumed the duration of the file was being updated like that
automatically.

Regards,
diff mbox

Patch

diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index e8b37d6..0e18901 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;
 }