Cleanup: split sequencer.c file

Move functions closely related to rendering images and proxies into
render.c and proxy.c files. render.h and proxy.h are created for
functions used internally.

There should be no functional changes.
This commit is contained in:
Richard Antalik 2020-11-05 13:33:27 +01:00
parent 7bc7b7da2d
commit 0f43fe7fa6
Notes: blender-bot 2023-02-14 05:16:25 +01:00
Referenced by issue #77580, Sequencer: restructuring the code layout
11 changed files with 3208 additions and 3004 deletions

View File

@ -48,6 +48,10 @@ set(SRC
intern/effects.c
intern/modifier.c
intern/prefetch.c
intern/proxy.c
intern/proxy.h
intern/render.c
intern/render.h
)
set(LIB

View File

@ -108,7 +108,7 @@ void BKE_sequence_iterator_next(SeqIterator *iter);
void BKE_sequence_iterator_end(SeqIterator *iter);
/* **********************************************************************
* sequencer.c
* render.c
*
* Sequencer render functions
* **********************************************************************
@ -146,7 +146,6 @@ struct ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra,
struct ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context,
float cfra,
struct Sequence *seq);
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequence_init_colorspace(struct Sequence *seq);
void BKE_sequencer_new_render_data(struct Main *bmain,
struct Depsgraph *depsgraph,
@ -156,11 +155,11 @@ void BKE_sequencer_new_render_data(struct Main *bmain,
int preview_render_size,
int for_render,
SeqRenderData *r_context);
bool SEQ_can_use_proxy(struct Sequence *seq, int psize);
int SEQ_rendersize_to_proxysize(int render_size);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
/* **********************************************************************
* sequencer.c
* render.c
*
* Sequencer color space functions
* ********************************************************************** */
@ -173,6 +172,7 @@ void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixe
*
* Sequencer scene functions
* ********************************************************************** */
struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc);
struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene);
void BKE_sequencer_editing_free(struct Scene *scene, const bool do_id_user);
@ -214,12 +214,21 @@ void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
struct Sequence *seq,
bool *r_was_reloaded,
bool *r_can_produce_frames);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene,
struct Sequence *changed_seq,
int len_change,
int ibuf_change);
bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b);
/* **********************************************************************
* proxy.c
*
* Proxy functions
* ********************************************************************** */
bool BKE_sequencer_proxy_rebuild_context(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
@ -232,9 +241,8 @@ void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context,
float *progress);
void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
void BKE_sequencer_proxy_set(struct Sequence *seq, bool value);
bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b);
bool SEQ_can_use_proxy(struct Sequence *seq, int psize);
int SEQ_rendersize_to_proxysize(int render_size);
double BKE_sequencer_rendersize_to_scale_factor(int size);
/* **********************************************************************

View File

@ -62,6 +62,7 @@
#include "BLF_api.h"
#include "render.h"
#include "sequencer.h"
static struct SeqEffectHandle get_sequence_effect_impl(int seq_type);
@ -151,15 +152,15 @@ static ImBuf *prepare_effect_imbufs(const SeqRenderData *context,
if (out->rect_float) {
if (ibuf1 && !ibuf1->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, true);
seq_imbuf_to_sequencer_space(scene, ibuf1, true);
}
if (ibuf2 && !ibuf2->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, true);
seq_imbuf_to_sequencer_space(scene, ibuf2, true);
}
if (ibuf3 && !ibuf3->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, true);
seq_imbuf_to_sequencer_space(scene, ibuf3, true);
}
IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name);
@ -2989,7 +2990,7 @@ static ImBuf *do_multicam(const SeqRenderData *context,
return NULL;
}
out = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
out = seq_render_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
return out;
}
@ -3018,7 +3019,7 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq);
if (seq->machine > 1) {
i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep);
i = seq_render_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep);
}
/* found nothing? so let's work the way up the metastrip stack, so
@ -3253,7 +3254,7 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context,
float cfra,
int input)
{
int nr = BKE_sequencer_give_stripelem_index(seq, cfra);
int nr = seq_give_stripelem_index(seq, cfra);
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
BKE_sequence_effect_speed_rebuild_map(context->scene, seq, false);
@ -3272,7 +3273,7 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context,
static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, Sequence *seq, float cfra)
{
int nr = BKE_sequencer_give_stripelem_index(seq, cfra);
int nr = seq_give_stripelem_index(seq, cfra);
return s->frameMap[nr] - floor(s->frameMap[nr]);
}
@ -3293,7 +3294,7 @@ static ImBuf *do_speed_effect(const SeqRenderData *context,
out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, cfra);
/* Current frame is ibuf1, next frame is ibuf2. */
out = BKE_sequencer_effect_execute_threaded(
out = seq_render_effect_execute_threaded(
&cross_effect, context, NULL, cfra, facf0, facf1, ibuf1, ibuf2, ibuf3);
return out;
}

