summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-10-23 18:11:26 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-10-23 18:11:26 +0200
commit5442c6cce33d6c4e4f691d55adb0f0f668d9773d (patch)
treef8ff1a17dc57a37f58ef6ad5795473cb80462910
parent31cdf6002ae56094b2ed11851f2d877acd6cf44f (diff)
lavf: fix duration estimation for multi program TS
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/avformat.h10
-rw-r--r--libavformat/utils.c23
2 files changed, 31 insertions, 2 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index ba2977144b..f993dbcff9 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -862,6 +862,16 @@ typedef struct AVProgram {
int program_num;
int pmt_pid;
int pcr_pid;
+
+ /*****************************************************************
+ * All fields below this line are not part of the public API. They
+ * may not be used outside of libavformat and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+ int64_t start_time;
+ int64_t end_time;
} AVProgram;
#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 7a734d4b1b..cd4161ff82 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2045,6 +2045,7 @@ static void update_stream_timings(AVFormatContext *ic)
int64_t duration, duration1, filesize;
int i;
AVStream *st;
+ AVProgram *p;
start_time = INT64_MAX;
start_time_text = INT64_MAX;
@@ -2059,11 +2060,18 @@ static void update_stream_timings(AVFormatContext *ic)
start_time_text = start_time1;
} else
start_time = FFMIN(start_time, start_time1);
+ end_time1 = AV_NOPTS_VALUE;
if (st->duration != AV_NOPTS_VALUE) {
end_time1 = start_time1
+ av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
end_time = FFMAX(end_time, end_time1);
}
+ for(p = NULL; (p = av_find_program_from_stream(ic, p, i)); ){
+ if(p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1)
+ p->start_time = start_time1;
+ if(p->end_time < end_time1)
+ p->end_time = end_time1;
+ }
}
if (st->duration != AV_NOPTS_VALUE) {
duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
@@ -2077,8 +2085,16 @@ static void update_stream_timings(AVFormatContext *ic)
if (start_time != INT64_MAX) {
ic->start_time = start_time;
- if (end_time != INT64_MIN)
- duration = FFMAX(duration, end_time - start_time);
+ if (end_time != INT64_MIN) {
+ if (ic->nb_programs) {
+ for (i=0; i<ic->nb_programs; i++) {
+ p = ic->programs[i];
+ if(p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time)
+ duration = FFMAX(duration, p->end_time - p->start_time);
+ }
+ } else
+ duration = FFMAX(duration, end_time - start_time);
+ }
}
if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) {
ic->duration = duration;
@@ -3162,6 +3178,9 @@ AVProgram *av_new_program(AVFormatContext *ac, int id)
}
program->id = id;
+ program->start_time =
+ program->end_time = AV_NOPTS_VALUE;
+
return program;
}