From 41e356c0e1460eca622534adea30f6cdf554930e Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Tue, 3 Mar 2015 16:38:18 +0100
Subject: [PATCH v1 2/2] v4l2: add min-buffers properties

Add min-buffers (capture-min-buffers/output-min-buffers) properties to v4l2src,
v4l2sink, v4l2videodec, v4l2videoenc and v4l2transform.
---
 sys/v4l2/gstv4l2bufferpool.c |  7 ++++++
 sys/v4l2/gstv4l2object.c     | 45 ++++++++++++++++++++++++++++++++++++
 sys/v4l2/gstv4l2object.h     |  4 ++++
 sys/v4l2/gstv4l2transform.c  |  2 ++
 sys/v4l2/gstv4l2videodec.c   |  2 ++
 sys/v4l2/gstv4l2videoenc.c   |  2 ++
 6 files changed, 62 insertions(+)

diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
index a57229368..5abef6bcc 100644
--- a/sys/v4l2/gstv4l2bufferpool.c
+++ b/sys/v4l2/gstv4l2bufferpool.c
@@ -551,6 +551,13 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
         | GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS);
   }
 
+  if (min_buffers < obj->custom_min_buffers) {
+    updated = TRUE;
+    min_buffers = obj->custom_min_buffers;
+    GST_INFO_OBJECT (pool, "increasing minimum buffers to %u on user request",
+        min_buffers);
+  }
+
   if (min_buffers < GST_V4L2_MIN_BUFFERS) {
     updated = TRUE;
     min_buffers = GST_V4L2_MIN_BUFFERS;
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
index ee6ebdb4a..85d9187b0 100644
--- a/sys/v4l2/gstv4l2object.c
+++ b/sys/v4l2/gstv4l2object.c
@@ -378,6 +378,16 @@ gst_v4l2_object_install_properties_helper (GObjectClass * gobject_class,
           GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstV4l2Src:min-buffers:
+   *
+   * Minimum allocated buffers
+   */
+  g_object_class_install_property (gobject_class, PROP_MIN_BUFFERS,
+      g_param_spec_int ("min-buffers", "Minimum allocated buffers",
+          "Minimum allocated buffers value",
+          0, G_MAXINT, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstV4l2Src:extra-controls:
    *
@@ -443,12 +453,22 @@ gst_v4l2_object_install_m2m_properties_helper (GObjectClass * gobject_class)
           GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_OUTPUT_MIN_BUFFERS,
+      g_param_spec_int ("output-min-buffers", "Output minimum allocated buffers",
+          "Output minimum allocated buffers value",
+          0, G_MAXINT, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (gobject_class, PROP_CAPTURE_IO_MODE,
       g_param_spec_enum ("capture-io-mode", "Capture IO mode",
           "Capture I/O mode (matches src pad)",
           GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_CAPTURE_MIN_BUFFERS,
+      g_param_spec_int ("capture-min-buffers", "Capture minimum allocated buffers",
+          "Capture minimum allocated buffers value",
+          0, G_MAXINT, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (gobject_class, PROP_EXTRA_CONTROLS,
       g_param_spec_boxed ("extra-controls", "Extra Controls",
           "Extra v4l2 controls (CIDs) for the device",
@@ -497,6 +517,9 @@ gst_v4l2_object_new (GstElement * element,
   v4l2object->update_fps_func = update_fps_func;
 
   v4l2object->video_fd = -1;
+
+  v4l2object->custom_min_buffers = 2;
+
   v4l2object->active = FALSE;
   v4l2object->videodev = g_strdup (default_device);
 
@@ -664,14 +687,25 @@ gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
     case PROP_IO_MODE:
       v4l2object->req_mode = g_value_get_enum (value);
       break;
+    case PROP_MIN_BUFFERS:
+      v4l2object->custom_min_buffers = g_value_get_int (value);
+      break;
     case PROP_CAPTURE_IO_MODE:
       g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
       v4l2object->req_mode = g_value_get_enum (value);
       break;
+    case PROP_CAPTURE_MIN_BUFFERS:
+      g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+      v4l2object->custom_min_buffers = g_value_get_int (value);
+      break;
     case PROP_OUTPUT_IO_MODE:
       g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
       v4l2object->req_mode = g_value_get_enum (value);
       break;
+    case PROP_OUTPUT_MIN_BUFFERS:
+      g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+      v4l2object->custom_min_buffers = g_value_get_int (value);
+      break;
     case PROP_EXTRA_CONTROLS:{
       const GstStructure *s = gst_value_get_structure (value);
 
@@ -781,14 +815,25 @@ gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object,
     case PROP_IO_MODE:
       g_value_set_enum (value, v4l2object->req_mode);
       break;
+    case PROP_MIN_BUFFERS:
+      g_value_set_int (value, v4l2object->custom_min_buffers);
+      break;
     case PROP_CAPTURE_IO_MODE:
       g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
       g_value_set_enum (value, v4l2object->req_mode);
       break;
+    case PROP_CAPTURE_MIN_BUFFERS:
+      g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+      g_value_set_int (value, v4l2object->custom_min_buffers);
+      break;
     case PROP_OUTPUT_IO_MODE:
       g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
       g_value_set_enum (value, v4l2object->req_mode);
       break;
+    case PROP_OUTPUT_MIN_BUFFERS:
+      g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+      g_value_set_int (value, v4l2object->custom_min_buffers);
+      break;
     case PROP_EXTRA_CONTROLS:
       gst_value_set_structure (value, v4l2object->extra_controls);
       break;
diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
index 9097a48f7..dd46eb4c8 100644
--- a/sys/v4l2/gstv4l2object.h
+++ b/sys/v4l2/gstv4l2object.h
@@ -122,6 +122,7 @@ struct _GstV4l2Object {
   /* the video-device's file descriptor */
   gint video_fd;
   GstV4l2IOMode mode;
+  gint custom_min_buffers;
 
   gboolean active;
   gboolean streaming;
@@ -228,8 +229,11 @@ GType gst_v4l2_object_get_type (void);
     PROP_HUE,                 \
     PROP_TV_NORM,             \
     PROP_IO_MODE,             \
+    PROP_MIN_BUFFERS,         \
     PROP_OUTPUT_IO_MODE,      \
+    PROP_OUTPUT_MIN_BUFFERS,  \
     PROP_CAPTURE_IO_MODE,     \
+    PROP_CAPTURE_MIN_BUFFERS, \
     PROP_EXTRA_CONTROLS,      \
     PROP_PIXEL_ASPECT_RATIO,  \
     PROP_FORCE_ASPECT_RATIO
diff --git a/sys/v4l2/gstv4l2transform.c b/sys/v4l2/gstv4l2transform.c
index 98f7dd87a..453886788 100644
--- a/sys/v4l2/gstv4l2transform.c
+++ b/sys/v4l2/gstv4l2transform.c
@@ -69,6 +69,7 @@ gst_v4l2_transform_set_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       gst_v4l2_object_set_property_helper (self->v4l2capture, prop_id, value,
           pspec);
       break;
@@ -91,6 +92,7 @@ gst_v4l2_transform_get_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       gst_v4l2_object_get_property_helper (self->v4l2capture, prop_id, value,
           pspec);
       break;
diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c
index a00ccd92a..81624f278 100644
--- a/sys/v4l2/gstv4l2videodec.c
+++ b/sys/v4l2/gstv4l2videodec.c
@@ -67,6 +67,7 @@ gst_v4l2_video_dec_set_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       if (!gst_v4l2_object_set_property_helper (self->v4l2capture,
               prop_id, value, pspec)) {
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -91,6 +92,7 @@ gst_v4l2_video_dec_get_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       if (!gst_v4l2_object_get_property_helper (self->v4l2capture,
               prop_id, value, pspec)) {
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/sys/v4l2/gstv4l2videoenc.c b/sys/v4l2/gstv4l2videoenc.c
index 5b6b81001..962d1c4a8 100644
--- a/sys/v4l2/gstv4l2videoenc.c
+++ b/sys/v4l2/gstv4l2videoenc.c
@@ -65,6 +65,7 @@ gst_v4l2_video_enc_set_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       if (!gst_v4l2_object_set_property_helper (self->v4l2capture,
               prop_id, value, pspec)) {
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -89,6 +90,7 @@ gst_v4l2_video_enc_get_property (GObject * object,
 
   switch (prop_id) {
     case PROP_CAPTURE_IO_MODE:
+    case PROP_CAPTURE_MIN_BUFFERS:
       if (!gst_v4l2_object_get_property_helper (self->v4l2capture,
               prop_id, value, pspec)) {
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-- 
2.17.1