View File

@ -46,6 +46,7 @@
#include "SEQ_sequencer.h"
#include "render.h"
#include "sequencer.h"
static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
@ -82,19 +83,58 @@ typedef struct ModifierThread {
modifier_apply_threaded_cb apply_callback;
} ModifierThread;
/**
* \a cfra is offset by \a fra_offset only in case we are using a real mask.
*/
static ImBuf *modifier_render_mask_input(const SeqRenderData *context,
int mask_input_type,
Sequence *mask_sequence,
Mask *mask_id,
int cfra,
int fra_offset,
bool make_float)
{
ImBuf *mask_input = NULL;
if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) {
if (mask_sequence) {
SeqRenderState state;
seq_render_state_init(&state);
mask_input = seq_render_strip(context, &state, mask_sequence, cfra);
if (make_float) {
if (!mask_input->rect_float) {
IMB_float_from_rect(mask_input);
}
}
else {
if (!mask_input->rect) {
IMB_rect_from_float(mask_input);
}
}
}
}
else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
mask_input = seq_render_mask(context, mask_id, cfra - fra_offset, make_float);
}
return mask_input;
}
static ImBuf *modifier_mask_get(SequenceModifierData *smd,
const SeqRenderData *context,
int cfra,
int fra_offset,
bool make_float)
{
return BKE_sequencer_render_mask_input(context,
smd->mask_input_type,
smd->mask_sequence,
smd->mask_id,
cfra,
fra_offset,
make_float);
return modifier_render_mask_input(context,
smd->mask_input_type,
smd->mask_sequence,
smd->mask_id,
cfra,
fra_offset,
make_float);
}
static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@ -174,6 +214,291 @@ static void modifier_apply_threaded(ImBuf *ibuf,
/** \name Color Balance Modifier
* \{ */
static StripColorBalance calc_cb(StripColorBalance *cb_)
{
StripColorBalance cb = *cb_;
int c;
for (c = 0; c < 3; c++) {
cb.lift[c] = 2.0f - cb.lift[c];
}
if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
for (c = 0; c < 3; c++) {
/* tweak to give more subtle results
* values above 1.0 are scaled */
if (cb.lift[c] > 1.0f) {
cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
}
cb.lift[c] = 2.0f - cb.lift[c];
}
}
if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
for (c = 0; c < 3; c++) {
if (cb.gain[c] != 0.0f) {
cb.gain[c] = 1.0f / cb.gain[c];
}
else {
cb.gain[c] = 1000000; /* should be enough :) */
}
}
}
if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
for (c = 0; c < 3; c++) {
if (cb.gamma[c] != 0.0f) {
cb.gamma[c] = 1.0f / cb.gamma[c];
}
else {
cb.gamma[c] = 1000000; /* should be enough :) */
}
}
}
return cb;
}
/* note: lift is actually 2-lift */
MINLINE float color_balance_fl(
float in, const float lift, const float gain, const float gamma, const float mul)
{
float x = (((in - 1.0f) * lift) + 1.0f) * gain;
/* prevent NaN */
if (x < 0.f) {
x = 0.f;
}
x = powf(x, gamma) * mul;
CLAMP(x, FLT_MIN, FLT_MAX);
return x;
}
static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul)
{
int y;
for (y = 0; y < 256; y++) {
float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
table[y] = v;
}
}
static void color_balance_byte_byte(StripColorBalance *cb_,
unsigned char *rect,
unsigned char *mask_rect,
int width,
int height,
float mul)
{
// unsigned char cb_tab[3][256];
unsigned char *cp = rect;
unsigned char *e = cp + width * 4 * height;
unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(cb_);
while (cp < e) {
float p[4];
int c;
straight_uchar_to_premul_float(p, cp);
for (c = 0; c < 3; c++) {
float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
if (m) {
float m_normal = (float)m[c] / 255.0f;
p[c] = p[c] * (1.0f - m_normal) + t * m_normal;
}
else {
p[c] = t;
}
}
premul_float_to_straight_uchar(cp, p);
cp += 4;
if (m) {
m += 4;
}
}
}
static void color_balance_byte_float(StripColorBalance *cb_,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
int width,
int height,
float mul)
{
float cb_tab[4][256];
int c, i;
unsigned char *p = rect;
unsigned char *e = p + width * 4 * height;
unsigned char *m = mask_rect;
float *o;
StripColorBalance cb;
o = rect_float;
cb = calc_cb(cb_);
for (c = 0; c < 3; c++) {
make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
}
for (i = 0; i < 256; i++) {
cb_tab[3][i] = ((float)i) * (1.0f / 255.0f);
}
while (p < e) {
if (m) {
const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
m += 4;
}
else {
o[0] = cb_tab[0][p[0]];
o[1] = cb_tab[1][p[1]];
o[2] = cb_tab[2][p[2]];
}
o[3] = cb_tab[3][p[3]];
p += 4;
o += 4;
}
}
static void color_balance_float_float(StripColorBalance *cb_,
float *rect_float,
const float *mask_rect_float,
int width,
int height,
float mul)
{
float *p = rect_float;
const float *e = rect_float + width * 4 * height;
const float *m = mask_rect_float;
StripColorBalance cb = calc_cb(cb_);
while (p < e) {
int c;
for (c = 0; c < 3; c++) {
float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
if (m) {
p[c] = p[c] * (1.0f - m[c]) + t * m[c];
}
else {
p[c] = t;
}
}
p += 4;
if (m) {
m += 4;
}
}
}
typedef struct ColorBalanceInitData {
StripColorBalance *cb;
ImBuf *ibuf;
float mul;
ImBuf *mask;
bool make_float;
} ColorBalanceInitData;
typedef struct ColorBalanceThread {
StripColorBalance *cb;
float mul;
int width, height;
unsigned char *rect, *mask_rect;
float *rect_float, *mask_rect_float;
bool make_float;
} ColorBalanceThread;
static void color_balance_init_handle(void *handle_v,
int start_line,
int tot_line,
void *init_data_v)
{
ColorBalanceThread *handle = (ColorBalanceThread *)handle_v;
ColorBalanceInitData *init_data = (ColorBalanceInitData *)init_data_v;
ImBuf *ibuf = init_data->ibuf;
ImBuf *mask = init_data->mask;
int offset = 4 * start_line * ibuf->x;
memset(handle, 0, sizeof(ColorBalanceThread));
handle->cb = init_data->cb;
handle->mul = init_data->mul;
handle->width = ibuf->x;
handle->height = tot_line;
handle->make_float = init_data->make_float;
if (ibuf->rect) {
handle->rect = (unsigned char *)ibuf->rect + offset;
}
if (ibuf->rect_float) {
handle->rect_float = ibuf->rect_float + offset;
}
if (mask) {
if (mask->rect) {
handle->mask_rect = (unsigned char *)mask->rect + offset;
}
if (mask->rect_float) {
handle->mask_rect_float = mask->rect_float + offset;
}
}
else {
handle->mask_rect = NULL;
handle->mask_rect_float = NULL;
}
}
static void *color_balance_do_thread(void *thread_data_v)
{
ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v;
StripColorBalance *cb = thread_data->cb;
int width = thread_data->width, height = thread_data->height;
unsigned char *rect = thread_data->rect;
unsigned char *mask_rect = thread_data->mask_rect;
float *rect_float = thread_data->rect_float;
float *mask_rect_float = thread_data->mask_rect_float;
float mul = thread_data->mul;
if (rect_float) {
color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul);
}
else if (thread_data->make_float) {
color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul);
}
else {
color_balance_byte_byte(cb, rect, mask_rect, width, height, mul);
}
return NULL;
}
static void colorBalance_init_data(SequenceModifierData *smd)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd;
@ -188,11 +513,41 @@ static void colorBalance_init_data(SequenceModifierData *smd)
}
}
static void modifier_color_balance_apply(
StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input)
{
ColorBalanceInitData init_data;
if (!ibuf->rect_float && make_float) {
imb_addrectfloatImBuf(ibuf);
}
init_data.cb = cb;
init_data.ibuf = ibuf;
init_data.mul = mul;
init_data.make_float = make_float;
init_data.mask = mask_input;
IMB_processor_apply_threaded(ibuf->y,
sizeof(ColorBalanceThread),
&init_data,
color_balance_init_handle,
color_balance_do_thread);
/* color balance either happens on float buffer or byte buffer, but never on both,
* free byte buffer if there's float buffer since float buffer would be used for
* color balance in favor of byte buffer
*/
if (ibuf->rect_float && ibuf->rect) {
imb_freerectImBuf(ibuf);
}
}
static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd;
BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
modifier_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
}
static SequenceModifierTypeInfo seqModifier_ColorBalance = {
@ -1100,7 +1455,7 @@ ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context,
}
if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
seq_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
}
return processed_ibuf;

