summaryrefslogtreecommitdiff
blob: 345f9dffffb03f7c9cc768c0b49f7e1065b66d49 (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
From 15c17ea368079fd5de19868af6d9ffad1cb09f3a Mon Sep 17 00:00:00 2001
From: Rob Clark <rob@ti.com>
Date: Wed, 19 May 2010 17:33:46 -0500
Subject: [PATCH 07/11] use GstQueryBuffers to get buffer requirements

---
 sys/v4l2/gstv4l2sink.c |   40 ++++++++++++++++++++++++++++++++++++++++
 sys/v4l2/gstv4l2sink.h |    1 +
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
index 66dda8e..12323f7 100644
--- a/sys/v4l2/gstv4l2sink.c
+++ b/sys/v4l2/gstv4l2sink.c
@@ -373,6 +373,7 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink, GstV4l2SinkClass * klass)
 
   /* number of buffers requested */
   v4l2sink->num_buffers = PROP_DEF_QUEUE_SIZE;
+  v4l2sink->num_buffers_can_change = TRUE;
   v4l2sink->min_queued_bufs = PROP_DEF_MIN_QUEUED_BUFS;
 
   v4l2sink->probed_caps = NULL;
@@ -808,6 +809,7 @@ static gboolean
 gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
 {
   GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
+  GstQuery *query;
   gint w = 0, h = 0;
   gboolean interlaced;
   struct v4l2_fmtdesc *format;
@@ -855,6 +857,39 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
     return FALSE;
   }
 
+  /* query to find if anyone upstream using these buffers has any
+   * minimum requirements:
+   */
+  query = gst_query_new_buffers (caps);
+  if (gst_element_query (GST_ELEMENT (v4l2sink), query)) {
+    gint min_buffers, min_width, min_height;
+
+    gst_query_parse_buffers_count (query, &min_buffers);
+
+    /* XXX need to account for some buffers used by queue, etc.. probably
+     * queue should handle query, pass on to sink pad, and then add some
+     * number of buffers to the min, so this value is dynamic depending
+     * on the pipeline?
+     */
+    if (min_buffers != -1) {
+      min_buffers += 3 + v4l2sink->min_queued_bufs;
+    }
+
+    if (min_buffers > v4l2sink->num_buffers) {
+      v4l2sink->num_buffers_can_change = FALSE;
+      v4l2sink->num_buffers = min_buffers;
+    }
+
+    gst_query_parse_buffers_dimensions (query, &min_width, &min_height);
+    if (min_width > w) {
+      w = min_width;
+    }
+    if (min_height > h) {
+      h = min_height;
+    }
+  }
+  gst_query_unref (query);
+
   if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, format->pixelformat,
           w, h, interlaced)) {
     /* error already posted */
@@ -944,6 +979,11 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
       GST_INFO_OBJECT (v4l2sink, "outputting buffers via mmap()");
 
       if (v4l2sink->num_buffers != v4l2sink->pool->buffer_count) {
+        if (!v4l2sink->num_buffers_can_change) {
+          GST_WARNING_OBJECT (v4l2sink,
+              "I can't handle a differing number of buffers!!!!");
+          return GST_FLOW_ERROR;
+        }
         v4l2sink->num_buffers = v4l2sink->pool->buffer_count;
         g_object_notify (G_OBJECT (v4l2sink), "queue-size");
       }
diff --git a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h
index 907973a..7649fa1 100644
--- a/sys/v4l2/gstv4l2sink.h
+++ b/sys/v4l2/gstv4l2sink.h
@@ -58,6 +58,7 @@ struct _GstV4l2Sink {
   GstCaps *current_caps;        /* the current negotiated caps */
   GstV4l2BufferPool *pool;
   guint32 num_buffers;
+  gboolean num_buffers_can_change;
   guint32 min_queued_bufs;
 
   gint video_width, video_height;      /* original (unscaled) video w/h */
-- 
1.7.1