From: Guennadi L. <g.l...@gm...> - 2010-03-10 19:24:59
|
Linux video (v4l2) output drivers can support multiple TV norms, add a parameter to the v4l2sink plugin to select one. Signed-off-by: Guennadi Liakhovetski <g.l...@gm...> --- Ok, I have no idea what's the patch submission procudure here, for now I just followed the one I'm familiar with - from the Linux kernel. Feel free to point me out to some doc. diff -u a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c --- a/sys/v4l2/gstv4l2sink.c 2010-03-08 16:41:32.000000000 +0100 +++ b/sys/v4l2/gstv4l2sink.c 2010-03-10 19:44:29.000000000 +0100 @@ -75,6 +75,7 @@ PROP_OVERLAY_LEFT, PROP_OVERLAY_WIDTH, PROP_OVERLAY_HEIGHT, + PROP_TV_NORM, }; @@ -251,6 +252,11 @@ "The height of the video overlay; default is equal to negotiated image height", 0, 0xffffffff, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TV_NORM, + g_param_spec_string ("tv-norm", "TV norm", + "One of NTSC-M, NTSC-J, NTSC-443, PAL-B, PAL-M, PAL-N", + "NTSC-M", G_PARAM_READWRITE)); + basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_get_caps); basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_set_caps); basesink_class->buffer_alloc = GST_DEBUG_FUNCPTR (gst_v4l2sink_buffer_alloc); @@ -280,6 +286,7 @@ v4l2sink->overlay_fields_set = 0; v4l2sink->state = 0; + v4l2sink->tv_norm = V4L2_STD_NTSC_M; } @@ -367,6 +374,7 @@ gst_v4l2sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { + const gchar *norm; GstV4l2Sink *v4l2sink = GST_V4L2SINK (object); if (!gst_v4l2_object_set_property_helper (v4l2sink->v4l2object, @@ -395,6 +403,23 @@ v4l2sink->overlay_fields_set |= OVERLAY_HEIGHT_SET; gst_v4l2sink_sync_overlay_fields (v4l2sink); break; + case PROP_TV_NORM: + norm = g_value_get_string (value); + if (strcmp (norm, "NTSC-M") == 0) + v4l2sink->tv_norm = V4L2_STD_NTSC_M; + else if (strcmp (norm, "NTSC-J") == 0) + v4l2sink->tv_norm = V4L2_STD_NTSC_M_JP; + else if (strcmp (norm, "NTSC-443") == 0) + v4l2sink->tv_norm = V4L2_STD_NTSC_443; + else if (strcmp (norm, "PAL-B") == 0) + v4l2sink->tv_norm = V4L2_STD_PAL_B; + else if (strcmp (norm, "PAL-M") == 0) + v4l2sink->tv_norm = V4L2_STD_PAL_M; + else if (strcmp (norm, "PAL-N") == 0) + v4l2sink->tv_norm = V4L2_STD_PAL_N; + else + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -427,6 +452,28 @@ case PROP_OVERLAY_HEIGHT: g_value_set_uint (value, v4l2sink->overlay.height); break; + case PROP_TV_NORM: + switch (v4l2sink->tv_norm) { + case V4L2_STD_NTSC_M: + g_value_set_string (value, "NTSC-M"); + break; + case V4L2_STD_NTSC_M_JP: + g_value_set_string (value, "NTSC-J"); + break; + case V4L2_STD_NTSC_443: + g_value_set_string (value, "NTSC-443"); + break; + case V4L2_STD_PAL_B: + g_value_set_string (value, "PAL-B"); + break; + case V4L2_STD_PAL_M: + g_value_set_string (value, "PAL-M"); + break; + case V4L2_STD_PAL_N: + g_value_set_string (value, "PAL-N"); + break; + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -591,6 +638,11 @@ return FALSE; } + if (!gst_v4l2_set_norm (v4l2sink->v4l2object, v4l2sink->tv_norm)) { + GST_DEBUG_OBJECT (v4l2sink, "unsupported TV norm %llx", v4l2sink->tv_norm); + return FALSE; + } + gst_v4l2sink_sync_overlay_fields (v4l2sink); v4l2sink->current_caps = gst_caps_ref (caps); diff -u a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h --- a/sys/v4l2/gstv4l2sink.h 2009-11-20 10:59:46.000000000 +0100 +++ b/sys/v4l2/gstv4l2sink.h 2010-03-10 19:34:54.000000000 +0100 @@ -28,6 +28,7 @@ #include <gst/video/gstvideosink.h> #include <gstv4l2object.h> #include <gstv4l2bufferpool.h> +#include <linux/videodev2.h> GST_DEBUG_CATEGORY_EXTERN (v4l2sink_debug); @@ -72,6 +73,7 @@ guint8 overlay_fields_set; guint8 state; + v4l2_std_id tv_norm; }; struct _GstV4l2SinkClass { |