]> git.sesse.net Git - nageru/blobdiff - theme.cpp
Removed a label that probably isn't going to be used right now.
[nageru] / theme.cpp
index 56e7ce2de3285733707c425b7d61f076eda6266b..dd564196e3c8abcf1e033e3981812a40f73e27d7 100644 (file)
--- a/theme.cpp
+++ b/theme.cpp
@@ -369,6 +369,14 @@ int VideoInput_change_rate(lua_State* L)
        return 0;
 }
 
+int VideoInput_get_signal_num(lua_State* L)
+{
+       assert(lua_gettop(L) == 1);
+       FFmpegCapture **video_input = (FFmpegCapture **)luaL_checkudata(L, 1, "VideoInput");
+       lua_pushnumber(L, -1 - (*video_input)->get_card_index());
+       return 1;
+}
+
 int WhiteBalanceEffect_new(lua_State* L)
 {
        assert(lua_gettop(L) == 0);
@@ -572,6 +580,7 @@ const luaL_Reg VideoInput_funcs[] = {
        { "new", VideoInput_new },
        { "rewind", VideoInput_rewind },
        { "change_rate", VideoInput_change_rate },
+       { "get_signal_num", VideoInput_get_signal_num },
        { NULL, NULL }
 };
 
@@ -710,12 +719,6 @@ LiveInputWrapper::LiveInputWrapper(Theme *theme, EffectChain *chain, bmusb::Pixe
                }
        } 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;
@@ -723,8 +726,8 @@ LiveInputWrapper::LiveInputWrapper(Theme *theme, EffectChain *chain, bmusb::Pixe
                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;
+               input_ycbcr_format.luma_coefficients = YCBCR_REC_709;  // Will be overridden later.
+               input_ycbcr_format.full_range = false;  // Will be overridden later.
 
                for (unsigned i = 0; i < num_inputs; ++i) {
                        // When using 10-bit input, we're converting to interleaved through v210Converter.
@@ -769,6 +772,31 @@ void LiveInputWrapper::connect_signal_raw(int signal_num)
                height = userdata->last_height[first_frame.field_number];
        }
 
+       movit::YCbCrLumaCoefficients ycbcr_coefficients = theme->input_state->ycbcr_coefficients[signal_num];
+       bool full_range = theme->input_state->full_range[signal_num];
+
+       if (theme->input_state->ycbcr_coefficients_auto[signal_num]) {
+               full_range = false;
+
+               // The Blackmagic driver docs claim that the device outputs Y'CbCr
+               // according to Rec. 601, but this seems to indicate the subsampling
+               // positions only, as they publish Y'CbCr → RGB formulas that are
+               // different for HD and SD (corresponding to Rec. 709 and 601, respectively),
+               // and a Lenovo X1 gen 3 I used to test definitely outputs Rec. 709
+               // (at least up to rounding error). Other devices seem to use Rec. 601
+               // even on HD resolutions. Nevertheless, Rec. 709 _is_ the right choice
+               // for HD, so we default to that if the user hasn't set anything.
+               if (height >= 720) {
+                       ycbcr_coefficients = YCBCR_REC_709;
+               } else {
+                       ycbcr_coefficients = YCBCR_REC_601;
+               }
+       }
+
+       // This is a global, but it doesn't really matter.
+       input_ycbcr_format.luma_coefficients = ycbcr_coefficients;
+       input_ycbcr_format.full_range = full_range;
+
        BufferedFrame last_good_frame = first_frame;
        for (unsigned i = 0; i < max(ycbcr_inputs.size(), rgba_inputs.size()); ++i) {
                BufferedFrame frame = theme->input_state->buffered_frames[signal_num][i];
@@ -792,18 +820,20 @@ void LiveInputWrapper::connect_signal_raw(int signal_num)
                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);
+                       ycbcr_inputs[i]->change_ycbcr_format(input_ycbcr_format);
+                       ycbcr_inputs[i]->set_width(width);
+                       ycbcr_inputs[i]->set_height(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);
+                       ycbcr_inputs[i]->change_ycbcr_format(input_ycbcr_format);
+                       ycbcr_inputs[i]->set_width(width);
+                       ycbcr_inputs[i]->set_height(height);
                        break;
                case bmusb::PixelFormat_8BitBGRA:
                        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);
+                       rgba_inputs[i]->set_width(width);
+                       rgba_inputs[i]->set_height(height);
                        break;
                default:
                        assert(false);
@@ -1084,6 +1114,11 @@ vector<string> Theme::get_transition_names(float t)
 
 int Theme::map_signal(int signal_num)
 {
+       // Negative numbers map to raw signals.
+       if (signal_num < 0) {
+               return -1 - signal_num;
+       }
+
        unique_lock<mutex> lock(map_m);
        if (signal_to_card_mapping.count(signal_num)) {
                return signal_to_card_mapping[signal_num];