From 2f86888a8db7e9c4b70af1ff93195c4c0e10a491 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 9 Mar 2019 06:32:29 +1100 Subject: [PATCH] removed windows commands from travis and addressed #602 --- .travis/after_success.sh | 19 +++-------- .travis/before_install.sh | 6 ---- .travis/install.sh | 7 ---- .travis/script.sh | 9 ------ rendering/cacher.cpp | 68 +++++++++++++++++++++++++++++++++------ 5 files changed, 63 insertions(+), 46 deletions(-) diff --git a/.travis/after_success.sh b/.travis/after_success.sh index 83d064822..c067764fa 100644 --- a/.travis/after_success.sh +++ b/.travis/after_success.sh @@ -1,14 +1,5 @@ #!/bin/bash -# retrieve upload tool -wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - -# only create release for master -#if [ "$TRAVIS_BRANCH" != "master" ] -#then -# export TRAVIS_EVENT_TYPE=pull_request -#fi - # Check if there's been a new commit since this build, and if so don't upload it REMOTE=$(curl -s -N https://api.github.com/repos/olive-editor/olive/commits/master | $GREP -Po '(?<=: \")(([a-z0-9])\w+)(?=\")' -m 1) @@ -18,10 +9,13 @@ if [ "$REMOTE" == "$LOCAL" ] then echo "[INFO] This commit is still current. Uploading..." else - echo "[INFO] This commit is no longer current. Aborting upload." + echo "[INFO] This commit is no longer current. $REMOTE vs $LOCAL - aborting upload." exit 0 fi +# retrieve upload tool +wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then # upload final package @@ -33,10 +27,5 @@ elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then # upload final package bash upload.sh Olive*.AppImage* - -elif [[ "$TRAVIS_OS_NAME" == "windows" ]]; then - - # upload final package - bash upload.sh Olive*.zip fi \ No newline at end of file diff --git a/.travis/before_install.sh b/.travis/before_install.sh index d16ea4f65..d363d510c 100644 --- a/.travis/before_install.sh +++ b/.travis/before_install.sh @@ -8,10 +8,4 @@ if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository ppa:jonathonf/ffmpeg-4 -y sudo apt-get update -qq -elif [[ "$TRAVIS_OS_NAME" == "windows" ]]; then - - # install msys2 for mingw package installation - # (chocolatey is seemingly missing a recent version of Qt) - choco install msys2 -y - fi \ No newline at end of file diff --git a/.travis/install.sh b/.travis/install.sh index a6a6432a6..2d63697a6 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -19,12 +19,5 @@ elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then fi source /opt/qt*/bin/qt*-env.sh -elif [[ "$TRAVIS_OS_NAME" == "windows" ]]; then - - #/c/msys64/usr/bin/bash -l -c "pacman -Syu --noconfirm" - - # install build tools - /c/msys64/usr/bin/bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-toolchain mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-qt5" - fi diff --git a/.travis/script.sh b/.travis/script.sh index 5a3773f4b..16d02789d 100644 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -69,13 +69,4 @@ elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./appimagetool-i686.AppImage "appdir" -n -g fi -elif [[ "$TRAVIS_OS_NAME" == "windows" ]]; then - - /c/msys64/mingw64/bin/qmake CONFIG+=release - /c/msys64/mingw64/bin/mingw32-make -f Makefile.Debug - mkdir olive-editor - mv olive-editor.exe olive-editor/ - /c/msys64/mingw64/bin/windeployqt olive-editor/olive-editor.exe - 7z a Olive-$(git rev-parse --short HEAD)-w64p.zip olive-editor - fi diff --git a/rendering/cacher.cpp b/rendering/cacher.cpp index 6adcd3a35..19fb9076a 100644 --- a/rendering/cacher.cpp +++ b/rendering/cacher.cpp @@ -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& 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& 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; }