[FFmpeg-devel] [RFC] mpegts: Provide a monotonic timestamp to the outside world

Harald Axmann harald.axmann at hotmail.com
Thu Nov 1 17:53:42 CET 2012


Am 01.11.2012 01:50, schrieb Michael Niedermayer:
> On Thu, Nov 01, 2012 at 01:39:34AM +0100, Harald Axmann wrote:
>> Am 31.10.2012 04:11, schrieb Michael Niedermayer:
>>> On Wed, Oct 31, 2012 at 01:15:26AM +0100, Harald Axmann wrote:
>>>> [...]
>>>> Everything is okay, it was a compiling issue there.
>>>>
>>>> What do you think about it? Should I change something or is it suitable now?
>>> it appears to break "make fate"
>> I executed "make fate", please see attached log file. Could you
>> please point me to the problem? Do I need to specify some samples,
>> as said in the first line?
> yes, and you can fill the samples with make fate-rsync
>
> [...]

Am 01.11.2012 01:59, schrieb Carl Eugen Hoyos:
> [...]
> Use the following to download the samples:
> $ make SAMPLES=fate-suite fate-rsync
>
> And the following to run all tests:
> $ make SAMPLES=fate-suite fate
>
> As long as you are working on the failing test,
> the following is sufficient:
> $ make SAMPLES=fate-suite fate-zmbv-8bit
>
> [...]

Thank you very much. I found the mistake, it was a missing cast, as I 
did not expect such high values for "time_base.den".

I also deactivated the wrapping detection now, if the number of time 
stamp bits is equal to 64.

Now "make fate" worked out for me. Could you please check the updated 
version of the patch? Thanks!
-------------- next part --------------
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3171b21..53a1a9a 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -78,6 +78,22 @@ static int is_relative(int64_t ts) {
     return ts > (RELATIVE_TS_BASE - (1LL<<48));
 }
 
+/**
+ * Wrap a given time stamp, if there is an indication for an overflow
+ *
+ * @param st stream
+ * @param timestamp the time stamp to wrap
+ * @return resulting time stamp
+ */
+static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
+{
+    if (st->pts_wrap_bits != 64 &&
+        st->first_dts != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE &&
+        timestamp < st->first_dts - 60*(int64_t)st->time_base.den)
+        return timestamp + (1LL<<st->pts_wrap_bits);
+    return timestamp;
+}
+
 /** head of registered input format linked list */
 static AVInputFormat *first_iformat = NULL;
 /** head of registered output format linked list */
@@ -739,6 +755,8 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
         }
 
         st= s->streams[pkt->stream_index];
+        pkt->dts = wrap_timestamp(st, pkt->dts);
+        pkt->pts = wrap_timestamp(st, pkt->pts);
 
         force_codec_ids(s, st);
 
@@ -1614,6 +1632,7 @@ int ff_add_index_entry(AVIndexEntry **index_entries,
 int av_add_index_entry(AVStream *st,
                        int64_t pos, int64_t timestamp, int size, int distance, int flags)
 {
+    timestamp = wrap_timestamp(st, timestamp);
     return ff_add_index_entry(&st->index_entries, &st->nb_index_entries,
                               &st->index_entries_allocated_size, pos,
                               timestamp, size, distance, flags);
@@ -1660,6 +1679,12 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
                                      wanted_timestamp, flags);
 }
 
+static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
+                                 int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+    return wrap_timestamp(s->streams[stream_index], read_timestamp(s, stream_index, ppos, pos_limit));
+}
+
 int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
 {
     AVInputFormat *avif= s->iformat;
@@ -1735,7 +1760,7 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
 
     if(ts_min == AV_NOPTS_VALUE){
         pos_min = s->data_offset;
-        ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+        ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
         if (ts_min == AV_NOPTS_VALUE)
             return -1;
     }
@@ -1751,7 +1776,7 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
         pos_max = filesize - 1;
         do{
             pos_max -= step;
-            ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
+            ts_max = ff_read_timestamp(s, stream_index, &pos_max, pos_max + step, read_timestamp);
             step += step;
         }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);
         if (ts_max == AV_NOPTS_VALUE)
@@ -1759,7 +1784,7 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
 
         for(;;){
             int64_t tmp_pos= pos_max + 1;
-            int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
+            int64_t tmp_ts= ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
             if(tmp_ts == AV_NOPTS_VALUE)
                 break;
             ts_max= tmp_ts;
@@ -1806,7 +1831,7 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
             pos= pos_limit;
         start_pos= pos;
 
-        ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
+        ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp); //may pass pos_limit instead of -1
         if(pos == pos_max)
             no_change++;
         else
@@ -1835,9 +1860,9 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
     ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;
 #if 0
     pos_min = pos;
-    ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
     pos_min++;
-    ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_max = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
     av_dlog(s, "pos=0x%"PRIx64" %s<=%s<=%s\n",
             pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max));
 #endif


More information about the ffmpeg-devel mailing list