diff --git a/effects/transition.cpp b/effects/transition.cpp index 59637dab0..8aeed8660 100644 --- a/effects/transition.cpp +++ b/effects/transition.cpp @@ -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"; diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 96fbb4e3c..12a578083 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -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(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; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 76ee15c68..6ff072bbd 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -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());