|
|
@ -377,9 +377,11 @@ int ncvisual_stream(notcurses* nc, ncvisual* ncv, int* averr,
|
|
|
|
struct timespec begin; // time we started
|
|
|
|
struct timespec begin; // time we started
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
|
|
|
uint64_t nsbegin = timespec_to_ns(&begin);
|
|
|
|
uint64_t nsbegin = timespec_to_ns(&begin);
|
|
|
|
struct timespec now;
|
|
|
|
|
|
|
|
bool usets = false;
|
|
|
|
bool usets = false;
|
|
|
|
while(clock_gettime(CLOCK_MONOTONIC, &now), (avf = ncvisual_decode(ncv, averr)) ){
|
|
|
|
// each frame has a pkt_duration in milliseconds. keep the aggregate, in case
|
|
|
|
|
|
|
|
// we don't have PTS available.
|
|
|
|
|
|
|
|
uint64_t sum_duration = 0;
|
|
|
|
|
|
|
|
while( (avf = ncvisual_decode(ncv, averr)) ){
|
|
|
|
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;
|
|
|
@ -395,21 +397,27 @@ int ncvisual_stream(notcurses* nc, ncvisual* ncv, int* averr,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++frame;
|
|
|
|
++frame;
|
|
|
|
|
|
|
|
struct timespec now;
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
|
|
|
|
|
|
uint64_t nsnow = timespec_to_ns(&now);
|
|
|
|
struct timespec interval;
|
|
|
|
struct timespec interval;
|
|
|
|
|
|
|
|
uint64_t duration = avf->pkt_duration * 1000000;
|
|
|
|
|
|
|
|
sum_duration += duration;
|
|
|
|
if(usets){
|
|
|
|
if(usets){
|
|
|
|
double tbase = av_q2d(ncv->codecctx->time_base);
|
|
|
|
double tbase = av_q2d(ncv->codecctx->time_base);
|
|
|
|
if(tbase == 0){
|
|
|
|
if(tbase == 0){
|
|
|
|
tbase = avf->pkt_duration * 1000000;
|
|
|
|
tbase = duration;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
double schedns = ts * tbase * NANOSECS_IN_SEC + nsbegin;
|
|
|
|
double schedns = ts * tbase * NANOSECS_IN_SEC + nsbegin;
|
|
|
|
uint64_t nsnow = timespec_to_ns(&now);
|
|
|
|
|
|
|
|
if(nsnow < schedns){
|
|
|
|
if(nsnow < schedns){
|
|
|
|
ns_to_timespec(schedns - nsnow, &interval);
|
|
|
|
ns_to_timespec(schedns - nsnow, &interval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nanosleep(&interval, NULL);
|
|
|
|
nanosleep(&interval, NULL);
|
|
|
|
}else{
|
|
|
|
}else{
|
|
|
|
uint64_t ns = avf->pkt_duration * 1000000;
|
|
|
|
uint64_t schedns = nsbegin + sum_duration;
|
|
|
|
ns_to_timespec(ns, &interval);
|
|
|
|
if(nsnow < schedns){
|
|
|
|
|
|
|
|
ns_to_timespec(schedns - nsnow, &interval);
|
|
|
|
|
|
|
|
}
|
|
|
|
nanosleep(&interval, NULL);
|
|
|
|
nanosleep(&interval, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|