further progress on ffmpeg filters
This commit is contained in:
+29
-68
@@ -25,6 +25,8 @@ extern "C" {
|
||||
#include <QtMath>
|
||||
#include <math.h>
|
||||
|
||||
int dest_format = AV_PIX_FMT_RGBA;
|
||||
|
||||
void apply_audio_effects(Clip* c, AVFrame* frame, int nb_bytes) {
|
||||
// perform all audio effects
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
@@ -188,9 +190,35 @@ void cache_video_worker(Clip* c, long playhead, ClipCache* cache) {
|
||||
if (!c->reached_end) {
|
||||
while (i < c->cache_size) {
|
||||
av_frame_unref(cache->frames[i]);
|
||||
int ret = av_buffersink_get_frame(c->buffersink_ctx, cache->frames[i]);
|
||||
|
||||
int ret = (c->filter_graph == NULL) ? AVERROR(EAGAIN) : av_buffersink_get_frame(c->buffersink_ctx, cache->frames[i]);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
if (c->filter_graph != NULL) {
|
||||
avfilter_graph_free(&c->filter_graph);
|
||||
}
|
||||
c->filter_graph = avfilter_graph_alloc();
|
||||
char args[512];
|
||||
snprintf(args, sizeof(args),
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||
c->stream->codecpar->width, c->stream->codecpar->height, c->stream->codecpar->format,
|
||||
c->stream->time_base.num, c->stream->time_base.den,
|
||||
c->stream->codecpar->sample_aspect_ratio.num, c->stream->codecpar->sample_aspect_ratio.den);
|
||||
avfilter_graph_create_filter(&c->buffersrc_ctx, avfilter_get_by_name("buffer"), "in", args, NULL, c->filter_graph);
|
||||
avfilter_graph_create_filter(&c->buffersink_ctx, avfilter_get_by_name("buffersink"), "out", NULL, NULL, c->filter_graph);
|
||||
enum AVPixelFormat pix_fmts[] = { static_cast<AVPixelFormat>(dest_format), AV_PIX_FMT_NONE };
|
||||
av_opt_set_int_list(c->buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
AVFilterContext* gblur_ctx;
|
||||
// avfilter_graph_create_filter(&gblur_ctx, avfilter_get_by_name("gblur"), "ol_gblur", "sigma=20:steps=1", NULL, c->filter_graph);
|
||||
avfilter_graph_create_filter(&gblur_ctx, avfilter_get_by_name("negate"), "ol_gblur", NULL, NULL, c->filter_graph);
|
||||
// avfilter_graph_create_filter(&gblur_ctx, avfilter_get_by_name("null"), "ol_gblur", NULL, NULL, c->filter_graph);
|
||||
avfilter_link(c->buffersrc_ctx, 0, gblur_ctx, 0);
|
||||
avfilter_link(gblur_ctx, 0, c->buffersink_ctx, 0);
|
||||
|
||||
avfilter_graph_config(c->filter_graph, NULL);
|
||||
|
||||
ret = retrieve_next_frame(c, c->frame);
|
||||
if (ret >= 0) {
|
||||
if ((ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, c->frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) {
|
||||
@@ -334,7 +362,6 @@ void open_clip_worker(Clip* clip) {
|
||||
// as "scaling" is actually done by OpenGL
|
||||
int dstW = ceil(clip->stream->codecpar->width/2)*2;
|
||||
int dstH = ceil(clip->stream->codecpar->height/2)*2;
|
||||
int dest_format = AV_PIX_FMT_RGBA;
|
||||
|
||||
clip->sws_ctx = sws_getContext(
|
||||
clip->stream->codecpar->width,
|
||||
@@ -374,71 +401,6 @@ void open_clip_worker(Clip* clip) {
|
||||
qDebug() << "[ERROR] Could not allocate buffer for sws_frame";
|
||||
}
|
||||
clip->sws_frame->linesize[0] = clip->stream->codecpar->width*4;
|
||||
|
||||
// SET UP FFMPEG FILTERGRAPH
|
||||
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
|
||||
clip->filter_graph = avfilter_graph_alloc();
|
||||
|
||||
if (outputs == NULL || inputs == NULL || clip->filter_graph == NULL) {
|
||||
qDebug() << "[ERROR] Couldn't alloc filter graphs. Out of memory?";
|
||||
} else {
|
||||
char args[512];
|
||||
snprintf(args, sizeof(args),
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||
clip->stream->codecpar->width, clip->stream->codecpar->height, clip->stream->codecpar->format,
|
||||
clip->stream->time_base.num, clip->stream->time_base.den,
|
||||
clip->stream->codecpar->sample_aspect_ratio.num, clip->stream->codecpar->sample_aspect_ratio.den);
|
||||
|
||||
int ret = avfilter_graph_create_filter(&clip->buffersrc_ctx, buffersrc, "in", args, NULL, clip->filter_graph);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] Could not create buffer source";
|
||||
} else {
|
||||
ret = avfilter_graph_create_filter(&clip->buffersink_ctx, buffersink, "out", NULL, NULL, clip->filter_graph);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] Could not create buffer sink";
|
||||
} else {
|
||||
enum AVPixelFormat pix_fmts[] = { static_cast<AVPixelFormat>(dest_format), AV_PIX_FMT_NONE };
|
||||
av_opt_set_int_list(clip->buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = clip->buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = clip->buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
inputs->next = 0;
|
||||
|
||||
/*ret = avfilter_graph_config(clip->filter_graph, NULL);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] AVFilter config failed";
|
||||
}*/
|
||||
|
||||
ret = avfilter_graph_parse_ptr(clip->filter_graph, "gblur=sigma=20:steps=4", &inputs, &outputs, NULL);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] Couldn't parse filters." << ret;
|
||||
} else {
|
||||
ret = avfilter_graph_config(clip->filter_graph, NULL);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] AVFilter config failed." << ret;
|
||||
}
|
||||
|
||||
/*ret = avfilter_graph_send_command(clip->filter_graph, "gblur", "enable", "2", NULL, 0, 0);
|
||||
if (ret < 0) {
|
||||
qDebug() << "[ERROR] Failed to send graph command." << ret << AVERROR(ENOSYS);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
} else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
// if FFmpeg can't pick up the channel layout (usually WAV), assume
|
||||
// based on channel count (doesn't support surround sound sources yet)
|
||||
@@ -509,7 +471,6 @@ void close_clip_worker(Clip* clip) {
|
||||
sws_freeContext(clip->sws_ctx);
|
||||
|
||||
// TODO will eventually be in audio too
|
||||
avfilter_graph_free(&clip->filter_graph);
|
||||
av_frame_free(&clip->sws_frame);
|
||||
} else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
swr_free(&clip->swr_ctx);
|
||||
|
||||
@@ -26,6 +26,7 @@ Clip::Clip(Sequence* s) :
|
||||
opening_transition(NULL),
|
||||
closing_transition(NULL),
|
||||
pkt(new AVPacket()),
|
||||
filter_graph(NULL),
|
||||
replaced(false),
|
||||
texture(NULL)
|
||||
{
|
||||
|
||||
+150
-154
@@ -512,187 +512,183 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
repaint = true;
|
||||
if (panel_timeline->ghosts.size() > 0) {
|
||||
const Ghost& first_ghost = panel_timeline->ghosts.at(0);
|
||||
if (first_ghost.old_in != first_ghost.in
|
||||
|| first_ghost.old_out != first_ghost.out
|
||||
|| first_ghost.old_clip_in != first_ghost.clip_in
|
||||
|| first_ghost.old_track != first_ghost.track) {
|
||||
TimelineAction* ta = new TimelineAction();
|
||||
|
||||
// if we were RIPPLING, move all the clips
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) {
|
||||
long ripple_length, ripple_point;
|
||||
TimelineAction* ta = new TimelineAction();
|
||||
|
||||
// ripple_length becomes the length/number of frames we trimmed
|
||||
// ripple point becomes the point to ripple (i.e. the point after or before which we move every clip)
|
||||
if (panel_timeline->trim_in_point) {
|
||||
ripple_length = first_ghost.old_in - panel_timeline->ghosts.at(0).in;
|
||||
ripple_point = first_ghost.old_in;
|
||||
} else {
|
||||
// if we're trimming an out-point
|
||||
ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out;
|
||||
ripple_point = first_ghost.old_out;
|
||||
}
|
||||
QVector<int> ignore_clips;
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
// if we were RIPPLING, move all the clips
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) {
|
||||
long ripple_length, ripple_point;
|
||||
|
||||
// push rippled clips forward if necessary
|
||||
if (panel_timeline->trim_in_point) {
|
||||
ignore_clips.append(g.clip);
|
||||
panel_timeline->ghosts[i].in += ripple_length;
|
||||
panel_timeline->ghosts[i].out += ripple_length;
|
||||
}
|
||||
|
||||
long comp_point = panel_timeline->trim_in_point ? g.old_in : g.old_out;
|
||||
ripple_point = qMin(ripple_point, comp_point);
|
||||
}
|
||||
if (!panel_timeline->trim_in_point) ripple_length = -ripple_length;
|
||||
ta->ripple(sequence, ripple_point, ripple_length, ignore_clips);
|
||||
// ripple_length becomes the length/number of frames we trimmed
|
||||
// ripple point becomes the point to ripple (i.e. the point after or before which we move every clip)
|
||||
if (panel_timeline->trim_in_point) {
|
||||
ripple_length = first_ghost.old_in - panel_timeline->ghosts.at(0).in;
|
||||
ripple_point = first_ghost.old_in;
|
||||
} else {
|
||||
// if we're trimming an out-point
|
||||
ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out;
|
||||
ripple_point = first_ghost.old_out;
|
||||
}
|
||||
QVector<int> ignore_clips;
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER
|
||||
&& (event->modifiers() & Qt::AltModifier)
|
||||
&& panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move
|
||||
// duplicate clips
|
||||
QVector<int> old_clips;
|
||||
QVector<Clip*> new_clips;
|
||||
// push rippled clips forward if necessary
|
||||
if (panel_timeline->trim_in_point) {
|
||||
ignore_clips.append(g.clip);
|
||||
panel_timeline->ghosts[i].in += ripple_length;
|
||||
panel_timeline->ghosts[i].out += ripple_length;
|
||||
}
|
||||
|
||||
long comp_point = panel_timeline->trim_in_point ? g.old_in : g.old_out;
|
||||
ripple_point = qMin(ripple_point, comp_point);
|
||||
}
|
||||
if (!panel_timeline->trim_in_point) ripple_length = -ripple_length;
|
||||
ta->ripple(sequence, ripple_point, ripple_length, ignore_clips);
|
||||
}
|
||||
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER
|
||||
&& (event->modifiers() & Qt::AltModifier)
|
||||
&& panel_timeline->trim_target == -1) { // if holding alt (and not trimming), duplicate rather than move
|
||||
// duplicate clips
|
||||
QVector<int> old_clips;
|
||||
QVector<Clip*> new_clips;
|
||||
QVector<Selection> delete_areas;
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) {
|
||||
// create copy of clip
|
||||
Clip* c = sequence->get_clip(g.clip)->copy(sequence);
|
||||
|
||||
c->timeline_in = g.in;
|
||||
c->timeline_out = g.out;
|
||||
c->track = g.track;
|
||||
|
||||
Selection s;
|
||||
s.in = g.in;
|
||||
s.out = g.out;
|
||||
s.track = g.track;
|
||||
delete_areas.append(s);
|
||||
|
||||
old_clips.append(g.clip);
|
||||
new_clips.append(c);
|
||||
}
|
||||
}
|
||||
if (new_clips.size() > 0) {
|
||||
panel_timeline->delete_areas_and_relink(ta, delete_areas);
|
||||
|
||||
// relink duplicated clips
|
||||
panel_timeline->relink_clips_using_ids(old_clips, new_clips);
|
||||
|
||||
for (int i=0;i<new_clips.size();i++) {
|
||||
ta->add_clips(sequence, new_clips);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// move clips
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
|
||||
QVector<Selection> delete_areas;
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
// step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them)
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) {
|
||||
// create copy of clip
|
||||
Clip* c = sequence->get_clip(g.clip)->copy(sequence);
|
||||
|
||||
c->timeline_in = g.in;
|
||||
c->timeline_out = g.out;
|
||||
c->track = g.track;
|
||||
sequence->get_clip(g.clip)->undeletable = true;
|
||||
|
||||
Selection s;
|
||||
s.in = g.in;
|
||||
s.out = g.out;
|
||||
s.track = g.track;
|
||||
delete_areas.append(s);
|
||||
|
||||
old_clips.append(g.clip);
|
||||
new_clips.append(c);
|
||||
}
|
||||
}
|
||||
if (new_clips.size() > 0) {
|
||||
panel_timeline->delete_areas_and_relink(ta, delete_areas);
|
||||
|
||||
// relink duplicated clips
|
||||
panel_timeline->relink_clips_using_ids(old_clips, new_clips);
|
||||
|
||||
for (int i=0;i<new_clips.size();i++) {
|
||||
ta->add_clips(sequence, new_clips);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// move clips
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
|
||||
QVector<Selection> delete_areas;
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
// step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them)
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
|
||||
sequence->get_clip(g.clip)->undeletable = true;
|
||||
|
||||
Selection s;
|
||||
s.in = g.in;
|
||||
s.out = g.out;
|
||||
s.track = g.track;
|
||||
delete_areas.append(s);
|
||||
}
|
||||
panel_timeline->delete_areas_and_relink(ta, delete_areas);
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false;
|
||||
}
|
||||
Selection s;
|
||||
s.in = g.in;
|
||||
s.out = g.out;
|
||||
s.track = g.track;
|
||||
delete_areas.append(s);
|
||||
}
|
||||
panel_timeline->delete_areas_and_relink(ta, delete_areas);
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
Ghost& g = panel_timeline->ghosts[i];
|
||||
sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false;
|
||||
}
|
||||
}
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
Ghost& g = panel_timeline->ghosts[i];
|
||||
|
||||
// step 3 - move clips
|
||||
Clip* c = sequence->get_clip(g.clip);
|
||||
if (g.transition == NULL) {
|
||||
ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
|
||||
ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
|
||||
ta->increase_track(sequence, g.clip, g.track - g.old_track);
|
||||
ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
|
||||
// step 3 - move clips
|
||||
Clip* c = sequence->get_clip(g.clip);
|
||||
if (g.transition == NULL) {
|
||||
ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
|
||||
ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
|
||||
ta->increase_track(sequence, g.clip, g.track - g.old_track);
|
||||
ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
|
||||
|
||||
// adjust transitions if we need to
|
||||
long new_clip_length = (g.out - g.in);
|
||||
if (c->opening_transition != NULL) {
|
||||
long max_open_length = new_clip_length;
|
||||
if (c->closing_transition != NULL && !panel_timeline->trim_in_point) {
|
||||
max_open_length -= c->closing_transition->length;
|
||||
}
|
||||
if (max_open_length <= 0) {
|
||||
ta->delete_transition(sequence, g.clip, TA_OPENING_TRANSITION);
|
||||
} else if (c->opening_transition->length > max_open_length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_OPENING_TRANSITION, max_open_length);
|
||||
}
|
||||
// adjust transitions if we need to
|
||||
long new_clip_length = (g.out - g.in);
|
||||
if (c->opening_transition != NULL) {
|
||||
long max_open_length = new_clip_length;
|
||||
if (c->closing_transition != NULL && !panel_timeline->trim_in_point) {
|
||||
max_open_length -= c->closing_transition->length;
|
||||
}
|
||||
if (max_open_length <= 0) {
|
||||
ta->delete_transition(sequence, g.clip, TA_OPENING_TRANSITION);
|
||||
} else if (c->opening_transition->length > max_open_length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_OPENING_TRANSITION, max_open_length);
|
||||
}
|
||||
}
|
||||
if (c->closing_transition != NULL) {
|
||||
long max_open_length = new_clip_length;
|
||||
if (c->opening_transition != NULL && panel_timeline->trim_in_point) {
|
||||
max_open_length -= c->opening_transition->length;
|
||||
}
|
||||
if (max_open_length <= 0) {
|
||||
ta->delete_transition(sequence, g.clip, TA_CLOSING_TRANSITION);
|
||||
} else if (c->closing_transition->length > max_open_length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_CLOSING_TRANSITION, max_open_length);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool is_opening_transition = (g.transition == c->opening_transition);
|
||||
long new_transition_length = g.out - g.in;
|
||||
ta->modify_transition(
|
||||
sequence,
|
||||
g.clip,
|
||||
is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION,
|
||||
new_transition_length
|
||||
);
|
||||
|
||||
long clip_length = c->getLength();
|
||||
if (is_opening_transition) {
|
||||
if (g.in != g.old_in) {
|
||||
// if transition is going to make the clip bigger, make the clip bigger
|
||||
ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
|
||||
clip_length -= (g.in - g.old_in);
|
||||
ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
|
||||
}
|
||||
|
||||
if (c->closing_transition != NULL) {
|
||||
long max_open_length = new_clip_length;
|
||||
if (c->opening_transition != NULL && panel_timeline->trim_in_point) {
|
||||
max_open_length -= c->opening_transition->length;
|
||||
}
|
||||
if (max_open_length <= 0) {
|
||||
if (new_transition_length == clip_length) {
|
||||
ta->delete_transition(sequence, g.clip, TA_CLOSING_TRANSITION);
|
||||
} else if (c->closing_transition->length > max_open_length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_CLOSING_TRANSITION, max_open_length);
|
||||
} else if (new_transition_length > clip_length - c->closing_transition->length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_CLOSING_TRANSITION, clip_length - new_transition_length);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool is_opening_transition = (g.transition == c->opening_transition);
|
||||
long new_transition_length = g.out - g.in;
|
||||
ta->modify_transition(
|
||||
sequence,
|
||||
g.clip,
|
||||
is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION,
|
||||
new_transition_length
|
||||
);
|
||||
if (g.out != g.old_out) {
|
||||
// if transition is going to make the clip bigger, make the clip bigger
|
||||
ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
|
||||
clip_length += (g.out - g.old_out);
|
||||
}
|
||||
|
||||
long clip_length = c->getLength();
|
||||
if (is_opening_transition) {
|
||||
if (g.in != g.old_in) {
|
||||
// if transition is going to make the clip bigger, make the clip bigger
|
||||
ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in);
|
||||
clip_length -= (g.in - g.old_in);
|
||||
ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in);
|
||||
}
|
||||
|
||||
if (c->closing_transition != NULL) {
|
||||
if (new_transition_length == clip_length) {
|
||||
ta->delete_transition(sequence, g.clip, TA_CLOSING_TRANSITION);
|
||||
} else if (new_transition_length > clip_length - c->closing_transition->length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_CLOSING_TRANSITION, clip_length - new_transition_length);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (g.out != g.old_out) {
|
||||
// if transition is going to make the clip bigger, make the clip bigger
|
||||
ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out);
|
||||
clip_length += (g.out - g.old_out);
|
||||
}
|
||||
|
||||
if (c->opening_transition != NULL) {
|
||||
if (new_transition_length == clip_length) {
|
||||
ta->delete_transition(sequence, g.clip, TA_OPENING_TRANSITION);
|
||||
} else if (new_transition_length > clip_length - c->opening_transition->length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_OPENING_TRANSITION, clip_length - new_transition_length);
|
||||
}
|
||||
if (c->opening_transition != NULL) {
|
||||
if (new_transition_length == clip_length) {
|
||||
ta->delete_transition(sequence, g.clip, TA_OPENING_TRANSITION);
|
||||
} else if (new_transition_length > clip_length - c->opening_transition->length) {
|
||||
ta->modify_transition(sequence, g.clip, TA_OPENING_TRANSITION, clip_length - new_transition_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
undo_stack.push(ta);
|
||||
|
||||
panel_timeline->redraw_all_clips(true);
|
||||
repaint = false;
|
||||
}
|
||||
|
||||
undo_stack.push(ta);
|
||||
|
||||
panel_timeline->redraw_all_clips(true);
|
||||
repaint = false;
|
||||
}
|
||||
} else if (panel_timeline->selecting || panel_timeline->rect_select_proc) {
|
||||
repaint = true;
|
||||
|
||||
Reference in New Issue
Block a user