changeset 349:2bed194f8362 libavformat

seeking fixes memleaks infinite loops uninitalized variables with some luck u can seek now a few times before it dies
author michael
date Wed, 14 Jan 2004 18:18:47 +0000
parents ca519d041ea1
children 9a6c7a56405c
files asf.c
diffstat 1 files changed, 56 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/asf.c	Wed Jan 14 14:45:53 2004 +0000
+++ b/asf.c	Wed Jan 14 18:18:47 2004 +0000
@@ -41,6 +41,8 @@
     int ds_chunk_size;
     int ds_data_size;
     int ds_silence_data;
+    
+    int packet_pos;
 
 } ASFStream;
 
@@ -116,6 +118,7 @@
     int packet_obj_size;
     int packet_time_delta;
     int packet_time_start;
+    int packet_pos;
 
     int stream_index;
     ASFStream* asf_st; /* currently decoded stream */
@@ -1117,6 +1120,7 @@
 	    //printf("PacketLeftSize:%d  Pad:%d Pos:%Ld\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb));
 	    /* fail safe */
 	    url_fskip(pb, ret);
+            asf->packet_pos= url_ftell(&s->pb);
 	    ret = asf_get_packet(s);
 	    //printf("READ ASF PACKET  %d   r:%d   c:%d\n", ret, asf->packet_size_left, pc++);
 	    if (ret < 0 || url_feof(pb))
@@ -1135,7 +1139,7 @@
 	    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
 	    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
 	    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
-
+//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size);
 	    if (asf->packet_replic_size > 1) {
                 // it should be always at least 8 bytes - FIXME validate
 		asf->packet_obj_size = get_le32(pb);
@@ -1228,6 +1232,10 @@
 	    asf_st->seq = asf->packet_seq;
 	    asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll;
 	    asf_st->pkt.stream_index = asf->stream_index;
+            asf_st->packet_pos= asf->packet_pos;
+//printf("new packet: stream:%d key:%d packet_key:%d audio:%d\n", 
+//asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,
+//s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO);
 	    if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO) 
 		asf->packet_key_frame = 1;
 	    if (asf->packet_key_frame)
@@ -1304,6 +1312,8 @@
 static void asf_reset_header(AVFormatContext *s)
 {
     ASFContext *asf = s->priv_data;
+    ASFStream *asf_st;
+    int i;
 
     asf->packet_nb_frames = 0;
     asf->packet_timestamp_start = -1;
@@ -1326,30 +1336,41 @@
     asf->packet_obj_size = 0;
     asf->packet_time_delta = 0;
     asf->packet_time_start = 0;
+    
+    for(i=0; i<s->nb_streams; i++){
+        asf_st= s->streams[i]->priv_data;
+        av_free_packet(&asf_st->pkt);
+        asf_st->frag_offset=0;
+        asf_st->seq=0;
+    }
+    asf->asf_st= NULL;
 }
 
 static int64_t asf_read_pts(AVFormatContext *s, int64_t *ppos, int stream_index)
 {
     ASFContext *asf = s->priv_data;
     AVPacket pkt1, *pkt = &pkt1;
+    ASFStream *asf_st;
+    int64_t pts;
     int64_t pos= *ppos;
-    int64_t pts;
 
     // ensure we are on the packet boundry
     assert(pos % asf->packet_size == 0);
-
+//printf("asf_read_pts\n");
     url_fseek(&s->pb, pos + s->data_offset, SEEK_SET);
+    asf_reset_header(s);
     do{
-        pos= url_ftell(&s->pb) - s->data_offset;
-        asf_reset_header(s);
-        if (av_read_frame(s, pkt) < 0)
+        if (av_read_frame(s, pkt) < 0){
+            printf("seek failed\n");
     	    return AV_NOPTS_VALUE;
+        }
         pts= pkt->pts;
 
         av_free_packet(pkt);
-    }while(pkt->stream_index != stream_index);
-    
-    *ppos= pos;
+    }while(pkt->stream_index != stream_index || !(pkt->flags&PKT_FLAG_KEY));
+    asf_st= s->streams[stream_index]->priv_data;
+    *ppos= asf_st->packet_pos - s->data_offset;
+//printf("found keyframe at %Ld stream %d stamp:%Ld\n", *ppos, stream_index, pts);
 
     return pts;
 }
@@ -1361,7 +1382,7 @@
     AVPacket pkt1, *pkt;
     int block_align;
     int64_t pos;
-    int64_t pos_min, pos_max, pts_min, pts_max, cur_pts;
+    int64_t pos_min, pos_max, pts_min, pts_max, cur_pts, pos_limit;
 
     pkt = &pkt1;
 
@@ -1386,48 +1407,42 @@
    
     pos_max = asf_align(s, url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset); //FIXME wrong
     pts_max = pts_min + s->duration;
+    pos_limit= pos_max;
 
-    while (pos_min <= pos_max) {
+    while (pos_min < pos_limit) {
+        int64_t start_pos;
+
+        assert(pos_limit <= pos_max);
 
-        if (pts <= pts_min) {
-            pos = pos_min;
-            goto found;
-        } else if (pts >= pts_max) {
-            pos = pos_max;
-            goto found;
-        } else {
-            // interpolate position (better than dichotomy)
-            pos = (int64_t)((double)(pos_max - pos_min) *
-                            (double)(pts - pts_min) /
-                            (double)(pts_max - pts_min)) + pos_min;
-            pos= asf_align(s, pos);
-        }
+        // interpolate position (better than dichotomy)
+        pos = (int64_t)((double)(pos_limit - pos_min) *
+                        (double)(pts - pts_min) /
+                        (double)(pts_max - pts_min)) + pos_min;
+        pos= asf_align(s, pos);
+        if(pos <= pos_min)
+            pos= pos_min + asf->packet_size;
+        else if(pos > pos_limit)
+            pos= pos_limit;
+        start_pos= pos;
 
         // read the next timestamp 
     	cur_pts = asf_read_pts(s, &pos, stream_index);    
-	
-        /* check if we are lucky */
-        if (pts == cur_pts) {
-            goto found;
-        } else if (cur_pts == AV_NOPTS_VALUE) {
-	    return -1;
+
+        if (cur_pts == AV_NOPTS_VALUE) {
+            return -1;
         } else if (pts < cur_pts) {
+            pos_limit = start_pos - asf->packet_size;
             pos_max = pos;
-	    pts_max = asf_read_pts(s, &pos_max, stream_index); //FIXME wrong, must do backward search, or change this somehow
-            if (pts >= pts_max) {
-                pos = pos_max;
-                goto found;
-            }
+            pts_max = cur_pts;
         } else {
-            pos_min = pos + asf->packet_size;
-	    pts_min = asf_read_pts(s, &pos_min, stream_index);
-            if (pts <= pts_min) {
-                goto found;
-            }
+            pos_min = pos;
+            pts_min = cur_pts;
+            /* check if we are lucky */
+            if (pts == cur_pts)
+                break;
         }
     }
     pos = pos_min;
-found:
     url_fseek(&s->pb, pos + s->data_offset, SEEK_SET);
     asf_reset_header(s);
     return 0;