Merge remote-tracking branch 'upstream/master' into pull_requests
# Conflicts: # io/previewgenerator.cpp
This commit is contained in:
+4
-4
@@ -5,15 +5,15 @@ extern "C" {
|
||||
}
|
||||
|
||||
enum QOpenGLTexture::PixelFormat get_gl_pix_fmt_from_av(int format) {
|
||||
switch (format) {
|
||||
/*switch (format) {
|
||||
case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB;
|
||||
}
|
||||
}*/
|
||||
return QOpenGLTexture::RGBA;
|
||||
}
|
||||
|
||||
enum QOpenGLTexture::TextureFormat get_gl_tex_fmt_from_av(int format) {
|
||||
switch (format) {
|
||||
/*switch (format) {
|
||||
case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB8_UNorm;
|
||||
}
|
||||
}*/
|
||||
return QOpenGLTexture::RGBA8_UNorm;
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#define SAVE_VERSION 190104 // YYMMDD
|
||||
#define SAVE_VERSION 190120 // YYMMDD
|
||||
#define MIN_SAVE_VERSION 190104 // lowest compatible project version
|
||||
|
||||
#define TIMECODE_DROP 0
|
||||
@@ -63,7 +63,7 @@ struct Config {
|
||||
bool seek_also_selects;
|
||||
QString css_path;
|
||||
int effect_textbox_lines;
|
||||
bool use_software_fallback;
|
||||
bool use_software_fallback;
|
||||
|
||||
void load(QString path);
|
||||
void save(QString path);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "crossplatformlib.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ModulePtr LibLoad(const QString &filename) {
|
||||
#ifdef _WIN32
|
||||
LPCWSTR dll_fn_w = reinterpret_cast<const wchar_t*>(filename.utf16());
|
||||
return LoadLibrary(dll_fn_w);
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
return dlopen(filename.toUtf8(), RTLD_LAZY);
|
||||
#else
|
||||
qWarning() << "Olive doesn't know how to open dynamic libraries on this platform, external libraries will not be functional";
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList LibFilter() {
|
||||
#ifdef _WIN32
|
||||
return QStringList("*.dll");
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
return {"*.so", "*.dylib"};
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef CROSSPLATFORMLIB_H
|
||||
#define CROSSPLATFORMLIB_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#define LibAddress GetProcAddress
|
||||
#define LibClose FreeModule
|
||||
#define ModulePtr HMODULE
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
#define LibAddress dlsym
|
||||
#define LibClose dlclose
|
||||
#define ModulePtr void*
|
||||
#endif
|
||||
|
||||
ModulePtr LibLoad(const QString& filename);
|
||||
QStringList LibFilter();
|
||||
|
||||
#endif // CROSSPLATFORMLIB_H
|
||||
@@ -489,5 +489,7 @@ void ExportThread::run() {
|
||||
}
|
||||
|
||||
void ExportThread::wake() {
|
||||
mutex.lock();
|
||||
waitCond.wakeAll();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
+46
-18
@@ -18,7 +18,6 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
struct TransitionData {
|
||||
@@ -35,11 +34,21 @@ LoadThread::LoadThread(LoadDialog* l, bool a) : ld(l), autorecovery(a), cancelle
|
||||
connect(this, SIGNAL(error()), this, SLOT(error_func()));
|
||||
connect(this, SIGNAL(start_create_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*)), this, SLOT(create_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*)));
|
||||
connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)));
|
||||
connect(this, SIGNAL(start_question(const QString&, const QString &, int)), this, SLOT(question_func(const QString &, const QString &, int)));
|
||||
}
|
||||
|
||||
const EffectMeta* get_meta_from_name(const QString& name) {
|
||||
const EffectMeta* get_meta_from_name(const QString& input) {
|
||||
int split_index = input.indexOf('/');
|
||||
QString category;
|
||||
if (split_index > -1) {
|
||||
category = input.left(split_index);
|
||||
}
|
||||
QString name = input.mid(split_index + 1);
|
||||
|
||||
for (int j=0;j<effects.size();j++) {
|
||||
if (effects.at(j).name == name) {
|
||||
if (effects.at(j).name == name
|
||||
&& (effects.at(j).category == category
|
||||
|| category.isEmpty())) {
|
||||
return &effects.at(j);
|
||||
}
|
||||
}
|
||||
@@ -152,13 +161,14 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
if (stream.name() == root_search) {
|
||||
if (type == LOAD_TYPE_VERSION) {
|
||||
int proj_version = stream.readElementText().toInt();
|
||||
if (proj_version < MIN_SAVE_VERSION && proj_version > SAVE_VERSION) {
|
||||
if (QMessageBox::warning(
|
||||
mainWindow,
|
||||
tr("Version Mismatch"),
|
||||
tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"),
|
||||
QMessageBox::Yes,
|
||||
QMessageBox::No) == QMessageBox::No) {
|
||||
if (proj_version < MIN_SAVE_VERSION || proj_version > SAVE_VERSION) {
|
||||
emit start_question(
|
||||
tr("Version Mismatch"),
|
||||
tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"),
|
||||
QMessageBox::Yes | QMessageBox::No
|
||||
);
|
||||
waitCond.wait(&mutex);
|
||||
if (question_btn == QMessageBox::No) {
|
||||
show_err = false;
|
||||
return false;
|
||||
}
|
||||
@@ -444,11 +454,14 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
if (!found) {
|
||||
correct_clip->linked.removeAt(j);
|
||||
j--;
|
||||
if (QMessageBox::warning(mainWindow,
|
||||
tr("Invalid Clip Link"),
|
||||
tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"),
|
||||
QMessageBox::Yes,
|
||||
QMessageBox::No) == QMessageBox::No) {
|
||||
|
||||
emit start_question(
|
||||
tr("Invalid Clip Link"),
|
||||
tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"),
|
||||
QMessageBox::Yes | QMessageBox::No
|
||||
);
|
||||
waitCond.wait(&mutex);
|
||||
if (question_btn == QMessageBox::No) {
|
||||
delete s;
|
||||
return false;
|
||||
}
|
||||
@@ -565,10 +578,14 @@ void LoadThread::run() {
|
||||
cont = !cancelled;
|
||||
|
||||
// find project file version
|
||||
cont = load_worker(file, stream, LOAD_TYPE_VERSION);
|
||||
if (cont) {
|
||||
cont = load_worker(file, stream, LOAD_TYPE_VERSION);
|
||||
}
|
||||
|
||||
// find project's internal URL
|
||||
cont = load_worker(file, stream, LOAD_TYPE_URL);
|
||||
if (cont) {
|
||||
cont = load_worker(file, stream, LOAD_TYPE_URL);
|
||||
}
|
||||
|
||||
// load folders first
|
||||
if (cont) {
|
||||
@@ -605,7 +622,6 @@ void LoadThread::run() {
|
||||
xml_error = true;
|
||||
emit error();
|
||||
cont = false;
|
||||
|
||||
} else {
|
||||
// attach nested sequence clips to their sequences
|
||||
for (int i=0;i<loaded_clips.size();i++) {
|
||||
@@ -626,6 +642,9 @@ void LoadThread::run() {
|
||||
for (int i=0;i<loaded_media_items.size();i++) {
|
||||
panel_project->start_preview_generator(loaded_media_items.at(i), true);
|
||||
}
|
||||
} else {
|
||||
error_str = tr("User aborted loading");
|
||||
emit error();
|
||||
}
|
||||
|
||||
file.close();
|
||||
@@ -638,6 +657,15 @@ void LoadThread::cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
void LoadThread::question_func(const QString &title, const QString &text, int buttons) {
|
||||
question_btn = QMessageBox::warning(
|
||||
mainWindow,
|
||||
title,
|
||||
text,
|
||||
static_cast<enum QMessageBox::StandardButton>(buttons));
|
||||
waitCond.wakeAll();
|
||||
}
|
||||
|
||||
void LoadThread::error_func() {
|
||||
if (xml_error) {
|
||||
qCritical() << "Error parsing XML." << error_str;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <QXmlStreamReader>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QMessageBox>
|
||||
|
||||
class Media;
|
||||
struct Footage;
|
||||
@@ -23,12 +24,14 @@ public:
|
||||
void run();
|
||||
void cancel();
|
||||
signals:
|
||||
void start_question(const QString &title, const QString &text, int buttons);
|
||||
void success();
|
||||
void error();
|
||||
void start_create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled);
|
||||
void start_create_dual_transition(const TransitionData* td, Clip* primary, Clip* secondary, const EffectMeta* meta);
|
||||
void report_progress(int p);
|
||||
private slots:
|
||||
void question_func(const QString &title, const QString &text, int buttons);
|
||||
void error_func();
|
||||
void success_func();
|
||||
void create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled);
|
||||
@@ -67,6 +70,8 @@ private:
|
||||
|
||||
bool cancelled;
|
||||
bool xml_error;
|
||||
|
||||
QMessageBox::StandardButton question_btn;
|
||||
};
|
||||
|
||||
#endif // LOADTHREAD_H
|
||||
|
||||
@@ -32,3 +32,12 @@ QString get_config_path() {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QString> get_effects_paths() {
|
||||
QList<QString> effects_paths;
|
||||
effects_paths.append(get_app_dir() + "/effects");
|
||||
effects_paths.append(get_app_dir() + "/../share/olive-editor/effects");
|
||||
QString env_path(qgetenv("OLIVE_EFFECTS_PATH"));
|
||||
if (!env_path.isEmpty()) effects_paths.append(env_path);
|
||||
return effects_paths;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
QString get_app_dir();
|
||||
QString get_data_path();
|
||||
QString get_config_path();
|
||||
QList<QString> get_effects_paths();
|
||||
|
||||
#endif // PATH_H
|
||||
|
||||
@@ -217,6 +217,10 @@ void PreviewGenerator::finalize_media() {
|
||||
}
|
||||
}
|
||||
|
||||
void thumb_data_cleanup(void *info) {
|
||||
delete [] static_cast<uint8_t*>(info);
|
||||
}
|
||||
|
||||
void PreviewGenerator::generate_waveform() {
|
||||
SwsContext* sws_ctx;
|
||||
SwrContext* swr_ctx;
|
||||
@@ -277,7 +281,7 @@ void PreviewGenerator::generate_waveform() {
|
||||
if (!s->preview_done) {
|
||||
int dstH = 120;
|
||||
int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height);
|
||||
uint8_t* imgData = new uint8_t[dstW*dstH*4];
|
||||
uint8_t* data = new uint8_t[dstW*dstH*4];
|
||||
|
||||
sws_ctx = sws_getContext(
|
||||
temp_frame->width,
|
||||
@@ -294,9 +298,9 @@ void PreviewGenerator::generate_waveform() {
|
||||
|
||||
int linesize[AV_NUM_DATA_POINTERS];
|
||||
linesize[0] = dstW*4;
|
||||
sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &imgData, linesize);
|
||||
sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize);
|
||||
|
||||
s->video_preview = QImage(imgData, dstW, dstH, linesize[0], QImage::Format_RGBA8888);
|
||||
s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888, thumb_data_cleanup);
|
||||
s->make_square_thumb();
|
||||
|
||||
// is video interlaced?
|
||||
@@ -311,8 +315,6 @@ void PreviewGenerator::generate_waveform() {
|
||||
avcodec_close(codec_ctx[packet->stream_index]);
|
||||
codec_ctx[packet->stream_index] = nullptr;
|
||||
}
|
||||
|
||||
delete[] imgData;
|
||||
}
|
||||
media_lengths[packet->stream_index]++;
|
||||
} else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
@@ -403,6 +405,7 @@ void PreviewGenerator::generate_waveform() {
|
||||
for (unsigned int i=0;i<fmt_ctx->nb_streams;i++) {
|
||||
if (codec_ctx[i] != nullptr) {
|
||||
avcodec_close(codec_ctx[i]);
|
||||
avcodec_free_context(&codec_ctx[i]);
|
||||
}
|
||||
}
|
||||
if (retrieve_duration) {
|
||||
@@ -417,10 +420,7 @@ void PreviewGenerator::generate_waveform() {
|
||||
finalize_media();
|
||||
}
|
||||
delete [] media_lengths;
|
||||
|
||||
if (codec_ctx != NULL) {
|
||||
avcodec_free_context(codec_ctx);
|
||||
}
|
||||
delete [] codec_ctx;
|
||||
}
|
||||
|
||||
QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) {
|
||||
|
||||
Reference in New Issue
Block a user