# HG changeset patch # User michael # Date 1074104327 0 # Node ID 2bed194f8362f71094efbf885425166fa8e5f38c # Parent ca519d041ea1a1b0aa8178b8b23c24deb3b1a163 seeking fixes memleaks infinite loops uninitalized variables with some luck u can seek now a few times before it dies diff -r ca519d041ea1 -r 2bed194f8362 asf.c --- 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; inb_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;