diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 3251dccb172..d179a6c3b2b 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -1456,6 +1456,47 @@ bool RE_seq_render_active(Scene *scene, RenderData *rd) return false; } +static bool seq_result_needs_float(const ImageFormatData &im_format) +{ + return ELEM(im_format.depth, R_IMF_CHAN_DEPTH_10, R_IMF_CHAN_DEPTH_12); +} + +static ImBuf *seq_process_render_image(ImBuf *src, + const ImageFormatData &im_format, + const Scene *scene) +{ + if (src == nullptr) { + return nullptr; + } + + ImBuf *dst = nullptr; + if (seq_result_needs_float(im_format) && src->float_buffer.data == nullptr) { + /* If render output needs >8 bpp input and we only have 8pp, convert to float. */ + dst = IMB_allocImBuf(src->x, src->y, src->planes, 0); + imb_addrectfloatImBuf(dst, src->channels, false); + /* Transform from sequencer space to scene linear. */ + const char *from_colorspace = IMB_colormanagement_get_rect_colorspace(src); + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( + COLOR_ROLE_SCENE_LINEAR); + IMB_colormanagement_transform_from_byte_threaded(dst->float_buffer.data, + src->byte_buffer.data, + src->x, + src->y, + src->channels, + from_colorspace, + to_colorspace); + } + else { + /* Duplicate sequencer output and ensure it is in needed color space. */ + dst = IMB_dupImBuf(src); + SEQ_render_imbuf_from_sequencer_space(scene, dst); + } + IMB_metadata_copy(dst, src); + IMB_freeImBuf(src); + + return dst; +} + /* Render sequencer strips into render result. */ static void do_render_sequencer(Render *re) { @@ -1500,16 +1541,7 @@ static void do_render_sequencer(Render *re) for (view_id = 0; view_id < tot_views; view_id++) { context.view_id = view_id; out = SEQ_render_give_ibuf(&context, cfra, 0); - - if (out) { - ibuf_arr[view_id] = IMB_dupImBuf(out); - IMB_metadata_copy(ibuf_arr[view_id], out); - IMB_freeImBuf(out); - SEQ_render_imbuf_from_sequencer_space(re->pipeline_scene_eval, ibuf_arr[view_id]); - } - else { - ibuf_arr[view_id] = nullptr; - } + ibuf_arr[view_id] = seq_process_render_image(out, re->r.im_format, re->pipeline_scene_eval); } rr = re->result; diff --git a/source/blender/sequencer/SEQ_render.hh b/source/blender/sequencer/SEQ_render.hh index ee9dff3fd5c..b3153b94423 100644 --- a/source/blender/sequencer/SEQ_render.hh +++ b/source/blender/sequencer/SEQ_render.hh @@ -70,8 +70,8 @@ void SEQ_render_new_render_data(Main *bmain, SeqRenderData *r_context); StripElem *SEQ_render_give_stripelem(const Scene *scene, const Strip *strip, int timeline_frame); -void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf); -void SEQ_render_pixel_from_sequencer_space_v4(Scene *scene, float pixel[4]); +void SEQ_render_imbuf_from_sequencer_space(const Scene *scene, ImBuf *ibuf); +void SEQ_render_pixel_from_sequencer_space_v4(const Scene *scene, float pixel[4]); /** * Check if `strip` is muted for rendering. * This function also checks `SeqTimelineChannel` flag. diff --git a/source/blender/sequencer/intern/render.cc b/source/blender/sequencer/intern/render.cc index 264425a39a1..65348f5dde8 100644 --- a/source/blender/sequencer/intern/render.cc +++ b/source/blender/sequencer/intern/render.cc @@ -176,7 +176,7 @@ void seq_imbuf_to_sequencer_space(const Scene *scene, ImBuf *ibuf, bool make_flo seq_imbuf_assign_spaces(scene, ibuf); } -void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) +void SEQ_render_imbuf_from_sequencer_space(const Scene *scene, ImBuf *ibuf) { const char *from_colorspace = scene->sequencer_colorspace_settings.name; const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( @@ -198,7 +198,7 @@ void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) } } -void SEQ_render_pixel_from_sequencer_space_v4(Scene *scene, float pixel[4]) +void SEQ_render_pixel_from_sequencer_space_v4(const Scene *scene, float pixel[4]) { const char *from_colorspace = scene->sequencer_colorspace_settings.name; const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(