From ff8ac210fbee1e5e85092aa177d200633d438809 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 16 Feb 2015 19:47:54 +0100 Subject: [PATCH 1/7] linux-v4l2: Remove camera constraint for inputs Remove the constraint for device inputs to be of the type "CAMERA". This was added under the false assumption that inputs of the type "TUNER" are only used for control purposes. --- plugins/linux-v4l2/v4l2-input.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index 1276b4d12..2374db2d6 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -336,12 +336,9 @@ static void v4l2_input_list(int_fast32_t dev, obs_property_t *prop) obs_property_list_add_int(prop, obs_module_text("LeaveUnchanged"), -1); while (v4l2_ioctl(dev, VIDIOC_ENUMINPUT, &in) == 0) { - if (in.type & V4L2_INPUT_TYPE_CAMERA) { - obs_property_list_add_int(prop, (char *) in.name, - in.index); - blog(LOG_INFO, "Found input '%s' (Index %d)", in.name, - in.index); - } + obs_property_list_add_int(prop, (char *) in.name, in.index); + blog(LOG_INFO, "Found input '%s' (Index %d)", in.name, + in.index); in.index++; } } From 96b994afb2d492aefd50c620663a6659444c6865 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 16 Feb 2015 22:29:39 +0100 Subject: [PATCH 2/7] linux-v4l2: Add helper function to get input caps Add a helper function to get the capabilities of a specific or the currently selected input of the device. --- plugins/linux-v4l2/v4l2-helpers.c | 21 +++++++++++++++++++++ plugins/linux-v4l2/v4l2-helpers.h | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/plugins/linux-v4l2/v4l2-helpers.c b/plugins/linux-v4l2/v4l2-helpers.c index 657b221b9..ffb8eedf0 100644 --- a/plugins/linux-v4l2/v4l2-helpers.c +++ b/plugins/linux-v4l2/v4l2-helpers.c @@ -133,6 +133,27 @@ int_fast32_t v4l2_set_input(int_fast32_t dev, int *input) : v4l2_ioctl(dev, VIDIOC_S_INPUT, input); } +int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps) +{ + if (!dev || !caps) + return -1; + + if (input == -1) { + if (v4l2_ioctl(dev, VIDIOC_G_INPUT, &input) < 0) + return -1; + } + + struct v4l2_input in; + memset(&in, 0, sizeof(in)); + in.index = input; + + if (v4l2_ioctl(dev, VIDIOC_ENUMINPUT, &in) < 0) + return -1; + + *caps = in.capabilities; + return 0; +} + int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, int *pixelformat, int *bytesperline) { diff --git a/plugins/linux-v4l2/v4l2-helpers.h b/plugins/linux-v4l2/v4l2-helpers.h index 6b5d862e7..79facf1cd 100644 --- a/plugins/linux-v4l2/v4l2-helpers.h +++ b/plugins/linux-v4l2/v4l2-helpers.h @@ -219,6 +219,17 @@ int_fast32_t v4l2_destroy_mmap(struct v4l2_buffer_data *buf); */ int_fast32_t v4l2_set_input(int_fast32_t dev, int *input); +/** + * Get capabilities for an input. + * + * @param dev handle for the v4l2 device + * @param input index of the input or -1 to use the currently selected + * @param caps capabilities for the input + * + * @return negative on failure + */ +int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps); + /** * Set the video format on the device. * From cc57222aa97f32adf00821fea1981c5f9bb80f5b Mon Sep 17 00:00:00 2001 From: fryshorts Date: Tue, 17 Feb 2015 20:09:58 +0100 Subject: [PATCH 3/7] linux-v4l2: Add function to enum video standards Add a helper function to enumerate video standards supported by the selected input and add them to a property. --- plugins/linux-v4l2/v4l2-input.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index 2374db2d6..d8218af2e 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -379,6 +379,24 @@ static void v4l2_format_list(int dev, obs_property_t *prop) dstr_free(&buffer); } +/* + * List video standards for the device + */ +static void v4l2_standard_list(int dev, obs_property_t *prop) +{ + struct v4l2_standard std; + std.index = 0; + + obs_property_list_clear(prop); + + obs_property_list_add_int(prop, obs_module_text("LeaveUnchanged"), -1); + + while (v4l2_ioctl(dev, VIDIOC_ENUMSTD, &std) == 0) { + obs_property_list_add_int(prop, (char *) std.name, std.id); + std.index++; + } +} + /* * List resolutions for device and format */ From bab2aa24d5d9b0e7d1cd29b5de8ed6f705031112 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Tue, 17 Feb 2015 20:16:12 +0100 Subject: [PATCH 4/7] linux-v4l2: Add video standard property Add the video standard property and hide it by default. --- plugins/linux-v4l2/data/locale/en-US.ini | 1 + plugins/linux-v4l2/v4l2-input.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/plugins/linux-v4l2/data/locale/en-US.ini b/plugins/linux-v4l2/data/locale/en-US.ini index d798c18ad..a1baf84ba 100644 --- a/plugins/linux-v4l2/data/locale/en-US.ini +++ b/plugins/linux-v4l2/data/locale/en-US.ini @@ -2,6 +2,7 @@ V4L2Input="Video Capture Device (V4L2)" Device="Device" Input="Input" ImageFormat="Video Format" +VideoStandard="Video Standard" Resolution="Resolution" FrameRate="Frame Rate" LeaveUnchanged="Leave Unchanged" diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index d8218af2e..923a3648e 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -214,6 +214,7 @@ static void v4l2_defaults(obs_data_t *settings) { obs_data_set_default_int(settings, "input", -1); obs_data_set_default_int(settings, "pixelformat", -1); + obs_data_set_default_int(settings, "standard", -1); obs_data_set_default_int(settings, "resolution", -1); obs_data_set_default_int(settings, "framerate", -1); obs_data_set_default_bool(settings, "system_timing", false); @@ -644,6 +645,11 @@ static obs_properties_t *v4l2_properties(void *vptr) "pixelformat", obs_module_text("VideoFormat"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *standard_list = obs_properties_add_list(props, + "standard", obs_module_text("VideoStandard"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_set_visible(standard_list, false); + obs_property_t *resolution_list = obs_properties_add_list(props, "resolution", obs_module_text("Resolution"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); From a9df1d921ae121c12a90348c66996ba4356fb4f5 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Tue, 17 Feb 2015 20:02:11 +0100 Subject: [PATCH 5/7] linux-v4l2: Use input caps for properties Use the capabilities for the selected input to decide which properties are enumerated and displayed. --- plugins/linux-v4l2/v4l2-input.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index 923a3648e..a0d13ada4 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -551,12 +551,34 @@ static bool format_selected(obs_properties_t *props, obs_property_t *p, if (dev == -1) return false; - obs_property_t *prop = obs_properties_get(props, "resolution"); - v4l2_resolution_list(dev, obs_data_get_int(settings, "pixelformat"), - prop); + int input = (int) obs_data_get_int(settings, "input"); + uint32_t caps = 0; + if (v4l2_get_input_caps(dev, input, &caps) < 0) + return false; + caps &= V4L2_IN_CAP_STD; + + obs_property_t *resolution = obs_properties_get(props, "resolution"); + obs_property_t *framerate = obs_properties_get(props, "framerate"); + obs_property_t *standard = obs_properties_get(props, "standard"); + + obs_property_set_visible(resolution, (!caps) ? true : false); + obs_property_set_visible(framerate, (!caps) ? true : false); + obs_property_set_visible(standard, + (caps & V4L2_IN_CAP_STD) ? true : false); + + if (!caps) { + v4l2_resolution_list(dev, obs_data_get_int( + settings, "pixelformat"), resolution); + } + if (caps & V4L2_IN_CAP_STD) + v4l2_standard_list(dev, standard); + v4l2_close(dev); - obs_property_modified(prop, settings); + if (!caps) + obs_property_modified(resolution, settings); + if (caps & V4L2_IN_CAP_STD) + obs_property_modified(standard, settings); return true; } From 7dc9069c1b2ba6ffbdf7a768744b37cea532e7e9 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 23 Feb 2015 21:08:57 +0100 Subject: [PATCH 6/7] linux-v4l2: Add helper function for video standard Add a helper function to get/set the video standard for the input. --- plugins/linux-v4l2/v4l2-helpers.c | 16 ++++++++++++++++ plugins/linux-v4l2/v4l2-helpers.h | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/plugins/linux-v4l2/v4l2-helpers.c b/plugins/linux-v4l2/v4l2-helpers.c index ffb8eedf0..2c824e55c 100644 --- a/plugins/linux-v4l2/v4l2-helpers.c +++ b/plugins/linux-v4l2/v4l2-helpers.c @@ -220,3 +220,19 @@ int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate) par.parm.capture.timeperframe.denominator); return 0; } + +int_fast32_t v4l2_set_standard(int_fast32_t dev, int *standard) +{ + if (!dev || !standard) + return -1; + + if (*standard == -1) { + if (v4l2_ioctl(dev, VIDIOC_G_STD, standard) < 0) + return -1; + } else { + if (v4l2_ioctl(dev, VIDIOC_S_STD, standard) < 0) + return -1; + } + + return 0; +} diff --git a/plugins/linux-v4l2/v4l2-helpers.h b/plugins/linux-v4l2/v4l2-helpers.h index 79facf1cd..5ee28fd4a 100644 --- a/plugins/linux-v4l2/v4l2-helpers.h +++ b/plugins/linux-v4l2/v4l2-helpers.h @@ -258,6 +258,18 @@ int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, */ int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate); +/** + * Set a video standard on the device. + * + * If the action succeeds standard is set to the used video standard id. + * + * @param dev handle to the v4l2 device + * @param standard id of the standard to use or -1 to leave as is + * + * @return negative on failure + */ +int_fast32_t v4l2_set_standard(int_fast32_t dev, int *standard); + #ifdef __cplusplus } #endif From f38347acc6ed8670ddf01cfa8a9d37f53b55cf1a Mon Sep 17 00:00:00 2001 From: fryshorts Date: Mon, 23 Feb 2015 21:22:24 +0100 Subject: [PATCH 7/7] linux-v4l2: Use video standard property in source Use the video standard selected in the source properties to configure the device instead of resolution/framerate. --- plugins/linux-v4l2/v4l2-input.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index a0d13ada4..cf0bfebd3 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -56,6 +56,7 @@ struct v4l2_data { char *device_id; int input; int pixfmt; + int standard; int resolution; int framerate; bool sys_timing; @@ -744,6 +745,7 @@ static void v4l2_destroy(void *vptr) */ static void v4l2_init(struct v4l2_data *data) { + uint32_t input_caps; int fps_num, fps_denom; blog(LOG_INFO, "Start capture from %s", data->device_id); @@ -759,6 +761,20 @@ static void v4l2_init(struct v4l2_data *data) goto fail; } blog(LOG_INFO, "Input: %d", data->input); + if (v4l2_get_input_caps(data->dev, -1, &input_caps) < 0) { + blog(LOG_ERROR, "Unable to get input capabilities"); + goto fail; + } + + /* set video standard if supported */ + if (input_caps & V4L2_IN_CAP_STD) { + if (v4l2_set_standard(data->dev, &data->standard) < 0) { + blog(LOG_ERROR, "Unable to set video standard"); + goto fail; + } + data->resolution = -1; + data->framerate = -1; + } /* set pixel format and resolution */ if (v4l2_set_format(data->dev, &data->resolution, &data->pixfmt, @@ -820,6 +836,7 @@ static void v4l2_update(void *vptr, obs_data_t *settings) data->device_id = bstrdup(obs_data_get_string(settings, "device_id")); data->input = obs_data_get_int(settings, "input"); data->pixfmt = obs_data_get_int(settings, "pixelformat"); + data->standard = obs_data_get_int(settings, "standard"); data->resolution = obs_data_get_int(settings, "resolution"); data->framerate = obs_data_get_int(settings, "framerate"); data->sys_timing = obs_data_get_bool(settings, "system_timing");