Updating repository fork
This commit is contained in:
+2
-2
@@ -8,11 +8,11 @@ if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
sudo apt-get -y install qt59base qt59multimedia libavformat-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev frei0r-plugins-dev frei0r-plugins fuse
|
||||
sudo apt-get -y install qt59base qt59multimedia qt59svg libavformat-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev frei0r-plugins-dev frei0r-plugins fuse
|
||||
fi
|
||||
|
||||
if [ "$ARCH" == "i386" ]; then
|
||||
sudo apt-get -y install gcc-multilib g++-multilib qt59base:i386 qt59multimedia:i386 libavformat-dev:i386 libavcodec-dev:i386 libavfilter-dev:i386 libavutil-dev:i386 libswscale-dev:i386 libswresample-dev:i386 frei0r-plugins-dev:i386 frei0r-plugins:i386 pkg-config:i386 libgl1-mesa-dev:i386 fuse:i386
|
||||
sudo apt-get -y install gcc-multilib g++-multilib qt59base:i386 qt59multimedia:i386 qt59svg:i386 libavformat-dev:i386 libavcodec-dev:i386 libavfilter-dev:i386 libavutil-dev:i386 libswscale-dev:i386 libswresample-dev:i386 frei0r-plugins-dev:i386 frei0r-plugins:i386 pkg-config:i386 libgl1-mesa-dev:i386 fuse:i386
|
||||
fi
|
||||
source /opt/qt*/bin/qt*-env.sh
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
export VERSION=$(git rev-parse --short HEAD)
|
||||
|
||||
# use linuxdeployqt to set up dependencies
|
||||
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage
|
||||
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -extra-plugins=imageformats/libqsvg.so -appimage
|
||||
|
||||
# 64-bit linuxdeployqt can only generate a 64-bit AppImage
|
||||
# to generate a 32-bit one, we need to download and run 32-bit AppImageTool
|
||||
|
||||
+22
-4
@@ -73,9 +73,22 @@ MainWindow* olive::MainWindow;
|
||||
void MainWindow::setup_layout(bool reset) {
|
||||
// load panels from file
|
||||
if (!reset) {
|
||||
QFile panel_config(get_config_path() + "/layout");
|
||||
QFile panel_config(get_config_dir().filePath("layout"));
|
||||
if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) {
|
||||
restoreState(panel_config.readAll(), 0);
|
||||
|
||||
// default to resetting unless we find the tag in the XML file
|
||||
reset = true;
|
||||
|
||||
// read XML layout file
|
||||
QXmlStreamReader stream(&panel_config);
|
||||
while (!stream.atEnd()) {
|
||||
stream.readNextStartElement();
|
||||
if (stream.name() == "panels") {
|
||||
restoreState(QByteArray::fromBase64(stream.readElementText().toUtf8()), 0);
|
||||
reset = false;
|
||||
}
|
||||
}
|
||||
|
||||
panel_config.close();
|
||||
} else {
|
||||
reset = true;
|
||||
@@ -888,9 +901,14 @@ void MainWindow::closeEvent(QCloseEvent *e) {
|
||||
olive::CurrentConfig.save(config_fn);
|
||||
|
||||
// save panel layout
|
||||
QFile panel_config(config_path + "/layout");
|
||||
QFile panel_config(get_config_dir().filePath("layout"));
|
||||
if (panel_config.open(QFile::WriteOnly)) {
|
||||
panel_config.write(saveState(0));
|
||||
QXmlStreamWriter stream(&panel_config);
|
||||
stream.writeStartDocument();
|
||||
|
||||
stream.writeTextElement("panels", saveState(0).toBase64());
|
||||
|
||||
stream.writeEndDocument();
|
||||
panel_config.close();
|
||||
} else {
|
||||
qCritical() << "Failed to save layout";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui multimedia opengl
|
||||
QT += core gui multimedia opengl svg
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
|
||||
+3
-1
@@ -126,9 +126,11 @@ Media *Clip::media()
|
||||
|
||||
FootageStream *Clip::media_stream()
|
||||
{
|
||||
if (media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
if (media() != nullptr
|
||||
&& media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
return media()->to_footage()->get_stream_from_file_index(track() < 0, media_stream_index());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -55,7 +55,9 @@ void Footage::reset() {
|
||||
}
|
||||
|
||||
long Footage::get_length_in_frames(double frame_rate) {
|
||||
if (length >= 0) return qFloor(((double) length / (double) AV_TIME_BASE) * frame_rate / speed);
|
||||
if (length >= 0) {
|
||||
return qFloor((double(length) / double(AV_TIME_BASE)) * frame_rate / speed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ SequencePtr Sequence::copy() {
|
||||
s->frame_rate = frame_rate;
|
||||
s->audio_frequency = audio_frequency;
|
||||
s->audio_layout = audio_layout;
|
||||
|
||||
// deep copy all of the sequence's clips
|
||||
s->clips.resize(clips.size());
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
@@ -53,6 +55,10 @@ SequencePtr Sequence::copy() {
|
||||
s->clips[i] = copy;
|
||||
}
|
||||
}
|
||||
|
||||
// copy all of the sequence's markers
|
||||
s->markers = markers;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
+59
-27
@@ -571,13 +571,12 @@ void Cacher::CacheVideoWorker() {
|
||||
do {
|
||||
AVFrame* decoded_frame;
|
||||
|
||||
// qint64 time = QDateTime::currentMSecsSinceEpoch();
|
||||
// retrieve raw RGBA frame from decoder + filter stack
|
||||
int retrieve_code = RetrieveFrameAndProcess(&decoded_frame);
|
||||
//qDebug() << "decode took:" << (QDateTime::currentMSecsSinceEpoch() - time);
|
||||
|
||||
// for some reason we were unable to retrieve a frame, likely a decoder error so we report it
|
||||
// again an EOF, is not really an "error", and we can continue execution if we encounter it
|
||||
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)
|
||||
|
||||
qCritical() << "Failed to retrieve frame from buffersink." << retrieve_code;
|
||||
|
||||
@@ -668,7 +667,22 @@ void Cacher::CacheVideoWorker() {
|
||||
|
||||
qWarning() << clip->name() << "frame had no PTS value";
|
||||
av_frame_free(&decoded_frame);
|
||||
SetRetrievedFrame(nullptr);
|
||||
|
||||
if (retrieve_code == AVERROR_EOF && retrieved_frame == nullptr) {
|
||||
// if we reached the end of the file, it's not an error but there are no more frames to retrieve
|
||||
// some formats EOF before the end of the duration that Olive calculates. In this event, we simply
|
||||
// return the last frame we retrieved
|
||||
//
|
||||
// TODO: Check duration formula
|
||||
|
||||
SetRetrievedFrame(queue.last());
|
||||
|
||||
} else {
|
||||
|
||||
SetRetrievedFrame(nullptr);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -735,7 +749,10 @@ void Cacher::WakeMainThread()
|
||||
main_thread_lock_.unlock();
|
||||
}
|
||||
|
||||
Cacher::Cacher(Clip* c) : clip(c) {}
|
||||
Cacher::Cacher(Clip* c) : clip(c) {
|
||||
frame_ = nullptr;
|
||||
pkt = nullptr;
|
||||
}
|
||||
|
||||
void Cacher::OpenWorker() {
|
||||
qint64 time_start = QDateTime::currentMSecsSinceEpoch();
|
||||
@@ -988,9 +1005,15 @@ void Cacher::CloseWorker() {
|
||||
queue.clear();
|
||||
queue.unlock();
|
||||
|
||||
av_frame_free(&frame_);
|
||||
if (frame_ != nullptr) {
|
||||
av_frame_free(&frame_);
|
||||
frame_ = nullptr;
|
||||
}
|
||||
|
||||
av_packet_free(&pkt);
|
||||
if (pkt != nullptr) {
|
||||
av_packet_free(&pkt);
|
||||
pkt = nullptr;
|
||||
}
|
||||
|
||||
if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
avfilter_graph_free(&filter_graph);
|
||||
@@ -1050,7 +1073,9 @@ void Cacher::Open()
|
||||
|
||||
void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int playback_speed)
|
||||
{
|
||||
if (clip->media_stream()->infinite_length && queue.size() > 0) {
|
||||
if (clip->media_stream() != nullptr
|
||||
&& queue.size() > 0
|
||||
&& clip->media_stream()->infinite_length) {
|
||||
retrieved_frame = queue.at(0);
|
||||
return;
|
||||
}
|
||||
@@ -1063,26 +1088,33 @@ void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int pla
|
||||
|
||||
bool wait_for_cacher_to_respond = true;
|
||||
|
||||
// see if we already have this frame
|
||||
retrieve_lock_.lock();
|
||||
queue.lock();
|
||||
retrieved_frame = nullptr;
|
||||
int64_t target_pts = seconds_to_timestamp(clip, playhead_to_clip_seconds(clip, playhead_));
|
||||
for (int i=0;i<queue.size();i++) {
|
||||
if (queue.at(i)->pts == target_pts) {
|
||||
retrieved_frame = queue.at(i);
|
||||
// qDebug() << "================> found frame at" << i;
|
||||
wait_for_cacher_to_respond = false;
|
||||
break;
|
||||
} else if (i > 0 && queue.at(i-1)->pts < target_pts && queue.at(i)->pts > target_pts) {
|
||||
retrieved_frame = queue.at(i-1);
|
||||
// qDebug() << "================> found frame at" << i-1;
|
||||
wait_for_cacher_to_respond = false;
|
||||
break;
|
||||
if (clip->media() != nullptr) {
|
||||
// see if we already have this frame
|
||||
retrieve_lock_.lock();
|
||||
queue.lock();
|
||||
retrieved_frame = nullptr;
|
||||
int64_t target_pts = seconds_to_timestamp(clip, playhead_to_clip_seconds(clip, playhead_));
|
||||
for (int i=0;i<queue.size();i++) {
|
||||
|
||||
if (queue.at(i)->pts == target_pts) {
|
||||
|
||||
// the queue has a frame with the exact timestamp
|
||||
|
||||
retrieved_frame = queue.at(i);
|
||||
wait_for_cacher_to_respond = false;
|
||||
break;
|
||||
} else if (i > 0 && queue.at(i-1)->pts < target_pts && queue.at(i)->pts > target_pts) {
|
||||
|
||||
// the queue has a frame with a close timestamp that we'll assume is different due to a rounding error
|
||||
|
||||
retrieved_frame = queue.at(i-1);
|
||||
wait_for_cacher_to_respond = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
queue.unlock();
|
||||
retrieve_lock_.unlock();
|
||||
}
|
||||
queue.unlock();
|
||||
retrieve_lock_.unlock();
|
||||
|
||||
if (wait_for_cacher_to_respond) {
|
||||
main_thread_lock_.lock();
|
||||
|
||||
Reference in New Issue
Block a user