whoomp, there it is: fix all libav timing issues #159

This commit is contained in:
nick black 2020-01-09 05:17:09 -05:00
parent aa79a86438
commit ebbac42bf6
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

View File

@ -392,6 +392,9 @@ int ncvisual_stream(notcurses* nc, ncvisual* ncv, int* averr,
// we don't have PTS available. // we don't have PTS available.
uint64_t sum_duration = 0; uint64_t sum_duration = 0;
while( (avf = ncvisual_decode(ncv, averr)) ){ while( (avf = ncvisual_decode(ncv, averr)) ){
// codecctx seems to be off by a factor of 2 regularly. instead, go with
// the time_base from the avformatctx.
double tbase = av_q2d(ncv->fmtctx->streams[ncv->stream_index]->time_base);
int64_t ts = avf->best_effort_timestamp; int64_t ts = avf->best_effort_timestamp;
if(frame == 1 && ts){ if(frame == 1 && ts){
usets = true; usets = true;
@ -410,26 +413,23 @@ int ncvisual_stream(notcurses* nc, ncvisual* ncv, int* averr,
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nsnow = timespec_to_ns(&now); uint64_t nsnow = timespec_to_ns(&now);
struct timespec interval; struct timespec interval;
uint64_t duration = avf->pkt_duration * 1000000; uint64_t duration = avf->pkt_duration * tbase * NANOSECS_IN_SEC;
//fprintf(stderr, "use: %u dur: %ju ts: %ju cctx: %f fctx: %f\n", usets, duration, ts, av_q2d(ncv->codecctx->time_base), av_q2d(ncv->fmtctx->streams[ncv->stream_index]->time_base));
sum_duration += duration; sum_duration += duration;
double schedns = nsbegin;
if(usets){ if(usets){
double tbase = av_q2d(ncv->codecctx->time_base);
if(tbase == 0){ if(tbase == 0){
tbase = duration; tbase = duration;
} }
double schedns = ts * tbase * NANOSECS_IN_SEC + nsbegin; schedns += ts * tbase * NANOSECS_IN_SEC;
if(nsnow < schedns){
ns_to_timespec(schedns - nsnow, &interval);
nanosleep(&interval, NULL);
}
}else{ }else{
uint64_t schedns = nsbegin + sum_duration; schedns += sum_duration;
}
if(nsnow < schedns){ if(nsnow < schedns){
ns_to_timespec(schedns - nsnow, &interval); ns_to_timespec(schedns - nsnow, &interval);
nanosleep(&interval, NULL); nanosleep(&interval, NULL);
} }
} }
}
if(*averr == AVERROR_EOF){ if(*averr == AVERROR_EOF){
return 0; return 0;
} }