changeset 5647:6f5cdb0fb3c2 libavformat

Use av_compare_ts from libavutil instead of the locale compare_ts, the calculations in the later one are not correct with large time stamps.
author reimar
date Wed, 10 Feb 2010 19:43:57 +0000
parents 7826bf683210
children e73024c5cb80
files seek.c
diffstat 1 files changed, 7 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/seek.c	Wed Feb 10 19:33:08 2010 +0000
+++ b/seek.c	Wed Feb 10 19:43:57 2010 +0000
@@ -48,38 +48,6 @@
 } AVSyncPoint;
 
 /**
- * Compare two timestamps exactly, taking their respective time bases into account.
- *
- * @param ts_a timestamp A
- * @param tb_a time base for timestamp A
- * @param ts_b timestamp B
- * @param tb_b time base for timestamp A
- * @return -1, 0 or 1 if timestamp A is less than, equal or greater than timestamp B
- */
-static int compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
-{
-    int64_t a, b, res;
-
-    if (ts_a == INT64_MIN)
-        return ts_a < ts_b ? -1 : 0;
-    if (ts_a == INT64_MAX)
-        return ts_a > ts_b ?  1 : 0;
-    if (ts_b == INT64_MIN)
-        return ts_a > ts_b ?  1 : 0;
-    if (ts_b == INT64_MAX)
-        return ts_a < ts_b ? -1 : 0;
-
-    a = ts_a * tb_a.num * tb_b.den;
-    b = ts_b * tb_b.num * tb_a.den;
-
-    res = a - b;
-    if (!res)
-        return 0;
-    else
-        return (res >> 63) | 1;
-}
-
-/**
  * Compute a distance between timestamps.
  *
  * Distances are only comparable, if same time bases are used for computing
@@ -216,7 +184,7 @@
             }
 
             if (sp->term_ts != AV_NOPTS_VALUE &&
-                compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) {
+                av_compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) {
                 // past the end position from last iteration, ignore packet
                 if (!sp->terminated) {
                     sp->terminated = 1;
@@ -233,7 +201,7 @@
                 continue;
             }
 
-            if (compare_ts(ts, ts_tb, timestamp, timebase) <= 0) {
+            if (av_compare_ts(ts, ts_tb, timestamp, timebase) <= 0) {
                 // keyframe found before target timestamp
                 if (sp->pos_lo == INT64_MAX) {
                     // found first keyframe lower than target timestamp
@@ -246,7 +214,7 @@
                     sp->pos_lo = pos;
                 }
             }
-            if (compare_ts(ts, ts_tb, timestamp, timebase) >= 0) {
+            if (av_compare_ts(ts, ts_tb, timestamp, timebase) >= 0) {
                 // keyframe found after target timestamp
                 if (sp->pos_hi == INT64_MAX) {
                     // found first keyframe higher than target timestamp
@@ -391,15 +359,15 @@
             min_distance = INT64_MAX;
             // Find timestamp closest to requested timestamp within min/max limits.
             if (sp->pos_lo != INT64_MAX
-                && compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0
-                && compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) {
+                && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0
+                && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) {
                 // low timestamp is in range
                 min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base);
                 min_pos = sp->pos_lo;
             }
             if (sp->pos_hi != INT64_MAX
-                && compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0
-                && compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) {
+                && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0
+                && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) {
                 // high timestamp is in range, check distance
                 distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base);
                 if (distance < min_distance) {