X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=theme.cpp;h=b6a19acd2ea5b5eb28e36772fc560400d36d5d9c;hb=25f6b207f157c081495d7abd4ea314b5ef760322;hp=9e04740d60b3636a636bf1460a4bfd4afb9e3a0a;hpb=ba2dc655c098912b8860676596fe89c1305affe9;p=nageru diff --git a/theme.cpp b/theme.cpp index 9e04740..b6a19ac 100644 --- a/theme.cpp +++ b/theme.cpp @@ -612,22 +612,6 @@ LiveInputWrapper::LiveInputWrapper(Theme *theme, EffectChain *chain, bmusb::Pixe // So we pick sRGB as the least evil here. inout_format.gamma_curve = GAMMA_sRGB; - // The Blackmagic driver docs claim that the device outputs Y'CbCr - // according to Rec. 601, but practical testing indicates it definitely - // is Rec. 709 (at least up to errors attributable to rounding errors). - // Perhaps 601 was only to indicate the subsampling positions, not the - // colorspace itself? Tested with a Lenovo X1 gen 3 as input. - YCbCrFormat input_ycbcr_format; - input_ycbcr_format.chroma_subsampling_x = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? 1 : 2; - input_ycbcr_format.chroma_subsampling_y = 1; - input_ycbcr_format.num_levels = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? 1024 : 256; - input_ycbcr_format.cb_x_position = 0.0; - input_ycbcr_format.cr_x_position = 0.0; - input_ycbcr_format.cb_y_position = 0.5; - input_ycbcr_format.cr_y_position = 0.5; - input_ycbcr_format.luma_coefficients = YCBCR_REC_709; - input_ycbcr_format.full_range = false; - unsigned num_inputs; if (deinterlace) { deinterlace_effect = new movit::DeinterlaceEffect(); @@ -643,20 +627,50 @@ LiveInputWrapper::LiveInputWrapper(Theme *theme, EffectChain *chain, bmusb::Pixe } else { num_inputs = 1; } - for (unsigned i = 0; i < num_inputs; ++i) { - // When using 10-bit input, we're converting to interleaved through v210Converter. - YCbCrInputSplitting splitting = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? YCBCR_INPUT_INTERLEAVED : YCBCR_INPUT_SPLIT_Y_AND_CBCR; - if (override_bounce) { - inputs.push_back(new NonBouncingYCbCrInput(inout_format, input_ycbcr_format, global_flags.width, global_flags.height, splitting)); - } else { - inputs.push_back(new YCbCrInput(inout_format, input_ycbcr_format, global_flags.width, global_flags.height, splitting)); + + if (pixel_format == bmusb::PixelFormat_8BitRGBA) { + for (unsigned i = 0; i < num_inputs; ++i) { + rgba_inputs.push_back(new FlatInput(inout_format, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, GL_UNSIGNED_BYTE, global_flags.width, global_flags.height)); + chain->add_input(rgba_inputs.back()); } - chain->add_input(inputs.back()); - } - if (deinterlace) { - vector reverse_inputs(inputs.rbegin(), inputs.rend()); - chain->add_effect(deinterlace_effect, reverse_inputs); + if (deinterlace) { + vector reverse_inputs(rgba_inputs.rbegin(), rgba_inputs.rend()); + chain->add_effect(deinterlace_effect, reverse_inputs); + } + } else { + assert(pixel_format == bmusb::PixelFormat_8BitYCbCr || pixel_format == bmusb::PixelFormat_10BitYCbCr); + // The Blackmagic driver docs claim that the device outputs Y'CbCr + // according to Rec. 601, but practical testing indicates it definitely + // is Rec. 709 (at least up to errors attributable to rounding errors). + // Perhaps 601 was only to indicate the subsampling positions, not the + // colorspace itself? Tested with a Lenovo X1 gen 3 as input. + YCbCrFormat input_ycbcr_format; + input_ycbcr_format.chroma_subsampling_x = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? 1 : 2; + input_ycbcr_format.chroma_subsampling_y = 1; + input_ycbcr_format.num_levels = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? 1024 : 256; + input_ycbcr_format.cb_x_position = 0.0; + input_ycbcr_format.cr_x_position = 0.0; + input_ycbcr_format.cb_y_position = 0.5; + input_ycbcr_format.cr_y_position = 0.5; + input_ycbcr_format.luma_coefficients = YCBCR_REC_709; + input_ycbcr_format.full_range = false; + + for (unsigned i = 0; i < num_inputs; ++i) { + // When using 10-bit input, we're converting to interleaved through v210Converter. + YCbCrInputSplitting splitting = (pixel_format == bmusb::PixelFormat_10BitYCbCr) ? YCBCR_INPUT_INTERLEAVED : YCBCR_INPUT_SPLIT_Y_AND_CBCR; + if (override_bounce) { + ycbcr_inputs.push_back(new NonBouncingYCbCrInput(inout_format, input_ycbcr_format, global_flags.width, global_flags.height, splitting)); + } else { + ycbcr_inputs.push_back(new YCbCrInput(inout_format, input_ycbcr_format, global_flags.width, global_flags.height, splitting)); + } + chain->add_input(ycbcr_inputs.back()); + } + + if (deinterlace) { + vector reverse_inputs(ycbcr_inputs.rbegin(), ycbcr_inputs.rend()); + chain->add_effect(deinterlace_effect, reverse_inputs); + } } } @@ -682,7 +696,7 @@ void LiveInputWrapper::connect_signal(int signal_num) } BufferedFrame last_good_frame = first_frame; - for (unsigned i = 0; i < inputs.size(); ++i) { + for (unsigned i = 0; i < max(ycbcr_inputs.size(), rgba_inputs.size()); ++i) { BufferedFrame frame = theme->input_state->buffered_frames[signal_num][i]; if (frame.frame == nullptr) { // Not enough data; reuse last frame (well, field). @@ -691,22 +705,35 @@ void LiveInputWrapper::connect_signal(int signal_num) } const PBOFrameAllocator::Userdata *userdata = (const PBOFrameAllocator::Userdata *)frame.frame->userdata; - if (userdata->last_width[frame.field_number] != width || - userdata->last_height[frame.field_number] != height) { + unsigned this_width = userdata->last_width[frame.field_number]; + unsigned this_height = userdata->last_height[frame.field_number]; + if (this_width != width || this_height != height) { // Resolution changed; reuse last frame/field. frame = last_good_frame; userdata = (const PBOFrameAllocator::Userdata *)frame.frame->userdata; } assert(userdata->pixel_format == pixel_format); - if (pixel_format == bmusb::PixelFormat_10BitYCbCr) { - inputs[i]->set_texture_num(0, userdata->tex_444[frame.field_number]); - } else { - inputs[i]->set_texture_num(0, userdata->tex_y[frame.field_number]); - inputs[i]->set_texture_num(1, userdata->tex_cbcr[frame.field_number]); + switch (pixel_format) { + case bmusb::PixelFormat_8BitYCbCr: + ycbcr_inputs[i]->set_texture_num(0, userdata->tex_y[frame.field_number]); + ycbcr_inputs[i]->set_texture_num(1, userdata->tex_cbcr[frame.field_number]); + ycbcr_inputs[i]->set_width(this_width); + ycbcr_inputs[i]->set_height(this_height); + break; + case bmusb::PixelFormat_10BitYCbCr: + ycbcr_inputs[i]->set_texture_num(0, userdata->tex_444[frame.field_number]); + ycbcr_inputs[i]->set_width(this_width); + ycbcr_inputs[i]->set_height(this_height); + break; + case bmusb::PixelFormat_8BitRGBA: + rgba_inputs[i]->set_texture_num(userdata->tex_rgba[frame.field_number]); + rgba_inputs[i]->set_width(this_width); + rgba_inputs[i]->set_height(this_height); + break; + default: + assert(false); } - inputs[i]->set_width(userdata->last_width[frame.field_number]); - inputs[i]->set_height(userdata->last_height[frame.field_number]); last_good_frame = frame; }