mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
fix timestamp rounding in syncpoints
index reading (unfinished and disabled) Originally committed as revision 6979 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6dd2cdf4b0
commit
e827202955
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user