From faf7cbf11083e262c15bd4985fc1d7d63dcf1f97 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 11 Nov 2006 19:37:21 +0000 Subject: nut simple seeking first try Originally committed as revision 6968 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/nutdec.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---- libavformat/utils.c | 2 +- 2 files changed, 55 insertions(+), 5 deletions(-) (limited to 'libavformat') diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 5a3caabe89..13215b78f4 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -449,7 +449,7 @@ static int decode_syncpoint(NUTContext *nut){ 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 @@ static int decode_syncpoint(NUTContext *nut){ //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 @@ static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap) decode_info_header(nut); } + s->data_offset= pos-8; + return 0; } @@ -534,7 +536,7 @@ static int decode_frame_header(NUTContext *nut, int *flags_ret, int64_t *pts, in 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 @@ static int decode_frame_header(NUTContext *nut, int *flags_ret, int64_t *pts, in 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 @@ av_log(s, AV_LOG_DEBUG, "sync\n"); } } +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 @@ AVInputFormat nut_demuxer = { nut_read_packet, nut_read_close, NULL, - NULL, + nut_read_timestamp, .extensions = "nut", }; #endif diff --git a/libavformat/utils.c b/libavformat/utils.c index 78974c7e74..d26a4057ce 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -404,7 +404,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, if (err < 0) goto fail; - if (pb) + if (pb && !ic->data_offset) ic->data_offset = url_ftell(&ic->pb); *ic_ptr = ic; -- cgit v1.2.3