View File

@ -55,6 +55,7 @@
#include "SEQ_sequencer.h"
#include "render.h"
#include "sequencer.h"
typedef struct PrefetchJob {
@ -361,7 +362,7 @@ static bool seq_prefetch_do_skip_frame(Scene *scene)
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
float cfra = seq_prefetch_cfra(pfjob);
Sequence *seq_arr[MAXSEQ + 1];
int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
int count = seq_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
SeqRenderData *ctx = &pfjob->context_cpy;
ImBuf *ibuf = NULL;

View File

@ -0,0 +1,570 @@
/*
* 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 "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#ifdef WIN32
# include "BLI_winstuff.h"
#else
# include <unistd.h>
#endif
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
#include "SEQ_sequencer.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_metadata.h"
#include "proxy.h"
#include "render.h"
#include "sequencer.h"
typedef struct SeqIndexBuildContext {
struct IndexBuildContext *index_context;
int tc_flags;
int size_flags;
int quality;
bool overwrite;
int view_id;
Main *bmain;
Depsgraph *depsgraph;
Scene *scene;
Sequence *seq, *orig_seq;
} SeqIndexBuildContext;
int SEQ_rendersize_to_proxysize(int render_size)
{
switch (render_size) {
case SEQ_RENDER_SIZE_PROXY_25:
return IMB_PROXY_25;
case SEQ_RENDER_SIZE_PROXY_50:
return IMB_PROXY_50;
case SEQ_RENDER_SIZE_PROXY_75:
return IMB_PROXY_75;
case SEQ_RENDER_SIZE_PROXY_100:
return IMB_PROXY_100;
}
return IMB_PROXY_NONE;
}
double BKE_sequencer_rendersize_to_scale_factor(int render_size)
{
switch (render_size) {
case SEQ_RENDER_SIZE_PROXY_25:
return 0.25;
case SEQ_RENDER_SIZE_PROXY_50:
return 0.50;
case SEQ_RENDER_SIZE_PROXY_75:
return 0.75;
}
return 1.0;
}
bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_id)
{
char fname[FILE_MAXFILE];
char suffix[24];
StripProxy *proxy = seq->strip->proxy;
if (proxy == NULL) {
return false;
}
BLI_join_dirfile(fname, PROXY_MAXFILE, proxy->dir, proxy->file);
BLI_path_abs(fname, BKE_main_blendfile_path_from_global());
if (view_id > 0) {
BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id);
/* TODO(sergey): This will actually append suffix after extension
* which is weird but how was originally coded in multi-view branch.
*/
BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", fname, suffix);
}
else {
BLI_strncpy(name, fname, PROXY_MAXFILE);
}
return true;
}
static bool seq_proxy_get_fname(Editing *ed,
Sequence *seq,
int cfra,
eSpaceSeq_Proxy_RenderSize render_size,
char *name,
const int view_id)
{
char dir[PROXY_MAXFILE];
char suffix[24] = {'\0'};
StripProxy *proxy = seq->strip->proxy;
if (proxy == NULL) {
return false;
}
/* Multi-view suffix. */
if (view_id > 0) {
BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id);
}
/* Per strip with Custom file situation is handled separately. */
if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE &&
ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE) {
if (seq_proxy_get_custom_file_fname(seq, name, view_id)) {
return true;
}
}
if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
/* Per project default. */
if (ed->proxy_dir[0] == 0) {
BLI_strncpy(dir, "//BL_proxy", sizeof(dir));
}
else { /* Per project with custom dir. */
BLI_strncpy(dir, ed->proxy_dir, sizeof(dir));
}
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
}
else {
/* Pre strip with custom dir. */
if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) {
BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
}
else { /* Per strip default. */
BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
}
}
/* Proxy size number to be used in path. */
int proxy_size_number = BKE_sequencer_rendersize_to_scale_factor(render_size) * 100;
BLI_snprintf(name,
PROXY_MAXFILE,
"%s/images/%d/%s_proxy%s",
dir,
proxy_size_number,
BKE_sequencer_give_stripelem(seq, cfra)->name,
suffix);
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
strcat(name, ".jpg");
return true;
}
bool SEQ_can_use_proxy(Sequence *seq, int psize)
{
if (seq->strip->proxy == NULL) {
return false;
}
short size_flags = seq->strip->proxy->build_size_flags;
return (seq->flag & SEQ_USE_PROXY) != 0 && psize != IMB_PROXY_NONE && (size_flags & psize) != 0;
}
ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra)
{
char name[PROXY_MAXFILE];
StripProxy *proxy = seq->strip->proxy;
const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size;
Editing *ed = context->scene->ed;
StripAnim *sanim;
/* only use proxies, if they are enabled (even if present!) */
if (!SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(psize))) {
return NULL;
}
if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
int frameno = (int)seq_give_stripelem_index(seq, cfra) + seq->anim_startofs;
if (proxy->anim == NULL) {
if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) {
return NULL;
}
proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name);
}
if (proxy->anim == NULL) {
return NULL;
}
seq_open_anim_file(context->scene, seq, true);
sanim = seq->anims.first;
frameno = IMB_anim_index_get_frame_index(
sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno);
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) {
return NULL;
}
if (BLI_exists(name)) {
ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL);
if (ibuf) {
seq_imbuf_assign_spaces(context->scene, ibuf);
}
return ibuf;
}
return NULL;
}
static void seq_proxy_build_frame(const SeqRenderData *context,
SeqRenderState *state,
Sequence *seq,
int cfra,
int proxy_render_size,
const bool overwrite)
{
char name[PROXY_MAXFILE];
int quality;
int rectx, recty;
int ok;
ImBuf *ibuf_tmp, *ibuf;
Editing *ed = context->scene->ed;
if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) {
return;
}
if (!overwrite && BLI_exists(name)) {
return;
}
ibuf_tmp = seq_render_strip(context, state, seq, cfra);
rectx = (proxy_render_size * ibuf_tmp->x) / 100;
recty = (proxy_render_size * ibuf_tmp->y) / 100;
if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) {
ibuf = IMB_dupImBuf(ibuf_tmp);
IMB_metadata_copy(ibuf, ibuf_tmp);
IMB_freeImBuf(ibuf_tmp);
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
}
else {
ibuf = ibuf_tmp;
}
/* depth = 32 is intentionally left in, otherwise ALPHA channels
* won't work... */
quality = seq->strip->proxy->quality;
ibuf->ftype = IMB_FTYPE_JPG;
ibuf->foptions.quality = quality;
/* unsupported feature only confuses other s/w */
if (ibuf->planes == 32) {
ibuf->planes = 24;
}
BLI_make_existing_file(name);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
if (ok == 0) {
perror(name);
}
IMB_freeImBuf(ibuf);
}
/**
* Returns whether the file this context would read from even exist,
* if not, don't create the context
*/
static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id)
{
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return false;
}
if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
static char prefix[FILE_MAX];
static const char *ext = NULL;
char str[FILE_MAX];
if (view_id == 0) {
char path[FILE_MAX];
BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
}
else {
prefix[0] = '\0';
}
if (prefix[0] == '\0') {
return view_id != 0;
}
seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX);
if (BLI_access(str, R_OK) == 0) {
return false;
}
return view_id != 0;
}
return false;
}
/**
* This returns the maximum possible number of required contexts
*/
static int seq_proxy_context_count(Sequence *seq, Scene *scene)
{
int num_views = 1;
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return 1;
}
switch (seq->type) {
case SEQ_TYPE_MOVIE: {
num_views = BLI_listbase_count(&seq->anims);
break;
}
case SEQ_TYPE_IMAGE: {
switch (seq->views_format) {
case R_IMF_VIEWS_INDIVIDUAL:
num_views = BKE_scene_multiview_num_views_get(&scene->r);
break;
case R_IMF_VIEWS_STEREO_3D:
num_views = 2;
break;
case R_IMF_VIEWS_MULTIVIEW:
/* not supported at the moment */
/* pass through */
default:
num_views = 1;
}
break;
}
}
return num_views;
}
bool BKE_sequencer_proxy_rebuild_context(Main *bmain,
Depsgraph *depsgraph,
Scene *scene,
Sequence *seq,
struct GSet *file_list,
ListBase *queue)
{
SeqIndexBuildContext *context;
Sequence *nseq;
LinkData *link;
int num_files;
int i;
if (!seq->strip || !seq->strip->proxy) {
return true;
}
if (!(seq->flag & SEQ_USE_PROXY)) {
return true;
}
num_files = seq_proxy_context_count(seq, scene);
for (i = 0; i < num_files; i++) {
if (seq_proxy_multiview_context_invalid(seq, scene, i)) {
continue;
}
context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
nseq = BKE_sequence_dupli_recursive(scene, scene, NULL, seq, 0);
context->tc_flags = nseq->strip->proxy->build_tc_flags;
context->size_flags = nseq->strip->proxy->build_size_flags;
context->quality = nseq->strip->proxy->quality;
context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0;
context->bmain = bmain;
context->depsgraph = depsgraph;
context->scene = scene;
context->orig_seq = seq;
context->seq = nseq;
context->view_id = i; /* only for images */
if (nseq->type == SEQ_TYPE_MOVIE) {
StripAnim *sanim;
seq_open_anim_file(scene, nseq, true);
sanim = BLI_findlink(&nseq->anims, i);
if (sanim->anim) {
context->index_context = IMB_anim_index_rebuild_context(sanim->anim,
context->tc_flags,
context->size_flags,
context->quality,
context->overwrite,
file_list);
}
if (!context->index_context) {
MEM_freeN(context);
return false;
}
}
link = BLI_genericNodeN(context);
BLI_addtail(queue, link);
}
return true;
}
void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context,
short *stop,
short *do_update,
float *progress)
{
const bool overwrite = context->overwrite;
SeqRenderData render_context;
Sequence *seq = context->seq;
Scene *scene = context->scene;
Main *bmain = context->bmain;
int cfra;
if (seq->type == SEQ_TYPE_MOVIE) {
if (context->index_context) {
IMB_anim_index_rebuild(context->index_context, stop, do_update, progress);
}
return;
}
if (!(seq->flag & SEQ_USE_PROXY)) {
return;
}
/* that's why it is called custom... */
if (seq->strip->proxy && seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
return;
}
/* fail safe code */
BKE_sequencer_new_render_data(bmain,
context->depsgraph,
context->scene,
roundf((scene->r.size * (float)scene->r.xsch) / 100.0f),
roundf((scene->r.size * (float)scene->r.ysch) / 100.0f),
100,
false,
&render_context);
render_context.skip_cache = true;
render_context.is_proxy_render = true;
render_context.view_id = context->view_id;
SeqRenderState state;
seq_render_state_init(&state);
for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
if (context->size_flags & IMB_PROXY_25) {
seq_proxy_build_frame(&render_context, &state, seq, cfra, 25, overwrite);
}
if (context->size_flags & IMB_PROXY_50) {
seq_proxy_build_frame(&render_context, &state, seq, cfra, 50, overwrite);
}
if (context->size_flags & IMB_PROXY_75) {
seq_proxy_build_frame(&render_context, &state, seq, cfra, 75, overwrite);
}
if (context->size_flags & IMB_PROXY_100) {
seq_proxy_build_frame(&render_context, &state, seq, cfra, 100, overwrite);
}
*progress = (float)(cfra - seq->startdisp - seq->startstill) /
(seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
*do_update = true;
if (*stop || G.is_break) {
break;
}
}
}
void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop)
{
if (context->index_context) {
StripAnim *sanim;
for (sanim = context->seq->anims.first; sanim; sanim = sanim->next) {
IMB_close_anim_proxies(sanim->anim);
}
for (sanim = context->orig_seq->anims.first; sanim; sanim = sanim->next) {
IMB_close_anim_proxies(sanim->anim);
}
IMB_anim_index_rebuild_finish(context->index_context, stop);
}
seq_free_sequence_recurse(NULL, context->seq, true);
MEM_freeN(context);
}
void BKE_sequencer_proxy_set(struct Sequence *seq, bool value)
{
if (value) {
seq->flag |= SEQ_USE_PROXY;
if (seq->strip->proxy == NULL) {
seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
seq->strip->proxy->quality = 90;
seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL;
seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25;
}
}
else {
seq->flag &= ~SEQ_USE_PROXY;
}
}

