merged with master
This commit is contained in:
Vendored
+1
-1
@@ -8,6 +8,6 @@ Homepage: https://olivevideoeditor.org/
|
||||
|
||||
Package: olive-editor
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5multimedia5-plugins, frei0r-plugins
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5multimedia5-plugins
|
||||
Description: Nonlinear video editor focused on performance and simplicity
|
||||
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ void debug_message_handler(QtMsgType type, const QMessageLogContext &context, co
|
||||
debug_stream << QString("[%1] %2 (%3:%4, %5)\n")
|
||||
.arg(msgTag, localMsg, context.file, QString::number(context.line), context.function);
|
||||
}
|
||||
debug_info.prepend(QString("<font color='%1'><b>[%2]</b> %3 (%4:%5, %6)</font><br>")
|
||||
debug_info.append(QString("<font color='%1'><b>[%2]</b> %3 (%4:%5, %6)</font><br>")
|
||||
.arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function));
|
||||
fflush(stderr);
|
||||
if (olive::DebugDialog != nullptr && olive::DebugDialog->isVisible()) {
|
||||
|
||||
@@ -79,6 +79,9 @@ QList<QString> get_effects_paths() {
|
||||
// folder in share folder - best for Linux
|
||||
effects_paths.append(app_dir.filePath("../share/olive-editor/effects"));
|
||||
|
||||
// user path - best for linux
|
||||
effects_paths.append(QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("effects"));
|
||||
|
||||
// Olive will also accept a manually provided folder with an environment variable
|
||||
QString env_path(qgetenv("OLIVE_EFFECTS_PATH"));
|
||||
if (!env_path.isEmpty()) effects_paths.append(env_path);
|
||||
|
||||
@@ -35,7 +35,7 @@ system("which git") {
|
||||
GITPATH = $$system(cygpath $$PWD)
|
||||
}
|
||||
|
||||
GITHASHVAR = $$system(git --git-dir="$$GITPATH/.git" --work-tree="$$GITPATH" log -1 --format=%h)
|
||||
GITHASHVAR = $$system(git --git-dir=\"$$GITPATH/.git\" --work-tree=\"$$GITPATH\" log -1 --format=%h)
|
||||
|
||||
# Fallback for Ubuntu/Launchpad (extracts Git hash from debian/changelog rather than Git repo)
|
||||
# (see https://answers.launchpad.net/launchpad/+question/678556)
|
||||
@@ -48,10 +48,6 @@ system("which git") {
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
CONFIG += console
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
ui/mainwindow.cpp \
|
||||
@@ -327,6 +323,10 @@ TRANSLATIONS += \
|
||||
ts/olive_id.ts
|
||||
|
||||
win32 {
|
||||
CONFIG(debug, debug|release) {
|
||||
CONFIG += console
|
||||
}
|
||||
|
||||
RC_FILE = packaging/windows/resources.rc
|
||||
LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lOpenColorIO -lopengl32 -luser32
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ void free_panels() {
|
||||
}
|
||||
|
||||
void scroll_to_frame_internal(QScrollBar* bar, long frame, double zoom, int area_width) {
|
||||
if (bar->value() == bar->minimum() || bar->value() == bar->maximum()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int screen_point = getScreenPointFromFrame(zoom, frame) - bar->value();
|
||||
int min_x = area_width*0.1;
|
||||
int max_x = area_width-min_x;
|
||||
|
||||
+5
-14
@@ -64,7 +64,6 @@ extern "C" {
|
||||
Viewer::Viewer(QWidget *parent) :
|
||||
Panel(parent),
|
||||
playing(false),
|
||||
just_played_(false),
|
||||
media(nullptr),
|
||||
seq(nullptr),
|
||||
created_sequence(false),
|
||||
@@ -292,7 +291,7 @@ void Viewer::play(bool in_to_out) {
|
||||
|
||||
playhead_start = seq->playhead;
|
||||
playing = true;
|
||||
just_played_ = true;
|
||||
SetAudioWakeObject(this);
|
||||
set_playpause_icon(false);
|
||||
start_msecs = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
@@ -301,17 +300,14 @@ void Viewer::play(bool in_to_out) {
|
||||
}
|
||||
|
||||
void Viewer::play_wake() {
|
||||
if (just_played_) {
|
||||
start_msecs = QDateTime::currentMSecsSinceEpoch();
|
||||
playback_updater.start();
|
||||
if (audio_thread != nullptr) audio_thread->notifyReceiver();
|
||||
just_played_ = false;
|
||||
}
|
||||
start_msecs = QDateTime::currentMSecsSinceEpoch();
|
||||
playback_updater.start();
|
||||
if (audio_thread != nullptr) audio_thread->notifyReceiver();
|
||||
}
|
||||
|
||||
void Viewer::pause() {
|
||||
playing = false;
|
||||
just_played_ = false;
|
||||
SetAudioWakeObject(nullptr);
|
||||
set_playpause_icon(true);
|
||||
playback_updater.stop();
|
||||
playback_speed = 0;
|
||||
@@ -352,11 +348,6 @@ void Viewer::pause() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Viewer::WaitingForPlayWake()
|
||||
{
|
||||
return just_played_;
|
||||
}
|
||||
|
||||
void Viewer::update_playhead_timecode(long p) {
|
||||
current_timecode_slider->SetValue(p);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ public:
|
||||
void seek(long p);
|
||||
void play(bool in_to_out = false);
|
||||
void pause();
|
||||
bool WaitingForPlayWake();
|
||||
bool playing;
|
||||
long playhead_start;
|
||||
qint64 start_msecs;
|
||||
@@ -139,7 +138,6 @@ private:
|
||||
double minimum_zoom;
|
||||
bool playing_in_to_out;
|
||||
long last_playhead;
|
||||
bool just_played_;
|
||||
void set_zoom_value(double d);
|
||||
void set_sb_max();
|
||||
void set_playback_speed(int s);
|
||||
|
||||
@@ -400,3 +400,32 @@ void combobox_audio_sample_rates(QComboBox *combobox) {
|
||||
combobox->addItem("88200 Hz", 88200);
|
||||
combobox->addItem("96000 Hz", 96000);
|
||||
}
|
||||
|
||||
QObject* audio_wake_object = nullptr;
|
||||
QMutex audio_wake_mutex;
|
||||
|
||||
QObject* GetAudioWakeObject()
|
||||
{
|
||||
audio_wake_mutex.lock();
|
||||
|
||||
QObject* wake_object = audio_wake_object;
|
||||
audio_wake_object = nullptr;
|
||||
|
||||
audio_wake_mutex.unlock();
|
||||
|
||||
return wake_object;
|
||||
}
|
||||
|
||||
void SetAudioWakeObject(QObject *o)
|
||||
{
|
||||
audio_wake_mutex.lock();
|
||||
audio_wake_object = o;
|
||||
audio_wake_mutex.unlock();
|
||||
}
|
||||
|
||||
void WakeAudioWakeObject() {
|
||||
QObject* audio_wake_object = GetAudioWakeObject();
|
||||
if (audio_wake_object != nullptr) {
|
||||
QMetaObject::invokeMethod(audio_wake_object, "play_wake", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,10 @@ extern bool recording;
|
||||
extern int audio_rendering_rate;
|
||||
void clear_audio_ibuffer();
|
||||
|
||||
QObject *GetAudioWakeObject();
|
||||
void SetAudioWakeObject(QObject* o);
|
||||
void WakeAudioWakeObject();
|
||||
|
||||
int current_audio_freq();
|
||||
|
||||
bool is_audio_device_set();
|
||||
|
||||
@@ -460,8 +460,8 @@ void Cacher::CacheAudioWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(panel_footage_viewer, "play_wake", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection);
|
||||
// If there's a QObject waiting for audio to be rendered, wake it now
|
||||
WakeAudioWakeObject();
|
||||
}
|
||||
|
||||
bool Cacher::IsReversed()
|
||||
|
||||
@@ -59,6 +59,7 @@ ExportThread::ExportThread(const ExportParams ¶ms,
|
||||
audio_stream(nullptr),
|
||||
acodec(nullptr),
|
||||
audio_frame(nullptr),
|
||||
sws_frame(nullptr),
|
||||
swr_frame(nullptr),
|
||||
acodec_ctx(nullptr),
|
||||
swr_ctx(nullptr),
|
||||
@@ -215,6 +216,8 @@ bool ExportThread::SetupVideo() {
|
||||
}
|
||||
|
||||
bool ExportThread::SetupAudio() {
|
||||
// if video is disabled, no setup necessary
|
||||
if (!params_.audio_enabled) return true;
|
||||
|
||||
// Find encoder for this codec
|
||||
acodec = avcodec_find_encoder(static_cast<AVCodecID>(params_.audio_codec));
|
||||
@@ -373,12 +376,12 @@ void ExportThread::Export()
|
||||
}
|
||||
|
||||
// If video is enabled, set it up in the container now
|
||||
if (params_.video_enabled && !SetupVideo()) {
|
||||
if (!SetupVideo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If audio is enabled, set it up in the container now
|
||||
if (params_.audio_enabled && !SetupAudio()) {
|
||||
if (!SetupAudio()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -421,6 +424,8 @@ void ExportThread::Export()
|
||||
|
||||
// If we're exporting audio, run compose_audio() which will write mixed audio to the internal audio buffer
|
||||
if (params_.audio_enabled) {
|
||||
waiting_for_audio_ = true;
|
||||
SetAudioWakeObject(this);
|
||||
olive::rendering::compose_audio(nullptr, olive::ActiveSequence.get(), 1, true);
|
||||
}
|
||||
|
||||
@@ -484,6 +489,13 @@ void ExportThread::Export()
|
||||
// If we're exporting audio, copy audio from the buffer into an AVFrame for encoding
|
||||
if (params_.audio_enabled) {
|
||||
|
||||
if (waiting_for_audio_) {
|
||||
waitCond.wait(&mutex);
|
||||
}
|
||||
|
||||
// Make sure nothing is writing while we're retrieving
|
||||
audio_write_lock.lock();
|
||||
|
||||
// Check if the count of encoded samples exceeds the current Sequence playhead, in which case we don't need to
|
||||
// encode any audio at this moment
|
||||
while (!interrupt_ && file_audio_samples <= (timecode_secs*params_.audio_sampling_rate)) {
|
||||
@@ -518,6 +530,9 @@ void ExportThread::Export()
|
||||
// Increment by the frame's number of samples
|
||||
file_audio_samples += swr_frame->nb_samples;
|
||||
}
|
||||
|
||||
audio_write_lock.unlock();
|
||||
|
||||
}
|
||||
|
||||
// Generating encoding statistics (e.g. the time it took to encode this frame/estimated remaining time)
|
||||
@@ -672,6 +687,14 @@ void ExportThread::Interrupt()
|
||||
interrupt_ = true;
|
||||
}
|
||||
|
||||
void ExportThread::play_wake()
|
||||
{
|
||||
mutex.lock();
|
||||
waiting_for_audio_ = false;
|
||||
waitCond.wakeAll();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void ExportThread::wake() {
|
||||
mutex.lock();
|
||||
waitCond.wakeAll();
|
||||
|
||||
@@ -82,6 +82,8 @@ signals:
|
||||
void ProgressChanged(int value, qint64 remaining_ms);
|
||||
public slots:
|
||||
void Interrupt();
|
||||
|
||||
void play_wake();
|
||||
private:
|
||||
bool Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream);
|
||||
bool SetupVideo();
|
||||
@@ -124,6 +126,8 @@ private:
|
||||
QWaitCondition waitCond;
|
||||
|
||||
QString export_error;
|
||||
|
||||
bool waiting_for_audio_;
|
||||
private slots:
|
||||
void wake();
|
||||
};
|
||||
|
||||
@@ -748,7 +748,6 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
// == END FINAL DRAW ON SEQUENCE BUFFER ==
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
@@ -778,8 +777,8 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_track_count == 0 && params.viewer != nullptr) {
|
||||
params.viewer->play_wake();
|
||||
if (audio_track_count == 0) {
|
||||
WakeAudioWakeObject();
|
||||
}
|
||||
|
||||
if (!params.nests.isEmpty() && !params.nests.last()->fbo.isEmpty()) {
|
||||
|
||||
+1015
-880
File diff suppressed because it is too large
Load Diff
@@ -86,6 +86,7 @@ EffectUI::EffectUI(Effect* e) :
|
||||
SetTitle(effect_name);
|
||||
|
||||
QWidget* ui = new QWidget(this);
|
||||
ui->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
||||
SetContents(ui);
|
||||
|
||||
SetExpanded(e->IsExpanded());
|
||||
|
||||
@@ -39,7 +39,11 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent, bool addLeftPad) : QWidget
|
||||
key_controls->addStretch();
|
||||
}
|
||||
|
||||
QSizePolicy button_size_policy;
|
||||
button_size_policy.setRetainSizeWhenHidden(true);
|
||||
|
||||
left_key_nav = new QPushButton(this);
|
||||
left_key_nav->setSizePolicy(button_size_policy);
|
||||
left_key_nav->setIcon(olive::icon::LeftArrow);
|
||||
left_key_nav->setIconSize(left_key_nav->iconSize()*0.5);
|
||||
left_key_nav->setVisible(false);
|
||||
@@ -48,6 +52,7 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent, bool addLeftPad) : QWidget
|
||||
connect(left_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
|
||||
|
||||
key_addremove = new QPushButton(this);
|
||||
key_addremove->setSizePolicy(button_size_policy);
|
||||
key_addremove->setIcon(olive::icon::Diamond);
|
||||
key_addremove->setIconSize(key_addremove->iconSize()*0.5);
|
||||
key_addremove->setVisible(false);
|
||||
@@ -56,6 +61,7 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent, bool addLeftPad) : QWidget
|
||||
connect(key_addremove, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
|
||||
|
||||
right_key_nav = new QPushButton(this);
|
||||
right_key_nav->setSizePolicy(button_size_policy);
|
||||
right_key_nav->setIcon(olive::icon::RightArrow);
|
||||
right_key_nav->setIconSize(right_key_nav->iconSize()*0.5);
|
||||
right_key_nav->setVisible(false);
|
||||
|
||||
@@ -98,7 +98,7 @@ SourceIconDelegate::SourceIconDelegate(QObject *parent) :
|
||||
{
|
||||
}
|
||||
|
||||
QSize SourceIconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
QSize SourceIconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &) const
|
||||
{
|
||||
if (option.decorationPosition == QStyleOptionViewItem::Top) { // Icon Mode
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ TimelineHeader::TimelineHeader(QWidget *parent) :
|
||||
in_visible(0),
|
||||
fm(font()),
|
||||
dragging_markers(false),
|
||||
scroll(0)
|
||||
scroll(0),
|
||||
height_actual(fm.height())
|
||||
{
|
||||
height_actual = fm.height();
|
||||
setCursor(Qt::ArrowCursor);
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
@@ -467,6 +467,10 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
|
||||
path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff);
|
||||
path.lineTo(start);
|
||||
p.fillPath(path, Qt::red);
|
||||
|
||||
// Draw white line at the top for clarity
|
||||
p.setPen(Qt::gray);
|
||||
p.drawLine(0, 0, width(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -242,7 +242,7 @@ void ViewerWidget::frame_update() {
|
||||
}
|
||||
|
||||
// render the audio
|
||||
olive::rendering::compose_audio(viewer, viewer->seq.get(), viewer->get_playback_speed(), viewer->WaitingForPlayWake());
|
||||
olive::rendering::compose_audio(viewer, viewer->seq.get(), viewer->get_playback_speed(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user