nested sequences mostly implemented
This commit is contained in:
+23
-5
@@ -76,7 +76,9 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
bool got_audio_values = false;
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* item = items.at(i);
|
||||
if (get_type_from_tree(item) == MEDIA_TYPE_FOOTAGE) {
|
||||
switch (get_type_from_tree(item)) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
Media* m = get_media_from_tree(item);
|
||||
if (m->ready) {
|
||||
if (!got_video_values) {
|
||||
@@ -101,9 +103,24 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (got_video_values && got_audio_values) break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
{
|
||||
Sequence* s = get_sequence_from_tree(item);
|
||||
predicted_video_width = s->width;
|
||||
predicted_video_height = s->height;
|
||||
predicted_new_frame_rate = s->frame_rate;
|
||||
predicted_audio_freq = s->audio_frequency;
|
||||
predicted_audio_layout = s->audio_layout;
|
||||
|
||||
got_video_values = true;
|
||||
got_audio_values = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (got_video_values && got_audio_values) break;
|
||||
}
|
||||
} else {
|
||||
entry_point = panel_timeline->getFrameFromScreenPoint(pos.x());
|
||||
@@ -130,6 +147,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
s = get_sequence_from_tree(item);
|
||||
sequence_length = s->getEndFrame();
|
||||
if (sequence != NULL) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, sequence->frame_rate);
|
||||
media = s;
|
||||
can_import = (s != sequence && sequence_length != 0);
|
||||
break;
|
||||
@@ -305,11 +323,11 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
|
||||
// DUMB HACKY CODE THAT MIGHT NOT WORK TO ADD EFFECTS
|
||||
if (c->track < 0) {
|
||||
// add default video effects
|
||||
ta->add_effect(s, i + sequence->clip_count(), VIDEO_TRANSFORM_EFFECT);
|
||||
ta->add_effect(s, i + s->clip_count(), VIDEO_TRANSFORM_EFFECT);
|
||||
} else {
|
||||
// add default audio effects
|
||||
ta->add_effect(s, i + sequence->clip_count(), AUDIO_VOLUME_EFFECT);
|
||||
ta->add_effect(s, i + sequence->clip_count(), AUDIO_PAN_EFFECT);
|
||||
ta->add_effect(s, i + s->clip_count(), AUDIO_VOLUME_EFFECT);
|
||||
ta->add_effect(s, i + s->clip_count(), AUDIO_PAN_EFFECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+60
-46
@@ -20,12 +20,13 @@ extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) : QOpenGLWidget(parent) {
|
||||
multithreaded = true;
|
||||
enable_paint = true;
|
||||
force_audio = false;
|
||||
flip = false;
|
||||
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
QOpenGLWidget(parent),
|
||||
multithreaded(true),
|
||||
force_audio(false),
|
||||
enable_paint(true),
|
||||
flip(false)
|
||||
{
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
setFormat(format);
|
||||
@@ -86,24 +87,52 @@ void ViewerWidget::paintEvent(QPaintEvent *e) {
|
||||
if (enable_paint) QOpenGLWidget::paintEvent(e);
|
||||
}
|
||||
|
||||
void ViewerWidget::compose_sequence(Sequence *s, bool render_audio) {
|
||||
void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
Sequence* s = sequence;
|
||||
long playhead = panel_timeline->playhead;
|
||||
if (nest != NULL) {
|
||||
s = static_cast<Sequence*>(nest->media);
|
||||
|
||||
// qDebug() << "nested sequence was null:" << (s == NULL);
|
||||
|
||||
playhead += nest->clip_in - nest->timeline_in;
|
||||
playhead = refactor_frame_number(playhead, sequence->frame_rate, s->frame_rate);
|
||||
}
|
||||
|
||||
QVector<Clip*> current_clips;
|
||||
|
||||
for (int i=0;i<s->clip_count();i++) {
|
||||
Clip* c = s->get_clip(i);
|
||||
|
||||
// if clip starts within one second and/or hasn't finished yet
|
||||
if (c != NULL && c->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
Media* m = static_cast<Media*>(c->media);
|
||||
if (m->ready
|
||||
&& m->get_stream_from_file_index(c->media_stream) != NULL
|
||||
&& is_clip_active(c, panel_timeline->playhead)) {
|
||||
// if thread is already working, we don't want to touch this,
|
||||
// but we also don't want to hang the UI thread
|
||||
if (!c->open) {
|
||||
open_clip(c, multithreaded);
|
||||
}
|
||||
if (c != NULL && !(nest != NULL && c->track != nest->track)) {
|
||||
bool clip_is_active = false;
|
||||
|
||||
switch (c->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
Media* m = static_cast<Media*>(c->media);
|
||||
if (m->ready
|
||||
&& m->get_stream_from_file_index(c->media_stream) != NULL
|
||||
&& is_clip_active(c, playhead)) {
|
||||
// if thread is already working, we don't want to touch this,
|
||||
// but we also don't want to hang the UI thread
|
||||
if (!c->open) {
|
||||
open_clip(c, multithreaded);
|
||||
}
|
||||
|
||||
clip_is_active = true;
|
||||
} else if (c->open) {
|
||||
close_clip(c);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
clip_is_active = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (clip_is_active) {
|
||||
bool added = false;
|
||||
for (int j=0;j<current_clips.size();j++) {
|
||||
if (current_clips.at(j)->track < c->track) {
|
||||
@@ -115,8 +144,6 @@ void ViewerWidget::compose_sequence(Sequence *s, bool render_audio) {
|
||||
if (!added) {
|
||||
current_clips.append(c);
|
||||
}
|
||||
} else if (c->open) {
|
||||
close_clip(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,52 +151,38 @@ void ViewerWidget::compose_sequence(Sequence *s, bool render_audio) {
|
||||
for (int i=0;i<current_clips.size();i++) {
|
||||
Clip* c = current_clips.at(i);
|
||||
|
||||
if (!c->finished_opening) {
|
||||
if (c->media_type == MEDIA_TYPE_FOOTAGE && !c->finished_opening) {
|
||||
qDebug() << "[WARNING] Tried to display clip" << i << "but it's closed";
|
||||
texture_failed = true;
|
||||
} else if (is_clip_active(c, panel_timeline->playhead)) {
|
||||
} else {
|
||||
switch (c->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
// start preparing cache
|
||||
get_clip_frame(c, panel_timeline->playhead);
|
||||
get_clip_frame(c, playhead);
|
||||
|
||||
if (c->texture == NULL) {
|
||||
qDebug() << "[WARNING] Texture hasn't been created yet";
|
||||
texture_failed = true;
|
||||
} else if (panel_timeline->playhead >= c->timeline_in) {
|
||||
} else if (playhead >= c->timeline_in) {
|
||||
MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->media_stream);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glLoadIdentity();
|
||||
|
||||
int half_width = s->width/2;
|
||||
int half_height = s->height/2;
|
||||
if (flip) {
|
||||
glOrtho(-half_width, half_width, -half_height, half_height, -1, 1);
|
||||
} else {
|
||||
glOrtho(-half_width, half_width, half_height, -half_height, -1, 1);
|
||||
}
|
||||
int half_width = sequence->width/2;
|
||||
int half_height = sequence->height/2;
|
||||
if (flip) half_height = -half_height;
|
||||
glOrtho(-half_width, half_width, half_height, -half_height, -1, 1);
|
||||
int anchor_x = ms->video_width/2;
|
||||
int anchor_y = ms->video_height/2;
|
||||
|
||||
// perform all transform effects
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
if (c->effects.at(j)->is_enabled()) c->effects.at(j)->process_gl(&anchor_x, &anchor_y);
|
||||
}
|
||||
c->run_video_pre_effect_stack(playhead, &anchor_x, &anchor_y);
|
||||
|
||||
if (c->opening_transition != NULL) {
|
||||
int transition_progress = panel_timeline->playhead-c->timeline_in;
|
||||
if (transition_progress < c->opening_transition->length) {
|
||||
c->opening_transition->process_transition((float)transition_progress/(float)c->opening_transition->length);
|
||||
}
|
||||
}
|
||||
if (c->closing_transition != NULL) {
|
||||
int transition_progress = c->closing_transition->length-(panel_timeline->playhead-c->timeline_in-c->getLength()+c->closing_transition->length);
|
||||
if (transition_progress < c->closing_transition->length) {
|
||||
c->closing_transition->process_transition((float)transition_progress/(float)c->closing_transition->length);
|
||||
}
|
||||
if (nest != NULL) {
|
||||
nest->run_video_pre_effect_stack(playhead, &anchor_x, &anchor_y);
|
||||
}
|
||||
|
||||
int anchor_right = ms->video_width - anchor_x;
|
||||
@@ -199,11 +212,12 @@ void ViewerWidget::compose_sequence(Sequence *s, bool render_audio) {
|
||||
c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
c->lock.tryLock()) {
|
||||
// clip is not caching, start caching audio
|
||||
cache_clip(c, panel_timeline->playhead, false, false, c->reset_audio);
|
||||
cache_clip(c, playhead, false, false, c->audio_reset, nest);
|
||||
c->lock.unlock();
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
compose_sequence(c, render_audio);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -221,7 +235,7 @@ void ViewerWidget::paintGL() {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// compose video preview
|
||||
compose_sequence(sequence, (panel_timeline->playing || force_audio));
|
||||
compose_sequence(NULL, (panel_timeline->playing || force_audio));
|
||||
|
||||
// send audio to IO device
|
||||
if (panel_timeline->playing) {
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ private:
|
||||
private slots:
|
||||
void retry();
|
||||
void deleteFunction();
|
||||
void compose_sequence(Sequence* s, bool render_audio);
|
||||
void compose_sequence(Clip *nest, bool render_audio);
|
||||
};
|
||||
|
||||
#endif // VIEWERWIDGET_H
|
||||
|
||||
Reference in New Issue
Block a user