View File

@ -0,0 +1,40 @@
/*
* 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) 2004 Blender Foundation.
* All rights reserved.
*/
#pragma once
/** \file
* \ingroup sequencer
*/
#ifdef __cplusplus
extern "C" {
#endif
struct SeqRenderData;
struct ImBuf;
struct Sequence;
#define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE)
struct ImBuf *seq_proxy_fetch(const struct SeqRenderData *context, struct Sequence *seq, int cfra);
bool seq_proxy_get_custom_file_fname(struct Sequence *seq, char *name, const int view_id);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
/*
* 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) 2004 Blender Foundation.
* All rights reserved.
*/
#pragma once
/** \file
* \ingroup sequencer
*/
#ifdef __cplusplus
extern "C" {
#endif
struct Editing;
struct SeqRenderData;
struct ListBase;
struct ImBuf;
struct Scene;
struct Sequence;
/* mutable state for sequencer */
typedef struct SeqRenderState {
struct LinkNode *scene_parents;
} SeqRenderState;
void seq_render_state_init(SeqRenderState *state);
struct ImBuf *seq_render_give_ibuf_seqbase(const struct SeqRenderData *context,
float cfra,
int chan_shown,
struct ListBase *seqbasep);
struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh,
const SeqRenderData *context,
struct Sequence *seq,
float cfra,
float facf0,
float facf1,
struct ImBuf *ibuf1,
struct ImBuf *ibuf2,
struct ImBuf *ibuf3);
void seq_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float);
float seq_give_stripelem_index(struct Sequence *seq, float cfra);
int seq_get_shown_sequences(struct ListBase *seqbasep,
int cfra,
int chanshown,
struct Sequence **seq_arr_out);
struct ImBuf *seq_render_strip(const struct SeqRenderData *context,
struct SeqRenderState *state,
struct Sequence *seq,
float cfra);
struct ImBuf *seq_render_mask(const struct SeqRenderData *context,
struct Mask *mask,
float nr,
bool make_float);
void seq_imbuf_assign_spaces(struct Scene *scene, struct ImBuf *ibuf);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -41,48 +41,6 @@ struct StripElem;
#define EARLY_USE_INPUT_1 1
#define EARLY_USE_INPUT_2 2
/* **********************************************************************
* sequencer.c
*
* sequencer render functions
* ********************************************************************** */
struct ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context,
float cfra,
int chan_shown,
struct ListBase *seqbasep);
struct ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh,
const SeqRenderData *context,
struct Sequence *seq,
float cfra,
float facf0,
float facf1,
struct ImBuf *ibuf1,
struct ImBuf *ibuf2,
struct ImBuf *ibuf3);
struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context,
int mask_input_type,
struct Sequence *mask_sequence,
struct Mask *mask_id,
int cfra,
int fra_offset,
bool make_float);
void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
struct ImBuf *ibuf,
float mul,
bool make_float,
struct ImBuf *mask_input);
/* **********************************************************************
* sequencer.c
*
* sequencer color space functions
* ********************************************************************** */
void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene,
struct ImBuf *ibuf,
bool make_float);
/* **********************************************************************
* sequencer.c
*
@ -90,15 +48,6 @@ void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene,
* ********************************************************************** */
void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
int cfra,
int chanshown,
struct Sequence **seq_arr_out);
bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
struct Sequence *seq,
float cfra);
float BKE_sequencer_give_stripelem_index(struct Sequence *seq, float cfra);
/* **********************************************************************
* image_cache.c
*
@ -174,6 +123,16 @@ void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq);
struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */,
struct Sequence *meta /* = NULL */,
struct Sequence *seq);
void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, const bool do_id_user);
void seq_multiview_name(struct Scene *scene,
const int view_id,
const char *prefix,
const char *ext,
char *r_path,
size_t r_size);
int seq_num_files(struct Scene *scene, char views_format, const bool is_multiview);
void seq_open_anim_file(struct Scene *scene, struct Sequence *seq, bool openfile);
void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir);
/* **********************************************************************
* sequencer.c