summaryrefslogtreecommitdiff
blob: 11b777c2b363bae8e4f3873bb49fb86c08e1888e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From d43a9444fc5f7655a8acd2978039667a04222ba0 Mon Sep 17 00:00:00 2001
From: Kiran Nataraju <knataraju@ti.com>
Date: Fri, 27 Aug 2010 09:00:57 +0200
Subject: [PATCH 02/11] v4l2sink: Add rotation support.

Signed-off-by: Kiran Nataraju <knataraju@ti.com>
Signed-off-by: Daniel Diaz <ddiaz@ti.com>
---
 sys/v4l2/gstv4l2sink.c |   34 ++++++++++++++++++++++++++++++++++
 sys/v4l2/gstv4l2sink.h |    1 +
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
index aa6785c..5abf915 100644
--- a/sys/v4l2/gstv4l2sink.c
+++ b/sys/v4l2/gstv4l2sink.c
@@ -72,6 +72,10 @@ GST_DEBUG_CATEGORY (v4l2sink_debug);
 #define PROP_DEF_MIN_QUEUED_BUFS    1
 #define DEFAULT_PROP_DEVICE   "/dev/video1"
 
+#define MIN_ROTATION_ANGLE 0
+#define MAX_ROTATION_ANGLE 360
+#define DEFAULT_ROTATION_ANGLE 0
+
 enum
 {
   PROP_0,
@@ -86,6 +90,7 @@ enum
   PROP_CROP_LEFT,
   PROP_CROP_WIDTH,
   PROP_CROP_HEIGHT,
+  PROP_ROTATION,
 };
 
 
@@ -220,6 +225,7 @@ static GstFlowReturn gst_v4l2sink_buffer_alloc (GstBaseSink * bsink,
     guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
 static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink,
     GstBuffer * buf);
+static void gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink);
 
 static void
 gst_v4l2sink_base_init (gpointer g_class)
@@ -306,6 +312,11 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
           "The height of the video crop; default is equal to negotiated image height",
           0, 0xffffffff, 0, G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class, PROP_ROTATION,
+      g_param_spec_int ("rotation", "Rotation angle",
+          "Rotation angle for the image", MIN_ROTATION_ANGLE,
+          MAX_ROTATION_ANGLE, DEFAULT_ROTATION_ANGLE, 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);
@@ -336,6 +347,7 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink, GstV4l2SinkClass * klass)
   v4l2sink->overlay_fields_set = 0;
   v4l2sink->crop_fields_set = 0;
   v4l2sink->state = 0;
+  v4l2sink->rotation = 0;
 }
 
 
@@ -475,6 +487,20 @@ gst_v4l2sink_sync_crop_fields (GstV4l2Sink * v4l2sink)
   }
 }
 
+static void
+gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink)
+{
+  if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
+    struct v4l2_control control;
+    gint fd = v4l2sink->v4l2object->video_fd;
+
+    memset (&control, 0x00, sizeof (struct v4l2_control));
+    control.id = V4L2_CID_ROTATE;
+    control.value = v4l2sink->rotation;
+    g_return_if_fail (v4l2_ioctl (fd, VIDIOC_S_CTRL, &control) >= 0);
+  }
+}
+
 
 static void
 gst_v4l2sink_set_property (GObject * object,
@@ -531,6 +557,10 @@ gst_v4l2sink_set_property (GObject * object,
         v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
         gst_v4l2sink_sync_crop_fields (v4l2sink);
         break;
+      case PROP_ROTATION:
+        v4l2sink->rotation = g_value_get_int (value);
+        gst_v4l2sink_set_rotation (v4l2sink);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -578,6 +608,9 @@ gst_v4l2sink_get_property (GObject * object,
       case PROP_CROP_HEIGHT:
         g_value_set_uint (value, v4l2sink->crop.height);
         break;
+      case PROP_ROTATION:
+        g_value_set_int (value, v4l2sink->rotation);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -600,6 +633,7 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
       /* open the device */
       if (!gst_v4l2_object_start (v4l2sink->v4l2object))
         return GST_STATE_CHANGE_FAILURE;
+      gst_v4l2sink_set_rotation (v4l2sink);
       break;
     default:
       break;
diff --git a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h
index 8fe8222..1239621 100644
--- a/sys/v4l2/gstv4l2sink.h
+++ b/sys/v4l2/gstv4l2sink.h
@@ -75,6 +75,7 @@ struct _GstV4l2Sink {
   guint8 overlay_fields_set, crop_fields_set;
 
   guint8 state;
+  gint rotation;
 };
 
 struct _GstV4l2SinkClass {
-- 
1.7.1