Fix T70612: Sequencer Crash on enabling Prefetch

Disable (skip) preftching scene strips if they target 3D scene.
Try to continue prefetching complete frame if disk cache images are found.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7514
This commit is contained in:
Richard Antalik 2020-05-12 22:50:33 +02:00
parent 4930eb15f7
commit be69f23b68
Notes: blender-bot 2023-02-14 08:08:56 +01:00
Referenced by commit f359102589, VSE: Fix incorrect condition for skipping prefetch frames
Referenced by issue #76761, VSE crashes while adding a scene
Referenced by issue #70612, Video Sequencer Crash on enabling Prefetch frames with Scene strips
3 changed files with 75 additions and 3 deletions

View File

@ -277,6 +277,10 @@ void BKE_sequence_reload_new_file(struct Main *bmain,
struct Sequence *seq,
const bool lock_range);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
int cfra,
int chanshown,
struct Sequence **seq_arr_out);
struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);

View File

@ -334,6 +334,66 @@ void BKE_sequencer_prefetch_free(Scene *scene)
scene->ed->prefetch_job = NULL;
}
static bool seq_prefetch_do_skip_frame(Scene *scene)
{
Editing *ed = scene->ed;
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
float cfra = pfjob->cfra + pfjob->num_frames_prefetched;
Sequence *seq_arr[MAXSEQ + 1];
int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
SeqRenderData *ctx = &pfjob->context_cpy;
ImBuf *ibuf = NULL;
/* Disable prefetching 3D scene strips, but check for disk cache. */
for (int i = 0; i < count; i++) {
if (seq_arr[i]->type == SEQ_TYPE_SCENE && (seq_arr[i]->flag & SEQ_SCENE_STRIPS) == 0) {
int cached_types = 0;
ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_FINAL_OUT;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_COMPOSITE;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_PREPROCESSED, false);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_PREPROCESSED;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_RAW, false);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_RAW;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
if ((cached_types & (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED)) != 0) {
continue;
}
/* It is only safe to use these cache types if strip is last in stack. */
if (i == count - 1 &&
(cached_types & (SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_RAW)) != 0) {
continue;
}
return true;
}
}
return false;
}
static void *seq_prefetch_frames(void *job)
{
PrefetchJob *pfjob = (PrefetchJob *)job;
@ -358,6 +418,11 @@ static void *seq_prefetch_frames(void *job)
*/
pfjob->scene_eval->ed->prefetch_job = pfjob;
if (seq_prefetch_do_skip_frame(pfjob->scene)) {
pfjob->num_frames_prefetched++;
continue;
}
ImBuf *ibuf = BKE_sequencer_give_ibuf(
&pfjob->context_cpy, pfjob->cfra + pfjob->num_frames_prefetched, 0);
BKE_sequencer_cache_free_temp_cache(

View File

@ -1538,7 +1538,10 @@ static bool video_seq_is_rendered(Sequence *seq)
return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM);
}
static int get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequence **seq_arr_out)
int BKE_sequencer_get_shown_sequences(ListBase *seqbasep,
int cfra,
int chanshown,
Sequence **seq_arr_out)
{
Sequence *seq_arr[MAXSEQ + 1];
int b = chanshown;
@ -3973,7 +3976,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
ImBuf *out = NULL;
clock_t begin;
count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
if (count == 0) {
return NULL;
@ -4081,7 +4084,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha
Sequence *seq_arr[MAXSEQ + 1];
int count;
count = get_shown_sequences(seqbasep, cfra, chanshown, seq_arr);
count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, seq_arr);
if (count) {
out = BKE_sequencer_cache_get(