diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-10-23 20:11:26 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-10-23 20:11:26 +0400 |
commit | 5442c6cce33d6c4e4f691d55adb0f0f668d9773d (patch) | |
tree | f8ff1a17dc57a37f58ef6ad5795473cb80462910 /libavformat | |
parent | 31cdf6002ae56094b2ed11851f2d877acd6cf44f (diff) |
lavf: fix duration estimation for multi program TS
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/avformat.h | 10 | ||||
-rw-r--r-- | libavformat/utils.c | 23 |
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; } |