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
|
From e7497b9f0c6c88b764d8f95e01197e2a2ea0dd95 Mon Sep 17 00:00:00 2001
From: Rob Clark <rob@ti.com>
Date: Tue, 25 May 2010 11:02:45 -0500
Subject: [PATCH 09/11] use GstEventCrop to get crop info
---
sys/v4l2/gstv4l2sink.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 62 insertions(+), 1 deletions(-)
diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
index a1f78cf..feafe7a 100644
--- a/sys/v4l2/gstv4l2sink.c
+++ b/sys/v4l2/gstv4l2sink.c
@@ -252,6 +252,7 @@ static GstCaps *gst_v4l2sink_get_caps (GstBaseSink * bsink);
static gboolean gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static GstFlowReturn gst_v4l2sink_buffer_alloc (GstBaseSink * bsink,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_v4l2sink_event (GstBaseSink * bsink, GstEvent * event);
static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink,
GstBuffer * buf);
static void gst_v4l2sink_sync_rotation (GstV4l2Sink * v4l2sink);
@@ -354,6 +355,7 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
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);
+ basesink_class->event = GST_DEBUG_FUNCPTR (gst_v4l2sink_event);
basesink_class->render = GST_DEBUG_FUNCPTR (gst_v4l2sink_show_frame);
}
@@ -895,11 +897,22 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
gst_query_parse_buffers_dimensions (query, &min_width, &min_height);
if (min_width > w) {
+ v4l2sink->crop.width = w;
+ v4l2sink->crop_fields_set |= RECT_WIDTH_SET;
w = min_width;
}
if (min_height > h) {
+ v4l2sink->crop.height = h;
+ v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
h = min_height;
}
+
+ /* clear top/left crop values.. otherwise by default display will try
+ * to center, rather than scale, the image if it is too big to fit on
+ * display
+ */
+ v4l2sink->crop.top = v4l2sink->crop.left = 0;
+ v4l2sink->crop_fields_set |= RECT_TOP_SET | RECT_LEFT_SET;
}
gst_query_unref (query);
@@ -919,7 +932,13 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
GST_VIDEO_SINK_WIDTH (v4l2sink) = w;
GST_VIDEO_SINK_HEIGHT (v4l2sink) = h;
- v4l2sink->current_caps = gst_caps_ref (caps);
+ /* this needs to go after gst_v4l2_object_set_format() to ensure driver
+ * has proper width/height (so we don't confuse it's error checking by
+ * setting a crop larger than the picture size)
+ */
+ gst_v4l2sink_sync_crop_fields (v4l2sink);
+
+ v4l2sink->current_caps = caps;
return TRUE;
}
@@ -1023,6 +1042,48 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
}
}
+/* called to handle events */
+static gboolean
+gst_v4l2sink_event (GstBaseSink * bsink, GstEvent * event)
+{
+ GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
+ GstEventType type = GST_EVENT_TYPE (event);
+
+ GST_DEBUG_OBJECT (v4l2sink, "event %" GST_PTR_FORMAT, event);
+
+ switch (type) {
+ case GST_EVENT_CROP:{
+ gint top, left, width, height;
+ gst_event_parse_crop (event, &top, &left, &width, &height);
+ if (top >= 0) {
+ v4l2sink->crop.top = top;
+ v4l2sink->crop_fields_set |= RECT_TOP_SET;
+ }
+ if (left >= 0) {
+ v4l2sink->crop.left = left;
+ v4l2sink->crop_fields_set |= RECT_LEFT_SET;
+ }
+ if (width >= 0) {
+ v4l2sink->crop.width = width;
+ v4l2sink->crop_fields_set |= RECT_WIDTH_SET;
+ }
+ if (height >= 0) {
+ v4l2sink->crop.height = height;
+ v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
+ }
+ gst_v4l2sink_sync_crop_fields (v4l2sink);
+ return TRUE;
+ }
+ default:{
+ if (GST_BASE_SINK_CLASS (parent_class)->event) {
+ return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
+ } else {
+ return TRUE;
+ }
+ }
+ }
+}
+
/* called after A/V sync to render frame */
static GstFlowReturn
gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
--
1.7.1
|