removed windows commands from travis and addressed #602

This commit is contained in:
itsmattkc
2019-03-09 06:32:29 +11:00
parent 130c03ce75
commit 2f86888a8d
5 changed files with 63 additions and 46 deletions
+59 -9
View File
@@ -509,14 +509,43 @@ void Cacher::CacheVideoWorker() {
}
}
// If we have to seek ahead, we may want to re-use the frame we retrieved later in the pipeline.
AVFrame* decoded_frame;
bool have_existing_frame_to_use = false;
bool seeked_to_zero = false;
// check if the frame is within this queue or if we'll have to seek elsewhere to get it
// (we check for one second of time after latest_pts, because if it's within that range it'll likely be faster to
// play up to that frame than seek to it)
if (target_pts < earliest_pts || target_pts > latest_pts + second_pts || queue_.size() == 0) {
// we need to seek to retrieve this frame
avcodec_flush_buffers(codecCtx);
av_seek_frame(formatCtx, clip->media_stream_index(), target_pts, AVSEEK_FLAG_BACKWARD);
int retrieve_code;
int64_t seek_ts = target_pts;
// Some formats don't seek reliably to the last keyframe, as a result we need to seek in a loop to ensure we
// get a frame prior to the timestamp
do {
// if we already allocated a frame here, we'd better free it
if (have_existing_frame_to_use) {
av_frame_free(&decoded_frame);
}
// If we already seeked to a timestamp of zero, there's no further we can go, so we have to exit the loop if so
seeked_to_zero = (seek_ts == 0);
avcodec_flush_buffers(codecCtx);
av_seek_frame(formatCtx, clip->media_stream_index(), seek_ts, AVSEEK_FLAG_BACKWARD);
retrieve_code = RetrieveFrameAndProcess(&decoded_frame);
//qDebug() << "Target:" << target_pts << "Seek:" << seek_ts << "Frame:" << decoded_frame->pts;
seek_ts = qMax(0LL, seek_ts - second_pts);
have_existing_frame_to_use = true;
} while (retrieve_code >= 0 && decoded_frame->pts > target_pts && !seeked_to_zero);
// also we assume none of the frames in the queue are usable
queue_.lock();
@@ -571,12 +600,19 @@ void Cacher::CacheVideoWorker() {
interrupt_ = false;
do {
AVFrame* decoded_frame;
// retrieve raw RGBA frame from decoder + filter stack
int retrieve_code = RetrieveFrameAndProcess(&decoded_frame);
int retrieve_code = 0;
// if we retrieved a perfectly good frame earlier by checking the seek, use that here
if (!have_existing_frame_to_use) {
retrieve_code = RetrieveFrameAndProcess(&decoded_frame);
} else {
have_existing_frame_to_use = false;
}
if (retrieve_code < 0 && retrieve_code != AVERROR_EOF) {
// for some reason we were unable to retrieve a frame, likely a decoder error so we report it
// again, an EOF isn't an "error" but will how we add frames (see below)
@@ -596,6 +632,12 @@ void Cacher::CacheVideoWorker() {
if (retrieved_frame == nullptr) {
if (decoded_frame->pts == target_pts) {
SetRetrievedFrame(decoded_frame);
} else if (seeked_to_zero) {
// If this flag is set, it means this was somehow the earliest frame we could get for this timestamp
SetRetrievedFrame(decoded_frame);
seeked_to_zero = false;
} else if (decoded_frame->pts > target_pts
&& queue_.size() > 0) {
SetRetrievedFrame(queue_.last());
@@ -693,6 +735,12 @@ void Cacher::CacheVideoWorker() {
}
}
// For some reason we couldn't get the frame, we should wake up the RenderThread anyway
if (retrieved_frame == nullptr) {
qCritical() << "Couldn't retrieve an appropriate frame. This is an error and may mean this media is corrupt.";
SetRetrievedFrame(nullptr);
}
}
void Cacher::Reset() {
@@ -1128,7 +1176,6 @@ void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int pla
// if not, wait for cacher to respond
if (wait_for_cacher_to_respond) {
// qDebug() << "================> didn't find frame - waiting for cacher to respond..." << clip->name();
interrupt_ = true;
main_thread_wait_.wait(&main_thread_lock_, 2000);
}
@@ -1136,8 +1183,6 @@ void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int pla
if (wait_for_cacher_to_respond) {
main_thread_lock_.unlock();
}
// qDebug() << "Cacher::Cache took" << (QDateTime::currentMSecsSinceEpoch() - time) << "and retrieved" << retrieved_frame;
}
AVFrame *Cacher::Retrieve()
@@ -1146,11 +1191,16 @@ AVFrame *Cacher::Retrieve()
return nullptr;
}
// for thread-safety, we lock a mutex to ensure this thread is never woken by anything out of sync
retrieve_lock_.lock();
// check if there's a frame ready to be shown by the cacher
if (retrieved_frame == nullptr) {
// wait for cacher to finish caching
if (clip->cache_lock.tryLock()) {
// If the queue could lock, the cacher isn't running which means no frame is coming. This is an error.
@@ -1160,14 +1210,14 @@ AVFrame *Cacher::Retrieve()
} else {
// cacher is running, wait for it to give a frame
retrieve_lock_.lock();
retrieve_wait_.wait(&retrieve_lock_);
retrieve_lock_.unlock();
}
}
retrieve_lock_.unlock();
return retrieved_frame;
}