nicer effects panel, improved split selection

This commit is contained in:
itsmattkc
2018-08-11 20:06:20 +10:00
parent abba6bf8b4
commit 7e6d4dce20
20 changed files with 302 additions and 155 deletions
+20 -20
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>557</width>
<height>659</height>
<width>358</width>
<height>442</height>
</rect>
</property>
<property name="windowTitle">
@@ -75,13 +75,6 @@
<item row="0" column="1">
<widget class="QComboBox" name="vcodecCombobox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="widthSpinbox">
<property name="maximum">
@@ -89,6 +82,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@@ -120,14 +120,14 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Bitrate (Mbps/CBR):</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="videobitrateSpinbox">
<property name="maximum">
<double>100.000000000000000</double>
@@ -159,13 +159,6 @@
<item row="0" column="1">
<widget class="QComboBox" name="acodecCombobox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Sampling Rate:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="samplingRateSpinbox">
<property name="maximum">
@@ -176,14 +169,21 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Sampling Rate:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Bitrate (Kbps/CBR):</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="audiobitrateSpinbox">
<property name="maximum">
<number>320</number>
-17
View File
@@ -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<nb_samples;i+=2) {
qint16 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
if (reverse) {
samp *= 1 - (range_start + (interval * i));
} else {
samp *= range_start + (interval * i);
}
samples[i+1] = (quint8) (samp >> 8);
samples[i] = (quint8) samp;
}
}
Transition* CrossDissolveTransition::copy() {
Transition* t = new CrossDissolveTransition();
t->length = length;
+2
View File
@@ -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) {
+14
View File
@@ -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:
+51
View File
@@ -0,0 +1,51 @@
#include "effects/effects.h"
#include "ui/labelslider.h"
#include <QLabel>
#include <QGridLayout>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QXmlStreamAttributes>
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;i<attr.size();i++) {
const QXmlStreamAttribute& a = attr.at(i);
if (a.name() == "amount") {
amount_val->set_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);
}
+26
View File
@@ -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<nb_samples;i+=2) {
qint16 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
if (reverse) {
samp *= 1 - (range_start + (interval * i));
} else {
samp *= range_start + (interval * i);
}
samples[i+1] = (quint8) (samp >> 8);
samples[i] = (quint8) samp;
}
}
Transition* LinearFadeTransition::copy() {
Transition* t = new LinearFadeTransition();
t->length = length;
return t;
}
+15 -9
View File
@@ -15,11 +15,6 @@ enum AudioTransitions {
AUDIO_TRANSITION_COUNT
};
void init_transitions();
extern QVector<QString> video_transition_names;
extern QVector<QString> 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<QString> video_transition_names;
extern QVector<QString> 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
+1 -1
View File
@@ -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);
+3 -1
View File
@@ -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 \
+49 -13
View File
@@ -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;i<selected_clips.size();i++) {
if ((sequence->get_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<QString>* 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<int>& 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() {
+6 -5
View File
@@ -19,7 +19,6 @@ class EffectControls : public QDockWidget
public:
explicit EffectControls(QWidget *parent = 0);
~EffectControls();
// void set_clip(Clip* c);
void set_clips(QVector<int>& 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<int> 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 {
+2 -2
View File
@@ -173,7 +173,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="add_video_transition_button">
<property name="toolTip">
<string>Add Video Transition</string>
</property>
@@ -318,7 +318,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<widget class="QPushButton" name="add_audio_transition_button">
<property name="toolTip">
<string>Add Audio Transition</string>
</property>
+19 -4
View File
@@ -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<int>& 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;i<selections.size();i++) {
const Selection& s = selections.at(i);
if (s.track == clip->track) {
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 {
+1 -1
View File
@@ -2,6 +2,7 @@
#define TIMELINE_H
#include "ui/timelinetools.h"
#include <QDockWidget>
#include <QVector>
#include <QTime>
@@ -68,7 +69,6 @@ class Timeline;
class Timeline : public QDockWidget
{
Q_OBJECT
public:
explicit Timeline(QWidget *parent = 0);
~Timeline();
+12 -6
View File
@@ -33,7 +33,7 @@
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<sizepolicy hsizetype="Maximum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -272,7 +272,7 @@
<x>0</x>
<y>0</y>
<width>819</width>
<height>551</height>
<height>557</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
@@ -309,6 +309,12 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="opaqueResize">
<bool>false</bool>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
<widget class="QScrollArea" name="videoScrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
@@ -327,8 +333,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>802</width>
<height>266</height>
<width>805</width>
<height>269</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -378,8 +384,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>802</width>
<height>265</height>
<width>805</width>
<height>269</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
+2 -2
View File
@@ -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();
+1
View File
@@ -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) {
+1 -1
View File
@@ -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);
+68 -64
View File
@@ -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<Clip*>& nests, bool render_audio) {
Sequence* s = sequence;
long playhead = panel_timeline->playhead;
if (nest != NULL) {
s = static_cast<Sequence*>(nest->media);
Clip* nest = NULL;
if (nests.size() > 0) {
nest = nests.last();
s = static_cast<Sequence*>(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<Clip*> 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;i<samples.size();i++) {
buffer_offset_adjusted = buffer_offset%audio_ibuffer_size;
samples[i] = qMax(qAbs((qint16) (((audio_ibuffer[buffer_offset_adjusted+1] & 0xFF) << 8) | (audio_ibuffer[buffer_offset_adjusted] & 0xFF))), samples[i]);
buffer_offset += 2;
}
}
panel_timeline->ui->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;i<samples.size();i++) {
buffer_offset_adjusted = buffer_offset%audio_ibuffer_size;
samples[i] = qMax(qAbs((qint16) (((audio_ibuffer[buffer_offset_adjusted+1] & 0xFF) << 8) | (audio_ibuffer[buffer_offset_adjusted] & 0xFF))), samples[i]);
buffer_offset += 2;
}
}
panel_timeline->ui->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;
}
+9 -9
View File
@@ -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<qint16> samples;
int send_audio_to_output(int offset, int max);
QVector<qint16> 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<Clip*>& nests, bool render_audio);
};
#endif // VIEWERWIDGET_H