improved timeline drawing with transitions
This commit is contained in:
@@ -24,6 +24,7 @@ Transition* create_transition(int transition_id, Clip* c) {
|
||||
}
|
||||
} else {
|
||||
switch (transition_id) {
|
||||
case AUDIO_LINEAR_FADE_TRANSITION: return new CrossDissolveTransition();
|
||||
}
|
||||
}
|
||||
qDebug() << "[ERROR] Invalid transition ID";
|
||||
|
||||
+13
-5
@@ -25,6 +25,9 @@ void apply_audio_effects(Clip* c, AVFrame* frame, int nb_bytes) {
|
||||
Effect* e = c->effects.at(j);
|
||||
if (e->is_enabled()) e->process_audio(frame->data[0], nb_bytes);
|
||||
}
|
||||
if (c->opening_transition != NULL) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
@@ -38,6 +41,12 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
timeline_out = refactor_frame_number(timeline_out, c->sequence->frame_rate, sequence->frame_rate) + nest->timeline_in;
|
||||
}
|
||||
|
||||
//
|
||||
// (c->clip_in / c->sequence->frame_rate) is the starting point in seconds
|
||||
// we need to convert it to bytes
|
||||
//
|
||||
//
|
||||
|
||||
while (written < max_write) {
|
||||
// gets one frame worth of audio and sends it to the audio buffer
|
||||
AVFrame* frame = c->cache_A.frames[0];
|
||||
@@ -48,9 +57,7 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
retrieve_next_frame_raw_data(c, frame);
|
||||
int byte_count = av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast<AVSampleFormat>(frame->format), 1);
|
||||
apply_audio_effects(c, frame, byte_count);
|
||||
if (nest != NULL) {
|
||||
apply_audio_effects(nest, frame, byte_count);
|
||||
}
|
||||
if (nest != NULL) apply_audio_effects(nest, frame, byte_count);
|
||||
} else {
|
||||
// set by retrieve_next_frame_raw_data indicating no more frames in file,
|
||||
// but there still may be samples in swresample
|
||||
@@ -60,13 +67,13 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
c->need_new_audio_frame = false;
|
||||
if (c->audio_just_reset) {
|
||||
// get precise sample offset for the elected clip_in from this audio frame
|
||||
float target_sts = 0;
|
||||
double target_sts = 0;
|
||||
if (c->audio_target_frame < timeline_in) {
|
||||
target_sts = clip_frame_to_seconds(c, c->clip_in);
|
||||
} else {
|
||||
target_sts = playhead_to_seconds(c, c->audio_target_frame);
|
||||
}
|
||||
float frame_sts = (frame->pts * av_q2d(c->stream->time_base));
|
||||
double frame_sts = (frame->pts * av_q2d(c->stream->time_base));
|
||||
int nb_samples = qRound((target_sts - frame_sts)*c->sequence->audio_frequency);
|
||||
if (nb_samples == 0) {
|
||||
c->frame_sample_index = 0;
|
||||
@@ -87,6 +94,7 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
int half_buffer = (audio_ibuffer_size/2);
|
||||
if (c->audio_buffer_write == 0) {
|
||||
c->audio_buffer_write = get_buffer_offset_from_frame(qMax(timeline_in, c->audio_target_frame));
|
||||
|
||||
int offset = audio_ibuffer_read - c->audio_buffer_write;
|
||||
if (offset > 0) {
|
||||
c->audio_buffer_write += offset;
|
||||
|
||||
+44
-39
@@ -1588,44 +1588,6 @@ void TimelineWidget::redraw_clips() {
|
||||
|
||||
QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1);
|
||||
|
||||
// draw clip transitions
|
||||
for (int i=0;i<2;i++) {
|
||||
Transition* t = (i == 0) ? clip->opening_transition : clip->closing_transition;
|
||||
if (t != NULL) {
|
||||
int transition_width = panel_timeline->getScreenPointFromFrame(t->length);
|
||||
int transition_height = clip_rect.height() * 0.6;
|
||||
if (transition_height <= TRACK_MIN_HEIGHT) {
|
||||
transition_height = clip_rect.height();
|
||||
}
|
||||
int tr_y = clip_rect.y() + ((clip_rect.height()-transition_height)/2);
|
||||
int tr_x = 0;
|
||||
if (i == 0) {
|
||||
tr_x = clip_rect.x();
|
||||
text_rect.setX(text_rect.x()+transition_width);
|
||||
thumb_x += transition_width;
|
||||
} else {
|
||||
tr_x = clip_rect.right()-transition_width;
|
||||
text_rect.setWidth(text_rect.width()-transition_width);
|
||||
}
|
||||
QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height);
|
||||
clip_painter.fillRect(transition_rect, transition_color);
|
||||
QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING);
|
||||
if (transition_text_rect.width() > MAX_TEXT_WIDTH) {
|
||||
clip_painter.setPen(QColor(0, 0, 0, 96));
|
||||
if (i == 0) {
|
||||
clip_painter.drawLine(transition_rect.bottomLeft(), transition_rect.topRight());
|
||||
} else {
|
||||
clip_painter.drawLine(transition_rect.topLeft(), transition_rect.bottomRight());
|
||||
}
|
||||
|
||||
clip_painter.setPen(Qt::white);
|
||||
clip_painter.drawText(transition_text_rect, 0, t->name, &transition_text_rect);
|
||||
}
|
||||
clip_painter.setPen(Qt::black);
|
||||
clip_painter.drawRect(transition_rect);
|
||||
}
|
||||
}
|
||||
|
||||
if (clip->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
bool draw_checkerboard = false;
|
||||
QRect checkerboard_rect = clip_rect;
|
||||
@@ -1644,10 +1606,19 @@ void TimelineWidget::redraw_clips() {
|
||||
}
|
||||
|
||||
if (clip->track < 0) {
|
||||
int space_for_thumb = clip_rect.width();
|
||||
if (clip->opening_transition != NULL) {
|
||||
int ot_width = panel_timeline->getScreenPointFromFrame(clip->opening_transition->length);
|
||||
thumb_x += ot_width;
|
||||
space_for_thumb -= ot_width;
|
||||
}
|
||||
if (clip->closing_transition != NULL) {
|
||||
space_for_thumb -= panel_timeline->getScreenPointFromFrame(clip->closing_transition->length);
|
||||
}
|
||||
int thumb_y = clip_painter.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING;
|
||||
int thumb_height = clip_rect.height()-thumb_y;
|
||||
int thumb_width = (thumb_height*((double)ms->video_preview.width()/(double)ms->video_preview.height()));
|
||||
if (thumb_height > thumb_y && text_rect.width() + CLIP_TEXT_PADDING > thumb_width) { // at small clip heights, don't even draw it
|
||||
if (thumb_height > thumb_y && text_rect.width() + CLIP_TEXT_PADDING > thumb_width && space_for_thumb >= thumb_width) { // at small clip heights, don't even draw it
|
||||
QRect thumb_rect(thumb_x, clip_rect.y()+thumb_y, thumb_width, thumb_height);
|
||||
clip_painter.drawImage(thumb_rect, ms->video_preview);
|
||||
}
|
||||
@@ -1705,6 +1676,40 @@ void TimelineWidget::redraw_clips() {
|
||||
}
|
||||
}
|
||||
|
||||
// draw clip transitions
|
||||
for (int i=0;i<2;i++) {
|
||||
Transition* t = (i == 0) ? clip->opening_transition : clip->closing_transition;
|
||||
if (t != NULL) {
|
||||
int transition_width = panel_timeline->getScreenPointFromFrame(t->length);
|
||||
int transition_height = clip_rect.height();
|
||||
int tr_y = clip_rect.y();
|
||||
int tr_x = 0;
|
||||
if (i == 0) {
|
||||
tr_x = clip_rect.x();
|
||||
text_rect.setX(text_rect.x()+transition_width);
|
||||
} else {
|
||||
tr_x = clip_rect.right()-transition_width;
|
||||
text_rect.setWidth(text_rect.width()-transition_width);
|
||||
}
|
||||
QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height);
|
||||
clip_painter.fillRect(transition_rect, transition_color);
|
||||
QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING);
|
||||
if (transition_text_rect.width() > MAX_TEXT_WIDTH) {
|
||||
clip_painter.setPen(QColor(0, 0, 0, 96));
|
||||
if (i == 0) {
|
||||
clip_painter.drawLine(transition_rect.bottomLeft(), transition_rect.topRight());
|
||||
} else {
|
||||
clip_painter.drawLine(transition_rect.topLeft(), transition_rect.bottomRight());
|
||||
}
|
||||
|
||||
clip_painter.setPen(Qt::white);
|
||||
clip_painter.drawText(transition_text_rect, 0, t->name, &transition_text_rect);
|
||||
}
|
||||
clip_painter.setPen(Qt::black);
|
||||
clip_painter.drawRect(transition_rect);
|
||||
}
|
||||
}
|
||||
|
||||
// top left bevel
|
||||
clip_painter.setPen(Qt::white);
|
||||
clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft());
|
||||
|
||||
Reference in New Issue
Block a user