aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/nutdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-06-30 17:19:43 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-06-30 17:22:37 +0200
commit3233ad4b446396766065978c0933155dee8fbff4 (patch)
tree651282f131544843bb44f9e91125bdd4546ea7dd /libavformat/nutdec.c
parente2c95e6bd8e89b4f8b4105ef521f8ac03a23ce8f (diff)
downloadffmpeg-3233ad4b446396766065978c0933155dee8fbff4.tar.gz
nutdec: estimate duration from last syncpoint
Previously nut used the fallback of estimation by bitrate. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/nutdec.c')
-rw-r--r--libavformat/nutdec.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 97f0b92d59..88eb3b89ff 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -31,6 +31,9 @@
#define NUT_MAX_STREAMS 256 /* arbitrary sanity check value */
+static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
+ int64_t *pos_arg, int64_t pos_limit);
+
static int get_str(AVIOContext *bc, char *string, unsigned int maxlen)
{
unsigned int len = ffio_read_varlen(bc);
@@ -551,6 +554,23 @@ static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
return 0;
}
+//FIXME calculate exactly, this is just a good approximation.
+static int64_t find_duration(NUTContext *nut, int64_t filesize)
+{
+ AVFormatContext *s = nut->avf;
+ int64_t duration = 0;
+
+ int64_t pos = FFMAX(0, filesize - 2*nut->max_distance);
+ for(;;){
+ int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX);
+ if(ts < 0)
+ break;
+ duration = FFMAX(duration, ts);
+ pos++;
+ }
+ return duration;
+}
+
static int find_and_decode_index(NUTContext *nut)
{
AVFormatContext *s = nut->avf;
@@ -569,6 +589,9 @@ static int find_and_decode_index(NUTContext *nut)
avio_seek(bc, filesize - avio_rb64(bc), SEEK_SET);
if (avio_rb64(bc) != INDEX_STARTCODE) {
av_log(s, AV_LOG_ERROR, "no index at the end\n");
+
+ if(s->duration<=0)
+ s->duration = find_duration(nut, filesize);
return -1;
}