[FFmpeg-devel] avformat/utils: fix estimate_timings_from_pts duration calculation for mpegts files which contain a PMT update

Submitted by Aman Gupta on April 6, 2017, 10:12 p.m.

Details

Message ID 20170406221235.93361-1-ffmpeg@tmm1.net
State New
Headers show

Commit Message

Aman Gupta April 6, 2017, 10:12 p.m.
From: Aman Gupta <aman@tmm1.net>

For example: https://s3.amazonaws.com/tmm1/pmt-version-change.ts

Before:

    Duration: 00:00:10.01, start: 1236.288878, bitrate: 16752 kb/s

After:

    Duration: 00:00:19.59, start: 1236.288878, bitrate: 8563 kb/s
---
 libavformat/utils.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/libavformat/utils.c b/libavformat/utils.c
index a059046a2c..3028d110aa 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2720,7 +2720,8 @@  static void estimate_timings_from_bit_rate(AVFormatContext *ic)
 static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
 {
     AVPacket pkt1, *pkt = &pkt1;
-    AVStream *st;
+    AVStream *st, *st2;
+    AVProgram *prg;
     int num, den, read_size, i, ret;
     int found_duration = 0;
     int is_end;
@@ -2768,6 +2769,24 @@  static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
             read_size += pkt->size;
             st         = ic->streams[pkt->stream_index];
             if (pkt->pts != AV_NOPTS_VALUE &&
+                (st->start_time == AV_NOPTS_VALUE &&
+                 st->first_dts  == AV_NOPTS_VALUE)) {
+                // try copying start time from another track of the same type
+                // in the same program.
+                prg = av_find_program_from_stream(ic, NULL, pkt->stream_index);
+                for (i = 0; prg && i < prg->nb_stream_indexes; i++) {
+                    st2 = ic->streams[prg->stream_index[i]];
+                    if (st2 != st &&
+                        st2->codecpar->codec_type == st->codecpar->codec_type &&
+                        (st2->start_time != AV_NOPTS_VALUE ||
+                         st2->first_dts != AV_NOPTS_VALUE)) {
+                        st->start_time = st2->start_time;
+                        st->first_dts = st2->first_dts;
+                        break;
+                    }
+                }
+            }
+            if (pkt->pts != AV_NOPTS_VALUE &&
                 (st->start_time != AV_NOPTS_VALUE ||
                  st->first_dts  != AV_NOPTS_VALUE)) {
                 if (pkt->duration == 0) {