Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Antalik <richardantalik@gmail.com>2020-11-16 07:02:30 +0300
committerRichard Antalik <richardantalik@gmail.com>2020-11-16 07:02:30 +0300
commit01db805a82129a27b1408d62417c40b0717228dc (patch)
tree53645581058b7d15db1aab11f684edbd0fb655fc /source/blender/sequencer/intern/strip_time.c
parent52a189936b697164db7349fdc1de017108f0a9eb (diff)
Cleanup: split sequencer.c file
Move most functions into separate files. File sequencer.c is reserved for alloc, free and duplicating functions. There should be no functional changes.
Diffstat (limited to 'source/blender/sequencer/intern/strip_time.c')
-rw-r--r--source/blender/sequencer/intern/strip_time.c353
1 files changed, 353 insertions, 0 deletions
diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c
new file mode 100644
index 00000000000..a0ae6d6f16d
--- /dev/null
+++ b/source/blender/sequencer/intern/strip_time.c
@@ -0,0 +1,353 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * - Blender Foundation, 2003-2009
+ * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "BKE_movieclip.h"
+#include "BKE_scene.h"
+#include "BKE_sound.h"
+
+#include "IMB_imbuf.h"
+
+#include "SEQ_sequencer.h"
+
+#include "strip_time.h"
+#include "utils.h"
+
+float seq_give_frame_index(Sequence *seq, float timeline_frame)
+{
+ float frame_index;
+ int sta = seq->start;
+ int end = seq->start + seq->len - 1;
+
+ if (seq->type & SEQ_TYPE_EFFECT) {
+ end = seq->enddisp;
+ }
+
+ if (end < sta) {
+ return -1;
+ }
+
+ if (seq->flag & SEQ_REVERSE_FRAMES) {
+ /*reverse frame in this sequence */
+ if (timeline_frame <= sta) {
+ frame_index = end - sta;
+ }
+ else if (timeline_frame >= end) {
+ frame_index = 0;
+ }
+ else {
+ frame_index = end - timeline_frame;
+ }
+ }
+ else {
+ if (timeline_frame <= sta) {
+ frame_index = 0;
+ }
+ else if (timeline_frame >= end) {
+ frame_index = end - sta;
+ }
+ else {
+ frame_index = timeline_frame - sta;
+ }
+ }
+
+ if (seq->strobe < 1.0f) {
+ seq->strobe = 1.0f;
+ }
+
+ if (seq->strobe > 1.0f) {
+ frame_index -= fmodf((double)frame_index, (double)seq->strobe);
+ }
+
+ return frame_index;
+}
+
+static int metaseq_start(Sequence *metaseq)
+{
+ return metaseq->start + metaseq->startofs;
+}
+
+static int metaseq_end(Sequence *metaseq)
+{
+ return metaseq->start + metaseq->len - metaseq->endofs;
+}
+
+static void seq_update_sound_bounds_recursive_impl(Scene *scene,
+ Sequence *metaseq,
+ int start,
+ int end)
+{
+ Sequence *seq;
+
+ /* for sound we go over full meta tree to update bounds of the sound strips,
+ * since sound is played outside of evaluating the imbufs, */
+ for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
+ if (seq->type == SEQ_TYPE_META) {
+ seq_update_sound_bounds_recursive_impl(
+ scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq)));
+ }
+ else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
+ if (seq->scene_sound) {
+ int startofs = seq->startofs;
+ int endofs = seq->endofs;
+ if (seq->startofs + seq->start < start) {
+ startofs = start - seq->start;
+ }
+
+ if (seq->start + seq->len - seq->endofs > end) {
+ endofs = seq->start + seq->len - end;
+ }
+
+ BKE_sound_move_scene_sound(scene,
+ seq->scene_sound,
+ seq->start + startofs,
+ seq->start + seq->len - endofs,
+ startofs + seq->anim_startofs);
+ }
+ }
+ }
+}
+
+void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+{
+ seq_update_sound_bounds_recursive_impl(
+ scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
+}
+
+void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
+{
+ if (seq->startofs && seq->startstill) {
+ seq->startstill = 0;
+ }
+ if (seq->endofs && seq->endstill) {
+ seq->endstill = 0;
+ }
+
+ seq->startdisp = seq->start + seq->startofs - seq->startstill;
+ seq->enddisp = seq->start + seq->len - seq->endofs + seq->endstill;
+
+ if (seq->type == SEQ_TYPE_META) {
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+}
+
+void BKE_sequence_calc(Scene *scene, Sequence *seq)
+{
+ Sequence *seqm;
+ int min, max;
+
+ /* check all metas recursively */
+ seqm = seq->seqbase.first;
+ while (seqm) {
+ if (seqm->seqbase.first) {
+ BKE_sequence_calc(scene, seqm);
+ }
+ seqm = seqm->next;
+ }
+
+ /* effects and meta: automatic start and end */
+ if (seq->type & SEQ_TYPE_EFFECT) {
+ if (seq->seq1) {
+ seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
+ if (seq->seq3) {
+ seq->start = seq->startdisp = max_iii(
+ seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
+ seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
+ }
+ else if (seq->seq2) {
+ seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp);
+ seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp);
+ }
+ else {
+ seq->start = seq->startdisp = seq->seq1->startdisp;
+ seq->enddisp = seq->seq1->enddisp;
+ }
+ /* we cant help if strips don't overlap, it wont give useful results.
+ * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
+ if (seq->enddisp < seq->startdisp) {
+ /* simple start/end swap */
+ seq->start = seq->enddisp;
+ seq->enddisp = seq->startdisp;
+ seq->startdisp = seq->start;
+ seq->flag |= SEQ_INVALID_EFFECT;
+ }
+ else {
+ seq->flag &= ~SEQ_INVALID_EFFECT;
+ }
+
+ seq->len = seq->enddisp - seq->startdisp;
+ }
+ else {
+ BKE_sequence_calc_disp(scene, seq);
+ }
+ }
+ else {
+ if (seq->type == SEQ_TYPE_META) {
+ seqm = seq->seqbase.first;
+ if (seqm) {
+ min = MAXFRAME * 2;
+ max = -MAXFRAME * 2;
+ while (seqm) {
+ if (seqm->startdisp < min) {
+ min = seqm->startdisp;
+ }
+ if (seqm->enddisp > max) {
+ max = seqm->enddisp;
+ }
+ seqm = seqm->next;
+ }
+ seq->start = min + seq->anim_startofs;
+ seq->len = max - min;
+ seq->len -= seq->anim_startofs;
+ seq->len -= seq->anim_endofs;
+ }
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+ BKE_sequence_calc_disp(scene, seq);
+ }
+}
+
+/** Comparison function suitable to be used with BLI_listbase_sort()... */
+int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b)
+{
+ const Sequence *seq_a = a;
+ const Sequence *seq_b = b;
+
+ return (seq_a->startdisp > seq_b->startdisp);
+}
+
+int BKE_sequencer_find_next_prev_edit(Scene *scene,
+ int timeline_frame,
+ const short side,
+ const bool do_skip_mute,
+ const bool do_center,
+ const bool do_unselected)
+{
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+
+ int dist, best_dist, best_frame = timeline_frame;
+ int seq_frames[2], seq_frames_tot;
+
+ /* In case where both is passed,
+ * frame just finds the nearest end while frame_left the nearest start. */
+
+ best_dist = MAXFRAME * 2;
+
+ if (ed == NULL) {
+ return timeline_frame;
+ }
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ int i;
+
+ if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
+ continue;
+ }
+
+ if (do_unselected && (seq->flag & SELECT)) {
+ continue;
+ }
+
+ if (do_center) {
+ seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
+ seq_frames_tot = 1;
+ }
+ else {
+ seq_frames[0] = seq->startdisp;
+ seq_frames[1] = seq->enddisp;
+
+ seq_frames_tot = 2;
+ }
+
+ for (i = 0; i < seq_frames_tot; i++) {
+ const int seq_frame = seq_frames[i];
+
+ dist = MAXFRAME * 2;
+
+ switch (side) {
+ case SEQ_SIDE_LEFT:
+ if (seq_frame < timeline_frame) {
+ dist = timeline_frame - seq_frame;
+ }
+ break;
+ case SEQ_SIDE_RIGHT:
+ if (seq_frame > timeline_frame) {
+ dist = seq_frame - timeline_frame;
+ }
+ break;
+ case SEQ_SIDE_BOTH:
+ dist = abs(seq_frame - timeline_frame);
+ break;
+ }
+
+ if (dist < best_dist) {
+ best_frame = seq_frame;
+ best_dist = dist;
+ }
+ }
+ }
+
+ return best_frame;
+}
+
+float BKE_sequence_get_fps(Scene *scene, Sequence *seq)
+{
+ switch (seq->type) {
+ case SEQ_TYPE_MOVIE: {
+ seq_open_anim_file(scene, seq, true);
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ return 0.0f;
+ }
+ StripAnim *strip_anim = seq->anims.first;
+ if (strip_anim->anim == NULL) {
+ return 0.0f;
+ }
+ short frs_sec;
+ float frs_sec_base;
+ if (IMB_anim_get_fps(strip_anim->anim, &frs_sec, &frs_sec_base, true)) {
+ return (float)frs_sec / frs_sec_base;
+ }
+ break;
+ }
+ case SEQ_TYPE_MOVIECLIP:
+ if (seq->clip != NULL) {
+ return BKE_movieclip_get_fps(seq->clip);
+ }
+ break;
+ case SEQ_TYPE_SCENE:
+ if (seq->scene != NULL) {
+ return (float)seq->scene->r.frs_sec / seq->scene->r.frs_sec_base;
+ }
+ break;
+ }
+ return 0.0f;
+}