Blender V4.5
strip_add.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 * SPDX-FileCopyrightText: 2003-2009 Blender Authors
3 * SPDX-FileCopyrightText: 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later */
6
10
11#include <algorithm>
12#include <cmath>
13#include <cstring>
14
15#include "BLI_math_base.hh"
16#include "MEM_guardedalloc.h"
17
18#include "DNA_mask_types.h"
19#include "DNA_scene_types.h"
20#include "DNA_sequence_types.h"
21#include "DNA_sound_types.h"
22
23#include "BLI_listbase.h"
24#include "BLI_path_utils.hh"
25#include "BLI_string.h"
26
27#include "BKE_image.hh"
28#include "BKE_lib_id.hh"
29#include "BKE_main.hh"
30#include "BKE_mask.h"
31#include "BKE_movieclip.h"
32#include "BKE_scene.hh"
33#include "BKE_sound.h"
34
36
38#include "IMB_imbuf.hh"
39#include "IMB_imbuf_types.hh"
40#include "IMB_metadata.hh"
41
42#include "MOV_read.hh"
43
44#include "SEQ_add.hh"
45#include "SEQ_edit.hh"
46#include "SEQ_effects.hh"
47#include "SEQ_relations.hh"
48#include "SEQ_render.hh"
49#include "SEQ_sequencer.hh"
50#include "SEQ_time.hh"
51#include "SEQ_transform.hh"
52#include "SEQ_utils.hh"
53
54#include "multiview.hh"
55#include "proxy.hh"
56#include "sequencer.hh"
57#include "strip_time.hh"
58
59namespace blender::seq {
60
62 const char *name,
63 const char *path,
64 const int start_frame,
65 const int channel)
66{
67 memset(load_data, 0, sizeof(LoadData));
68 if (name != nullptr) {
69 STRNCPY(load_data->name, name);
70 }
71 if (path != nullptr) {
72 STRNCPY(load_data->path, path);
73 }
74 load_data->start_frame = start_frame;
75 load_data->channel = channel;
76}
77
78static void strip_add_generic_update(Scene *scene, Strip *strip)
79{
80 strip_unique_name_set(scene, &scene->ed->seqbase, strip);
81 /* Set effect time range values before cache invalidation. */
82 strip_time_effect_range_set(scene, strip);
83 relations_invalidate_cache(scene, strip);
86}
87
88static void strip_add_set_name(Scene *scene, Strip *strip, LoadData *load_data)
89{
90 if (load_data->name[0] != '\0') {
91 edit_strip_name_set(scene, strip, load_data->name);
92 }
93 else {
94 if (strip->type == STRIP_TYPE_SCENE) {
95 edit_strip_name_set(scene, strip, load_data->scene->id.name + 2);
96 }
97 else if (strip->type == STRIP_TYPE_MOVIECLIP) {
98 edit_strip_name_set(scene, strip, load_data->clip->id.name + 2);
99 }
100 else if (strip->type == STRIP_TYPE_MASK) {
101 edit_strip_name_set(scene, strip, load_data->mask->id.name + 2);
102 }
103 else if ((strip->type & STRIP_TYPE_EFFECT) != 0) {
104 edit_strip_name_set(scene, strip, strip_give_name(strip));
105 }
106 else { /* Image, sound and movie. */
107 edit_strip_name_set(scene, strip, load_data->name);
108 }
109 }
110}
111
112static void strip_add_set_view_transform(Scene *scene, Strip *strip, LoadData *load_data)
113{
114 const char *strip_colorspace = strip->data->colorspace_settings.name;
115
116 if (load_data->flags & SEQ_LOAD_SET_VIEW_TRANSFORM) {
117 const char *role_colorspace_byte;
119
120 if (STREQ(strip_colorspace, role_colorspace_byte)) {
123 const char *default_view_transform =
125 STRNCPY(scene->view_settings.view_transform, default_view_transform);
126 }
127 }
128}
129
130Strip *add_scene_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
131{
132 Strip *strip = strip_alloc(
133 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_SCENE);
134 strip->scene = load_data->scene;
135 strip->len = load_data->scene->r.efra - load_data->scene->r.sfra + 1;
136 id_us_ensure_real((ID *)load_data->scene);
137 strip_add_set_name(scene, strip, load_data);
138 strip_add_generic_update(scene, strip);
139 return strip;
140}
141
142Strip *add_movieclip_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
143{
144 Strip *strip = strip_alloc(
145 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_MOVIECLIP);
146 strip->clip = load_data->clip;
147 strip->len = BKE_movieclip_get_duration(load_data->clip);
148 id_us_ensure_real((ID *)load_data->clip);
149 strip_add_set_name(scene, strip, load_data);
150 strip_add_generic_update(scene, strip);
151 return strip;
152}
153
154Strip *add_mask_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
155{
156 Strip *strip = strip_alloc(seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_MASK);
157 strip->mask = load_data->mask;
158 strip->len = BKE_mask_get_duration(load_data->mask);
159 id_us_ensure_real((ID *)load_data->mask);
160 strip_add_set_name(scene, strip, load_data);
161 strip_add_generic_update(scene, strip);
162 return strip;
163}
164
165Strip *add_effect_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
166{
167 Strip *strip = strip_alloc(
168 seqbase, load_data->start_frame, load_data->channel, load_data->effect.type);
169
172 sh.init(strip);
173
174 if (seq::effect_get_num_inputs(strip->type) != 0) {
175 strip->input1 = load_data->effect.input1;
176 strip->input2 = load_data->effect.input2;
177 }
178
179 if (effect_get_num_inputs(strip->type) == 1) {
180 strip->blend_mode = strip->input1->blend_mode;
181 strip->blend_opacity = strip->input1->blend_opacity;
182 }
183
184 if (strip->input1 == nullptr) {
185 strip->len = 1; /* Effect is generator, set non zero length. */
187 time_right_handle_frame_set(scene, strip, load_data->effect.end_frame);
188 }
189
190 strip_add_set_name(scene, strip, load_data);
191 strip_add_generic_update(scene, strip);
192
193 return strip;
194}
195
196void add_image_set_directory(Strip *strip, const char *dirpath)
197{
198 STRNCPY(strip->data->dirpath, dirpath);
199}
200
201void add_image_load_file(Scene *scene, Strip *strip, size_t strip_frame, const char *filename)
202{
203 StripElem *se = render_give_stripelem(scene, strip, time_start_frame_get(strip) + strip_frame);
204 STRNCPY(se->filename, filename);
205}
206
208{
209 if (strip->data && strip->data->stripdata) {
210 char filepath[FILE_MAX];
211 ImBuf *ibuf;
212
214 filepath, sizeof(filepath), strip->data->dirpath, strip->data->stripdata->filename);
216
217 /* Initialize input color space. */
218 if (strip->type == STRIP_TYPE_IMAGE) {
219 ibuf = IMB_load_image_from_filepath(filepath,
222
223 /* Byte images are default to straight alpha, however sequencer
224 * works in premul space, so mark strip to be premultiplied first.
225 */
227 if (ibuf) {
228 if (ibuf->flags & IB_alphamode_premul) {
230 }
231
232 IMB_freeImBuf(ibuf);
233 }
234 }
235 }
236}
237
238Strip *add_image_strip(Main *bmain, Scene *scene, ListBase *seqbase, LoadData *load_data)
239{
240 Strip *strip = strip_alloc(
241 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_IMAGE);
242 strip->len = load_data->image.len;
243 StripData *data = strip->data;
244 data->stripdata = MEM_calloc_arrayN<StripElem>(load_data->image.len, "stripelem");
245
246 if (strip->len == 1) {
248 }
249
250 /* Multiview settings. */
251 if (load_data->use_multiview) {
252 strip->flag |= SEQ_USE_VIEWS;
253 strip->views_format = load_data->views_format;
254 }
255 if (load_data->stereo3d_format) {
256 strip->stereo3d_format = load_data->stereo3d_format;
257 }
258
259 /* Set initial scale based on load_data->fit_method. */
260 char file_path[FILE_MAX];
261 STRNCPY(file_path, load_data->path);
262 BLI_path_abs(file_path, BKE_main_blendfile_path(bmain));
265 if (ibuf != nullptr) {
266 /* Set image resolution. Assume that all images in sequence are same size. This fields are only
267 * informative. */
268 StripElem *strip_elem = data->stripdata;
269 for (int i = 0; i < load_data->image.len; i++) {
270 strip_elem->orig_width = ibuf->x;
271 strip_elem->orig_height = ibuf->y;
272 strip_elem++;
273 }
274
275 set_scale_to_fit(strip, ibuf->x, ibuf->y, scene->r.xsch, scene->r.ysch, load_data->fit_method);
276 IMB_freeImBuf(ibuf);
277 }
278
279 /* Set Last active directory. */
280 STRNCPY(scene->ed->act_imagedir, strip->data->dirpath);
281 strip_add_set_view_transform(scene, strip, load_data);
282 strip_add_set_name(scene, strip, load_data);
283 strip_add_generic_update(scene, strip);
284
285 return strip;
286}
287
288#ifdef WITH_AUDASPACE
289
290void add_sound_av_sync(Main *bmain, Scene *scene, Strip *strip, LoadData *load_data)
291{
292 SoundStreamInfo sound_stream;
293 if (!BKE_sound_stream_info_get(bmain, load_data->path, 0, &sound_stream)) {
294 return;
295 }
296
297 const double av_stream_offset = sound_stream.start - load_data->r_video_stream_start;
298 const int frame_offset = av_stream_offset * FPS;
299 /* Set sub-frame offset. */
300 strip->sound->offset_time = (double(frame_offset) / FPS) - av_stream_offset;
301 transform_translate_strip(scene, strip, frame_offset);
302}
303
304Strip *add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, LoadData *load_data)
305{
306 bSound *sound = BKE_sound_new_file(bmain, load_data->path); /* Handles relative paths. */
307 SoundInfo info;
308 bool sound_loaded = BKE_sound_info_get(bmain, sound, &info);
309
310 if (!sound_loaded && !load_data->allow_invalid_file) {
311 BKE_id_free(bmain, sound);
312 return nullptr;
313 }
314
315 if (info.specs.channels == SOUND_CHANNELS_INVALID && !load_data->allow_invalid_file) {
316 BKE_id_free(bmain, sound);
317 return nullptr;
318 }
319
320 Strip *strip = strip_alloc(
321 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_SOUND_RAM);
322 strip->sound = sound;
323 strip->scene_sound = nullptr;
324
325 /* We round the frame duration as the audio sample lengths usually does not
326 * line up with the video frames. Therefore we round this number to the
327 * nearest frame as the audio track usually overshoots or undershoots the
328 * end frame of the video by a little bit.
329 * See #47135 for under shoot example. */
330 strip->len = std::max(1, int(round((info.length - sound->offset_time) * FPS)));
331
332 StripData *data = strip->data;
333 /* We only need 1 element to store the filename. */
334 StripElem *se = data->stripdata = MEM_callocN<StripElem>("stripelem");
336 load_data->path, data->dirpath, sizeof(data->dirpath), se->filename, sizeof(se->filename));
337
338 if (strip->sound != nullptr) {
339 if (load_data->flags & SEQ_LOAD_SOUND_MONO) {
340 strip->sound->flags |= SOUND_FLAGS_MONO;
341 }
342
343 if (load_data->flags & SEQ_LOAD_SOUND_CACHE) {
344 if (strip->sound) {
346 }
347 }
348
349 /* Turn on Display Waveform by default. */
351 }
352
353 /* Set Last active directory. */
354 BLI_strncpy(scene->ed->act_sounddir, data->dirpath, FILE_MAXDIR);
355 strip_add_set_name(scene, strip, load_data);
356 strip_add_generic_update(scene, strip);
357
358 return strip;
359}
360
361#else // WITH_AUDASPACE
362
363void add_sound_av_sync(Main * /*bmain*/,
364 Scene * /*scene*/,
365 Strip * /*strip*/,
366 LoadData * /*load_data*/)
367{
368}
369
371 Scene * /*scene*/,
372 ListBase * /*seqbase*/,
373 LoadData * /*load_data*/)
374{
375 return nullptr;
376}
377#endif // WITH_AUDASPACE
378
379Strip *add_meta_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
380{
381 /* Allocate strip. */
382 Strip *strip_meta = strip_alloc(
383 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_META);
384
385 /* Set name. */
386 strip_add_set_name(scene, strip_meta, load_data);
387
388 /* Set frames start and length. */
389 strip_meta->start = load_data->start_frame;
390 strip_meta->len = 1;
391
392 strip_add_generic_update(scene, strip_meta);
393
394 return strip_meta;
395}
396
397Strip *add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, LoadData *load_data)
398{
399 char filepath[sizeof(load_data->path)];
400 STRNCPY(filepath, load_data->path);
401 BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
402
403 char colorspace[64] = "\0"; /* MAX_COLORSPACE_NAME */
404 bool is_multiview_loaded = false;
405 const int totfiles = seq_num_files(scene, load_data->views_format, load_data->use_multiview);
406 MovieReader **anim_arr = MEM_calloc_arrayN<MovieReader *>(totfiles, "Video files");
407 int i;
408 int orig_width = 0;
409 int orig_height = 0;
410
411 if (load_data->use_multiview && (load_data->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
412 char prefix[FILE_MAX];
413 const char *ext = nullptr;
414 size_t j = 0;
415
416 BKE_scene_multiview_view_prefix_get(scene, filepath, prefix, &ext);
417
418 if (prefix[0] != '\0') {
419 for (i = 0; i < totfiles; i++) {
420 char filepath_view[FILE_MAX];
421
422 seq_multiview_name(scene, i, prefix, ext, filepath_view, sizeof(filepath_view));
423 anim_arr[j] = openanim(filepath_view, IB_byte_data, 0, colorspace);
424
425 if (anim_arr[j]) {
426 seq_anim_add_suffix(scene, anim_arr[j], i);
427 j++;
428 }
429 }
430 is_multiview_loaded = true;
431 }
432 }
433
434 if (is_multiview_loaded == false) {
435 anim_arr[0] = openanim(filepath, IB_byte_data, 0, colorspace);
436 }
437
438 if (anim_arr[0] == nullptr && !load_data->allow_invalid_file) {
439 MEM_freeN(anim_arr);
440 return nullptr;
441 }
442
443 float video_fps = 0.0f;
444 load_data->r_video_stream_start = 0.0;
445
446 if (anim_arr[0] != nullptr) {
447 short fps_num;
448 float fps_denom;
449 bool have_fps = MOV_get_fps_num_denom(anim_arr[0], fps_num, fps_denom);
450 if (have_fps) {
451 video_fps = fps_num / fps_denom;
452 }
453
454 /* Adjust scene's frame rate settings to match. */
455 if (have_fps && (load_data->flags & SEQ_LOAD_MOVIE_SYNC_FPS)) {
456 scene->r.frs_sec = fps_num;
457 scene->r.frs_sec_base = fps_denom;
459 }
460
461 load_data->r_video_stream_start = MOV_get_start_offset_seconds(anim_arr[0]);
462 }
463
464 Strip *strip = strip_alloc(
465 seqbase, load_data->start_frame, load_data->channel, STRIP_TYPE_MOVIE);
466
467 /* Multiview settings. */
468 if (load_data->use_multiview) {
469 strip->flag |= SEQ_USE_VIEWS;
470 strip->views_format = load_data->views_format;
471 }
472 if (load_data->stereo3d_format) {
473 strip->stereo3d_format = load_data->stereo3d_format;
474 }
475
476 for (i = 0; i < totfiles; i++) {
477 if (anim_arr[i]) {
478 StripAnim *sanim = MEM_mallocN<StripAnim>("Strip Anim");
479 BLI_addtail(&strip->anims, sanim);
480 sanim->anim = anim_arr[i];
481 }
482 else {
483 break;
484 }
485 }
486
487 if (anim_arr[0] != nullptr) {
488 strip->len = MOV_get_duration_frames(anim_arr[0], IMB_TC_RECORD_RUN);
489
490 MOV_load_metadata(anim_arr[0]);
491
492 /* Set initial scale based on load_data->fit_method. */
493 orig_width = MOV_get_image_width(anim_arr[0]);
494 orig_height = MOV_get_image_height(anim_arr[0]);
496 strip, orig_width, orig_height, scene->r.xsch, scene->r.ysch, load_data->fit_method);
497
498 float fps = MOV_get_fps(anim_arr[0]);
499 if (fps > 0.0f) {
500 strip->media_playback_rate = fps;
501 }
502 }
503
504 strip->len = std::max(1, strip->len);
505 if (load_data->adjust_playback_rate) {
507 }
508
509 STRNCPY(strip->data->colorspace_settings.name, colorspace);
510
511 StripData *data = strip->data;
512 /* We only need 1 element for MOVIE strips. */
513 StripElem *se;
514 data->stripdata = se = MEM_callocN<StripElem>("stripelem");
515 data->stripdata->orig_width = orig_width;
516 data->stripdata->orig_height = orig_height;
517 data->stripdata->orig_fps = video_fps;
519 load_data->path, data->dirpath, sizeof(data->dirpath), se->filename, sizeof(se->filename));
520
521 strip_add_set_view_transform(scene, strip, load_data);
522 strip_add_set_name(scene, strip, load_data);
523 strip_add_generic_update(scene, strip);
524
525 MEM_freeN(anim_arr);
526 return strip;
527}
528
529void add_reload_new_file(Main *bmain, Scene *scene, Strip *strip, const bool lock_range)
530{
531 int prev_startdisp = 0, prev_enddisp = 0;
532 /* NOTE: don't rename the strip, will break animation curves. */
533
534 if (ELEM(strip->type,
541 STRIP_TYPE_MASK) == 0)
542 {
543 return;
544 }
545
546 if (lock_range) {
547 /* keep so we don't have to move the actual start and end points (only the data) */
548 prev_startdisp = time_left_handle_frame_get(scene, strip);
549 prev_enddisp = time_right_handle_frame_get(scene, strip);
550 }
551
552 switch (strip->type) {
553 case STRIP_TYPE_IMAGE: {
554 /* Hack? */
555 size_t olen = MEM_allocN_len(strip->data->stripdata) / sizeof(StripElem);
556
557 strip->len = olen;
558 strip->len -= strip->anim_startofs;
559 strip->len -= strip->anim_endofs;
560 strip->len = std::max(strip->len, 0);
561 break;
562 }
563 case STRIP_TYPE_MOVIE: {
564 char filepath[FILE_MAX];
565 StripAnim *sanim;
566 bool is_multiview_loaded = false;
567 const bool is_multiview = (strip->flag & SEQ_USE_VIEWS) != 0 &&
568 (scene->r.scemode & R_MULTIVIEW) != 0;
569
571 filepath, sizeof(filepath), strip->data->dirpath, strip->data->stripdata->filename);
573
575
576 if (is_multiview && (strip->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
577 char prefix[FILE_MAX];
578 const char *ext = nullptr;
579 const int totfiles = seq_num_files(scene, strip->views_format, true);
580 int i = 0;
581
582 BKE_scene_multiview_view_prefix_get(scene, filepath, prefix, &ext);
583
584 if (prefix[0] != '\0') {
585 for (i = 0; i < totfiles; i++) {
586 MovieReader *anim;
587 char filepath_view[FILE_MAX];
588
589 seq_multiview_name(scene, i, prefix, ext, filepath_view, sizeof(filepath_view));
590 anim = openanim(filepath_view,
591 IB_byte_data | ((strip->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
592 strip->streamindex,
594
595 if (anim) {
596 seq_anim_add_suffix(scene, anim, i);
597 sanim = MEM_mallocN<StripAnim>("Strip Anim");
598 BLI_addtail(&strip->anims, sanim);
599 sanim->anim = anim;
600 }
601 }
602 is_multiview_loaded = true;
603 }
604 }
605
606 if (is_multiview_loaded == false) {
607 MovieReader *anim;
608 anim = openanim(filepath,
609 IB_byte_data | ((strip->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
610 strip->streamindex,
612 if (anim) {
613 sanim = MEM_mallocN<StripAnim>("Strip Anim");
614 BLI_addtail(&strip->anims, sanim);
615 sanim->anim = anim;
616 }
617 }
618
619 /* use the first video as reference for everything */
620 sanim = static_cast<StripAnim *>(strip->anims.first);
621
622 if ((!sanim) || (!sanim->anim)) {
623 return;
624 }
625
626 MOV_load_metadata(sanim->anim);
627
629 sanim->anim,
632
633 strip->len -= strip->anim_startofs;
634 strip->len -= strip->anim_endofs;
635 strip->len = std::max(strip->len, 0);
636 break;
637 }
639 if (strip->clip == nullptr) {
640 return;
641 }
642
643 strip->len = BKE_movieclip_get_duration(strip->clip);
644
645 strip->len -= strip->anim_startofs;
646 strip->len -= strip->anim_endofs;
647 strip->len = std::max(strip->len, 0);
648 break;
649 case STRIP_TYPE_MASK:
650 if (strip->mask == nullptr) {
651 return;
652 }
653 strip->len = BKE_mask_get_duration(strip->mask);
654 strip->len -= strip->anim_startofs;
655 strip->len -= strip->anim_endofs;
656 strip->len = std::max(strip->len, 0);
657 break;
659#ifdef WITH_AUDASPACE
660 if (!strip->sound) {
661 return;
662 }
663 strip->len = ceil(double(BKE_sound_get_length(bmain, strip->sound)) * FPS);
664 strip->len -= strip->anim_startofs;
665 strip->len -= strip->anim_endofs;
666 strip->len = std::max(strip->len, 0);
667#else
668 UNUSED_VARS(bmain);
669 return;
670#endif
671 break;
672 case STRIP_TYPE_SCENE: {
673 strip->len = (strip->scene) ? strip->scene->r.efra - strip->scene->r.sfra + 1 : 0;
674 strip->len -= strip->anim_startofs;
675 strip->len -= strip->anim_endofs;
676 strip->len = std::max(strip->len, 0);
677 break;
678 }
679 }
680
681 free_strip_proxy(strip);
682
683 if (lock_range) {
684 time_left_handle_frame_set(scene, strip, prev_startdisp);
685 time_right_handle_frame_set(scene, strip, prev_enddisp);
686 }
687
688 relations_invalidate_cache_raw(scene, strip);
689}
690
692 Main *bmain, Scene *scene, Strip *strip, bool *r_was_reloaded, bool *r_can_produce_frames)
693{
695 "This function is only implemented for movie strips.");
696
697 bool must_reload = false;
698
699 /* The Sequence struct allows for multiple anim structs to be associated with one strip.
700 * This function will return true only if there is at least one 'anim' AND all anims can
701 * produce frames. */
702
703 if (BLI_listbase_is_empty(&strip->anims)) {
704 /* No anim present, so reloading is always necessary. */
705 must_reload = true;
706 }
707 else {
708 LISTBASE_FOREACH (StripAnim *, sanim, &strip->anims) {
709 if (!MOV_is_initialized_and_valid(sanim->anim)) {
710 /* Anim cannot produce frames, try reloading. */
711 must_reload = true;
712 break;
713 }
714 };
715 }
716
717 if (!must_reload) {
718 /* There are one or more anims, and all can produce frames. */
719 *r_was_reloaded = false;
720 *r_can_produce_frames = true;
721 return;
722 }
723
724 add_reload_new_file(bmain, scene, strip, true);
725 *r_was_reloaded = true;
726
727 if (BLI_listbase_is_empty(&strip->anims)) {
728 /* No anims present after reloading => no frames can be produced. */
729 *r_can_produce_frames = false;
730 return;
731 }
732
733 /* Check if there are still anims that cannot produce frames. */
734 LISTBASE_FOREACH (StripAnim *, sanim, &strip->anims) {
735 if (!MOV_is_initialized_and_valid(sanim->anim)) {
736 /* There still is an anim that cannot produce frames. */
737 *r_can_produce_frames = false;
738 return;
739 }
740 };
741
742 /* There are one or more anims, and all can produce frames. */
743 *r_can_produce_frames = true;
744}
745
746} // namespace blender::seq
MovieReader * openanim(const char *filepath, int flags, int streamindex, char colorspace[IMA_MAX_SPACE])
void BKE_id_free(Main *bmain, void *idv)
void id_us_ensure_real(ID *id)
Definition lib_id.cc:308
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:872
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:877
int BKE_mask_get_duration(struct Mask *mask)
int BKE_movieclip_get_duration(struct MovieClip *clip)
void BKE_scene_multiview_view_prefix_get(Scene *scene, const char *filepath, char *r_prefix, const char **r_ext)
Definition scene.cc:3176
float BKE_sound_get_length(struct Main *bmain, struct bSound *sound)
bool BKE_sound_info_get(struct Main *main, struct bSound *sound, SoundInfo *sound_info)
struct bSound * BKE_sound_new_file(struct Main *bmain, const char *filepath)
struct SoundInfo SoundInfo
bool BKE_sound_stream_info_get(struct Main *main, const char *filepath, int stream, SoundStreamInfo *sound_info)
@ SOUND_CHANNELS_INVALID
Definition BKE_sound.h:63
blender::ocio::Display ColorManagedDisplay
Definition BLF_api.hh:35
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define FILE_MAX
#define BLI_path_join(...)
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
#define FILE_MAXDIR
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define UNUSED_VARS(...)
#define ELEM(...)
#define STREQ(a, b)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1035
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1030
@ IMA_ALPHA_PREMUL
struct ListBase ListBase
struct Scene Scene
@ R_IMF_VIEWS_INDIVIDUAL
#define FPS
@ R_MULTIVIEW
@ SEQ_ALPHA_STRAIGHT
struct StripData StripData
@ STRIP_TYPE_SCENE
@ STRIP_TYPE_MOVIECLIP
@ STRIP_TYPE_SOUND_RAM
@ STRIP_TYPE_IMAGE
@ STRIP_TYPE_MOVIE
@ STRIP_TYPE_EFFECT
@ STRIP_TYPE_META
@ STRIP_TYPE_MASK
struct StripElem StripElem
struct Strip Strip
@ SEQ_FILTERY
@ SEQ_SINGLE_FRAME_CONTENT
@ SEQ_AUTO_PLAYBACK_RATE
@ SEQ_USE_EFFECT_DEFAULT_FADE
@ SEQ_USE_VIEWS
@ SEQ_AUDIO_DRAW_WAVEFORM
@ SOUND_FLAGS_MONO
@ SOUND_FLAGS_CACHING
struct bSound bSound
@ COLOR_ROLE_DEFAULT_BYTE
const char * IMB_colormanagement_role_colorspace_name_get(int role)
const char * IMB_colormanagement_display_get_default_view_transform_name(const ColorManagedDisplay *display)
const ColorManagedDisplay * IMB_colormanagement_display_get_named(const char *name)
ImBuf * IMB_load_image_from_filepath(const char *filepath, const int flags, char r_colorspace[IM_MAX_SPACE]=nullptr)
Definition readimage.cc:204
void IMB_freeImBuf(ImBuf *ibuf)
@ IB_animdeinterlace
@ IB_alphamode_premul
@ IB_byte_data
@ IB_multilayer
@ IB_alphamode_detect
@ IB_test
Read Guarded memory(de)allocation.
IMB_Timecode_Type
Definition MOV_enums.hh:44
@ IMB_TC_RECORD_RUN
Definition MOV_enums.hh:54
BMesh const char void * data
#define round
#define ceil
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
double MOV_get_start_offset_seconds(const MovieReader *anim)
int MOV_get_duration_frames(MovieReader *anim, IMB_Timecode_Type tc)
bool MOV_is_initialized_and_valid(const MovieReader *anim)
int MOV_get_image_width(const MovieReader *anim)
float MOV_get_fps(const MovieReader *anim)
IDProperty * MOV_load_metadata(MovieReader *anim)
Definition movie_read.cc:78
bool MOV_get_fps_num_denom(const MovieReader *anim, short &r_fps_num, float &r_fps_denom)
int MOV_get_image_height(const MovieReader *anim)
void relations_strip_free_anim(Strip *strip)
Strip * lookup_meta_by_strip(Editing *ed, const Strip *key)
int time_right_handle_frame_get(const Scene *scene, const Strip *strip)
void add_movie_reload_if_needed(Main *bmain, Scene *scene, Strip *strip, bool *r_was_reloaded, bool *r_can_produce_frames)
Definition strip_add.cc:691
void relations_invalidate_cache(Scene *scene, Strip *strip)
EffectHandle strip_effect_handle_get(Strip *strip)
Definition effects.cc:249
void transform_translate_strip(Scene *evil_scene, Strip *strip, int delta)
void add_image_init_alpha_mode(Strip *strip)
Definition strip_add.cc:207
static void strip_add_generic_update(Scene *scene, Strip *strip)
Definition strip_add.cc:78
Strip * add_effect_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:165
void edit_strip_name_set(Scene *scene, Strip *strip, const char *new_name)
void add_image_load_file(Scene *scene, Strip *strip, size_t strip_frame, const char *filename)
Definition strip_add.cc:201
void add_image_set_directory(Strip *strip, const char *dirpath)
Definition strip_add.cc:196
int time_left_handle_frame_get(const Scene *, const Strip *strip)
Strip * add_sound_strip(Main *, Scene *, ListBase *, LoadData *)
Definition strip_add.cc:370
const char * strip_give_name(const Strip *strip)
void relations_invalidate_cache_raw(Scene *scene, Strip *strip)
void add_sound_av_sync(Main *, Scene *, Strip *, LoadData *)
Definition strip_add.cc:363
static void strip_add_set_view_transform(Scene *scene, Strip *strip, LoadData *load_data)
Definition strip_add.cc:112
float time_start_frame_get(const Strip *strip)
Strip * add_meta_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:379
void add_reload_new_file(Main *bmain, Scene *scene, Strip *strip, const bool lock_range)
Definition strip_add.cc:529
void time_update_meta_strip_range(const Scene *scene, Strip *strip_meta)
Strip * add_scene_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:130
Strip * add_image_strip(Main *bmain, Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:238
Strip * add_movieclip_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:142
void free_strip_proxy(Strip *strip)
Definition proxy.cc:624
void strip_unique_name_set(Scene *scene, ListBase *seqbasep, Strip *strip)
static void strip_add_set_name(Scene *scene, Strip *strip, LoadData *load_data)
Definition strip_add.cc:88
@ SEQ_LOAD_SOUND_MONO
Definition SEQ_add.hh:28
@ SEQ_LOAD_SET_VIEW_TRANSFORM
Definition SEQ_add.hh:30
@ SEQ_LOAD_SOUND_CACHE
Definition SEQ_add.hh:27
@ SEQ_LOAD_MOVIE_SYNC_FPS
Definition SEQ_add.hh:29
Strip * add_mask_strip(Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:154
void time_left_handle_frame_set(const Scene *scene, Strip *strip, int timeline_frame)
void time_right_handle_frame_set(const Scene *scene, Strip *strip, int timeline_frame)
void seq_anim_add_suffix(Scene *scene, MovieReader *anim, const int view_id)
Definition multiview.cc:23
Strip * strip_alloc(ListBase *lb, int timeline_frame, int channel, int type)
Definition sequencer.cc:130
void strip_lookup_invalidate(const Editing *ed)
Strip * add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, LoadData *load_data)
Definition strip_add.cc:397
int seq_num_files(Scene *scene, char views_format, const bool is_multiview)
Definition multiview.cc:29
void add_load_data_init(LoadData *load_data, const char *name, const char *path, const int start_frame, const int channel)
Definition strip_add.cc:61
void set_scale_to_fit(const Strip *strip, const int image_width, const int image_height, const int preview_width, const int preview_height, const eSeqImageFitMethod fit_method)
StripElem * render_give_stripelem(const Scene *scene, const Strip *strip, int timeline_frame)
Definition render.cc:234
void strip_time_effect_range_set(const Scene *scene, Strip *strip)
int effect_get_num_inputs(int strip_type)
Definition effects.cc:286
void seq_multiview_name(Scene *scene, const int view_id, const char *prefix, const char *ext, char *r_path, size_t r_size)
Definition multiview.cc:42
ListBase seqbase
char act_sounddir[1024]
char act_imagedir[1024]
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
void * first
ColorManagedViewSettings view_settings
struct Editing * ed
struct RenderData r
ColorManagedDisplaySettings display_settings
struct SoundInfo::@044326216360345075252245153320322143020002364111 specs
eSoundChannels channels
Definition BKE_sound.h:76
float length
Definition BKE_sound.h:79
struct MovieReader * anim
StripProxy * proxy
StripElem * stripdata
char dirpath[768]
ColorManagedColorspaceSettings colorspace_settings
char filename[256]
struct Stereo3dFormat * stereo3d_format
void * scene_sound
struct Strip * input1
struct Mask * mask
StripData * data
struct Scene * scene
struct MovieClip * clip
struct bSound * sound
float media_playback_rate
short streamindex
float blend_opacity
struct Strip * input2
ListBase anims
short flags
double offset_time
void(* init)(Strip *strip)
eSeqImageFitMethod fit_method
Definition SEQ_add.hh:55
Stereo3dFormat * stereo3d_format
Definition SEQ_add.hh:58
double r_video_stream_start
Definition SEQ_add.hh:60
struct blender::seq::LoadData::@122240022272052120321215271261271275102156175102 effect
struct blender::seq::LoadData::@040370310161133255324147242161304341014322202023 image
i
Definition text_draw.cc:230