diff --git a/dialogs/exportdialog.ui b/dialogs/exportdialog.ui
index df0d18d2f..9e1a43f4d 100644
--- a/dialogs/exportdialog.ui
+++ b/dialogs/exportdialog.ui
@@ -6,8 +6,8 @@
0
0
- 557
- 659
+ 358
+ 442
@@ -75,13 +75,6 @@
-
- -
-
-
- Width:
-
-
-
-
@@ -89,6 +82,13 @@
+ -
+
+
+ Width:
+
+
+
-
@@ -120,14 +120,14 @@
- -
+
-
Bitrate (Mbps/CBR):
- -
+
-
100.000000000000000
@@ -159,13 +159,6 @@
-
- -
-
-
- Sampling Rate:
-
-
-
-
@@ -176,14 +169,21 @@
- -
+
-
+
+
+ Sampling Rate:
+
+
+
+ -
Bitrate (Kbps/CBR):
- -
+
-
320
diff --git a/effects/crossdissolvetransition.cpp b/effects/crossdissolvetransition.cpp
index 16b0c2640..b112615fe 100644
--- a/effects/crossdissolvetransition.cpp
+++ b/effects/crossdissolvetransition.cpp
@@ -10,23 +10,6 @@ void CrossDissolveTransition::process_transition(double progress) {
glColor4f(1.0, 1.0, 1.0, color[3]*progress);
}
-void CrossDissolveTransition::process_audio(double range_start, double range_end, quint8* samples, int nb_samples, bool reverse) {
- double interval = (range_end - range_start) / nb_samples;
-
- for (int i=0;i> 8);
- samples[i] = (quint8) samp;
- }
-}
-
Transition* CrossDissolveTransition::copy() {
Transition* t = new CrossDissolveTransition();
t->length = length;
diff --git a/effects/effects.cpp b/effects/effects.cpp
index b4f216bc7..af785ab8c 100644
--- a/effects/effects.cpp
+++ b/effects/effects.cpp
@@ -16,6 +16,7 @@ void init_effects() {
video_effect_names[VIDEO_SHAKE_EFFECT] = "Shake";
video_effect_names[VIDEO_TEXT_EFFECT] = "Text";
video_effect_names[VIDEO_SOLID_EFFECT] = "Solid";
+ video_effect_names[VIDEO_INVERT_EFFECT] = "Invert";
audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume";
audio_effect_names[AUDIO_PAN_EFFECT] = "Pan";
@@ -28,6 +29,7 @@ Effect* create_effect(int effect_id, Clip* c) {
case VIDEO_SHAKE_EFFECT: return new ShakeEffect(c); break;
case VIDEO_TEXT_EFFECT: return new TextEffect(c); break;
case VIDEO_SOLID_EFFECT: return new SolidEffect(c); break;
+ case VIDEO_INVERT_EFFECT: return new InvertEffect(c); break;
}
} else {
switch (effect_id) {
diff --git a/effects/effects.h b/effects/effects.h
index 5a887bdad..cbbdf5613 100644
--- a/effects/effects.h
+++ b/effects/effects.h
@@ -21,6 +21,7 @@ enum VideoEffects {
VIDEO_SHAKE_EFFECT,
VIDEO_TEXT_EFFECT,
VIDEO_SOLID_EFFECT,
+ VIDEO_INVERT_EFFECT,
VIDEO_EFFECT_COUNT
};
@@ -130,6 +131,19 @@ private:
QOpenGLTexture* texture;
};
+class InvertEffect : public Effect {
+ Q_OBJECT
+public:
+ InvertEffect(Clip* c);
+ void init();
+ void process_gl(int *anchor_x, int *anchor_y);
+ Effect* copy(Clip *c);
+ void load(QXmlStreamReader* stream);
+ void save(QXmlStreamWriter* stream);
+
+ LabelSlider* amount_val;
+};
+
// audio effects
class VolumeEffect : public Effect {
public:
diff --git a/effects/inverteffect.cpp b/effects/inverteffect.cpp
new file mode 100644
index 000000000..4f399f44f
--- /dev/null
+++ b/effects/inverteffect.cpp
@@ -0,0 +1,51 @@
+#include "effects/effects.h"
+
+#include "ui/labelslider.h"
+
+#include
+#include
+#include
+#include
+#include
+
+InvertEffect::InvertEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_INVERT_EFFECT) {
+ ui_layout->addWidget(new QLabel("Amount:"), 0, 0);
+ amount_val = new LabelSlider();
+ ui_layout->addWidget(amount_val, 0, 1);
+
+ // set defaults
+ amount_val->set_minimum_value(0);
+ amount_val->set_maximum_value(100);
+ init();
+
+ connect(amount_val, SIGNAL(valueChanged()), this, SLOT(field_changed()));
+}
+
+void InvertEffect::init() {
+ amount_val->set_default_value(100);
+}
+
+Effect* InvertEffect::copy(Clip* c) {
+ InvertEffect* i = new InvertEffect(c);
+ i->amount_val->set_value(amount_val->value());
+ return i;
+}
+
+void InvertEffect::load(QXmlStreamReader *stream) {
+ const QXmlStreamAttributes& attr = stream->attributes();
+ for (int i=0;iset_value(a.value().toDouble());
+ }
+ }
+}
+
+void InvertEffect::save(QXmlStreamWriter *stream) {
+ stream->writeAttribute("amount", QString::number(amount_val->value()));
+}
+
+void InvertEffect::process_gl(int* anchor_x, int* anchor_y) {
+
+// gl_FragColor = vec4(1.0 - textureColor.r, 1.0 -textureColor.g, 1.0 -textureColor.b, 1);
+}
diff --git a/effects/linearfadetransition.cpp b/effects/linearfadetransition.cpp
new file mode 100644
index 000000000..6cf1edf7e
--- /dev/null
+++ b/effects/linearfadetransition.cpp
@@ -0,0 +1,26 @@
+#include "transition.h"
+
+LinearFadeTransition::LinearFadeTransition() : Transition(AUDIO_LINEAR_FADE_TRANSITION) {}
+
+void LinearFadeTransition::process_audio(double range_start, double range_end, quint8* samples, int nb_samples, bool reverse) {
+ double interval = (range_end - range_start) / nb_samples;
+
+ for (int i=0;i> 8);
+ samples[i] = (quint8) samp;
+ }
+}
+
+Transition* LinearFadeTransition::copy() {
+ Transition* t = new LinearFadeTransition();
+ t->length = length;
+ return t;
+}
diff --git a/effects/transition.h b/effects/transition.h
index b163cea7e..3f9f7ec80 100644
--- a/effects/transition.h
+++ b/effects/transition.h
@@ -15,11 +15,6 @@ enum AudioTransitions {
AUDIO_TRANSITION_COUNT
};
-void init_transitions();
-
-extern QVector video_transition_names;
-extern QVector audio_transition_names;
-
class Transition
{
public:
@@ -28,20 +23,31 @@ public:
int id;
QString name;
int length;
- Transition* link;
+ Transition* link;
virtual void process_transition(double);
virtual void process_audio(double, double, quint8*, int, bool);
- virtual Transition* copy();
+ virtual Transition* copy();
};
+void init_transitions();
+Transition* create_transition(int transition_id, Clip* c);
+extern QVector video_transition_names;
+extern QVector audio_transition_names;
+
+// Video Transitions
class CrossDissolveTransition : public Transition {
public:
CrossDissolveTransition();
void process_transition(double);
- void process_audio(double, double, quint8*, int, bool);
Transition* copy();
};
-Transition* create_transition(int transition_id, Clip* c);
+// Audio Transitions
+class LinearFadeTransition : public Transition {
+public:
+ LinearFadeTransition();
+ void process_audio(double, double, quint8*, int, bool);
+ Transition* copy();
+};
#endif // TRANSITION_H
diff --git a/mainwindow.cpp b/mainwindow.cpp
index ee2c011e6..b3523e48a 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -79,7 +79,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this);
- setWindowTitle("Olive (August 2018 | Pre-Alpha)");
+ setWindowTitle("Olive (August 2018 | Alpha)");
statusBar()->showMessage("Welcome to Olive");
ui->centralWidget->setMaximumSize(0, 0);
diff --git a/olive.pro b/olive.pro
index 258974f53..9dbd02ddf 100644
--- a/olive.pro
+++ b/olive.pro
@@ -66,7 +66,9 @@ SOURCES += \
ui/comboboxex.cpp \
ui/colorbutton.cpp \
effects/solideffect.cpp \
- dialogs/replaceclipmediadialog.cpp
+ dialogs/replaceclipmediadialog.cpp \
+ effects/inverteffect.cpp \
+ effects/linearfadetransition.cpp
HEADERS += \
mainwindow.h \
diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp
index 98ad273f7..f6f316f15 100644
--- a/panels/effectcontrols.cpp
+++ b/panels/effectcontrols.cpp
@@ -14,6 +14,7 @@
#include "project/sequence.h"
#include "project/undo.h"
#include "panels/project.h"
+#include "panels/timeline.h"
EffectControls::EffectControls(QWidget *parent) :
QDockWidget(parent),
@@ -33,26 +34,51 @@ EffectControls::~EffectControls()
void EffectControls::menu_select(QAction* q) {
TimelineAction* ta = new TimelineAction();
for (int i=0;iget_clip(selected_clips.at(i))->track < 0) == video_menu) {
- ta->add_effect(sequence, selected_clips.at(i), q->data().toInt());
+ Clip* c = sequence->get_clip(selected_clips.at(i));
+ if (c->track < 0 == video_menu) {
+ if (transition_menu) {
+ if (c->opening_transition == NULL) {
+ ta->add_transition(sequence, selected_clips.at(i), q->data().toInt(), TA_OPENING_TRANSITION);
+ }
+ if (c->closing_transition == NULL) {
+ ta->add_transition(sequence, selected_clips.at(i), q->data().toInt(), TA_CLOSING_TRANSITION);
+ }
+ } else {
+ ta->add_effect(sequence, selected_clips.at(i), q->data().toInt());
+ }
}
}
undo_stack.push(ta);
- reload_clips();
+ if (transition_menu) {
+ panel_timeline->redraw_all_clips(true);
+ } else {
+ reload_clips();
+ }
}
-void EffectControls::show_menu(bool video) {
+void EffectControls::show_effect_menu(bool video, bool transitions) {
video_menu = video;
+ transition_menu = transitions;
int lim;
QVector* effect_names;
- if (video) {
- lim = VIDEO_EFFECT_COUNT;
- effect_names = &video_effect_names;
- } else {
- lim = AUDIO_EFFECT_COUNT;
- effect_names = &audio_effect_names;
- }
+ if (transitions) {
+ if (video) {
+ lim = VIDEO_TRANSITION_COUNT;
+ effect_names = &video_transition_names;
+ } else {
+ lim = AUDIO_TRANSITION_COUNT;
+ effect_names = &audio_transition_names;
+ }
+ } else {
+ if (video) {
+ lim = VIDEO_EFFECT_COUNT;
+ effect_names = &video_effect_names;
+ } else {
+ lim = AUDIO_EFFECT_COUNT;
+ effect_names = &audio_effect_names;
+ }
+ }
QMenu effects_menu(this);
@@ -168,12 +194,22 @@ void EffectControls::set_clips(QVector& clips) {
void EffectControls::on_add_video_effect_button_clicked()
{
- show_menu(true);
+ show_effect_menu(true, false);
}
void EffectControls::on_add_audio_effect_button_clicked()
{
- show_menu(false);
+ show_effect_menu(false, false);
+}
+
+void EffectControls::on_add_video_transition_button_clicked()
+{
+ show_effect_menu(true, true);
+}
+
+void EffectControls::on_add_audio_transition_button_clicked()
+{
+ show_effect_menu(false, true);
}
bool EffectControls::is_focused() {
diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h
index be4ac8a7b..50cab070e 100644
--- a/panels/effectcontrols.h
+++ b/panels/effectcontrols.h
@@ -19,7 +19,6 @@ class EffectControls : public QDockWidget
public:
explicit EffectControls(QWidget *parent = 0);
~EffectControls();
- // void set_clip(Clip* c);
void set_clips(QVector& clips);
void clear_effects(bool clear_cache);
void delete_effects();
@@ -28,20 +27,22 @@ public:
private slots:
void menu_select(QAction* q);
-
void on_add_video_effect_button_clicked();
-
void on_add_audio_effect_button_clicked();
+ void deselect_all_effects(QWidget*);
- void deselect_all_effects(QWidget*);
+ void on_add_video_transition_button_clicked();
+
+ void on_add_audio_transition_button_clicked();
private:
Ui::EffectControls *ui;
QVector selected_clips;
- void show_menu(bool video);
+ void show_effect_menu(bool video, bool transitions);
void load_effects();
bool video_menu;
+ bool transition_menu;
};
/*class EffectAddCommand : public QUndoCommand {
diff --git a/panels/effectcontrols.ui b/panels/effectcontrols.ui
index c1b26eec2..a5c46f64e 100644
--- a/panels/effectcontrols.ui
+++ b/panels/effectcontrols.ui
@@ -173,7 +173,7 @@
-
-
+
Add Video Transition
@@ -318,7 +318,7 @@
-
-
+
Add Audio Transition
diff --git a/panels/timeline.cpp b/panels/timeline.cpp
index ea49e9631..9aed6d8af 100644
--- a/panels/timeline.cpp
+++ b/panels/timeline.cpp
@@ -50,7 +50,7 @@ Timeline::Timeline(QWidget *parent) :
ui(new Ui::Timeline),
last_frame(0)
{
- default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * default_track_height;
+ default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT;
ui->setupUi(this);
@@ -215,7 +215,7 @@ int Timeline::calculate_track_height(int track, int value) {
int index = (track < 0) ? qAbs(track + 1) : track;
QVector& vector = (track < 0) ? video_track_heights : audio_track_heights;
while (vector.size() < index+1) {
- vector.append(TRACK_DEFAULT_HEIGHT);
+ vector.append(default_track_height);
}
if (value > -1) {
vector[index] = value;
@@ -837,19 +837,34 @@ bool Timeline::split_selection(TimelineAction* ta) {
for (int i=0;itrack) {
- if (clip->timeline_in < s.in && clip->timeline_out > s.out) {
+ if (clip->timeline_in < s.in && clip->timeline_out > s.out) {
Clip* split_A = clip->copy(sequence);
split_A->clip_in += (s.in - clip->timeline_in);
split_A->timeline_in = s.in;
split_A->timeline_out = s.out;
pre_splits.append(j);
- post_splits.append(split_A);
+ post_splits.append(split_A);
Clip* split_B = clip->copy(sequence);
split_B->clip_in += (s.out - clip->timeline_in);
split_B->timeline_in = s.out;
secondary_post_splits.append(split_B);
+ if (clip->opening_transition != NULL) {
+ delete split_B->opening_transition;
+ split_B->opening_transition = NULL;
+
+ delete split_A->opening_transition;
+ split_A->opening_transition = NULL;
+ }
+
+ if (clip->closing_transition != NULL) {
+ ta->delete_transition(sequence, j, TA_CLOSING_TRANSITION);
+
+ delete split_A->closing_transition;
+ split_A->closing_transition = NULL;
+ }
+
ta->set_timeline_out(sequence, j, s.in);
split = true;
} else {
diff --git a/panels/timeline.h b/panels/timeline.h
index 33b47b461..f5e57729f 100644
--- a/panels/timeline.h
+++ b/panels/timeline.h
@@ -2,6 +2,7 @@
#define TIMELINE_H
#include "ui/timelinetools.h"
+
#include
#include
#include
@@ -68,7 +69,6 @@ class Timeline;
class Timeline : public QDockWidget
{
Q_OBJECT
-
public:
explicit Timeline(QWidget *parent = 0);
~Timeline();
diff --git a/panels/timeline.ui b/panels/timeline.ui
index 9df286d0c..126e6b0b7 100644
--- a/panels/timeline.ui
+++ b/panels/timeline.ui
@@ -33,7 +33,7 @@
-
-
+
0
0
@@ -272,7 +272,7 @@
0
0
819
- 551
+ 557
@@ -309,6 +309,12 @@
Qt::Vertical
+
+ false
+
+
+ false
+
QFrame::NoFrame
@@ -327,8 +333,8 @@
0
0
- 802
- 266
+ 805
+ 269
@@ -378,8 +384,8 @@
0
0
- 802
- 265
+ 805
+ 269
diff --git a/playback/audio.cpp b/playback/audio.cpp
index c51a6f7c7..7b7b64fc5 100644
--- a/playback/audio.cpp
+++ b/playback/audio.cpp
@@ -38,8 +38,8 @@ void init_audio() {
if (!info.isFormatSupported(audio_format)) {
qWarning() << "[WARNING] Couldn't initialize audio. Audio format is not supported by backend";
} else {
- audio_output = new QAudioOutput(audio_format);
- audio_output->setBufferSize(20480);
+ audio_output = new QAudioOutput(audio_format);
+ audio_output->setBufferSize(20480);
// connect
audio_io_device = audio_output->start();
diff --git a/project/clip.cpp b/project/clip.cpp
index facf772c8..d454e37b5 100644
--- a/project/clip.cpp
+++ b/project/clip.cpp
@@ -131,6 +131,7 @@ void Clip::run_video_pre_effect_stack(long playhead, int* anchor_x, int* anchor_
opening_transition->process_transition((double)transition_progress/(double)opening_transition->length);
}
}
+
if (closing_transition != NULL) {
int transition_progress = closing_transition->length - (playhead - timeline_in - getLength() + closing_transition->length);
if (transition_progress < closing_transition->length) {
diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp
index 2cfa5af90..d8c75e9b9 100644
--- a/ui/timelinewidget.cpp
+++ b/ui/timelinewidget.cpp
@@ -1579,7 +1579,7 @@ void TimelineWidget::redraw_clips() {
}
}
- if (minimumWidth() != panel_width || /*clip_pixmap.height() != height() || */panel_height != minimumHeight()) {
+ if (minimumWidth() != panel_width || clip_pixmap.height() != height() || panel_height != minimumHeight()) {
setMinimumWidth(panel_width);
container->setMinimumWidth(panel_width);
setMinimumHeight(panel_height);
diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp
index c4a6eb0af..47e44fd5b 100644
--- a/ui/viewerwidget.cpp
+++ b/ui/viewerwidget.cpp
@@ -32,7 +32,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
setFormat(format);
// start audio sending thread
- audio_sender_thread.start();
+ audio_sender_thread.start();
// error handler - retries after 250ms if we couldn't get the entire image
retry_timer.setInterval(250);
@@ -40,9 +40,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
}
ViewerWidget::~ViewerWidget() {
- audio_sender_thread.close = true;
+ audio_sender_thread.close = true;
audio_sender_thread.cond.wakeAll();
- audio_sender_thread.wait();
+ audio_sender_thread.wait();
}
void ViewerWidget::deleteFunction() {
@@ -87,12 +87,14 @@ void ViewerWidget::paintEvent(QPaintEvent *e) {
if (enable_paint) QOpenGLWidget::paintEvent(e);
}
-void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
+void ViewerWidget::compose_sequence(QVector& nests, bool render_audio) {
Sequence* s = sequence;
long playhead = panel_timeline->playhead;
- if (nest != NULL) {
- s = static_cast(nest->media);
+ Clip* nest = NULL;
+ if (nests.size() > 0) {
+ nest = nests.last();
+ s = static_cast(nest->media);
playhead += nest->clip_in - nest->timeline_in;
playhead = refactor_frame_number(playhead, sequence->frame_rate, s->frame_rate);
}
@@ -157,8 +159,7 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
texture_failed = true;
} else {
switch (c->media_type) {
- case MEDIA_TYPE_FOOTAGE:
- qDebug() << "clip";
+ case MEDIA_TYPE_FOOTAGE:
if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
// start preparing cache
get_clip_frame(c, playhead);
@@ -183,9 +184,9 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
// perform all transform effects
c->run_video_pre_effect_stack(playhead, &anchor_x, &anchor_y);
- if (nest != NULL) {
- nest->run_video_pre_effect_stack(playhead, &anchor_x, &anchor_y);
- }
+ for (int i=nests.size()-1;i>=0;i--) {
+ nests.at(i)->run_video_pre_effect_stack(playhead, &anchor_x, &anchor_y);
+ }
int anchor_right = ms->video_width - anchor_x;
int anchor_bottom = ms->video_height - anchor_y;
@@ -217,8 +218,8 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
}
break;
case MEDIA_TYPE_SEQUENCE:
- qDebug() << "nest";
- compose_sequence(c, render_audio);
+ nests.append(c);
+ compose_sequence(nests, render_audio);
c->run_video_post_effect_stack();
break;
}
@@ -237,12 +238,13 @@ void ViewerWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
// compose video preview
- compose_sequence(NULL, (panel_timeline->playing || force_audio));
+ QVector nests;
+ compose_sequence(nests, (panel_timeline->playing || force_audio));
- // send audio to IO device
- if (panel_timeline->playing) {
- audio_sender_thread.cond.wakeAll();
- }
+ // send audio to IO device
+ if (panel_timeline->playing) {
+ audio_sender_thread.cond.wakeAll();
+ }
if (texture_failed) {
if (multithreaded) {
@@ -256,60 +258,62 @@ void ViewerWidget::paintGL() {
}
AudioSenderThread::AudioSenderThread() : close(false) {
- connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
+ connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
}
void AudioSenderThread::run() {
- lock.lock();
- while (true) {
- cond.wait(&lock);
- if (close) {
- break;
- } else {
- int written_bytes = 0;
+ lock.lock();
+ while (true) {
+ cond.wait(&lock);
+ if (close) {
+ break;
+ } else {
+ int written_bytes = 0;
- int adjusted_read_index = audio_ibuffer_read%audio_ibuffer_size;
- int max_write = audio_ibuffer_size - adjusted_read_index;
- int actual_write = send_audio_to_output(adjusted_read_index, max_write);
- written_bytes += actual_write;
- if (actual_write == max_write) {
- // got all the bytes, write again
- written_bytes += send_audio_to_output(0, audio_ibuffer_size);
- }
- }
- }
- lock.unlock();
+ int adjusted_read_index = audio_ibuffer_read%audio_ibuffer_size;
+ int max_write = audio_ibuffer_size - adjusted_read_index;
+ int actual_write = send_audio_to_output(adjusted_read_index, max_write);
+ written_bytes += actual_write;
+ if (actual_write == max_write) {
+ // got all the bytes, write again
+ written_bytes += send_audio_to_output(0, audio_ibuffer_size);
+ }
+
+ qDebug() << "WB:" << written_bytes;
+ }
+ }
+ lock.unlock();
}
int AudioSenderThread::send_audio_to_output(int offset, int max) {
- // send audio to device
- int actual_write = audio_io_device->write((const char*) audio_ibuffer+offset, max);
- audio_ibuffer_read += actual_write;
+ // send audio to device
+ int actual_write = audio_io_device->write((const char*) audio_ibuffer+offset, max);
+ audio_ibuffer_read += actual_write;
- // send samples to audio monitor cache
- if (panel_timeline->ui->audio_monitor->sample_cache_offset == -1) {
- panel_timeline->ui->audio_monitor->sample_cache_offset = panel_timeline->playhead;
- }
- long sample_cache_playhead = panel_timeline->ui->audio_monitor->sample_cache_offset + panel_timeline->ui->audio_monitor->sample_cache.size();
- int next_buffer_offset, buffer_offset_adjusted, i;
- int buffer_offset = get_buffer_offset_from_frame(sample_cache_playhead);
- samples.resize(av_get_channel_layout_nb_channels(sequence->audio_layout));
- samples.fill(0);
- while (buffer_offset < audio_ibuffer_read) {
- sample_cache_playhead++;
- next_buffer_offset = qMin(get_buffer_offset_from_frame(sample_cache_playhead), audio_ibuffer_read);
- while (buffer_offset < next_buffer_offset) {
- for (i=0;iui->audio_monitor->sample_cache.append(samples);
- buffer_offset = next_buffer_offset;
- }
+ // send samples to audio monitor cache
+ if (panel_timeline->ui->audio_monitor->sample_cache_offset == -1) {
+ panel_timeline->ui->audio_monitor->sample_cache_offset = panel_timeline->playhead;
+ }
+ long sample_cache_playhead = panel_timeline->ui->audio_monitor->sample_cache_offset + panel_timeline->ui->audio_monitor->sample_cache.size();
+ int next_buffer_offset, buffer_offset_adjusted, i;
+ int buffer_offset = get_buffer_offset_from_frame(sample_cache_playhead);
+ samples.resize(av_get_channel_layout_nb_channels(sequence->audio_layout));
+ samples.fill(0);
+ while (buffer_offset < audio_ibuffer_read) {
+ sample_cache_playhead++;
+ next_buffer_offset = qMin(get_buffer_offset_from_frame(sample_cache_playhead), audio_ibuffer_read);
+ while (buffer_offset < next_buffer_offset) {
+ for (i=0;iui->audio_monitor->sample_cache.append(samples);
+ buffer_offset = next_buffer_offset;
+ }
- memset(audio_ibuffer+offset, 0, actual_write);
+ memset(audio_ibuffer+offset, 0, actual_write);
- return actual_write;
+ return actual_write;
}
diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h
index 7e2ba1da6..e04b0944a 100644
--- a/ui/viewerwidget.h
+++ b/ui/viewerwidget.h
@@ -15,14 +15,14 @@ struct Sequence;
class AudioSenderThread : public QThread {
public:
- AudioSenderThread();
- void run();
- QWaitCondition cond;
- bool close;
- QMutex lock;
+ AudioSenderThread();
+ void run();
+ QWaitCondition cond;
+ bool close;
+ QMutex lock;
private:
- QVector samples;
- int send_audio_to_output(int offset, int max);
+ QVector samples;
+ int send_audio_to_output(int offset, int max);
};
class ViewerWidget : public QOpenGLWidget, public QOpenGLFunctions
@@ -43,11 +43,11 @@ protected:
// void resizeGL(int w, int h);
private:
QTimer retry_timer;
- AudioSenderThread audio_sender_thread;
+ AudioSenderThread audio_sender_thread;
private slots:
void retry();
void deleteFunction();
- void compose_sequence(Clip *nest, bool render_audio);
+ void compose_sequence(QVector& nests, bool render_audio);
};
#endif // VIEWERWIDGET_H