summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2006-11-12 12:07:42 +0000
committerMichael Niedermayer <michaelni@gmx.at>2006-11-12 12:07:42 +0000
commite8272029550aabc72a5b2fbce61c42def6e1ff17 (patch)
tree384ee00a9e39b97996792125482692f6363a18fa /libavformat
parent6dd2cdf4b0769685b77a497c63312827f6e33a83 (diff)
fix timestamp rounding in syncpoints
index reading (unfinished and disabled) Originally committed as revision 6979 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/nutdec.c105
1 files changed, 103 insertions, 2 deletions
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 280ff12740..9625f6705d 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -199,7 +199,7 @@ static int nut_probe(AVProbeData *p){
static int skip_reserved(ByteIOContext *bc, int64_t pos){
pos -= url_ftell(bc);
-
+av_log(NULL, AV_LOG_ERROR, "skip %d\n", (int)pos);
if(pos<0){
url_fseek(bc, pos, SEEK_CUR);
return -1;
@@ -459,7 +459,11 @@ static int decode_syncpoint(NUTContext *nut){
time_base= nut->time_base[tmp % nut->time_base_count];
for(i=0; i<s->nb_streams; i++){
- nut->stream[i].last_pts= av_rescale_q(tmp / nut->time_base_count, time_base, nut->stream[i].time_base); //FIXME rounding and co
+ nut->stream[i].last_pts= av_rescale_rnd(
+ tmp / nut->time_base_count,
+ time_base.num * (int64_t)nut->stream[i].time_base.den,
+ time_base.den * (int64_t)nut->stream[i].time_base.num,
+ AV_ROUND_DOWN);
//last_key_frame ?
}
//FIXME put this in a reset func maybe
@@ -471,6 +475,96 @@ static int decode_syncpoint(NUTContext *nut){
return 0;
}
+static int find_and_decode_index(NUTContext *nut){
+ AVFormatContext *s= nut->avf;
+ ByteIOContext *bc = &s->pb;
+ uint64_t tmp, end;
+ int i, j, syncpoint_count;
+ int64_t filesize= url_fsize(bc);
+ int64_t *syncpoints;
+ int8_t *has_keyframe;
+
+ url_fseek(bc, filesize-12, SEEK_SET);
+ url_fseek(bc, filesize-get_be64(bc), SEEK_SET);
+ if(get_be64(bc) != INDEX_STARTCODE){
+ av_log(s, AV_LOG_ERROR, "no index at the end\n");
+ return -1;
+ }
+
+ end= get_packetheader(nut, bc, 1);
+ end += url_ftell(bc) - 4;
+
+ get_v(bc); //max_pts
+ GET_V(syncpoint_count, tmp < INT_MAX/8 && tmp > 0)
+ syncpoints= av_malloc(sizeof(int64_t)*syncpoint_count);
+ has_keyframe= av_malloc(sizeof(int8_t)*(syncpoint_count+1));
+ for(i=0; i<syncpoint_count; i++){
+ GET_V(syncpoints[i], tmp>0)
+ if(i)
+ syncpoints[i] += syncpoints[i-1];
+ }
+
+ for(i=0; i<s->nb_streams; i++){
+ int64_t last_pts= -1;
+ for(j=0; j<syncpoint_count;){
+ uint64_t x= get_v(bc);
+ int type= x&1;
+ int n= j;
+ x>>=1;
+ if(type){
+ int flag= x&1;
+ x>>=1;
+ if(n+x >= syncpoint_count + 1){
+ av_log(s, AV_LOG_ERROR, "index overflow A\n");
+ return -1;
+ }
+ while(x--)
+ has_keyframe[n++]= flag;
+ has_keyframe[n++]= !flag;
+ }else{
+ while(x != 1){
+ if(n>=syncpoint_count + 1){
+ av_log(s, AV_LOG_ERROR, "index overflow B\n");
+ return -1;
+ }
+ has_keyframe[n++]= x&1;
+ x>>=1;
+ }
+ }
+ if(has_keyframe[0]){
+ av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n");
+ return -1;
+ }
+ assert(n<=syncpoint_count+1);
+ for(; j<n; j++){
+ if(has_keyframe[j]){
+ uint64_t B, A= get_v(bc);
+ if(!A){
+ A= get_v(bc);
+ B= get_v(bc);
+ //eor_pts[j][i] = last_pts + A + B
+ }else
+ B= 0;
+ av_add_index_entry(
+ s->streams[i],
+ 16*syncpoints[j-1],
+ last_pts + A,
+ 0,
+ 0,
+ AVINDEX_KEYFRAME);
+ last_pts += A + B;
+ }
+ }
+ }
+ }
+
+ if(skip_reserved(bc, end) || check_checksum(bc)){
+ av_log(s, AV_LOG_ERROR, "Index checksum mismatch\n");
+ return -1;
+ }
+ return 0;
+}
+
static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
NUTContext *nut = s->priv_data;
@@ -523,6 +617,13 @@ static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
s->data_offset= pos-8;
+ if(0 &&!url_is_streamed(bc)){
+ int64_t orig_pos= url_ftell(bc);
+ find_and_decode_index(nut);
+ url_fseek(bc, orig_pos, SEEK_SET);
+ }
+ assert(nut->next_startcode == SYNCPOINT_STARTCODE);
+
return 0;
}