diff nutdec.c @ 1478:5e1b279a26d2 libavformat

nut simple seeking first try
author michael
date Sat, 11 Nov 2006 19:37:21 +0000
parents 56fe078ffc27
children 6a33963be49a
line wrap: on
line diff
--- a/nutdec.c	Sat Nov 11 01:35:50 2006 +0000
+++ b/nutdec.c	Sat Nov 11 19:37:21 2006 +0000
@@ -449,7 +449,7 @@
     int i;
     AVRational time_base;
 
-    nut->last_syncpoint_pos= url_ftell(bc);
+    nut->last_syncpoint_pos= url_ftell(bc)-8;
 
     end= get_packetheader(nut, bc, 1);
     end += url_ftell(bc) - 4;
@@ -465,7 +465,7 @@
     //FIXME put this in a reset func maybe
 
     if(skip_reserved(bc, end) || check_checksum(bc)){
-        av_log(s, AV_LOG_ERROR, "Info header checksum mismatch\n");
+        av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n");
         return -1;
     }
     return 0;
@@ -523,6 +523,8 @@
         decode_info_header(nut);
     }
 
+    s->data_offset= pos-8;
+
     return 0;
 }
 
@@ -534,7 +536,7 @@
     uint64_t tmp;
 
     if(url_ftell(bc) > nut->last_syncpoint_pos + nut->max_distance){
-        av_log(s, AV_LOG_ERROR, "last frame must have been damaged\n");
+        av_log(s, AV_LOG_ERROR, "last frame must have been damaged %Ld > %Ld + %d\n", url_ftell(bc), nut->last_syncpoint_pos, nut->max_distance);
         return -1;
     }
 
@@ -577,6 +579,16 @@
     stc->last_pts= *pts;
     stc->last_key_frame= flags&FLAG_KEY; //FIXME change to last flags
 
+    if(flags&FLAG_KEY){
+        av_add_index_entry(
+            s->streams[*stream_id],
+            nut->last_syncpoint_pos,
+            *pts,
+            0,
+            0,
+            AVINDEX_KEYFRAME);
+    }
+
     return size;
 }
 
@@ -665,6 +677,44 @@
     }
 }
 
+static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){
+    NUTContext *nut = s->priv_data;
+    ByteIOContext *bc = &s->pb;
+    int64_t pos, pts;
+    int frame_code, stream_id,size, flags;
+av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n", stream_index, *pos_arg, pos_limit);
+
+    pos= *pos_arg;
+resync:
+    do{
+        pos= find_startcode(bc, SYNCPOINT_STARTCODE, pos)+1;
+        if(pos < 1){
+            assert(nut->next_startcode == 0);
+            av_log(s, AV_LOG_ERROR, "read_timestamp failed\n");
+            return AV_NOPTS_VALUE;
+        }
+    }while(decode_syncpoint(nut) < 0);
+    *pos_arg = pos-1;
+    assert(nut->last_syncpoint_pos == *pos_arg);
+
+    do{
+        frame_code= get_byte(bc);
+        if(frame_code == 'N') //FIXME update pos
+            goto resync;
+        //FIXME consider pos_limit and eof
+        size= decode_frame_header(nut, &flags, &pts, &stream_id, frame_code);
+
+        if(size < 0)
+            goto resync;
+
+        url_fseek(bc, size, SEEK_CUR);
+    }while(stream_id != stream_index || !(flags & FLAG_KEY));
+    assert(nut->next_startcode == 0);
+    av_log(s, AV_LOG_DEBUG, "read_timestamp success\n");
+
+    return pts;
+}
+
 static int nut_read_close(AVFormatContext *s)
 {
     NUTContext *nut = s->priv_data;
@@ -685,7 +735,7 @@
     nut_read_packet,
     nut_read_close,
     NULL,
-    NULL,
+    nut_read_timestamp,
     .extensions = "nut",
 };
 #endif