amlv4l2dec: CB2 amlv4l2dec code style refine [1/1]
PD#SWPL-185554
Problem:
amlv4l2dec plugin code style refine
Solution:
amlv4l2dec plugin code style refine
Verify:
ap222
Change-Id: Id558f2a1e0a21f63d2b47a20139d8baf5dad5659
Signed-off-by: bo.xiao <bo.xiao@amlogic.com>
diff --git a/src/aml-v4l2-utils.c b/src/aml-v4l2-utils.c
index 06f3baa..5562ef1 100644
--- a/src/aml-v4l2-utils.c
+++ b/src/aml-v4l2-utils.c
@@ -32,173 +32,177 @@
struct _GstAmlV4l2GUdevIterator
{
- GstAmlV4l2Iterator parent;
- GList *devices;
- GUdevDevice *device;
- GUdevClient *client;
+ GstAmlV4l2Iterator parent;
+ GList *devices;
+ GUdevDevice *device;
+ GUdevClient *client;
};
GstAmlV4l2Iterator *
gst_aml_v4l2_iterator_new(void)
{
- static const gchar *subsystems[] = {"video4linux", NULL};
- struct _GstAmlV4l2GUdevIterator *it;
+ static const gchar *subsystems[] = { "video4linux", NULL };
+ struct _GstAmlV4l2GUdevIterator *it;
- it = g_slice_new0(struct _GstAmlV4l2GUdevIterator);
+ it = g_slice_new0(struct _GstAmlV4l2GUdevIterator);
- it->client = g_udev_client_new(subsystems);
- it->devices = g_udev_client_query_by_subsystem(it->client, "video4linux");
+ it->client = g_udev_client_new (subsystems);
+ it->devices = g_udev_client_query_by_subsystem (it->client, "video4linux");
- return (GstAmlV4l2Iterator *)it;
+ return (GstAmlV4l2Iterator *)it;
}
gboolean
gst_aml_v4l2_iterator_next(GstAmlV4l2Iterator *_it)
{
- struct _GstAmlV4l2GUdevIterator *it = (struct _GstAmlV4l2GUdevIterator *)_it;
- const gchar *device_name;
+ struct _GstAmlV4l2GUdevIterator *it = (struct _GstAmlV4l2GUdevIterator *)_it;
+ const gchar *device_name;
- if (it->device)
- g_object_unref(it->device);
+ if (it->device)
+ g_object_unref (it->device);
- it->device = NULL;
- it->parent.device_path = NULL;
- it->parent.device_name = NULL;
+ it->device = NULL;
+ it->parent.device_path = NULL;
+ it->parent.device_name = NULL;
- if (it->devices == NULL)
- return FALSE;
+ if (it->devices == NULL)
+ return FALSE;
- it->device = it->devices->data;
- it->devices = g_list_delete_link(it->devices, it->devices);
+ it->device = it->devices->data;
+ it->devices = g_list_delete_link (it->devices, it->devices);
- device_name = g_udev_device_get_property(it->device, "ID_V4L_PRODUCT");
- if (!device_name)
- device_name = g_udev_device_get_property(it->device, "ID_MODEL_ENC");
- if (!device_name)
- device_name = g_udev_device_get_property(it->device, "ID_MODEL");
+ device_name = g_udev_device_get_property (it->device, "ID_V4L_PRODUCT");
+ if (!device_name)
+ device_name = g_udev_device_get_property (it->device, "ID_MODEL_ENC");
+ if (!device_name)
+ device_name = g_udev_device_get_property (it->device, "ID_MODEL");
- it->parent.device_path = g_udev_device_get_device_file(it->device);
- it->parent.device_name = device_name;
- it->parent.sys_path = g_udev_device_get_sysfs_path(it->device);
+ it->parent.device_path = g_udev_device_get_device_file (it->device);
+ it->parent.device_name = device_name;
+ it->parent.sys_path = g_udev_device_get_sysfs_path (it->device);
- return TRUE;
+ return TRUE;
}
-void gst_aml_v4l2_iterator_free(GstAmlV4l2Iterator *_it)
+void
+gst_aml_v4l2_iterator_free (GstAmlV4l2Iterator *_it)
{
- struct _GstAmlV4l2GUdevIterator *it = (struct _GstAmlV4l2GUdevIterator *)_it;
- g_list_free_full(it->devices, g_object_unref);
- gst_object_unref(it->client);
- g_slice_free(struct _GstAmlV4l2GUdevIterator, it);
+ struct _GstAmlV4l2GUdevIterator *it = (struct _GstAmlV4l2GUdevIterator *) _it;
+ g_list_free_full (it->devices, g_object_unref);
+ gst_object_unref (it->client);
+ g_slice_free(struct _GstAmlV4l2GUdevIterator, it);
}
#else /* No GUDEV */
struct _GstAmlV4l2FsIterator
{
- GstAmlV4l2Iterator parent;
- gint base_idx;
- gint video_idx;
- gchar *device;
+ GstAmlV4l2Iterator parent;
+ gint base_idx;
+ gint video_idx;
+ gchar *device;
};
GstAmlV4l2Iterator *
-gst_aml_v4l2_iterator_new(void)
+gst_aml_v4l2_iterator_new (void)
{
- struct _GstAmlV4l2FsIterator *it;
+ struct _GstAmlV4l2FsIterator *it;
- it = g_slice_new0(struct _GstAmlV4l2FsIterator);
- it->base_idx = 0;
- it->video_idx = -1;
- it->device = NULL;
- it->parent.device_path = NULL;
+ it = g_slice_new0(struct _GstAmlV4l2FsIterator);
+ it->base_idx = 0;
+ it->video_idx = -1;
+ it->device = NULL;
+ it->parent.device_path = NULL;
- return (GstAmlV4l2Iterator *)it;
+ return (GstAmlV4l2Iterator *) it;
}
gboolean
-gst_aml_v4l2_iterator_next(GstAmlV4l2Iterator *_it)
+gst_aml_v4l2_iterator_next (GstAmlV4l2Iterator * _it)
{
- struct _GstAmlV4l2FsIterator *it = (struct _GstAmlV4l2FsIterator *)_it;
- static const gchar *dev_base[] = {"/dev/video", "/dev/v4l2/video", NULL};
- gchar *device = NULL;
+ struct _GstAmlV4l2FsIterator *it = (struct _GstAmlV4l2FsIterator *)_it;
+ static const gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL };
+ gchar *device = NULL;
- if (it->parent.device_path) {
- g_free((gchar *)it->parent.device_path);
- it->parent.device_path = NULL;
- }
+ if (it->parent.device_path) {
+ g_free((gchar *)it->parent.device_path);
+ it->parent.device_path = NULL;
+ }
- while (device == NULL)
+ while (device == NULL)
+ {
+ it->video_idx++;
+
+ if (it->video_idx >= 64)
{
- it->video_idx++;
-
- if (it->video_idx >= 64)
- {
- it->video_idx = 0;
- it->base_idx++;
- }
-
- if (dev_base[it->base_idx] == NULL)
- {
- it->video_idx = 0;
- break;
- }
-
- device = g_strdup_printf("%s%d", dev_base[it->base_idx], it->video_idx);
-
- if (g_file_test(device, G_FILE_TEST_EXISTS))
- {
- it->parent.device_path = device;
- break;
- }
-
- g_free(device);
- device = NULL;
+ it->video_idx = 0;
+ it->base_idx++;
}
- return it->parent.device_path != NULL;
+ if (dev_base[it->base_idx] == NULL)
+ {
+ it->video_idx = 0;
+ break;
+ }
+
+ device = g_strdup_printf ("%s%d", dev_base[it->base_idx], it->video_idx);
+
+ if (g_file_test(device, G_FILE_TEST_EXISTS))
+ {
+ it->parent.device_path = device;
+ break;
+ }
+
+ g_free (device);
+ device = NULL;
+ }
+
+ return it->parent.device_path != NULL;
}
-void gst_aml_v4l2_iterator_free(GstAmlV4l2Iterator *_it)
+void
+gst_aml_v4l2_iterator_free (GstAmlV4l2Iterator * _it)
{
- struct _GstAmlV4l2FsIterator *it = (struct _GstAmlV4l2FsIterator *)_it;
- g_free((gchar *)it->parent.device_path);
- g_slice_free(struct _GstAmlV4l2FsIterator, it);
+ struct _GstAmlV4l2FsIterator *it = (struct _GstAmlV4l2FsIterator *)_it;
+ g_free ((gchar *) it->parent.device_path);
+ g_slice_free (struct _GstAmlV4l2FsIterator, it);
}
#endif
-void gst_aml_v4l2_clear_error(GstAmlV4l2Error *v4l2err)
+void
+gst_aml_v4l2_clear_error (GstAmlV4l2Error * v4l2err)
{
- if (v4l2err)
- {
- g_clear_error(&v4l2err->error);
- g_free(v4l2err->dbg_message);
- v4l2err->dbg_message = NULL;
- }
+ if (v4l2err)
+ {
+ g_clear_error (&v4l2err->error);
+ g_free (v4l2err->dbg_message);
+ v4l2err->dbg_message = NULL;
+ }
}
-void gst_aml_v4l2_error(gpointer element, GstAmlV4l2Error *v4l2err)
+void
+gst_aml_v4l2_error (gpointer element, GstAmlV4l2Error * v4l2err)
{
- GError *error;
+ GError *error;
- if (!v4l2err || !v4l2err->error)
- return;
+ if (!v4l2err || !v4l2err->error)
+ return;
- error = v4l2err->error;
+ error = v4l2err->error;
- if (error->message)
- GST_WARNING_OBJECT(element, "error: %s", error->message);
+ if (error->message)
+ GST_WARNING_OBJECT (element, "error: %s", error->message);
- if (v4l2err->dbg_message)
- GST_WARNING_OBJECT(element, "error: %s", v4l2err->dbg_message);
+ if (v4l2err->dbg_message)
+ GST_WARNING_OBJECT (element, "error: %s", v4l2err->dbg_message);
- gst_element_message_full(GST_ELEMENT(element), GST_MESSAGE_ERROR,
- error->domain, error->code, error->message, v4l2err->dbg_message,
- v4l2err->file, v4l2err->func, v4l2err->line);
+ gst_element_message_full (GST_ELEMENT (element), GST_MESSAGE_ERROR,
+ error->domain, error->code, error->message, v4l2err->dbg_message,
+ v4l2err->file, v4l2err->func, v4l2err->line);
- error->message = NULL;
- v4l2err->dbg_message = NULL;
+ error->message = NULL;
+ v4l2err->dbg_message = NULL;
- gst_aml_v4l2_clear_error(v4l2err);
+ gst_aml_v4l2_clear_error (v4l2err);
}
diff --git a/src/aml-v4l2-utils.h b/src/aml-v4l2-utils.h
index 961be22..2586e18 100644
--- a/src/aml-v4l2-utils.h
+++ b/src/aml-v4l2-utils.h
@@ -24,24 +24,20 @@
G_BEGIN_DECLS
-#define GST_AML_V4L2_ERROR_INIT \
- { \
- NULL, NULL \
- }
-#define GST_AML_V4L2_ERROR(v4l2err, domain, code, msg, dbg) \
- { \
- if (v4l2err) \
- { \
- gchar *_msg = _gst_element_error_printf msg; \
- v4l2err->error = g_error_new_literal(GST_##domain##_ERROR, \
- GST_##domain##_ERROR_##code, _msg); \
- g_free(_msg); \
- v4l2err->dbg_message = _gst_element_error_printf dbg; \
- v4l2err->file = __FILE__; \
- v4l2err->func = GST_FUNCTION; \
- v4l2err->line = __LINE__; \
- } \
- }
+#define GST_AML_V4L2_ERROR_INIT { NULL, NULL }
+#define GST_AML_V4L2_ERROR(v4l2err,domain,code,msg,dbg) \
+{\
+ if (v4l2err) { \
+ gchar *_msg = _gst_element_error_printf msg; \
+ v4l2err->error = g_error_new_literal (GST_##domain##_ERROR, \
+ GST_##domain##_ERROR_##code, _msg); \
+ g_free (_msg); \
+ v4l2err->dbg_message = _gst_element_error_printf dbg; \
+ v4l2err->file = __FILE__; \
+ v4l2err->func = GST_FUNCTION; \
+ v4l2err->line = __LINE__; \
+ } \
+}
/**
* GST_AML_V4L2_IS_M2M:
@@ -58,7 +54,7 @@
(((_dcaps) & \
(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) && \
((_dcaps) & \
- (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))))
+ (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))))
typedef struct _GstAmlV4l2Iterator GstAmlV4l2Iterator;
typedef struct _GstAmlV4l2Error GstAmlV4l2Error;
diff --git a/src/aml_v4l2_calls.c b/src/aml_v4l2_calls.c
index 8df6a32..6e094a7 100644
--- a/src/aml_v4l2_calls.c
+++ b/src/aml_v4l2_calls.c
@@ -45,42 +45,41 @@
static gboolean
gst_aml_v4l2_get_capabilities(GstAmlV4l2Object *v4l2object)
{
- GstElement *e;
+ GstElement *e;
- e = v4l2object->element;
+ e = v4l2object->element;
- GST_DEBUG_OBJECT(e, "getting capabilities");
+ GST_DEBUG_OBJECT (e, "getting capabilities");
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_QUERYCAP,
- &v4l2object->vcap) < 0)
- goto cap_failed;
-
- if (v4l2object->vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
- v4l2object->device_caps = v4l2object->vcap.device_caps;
- else
- v4l2object->device_caps = v4l2object->vcap.capabilities;
-
- GST_LOG_OBJECT(e, "driver: '%s'", v4l2object->vcap.driver);
- GST_LOG_OBJECT(e, "card: '%s'", v4l2object->vcap.card);
- GST_LOG_OBJECT(e, "bus_info: '%s'", v4l2object->vcap.bus_info);
- GST_LOG_OBJECT(e, "version: %08x", v4l2object->vcap.version);
- GST_LOG_OBJECT(e, "capabilites: %08x", v4l2object->device_caps);
-
- return TRUE;
-
- /* ERRORS */
-cap_failed:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS,
- (_("Error getting capabilities for device '%s': "
- "It isn't a v4l2 driver. Check if it is a v4l1 driver."),
- v4l2object->videodev),
- GST_ERROR_SYSTEM);
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
-}
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP,
+ &v4l2object->vcap) < 0)
+ goto cap_failed;
+
+ if (v4l2object->vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
+ v4l2object->device_caps = v4l2object->vcap.device_caps;
+ else
+ v4l2object->device_caps = v4l2object->vcap.capabilities;
+
+ GST_LOG_OBJECT (e, "driver: '%s'", v4l2object->vcap.driver);
+ GST_LOG_OBJECT (e, "card: '%s'", v4l2object->vcap.card);
+ GST_LOG_OBJECT (e, "bus_info: '%s'", v4l2object->vcap.bus_info);
+ GST_LOG_OBJECT (e, "version: %08x", v4l2object->vcap.version);
+ GST_LOG_OBJECT (e, "capabilities: %08x", v4l2object->device_caps);
+
+ return TRUE;
+
+ /* ERRORS */
+cap_failed:
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Error getting capabilities for device '%s': "
+ "It isn't a v4l2 driver. Check if it is a v4l1 driver."),
+ v4l2object->videodev), GST_ERROR_SYSTEM);
+ return FALSE;
+ }
}
/******************************************************
@@ -96,71 +95,71 @@
static void
gst_aml_v4l2_normalise_control_name(gchar *name)
{
- int i, j;
- for (i = 0, j = 0; name[j]; ++j)
+ int i, j;
+ for (i = 0, j = 0; name[j]; ++j)
+ {
+ if (g_ascii_isalnum (name[j]))
{
- if (g_ascii_isalnum(name[j]))
- {
- if (i > 0 && !g_ascii_isalnum(name[j - 1]))
- name[i++] = '_';
- name[i++] = g_ascii_tolower(name[j]);
- }
+ if (i > 0 && !g_ascii_isalnum (name[j - 1]))
+ name[i++] = '_';
+ name[i++] = g_ascii_tolower (name[j]);
}
- name[i++] = '\0';
+ }
+ name[i++] = '\0';
}
static void
gst_aml_v4l2_empty_lists(GstAmlV4l2Object *v4l2object)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "deleting enumerations");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "deleting enumerations");
- g_list_foreach(v4l2object->channels, (GFunc)g_object_unref, NULL);
- g_list_free(v4l2object->channels);
- v4l2object->channels = NULL;
+ g_list_foreach (v4l2object->channels, (GFunc) g_object_unref, NULL);
+ g_list_free (v4l2object->channels);
+ v4l2object->channels = NULL;
- g_list_foreach(v4l2object->norms, (GFunc)g_object_unref, NULL);
- g_list_free(v4l2object->norms);
- v4l2object->norms = NULL;
+ g_list_foreach (v4l2object->norms, (GFunc) g_object_unref, NULL);
+ g_list_free (v4l2object->norms);
+ v4l2object->norms = NULL;
- g_list_foreach(v4l2object->colors, (GFunc)g_object_unref, NULL);
- g_list_free(v4l2object->colors);
- v4l2object->colors = NULL;
+ g_list_foreach (v4l2object->colors, (GFunc) g_object_unref, NULL);
+ g_list_free (v4l2object->colors);
+ v4l2object->colors = NULL;
- g_datalist_clear(&v4l2object->controls);
+ g_datalist_clear (&v4l2object->controls);
}
static void
gst_aml_v4l2_adjust_buf_type(GstAmlV4l2Object *v4l2object)
{
- /* when calling gst_aml_v4l2_object_new the user decides the initial type
- * so adjust it if multi-planar is supported
- * the driver should make it exclusive. So the driver should
- * not support both MPLANE and non-PLANE.
- * Because even when using MPLANE it still possibles to use it
- * in a contiguous manner. In this case the first v4l2 plane
- * contains all the gst planes.
- */
- switch (v4l2object->type)
- {
+ /* when calling gst_aml_v4l2_object_new the user decides the initial type
+ * so adjust it if multi-planar is supported
+ * the driver should make it exclusive. So the driver should
+ * not support both MPLANE and non-PLANE.
+ * Because even when using MPLANE it still possibles to use it
+ * in a contiguous manner. In this case the first v4l2 plane
+ * contains all the gst planes.
+ */
+ switch (v4l2object->type)
+ {
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (v4l2object->device_caps &
- (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
- {
- GST_DEBUG("adjust type to multi-planar output");
- v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- }
- break;
+ if (v4l2object->device_caps &
+ (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ {
+ GST_DEBUG ("adjust type to multi-planar output");
+ v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ }
+ break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (v4l2object->device_caps &
- (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
- {
- GST_DEBUG("adjust type to multi-planar capture");
- v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- }
- break;
+ if (v4l2object->device_caps &
+ (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ {
+ GST_DEBUG ("adjust type to multi-planar capture");
+ v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ }
+ break;
default:
- break;
- }
+ break;
+ }
}
gboolean
@@ -231,198 +230,197 @@
gboolean
gst_aml_v4l2_open(GstAmlV4l2Object *v4l2object)
{
- struct stat st;
+ struct stat st;
#ifdef HAVE_LIBV4L2
- int libv4l2_fd = -1;
+ int libv4l2_fd = -1;
#endif
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Trying to open device %s",
- v4l2object->videodev);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to open device %s",
+ v4l2object->videodev);
- GST_AML_V4L2_CHECK_NOT_OPEN(v4l2object);
- GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
+ GST_AML_V4L2_CHECK_NOT_OPEN(v4l2object);
+ GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
- /* be sure we have a device */
- if (!v4l2object->videodev)
- v4l2object->videodev = g_strdup("/dev/video");
+ /* be sure we have a device */
+ if (!v4l2object->videodev)
+ v4l2object->videodev = g_strdup ("/dev/video");
- /* check if it is a device */
- if ((v4l2object->videodev) && stat(v4l2object->videodev, &st) == -1)
- goto stat_failed;
+ /* check if it is a device */
+ if ((v4l2object->videodev) && stat(v4l2object->videodev, &st) == -1)
+ goto stat_failed;
- if (!S_ISCHR(st.st_mode))
- goto no_device;
+ if (!S_ISCHR (st.st_mode))
+ goto no_device;
- /* open the device */
- v4l2object->video_fd =
- open(v4l2object->videodev, O_RDWR /* | O_NONBLOCK */);
+ /* open the device */
+ v4l2object->video_fd =
+ open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ );
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- goto not_open;
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
+ goto not_open;
#ifdef HAVE_LIBV4L2
- if (v4l2object->fd_open)
- libv4l2_fd = v4l2object->fd_open(v4l2object->video_fd,
- V4L2_ENABLE_ENUM_FMT_EMULATION);
- if (libv4l2_fd != -1)
- v4l2object->video_fd = libv4l2_fd;
+ if (v4l2object->fd_open)
+ libv4l2_fd = v4l2object->fd_open (v4l2object->video_fd,
+ V4L2_ENABLE_ENUM_FMT_EMULATION);
+ if (libv4l2_fd != -1)
+ v4l2object->video_fd = libv4l2_fd;
#endif
- /* Note the v4l2_xxx functions are designed so that if they get passed an
- unknown fd, the will behave exactly as their regular xxx counterparts, so
- if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom
- cam format to normal formats conversion). Chances are big we will still
- fail then though, as normally v4l2_fd_open only fails if the device is not
- a v4l2 device. */
+ /* Note the v4l2_xxx functions are designed so that if they get passed an
+ unknown fd, the will behave exactly as their regular xxx counterparts, so
+ if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom
+ cam format to normal formats conversion). Chances are big we will still
+ fail then though, as normally v4l2_fd_open only fails if the device is not
+ a v4l2 device. */
- /* get capabilities, error will be posted */
- if (!gst_aml_v4l2_get_capabilities(v4l2object))
- goto error;
+ /* get capabilities, error will be posted */
+ if (!gst_aml_v4l2_get_capabilities(v4l2object))
+ goto error;
- if (GST_IS_AML_V4L2_VIDEO_DEC(v4l2object->element) &&
- !GST_AML_V4L2_IS_M2M(v4l2object->device_caps))
- goto not_m2m;
+ if (GST_IS_AML_V4L2_VIDEO_DEC(v4l2object->element) &&
+ !GST_AML_V4L2_IS_M2M(v4l2object->device_caps))
+ goto not_m2m;
- gst_aml_v4l2_adjust_buf_type(v4l2object);
+ gst_aml_v4l2_adjust_buf_type(v4l2object);
- if (v4l2object->tvin_port != -1)
+ if (v4l2object->tvin_port != -1)
+ {
+ unsigned int portType = v4l2object->tvin_port;
+ if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_INPUT, &portType) < 0)
{
- unsigned int portType = v4l2object->tvin_port;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_INPUT, &portType) < 0)
- {
- GST_INFO_OBJECT(v4l2object->dbg_obj, "set tvin_port 0x%x failed", portType);
- }
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "set tvin_port 0x%x failed", portType);
}
+ }
- GST_INFO_OBJECT(v4l2object->dbg_obj,
- "Opened device '%s' (%s) successfully",
- v4l2object->vcap.card, v4l2object->videodev);
+ GST_INFO_OBJECT (v4l2object->dbg_obj,
+ "Opened device '%s' (%s) successfully",
+ v4l2object->vcap.card, v4l2object->videodev);
- if (v4l2object->extra_controls)
- gst_aml_v4l2_set_controls(v4l2object, v4l2object->extra_controls);
+ if (v4l2object->extra_controls)
+ gst_aml_v4l2_set_controls(v4l2object, v4l2object->extra_controls);
- if (GST_IS_AML_V4L2_VIDEO_DEC(v4l2object->element))
- {
- gst_aml_v4l2_subscribe_event(v4l2object);
- }
+ if (GST_IS_AML_V4L2_VIDEO_DEC(v4l2object->element))
+ {
+ gst_aml_v4l2_subscribe_event(v4l2object);
+ }
- /* UVC devices are never interlaced, and doing VIDIOC_TRY_FMT on them
- * causes expensive and slow USB IO, so don't probe them for interlaced
- */
- if (!strcmp((char *)v4l2object->vcap.driver, "uvcusb") ||
- !strcmp((char *)v4l2object->vcap.driver, "uvcvideo"))
- {
- v4l2object->never_interlaced = TRUE;
- }
+ /* UVC devices are never interlaced, and doing VIDIOC_TRY_FMT on them
+ * causes expensive and slow USB IO, so don't probe them for interlaced
+ */
+ if (!strcmp ((char *) v4l2object->vcap.driver, "uvcusb") ||
+ !strcmp ((char *) v4l2object->vcap.driver, "uvcvideo"))
+ {
+ v4l2object->never_interlaced = TRUE;
+ }
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
stat_failed:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, NOT_FOUND,
(_("Cannot identify device '%s'."), v4l2object->videodev),
GST_ERROR_SYSTEM);
goto error;
-}
+ }
no_device:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, NOT_FOUND,
(_("This isn't a device '%s'."), v4l2object->videodev),
GST_ERROR_SYSTEM);
goto error;
-}
+ }
not_open:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, OPEN_READ_WRITE,
(_("Could not open device '%s' for reading and writing."),
v4l2object->videodev),
GST_ERROR_SYSTEM);
goto error;
-}
+ }
#ifdef DELETE_FOR_LGE
not_capture:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, NOT_FOUND,
(_("Device '%s' is not a capture device."),
v4l2object->videodev),
("Capabilities: 0x%x", v4l2object->device_caps));
goto error;
-}
+ }
not_output:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, NOT_FOUND,
(_("Device '%s' is not a output device."),
v4l2object->videodev),
("Capabilities: 0x%x", v4l2object->device_caps));
goto error;
-}
+ }
#endif
not_m2m:
-{
+ {
GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, NOT_FOUND,
(_("Device '%s' is not a M2M device."),
v4l2object->videodev),
("Capabilities: 0x%x", v4l2object->device_caps));
goto error;
-}
+ }
error:
-{
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
+ {
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
{
- /* close device */
- v4l2object->close(v4l2object->video_fd);
- v4l2object->video_fd = -1;
+ /* close device */
+ v4l2object->close (v4l2object->video_fd);
+ v4l2object->video_fd = -1;
}
/* empty lists */
gst_aml_v4l2_empty_lists(v4l2object);
return FALSE;
-}
+ }
}
gboolean
gst_aml_v4l2_dup(GstAmlV4l2Object *v4l2object, GstAmlV4l2Object *other)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Trying to dup device %s",
- other->videodev);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to dup device %s",
+ other->videodev);
- GST_AML_V4L2_CHECK_OPEN(other);
- GST_AML_V4L2_CHECK_NOT_OPEN(v4l2object);
- GST_AML_V4L2_CHECK_NOT_ACTIVE(other);
- GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
+ GST_AML_V4L2_CHECK_OPEN(other);
+ GST_AML_V4L2_CHECK_NOT_OPEN(v4l2object);
+ GST_AML_V4L2_CHECK_NOT_ACTIVE(other);
+ GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
- v4l2object->vcap = other->vcap;
- v4l2object->device_caps = other->device_caps;
- gst_aml_v4l2_adjust_buf_type(v4l2object);
+ v4l2object->vcap = other->vcap;
+ v4l2object->device_caps = other->device_caps;
+ gst_aml_v4l2_adjust_buf_type(v4l2object);
- v4l2object->video_fd = v4l2object->dup(other->video_fd);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- goto not_open;
+ v4l2object->video_fd = v4l2object->dup (other->video_fd);
+ if (!GST_AML_V4L2_IS_OPEN(v4l2object))
+ goto not_open;
- g_free(v4l2object->videodev);
- v4l2object->videodev = g_strdup(other->videodev);
+ g_free (v4l2object->videodev);
+ v4l2object->videodev = g_strdup (other->videodev);
- GST_INFO_OBJECT(v4l2object->dbg_obj,
- "Cloned device '%s' (%s) successfully",
- v4l2object->vcap.card, v4l2object->videodev);
+ GST_INFO_OBJECT (v4l2object->dbg_obj,
+ "Cloned device '%s' (%s) successfully",
+ v4l2object->vcap.card, v4l2object->videodev);
- v4l2object->never_interlaced = other->never_interlaced;
- v4l2object->no_initial_format = other->no_initial_format;
- v4l2object->can_wait_event = other->can_wait_event;
+ v4l2object->never_interlaced = other->never_interlaced;
+ v4l2object->no_initial_format = other->no_initial_format;
+ v4l2object->can_wait_event = other->can_wait_event;
- return TRUE;
+ return TRUE;
not_open:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, OPEN_READ_WRITE,
- (_("Could not dup device '%s' for reading and writing."),
- v4l2object->videodev),
- GST_ERROR_SYSTEM);
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE,
+ (_("Could not dup device '%s' for reading and writing."),
+ v4l2object->videodev), GST_ERROR_SYSTEM);
return FALSE;
-}
+ }
}
/******************************************************
@@ -433,20 +431,20 @@
gboolean
gst_aml_v4l2_close(GstAmlV4l2Object *v4l2object)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Trying to close %s",
- v4l2object->videodev);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to close %s",
+ v4l2object->videodev);
- GST_AML_V4L2_CHECK_OPEN(v4l2object);
- GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
+ GST_AML_V4L2_CHECK_OPEN(v4l2object);
+ GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
- /* close device */
- v4l2object->close(v4l2object->video_fd);
- v4l2object->video_fd = -1;
+ /* close device */
+ v4l2object->close (v4l2object->video_fd);
+ v4l2object->video_fd = -1;
- /* empty lists */
- gst_aml_v4l2_empty_lists(v4l2object);
+ /* empty lists */
+ gst_aml_v4l2_empty_lists(v4l2object);
- return TRUE;
+ return TRUE;
}
/******************************************************
@@ -457,23 +455,23 @@
gboolean
gst_aml_v4l2_get_norm(GstAmlV4l2Object *v4l2object, v4l2_std_id *norm)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "getting norm");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "getting norm");
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_STD, norm) < 0)
- goto std_failed;
-
- return TRUE;
-
- /* ERRORS */
-std_failed:
-{
- GST_DEBUG("Failed to get the current norm for device %s",
- v4l2object->videodev);
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
-}
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_STD, norm) < 0)
+ goto std_failed;
+
+ return TRUE;
+
+ /* ERRORS */
+std_failed:
+ {
+ GST_DEBUG ("Failed to get the current norm for device %s",
+ v4l2object->videodev);
+ return FALSE;
+ }
}
/******************************************************
@@ -484,59 +482,25 @@
gboolean
gst_aml_v4l2_set_norm(GstAmlV4l2Object *v4l2object, v4l2_std_id norm)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to set norm to "
- "%" G_GINT64_MODIFIER "x",
- (guint64)norm);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "trying to set norm to "
+ "%" G_GINT64_MODIFIER "x", (guint64) norm);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
+ return FALSE;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0)
- goto std_failed;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0)
+ goto std_failed;
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
std_failed:
-{
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to set norm for device '%s'."),
- v4l2object->videodev),
- GST_ERROR_SYSTEM);
+ {
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to set norm for device '%s'."),
+ v4l2object->videodev), GST_ERROR_SYSTEM);
return FALSE;
-}
-}
-
-gboolean
-gst_aml_v4l2_signal_strength(GstAmlV4l2Object *v4l2object,
- gint tunernum, gulong *signal_strength)
-{
- struct v4l2_tuner tuner = {
- 0,
- };
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to get signal strength");
-
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- tuner.index = tunernum;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_TUNER, &tuner) < 0)
- goto tuner_failed;
-
- *signal_strength = tuner.signal;
-
- return TRUE;
-
- /* ERRORS */
-tuner_failed:
-{
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to get signal strength for device '%s'."),
- v4l2object->videodev),
- GST_ERROR_SYSTEM);
- return FALSE;
-}
+ }
}
/******************************************************
@@ -548,33 +512,31 @@
gst_aml_v4l2_get_attribute(GstAmlV4l2Object *v4l2object,
int attribute_num, int *value)
{
- struct v4l2_control control = {
- 0,
- };
+ struct v4l2_control control = { 0, };
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "getting value of attribute %d",
- attribute_num);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "getting value of attribute %d",
+ attribute_num);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- control.id = attribute_num;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
- goto ctrl_failed;
-
- *value = control.value;
-
- return TRUE;
-
- /* ERRORS */
-ctrl_failed:
-{
- GST_WARNING_OBJECT(v4l2object,
- _("Failed to get value for control %d on device '%s'."),
- attribute_num, v4l2object->videodev);
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
-}
+
+ control.id = attribute_num;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
+ goto ctrl_failed;
+
+ *value = control.value;
+
+ return TRUE;
+
+ /* ERRORS */
+ctrl_failed:
+ {
+ GST_WARNING_OBJECT (v4l2object,
+ _("Failed to get value for control %d on device '%s'."),
+ attribute_num, v4l2object->videodev);
+ return FALSE;
+ }
}
/******************************************************
@@ -583,69 +545,68 @@
* return value: TRUE on success, FALSE on error
******************************************************/
gboolean
-gst_aml_v4l2_set_attribute(GstAmlV4l2Object *v4l2object,
+gst_aml_v4l2_set_attribute (GstAmlV4l2Object *v4l2object,
int attribute_num, const int value)
{
- struct v4l2_control control = {
- 0,
- };
+ struct v4l2_control control = { 0, };
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "setting value of attribute %d to %d",
- attribute_num, value);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "setting value of attribute %d to %d",
+ attribute_num, value);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- control.id = attribute_num;
- control.value = value;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0)
- goto ctrl_failed;
-
- return TRUE;
-
- /* ERRORS */
-ctrl_failed:
-{
- GST_WARNING_OBJECT(v4l2object,
- _("Failed to set value %d for control %d on device '%s'."),
- value, attribute_num, v4l2object->videodev);
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
+
+ control.id = attribute_num;
+ control.value = value;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0)
+ goto ctrl_failed;
+
+ return TRUE;
+
+ /* ERRORS */
+ctrl_failed:
+ {
+ GST_WARNING_OBJECT (v4l2object,
+ _("Failed to set value %d for control %d on device '%s'."),
+ value, attribute_num, v4l2object->videodev);
+ return FALSE;
+ }
}
-}
+
static gboolean
-set_control(GQuark field_id, const GValue *value, gpointer user_data)
+set_control (GQuark field_id, const GValue * value, gpointer user_data)
{
- GstAmlV4l2Object *v4l2object = user_data;
- GQuark normalised_field_id;
- gpointer *d;
+ GstAmlV4l2Object *v4l2object = user_data;
+ GQuark normalised_field_id;
+ gpointer *d;
- /* 32 bytes is the maximum size for a control name according to v4l2 */
- gchar name[32];
+ /* 32 bytes is the maximum size for a control name according to v4l2 */
+ gchar name[32];
- /* Backwards compatibility: in the past GStreamer would normalise strings in
- a subtly different way to v4l2-ctl. e.g. the kernel's "Focus (absolute)"
- would become "focus__absolute_" whereas now it becomes "focus_absolute".
- Please remove the following in GStreamer 1.5 for 1.6 */
- strncpy(name, g_quark_to_string(field_id), sizeof(name));
- name[31] = '\0';
- gst_aml_v4l2_normalise_control_name(name);
- normalised_field_id = g_quark_from_string(name);
- if (normalised_field_id != field_id)
- g_warning("In GStreamer 1.4 the way V4L2 control names were normalised "
- "changed. Instead of setting \"%s\" please use \"%s\". The former is "
- "deprecated and will be removed in a future version of GStreamer",
- g_quark_to_string(field_id), name);
- field_id = normalised_field_id;
+ /* Backwards compatibility: in the past GStreamer would normalise strings in
+ a subtly different way to v4l2-ctl. e.g. the kernel's "Focus (absolute)"
+ would become "focus__absolute_" whereas now it becomes "focus_absolute".
+ Please remove the following in GStreamer 1.5 for 1.6 */
+ strncpy (name, g_quark_to_string (field_id), sizeof (name));
+ name[31] = '\0';
+ gst_aml_v4l2_normalise_control_name(name);
+ normalised_field_id = g_quark_from_string (name);
+ if (normalised_field_id != field_id)
+ g_warning ("In GStreamer 1.4 the way V4L2 control names were normalised "
+ "changed. Instead of setting \"%s\" please use \"%s\". The former is "
+ "deprecated and will be removed in a future version of GStreamer",
+ g_quark_to_string (field_id), name);
+ field_id = normalised_field_id;
- d = g_datalist_id_get_data(&v4l2object->controls, field_id);
- if (!d)
- {
- GST_WARNING_OBJECT(v4l2object,
- "Control '%s' does not exist or has an unsupported type.",
- g_quark_to_string(field_id));
- return TRUE;
- }
+ d = g_datalist_id_get_data (&v4l2object->controls, field_id);
+ if (!d)
+ {
+ GST_WARNING_OBJECT (v4l2object,
+ "Control '%s' does not exist or has an unsupported type.",
+ g_quark_to_string (field_id));
+ return TRUE;
+ }
if (!G_VALUE_HOLDS(value, G_TYPE_INT))
{
GST_WARNING_OBJECT(v4l2object,
@@ -660,125 +621,124 @@
gboolean
gst_aml_v4l2_set_controls(GstAmlV4l2Object *v4l2object, GstStructure *controls)
{
- return gst_structure_foreach(controls, set_control, v4l2object);
+ return gst_structure_foreach (controls, set_control, v4l2object);
}
gboolean
gst_aml_v4l2_get_input(GstAmlV4l2Object *v4l2object, gint *input)
{
- gint n;
+ gint n;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to get input");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "trying to get input");
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0)
- goto input_failed;
-
- *input = n;
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "input: %d", n);
-
- return TRUE;
-
- /* ERRORS */
-input_failed:
- if (v4l2object->device_caps & V4L2_CAP_TUNER)
- {
- /* only give a warning message if driver actually claims to have tuner
- * support
- */
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to get current input on device '%s'. May be it is a radio device"), v4l2object->videodev), GST_ERROR_SYSTEM);
- }
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0)
+ goto input_failed;
+
+ *input = n;
+
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "input: %d", n);
+
+ return TRUE;
+
+ /* ERRORS */
+input_failed:
+ if (v4l2object->device_caps & V4L2_CAP_TUNER)
+ {
+ /* only give a warning message if driver actually claims to have tuner
+ * support
+ */
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to get current input on device '%s'. May be it is a radio device"), v4l2object->videodev), GST_ERROR_SYSTEM);
+ }
+ return FALSE;
}
gboolean
gst_aml_v4l2_set_input(GstAmlV4l2Object *v4l2object, gint input)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to set input to %d", input);
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to set input to %d", input);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0)
- goto input_failed;
-
- return TRUE;
-
- /* ERRORS */
-input_failed:
- if (v4l2object->device_caps & V4L2_CAP_TUNER)
- {
- /* only give a warning message if driver actually claims to have tuner
- * support
- */
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to set input %d on device %s."),
- input, v4l2object->videodev),
- GST_ERROR_SYSTEM);
- }
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0)
+ goto input_failed;
+
+ return TRUE;
+
+ /* ERRORS */
+input_failed:
+ if (v4l2object->device_caps & V4L2_CAP_TUNER)
+ {
+ /* only give a warning message if driver actually claims to have tuner
+ * support
+ */
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to set input %d on device %s."),
+ input, v4l2object->videodev), GST_ERROR_SYSTEM);
+ }
+ return FALSE;
}
gboolean
gst_aml_v4l2_get_output(GstAmlV4l2Object *v4l2object, gint *output)
{
- gint n;
+ gint n;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to get output");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "trying to get output");
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_OUTPUT, &n) < 0)
- goto output_failed;
-
- *output = n;
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "output: %d", n);
-
- return TRUE;
-
- /* ERRORS */
-output_failed:
- if (v4l2object->device_caps & V4L2_CAP_TUNER)
- {
- /* only give a warning message if driver actually claims to have tuner
- * support
- */
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to get current output on device '%s'. May be it is a radio device"), v4l2object->videodev), GST_ERROR_SYSTEM);
- }
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_OUTPUT, &n) < 0)
+ goto output_failed;
+
+ *output = n;
+
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "output: %d", n);
+
+ return TRUE;
+
+ /* ERRORS */
+output_failed:
+ if (v4l2object->device_caps & V4L2_CAP_TUNER)
+ {
+ /* only give a warning message if driver actually claims to have tuner
+ * support
+ */
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to get current output on device '%s'. May be it is a radio device"), v4l2object->videodev), GST_ERROR_SYSTEM);
+ }
+ return FALSE;
}
gboolean
gst_aml_v4l2_set_output(GstAmlV4l2Object *v4l2object, gint output)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to set output to %d", output);
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "trying to set output to %d", output);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_OUTPUT, &output) < 0)
- goto output_failed;
-
- return TRUE;
-
- /* ERRORS */
-output_failed:
- if (v4l2object->device_caps & V4L2_CAP_TUNER)
- {
- /* only give a warning message if driver actually claims to have tuner
- * support
- */
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to set output %d on device %s."),
- output, v4l2object->videodev),
- GST_ERROR_SYSTEM);
- }
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
return FALSE;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_OUTPUT, &output) < 0)
+ goto output_failed;
+
+ return TRUE;
+
+ /* ERRORS */
+output_failed:
+ if (v4l2object->device_caps & V4L2_CAP_TUNER)
+ {
+ /* only give a warning message if driver actually claims to have tuner
+ * support
+ */
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to set output %d on device %s."),
+ output, v4l2object->videodev), GST_ERROR_SYSTEM);
+ }
+ return FALSE;
}
+
diff --git a/src/ext/v4l2-common.h b/src/ext/v4l2-common.h
index 4447337..4345d84 100644
--- a/src/ext/v4l2-common.h
+++ b/src/ext/v4l2-common.h
@@ -86,11 +86,11 @@
struct v4l2_edid
{
- __u32 pad;
- __u32 start_block;
- __u32 blocks;
- __u32 reserved[5];
- __u8 *edid;
+ __u32 pad;
+ __u32 start_block;
+ __u32 blocks;
+ __u32 reserved[5];
+ __u8 *edid;
};
/* Backward compatibility target definitions --- to be removed. */
diff --git a/src/ext/v4l2-controls.h b/src/ext/v4l2-controls.h
index 683defc..dd90e16 100644
--- a/src/ext/v4l2-controls.h
+++ b/src/ext/v4l2-controls.h
@@ -111,22 +111,22 @@
#define V4L2_CID_COLORFX (V4L2_CID_BASE + 31)
enum v4l2_colorfx
{
- V4L2_COLORFX_NONE = 0,
- V4L2_COLORFX_BW = 1,
- V4L2_COLORFX_SEPIA = 2,
- V4L2_COLORFX_NEGATIVE = 3,
- V4L2_COLORFX_EMBOSS = 4,
- V4L2_COLORFX_SKETCH = 5,
- V4L2_COLORFX_SKY_BLUE = 6,
- V4L2_COLORFX_GRASS_GREEN = 7,
- V4L2_COLORFX_SKIN_WHITEN = 8,
- V4L2_COLORFX_VIVID = 9,
- V4L2_COLORFX_AQUA = 10,
- V4L2_COLORFX_ART_FREEZE = 11,
- V4L2_COLORFX_SILHOUETTE = 12,
- V4L2_COLORFX_SOLARIZATION = 13,
- V4L2_COLORFX_ANTIQUE = 14,
- V4L2_COLORFX_SET_CBCR = 15,
+ V4L2_COLORFX_NONE = 0,
+ V4L2_COLORFX_BW = 1,
+ V4L2_COLORFX_SEPIA = 2,
+ V4L2_COLORFX_NEGATIVE = 3,
+ V4L2_COLORFX_EMBOSS = 4,
+ V4L2_COLORFX_SKETCH = 5,
+ V4L2_COLORFX_SKY_BLUE = 6,
+ V4L2_COLORFX_GRASS_GREEN = 7,
+ V4L2_COLORFX_SKIN_WHITEN = 8,
+ V4L2_COLORFX_VIVID = 9,
+ V4L2_COLORFX_AQUA = 10,
+ V4L2_COLORFX_ART_FREEZE = 11,
+ V4L2_COLORFX_SILHOUETTE = 12,
+ V4L2_COLORFX_SOLARIZATION = 13,
+ V4L2_COLORFX_ANTIQUE = 14,
+ V4L2_COLORFX_SET_CBCR = 15,
};
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE + 32)
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE + 33)
@@ -204,12 +204,12 @@
#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE + 0)
enum v4l2_mpeg_stream_type
{
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
- V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */
- V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
};
#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE + 1)
#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE + 2)
diff --git a/src/gstamlv4l2.c b/src/gstamlv4l2.c
index 955fe09..dc5525e 100644
--- a/src/gstamlv4l2.c
+++ b/src/gstamlv4l2.c
@@ -45,163 +45,163 @@
/* This is a minimalist probe, for speed, we only enumerate formats */
static GstCaps *
gst_aml_v4l2_probe_template_caps(const gchar *device, gint video_fd,
- enum v4l2_buf_type type)
+ enum v4l2_buf_type type)
{
- gint n;
- struct v4l2_fmtdesc format;
- GstCaps *caps;
+ gint n;
+ struct v4l2_fmtdesc format;
+ GstCaps *caps;
- GST_DEBUG("Getting %s format enumerations", device);
- caps = gst_caps_new_empty();
+ GST_DEBUG ("Getting %s format enumerations", device);
+ caps = gst_caps_new_empty ();
- for (n = 0;; n++)
+ for (n = 0;; n++)
+ {
+ GstStructure *template;
+
+ memset (&format, 0, sizeof (format));
+
+ format.index = n;
+ format.type = type;
+
+ if (ioctl (video_fd, VIDIOC_ENUM_FMT, &format) < 0)
+ break; /* end of enumeration */
+
+ GST_LOG ("index: %u", format.index);
+ GST_LOG ("type: %d", format.type);
+ GST_LOG ("flags: %08x", format.flags);
+ GST_LOG ("description: '%s'", format.description);
+ GST_LOG ("pixelformat: %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (format.pixelformat));
+
+ template = gst_aml_v4l2_object_v4l2fourcc_to_structure(format.pixelformat);
+
+ if (template)
{
- GstStructure *template;
+ GstStructure *alt_t = NULL;
- memset(&format, 0, sizeof(format));
+ switch (format.pixelformat)
+ {
+ case V4L2_PIX_FMT_RGB32:
+ alt_t = gst_structure_copy (template);
+ gst_structure_set (alt_t, "format", G_TYPE_STRING, "ARGB", NULL);
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ alt_t = gst_structure_copy (template);
+ gst_structure_set (alt_t, "format", G_TYPE_STRING, "BGRA", NULL);
+ default:
+ break;
+ }
- format.index = n;
- format.type = type;
+ gst_caps_append_structure (caps, template);
- if (ioctl(video_fd, VIDIOC_ENUM_FMT, &format) < 0)
- break; /* end of enumeration */
-
- GST_LOG("index: %u", format.index);
- GST_LOG("type: %d", format.type);
- GST_LOG("flags: %08x", format.flags);
- GST_LOG("description: '%s'", format.description);
- GST_LOG("pixelformat: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS(format.pixelformat));
-
- template = gst_aml_v4l2_object_v4l2fourcc_to_structure(format.pixelformat);
-
- if (template)
- {
- GstStructure *alt_t = NULL;
-
- switch (format.pixelformat)
- {
- case V4L2_PIX_FMT_RGB32:
- alt_t = gst_structure_copy(template);
- gst_structure_set(alt_t, "format", G_TYPE_STRING, "ARGB", NULL);
- break;
- case V4L2_PIX_FMT_BGR32:
- alt_t = gst_structure_copy(template);
- gst_structure_set(alt_t, "format", G_TYPE_STRING, "BGRA", NULL);
- default:
- break;
- }
-
- gst_caps_append_structure(caps, template);
-
- if (alt_t)
- gst_caps_append_structure(caps, alt_t);
- }
+ if (alt_t)
+ gst_caps_append_structure (caps, alt_t);
}
+ }
- return gst_caps_simplify(caps);
+ return gst_caps_simplify (caps);
}
static gboolean
gst_aml_v4l2_register(GstPlugin *plugin)
{
- gint video_fd = -1;
- struct v4l2_capability vcap;
- guint32 device_caps;
- GstCaps *src_caps, *sink_caps;
+ gint video_fd = -1;
+ struct v4l2_capability vcap;
+ guint32 device_caps;
+ GstCaps *src_caps, *sink_caps;
- GST_DEBUG("regist aml v4l2 device");
+ GST_DEBUG("regist aml v4l2 device");
- GST_DEBUG("open: %s", DEFAULT_DEVICE_NAME);
- video_fd = open(DEFAULT_DEVICE_NAME, O_RDWR | O_CLOEXEC);
+ GST_DEBUG("open: %s", DEFAULT_DEVICE_NAME);
+ video_fd = open(DEFAULT_DEVICE_NAME, O_RDWR | O_CLOEXEC);
- if (video_fd == -1)
- {
- GST_DEBUG("Failed to open %s: %s", DEFAULT_DEVICE_NAME, g_strerror(errno));
- goto error_tag;
- }
+ if (video_fd == -1)
+ {
+ GST_DEBUG("Failed to open %s: %s", DEFAULT_DEVICE_NAME, g_strerror(errno));
+ goto error_tag;
+ }
- memset(&vcap, 0, sizeof(vcap));
+ memset(&vcap, 0, sizeof(vcap));
- if (ioctl(video_fd, VIDIOC_QUERYCAP, &vcap) < 0)
- {
- GST_DEBUG("Failed to get device capabilities: %s", g_strerror(errno));
- goto error_tag;
- }
+ if (ioctl(video_fd, VIDIOC_QUERYCAP, &vcap) < 0)
+ {
+ GST_DEBUG("Failed to get device capabilities: %s", g_strerror(errno));
+ goto error_tag;
+ }
- if (vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
- device_caps = vcap.device_caps;
- else
- device_caps = vcap.capabilities;
+ if (vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
+ device_caps = vcap.device_caps;
+ else
+ device_caps = vcap.capabilities;
- if (!GST_AML_V4L2_IS_M2M(device_caps)) {
- goto error_tag;
- }
+ if (!GST_AML_V4L2_IS_M2M(device_caps)) {
+ goto error_tag;
+ }
- /* get sink supported format (no MPLANE for codec) */
- sink_caps = gst_caps_merge(gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME,
- video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT),
+ /* get sink supported format (no MPLANE for codec) */
+ sink_caps = gst_caps_merge(gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME,
+ video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT),
+ gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME, video_fd,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE));
+ GST_DEBUG ("prob sink_caps %" GST_PTR_FORMAT, sink_caps);
+
+ /* get src supported format */
+ src_caps = gst_caps_merge(gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME,
+ video_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE),
gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME, video_fd,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE));
- GST_DEBUG ("prob sink_caps %" GST_PTR_FORMAT, sink_caps);
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE));
+ GST_DEBUG ("prob src_caps %" GST_PTR_FORMAT, src_caps);
- /* get src supported format */
- src_caps = gst_caps_merge(gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME,
- video_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE),
- gst_aml_v4l2_probe_template_caps(DEFAULT_DEVICE_NAME, video_fd,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE));
- GST_DEBUG ("prob src_caps %" GST_PTR_FORMAT, src_caps);
-
- /* Skip devices without any supported formats */
- if (gst_caps_is_empty(sink_caps) || gst_caps_is_empty(src_caps))
- {
- gst_caps_unref(sink_caps);
- gst_caps_unref(src_caps);
- goto error_tag;
- }
-
- /* Caps won't be freed if the subclass is not instantiated */
- GST_MINI_OBJECT_FLAG_SET(sink_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
- GST_MINI_OBJECT_FLAG_SET(src_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
-
- if (gst_aml_v4l2_is_video_dec(sink_caps, src_caps))
- {
- gst_aml_v4l2_video_dec_register(plugin, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_NAME,
- sink_caps, src_caps);
- }
-
+ /* Skip devices without any supported formats */
+ if (gst_caps_is_empty(sink_caps) || gst_caps_is_empty(src_caps))
+ {
gst_caps_unref(sink_caps);
gst_caps_unref(src_caps);
+ goto error_tag;
+ }
+
+ /* Caps won't be freed if the subclass is not instantiated */
+ GST_MINI_OBJECT_FLAG_SET(sink_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+ GST_MINI_OBJECT_FLAG_SET(src_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+
+ if (gst_aml_v4l2_is_video_dec(sink_caps, src_caps))
+ {
+ gst_aml_v4l2_video_dec_register(plugin, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_NAME,
+ sink_caps, src_caps);
+ }
+
+ gst_caps_unref(sink_caps);
+ gst_caps_unref(src_caps);
- if (video_fd >= 0)
- close(video_fd);
+ if (video_fd >= 0)
+ close (video_fd);
- return TRUE;
+ return TRUE;
error_tag:
- if (video_fd >= 0)
- close(video_fd);
- return FALSE;
+ if (video_fd >= 0)
+ close (video_fd);
+ return FALSE;
}
static gboolean
-plugin_init(GstPlugin *plugin)
+plugin_init (GstPlugin * plugin)
{
- //const gchar *paths[] = {"/dev", "/dev/v4l2", NULL};
- //const gchar *names[] = {"video", NULL};
+ //const gchar *paths[] = {"/dev", "/dev/v4l2", NULL};
+ //const gchar *names[] = {"video", NULL};
- GST_DEBUG_CATEGORY_INIT(aml_v4l2_debug, "amlv4l2", 0, "aml V4L2 API calls");
+ GST_DEBUG_CATEGORY_INIT(aml_v4l2_debug, "amlv4l2", 0, "aml V4L2 API calls");
- /* Add some depedency, so the dynamic features get updated upon changes in
- * /dev/video* */
- //gst_plugin_add_dependency(plugin,
- // NULL, paths, names, GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX);
+ /* Add some depedency, so the dynamic features get updated upon changes in
+ * /dev/video* */
+ //gst_plugin_add_dependency(plugin,
+ // NULL, paths, names, GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX);
- if (!gst_aml_v4l2_register(plugin))
- return FALSE;
+ if (!gst_aml_v4l2_register(plugin))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
#ifndef VERSION
diff --git a/src/gstamlv4l2allocator.c b/src/gstamlv4l2allocator.c
index 118acf0..442031a 100644
--- a/src/gstamlv4l2allocator.c
+++ b/src/gstamlv4l2allocator.c
@@ -52,8 +52,8 @@
enum
{
- GROUP_RELEASED,
- LAST_SIGNAL
+ GROUP_RELEASED,
+ LAST_SIGNAL
};
static guint gst_aml_v4l2_allocator_signals[LAST_SIGNAL] = {0};
@@ -97,22 +97,22 @@
}
static void gst_aml_v4l2_allocator_release(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2Memory *mem);
+ GstAmlV4l2Memory *mem);
static const gchar *
-memory_type_to_str(guint32 memory)
+memory_type_to_str (guint32 memory)
{
- switch (memory)
- {
+ switch (memory)
+ {
case V4L2_MEMORY_MMAP:
- return "mmap";
+ return "mmap";
case V4L2_MEMORY_USERPTR:
- return "userptr";
+ return "userptr";
case V4L2_MEMORY_DMABUF:
- return "dmabuf";
+ return "dmabuf";
default:
- return "unknown";
- }
+ return "unknown";
+ }
}
/*************************************/
@@ -122,141 +122,140 @@
static gpointer
_v4l2mem_map(GstAmlV4l2Memory *mem, gsize maxsize, GstMapFlags flags)
{
- gpointer data = NULL;
+ gpointer data = NULL;
- switch (mem->group->buffer.memory)
- {
+ switch (mem->group->buffer.memory)
+ {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
- data = mem->data;
- break;
+ data = mem->data;
+ break;
case V4L2_MEMORY_DMABUF:
- /* v4l2 dmabuf memory are not shared with downstream */
- g_assert_not_reached();
- break;
+ /* v4l2 dmabuf memory are not shared with downstream */
+ g_assert_not_reached ();
+ break;
default:
- GST_WARNING("Unknown memory type %i", mem->group->buffer.memory);
- break;
- }
- return data;
+ GST_WARNING ("Unknown memory type %i", mem->group->buffer.memory);
+ break;
+ }
+ return data;
}
static gboolean
_v4l2mem_unmap(GstAmlV4l2Memory *mem)
{
- gboolean ret = FALSE;
+ gboolean ret = FALSE;
- switch (mem->group->buffer.memory)
- {
+ switch (mem->group->buffer.memory)
+ {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
- ret = TRUE;
- break;
+ ret = TRUE;
+ break;
case V4L2_MEMORY_DMABUF:
- /* v4l2 dmabuf memory are not share with downstream */
- g_assert_not_reached();
- break;
+ /* v4l2 dmabuf memory are not share with downstream */
+ g_assert_not_reached ();
+ break;
default:
- GST_WARNING("Unknown memory type %i", mem->group->buffer.memory);
- break;
- }
- return ret;
+ GST_WARNING ("Unknown memory type %i", mem->group->buffer.memory);
+ break;
+ }
+ return ret;
}
static gboolean
_v4l2mem_dispose(GstAmlV4l2Memory *mem)
{
- GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)mem->mem.allocator;
- GstAmlV4l2MemoryGroup *group = mem->group;
- gboolean ret;
+ GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)mem->mem.allocator;
+ GstAmlV4l2MemoryGroup *group = mem->group;
+ gboolean ret;
- if (group->mem[mem->plane])
- {
- /* We may have a dmabuf, replace it with returned original memory */
- group->mem[mem->plane] = gst_memory_ref((GstMemory *)mem);
- gst_aml_v4l2_allocator_release(allocator, mem);
- ret = FALSE;
- }
- else
- {
- gst_object_ref(allocator);
- ret = TRUE;
- }
+ if (group->mem[mem->plane])
+ {
+ /* We may have a dmabuf, replace it with returned original memory */
+ group->mem[mem->plane] = gst_memory_ref ((GstMemory *) mem);
+ gst_aml_v4l2_allocator_release(allocator, mem);
+ ret = FALSE;
+ }
+ else
+ {
+ gst_object_ref (allocator);
+ ret = TRUE;
+ }
- return ret;
+ return ret;
}
static inline GstAmlV4l2Memory *
-_v4l2mem_new(GstMemoryFlags flags, GstAllocator *allocator,
- GstMemory *parent, gsize maxsize, gsize align, gsize offset, gsize size,
- gint plane, gpointer data, int dmafd, GstAmlV4l2MemoryGroup *group)
+_v4l2mem_new (GstMemoryFlags flags, GstAllocator * allocator,
+ GstMemory * parent, gsize maxsize, gsize align, gsize offset, gsize size,
+ gint plane, gpointer data, int dmafd, GstAmlV4l2MemoryGroup *group)
{
- GstAmlV4l2Memory *mem;
+ GstAmlV4l2Memory *mem;
- mem = g_slice_new0(GstAmlV4l2Memory);
- gst_memory_init(GST_MEMORY_CAST(mem),
- flags, allocator, parent, maxsize, align, offset, size);
+ mem = g_slice_new0 (GstAmlV4l2Memory);
+ gst_memory_init (GST_MEMORY_CAST (mem),
+ flags, allocator, parent, maxsize, align, offset, size);
- if (parent == NULL)
- mem->mem.mini_object.dispose =
- (GstMiniObjectDisposeFunction)_v4l2mem_dispose;
+ if (parent == NULL)
+ mem->mem.mini_object.dispose =
+ (GstMiniObjectDisposeFunction) _v4l2mem_dispose;
- mem->plane = plane;
- mem->data = data;
- mem->dmafd = dmafd;
- mem->group = group;
+ mem->plane = plane;
+ mem->data = data;
+ mem->dmafd = dmafd;
+ mem->group = group;
- return mem;
+ return mem;
}
static GstAmlV4l2Memory *
_v4l2mem_share(GstAmlV4l2Memory *mem, gssize offset, gsize size)
{
- GstAmlV4l2Memory *sub;
- GstMemory *parent;
+ GstAmlV4l2Memory *sub;
+ GstMemory *parent;
- /* find the real parent */
- if ((parent = mem->mem.parent) == NULL)
- parent = (GstMemory *)mem;
+ /* find the real parent */
+ if ((parent = mem->mem.parent) == NULL)
+ parent = (GstMemory *) mem;
- if (size == -1)
- size = mem->mem.size - offset;
+ if (size == -1)
+ size = mem->mem.size - offset;
- /* the shared memory is always readonly */
- sub = _v4l2mem_new(GST_MINI_OBJECT_FLAGS(parent) |
- GST_MINI_OBJECT_FLAG_LOCK_READONLY,
- mem->mem.allocator, parent,
- mem->mem.maxsize, mem->mem.align, offset, size, mem->plane, mem->data,
- -1, mem->group);
+ /* the shared memory is always readonly */
+ sub = _v4l2mem_new (GST_MINI_OBJECT_FLAGS (parent) |
+ GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent,
+ mem->mem.maxsize, mem->mem.align, offset, size, mem->plane, mem->data,
+ -1, mem->group);
- return sub;
+ return sub;
}
static gboolean
_v4l2mem_is_span(GstAmlV4l2Memory *mem1, GstAmlV4l2Memory *mem2, gsize *offset)
{
- if (offset)
- *offset = mem1->mem.offset - mem1->mem.parent->offset;
+ if (offset)
+ *offset = mem1->mem.offset - mem1->mem.parent->offset;
- /* and memory is contiguous */
- return mem1->mem.offset + mem1->mem.size == mem2->mem.offset;
+ /* and memory is contiguous */
+ return mem1->mem.offset + mem1->mem.size == mem2->mem.offset;
}
gboolean
-gst_is_aml_v4l2_memory(GstMemory *mem)
+gst_aml_is_v4l2_memory(GstMemory *mem)
{
- return gst_memory_is_type(mem, GST_AML_V4L2_MEMORY_TYPE);
+ return gst_memory_is_type(mem, GST_AML_V4L2_MEMORY_TYPE);
}
GQuark
gst_aml_v4l2_memory_quark(void)
{
- static GQuark quark = 0;
+ static GQuark quark = 0;
- if (quark == 0)
- quark = g_quark_from_string("GstAmlV4l2Memory");
+ if (quark == 0)
+ quark = g_quark_from_string ("GstAmlV4l2Memory");
- return quark;
+ return quark;
}
/*************************************/
@@ -266,133 +265,134 @@
static void
gst_aml_v4l2_memory_group_free(GstAmlV4l2MemoryGroup *group)
{
- gint i;
+ gint i;
- for (i = 0; i < group->n_mem; i++)
- {
- GstMemory *mem = group->mem[i];
- group->mem[i] = NULL;
- if (mem)
- gst_memory_unref(mem);
- }
+ for (i = 0; i < group->n_mem; i++)
+ {
+ GstMemory *mem = group->mem[i];
+ group->mem[i] = NULL;
+ if (mem)
+ gst_memory_unref (mem);
+ }
- g_slice_free(GstAmlV4l2MemoryGroup, group);
+ g_slice_free(GstAmlV4l2MemoryGroup, group);
}
static GstAmlV4l2MemoryGroup *
gst_aml_v4l2_memory_group_new(GstAmlV4l2Allocator *allocator, guint32 index)
{
- GstAmlV4l2Object *obj = allocator->obj;
- guint32 memory = allocator->memory;
- struct v4l2_format *format = &obj->format;
- GstAmlV4l2MemoryGroup *group;
- gsize img_size, buf_size;
+ GstAmlV4l2Object *obj = allocator->obj;
+ guint32 memory = allocator->memory;
+ struct v4l2_format *format = &obj->format;
+ GstAmlV4l2MemoryGroup *group;
+ gsize img_size, buf_size;
- group = g_slice_new0(GstAmlV4l2MemoryGroup);
+ group = g_slice_new0 (GstAmlV4l2MemoryGroup);
- group->buffer.type = format->type;
- group->buffer.index = index;
- group->buffer.memory = memory;
+ group->buffer.type = format->type;
+ group->buffer.index = index;
+ group->buffer.memory = memory;
- if (V4L2_TYPE_IS_MULTIPLANAR(format->type))
+ if (V4L2_TYPE_IS_MULTIPLANAR(format->type))
+ {
+ group->n_mem = group->buffer.length = format->fmt.pix_mp.num_planes;
+ group->buffer.m.planes = group->planes;
+ }
+ else
+ {
+ group->n_mem = 1;
+ }
+
+ if (obj->ioctl (obj->video_fd, VIDIOC_QUERYBUF, &group->buffer) < 0)
+ goto querybuf_failed;
+
+ if (group->buffer.index != index)
+ {
+ GST_ERROR_OBJECT (allocator, "Buffer index returned by VIDIOC_QUERYBUF "
+ "didn't match, this indicate the presence of a bug in your driver or "
+ "libv4l2");
+ g_slice_free (GstAmlV4l2MemoryGroup, group);
+ return NULL;
+ }
+
+ /* Check that provided size matches the format we have negotiation. Failing
+ * there usually means a driver of libv4l bug. */
+ if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ gint i;
+
+ for (i = 0; i < group->n_mem; i++)
{
- group->n_mem = group->buffer.length = format->fmt.pix_mp.num_planes;
- group->buffer.m.planes = group->planes;
+ img_size = obj->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+ buf_size = group->planes[i].length;
+ if (buf_size < img_size)
+ goto buffer_too_short;
}
- else
- {
- group->n_mem = 1;
- }
+ }
+ else
+ {
+ img_size = obj->format.fmt.pix.sizeimage;
+ buf_size = group->buffer.length;
+ if (buf_size < img_size)
+ goto buffer_too_short;
+ }
- if (obj->ioctl(obj->video_fd, VIDIOC_QUERYBUF, &group->buffer) < 0)
- goto querybuf_failed;
+ /* We save non planar buffer information into the multi-planar plane array
+ * to avoid duplicating the code later */
+ if (!V4L2_TYPE_IS_MULTIPLANAR(format->type))
+ {
+ group->planes[0].bytesused = group->buffer.bytesused;
+ group->planes[0].length = group->buffer.length;
+ group->planes[0].data_offset = 0;
+ g_assert (sizeof (group->planes[0].m) == sizeof (group->buffer.m));
+ memcpy (&group->planes[0].m, &group->buffer.m, sizeof (group->buffer.m));
+ }
- if (group->buffer.index != index)
- {
- GST_ERROR_OBJECT(allocator, "Buffer index returned by VIDIOC_QUERYBUF "
- "didn't match, this indicate the presence of a bug in your driver or "
- "libv4l2");
- g_slice_free(GstAmlV4l2MemoryGroup, group);
- return NULL;
- }
-
- /* Check that provided size matches the format we have negotiation. Failing
- * there usually means a driver of libv4l bug. */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- gint i;
-
- for (i = 0; i < group->n_mem; i++)
- {
- img_size = obj->format.fmt.pix_mp.plane_fmt[i].sizeimage;
- buf_size = group->planes[i].length;
- if (buf_size < img_size)
- goto buffer_too_short;
- }
- }
- else
- {
- img_size = obj->format.fmt.pix.sizeimage;
- buf_size = group->buffer.length;
- if (buf_size < img_size)
- goto buffer_too_short;
- }
-
- /* We save non planar buffer information into the multi-planar plane array
- * to avoid duplicating the code later */
- if (!V4L2_TYPE_IS_MULTIPLANAR(format->type))
- {
- group->planes[0].bytesused = group->buffer.bytesused;
- group->planes[0].length = group->buffer.length;
- group->planes[0].data_offset = 0;
- g_assert(sizeof(group->planes[0].m) == sizeof(group->buffer.m));
- memcpy(&group->planes[0].m, &group->buffer.m, sizeof(group->buffer.m));
- }
-
- GST_LOG_OBJECT(allocator, "Got %s buffer", memory_type_to_str(memory));
- GST_LOG_OBJECT(allocator, " index: %u", group->buffer.index);
- GST_LOG_OBJECT(allocator, " type: %d", group->buffer.type);
- GST_LOG_OBJECT(allocator, " flags: %08x", group->buffer.flags);
- GST_LOG_OBJECT(allocator, " field: %d", group->buffer.field);
- GST_LOG_OBJECT(allocator, " memory: %d", group->buffer.memory);
- GST_LOG_OBJECT(allocator, " planes: %d", group->n_mem);
+ GST_LOG_OBJECT (allocator, "Got %s buffer", memory_type_to_str (memory));
+ GST_LOG_OBJECT (allocator, " index: %u", group->buffer.index);
+ GST_LOG_OBJECT (allocator, " type: %d", group->buffer.type);
+ GST_LOG_OBJECT (allocator, " flags: %08x", group->buffer.flags);
+ GST_LOG_OBJECT (allocator, " field: %d", group->buffer.field);
+ GST_LOG_OBJECT (allocator, " memory: %d", group->buffer.memory);
+ GST_LOG_OBJECT (allocator, " planes: %d", group->n_mem);
#ifndef GST_DISABLE_GST_DEBUG
- if (memory == V4L2_MEMORY_MMAP)
+ if (memory == V4L2_MEMORY_MMAP)
+ {
+ gint i;
+ for (i = 0; i < group->n_mem; i++)
{
- gint i;
- for (i = 0; i < group->n_mem; i++)
- {
- GST_LOG_OBJECT(allocator,
- " [%u] bytesused: %u, length: %u, offset: %u", i,
- group->planes[i].bytesused, group->planes[i].length,
- group->planes[i].data_offset);
- GST_LOG_OBJECT(allocator, " [%u] MMAP offset: %u", i,
- group->planes[i].m.mem_offset);
- }
+ GST_LOG_OBJECT (allocator,
+ " [%u] bytesused: %u, length: %u, offset: %u", i,
+ group->planes[i].bytesused, group->planes[i].length,
+ group->planes[i].data_offset);
+ GST_LOG_OBJECT (allocator, " [%u] MMAP offset: %u", i,
+ group->planes[i].m.mem_offset);
}
+ }
#endif
- return group;
+ return group;
querybuf_failed:
-{
- GST_ERROR("error querying buffer %d: %s", index, g_strerror(errno));
+ {
+ GST_ERROR ("error querying buffer %d: %s", index, g_strerror (errno));
goto failed;
-}
+ }
buffer_too_short:
-{
- GST_ERROR("buffer size %" G_GSIZE_FORMAT
- " is smaller then negotiated size %" G_GSIZE_FORMAT
- ", this is usually the result of a bug in the v4l2 driver or libv4l.",
- buf_size, img_size);
+ {
+ GST_ERROR ("buffer size %" G_GSIZE_FORMAT
+ " is smaller then negotiated size %" G_GSIZE_FORMAT
+ ", this is usually the result of a bug in the v4l2 driver or libv4l.",
+ buf_size, img_size);
goto failed;
-}
+ }
failed:
- gst_aml_v4l2_memory_group_free(group);
- return NULL;
+ gst_aml_v4l2_memory_group_free(group);
+ return NULL;
}
+
/*************************************/
/* GstV4lAllocator implementation */
/*************************************/
@@ -400,1198 +400,1201 @@
static void
gst_aml_v4l2_allocator_release(GstAmlV4l2Allocator *allocator, GstAmlV4l2Memory *mem)
{
- GstAmlV4l2MemoryGroup *group = mem->group;
+ GstAmlV4l2MemoryGroup *group = mem->group;
- GST_LOG_OBJECT(allocator, "plane %i of buffer %u released",
- mem->plane, group->buffer.index);
+ GST_LOG_OBJECT (allocator, "plane %i of buffer %u released",
+ mem->plane, group->buffer.index);
- switch (allocator->memory)
- {
+ switch (allocator->memory)
+ {
case V4L2_MEMORY_DMABUF:
- close(mem->dmafd);
- mem->dmafd = -1;
- break;
+ close (mem->dmafd);
+ mem->dmafd = -1;
+ break;
case V4L2_MEMORY_USERPTR:
- mem->data = NULL;
- break;
+ mem->data = NULL;
+ break;
default:
- break;
- }
+ break;
+ }
- /* When all memory are back, put the group back in the free queue */
- if (g_atomic_int_dec_and_test(&group->mems_allocated))
- {
- GST_LOG_OBJECT(allocator, "buffer %u released", group->buffer.index);
- gst_atomic_queue_push(allocator->free_queue, group);
- g_signal_emit(allocator, gst_aml_v4l2_allocator_signals[GROUP_RELEASED], 0);
- }
+ /* When all memory are back, put the group back in the free queue */
+ if (g_atomic_int_dec_and_test(&group->mems_allocated))
+ {
+ GST_LOG_OBJECT (allocator, "buffer %u released", group->buffer.index);
+ gst_atomic_queue_push (allocator->free_queue, group);
+ g_signal_emit (allocator, gst_aml_v4l2_allocator_signals[GROUP_RELEASED], 0);
+ }
- /* Keep last, allocator may be freed after this call */
- g_object_unref(allocator);
+ /* Keep last, allocator may be freed after this call */
+ g_object_unref (allocator);
}
static void
gst_aml_v4l2_allocator_free(GstAllocator *gallocator, GstMemory *gmem)
{
- GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)gallocator;
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2Memory *mem = (GstAmlV4l2Memory *)gmem;
- GstAmlV4l2MemoryGroup *group = mem->group;
+ GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)gallocator;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2Memory *mem = (GstAmlV4l2Memory *)gmem;
+ GstAmlV4l2MemoryGroup *group = mem->group;
- /* Only free unparented memory */
- if (mem->mem.parent == NULL)
+ /* Only free unparented memory */
+ if (mem->mem.parent == NULL)
+ {
+ GST_LOG_OBJECT (allocator, "freeing plane %i of buffer %u",
+ mem->plane, group->buffer.index);
+
+ if (allocator->memory == V4L2_MEMORY_MMAP)
{
- GST_LOG_OBJECT(allocator, "freeing plane %i of buffer %u",
- mem->plane, group->buffer.index);
-
- if (allocator->memory == V4L2_MEMORY_MMAP)
- {
- if (mem->data)
- obj->munmap(mem->data, group->planes[mem->plane].length);
- }
-
- /* This apply for both mmap with expbuf, and dmabuf imported memory */
- if (mem->dmafd >= 0)
- close(mem->dmafd);
+ if (mem->data)
+ obj->munmap (mem->data, group->planes[mem->plane].length);
}
- g_slice_free(GstAmlV4l2Memory, mem);
+ /* This apply for both mmap with expbuf, and dmabuf imported memory */
+ if (mem->dmafd >= 0)
+ close (mem->dmafd);
+ }
+
+ g_slice_free (GstAmlV4l2Memory, mem);
}
static void
gst_aml_v4l2_allocator_dispose(GObject *obj)
{
- GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)obj;
- gint i;
+ GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)obj;
+ gint i;
- GST_LOG_OBJECT(obj, "called");
+ GST_LOG_OBJECT (obj, "called");
- for (i = 0; i < allocator->count; i++)
- {
- GstAmlV4l2MemoryGroup *group = allocator->groups[i];
- allocator->groups[i] = NULL;
- if (group)
- gst_aml_v4l2_memory_group_free(group);
- }
+ for (i = 0; i < allocator->count; i++)
+ {
+ GstAmlV4l2MemoryGroup *group = allocator->groups[i];
+ allocator->groups[i] = NULL;
+ if (group)
+ gst_aml_v4l2_memory_group_free(group);
+ }
- G_OBJECT_CLASS(parent_class)->dispose(obj);
+ G_OBJECT_CLASS (parent_class)->dispose (obj);
}
static void
gst_aml_v4l2_allocator_finalize(GObject *obj)
{
- GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)obj;
+ GstAmlV4l2Allocator *allocator = (GstAmlV4l2Allocator *)obj;
- GST_LOG_OBJECT(obj, "called");
+ GST_LOG_OBJECT (obj, "called");
- gst_atomic_queue_unref(allocator->free_queue);
- gst_object_unref(allocator->obj->element);
+ gst_atomic_queue_unref (allocator->free_queue);
+ gst_object_unref (allocator->obj->element);
- G_OBJECT_CLASS(parent_class)->finalize(obj);
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static void
gst_aml_v4l2_allocator_class_init(GstAmlV4l2AllocatorClass *klass)
{
- GObjectClass *object_class;
- GstAllocatorClass *allocator_class;
+ GObjectClass *object_class;
+ GstAllocatorClass *allocator_class;
- allocator_class = (GstAllocatorClass *)klass;
- object_class = (GObjectClass *)klass;
+ allocator_class = (GstAllocatorClass *) klass;
+ object_class = (GObjectClass *) klass;
- allocator_class->alloc = NULL;
- allocator_class->free = gst_aml_v4l2_allocator_free;
+ allocator_class->alloc = NULL;
+ allocator_class->free = gst_aml_v4l2_allocator_free;
- object_class->dispose = gst_aml_v4l2_allocator_dispose;
- object_class->finalize = gst_aml_v4l2_allocator_finalize;
+ object_class->dispose = gst_aml_v4l2_allocator_dispose;
+ object_class->finalize = gst_aml_v4l2_allocator_finalize;
- gst_aml_v4l2_allocator_signals[GROUP_RELEASED] = g_signal_new("group-released",
- G_TYPE_FROM_CLASS(object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
+ gst_aml_v4l2_allocator_signals[GROUP_RELEASED] = g_signal_new("group-released",
+ G_TYPE_FROM_CLASS(object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
- GST_DEBUG_CATEGORY_INIT(amlv4l2allocator_debug, "v4l2allocator", 0,
- "V4L2 Allocator");
+ GST_DEBUG_CATEGORY_INIT(amlv4l2allocator_debug, "v4l2allocator", 0,
+ "V4L2 Allocator");
}
static void
gst_aml_v4l2_allocator_init(GstAmlV4l2Allocator *allocator)
{
- GstAllocator *alloc = GST_ALLOCATOR_CAST(allocator);
+ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
- alloc->mem_type = GST_AML_V4L2_MEMORY_TYPE;
- alloc->mem_map = (GstMemoryMapFunction)_v4l2mem_map;
- alloc->mem_unmap = (GstMemoryUnmapFunction)_v4l2mem_unmap;
- alloc->mem_share = (GstMemoryShareFunction)_v4l2mem_share;
- alloc->mem_is_span = (GstMemoryIsSpanFunction)_v4l2mem_is_span;
- /* Use the default, fallback copy function */
+ alloc->mem_type = GST_AML_V4L2_MEMORY_TYPE;
+ alloc->mem_map = (GstMemoryMapFunction) _v4l2mem_map;
+ alloc->mem_unmap = (GstMemoryUnmapFunction) _v4l2mem_unmap;
+ alloc->mem_share = (GstMemoryShareFunction) _v4l2mem_share;
+ alloc->mem_is_span = (GstMemoryIsSpanFunction) _v4l2mem_is_span;
+ /* Use the default, fallback copy function */
- allocator->free_queue = gst_atomic_queue_new(VIDEO_MAX_FRAME);
+ allocator->free_queue = gst_atomic_queue_new (VIDEO_MAX_FRAME);
- GST_OBJECT_FLAG_SET(allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}
#define GST_AML_V4L2_ALLOCATOR_PROBE(obj, type) \
- gst_aml_v4l2_allocator_probe((obj), V4L2_MEMORY_##type, \
- GST_V4L2_ALLOCATOR_FLAG_##type##_REQBUFS, \
- GST_V4L2_ALLOCATOR_FLAG_##type##_CREATE_BUFS)
+ gst_aml_v4l2_allocator_probe((obj), V4L2_MEMORY_##type, \
+ GST_V4L2_ALLOCATOR_FLAG_##type##_REQBUFS, \
+ GST_V4L2_ALLOCATOR_FLAG_##type##_CREATE_BUFS)
static guint32
gst_aml_v4l2_allocator_probe(GstAmlV4l2Allocator *allocator, guint32 memory,
- guint32 breq_flag, guint32 bcreate_flag)
+ guint32 breq_flag, guint32 bcreate_flag)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_requestbuffers breq = {0};
- guint32 flags = 0;
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_requestbuffers breq = { 0 };
+ guint32 flags = 0;
- breq.type = obj->type;
- breq.count = 0;
- breq.memory = memory;
+ breq.type = obj->type;
+ breq.count = 0;
+ breq.memory = memory;
- if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) == 0)
- {
- struct v4l2_create_buffers bcreate = {0};
+ if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) == 0)
+ {
+ struct v4l2_create_buffers bcreate = { 0 };
- flags |= breq_flag;
+ flags |= breq_flag;
- bcreate.memory = memory;
- bcreate.format = obj->format;
+ bcreate.memory = memory;
+ bcreate.format = obj->format;
- if ((obj->ioctl(obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
- flags |= bcreate_flag;
- }
+ if ((obj->ioctl (obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
+ flags |= bcreate_flag;
+ }
- if (breq.capabilities & V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS)
- {
- flags |= GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS;
- GST_DEBUG_OBJECT(allocator, "v4l2 support GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS");
- }
+ if (breq.capabilities & V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS)
+ {
+ flags |= GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS;
+ GST_DEBUG_OBJECT(allocator, "v4l2 support GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS");
+ }
- return flags;
+ return flags;
}
static GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_create_buf(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_create_buffers bcreate = {0};
- GstAmlV4l2MemoryGroup *group = NULL;
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_create_buffers bcreate = { 0 };
+ GstAmlV4l2MemoryGroup *group = NULL;
- GST_OBJECT_LOCK(allocator);
+ GST_OBJECT_LOCK (allocator);
- if (!g_atomic_int_get(&allocator->active))
- goto done;
+ if (!g_atomic_int_get (&allocator->active))
+ goto done;
- if (GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
- goto orphaned_bug;
+ if (GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
+ goto orphaned_bug;
- bcreate.memory = allocator->memory;
- bcreate.format = obj->format;
- bcreate.count = 1;
+ bcreate.memory = allocator->memory;
+ bcreate.format = obj->format;
+ bcreate.count = 1;
- if (!allocator->can_allocate)
- goto done;
+ if (!allocator->can_allocate)
+ goto done;
- if (obj->ioctl(obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) < 0)
- goto create_bufs_failed;
+ if (obj->ioctl (obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) < 0)
+ goto create_bufs_failed;
- if (allocator->groups[bcreate.index] != NULL)
- goto create_bufs_bug;
+ if (allocator->groups[bcreate.index] != NULL)
+ goto create_bufs_bug;
- group = gst_aml_v4l2_memory_group_new(allocator, bcreate.index);
+ group = gst_aml_v4l2_memory_group_new(allocator, bcreate.index);
- if (group)
- {
- allocator->groups[bcreate.index] = group;
- allocator->count++;
- }
+ if (group)
+ {
+ allocator->groups[bcreate.index] = group;
+ allocator->count++;
+ }
done:
- GST_OBJECT_UNLOCK(allocator);
- return group;
+ GST_OBJECT_UNLOCK (allocator);
+ return group;
orphaned_bug:
-{
- GST_ERROR_OBJECT(allocator, "allocator was orphaned, "
- "not creating new buffers");
+ {
+ GST_ERROR_OBJECT (allocator, "allocator was orphaned, "
+ "not creating new buffers");
goto done;
-}
+ }
create_bufs_failed:
-{
- GST_WARNING_OBJECT(allocator, "error creating a new buffer: %s",
- g_strerror(errno));
+ {
+ GST_WARNING_OBJECT (allocator, "error creating a new buffer: %s",
+ g_strerror (errno));
goto done;
-}
+ }
create_bufs_bug:
-{
- GST_ERROR_OBJECT(allocator, "created buffer has already used buffer "
- "index %i, this means there is an bug in your driver or libv4l2",
- bcreate.index);
+ {
+ GST_ERROR_OBJECT (allocator, "created buffer has already used buffer "
+ "index %i, this means there is an bug in your driver or libv4l2",
+ bcreate.index);
goto done;
-}
+ }
}
static GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_alloc(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2MemoryGroup *group;
+ GstAmlV4l2MemoryGroup *group;
- if (!g_atomic_int_get(&allocator->active))
- return NULL;
+ if (!g_atomic_int_get (&allocator->active))
+ return NULL;
- group = gst_atomic_queue_pop(allocator->free_queue);
+ group = gst_atomic_queue_pop (allocator->free_queue);
- if (group == NULL)
+ if (group == NULL)
+ {
+ if (allocator->can_allocate)
{
- if (allocator->can_allocate)
- {
- group = gst_aml_v4l2_allocator_create_buf(allocator);
+ group = gst_aml_v4l2_allocator_create_buf(allocator);
- /* Don't hammer on CREATE_BUFS */
- if (group == NULL)
- allocator->can_allocate = FALSE;
- }
+ /* Don't hammer on CREATE_BUFS */
+ if (group == NULL)
+ allocator->can_allocate = FALSE;
}
+ }
- return group;
+ return group;
}
static void
gst_aml_v4l2_allocator_reset_size(GstAmlV4l2Allocator *allocator,
GstAmlV4l2MemoryGroup *group)
{
- gint i;
- for (i = 0; i < group->n_mem; i++)
- {
- group->mem[i]->maxsize = group->planes[i].length;
- group->mem[i]->offset = 0;
- group->mem[i]->size = group->planes[i].length;
- }
+ gint i;
+ for (i = 0; i < group->n_mem; i++)
+ {
+ group->mem[i]->maxsize = group->planes[i].length;
+ group->mem[i]->offset = 0;
+ group->mem[i]->size = group->planes[i].length;
+ }
}
static void
_cleanup_failed_alloc(GstAmlV4l2Allocator *allocator, GstAmlV4l2MemoryGroup *group)
{
- if (group->mems_allocated > 0)
- {
- gint i;
- /* If one or more mmap worked, we need to unref the memory, otherwise
- * they will keep a ref on the allocator and leak it. This will put back
- * the group into the free_queue */
- for (i = 0; i < group->n_mem; i++)
- gst_memory_unref(group->mem[i]);
- }
- else
- {
- /* Otherwise, group has to be on free queue for _stop() to work */
- gst_atomic_queue_push(allocator->free_queue, group);
- }
+ if (group->mems_allocated > 0)
+ {
+ gint i;
+ /* If one or more mmap worked, we need to unref the memory, otherwise
+ * they will keep a ref on the allocator and leak it. This will put back
+ * the group into the free_queue */
+ for (i = 0; i < group->n_mem; i++)
+ gst_memory_unref (group->mem[i]);
+ }
+ else
+ {
+ /* Otherwise, group has to be on free queue for _stop() to work */
+ gst_atomic_queue_push (allocator->free_queue, group);
+ }
}
GstAmlV4l2Allocator *
gst_aml_v4l2_allocator_new(GstObject *parent, GstAmlV4l2Object *v4l2object)
{
- GstAmlV4l2Allocator *allocator;
- guint32 flags = 0;
- gchar *name, *parent_name;
+ GstAmlV4l2Allocator *allocator;
+ guint32 flags = 0;
+ gchar *name, *parent_name;
- parent_name = gst_object_get_name(parent);
- name = g_strconcat(parent_name, ":allocator", NULL);
- g_free(parent_name);
+ parent_name = gst_object_get_name (parent);
+ name = g_strconcat (parent_name, ":allocator", NULL);
+ g_free (parent_name);
- allocator = g_object_new(GST_TYPE_AML_V4L2_ALLOCATOR, "name", name, NULL);
- gst_object_ref_sink(allocator);
- g_free(name);
+ allocator = g_object_new(GST_TYPE_AML_V4L2_ALLOCATOR, "name", name, NULL);
+ gst_object_ref_sink (allocator);
+ g_free (name);
- /* Save everything */
- allocator->obj = v4l2object;
+ /* Save everything */
+ allocator->obj = v4l2object;
- /* Keep a ref on the elemnt so obj does not disapear */
- gst_object_ref(allocator->obj->element);
+ /* Keep a ref on the element so obj does not disappear */
+ gst_object_ref (allocator->obj->element);
- flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, MMAP);
- flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, USERPTR);
- flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, DMABUF);
+ flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, MMAP);
+ flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, USERPTR);
+ flags |= GST_AML_V4L2_ALLOCATOR_PROBE(allocator, DMABUF);
- if (flags == 0)
- {
- /* Drivers not ported from videobuf to videbuf2 don't allow freeing buffers
- * using REQBUFS(0). This is a workaround to still support these drivers,
- * which are known to have MMAP support. */
- GST_WARNING_OBJECT(allocator, "Could not probe supported memory type, "
- "assuming MMAP is supported, this is expected for older drivers not "
- " yet ported to videobuf2 framework");
- flags = GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS;
- }
- GST_OBJECT_FLAG_SET(allocator, flags);
+ if (flags == 0)
+ {
+ /* Drivers not ported from videobuf to videbuf2 don't allow freeing buffers
+ * using REQBUFS(0). This is a workaround to still support these drivers,
+ * which are known to have MMAP support. */
+ GST_WARNING_OBJECT (allocator, "Could not probe supported memory type, "
+ "assuming MMAP is supported, this is expected for older drivers not "
+ " yet ported to videobuf2 framework");
+ flags = GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS;
+ }
- return allocator;
+ GST_OBJECT_FLAG_SET (allocator, flags);
+
+ return allocator;
}
-guint gst_aml_v4l2_allocator_start(GstAmlV4l2Allocator *allocator, guint32 count,
+guint
+gst_aml_v4l2_allocator_start(GstAmlV4l2Allocator *allocator, guint32 count,
guint32 memory)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_requestbuffers breq = {count, obj->type, memory};
- gboolean can_allocate;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_requestbuffers breq = { count, obj->type, memory };
+ gboolean can_allocate;
+ gint i;
- g_return_val_if_fail(count != 0, 0);
+ g_return_val_if_fail (count != 0, 0);
- GST_OBJECT_LOCK(allocator);
+ GST_OBJECT_LOCK (allocator);
- if (g_atomic_int_get(&allocator->active))
- goto already_active;
+ if (g_atomic_int_get (&allocator->active))
+ goto already_active;
- if (GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
- goto orphaned;
+ if (GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
+ goto orphaned;
- if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
- goto reqbufs_failed;
+ if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
+ goto reqbufs_failed;
- if (breq.count < 1)
- goto out_of_memory;
+ if (breq.count < 1)
+ goto out_of_memory;
- switch (memory)
- {
+ switch (memory)
+ {
case V4L2_MEMORY_MMAP:
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, MMAP);
- break;
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, MMAP);
+ break;
case V4L2_MEMORY_USERPTR:
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, USERPTR);
- break;
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, USERPTR);
+ break;
case V4L2_MEMORY_DMABUF:
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, DMABUF);
- break;
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(allocator, DMABUF);
+ break;
default:
- can_allocate = FALSE;
- break;
- }
+ can_allocate = FALSE;
+ break;
+ }
- GST_DEBUG_OBJECT(allocator, "allocated %u %s buffers out of %u requested",
- breq.count, memory_type_to_str(memory), count);
+ GST_DEBUG_OBJECT (allocator, "allocated %u %s buffers out of %u requested",
+ breq.count, memory_type_to_str (memory), count);
- allocator->can_allocate = can_allocate;
- allocator->count = breq.count;
- allocator->memory = memory;
+ allocator->can_allocate = can_allocate;
+ allocator->count = breq.count;
+ allocator->memory = memory;
- /* Create memory groups */
- for (i = 0; i < allocator->count; i++)
- {
- allocator->groups[i] = gst_aml_v4l2_memory_group_new(allocator, i);
- if (allocator->groups[i] == NULL)
- goto error;
+ /* Create memory groups */
+ for (i = 0; i < allocator->count; i++)
+ {
+ allocator->groups[i] = gst_aml_v4l2_memory_group_new(allocator, i);
+ if (allocator->groups[i] == NULL)
+ goto error;
- gst_atomic_queue_push(allocator->free_queue, allocator->groups[i]);
- }
+ gst_atomic_queue_push (allocator->free_queue, allocator->groups[i]);
+ }
- g_atomic_int_set(&allocator->active, TRUE);
+ g_atomic_int_set (&allocator->active, TRUE);
done:
- GST_OBJECT_UNLOCK(allocator);
- return breq.count;
+ GST_OBJECT_UNLOCK (allocator);
+ return breq.count;
already_active:
-{
- GST_ERROR_OBJECT(allocator, "allocator already active");
+ {
+ GST_ERROR_OBJECT (allocator, "allocator already active");
goto error;
-}
+ }
orphaned:
-{
- GST_ERROR_OBJECT(allocator, "allocator was orphaned");
+ {
+ GST_ERROR_OBJECT (allocator, "allocator was orphaned");
goto error;
-}
+ }
reqbufs_failed:
-{
- GST_ERROR_OBJECT(allocator,
- "error requesting %d buffers: %s", count, g_strerror(errno));
+ {
+ GST_ERROR_OBJECT (allocator,
+ "error requesting %d buffers: %s", count, g_strerror (errno));
goto error;
-}
+ }
out_of_memory:
-{
- GST_ERROR_OBJECT(allocator, "Not enough memory to allocate buffers");
+ {
+ GST_ERROR_OBJECT (allocator, "Not enough memory to allocate buffers");
goto error;
-}
+ }
error:
-{
+ {
breq.count = 0;
goto done;
-}
+ }
}
GstAmlV4l2Return
gst_aml_v4l2_allocator_stop(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_requestbuffers breq = {0, obj->type, allocator->memory};
- gint i = 0;
- GstAmlV4l2Return ret = GST_V4L2_OK;
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_requestbuffers breq = { 0, obj->type, allocator->memory };
+ gint i = 0;
+ GstAmlV4l2Return ret = GST_AML_V4L2_OK;
- GST_DEBUG_OBJECT(allocator, "stop allocator");
+ GST_DEBUG_OBJECT (allocator, "stop allocator");
- GST_OBJECT_LOCK(allocator);
+ GST_OBJECT_LOCK (allocator);
- if (!g_atomic_int_get(&allocator->active))
- goto done;
+ if (!g_atomic_int_get (&allocator->active))
+ goto done;
- if (gst_atomic_queue_length(allocator->free_queue) != allocator->count)
- {
- GST_DEBUG_OBJECT(allocator, "allocator is still in use");
- ret = GST_V4L2_BUSY;
- goto done;
- }
+ if (gst_atomic_queue_length(allocator->free_queue) != allocator->count)
+ {
+ GST_DEBUG_OBJECT (allocator, "allocator is still in use");
+ ret = GST_AML_V4L2_BUSY;
+ goto done;
+ }
- while (gst_atomic_queue_pop(allocator->free_queue))
- {
- /* nothing */
- };
+ while (gst_atomic_queue_pop(allocator->free_queue))
+ {
+ /* nothing */
+ };
- for (i = 0; i < allocator->count; i++)
- {
- GstAmlV4l2MemoryGroup *group = allocator->groups[i];
- allocator->groups[i] = NULL;
- if (group)
- gst_aml_v4l2_memory_group_free(group);
- }
+ for (i = 0; i < allocator->count; i++)
+ {
+ GstAmlV4l2MemoryGroup *group = allocator->groups[i];
+ allocator->groups[i] = NULL;
+ if (group)
+ gst_aml_v4l2_memory_group_free(group);
+ }
- if (!GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
- {
- /* Not all drivers support rebufs(0), so warn only */
- if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
- GST_WARNING_OBJECT(allocator,
- "error releasing buffers buffers: %s", g_strerror(errno));
- }
+ if (!GST_AML_V4L2_ALLOCATOR_IS_ORPHANED(allocator))
+ {
+ /* Not all drivers support rebufs(0), so warn only */
+ if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
+ GST_WARNING_OBJECT (allocator,
+ "error releasing buffers buffers: %s", g_strerror (errno));
+ }
- allocator->count = 0;
+ allocator->count = 0;
- g_atomic_int_set(&allocator->active, FALSE);
+ g_atomic_int_set (&allocator->active, FALSE);
done:
- GST_OBJECT_UNLOCK(allocator);
- return ret;
+ GST_OBJECT_UNLOCK (allocator);
+ return ret;
}
gboolean
gst_aml_v4l2_allocator_orphan(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_requestbuffers breq = {0, obj->type, allocator->memory};
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_requestbuffers breq = { 0, obj->type, allocator->memory };
- if (!GST_AML_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(allocator))
- return FALSE;
+ if (!GST_AML_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(allocator))
+ return FALSE;
- GST_OBJECT_FLAG_SET(allocator, GST_V4L2_ALLOCATOR_FLAG_ORPHANED);
+ GST_OBJECT_FLAG_SET (allocator, GST_V4L2_ALLOCATOR_FLAG_ORPHANED);
- if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
- {
- GST_ERROR_OBJECT(allocator,
- "error orphaning buffers buffers: %s", g_strerror(errno));
- return FALSE;
- }
+ if (obj->ioctl(obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
+ {
+ GST_ERROR_OBJECT (allocator,
+ "error orphaning buffers buffers: %s", g_strerror (errno));
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_alloc_mmap(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2MemoryGroup *group;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2MemoryGroup *group;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_MMAP, NULL);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_MMAP, NULL);
- group = gst_aml_v4l2_allocator_alloc(allocator);
+ group = gst_aml_v4l2_allocator_alloc(allocator);
- if (group == NULL)
- return NULL;
+ if (group == NULL)
+ return NULL;
- for (i = 0; i < group->n_mem; i++)
+ for (i = 0; i < group->n_mem; i++)
+ {
+ if (group->mem[i] == NULL)
{
- if (group->mem[i] == NULL)
- {
- gpointer data;
- data = obj->mmap(NULL, group->planes[i].length, PROT_READ | PROT_WRITE,
- MAP_SHARED, obj->video_fd, group->planes[i].m.mem_offset);
+ gpointer data;
+ data = obj->mmap (NULL, group->planes[i].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, obj->video_fd, group->planes[i].m.mem_offset);
- if (data == MAP_FAILED)
- goto mmap_failed;
+ if (data == MAP_FAILED)
+ goto mmap_failed;
- GST_LOG_OBJECT(allocator,
- "mmap buffer length %d, data offset %d, plane %d",
- group->planes[i].length, group->planes[i].data_offset, i);
+ GST_LOG_OBJECT (allocator,
+ "mmap buffer length %d, data offset %d, plane %d",
+ group->planes[i].length, group->planes[i].data_offset, i);
- group->mem[i] = (GstMemory *)_v4l2mem_new(0, GST_ALLOCATOR(allocator),
- NULL, group->planes[i].length, 0, 0, group->planes[i].length, i, data,
- -1, group);
- }
- else
- {
- /* Take back the allocator reference */
- gst_object_ref(allocator);
- }
-
- group->mems_allocated++;
+ group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+ NULL, group->planes[i].length, 0, 0, group->planes[i].length, i, data,
+ -1, group);
+ }
+ else
+ {
+ /* Take back the allocator reference */
+ gst_object_ref (allocator);
}
- /* Ensure group size. Unlike GST, v4l2 have size (bytesused) initially set
- * to 0. As length might be bigger then the expected size exposed in the
- * format, we simply set bytesused initially and reset it here for
- * simplicity */
- gst_aml_v4l2_allocator_reset_size(allocator, group);
+ group->mems_allocated++;
+ }
- return group;
+ /* Ensure group size. Unlike GST, v4l2 have size (bytesused) initially set
+ * to 0. As length might be bigger then the expected size exposed in the
+ * format, we simply set bytesused initially and reset it here for
+ * simplicity */
+ gst_aml_v4l2_allocator_reset_size(allocator, group);
+
+ return group;
mmap_failed:
-{
- GST_ERROR_OBJECT(allocator, "Failed to mmap buffer: %s",
- g_strerror(errno));
- _cleanup_failed_alloc(allocator, group);
+ {
+ GST_ERROR_OBJECT (allocator, "Failed to mmap buffer: %s",
+ g_strerror (errno));
+ _cleanup_failed_alloc (allocator, group);
return NULL;
-}
+ }
}
GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_alloc_dmabuf(GstAmlV4l2Allocator *allocator,
- GstAllocator *dmabuf_allocator)
+ GstAllocator * dmabuf_allocator)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2MemoryGroup *group;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2MemoryGroup *group;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_MMAP, NULL);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_MMAP, NULL);
- group = gst_aml_v4l2_allocator_alloc(allocator);
+ group = gst_aml_v4l2_allocator_alloc(allocator);
- if (group == NULL)
- return NULL;
+ if (group == NULL)
+ return NULL;
- for (i = 0; i < group->n_mem; i++)
+ for (i = 0; i < group->n_mem; i++)
+ {
+ GstAmlV4l2Memory *mem;
+ GstMemory *dma_mem;
+
+ if (group->mem[i] == NULL)
{
- GstAmlV4l2Memory *mem;
- GstMemory *dma_mem;
+ struct v4l2_exportbuffer expbuf = { 0 };
- if (group->mem[i] == NULL)
- {
- struct v4l2_exportbuffer expbuf = {0};
+ expbuf.type = obj->type;
+ expbuf.index = group->buffer.index;
+ expbuf.plane = i;
+ expbuf.flags = O_CLOEXEC | O_RDWR;
- expbuf.type = obj->type;
- expbuf.index = group->buffer.index;
- expbuf.plane = i;
- expbuf.flags = O_CLOEXEC | O_RDWR;
+ if (obj->ioctl (obj->video_fd, VIDIOC_EXPBUF, &expbuf) < 0)
+ goto expbuf_failed;
- if (obj->ioctl(obj->video_fd, VIDIOC_EXPBUF, &expbuf) < 0)
- goto expbuf_failed;
+ GST_LOG_OBJECT (allocator, "exported DMABUF as fd %i plane %d",
+ expbuf.fd, i);
- GST_LOG_OBJECT(allocator, "exported DMABUF as fd %i plane %d",
- expbuf.fd, i);
-
- group->mem[i] = (GstMemory *)_v4l2mem_new(0, GST_ALLOCATOR(allocator),
- NULL, group->planes[i].length, 0, group->planes[i].data_offset,
- group->planes[i].length - group->planes[i].data_offset, i, NULL,
- expbuf.fd, group);
- }
- else
- {
- /* Take back the allocator reference */
- gst_object_ref(allocator);
- }
-
- group->mems_allocated++;
-
- g_assert(gst_is_aml_v4l2_memory(group->mem[i]));
- mem = (GstAmlV4l2Memory *)group->mem[i];
-
- dma_mem = gst_fd_allocator_alloc(dmabuf_allocator, mem->dmafd,
- group->planes[i].length, GST_FD_MEMORY_FLAG_DONT_CLOSE);
- gst_memory_resize(dma_mem, group->planes[i].data_offset,
- group->planes[i].length - group->planes[i].data_offset);
-
- gst_mini_object_set_qdata(GST_MINI_OBJECT(dma_mem),
- GST_AML_V4L2_MEMORY_QUARK, mem, (GDestroyNotify)gst_memory_unref);
-
- group->mem[i] = dma_mem;
+ group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+ NULL, group->planes[i].length, 0, group->planes[i].data_offset,
+ group->planes[i].length - group->planes[i].data_offset, i, NULL,
+ expbuf.fd, group);
+ }
+ else
+ {
+ /* Take back the allocator reference */
+ gst_object_ref (allocator);
}
- gst_aml_v4l2_allocator_reset_size(allocator, group);
+ group->mems_allocated++;
- return group;
+ g_assert(gst_aml_is_v4l2_memory(group->mem[i]));
+ mem = (GstAmlV4l2Memory *)group->mem[i];
+
+ dma_mem = gst_fd_allocator_alloc (dmabuf_allocator, mem->dmafd,
+ group->planes[i].length, GST_FD_MEMORY_FLAG_DONT_CLOSE);
+ gst_memory_resize (dma_mem, group->planes[i].data_offset,
+ group->planes[i].length - group->planes[i].data_offset);
+
+ gst_mini_object_set_qdata (GST_MINI_OBJECT (dma_mem),
+ GST_AML_V4L2_MEMORY_QUARK, mem, (GDestroyNotify)gst_memory_unref);
+
+ group->mem[i] = dma_mem;
+ }
+
+ gst_aml_v4l2_allocator_reset_size(allocator, group);
+
+ return group;
expbuf_failed:
-{
- GST_ERROR_OBJECT(allocator, "Failed to export DMABUF: %s",
- g_strerror(errno));
+ {
+ GST_ERROR_OBJECT (allocator, "Failed to export DMABUF: %s",
+ g_strerror (errno));
goto cleanup;
-}
+ }
cleanup:
-{
- _cleanup_failed_alloc(allocator, group);
+ {
+ _cleanup_failed_alloc (allocator, group);
return NULL;
-}
+ }
}
static void
gst_aml_v4l2_allocator_clear_dmabufin(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2MemoryGroup *group)
+ GstAmlV4l2MemoryGroup *group)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2Memory *mem;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2Memory *mem;
+ gint i;
- g_return_if_fail(allocator->memory == V4L2_MEMORY_DMABUF);
+ g_return_if_fail (allocator->memory == V4L2_MEMORY_DMABUF);
- for (i = 0; i < group->n_mem; i++)
- {
+ for (i = 0; i < group->n_mem; i++)
+ {
- mem = (GstAmlV4l2Memory *)group->mem[i];
+ mem = (GstAmlV4l2Memory *)group->mem[i];
- GST_LOG_OBJECT(allocator, "[%i] clearing DMABUF import, fd %i plane %d",
- group->buffer.index, mem->dmafd, i);
+ GST_LOG_OBJECT (allocator, "[%i] clearing DMABUF import, fd %i plane %d",
+ group->buffer.index, mem->dmafd, i);
- /* Update memory */
- mem->mem.maxsize = 0;
- mem->mem.offset = 0;
- mem->mem.size = 0;
- mem->dmafd = -1;
+ /* Update memory */
+ mem->mem.maxsize = 0;
+ mem->mem.offset = 0;
+ mem->mem.size = 0;
+ mem->dmafd = -1;
- /* Update v4l2 structure */
- group->planes[i].length = 0;
- group->planes[i].bytesused = 0;
- group->planes[i].m.fd = -1;
- group->planes[i].data_offset = 0;
- }
+ /* Update v4l2 structure */
+ group->planes[i].length = 0;
+ group->planes[i].bytesused = 0;
+ group->planes[i].m.fd = -1;
+ group->planes[i].data_offset = 0;
+ }
- if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- group->buffer.bytesused = 0;
- group->buffer.length = 0;
- group->buffer.m.fd = -1;
- }
+ if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ group->buffer.bytesused = 0;
+ group->buffer.length = 0;
+ group->buffer.m.fd = -1;
+ }
}
GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_alloc_dmabufin(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2MemoryGroup *group;
- gint i;
+ GstAmlV4l2MemoryGroup *group;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_DMABUF, NULL);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_DMABUF, NULL);
- group = gst_aml_v4l2_allocator_alloc(allocator);
+ group = gst_aml_v4l2_allocator_alloc(allocator);
- if (group == NULL)
- return NULL;
+ if (group == NULL)
+ return NULL;
- GST_LOG_OBJECT(allocator, "allocating empty DMABUF import group");
+ GST_LOG_OBJECT (allocator, "allocating empty DMABUF import group");
- for (i = 0; i < group->n_mem; i++)
+ for (i = 0; i < group->n_mem; i++)
+ {
+ if (group->mem[i] == NULL)
{
- if (group->mem[i] == NULL)
- {
- group->mem[i] = (GstMemory *)_v4l2mem_new(0, GST_ALLOCATOR(allocator),
- NULL, 0, 0, 0, 0, i, NULL, -1, group);
- }
- else
- {
- /* Take back the allocator reference */
- gst_object_ref(allocator);
- }
-
- group->mems_allocated++;
+ group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+ NULL, 0, 0, 0, 0, i, NULL, -1, group);
+ }
+ else
+ {
+ /* Take back the allocator reference */
+ gst_object_ref (allocator);
}
- gst_aml_v4l2_allocator_clear_dmabufin(allocator, group);
+ group->mems_allocated++;
+ }
- return group;
+ gst_aml_v4l2_allocator_clear_dmabufin(allocator, group);
+
+ return group;
}
static void
gst_aml_v4l2_allocator_clear_userptr(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2MemoryGroup *group)
+ GstAmlV4l2MemoryGroup *group)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2Memory *mem;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2Memory *mem;
+ gint i;
- g_return_if_fail(allocator->memory == V4L2_MEMORY_USERPTR);
+ g_return_if_fail (allocator->memory == V4L2_MEMORY_USERPTR);
- for (i = 0; i < group->n_mem; i++)
- {
- mem = (GstAmlV4l2Memory *)group->mem[i];
+ for (i = 0; i < group->n_mem; i++)
+ {
+ mem = (GstAmlV4l2Memory *)group->mem[i];
- GST_LOG_OBJECT(allocator, "[%i] clearing USERPTR %p plane %d size %" G_GSIZE_FORMAT, group->buffer.index, mem->data, i, mem->mem.size);
+ GST_LOG_OBJECT (allocator, "[%i] clearing USERPTR %p plane %d size %"
+ G_GSIZE_FORMAT, group->buffer.index, mem->data, i, mem->mem.size);
- mem->mem.maxsize = 0;
- mem->mem.size = 0;
- mem->data = NULL;
+ mem->mem.maxsize = 0;
+ mem->mem.size = 0;
+ mem->data = NULL;
- group->planes[i].length = 0;
- group->planes[i].bytesused = 0;
- group->planes[i].m.userptr = 0;
- }
+ group->planes[i].length = 0;
+ group->planes[i].bytesused = 0;
+ group->planes[i].m.userptr = 0;
+ }
- if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- group->buffer.bytesused = 0;
- group->buffer.length = 0;
- group->buffer.m.userptr = 0;
- }
+ if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ group->buffer.bytesused = 0;
+ group->buffer.length = 0;
+ group->buffer.m.userptr = 0;
+ }
}
GstAmlV4l2MemoryGroup *
gst_aml_v4l2_allocator_alloc_userptr(GstAmlV4l2Allocator *allocator)
{
- GstAmlV4l2MemoryGroup *group;
- gint i;
+ GstAmlV4l2MemoryGroup *group;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_USERPTR, NULL);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_USERPTR, NULL);
- group = gst_aml_v4l2_allocator_alloc(allocator);
+ group = gst_aml_v4l2_allocator_alloc (allocator);
- if (group == NULL)
- return NULL;
+ if (group == NULL)
+ return NULL;
- GST_LOG_OBJECT(allocator, "allocating empty USERPTR group");
+ GST_LOG_OBJECT (allocator, "allocating empty USERPTR group");
- for (i = 0; i < group->n_mem; i++)
+ for (i = 0; i < group->n_mem; i++)
+ {
+
+ if (group->mem[i] == NULL)
{
-
- if (group->mem[i] == NULL)
- {
- group->mem[i] = (GstMemory *)_v4l2mem_new(0, GST_ALLOCATOR(allocator),
- NULL, 0, 0, 0, 0, i, NULL, -1, group);
- }
- else
- {
- /* Take back the allocator reference */
- gst_object_ref(allocator);
- }
-
- group->mems_allocated++;
+ group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
+ NULL, 0, 0, 0, 0, i, NULL, -1, group);
+ }
+ else
+ {
+ /* Take back the allocator reference */
+ gst_object_ref (allocator);
}
- gst_aml_v4l2_allocator_clear_userptr(allocator, group);
+ group->mems_allocated++;
+ }
- return group;
+ gst_aml_v4l2_allocator_clear_userptr(allocator, group);
+
+ return group;
}
gboolean
gst_aml_v4l2_allocator_import_dmabuf(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2MemoryGroup *group, gint n_mem, GstMemory **dma_mem)
+ GstAmlV4l2MemoryGroup *group, gint n_mem, GstMemory **dma_mem)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2Memory *mem;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2Memory *mem;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_DMABUF, FALSE);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_DMABUF, FALSE);
- if (group->n_mem != n_mem)
- goto n_mem_missmatch;
+ if (group->n_mem != n_mem)
+ goto n_mem_missmatch;
- for (i = 0; i < group->n_mem; i++)
- {
- gint dmafd;
- gsize size, offset, maxsize;
+ for (i = 0; i < group->n_mem; i++)
+ {
+ gint dmafd;
+ gsize size, offset, maxsize;
- if (!gst_is_dmabuf_memory(dma_mem[i]))
- goto not_dmabuf;
+ if (!gst_is_dmabuf_memory (dma_mem[i]))
+ goto not_dmabuf;
- size = gst_memory_get_sizes(dma_mem[i], &offset, &maxsize);
+ size = gst_memory_get_sizes (dma_mem[i], &offset, &maxsize);
- dmafd = gst_dmabuf_memory_get_fd(dma_mem[i]);
+ dmafd = gst_dmabuf_memory_get_fd (dma_mem[i]);
- GST_LOG_OBJECT(allocator, "[%i] imported DMABUF as fd %i plane %d",
- group->buffer.index, dmafd, i);
+ GST_LOG_OBJECT (allocator, "[%i] imported DMABUF as fd %i plane %d",
+ group->buffer.index, dmafd, i);
- mem = (GstAmlV4l2Memory *)group->mem[i];
+ mem = (GstAmlV4l2Memory *) group->mem[i];
- /* Update memory */
- mem->mem.maxsize = maxsize;
- mem->mem.offset = offset;
- mem->mem.size = size;
- mem->dmafd = dmafd;
+ /* Update memory */
+ mem->mem.maxsize = maxsize;
+ mem->mem.offset = offset;
+ mem->mem.size = size;
+ mem->dmafd = dmafd;
- /* Update v4l2 structure */
- group->planes[i].length = maxsize;
- group->planes[i].bytesused = size + offset;
- group->planes[i].m.fd = dmafd;
- group->planes[i].data_offset = offset;
- }
+ /* Update v4l2 structure */
+ group->planes[i].length = maxsize;
+ group->planes[i].bytesused = size + offset;
+ group->planes[i].m.fd = dmafd;
+ group->planes[i].data_offset = offset;
+ }
- /* Copy into buffer structure if not using planes */
- if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- group->buffer.bytesused = group->planes[0].bytesused;
- group->buffer.length = group->planes[0].length;
- group->buffer.m.fd = group->planes[0].m.userptr;
+ /* Copy into buffer structure if not using planes */
+ if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ group->buffer.bytesused = group->planes[0].bytesused;
+ group->buffer.length = group->planes[0].length;
+ group->buffer.m.fd = group->planes[0].m.fd;
- /* FIXME Check if data_offset > 0 and fail for non-multi-planar */
- g_assert(group->planes[0].data_offset == 0);
- }
- else
- {
- group->buffer.length = group->n_mem;
- }
+ /* FIXME Check if data_offset > 0 and fail for non-multi-planar */
+ g_assert (group->planes[0].data_offset == 0);
+ }
+ else
+ {
+ group->buffer.length = group->n_mem;
+ }
- return TRUE;
+ return TRUE;
n_mem_missmatch:
-{
- GST_ERROR_OBJECT(allocator, "Got %i dmabuf but needed %i", n_mem,
- group->n_mem);
+ {
+ GST_ERROR_OBJECT (allocator, "Got %i dmabuf but needed %i", n_mem,
+ group->n_mem);
return FALSE;
-}
+ }
not_dmabuf:
-{
- GST_ERROR_OBJECT(allocator, "Memory %i is not of DMABUF", i);
+ {
+ GST_ERROR_OBJECT (allocator, "Memory %i is not of DMABUF", i);
return FALSE;
-}
+ }
}
gboolean
gst_aml_v4l2_allocator_import_userptr(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2MemoryGroup *group, gsize img_size, int n_planes,
- gpointer *data, gsize *size)
+ GstAmlV4l2MemoryGroup *group, gsize img_size, int n_planes,
+ gpointer * data, gsize * size)
{
- GstAmlV4l2Object *obj = allocator->obj;
- GstAmlV4l2Memory *mem;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ GstAmlV4l2Memory *mem;
+ gint i;
- g_return_val_if_fail(allocator->memory == V4L2_MEMORY_USERPTR, FALSE);
+ g_return_val_if_fail (allocator->memory == V4L2_MEMORY_USERPTR, FALSE);
- /* TODO Support passing N plane from 1 memory to MPLANE v4l2 format */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type) && n_planes != group->n_mem)
- goto n_mem_missmatch;
+ /* TODO Support passing N plane from 1 memory to MPLANE v4l2 format */
+ if (V4L2_TYPE_IS_MULTIPLANAR (obj->type) && n_planes != group->n_mem)
+ goto n_mem_missmatch;
- for (i = 0; i < group->n_mem; i++)
- {
- gsize maxsize, psize;
+ for (i = 0; i < group->n_mem; i++)
+ {
+ gsize maxsize, psize;
- /* TODO request used size and maxsize seperatly */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- maxsize = psize = size[i];
- else
- maxsize = psize = img_size;
-
- g_assert(psize <= img_size);
-
- GST_LOG_OBJECT(allocator, "[%i] imported USERPTR %p plane %d size %" G_GSIZE_FORMAT, group->buffer.index, data[i], i, psize);
-
- mem = (GstAmlV4l2Memory *)group->mem[i];
-
- mem->mem.maxsize = maxsize;
- mem->mem.size = psize;
- mem->data = data[i];
-
- group->planes[i].length = maxsize;
- group->planes[i].bytesused = psize;
- group->planes[i].m.userptr = (unsigned long)data[i];
- group->planes[i].data_offset = 0;
- }
-
- /* Copy into buffer structure if not using planes */
- if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- group->buffer.bytesused = group->planes[0].bytesused;
- group->buffer.length = group->planes[0].length;
- group->buffer.m.userptr = group->planes[0].m.userptr;
- }
+ /* TODO request used size and maxsize separately */
+ if (V4L2_TYPE_IS_MULTIPLANAR (obj->type))
+ maxsize = psize = size[i];
else
- {
- group->buffer.length = group->n_mem;
- }
+ maxsize = psize = img_size;
- return TRUE;
+ g_assert (psize <= img_size);
+
+ GST_LOG_OBJECT(allocator, "[%i] imported USERPTR %p plane %d size %" G_GSIZE_FORMAT, group->buffer.index, data[i], i, psize);
+
+ mem = (GstAmlV4l2Memory *)group->mem[i];
+
+ mem->mem.maxsize = maxsize;
+ mem->mem.size = psize;
+ mem->data = data[i];
+
+ group->planes[i].length = maxsize;
+ group->planes[i].bytesused = psize;
+ group->planes[i].m.userptr = (unsigned long) data[i];
+ group->planes[i].data_offset = 0;
+ }
+
+ /* Copy into buffer structure if not using planes */
+ if (!V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ group->buffer.bytesused = group->planes[0].bytesused;
+ group->buffer.length = group->planes[0].length;
+ group->buffer.m.userptr = group->planes[0].m.userptr;
+ }
+ else
+ {
+ group->buffer.length = group->n_mem;
+ }
+
+ return TRUE;
n_mem_missmatch:
-{
- GST_ERROR_OBJECT(allocator, "Got %i userptr plane while driver need %i",
- n_planes, group->n_mem);
+ {
+ GST_ERROR_OBJECT (allocator, "Got %i userptr plane while driver need %i",
+ n_planes, group->n_mem);
return FALSE;
-}
+ }
}
void gst_aml_v4l2_allocator_flush(GstAmlV4l2Allocator *allocator)
{
- gint i;
+ gint i;
- GST_OBJECT_LOCK(allocator);
+ GST_OBJECT_LOCK (allocator);
- if (!g_atomic_int_get(&allocator->active))
- goto done;
+ if (!g_atomic_int_get (&allocator->active))
+ goto done;
- for (i = 0; i < allocator->count; i++)
+ for (i = 0; i < allocator->count; i++)
+ {
+ GstAmlV4l2MemoryGroup *group = allocator->groups[i];
+ gint n;
+
+ if (IS_QUEUED (group->buffer))
{
- GstAmlV4l2MemoryGroup *group = allocator->groups[i];
- gint n;
+ UNSET_QUEUED (group->buffer);
- if (IS_QUEUED(group->buffer))
- {
- UNSET_QUEUED(group->buffer);
+ gst_aml_v4l2_allocator_reset_group (allocator, group);
- gst_aml_v4l2_allocator_reset_group(allocator, group);
-
- for (n = 0; n < group->n_mem; n++)
- gst_memory_unref(group->mem[n]);
- }
+ for (n = 0; n < group->n_mem; n++)
+ gst_memory_unref (group->mem[n]);
}
+ }
done:
- GST_OBJECT_UNLOCK(allocator);
+ GST_OBJECT_UNLOCK (allocator);
}
gboolean
gst_aml_v4l2_allocator_qbuf(GstAmlV4l2Allocator *allocator,
GstAmlV4l2MemoryGroup *group)
{
- GstAmlV4l2Object *obj = allocator->obj;
- gboolean ret = TRUE;
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ gboolean ret = TRUE;
+ gint i;
- g_return_val_if_fail(g_atomic_int_get(&allocator->active), FALSE);
+ g_return_val_if_fail (g_atomic_int_get (&allocator->active), FALSE);
- /* update sizes */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- for (i = 0; i < group->n_mem; i++)
- group->planes[i].bytesused =
- gst_memory_get_sizes(group->mem[i], NULL, NULL);
- }
- else
- {
- group->buffer.bytesused = gst_memory_get_sizes(group->mem[0], NULL, NULL);
- }
-
- /* Ensure the memory will stay around and is RO */
+ /* update sizes */
+ if (V4L2_TYPE_IS_MULTIPLANAR (obj->type))
+ {
for (i = 0; i < group->n_mem; i++)
- gst_memory_ref(group->mem[i]);
+ group->planes[i].bytesused =
+ gst_memory_get_sizes (group->mem[i], NULL, NULL);
+ }
+ else
+ {
+ group->buffer.bytesused = gst_memory_get_sizes (group->mem[0], NULL, NULL);
+ }
- gint64 currFramePTS= 0;
- if (group->buffer.timestamp.tv_sec != -1) {
- currFramePTS= group->buffer.timestamp.tv_sec * 1000000LL + group->buffer.timestamp.tv_usec;
- }
- GST_LOG_OBJECT(allocator, "q buffer, timestamp:%lld",currFramePTS);
+ /* Ensure the memory will stay around and is RO */
+ for (i = 0; i < group->n_mem; i++)
+ gst_memory_ref (group->mem[i]);
- gst_aml_v4l2_allocator_dump_es_buf(allocator, group);
+ gint64 currFramePTS= 0;
+ if (group->buffer.timestamp.tv_sec != -1) {
+ currFramePTS= group->buffer.timestamp.tv_sec * 1000000LL + group->buffer.timestamp.tv_usec;
+ }
+ GST_LOG_OBJECT(allocator, "q buffer, timestamp:%lld",currFramePTS);
- if (obj->ioctl(obj->video_fd, VIDIOC_QBUF, &group->buffer) < 0)
+ gst_aml_v4l2_allocator_dump_es_buf(allocator, group);
+
+ if (obj->ioctl(obj->video_fd, VIDIOC_QBUF, &group->buffer) < 0)
+ {
+ GST_ERROR_OBJECT (allocator, "failed queueing buffer %i: %s",
+ group->buffer.index, g_strerror (errno));
+
+ /* Release the memory, possibly making it RW again */
+ for (i = 0; i < group->n_mem; i++)
+ gst_memory_unref (group->mem[i]);
+
+ ret = FALSE;
+ if (IS_QUEUED(group->buffer))
{
- GST_ERROR_OBJECT(allocator, "failed queueing buffer %i: %s",
- group->buffer.index, g_strerror(errno));
-
- /* Release the memory, possibly making it RW again */
- for (i = 0; i < group->n_mem; i++)
- gst_memory_unref(group->mem[i]);
-
- ret = FALSE;
- if (IS_QUEUED(group->buffer))
- {
- GST_DEBUG_OBJECT(allocator,
- "driver pretends buffer is queued even if queue failed");
- UNSET_QUEUED(group->buffer);
- }
- goto done;
+ GST_DEBUG_OBJECT (allocator,
+ "driver pretends buffer is queued even if queue failed");
+ UNSET_QUEUED (group->buffer);
}
+ goto done;
+ }
- GST_LOG_OBJECT(allocator, "queued buffer %i (flags 0x%X)",
- group->buffer.index, group->buffer.flags);
+ GST_LOG_OBJECT (allocator, "queued buffer %i (flags 0x%X)",
+ group->buffer.index, group->buffer.flags);
- if (!IS_QUEUED(group->buffer))
- {
- GST_DEBUG_OBJECT(allocator,
- "driver pretends buffer is not queued even if queue succeeded");
- SET_QUEUED(group->buffer);
- }
+ if (!IS_QUEUED(group->buffer))
+ {
+ GST_DEBUG_OBJECT (allocator,
+ "driver pretends buffer is not queued even if queue succeeded");
+ SET_QUEUED (group->buffer);
+ }
done:
- return ret;
+ return ret;
}
GstFlowReturn
gst_aml_v4l2_allocator_dqbuf(GstAmlV4l2Allocator *allocator,
GstAmlV4l2MemoryGroup **group_out)
{
- GstAmlV4l2Object *obj = allocator->obj;
- struct v4l2_buffer buffer = {0};
- struct v4l2_plane planes[VIDEO_MAX_PLANES] = {{0}};
- gint i;
+ GstAmlV4l2Object *obj = allocator->obj;
+ struct v4l2_buffer buffer = { 0 };
+ struct v4l2_plane planes[VIDEO_MAX_PLANES] = { {0} };
+ gint i;
- GstAmlV4l2MemoryGroup *group = NULL;
+ GstAmlV4l2MemoryGroup *group = NULL;
- g_return_val_if_fail(g_atomic_int_get(&allocator->active), GST_FLOW_ERROR);
+ g_return_val_if_fail (g_atomic_int_get (&allocator->active), GST_FLOW_ERROR);
- buffer.type = obj->type;
- buffer.memory = allocator->memory;
+ buffer.type = obj->type;
+ buffer.memory = allocator->memory;
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- buffer.length = obj->format.fmt.pix_mp.num_planes;
- buffer.m.planes = planes;
- }
+ if (V4L2_TYPE_IS_MULTIPLANAR (obj->type))
+ {
+ buffer.length = obj->format.fmt.pix_mp.num_planes;
+ buffer.m.planes = planes;
+ }
- if (obj->ioctl(obj->video_fd, VIDIOC_DQBUF, &buffer) < 0)
- goto error;
+ if (obj->ioctl (obj->video_fd, VIDIOC_DQBUF, &buffer) < 0)
+ goto error;
- group = allocator->groups[buffer.index];
+ group = allocator->groups[buffer.index];
- if (!IS_QUEUED(group->buffer))
- {
- GST_ERROR_OBJECT(allocator,
- "buffer %i was not queued, this indicate a driver bug.", buffer.index);
- return GST_FLOW_ERROR;
- }
+ if (!IS_QUEUED(group->buffer))
+ {
+ GST_ERROR_OBJECT (allocator,
+ "buffer %i was not queued, this indicate a driver bug.", buffer.index);
+ return GST_FLOW_ERROR;
+ }
- group->buffer = buffer;
+ group->buffer = buffer;
- GST_LOG_OBJECT(allocator, "dequeued buffer %i (flags 0x%X)", buffer.index,
- buffer.flags);
+ GST_LOG_OBJECT (allocator, "dequeued buffer %i (flags 0x%X)", buffer.index,
+ buffer.flags);
- if (IS_QUEUED(group->buffer))
- {
- GST_DEBUG_OBJECT(allocator,
- "driver pretends buffer is queued even if dequeue succeeded");
- UNSET_QUEUED(group->buffer);
- }
+ if (IS_QUEUED(group->buffer))
+ {
+ GST_DEBUG_OBJECT (allocator,
+ "driver pretends buffer is queued even if dequeue succeeded");
+ UNSET_QUEUED (group->buffer);
+ }
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- group->buffer.m.planes = group->planes;
- memcpy(group->planes, buffer.m.planes, sizeof(planes));
- }
- else
- {
- group->planes[0].bytesused = group->buffer.bytesused;
- group->planes[0].length = group->buffer.length;
- g_assert(sizeof(group->planes[0].m) == sizeof(group->buffer.m));
- memcpy(&group->planes[0].m, &group->buffer.m, sizeof(group->buffer.m));
- }
+ if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ group->buffer.m.planes = group->planes;
+ memcpy (group->planes, buffer.m.planes, sizeof (planes));
+ }
+ else
+ {
+ group->planes[0].bytesused = group->buffer.bytesused;
+ group->planes[0].length = group->buffer.length;
+ g_assert (sizeof (group->planes[0].m) == sizeof (group->buffer.m));
+ memcpy (&group->planes[0].m, &group->buffer.m, sizeof (group->buffer.m));
+ }
- /* And update memory size */
- if (V4L2_TYPE_IS_OUTPUT(obj->type))
- {
- gst_aml_v4l2_allocator_reset_size(allocator, group);
- }
- else
- {
- /* for capture, simply read the size */
- for (i = 0; i < group->n_mem; i++)
- {
- gsize size, offset;
-
- GST_LOG_OBJECT(allocator,
- "Dequeued capture buffer, length: %u bytesused: %u data_offset: %u",
- group->planes[i].length, group->planes[i].bytesused,
- group->planes[i].data_offset);
-
- offset = group->planes[i].data_offset;
-
- if (group->planes[i].bytesused > group->planes[i].data_offset)
- {
- size = group->planes[i].bytesused - group->planes[i].data_offset;
- }
- else
- {
- GST_WARNING_OBJECT(allocator, "V4L2 provided buffer has bytesused %" G_GUINT32_FORMAT " which is too small to include data_offset %" G_GUINT32_FORMAT, group->planes[i].bytesused,
- group->planes[i].data_offset);
- size = group->planes[i].bytesused;
- /*if this buffer is last buffer,bytesused is 0,so size equal 0,this cause assert fail of gst_memory_resize*/
- if ( (group->buffer.flags & V4L2_BUF_FLAG_LAST) &&(group->buffer.bytesused == 0))
- {
- size = group->planes[i].length;
- }
- }
-
- if (G_LIKELY(size + offset <= group->mem[i]->maxsize))
- gst_memory_resize(group->mem[i], offset, size);
- else
- {
- GST_WARNING_OBJECT(allocator,
- "v4l2 provided buffer that is too big for the memory it was "
- "writing into. v4l2 claims %" G_GSIZE_FORMAT " bytes used but "
- "memory is only %" G_GSIZE_FORMAT "B. This is probably a driver "
- "bug.",
- size, group->mem[i]->maxsize);
- gst_memory_resize(group->mem[i], 0, group->mem[i]->maxsize);
- }
- }
- }
-
- /* Release the memory, possibly making it RW again */
+ /* And update memory size */
+ if (V4L2_TYPE_IS_OUTPUT(obj->type))
+ {
+ gst_aml_v4l2_allocator_reset_size(allocator, group);
+ }
+ else
+ {
+ /* for capture, simply read the size */
for (i = 0; i < group->n_mem; i++)
- gst_memory_unref(group->mem[i]);
+ {
+ gsize size, offset;
- *group_out = group;
- return GST_FLOW_OK;
+ GST_LOG_OBJECT (allocator,
+ "Dequeued capture buffer, length: %u bytesused: %u data_offset: %u",
+ group->planes[i].length, group->planes[i].bytesused,
+ group->planes[i].data_offset);
+
+ offset = group->planes[i].data_offset;
+
+ if (group->planes[i].bytesused > group->planes[i].data_offset)
+ {
+ size = group->planes[i].bytesused - group->planes[i].data_offset;
+ }
+ else
+ {
+ GST_WARNING_OBJECT(allocator, "V4L2 provided buffer has bytesused %" G_GUINT32_FORMAT " which is too small to include data_offset %" G_GUINT32_FORMAT, group->planes[i].bytesused,
+ group->planes[i].data_offset);
+ size = group->planes[i].bytesused;
+ /*if this buffer is last buffer,bytesused is 0,so size equal 0,this cause assert fail of gst_memory_resize*/
+ if ( (group->buffer.flags & V4L2_BUF_FLAG_LAST) &&(group->buffer.bytesused == 0))
+ {
+ size = group->planes[i].length;
+ }
+ }
+
+ if (G_LIKELY (size + offset <= group->mem[i]->maxsize))
+ gst_memory_resize (group->mem[i], offset, size);
+ else
+ {
+ GST_WARNING_OBJECT (allocator,
+ "v4l2 provided buffer that is too big for the memory it was "
+ "writing into. v4l2 claims %" G_GSIZE_FORMAT " bytes used but "
+ "memory is only %" G_GSIZE_FORMAT "B. This is probably a driver "
+ "bug.", size, group->mem[i]->maxsize);
+ gst_memory_resize (group->mem[i], 0, group->mem[i]->maxsize);
+ }
+ }
+ }
+
+ /* Release the memory, possibly making it RW again */
+ for (i = 0; i < group->n_mem; i++)
+ gst_memory_unref (group->mem[i]);
+
+ *group_out = group;
+ return GST_FLOW_OK;
error:
- if (errno == EPIPE)
- {
- GST_DEBUG_OBJECT(allocator, "broken pipe signals last buffer");
- return GST_FLOW_EOS;
- }
+ if (errno == EPIPE)
+ {
+ GST_DEBUG_OBJECT (allocator, "broken pipe signals last buffer");
+ return GST_FLOW_EOS;
+ }
- GST_ERROR_OBJECT(allocator, "failed dequeuing a %s buffer: %s",
- memory_type_to_str(allocator->memory), g_strerror(errno));
+ GST_ERROR_OBJECT (allocator, "failed dequeuing a %s buffer: %s",
+ memory_type_to_str (allocator->memory), g_strerror (errno));
- switch (errno)
- {
+ switch (errno)
+ {
case EAGAIN:
- GST_WARNING_OBJECT(allocator,
- "Non-blocking I/O has been selected using O_NONBLOCK and"
- " no buffer was in the outgoing queue.");
- break;
+ GST_WARNING_OBJECT (allocator,
+ "Non-blocking I/O has been selected using O_NONBLOCK and"
+ " no buffer was in the outgoing queue.");
+ break;
case EINVAL:
- GST_ERROR_OBJECT(allocator,
- "The buffer type is not supported, or the index is out of bounds, "
- "or no buffers have been allocated yet, or the userptr "
- "or length are invalid.");
- break;
+ GST_ERROR_OBJECT (allocator,
+ "The buffer type is not supported, or the index is out of bounds, "
+ "or no buffers have been allocated yet, or the userptr "
+ "or length are invalid.");
+ break;
case ENOMEM:
- GST_ERROR_OBJECT(allocator,
- "insufficient memory to enqueue a user pointer buffer");
- break;
+ GST_ERROR_OBJECT (allocator,
+ "insufficient memory to enqueue a user pointer buffer");
+ break;
case EIO:
- GST_INFO_OBJECT(allocator,
- "VIDIOC_DQBUF failed due to an internal error."
- " Can also indicate temporary problems like signal loss."
- " Note the driver might dequeue an (empty) buffer despite"
- " returning an error, or even stop capturing.");
- /* have we de-queued a buffer ? */
- if (!IS_QUEUED(buffer))
- {
- GST_DEBUG_OBJECT(allocator, "reenqueueing buffer");
- /* FIXME ... should we do something here? */
- }
- break;
+ GST_INFO_OBJECT (allocator,
+ "VIDIOC_DQBUF failed due to an internal error."
+ " Can also indicate temporary problems like signal loss."
+ " Note the driver might dequeue an (empty) buffer despite"
+ " returning an error, or even stop capturing.");
+ /* have we de-queued a buffer ? */
+ if (!IS_QUEUED(buffer))
+ {
+ GST_DEBUG_OBJECT (allocator, "reenqueueing buffer");
+ /* FIXME ... should we do something here? */
+ }
+ break;
case EINTR:
- GST_WARNING_OBJECT(allocator, "could not sync on a buffer on device");
- break;
+ GST_WARNING_OBJECT (allocator, "could not sync on a buffer on device");
+ break;
default:
- GST_WARNING_OBJECT(allocator,
- "Grabbing frame got interrupted unexpectedly. %d: %s.", errno,
- g_strerror(errno));
- break;
- }
+ GST_WARNING_OBJECT (allocator,
+ "Grabbing frame got interrupted unexpectedly. %d: %s.", errno,
+ g_strerror (errno));
+ break;
+ }
- return GST_FLOW_ERROR;
+ return GST_FLOW_ERROR;
}
-void gst_aml_v4l2_allocator_reset_group(GstAmlV4l2Allocator *allocator,
- GstAmlV4l2MemoryGroup *group)
+void
+gst_aml_v4l2_allocator_reset_group (GstAmlV4l2Allocator *allocator,
+ GstAmlV4l2MemoryGroup *group)
{
- switch (allocator->memory)
- {
+ switch (allocator->memory)
+ {
case V4L2_MEMORY_USERPTR:
- gst_aml_v4l2_allocator_clear_userptr(allocator, group);
- break;
+ gst_aml_v4l2_allocator_clear_userptr (allocator, group);
+ break;
case V4L2_MEMORY_DMABUF:
- gst_aml_v4l2_allocator_clear_dmabufin(allocator, group);
- break;
+ gst_aml_v4l2_allocator_clear_dmabufin (allocator, group);
+ break;
case V4L2_MEMORY_MMAP:
- break;
+ break;
default:
- g_assert_not_reached();
- break;
- }
+ g_assert_not_reached ();
+ break;
+ }
- gst_aml_v4l2_allocator_reset_size(allocator, group);
+ gst_aml_v4l2_allocator_reset_size(allocator, group);
}
diff --git a/src/gstamlv4l2allocator.h b/src/gstamlv4l2allocator.h
index dc9eb79..20138e1 100644
--- a/src/gstamlv4l2allocator.h
+++ b/src/gstamlv4l2allocator.h
@@ -54,63 +54,64 @@
enum _GstAmlV4l2AllocatorFlags
{
- GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 0),
- GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 1),
- GST_V4L2_ALLOCATOR_FLAG_USERPTR_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 2),
- GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 3),
- GST_V4L2_ALLOCATOR_FLAG_DMABUF_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 4),
- GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 5),
- GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS = (GST_ALLOCATOR_FLAG_LAST << 6),
- GST_V4L2_ALLOCATOR_FLAG_ORPHANED = (GST_ALLOCATOR_FLAG_LAST << 7),
+ GST_V4L2_ALLOCATOR_FLAG_MMAP_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 0),
+ GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 1),
+ GST_V4L2_ALLOCATOR_FLAG_USERPTR_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 2),
+ GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 3),
+ GST_V4L2_ALLOCATOR_FLAG_DMABUF_REQBUFS = (GST_ALLOCATOR_FLAG_LAST << 4),
+ GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS = (GST_ALLOCATOR_FLAG_LAST << 5),
+ GST_V4L2_ALLOCATOR_FLAG_SUPPORTS_ORPHANED_BUFS = (GST_ALLOCATOR_FLAG_LAST << 6),
+ GST_V4L2_ALLOCATOR_FLAG_ORPHANED = (GST_ALLOCATOR_FLAG_LAST << 7),
};
enum _GstAmlV4l2Return
{
- GST_V4L2_OK = 0,
- GST_AML_V4L2_ERROR = -1,
- GST_V4L2_BUSY = -2
+ GST_AML_V4L2_OK = 0,
+ GST_AML_V4L2_ERROR = -1,
+ GST_AML_V4L2_BUSY = -2
};
struct _GstAmlV4l2Memory
{
- GstMemory mem;
- gint plane;
- GstAmlV4l2MemoryGroup *group;
- gpointer data;
- gint dmafd;
+ GstMemory mem;
+ gint plane;
+ GstAmlV4l2MemoryGroup *group;
+ gpointer data;
+ gint dmafd;
};
struct _GstAmlV4l2MemoryGroup
{
- gint n_mem;
- GstMemory *mem[VIDEO_MAX_PLANES];
- gint mems_allocated;
- struct v4l2_buffer buffer;
- struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ gint n_mem;
+ GstMemory * mem[VIDEO_MAX_PLANES];
+ gint mems_allocated;
+ struct v4l2_buffer buffer;
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
};
struct _GstAmlV4l2Allocator
{
- GstAllocator parent;
- GstAmlV4l2Object *obj;
- guint32 count;
- guint32 memory;
- gboolean can_allocate;
- gboolean active;
+ GstAllocator parent;
+ GstAmlV4l2Object *obj;
+ guint32 count;
+ guint32 memory;
+ gboolean can_allocate;
+ gboolean active;
- GstAmlV4l2MemoryGroup *groups[VIDEO_MAX_FRAME];
- GstAtomicQueue *free_queue;
- GstAtomicQueue *pending_queue;
+ GstAmlV4l2MemoryGroup *groups[VIDEO_MAX_FRAME];
+ GstAtomicQueue *free_queue;
+ GstAtomicQueue *pending_queue;
+
};
struct _GstAmlV4l2AllocatorClass
{
- GstAllocatorClass parent_class;
+ GstAllocatorClass parent_class;
};
GType gst_aml_v4l2_allocator_get_type(void);
-gboolean gst_is_aml_v4l2_memory(GstMemory *mem);
+gboolean gst_aml_is_v4l2_memory(GstMemory *mem);
GQuark gst_aml_v4l2_memory_quark(void);
diff --git a/src/gstamlv4l2bufferpool.c b/src/gstamlv4l2bufferpool.c
index 46d25af..5b37b1e 100644
--- a/src/gstamlv4l2bufferpool.c
+++ b/src/gstamlv4l2bufferpool.c
@@ -43,7 +43,7 @@
#define GST_DUMP_OUTPUT_BP_STAT_FILENAME "amlv4l2dec_output_bp_buf_stat"
GST_DEBUG_CATEGORY_STATIC(amlv4l2bufferpool_debug);
-GST_DEBUG_CATEGORY_STATIC(CAT_PERFORMANCE);
+GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE);
#define GST_CAT_DEFAULT amlv4l2bufferpool_debug
#define GST_AML_V4L2_IMPORT_QUARK gst_aml_v4l2_buffer_pool_import_quark()
@@ -56,9 +56,9 @@
enum _GstAmlV4l2BufferPoolAcquireFlags
{
- GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT =
- GST_BUFFER_POOL_ACQUIRE_FLAG_LAST,
- GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_LAST
+ GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT =
+ GST_BUFFER_POOL_ACQUIRE_FLAG_LAST,
+ GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_LAST
};
static void gst_aml_v4l2_buffer_pool_release_buffer(GstBufferPool *bpool,
@@ -243,1810 +243,1816 @@
static gboolean
gst_aml_v4l2_is_buffer_valid(GstBuffer *buffer, GstAmlV4l2MemoryGroup **out_group)
{
- GstMemory *mem = gst_buffer_peek_memory(buffer, 0);
- gboolean valid = FALSE;
+ GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
+ gboolean valid = FALSE;
- if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_TAG_MEMORY))
+ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY))
+ goto done;
+
+ if (gst_is_dmabuf_memory (mem))
+ mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
+ GST_AML_V4L2_MEMORY_QUARK);
+
+ if (mem && gst_aml_is_v4l2_memory(mem))
+ {
+ GstAmlV4l2Memory *vmem = (GstAmlV4l2Memory *)mem;
+ GstAmlV4l2MemoryGroup *group = vmem->group;
+ gint i;
+
+ if (group->n_mem != gst_buffer_n_memory (buffer))
+ goto done;
+
+ for (i = 0; i < group->n_mem; i++)
+ {
+ if (group->mem[i] != gst_buffer_peek_memory (buffer, i))
goto done;
- if (gst_is_dmabuf_memory(mem))
- mem = gst_mini_object_get_qdata(GST_MINI_OBJECT(mem),
- GST_AML_V4L2_MEMORY_QUARK);
-
- if (mem && gst_is_aml_v4l2_memory(mem))
- {
- GstAmlV4l2Memory *vmem = (GstAmlV4l2Memory *)mem;
- GstAmlV4l2MemoryGroup *group = vmem->group;
- gint i;
-
- if (group->n_mem != gst_buffer_n_memory(buffer))
- goto done;
-
- for (i = 0; i < group->n_mem; i++)
- {
- if (group->mem[i] != gst_buffer_peek_memory(buffer, i))
- goto done;
-
- if (!gst_memory_is_writable(group->mem[i]))
- goto done;
- }
-
- valid = TRUE;
- if (out_group)
- *out_group = group;
+ if (!gst_memory_is_writable (group->mem[i]))
+ goto done;
}
+ valid = TRUE;
+ if (out_group)
+ *out_group = group;
+ }
+
done:
- return valid;
+ return valid;
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_copy_buffer(GstAmlV4l2BufferPool *pool, GstBuffer *dest,
GstBuffer *src)
{
- const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
+ const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
- GST_LOG_OBJECT(pool, "copying buffer");
+ GST_LOG_OBJECT(pool, "copying buffer");
- if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
- finfo->format != GST_VIDEO_FORMAT_ENCODED))
+ if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
+ finfo->format != GST_VIDEO_FORMAT_ENCODED))
+ {
+ GstVideoFrame src_frame, dest_frame;
+
+ GST_DEBUG_OBJECT (pool, "copy video frame");
+
+ /* we have raw video, use videoframe copy to get strides right */
+ if (!gst_video_frame_map (&src_frame, &pool->caps_info, src, GST_MAP_READ))
+ goto invalid_buffer;
+
+ if (!gst_video_frame_map (&dest_frame, &pool->caps_info, dest,
+ GST_MAP_WRITE))
{
- GstVideoFrame src_frame, dest_frame;
-
- GST_DEBUG_OBJECT(pool, "copy video frame");
-
- /* we have raw video, use videoframe copy to get strides right */
- if (!gst_video_frame_map(&src_frame, &pool->caps_info, src, GST_MAP_READ))
- goto invalid_buffer;
-
- if (!gst_video_frame_map(&dest_frame, &pool->caps_info, dest,
- GST_MAP_WRITE))
- {
- gst_video_frame_unmap(&src_frame);
- goto invalid_buffer;
- }
-
- gst_video_frame_copy(&dest_frame, &src_frame);
-
- gst_video_frame_unmap(&src_frame);
- gst_video_frame_unmap(&dest_frame);
- }
- else
- {
- GstMapInfo map;
-
- GST_DEBUG_OBJECT(pool, "copy raw bytes size:%d", gst_buffer_get_size(src));
-
- if (!gst_buffer_map(src, &map, GST_MAP_READ))
- goto invalid_buffer;
-
- gst_buffer_fill(dest, 0, map.data, gst_buffer_get_size(src));
-
- gst_buffer_unmap(src, &map);
- gst_buffer_resize(dest, 0, gst_buffer_get_size(src));
+ gst_video_frame_unmap (&src_frame);
+ goto invalid_buffer;
}
- gst_buffer_copy_into(dest, src,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+ gst_video_frame_copy (&dest_frame, &src_frame);
- GST_CAT_LOG_OBJECT(CAT_PERFORMANCE, pool, "slow copy into buffer %p", dest);
+ gst_video_frame_unmap (&src_frame);
+ gst_video_frame_unmap (&dest_frame);
+ }
+ else
+ {
+ GstMapInfo map;
- return GST_FLOW_OK;
+ GST_DEBUG_OBJECT(pool, "copy raw bytes size:%d", gst_buffer_get_size(src));
+
+ if (!gst_buffer_map (src, &map, GST_MAP_READ))
+ goto invalid_buffer;
+
+ gst_buffer_fill (dest, 0, map.data, gst_buffer_get_size (src));
+
+ gst_buffer_unmap (src, &map);
+ gst_buffer_resize (dest, 0, gst_buffer_get_size (src));
+ }
+
+ gst_buffer_copy_into (dest, src,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+
+ GST_CAT_LOG_OBJECT (CAT_PERFORMANCE, pool, "slow copy into buffer %p", dest);
+
+ return GST_FLOW_OK;
invalid_buffer:
-{
- GST_ERROR_OBJECT(pool, "could not map buffer");
+ {
+ GST_ERROR_OBJECT (pool, "could not map buffer");
return GST_FLOW_ERROR;
-}
+ }
}
struct UserPtrData
{
- GstBuffer *buffer;
- gboolean is_frame;
- GstVideoFrame frame;
- GstMapInfo map;
+ GstBuffer *buffer;
+ gboolean is_frame;
+ GstVideoFrame frame;
+ GstMapInfo map;
};
static GQuark
gst_aml_v4l2_buffer_pool_import_quark(void)
{
- static GQuark quark = 0;
+ static GQuark quark = 0;
- if (quark == 0)
- quark = g_quark_from_string("GstAmlV4l2BufferPoolUsePtrData");
+ if (quark == 0)
+ quark = g_quark_from_string("GstAmlV4l2BufferPoolUsePtrData");
- return quark;
+ return quark;
}
static void
-_unmap_userptr_frame(struct UserPtrData *data)
+_unmap_userptr_frame (struct UserPtrData *data)
{
- if (data->is_frame)
- gst_video_frame_unmap(&data->frame);
- else
- gst_buffer_unmap(data->buffer, &data->map);
+ if (data->is_frame)
+ gst_video_frame_unmap (&data->frame);
+ else
+ gst_buffer_unmap (data->buffer, &data->map);
- if (data->buffer)
- gst_buffer_unref(data->buffer);
+ if (data->buffer)
+ gst_buffer_unref (data->buffer);
- g_slice_free(struct UserPtrData, data);
+ g_slice_free (struct UserPtrData, data);
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_import_userptr(GstAmlV4l2BufferPool *pool,
GstBuffer *dest, GstBuffer *src)
{
- GstFlowReturn ret = GST_FLOW_OK;
- GstAmlV4l2MemoryGroup *group = NULL;
- GstMapFlags flags;
- const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
- struct UserPtrData *data = NULL;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstAmlV4l2MemoryGroup *group = NULL;
+ GstMapFlags flags;
+ const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
+ struct UserPtrData *data = NULL;
- GST_LOG_OBJECT(pool, "importing userptr");
+ GST_LOG_OBJECT (pool, "importing userptr");
- /* get the group */
- if (!gst_aml_v4l2_is_buffer_valid(dest, &group))
- goto not_our_buffer;
+ /* get the group */
+ if (!gst_aml_v4l2_is_buffer_valid(dest, &group))
+ goto not_our_buffer;
- if (V4L2_TYPE_IS_OUTPUT(pool->obj->type))
- flags = GST_MAP_READ;
- else
- flags = GST_MAP_WRITE;
+ if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
+ flags = GST_MAP_READ;
+ else
+ flags = GST_MAP_WRITE;
- data = g_slice_new0(struct UserPtrData);
+ data = g_slice_new0 (struct UserPtrData);
- if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
- finfo->format != GST_VIDEO_FORMAT_ENCODED))
+ if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
+ finfo->format != GST_VIDEO_FORMAT_ENCODED))
+ {
+ gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
+ gint i;
+
+ data->is_frame = TRUE;
+
+ if (!gst_video_frame_map (&data->frame, &pool->caps_info, src, flags))
+ goto invalid_buffer;
+
+ for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES(finfo); i++)
{
- gsize size[GST_VIDEO_MAX_PLANES] = {
- 0,
- };
- gint i;
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED(finfo))
+ {
+ gint tinfo = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i);
+ gint pstride;
+ guint pheight;
- data->is_frame = TRUE;
+ pstride = GST_VIDEO_TILE_X_TILES (tinfo) <<
+ GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
- if (!gst_video_frame_map(&data->frame, &pool->caps_info, src, flags))
- goto invalid_buffer;
+ pheight = GST_VIDEO_TILE_Y_TILES (tinfo) <<
+ GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
- for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES(finfo); i++)
- {
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(finfo))
- {
- gint tinfo = GST_VIDEO_FRAME_PLANE_STRIDE(&data->frame, i);
- gint pstride;
- guint pheight;
-
- pstride = GST_VIDEO_TILE_X_TILES(tinfo) << GST_VIDEO_FORMAT_INFO_TILE_WS(finfo);
-
- pheight = GST_VIDEO_TILE_Y_TILES(tinfo) << GST_VIDEO_FORMAT_INFO_TILE_HS(finfo);
-
- size[i] = pstride * pheight;
- }
- else
- {
- size[i] = GST_VIDEO_FRAME_PLANE_STRIDE(&data->frame, i) *
- GST_VIDEO_FRAME_COMP_HEIGHT(&data->frame, i);
- }
- }
-
- /* In the single planar API, planes must be contiguous in memory and
- * therefore they must have expected size. ie: no padding.
- * To check these conditions, we check that plane 'i' start address
- * + plane 'i' size equals to plane 'i+1' start address */
- if (!V4L2_TYPE_IS_MULTIPLANAR(pool->obj->type))
- {
- for (i = 0; i < (GST_VIDEO_FORMAT_INFO_N_PLANES(finfo) - 1); i++)
- {
- const struct v4l2_pix_format *pix_fmt = &pool->obj->format.fmt.pix;
- gpointer tmp;
- gint estride = gst_aml_v4l2_object_extrapolate_stride(finfo, i,
- pix_fmt->bytesperline);
- guint eheight = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(finfo, i,
- pix_fmt->height);
-
- tmp = ((guint8 *)data->frame.data[i]) + estride * eheight;
- if (tmp != data->frame.data[i + 1])
- goto non_contiguous_mem;
- }
- }
-
- if (!gst_aml_v4l2_allocator_import_userptr(pool->vallocator, group,
- data->frame.info.size, finfo->n_planes, data->frame.data, size))
- goto import_failed;
- }
- else
- {
- gpointer ptr[1];
- gsize size[1];
-
- data->is_frame = FALSE;
-
- if (!gst_buffer_map(src, &data->map, flags))
- goto invalid_buffer;
-
- ptr[0] = data->map.data;
- size[0] = data->map.size;
-
- if (!gst_aml_v4l2_allocator_import_userptr(pool->vallocator, group,
- data->map.size, 1, ptr, size))
- goto import_failed;
+ size[i] = pstride * pheight;
+ }
+ else
+ {
+ size[i] = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i) *
+ GST_VIDEO_FRAME_COMP_HEIGHT (&data->frame, i);
+ }
}
- data->buffer = gst_buffer_ref(src);
+ /* In the single planar API, planes must be contiguous in memory and
+ * therefore they must have expected size. ie: no padding.
+ * To check these conditions, we check that plane 'i' start address
+ * + plane 'i' size equals to plane 'i+1' start address */
+ if (!V4L2_TYPE_IS_MULTIPLANAR(pool->obj->type))
+ {
+ for (i = 0; i < (GST_VIDEO_FORMAT_INFO_N_PLANES(finfo) - 1); i++)
+ {
+ const struct v4l2_pix_format *pix_fmt = &pool->obj->format.fmt.pix;
+ gpointer tmp;
+ gint estride = gst_aml_v4l2_object_extrapolate_stride(finfo, i,
+ pix_fmt->bytesperline);
+ guint eheight = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i,
+ pix_fmt->height);
- gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK,
- data, (GDestroyNotify)_unmap_userptr_frame);
+ tmp = ((guint8 *) data->frame.data[i]) + estride * eheight;
+ if (tmp != data->frame.data[i + 1])
+ goto non_contiguous_mem;
+ }
+ }
- gst_buffer_copy_into(dest, src,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+ if (!gst_aml_v4l2_allocator_import_userptr(pool->vallocator, group,
+ data->frame.info.size, finfo->n_planes, data->frame.data, size))
+ goto import_failed;
+ }
+ else
+ {
+ gpointer ptr[1];
+ gsize size[1];
- return ret;
+ data->is_frame = FALSE;
+
+ if (!gst_buffer_map (src, &data->map, flags))
+ goto invalid_buffer;
+
+ ptr[0] = data->map.data;
+ size[0] = data->map.size;
+
+ if (!gst_aml_v4l2_allocator_import_userptr(pool->vallocator, group,
+ data->map.size, 1, ptr, size))
+ goto import_failed;
+ }
+
+ data->buffer = gst_buffer_ref (src);
+
+ gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK,
+ data, (GDestroyNotify) _unmap_userptr_frame);
+
+ gst_buffer_copy_into (dest, src,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+
+ return ret;
not_our_buffer:
-{
- GST_ERROR_OBJECT(pool, "destination buffer invalid or not from our pool");
+ {
+ GST_ERROR_OBJECT (pool, "destination buffer invalid or not from our pool");
return GST_FLOW_ERROR;
-}
+ }
invalid_buffer:
-{
- GST_ERROR_OBJECT(pool, "could not map buffer");
- g_slice_free(struct UserPtrData, data);
+ {
+ GST_ERROR_OBJECT (pool, "could not map buffer");
+ g_slice_free (struct UserPtrData, data);
return GST_FLOW_ERROR;
-}
+ }
non_contiguous_mem:
-{
- GST_ERROR_OBJECT(pool, "memory is not contiguous or plane size mismatch");
- _unmap_userptr_frame(data);
+ {
+ GST_ERROR_OBJECT (pool, "memory is not contiguous or plane size mismatch");
+ _unmap_userptr_frame (data);
return GST_FLOW_ERROR;
-}
+ }
import_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to import data");
- _unmap_userptr_frame(data);
+ {
+ GST_ERROR_OBJECT (pool, "failed to import data");
+ _unmap_userptr_frame (data);
return GST_FLOW_ERROR;
-}
+ }
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_import_dmabuf(GstAmlV4l2BufferPool *pool,
GstBuffer *dest, GstBuffer *src)
{
- GstAmlV4l2MemoryGroup *group = NULL;
- GstMemory *dma_mem[GST_VIDEO_MAX_PLANES] = {0};
- guint n_mem = gst_buffer_n_memory(src);
- gint i;
+ GstAmlV4l2MemoryGroup *group = NULL;
+ GstMemory *dma_mem[GST_VIDEO_MAX_PLANES] = { 0 };
+ guint n_mem = gst_buffer_n_memory (src);
+ gint i;
- GST_LOG_OBJECT(pool, "importing dmabuf");
+ GST_LOG_OBJECT (pool, "importing dmabuf");
- if (!gst_aml_v4l2_is_buffer_valid(dest, &group))
- goto not_our_buffer;
+ if (!gst_aml_v4l2_is_buffer_valid(dest, &group))
+ goto not_our_buffer;
- if (n_mem > GST_VIDEO_MAX_PLANES)
- goto too_many_mems;
+ if (n_mem > GST_VIDEO_MAX_PLANES)
+ goto too_many_mems;
- for (i = 0; i < n_mem; i++)
- dma_mem[i] = gst_buffer_peek_memory(src, i);
+ for (i = 0; i < n_mem; i++)
+ dma_mem[i] = gst_buffer_peek_memory (src, i);
- if (!gst_aml_v4l2_allocator_import_dmabuf(pool->vallocator, group, n_mem,
- dma_mem))
- goto import_failed;
+ if (!gst_aml_v4l2_allocator_import_dmabuf(pool->vallocator, group, n_mem,
+ dma_mem))
+ goto import_failed;
- // Output buf is secure memory, Need to unref by itselt
- // Capture buf is secure memory, Need to unref by downstreaming element gstvideosink
- if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
- gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK,
- gst_buffer_ref(src), (GDestroyNotify)gst_buffer_unref);
- else
- gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK, gst_buffer_ref(src), NULL);
+ // Output buf is secure memory, Need to unref by itselt
+ // Capture buf is secure memory, Need to unref by downstreaming element gstvideosink
+ if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
+ gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK,
+ gst_buffer_ref(src), (GDestroyNotify) gst_buffer_unref);
+ else
+ gst_mini_object_set_qdata(GST_MINI_OBJECT(dest), GST_AML_V4L2_IMPORT_QUARK, gst_buffer_ref(src), NULL);
- gst_buffer_copy_into(dest, src,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+ gst_buffer_copy_into (dest, src,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
- GST_DEBUG_OBJECT(pool, "v4l2 buf:%p, import buf:%p as qdata", dest, src);
- return GST_FLOW_OK;
+ GST_DEBUG_OBJECT(pool, "v4l2 buf:%p, import buf:%p as qdata", dest, src);
+
+ return GST_FLOW_OK;
not_our_buffer:
-{
- GST_ERROR_OBJECT(pool, "destination buffer invalid or not from our pool");
+ {
+ GST_ERROR_OBJECT (pool, "destination buffer invalid or not from our pool");
return GST_FLOW_ERROR;
-}
+ }
too_many_mems:
-{
- GST_ERROR_OBJECT(pool, "could not map buffer");
+ {
+ GST_ERROR_OBJECT (pool, "could not map buffer");
return GST_FLOW_ERROR;
-}
+ }
import_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to import dmabuf");
+ {
+ GST_ERROR_OBJECT (pool, "failed to import dmabuf");
return GST_FLOW_ERROR;
-}
+ }
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_prepare_buffer(GstAmlV4l2BufferPool *pool,
GstBuffer *dest, GstBuffer *src)
{
- GstFlowReturn ret = GST_FLOW_OK;
- gboolean own_src = FALSE;
+ GstFlowReturn ret = GST_FLOW_OK;
+ gboolean own_src = FALSE;
- if (src == NULL)
+ if (src == NULL)
+ {
+ if (pool->other_pool == NULL)
{
- if (pool->other_pool == NULL)
- {
- GST_ERROR_OBJECT(pool, "can't prepare buffer, source buffer missing");
- return GST_FLOW_ERROR;
- }
-
- ret = gst_buffer_pool_acquire_buffer(pool->other_pool, &src, NULL);
- if (ret != GST_FLOW_OK)
- {
- GST_ERROR_OBJECT(pool, "failed to acquire buffer from downstream pool");
- goto done;
- }
-
- own_src = TRUE;
+ GST_ERROR_OBJECT (pool, "can't prepare buffer, source buffer missing");
+ return GST_FLOW_ERROR;
}
- switch (pool->obj->mode)
+ ret = gst_buffer_pool_acquire_buffer(pool->other_pool, &src, NULL);
+ if (ret != GST_FLOW_OK)
{
+ GST_ERROR_OBJECT (pool, "failed to acquire buffer from downstream pool");
+ goto done;
+ }
+
+ own_src = TRUE;
+ }
+
+ switch (pool->obj->mode)
+ {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
- ret = gst_aml_v4l2_buffer_pool_copy_buffer(pool, dest, src);
- break;
+ ret = gst_aml_v4l2_buffer_pool_copy_buffer(pool, dest, src);
+ break;
case GST_V4L2_IO_USERPTR:
- ret = gst_aml_v4l2_buffer_pool_import_userptr(pool, dest, src);
- break;
+ ret = gst_aml_v4l2_buffer_pool_import_userptr(pool, dest, src);
+ break;
case GST_V4L2_IO_DMABUF_IMPORT:
- ret = gst_aml_v4l2_buffer_pool_import_dmabuf(pool, dest, src);
- break;
+ ret = gst_aml_v4l2_buffer_pool_import_dmabuf(pool, dest, src);
+ break;
default:
- break;
- }
+ break;
+ }
- if (own_src)
- gst_buffer_unref(src);
+ if (own_src)
+ gst_buffer_unref (src);
done:
- return ret;
+ return ret;
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_alloc_buffer(GstBufferPool *bpool, GstBuffer **buffer,
GstBufferPoolAcquireParams *params)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstAmlV4l2MemoryGroup *group = NULL;
- GstBuffer *newbuf = NULL;
- GstAmlV4l2Object *obj;
- GstVideoInfo *info;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstAmlV4l2MemoryGroup *group = NULL;
+ GstBuffer *newbuf = NULL;
+ GstAmlV4l2Object *obj;
+ GstVideoInfo *info;
- obj = pool->obj;
- info = &obj->info;
+ obj = pool->obj;
+ info = &obj->info;
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- newbuf =
- gst_buffer_new_allocate(pool->allocator, pool->size, &pool->params);
- break;
+ newbuf =
+ gst_buffer_new_allocate (pool->allocator, pool->size, &pool->params);
+ break;
case GST_V4L2_IO_MMAP:
- group = gst_aml_v4l2_allocator_alloc_mmap(pool->vallocator);
- break;
- case GST_V4L2_IO_DMABUF:
- group = gst_aml_v4l2_allocator_alloc_dmabuf(pool->vallocator,
- pool->allocator);
- break;
+ group = gst_aml_v4l2_allocator_alloc_mmap(pool->vallocator);
+ break;
+ case GST_V4L2_IO_DMABUF:
+ group = gst_aml_v4l2_allocator_alloc_dmabuf(pool->vallocator,
+ pool->allocator);
+ break;
case GST_V4L2_IO_USERPTR:
- group = gst_aml_v4l2_allocator_alloc_userptr(pool->vallocator);
- break;
+ group = gst_aml_v4l2_allocator_alloc_userptr(pool->vallocator);
+ break;
case GST_V4L2_IO_DMABUF_IMPORT:
- group = gst_aml_v4l2_allocator_alloc_dmabufin(pool->vallocator);
- break;
+ group = gst_aml_v4l2_allocator_alloc_dmabufin(pool->vallocator);
+ break;
default:
- newbuf = NULL;
- g_assert_not_reached();
- break;
+ newbuf = NULL;
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (group != NULL)
+ {
+ gint i;
+ newbuf = gst_buffer_new ();
+
+ for (i = 0; i < group->n_mem; i++)
+ gst_buffer_append_memory (newbuf, group->mem[i]);
}
+ else if (newbuf == NULL)
+ {
+ goto allocation_failed;
+ }
- if (group != NULL)
- {
- gint i;
- newbuf = gst_buffer_new();
+ /* add metadata to raw video buffers */
+ if (pool->add_videometa)
+ gst_buffer_add_video_meta_full(newbuf, GST_VIDEO_FRAME_FLAG_NONE,
+ GST_VIDEO_INFO_FORMAT(info), GST_VIDEO_INFO_WIDTH(info),
+ GST_VIDEO_INFO_HEIGHT(info), GST_VIDEO_INFO_N_PLANES(info),
+ info->offset, info->stride);
- for (i = 0; i < group->n_mem; i++)
- gst_buffer_append_memory(newbuf, group->mem[i]);
- }
- else if (newbuf == NULL)
- {
- goto allocation_failed;
- }
+ *buffer = newbuf;
- /* add metadata to raw video buffers */
- if (pool->add_videometa)
- gst_buffer_add_video_meta_full(newbuf, GST_VIDEO_FRAME_FLAG_NONE,
- GST_VIDEO_INFO_FORMAT(info), GST_VIDEO_INFO_WIDTH(info),
- GST_VIDEO_INFO_HEIGHT(info), GST_VIDEO_INFO_N_PLANES(info),
- info->offset, info->stride);
+ return GST_FLOW_OK;
- *buffer = newbuf;
-
- return GST_FLOW_OK;
-
- /* ERRORS */
+ /* ERRORS */
allocation_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to allocate buffer");
+ {
+ GST_ERROR_OBJECT (pool, "failed to allocate buffer");
return GST_FLOW_ERROR;
-}
+ }
}
static gboolean
gst_aml_v4l2_buffer_pool_set_config(GstBufferPool *bpool, GstStructure *config)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstAmlV4l2Object *obj = pool->obj;
- GstCaps *caps;
- guint size, min_buffers, max_buffers;
- GstAllocator *allocator;
- GstAllocationParams params;
- gboolean can_allocate = FALSE;
- gboolean updated = FALSE;
- gboolean ret;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstAmlV4l2Object *obj = pool->obj;
+ GstCaps *caps;
+ guint size, min_buffers, max_buffers;
+ GstAllocator *allocator;
+ GstAllocationParams params;
+ gboolean can_allocate = FALSE;
+ gboolean updated = FALSE;
+ gboolean ret;
- pool->add_videometa =
- gst_buffer_pool_config_has_option(config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
+ pool->add_videometa =
+ gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
- /* parse the config and keep around */
- if (!gst_buffer_pool_config_get_params(config, &caps, &size, &min_buffers,
- &max_buffers))
- goto wrong_config;
+ /* parse the config and keep around */
+ if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers,
+ &max_buffers))
+ goto wrong_config;
- if (!gst_buffer_pool_config_get_allocator(config, &allocator, ¶ms))
- goto wrong_config;
+ if (!gst_buffer_pool_config_get_allocator (config, &allocator, ¶ms))
+ goto wrong_config;
- GST_DEBUG_OBJECT(pool, "config %" GST_PTR_FORMAT, config);
+ GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config);
- if (pool->allocator)
- gst_object_unref(pool->allocator);
- pool->allocator = NULL;
+ if (pool->allocator)
+ gst_object_unref (pool->allocator);
+ pool->allocator = NULL;
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_DMABUF:
- pool->allocator = gst_dmabuf_allocator_new();
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
- break;
+ pool->allocator = gst_dmabuf_allocator_new ();
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
+ break;
case GST_V4L2_IO_MMAP:
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
- break;
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
+ break;
case GST_V4L2_IO_USERPTR:
- can_allocate =
- GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, USERPTR);
- break;
+ can_allocate =
+ GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, USERPTR);
+ break;
case GST_V4L2_IO_DMABUF_IMPORT:
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, DMABUF);
- break;
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, DMABUF);
+ break;
case GST_V4L2_IO_RW:
- if (allocator)
- pool->allocator = g_object_ref(allocator);
- pool->params = params;
- /* No need to change the configuration */
- goto done;
- break;
+ if (allocator)
+ pool->allocator = g_object_ref (allocator);
+ pool->params = params;
+ /* No need to change the configuration */
+ goto done;
+ break;
default:
- g_assert_not_reached();
- break;
- }
+ g_assert_not_reached ();
+ break;
+ }
- /* libv4l2 conversion code does not handle CREATE_BUFS, and may lead to
- * instability and crash, disable it for now */
- if (can_allocate && obj->fmtdesc->flags & V4L2_FMT_FLAG_EMULATED)
+ /* libv4l2 conversion code does not handle CREATE_BUFS, and may lead to
+ * instability and crash, disable it for now */
+ if (can_allocate && obj->fmtdesc->flags & V4L2_FMT_FLAG_EMULATED)
+ {
+ GST_WARNING_OBJECT (pool,
+ "libv4l2 converter detected, disabling CREATE_BUFS");
+ can_allocate = FALSE;
+ GST_OBJECT_FLAG_UNSET (pool->vallocator,
+ GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS
+ | GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS
+ | GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS);
+ }
+
+ if (min_buffers < GST_AML_V4L2_MIN_BUFFERS)
+ {
+ updated = TRUE;
+ min_buffers = GST_AML_V4L2_MIN_BUFFERS;
+ GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers);
+ }
+
+ /* respect driver requirements */
+ if (min_buffers < obj->min_buffers)
+ {
+ updated = TRUE;
+ min_buffers = obj->min_buffers;
+ GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers);
+ }
+
+ if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0)
+ {
+ updated = TRUE;
+ max_buffers = VIDEO_MAX_FRAME;
+ GST_INFO_OBJECT (pool, "reducing maximum buffers to %u", max_buffers);
+ }
+
+ if (min_buffers > max_buffers)
+ {
+ updated = TRUE;
+ min_buffers = max_buffers;
+ GST_INFO_OBJECT (pool, "reducing minimum buffers to %u", min_buffers);
+ }
+ else if (min_buffers != max_buffers)
+ {
+ if (!can_allocate)
{
- GST_WARNING_OBJECT(pool,
- "libv4l2 converter detected, disabling CREATE_BUFS");
- can_allocate = FALSE;
- GST_OBJECT_FLAG_UNSET(pool->vallocator,
- GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS | GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS | GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS);
+ updated = TRUE;
+ max_buffers = min_buffers;
+ GST_INFO_OBJECT (pool, "can't allocate, setting maximum to minimum");
}
+ }
- if (min_buffers < GST_AML_V4L2_MIN_BUFFERS)
- {
- updated = TRUE;
- min_buffers = GST_AML_V4L2_MIN_BUFFERS;
- GST_INFO_OBJECT(pool, "increasing minimum buffers to %u", min_buffers);
- }
+ if (!pool->add_videometa && obj->need_video_meta)
+ {
+ GST_INFO_OBJECT (pool, "adding needed video meta");
+ updated = TRUE;
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
+ }
- /* respect driver requirements */
- if (min_buffers < obj->min_buffers)
- {
- updated = TRUE;
- min_buffers = obj->min_buffers;
- GST_INFO_OBJECT(pool, "increasing minimum buffers to %u", min_buffers);
- }
+ /* Always update the config to ensure the configured size matches */
+ gst_buffer_pool_config_set_params (config, caps, obj->info.size, min_buffers,
+ max_buffers);
- if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0)
- {
- updated = TRUE;
- max_buffers = VIDEO_MAX_FRAME;
- GST_INFO_OBJECT(pool, "reducing maximum buffers to %u", max_buffers);
- }
-
- if (min_buffers > max_buffers)
- {
- updated = TRUE;
- min_buffers = max_buffers;
- GST_INFO_OBJECT(pool, "reducing minimum buffers to %u", min_buffers);
- }
- else if (min_buffers != max_buffers)
- {
- if (!can_allocate)
- {
- updated = TRUE;
- max_buffers = min_buffers;
- GST_INFO_OBJECT(pool, "can't allocate, setting maximum to minimum");
- }
- }
-
- if (!pool->add_videometa && obj->need_video_meta)
- {
- GST_INFO_OBJECT(pool, "adding needed video meta");
- updated = TRUE;
- gst_buffer_pool_config_add_option(config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
- }
-
- /* Always update the config to ensure the configured size matches */
- gst_buffer_pool_config_set_params(config, caps, obj->info.size, min_buffers,
- max_buffers);
-
- /* keep a GstVideoInfo with defaults for the when we need to copy */
- gst_video_info_from_caps(&pool->caps_info, caps);
+ /* keep a GstVideoInfo with defaults for the when we need to copy */
+ gst_video_info_from_caps (&pool->caps_info, caps);
done:
- ret = GST_BUFFER_POOL_CLASS(parent_class)->set_config(bpool, config);
+ ret = GST_BUFFER_POOL_CLASS (parent_class)->set_config (bpool, config);
- /* If anything was changed documentation recommand to return FALSE */
- return !updated && ret;
+ /* If anything was changed documentation recommend to return FALSE */
+ return !updated && ret;
- /* ERRORS */
+ /* ERRORS */
wrong_config:
-{
- GST_ERROR_OBJECT(pool, "invalid config %" GST_PTR_FORMAT, config);
+ {
+ GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config);
return FALSE;
-}
+ }
}
static GstFlowReturn
gst_aml_v4l2_buffer_pool_resurrect_buffer(GstAmlV4l2BufferPool *pool)
{
- GstBufferPoolAcquireParams params = {0};
- GstBuffer *buffer = NULL;
- GstFlowReturn ret;
+ GstBufferPoolAcquireParams params = { 0 };
+ GstBuffer *buffer = NULL;
+ GstFlowReturn ret;
- GST_DEBUG_OBJECT(pool, "A buffer was lost, reallocating it");
+ GST_DEBUG_OBJECT (pool, "A buffer was lost, reallocating it");
- /* block recursive calls to this function */
- g_signal_handler_block(pool->vallocator, pool->group_released_handler);
+ /* block recursive calls to this function */
+ g_signal_handler_block (pool->vallocator, pool->group_released_handler);
- params.flags =
- (GstBufferPoolAcquireFlags)GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT |
- GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
- ret =
- gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool), &buffer, ¶ms);
+ params.flags =
+ (GstBufferPoolAcquireFlags) GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT |
+ GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
+ ret =
+ gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (pool), &buffer, ¶ms);
- if (ret == GST_FLOW_OK)
- gst_buffer_unref(buffer);
+ if (ret == GST_FLOW_OK)
+ gst_buffer_unref (buffer);
- g_signal_handler_unblock(pool->vallocator, pool->group_released_handler);
+ g_signal_handler_unblock (pool->vallocator, pool->group_released_handler);
- return ret;
+ return ret;
}
static gboolean
gst_aml_v4l2_buffer_pool_streamon(GstAmlV4l2BufferPool *pool)
{
- GstAmlV4l2Object *obj = pool->obj;
+ GstAmlV4l2Object *obj = pool->obj;
- if (pool->streaming)
- return TRUE;
+ if (pool->streaming)
+ return TRUE;
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_DMABUF_IMPORT:
- if (!V4L2_TYPE_IS_OUTPUT(pool->obj->type))
- {
- guint i;
+ if (!V4L2_TYPE_IS_OUTPUT(pool->obj->type))
+ {
+ guint i;
- /* For captures, we need to enqueue buffers before we start streaming,
- * so the driver don't underflow immediatly. As we have put then back
- * into the base class queue, resurrect them, then releasing will queue
- * them back. */
- for (i = 0; i < pool->num_allocated; i++)
- gst_aml_v4l2_buffer_pool_resurrect_buffer(pool);
- }
+ /* For captures, we need to enqueue buffers before we start streaming,
+ * so the driver don't underflow immediately. As we have put then back
+ * into the base class queue, resurrect them, then releasing will queue
+ * them back. */
+ for (i = 0; i < pool->num_allocated; i++)
+ gst_aml_v4l2_buffer_pool_resurrect_buffer(pool);
+ }
- if (obj->ioctl(pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
- goto streamon_failed;
+ if (obj->ioctl (pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
+ goto streamon_failed;
- pool->streaming = TRUE;
+ pool->streaming = TRUE;
- GST_DEBUG_OBJECT(pool, "Started streaming");
- break;
+ GST_DEBUG_OBJECT (pool, "Started streaming");
+ break;
default:
- break;
- }
+ break;
+ }
- return TRUE;
+ return TRUE;
streamon_failed:
-{
- GST_ERROR_OBJECT(pool, "error with STREAMON %d (%s)", errno,
- g_strerror(errno));
+ {
+ GST_ERROR_OBJECT (pool, "error with STREAMON %d (%s)", errno,
+ g_strerror (errno));
return FALSE;
-}
+ }
}
/* Call with streamlock held, or when streaming threads are down */
static void
gst_aml_v4l2_buffer_pool_streamoff(GstAmlV4l2BufferPool *pool)
{
- GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
- GstAmlV4l2Object *obj = pool->obj;
- gint i;
+ GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
+ GstAmlV4l2Object *obj = pool->obj;
+ gint i;
- if (!pool->streaming)
- return;
+ if (!pool->streaming)
+ return;
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_DMABUF_IMPORT:
- if (obj->ioctl(pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
- GST_WARNING_OBJECT(pool, "STREAMOFF failed with errno %d (%s)",
- errno, g_strerror(errno));
+ if (obj->ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
+ GST_WARNING_OBJECT (pool, "STREAMOFF failed with errno %d (%s)",
+ errno, g_strerror (errno));
- GST_DEBUG_OBJECT(pool, "Stopped streaming");
- if (pool->vallocator)
- gst_aml_v4l2_allocator_flush(pool->vallocator);
- break;
+ GST_DEBUG_OBJECT (pool, "Stopped streaming");
+
+ if (pool->vallocator)
+ gst_aml_v4l2_allocator_flush(pool->vallocator);
+ break;
default:
- break;
- }
+ break;
+ }
- GstBufferPool *bpool = GST_BUFFER_POOL(pool);
- if (V4L2_TYPE_IS_OUTPUT(pool->obj->type))
- {
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
- {
- GST_INFO_OBJECT(pool, "deal with output buf index:%d, buf:%p", i, pool->buffers[i]);
- if (pool->buffers[i])
- {
- GstBuffer *buffer = pool->buffers[i];
- pool->buffers[i] = NULL;
- gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
- g_atomic_int_add(&pool->num_queued, -1);
- }
- }
- }
- else
- {
+ GstBufferPool *bpool = GST_BUFFER_POOL(pool);
+ if (V4L2_TYPE_IS_OUTPUT(pool->obj->type))
+ {
+ for (i = 0; i < VIDEO_MAX_FRAME; i++)
+ {
+ GST_INFO_OBJECT(pool, "deal with output buf index:%d, buf:%p", i, pool->buffers[i]);
+ if (pool->buffers[i])
+ {
+ GstBuffer *buffer = pool->buffers[i];
+ pool->buffers[i] = NULL;
+ gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
+ g_atomic_int_add(&pool->num_queued, -1);
+ }
+ }
+ }
+ else
+ {
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- if (GST_V4L2_IO_DMABUF_IMPORT == obj->mode)
- {
- GST_DEBUG_OBJECT(pool, "have %d ready to free capture buffer", pool->ready_to_free_buf_num);
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
- {
- GST_DEBUG_OBJECT(pool, "buffers[%d]:%p, read_to_free_bufs[%d]:%p", i, pool->buffers[i], i, pool->read_to_free_bufs[i]);
- if (pool->buffers[i])
- {
- if (pool->other_pool)
- {
- GstBuffer *other_pool_buf = gst_mini_object_get_qdata(GST_MINI_OBJECT(pool->buffers[i]), GST_AML_V4L2_IMPORT_QUARK);
- GST_DEBUG_OBJECT(pool, "release v4l2 capture buf[%d]:%p other pool buf:%p", i, pool->buffers[i], other_pool_buf);
- gst_buffer_unref(other_pool_buf);
- }
- }
- else if (pool->read_to_free_bufs[i])
- {
- pool->buffers[i] = pool->read_to_free_bufs[i];
- pool->read_to_free_bufs[i] = NULL;
- pool->ready_to_free_buf_num--;
- }
- }
- GST_DEBUG_OBJECT(pool, "%d ready to free capture buffer left", pool->ready_to_free_buf_num);
- pool->num_queued = 0;
- }
+ if (GST_V4L2_IO_DMABUF_IMPORT == obj->mode)
+ {
+ GST_DEBUG_OBJECT(pool, "have %d ready to free capture buffer", pool->ready_to_free_buf_num);
+ for (i = 0; i < VIDEO_MAX_FRAME; i++)
+ {
+ GST_DEBUG_OBJECT(pool, "buffers[%d]:%p, read_to_free_bufs[%d]:%p", i, pool->buffers[i], i, pool->read_to_free_bufs[i]);
+ if (pool->buffers[i])
+ {
+ if (pool->other_pool)
+ {
+ GstBuffer *other_pool_buf = gst_mini_object_get_qdata(GST_MINI_OBJECT(pool->buffers[i]), GST_AML_V4L2_IMPORT_QUARK);
+ GST_DEBUG_OBJECT(pool, "release v4l2 capture buf[%d]:%p other pool buf:%p", i, pool->buffers[i], other_pool_buf);
+ gst_buffer_unref(other_pool_buf);
+ }
+ }
+ else if (pool->read_to_free_bufs[i])
+ {
+ pool->buffers[i] = pool->read_to_free_bufs[i];
+ pool->read_to_free_bufs[i] = NULL;
+ pool->ready_to_free_buf_num--;
+ }
+ }
+ GST_DEBUG_OBJECT(pool, "%d ready to free capture buffer left", pool->ready_to_free_buf_num);
+ pool->num_queued = 0;
+ }
#endif
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
- {
- GST_INFO_OBJECT(pool, "deal with caputre buf index:%d, buf:%p", i, pool->buffers[i]);
- if (pool->buffers[i])
- {
- GstBuffer *buffer = pool->buffers[i];
- pool->buffers[i] = NULL;
- pclass->release_buffer(bpool, buffer);
+ for (i = 0; i < VIDEO_MAX_FRAME; i++)
+ {
+ GST_INFO_OBJECT(pool, "deal with caputre buf index:%d, buf:%p", i, pool->buffers[i]);
+ if (pool->buffers[i])
+ {
+ GstBuffer *buffer = pool->buffers[i];
+ pool->buffers[i] = NULL;
+ pclass->release_buffer(bpool, buffer);
#ifndef GST_AML_SPEC_FLOW_FOR_VBP
- g_atomic_int_add(&pool->num_queued, -1);
+ g_atomic_int_add(&pool->num_queued, -1);
#endif
- }
- }
- }
- pool->streaming = FALSE;
+ }
+ }
+ }
+ pool->streaming = FALSE;
}
static gboolean
gst_aml_v4l2_buffer_pool_start(GstBufferPool *bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
- GstAmlV4l2Object *obj = pool->obj;
- GstStructure *config;
- GstCaps *caps;
- guint size, min_buffers, max_buffers;
- guint max_latency, min_latency, copy_threshold = 0;
- gboolean can_allocate = FALSE, ret = TRUE;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
+ GstAmlV4l2Object *obj = pool->obj;
+ GstStructure *config;
+ GstCaps *caps;
+ guint size, min_buffers, max_buffers;
+ guint max_latency, min_latency, copy_threshold = 0;
+ gboolean can_allocate = FALSE, ret = TRUE;
- GST_DEBUG_OBJECT(pool, "activating pool");
+ GST_DEBUG_OBJECT (pool, "activating pool");
- if (pool->other_pool)
+ if (pool->other_pool)
+ {
+ GstBuffer *buffer;
+
+ if (!gst_buffer_pool_set_active (pool->other_pool, TRUE))
+ goto other_pool_failed;
+
+ if (gst_buffer_pool_acquire_buffer (pool->other_pool, &buffer, NULL) !=
+ GST_FLOW_OK)
+ goto other_pool_failed;
+
+ if (!gst_aml_v4l2_object_try_import(obj, buffer))
{
- GstBuffer *buffer;
-
- if (!gst_buffer_pool_set_active(pool->other_pool, TRUE))
- goto other_pool_failed;
-
- if (gst_buffer_pool_acquire_buffer(pool->other_pool, &buffer, NULL) !=
- GST_FLOW_OK)
- goto other_pool_failed;
-
- if (!gst_aml_v4l2_object_try_import(obj, buffer))
- {
- gst_buffer_unref(buffer);
- goto cannot_import;
- }
- gst_buffer_unref(buffer);
+ gst_buffer_unref (buffer);
+ goto cannot_import;
}
+ gst_buffer_unref (buffer);
+ }
- config = gst_buffer_pool_get_config(bpool);
- if (!gst_buffer_pool_config_get_params(config, &caps, &size, &min_buffers,
- &max_buffers))
- goto wrong_config;
+ config = gst_buffer_pool_get_config (bpool);
+ if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers,
+ &max_buffers))
+ goto wrong_config;
- min_latency = MAX(GST_AML_V4L2_MIN_BUFFERS, obj->min_buffers);
+ min_latency = MAX(GST_AML_V4L2_MIN_BUFFERS, obj->min_buffers);
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- can_allocate = TRUE;
+ can_allocate = TRUE;
#ifdef HAVE_LIBV4L2
- /* This workaround a unfixable bug in libv4l2 when RW is emulated on top
- * of MMAP. In this case, the first read initialize the queues, but the
- * poll before that will always fail. Doing an empty read, forces the
- * queue to be initialized now. We only do this if we have a streaming
- * driver. */
- if (obj->device_caps & V4L2_CAP_STREAMING)
- obj->read(obj->video_fd, NULL, 0);
+ /* This workaround a unfixable bug in libv4l2 when RW is emulated on top
+ * of MMAP. In this case, the first read initialize the queues, but the
+ * poll before that will always fail. Doing an empty read, forces the
+ * queue to be initialized now. We only do this if we have a streaming
+ * driver. */
+ if (obj->device_caps & V4L2_CAP_STREAMING)
+ obj->read (obj->video_fd, NULL, 0);
#endif
- break;
+ break;
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_MMAP:
{
- guint count;
+ guint count;
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP);
- /* first, lets request buffers, and see how many we can get: */
- GST_DEBUG_OBJECT(pool, "requesting %d MMAP buffers", min_buffers);
+ /* first, lets request buffers, and see how many we can get: */
+ GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers);
- count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
- V4L2_MEMORY_MMAP);
- pool->num_allocated = count;
+ count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
+ V4L2_MEMORY_MMAP);
+ pool->num_allocated = count;
- if (count < GST_AML_V4L2_MIN_BUFFERS)
- {
- min_buffers = count;
- goto no_buffers;
- }
+ if (count < GST_AML_V4L2_MIN_BUFFERS)
+ {
+ min_buffers = count;
+ goto no_buffers;
+ }
- /* V4L2 buffer pool are often very limited in the amount of buffers it
- * can offer. The copy_threshold will workaround this limitation by
- * falling back to copy if the pipeline needed more buffers. This also
- * prevent having to do REQBUFS(N)/REQBUFS(0) everytime configure is
- * called. */
- if (count != min_buffers || pool->enable_copy_threshold)
- {
- GST_WARNING_OBJECT(pool,
- "Uncertain or not enough buffers, enabling copy threshold");
- min_buffers = count;
- copy_threshold = min_latency;
- }
+ /* V4L2 buffer pool are often very limited in the amount of buffers it
+ * can offer. The copy_threshold will workaround this limitation by
+ * falling back to copy if the pipeline needed more buffers. This also
+ * prevent having to do REQBUFS(N)/REQBUFS(0) every time configure is
+ * called. */
+ if (count != min_buffers || pool->enable_copy_threshold)
+ {
+ GST_WARNING_OBJECT (pool,
+ "Uncertain or not enough buffers, enabling copy threshold");
+ min_buffers = count;
+ copy_threshold = min_latency;
+ }
- break;
+ break;
}
case GST_V4L2_IO_USERPTR:
{
- guint count;
+ guint count;
- can_allocate =
- GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, USERPTR);
+ can_allocate =
+ GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, USERPTR);
- GST_DEBUG_OBJECT(pool, "requesting %d USERPTR buffers", min_buffers);
+ GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers);
- count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
- V4L2_MEMORY_USERPTR);
+ count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
+ V4L2_MEMORY_USERPTR);
- /* There is no rational to not get what we asked */
- if (count < min_buffers)
- {
- min_buffers = count;
- goto no_buffers;
- }
-
+ /* There is no rational to not get what we asked */
+ if (count < min_buffers)
+ {
min_buffers = count;
- break;
+ goto no_buffers;
+ }
+
+ min_buffers = count;
+ break;
}
case GST_V4L2_IO_DMABUF_IMPORT:
{
- guint count;
+ guint count;
- can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, DMABUF);
+ can_allocate = GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, DMABUF);
- GST_DEBUG_OBJECT(pool, "requesting %d DMABUF buffers", min_buffers);
+ GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers);
- count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
- V4L2_MEMORY_DMABUF);
+ count = gst_aml_v4l2_allocator_start(pool->vallocator, min_buffers,
+ V4L2_MEMORY_DMABUF);
- /* There is no rational to not get what we asked */
- if (count < min_buffers)
- {
- min_buffers = count;
- goto no_buffers;
- }
-
+ /* There is no rational to not get what we asked */
+ if (count < min_buffers)
+ {
min_buffers = count;
- break;
+ goto no_buffers;
+ }
+
+ min_buffers = count;
+ break;
}
default:
- min_buffers = 0;
- copy_threshold = 0;
- g_assert_not_reached();
- break;
- }
+ min_buffers = 0;
+ copy_threshold = 0;
+ g_assert_not_reached ();
+ break;
+ }
- if (can_allocate)
- max_latency = max_buffers;
- else
- max_latency = min_buffers;
+ if (can_allocate)
+ max_latency = max_buffers;
+ else
+ max_latency = min_buffers;
- pool->size = size;
- pool->copy_threshold = copy_threshold;
- pool->max_latency = max_latency;
- pool->min_latency = min_latency;
- pool->num_queued = 0;
+ pool->size = size;
+ pool->copy_threshold = copy_threshold;
+ pool->max_latency = max_latency;
+ pool->min_latency = min_latency;
+ pool->num_queued = 0;
- if (max_buffers != 0 && max_buffers < min_buffers)
- max_buffers = min_buffers;
+ if (max_buffers != 0 && max_buffers < min_buffers)
+ max_buffers = min_buffers;
- gst_buffer_pool_config_set_params(config, caps, size, min_buffers,
- max_buffers);
- pclass->set_config(bpool, config);
- gst_structure_free(config);
+ gst_buffer_pool_config_set_params (config, caps, size, min_buffers,
+ max_buffers);
+ pclass->set_config (bpool, config);
+ gst_structure_free (config);
- /* now, allocate the buffers: */
- if (!pclass->start(bpool))
- goto start_failed;
+ /* now, allocate the buffers: */
+ if (!pclass->start (bpool))
+ goto start_failed;
- if (!V4L2_TYPE_IS_OUTPUT(obj->type))
+ if (!V4L2_TYPE_IS_OUTPUT(obj->type))
+ {
+ if (g_atomic_int_get(&pool->num_queued) < min_buffers)
{
- if (g_atomic_int_get(&pool->num_queued) < min_buffers)
- {
- if (obj->old_other_pool || obj->old_old_other_pool)
- GST_DEBUG_OBJECT(pool, "resolution switching flow, need to wait other pool recycle");
- else
- goto queue_failed;
- }
-
- pool->group_released_handler =
- g_signal_connect_swapped(pool->vallocator, "group-released",
- G_CALLBACK(gst_aml_v4l2_buffer_pool_resurrect_buffer), pool);
- ret = gst_aml_v4l2_buffer_pool_streamon(pool);
+ if (obj->old_other_pool || obj->old_old_other_pool)
+ GST_DEBUG_OBJECT(pool, "resolution switching flow, need to wait other pool recycle");
+ else
+ goto queue_failed;
}
- return ret;
+ pool->group_released_handler =
+ g_signal_connect_swapped (pool->vallocator, "group-released",
+ G_CALLBACK(gst_aml_v4l2_buffer_pool_resurrect_buffer), pool);
+ ret = gst_aml_v4l2_buffer_pool_streamon(pool);
+ }
- /* ERRORS */
+ return ret;
+
+ /* ERRORS */
wrong_config:
-{
- GST_ERROR_OBJECT(pool, "invalid config %" GST_PTR_FORMAT, config);
- gst_structure_free(config);
+ {
+ GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config);
+ gst_structure_free (config);
return FALSE;
-}
+ }
no_buffers:
-{
- GST_ERROR_OBJECT(pool,
- "we received %d buffer from device '%s', we want at least %d",
- min_buffers, obj->videodev, GST_AML_V4L2_MIN_BUFFERS);
- gst_structure_free(config);
+ {
+ GST_ERROR_OBJECT (pool,
+ "we received %d buffer from device '%s', we want at least %d",
+ min_buffers, obj->videodev, GST_AML_V4L2_MIN_BUFFERS);
+ gst_structure_free (config);
return FALSE;
-}
+ }
start_failed:
-{
- GST_ERROR_OBJECT(pool, "allocate failed");
+ {
+ GST_ERROR_OBJECT (pool, "allocate failed");
return FALSE;
-}
+ }
other_pool_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to activate the other pool %" GST_PTR_FORMAT, pool->other_pool);
+ {
+ GST_ERROR_OBJECT (pool, "failed to activate the other pool %"
+ GST_PTR_FORMAT, pool->other_pool);
return FALSE;
-}
+ }
queue_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to queue buffers into the capture queue");
+ {
+ GST_ERROR_OBJECT (pool, "failed to queue buffers into the capture queue");
return FALSE;
-}
+ }
cannot_import:
-{
- GST_ERROR_OBJECT(pool, "cannot import buffers from downstream pool");
+ {
+ GST_ERROR_OBJECT (pool, "cannot import buffers from downstream pool");
return FALSE;
-}
+ }
}
static gboolean
gst_aml_v4l2_buffer_pool_vallocator_stop(GstAmlV4l2BufferPool *pool)
{
- GstAmlV4l2Return vret;
+ GstAmlV4l2Return vret;
- if (!pool->vallocator)
- return TRUE;
+ if (!pool->vallocator)
+ return TRUE;
- vret = gst_aml_v4l2_allocator_stop(pool->vallocator);
+ vret = gst_aml_v4l2_allocator_stop(pool->vallocator);
- if (vret == GST_V4L2_BUSY)
- GST_WARNING_OBJECT(pool, "some buffers are still outstanding");
+ if (vret == GST_AML_V4L2_BUSY)
+ GST_WARNING_OBJECT (pool, "some buffers are still outstanding");
- return (vret == GST_V4L2_OK);
+ return (vret == GST_AML_V4L2_OK);
}
static gboolean
gst_aml_v4l2_buffer_pool_stop(GstBufferPool *bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- gboolean ret;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ gboolean ret;
- if (pool->orphaned)
- return gst_aml_v4l2_buffer_pool_vallocator_stop(pool);
+ if (pool->orphaned)
+ return gst_aml_v4l2_buffer_pool_vallocator_stop(pool);
- GST_DEBUG_OBJECT(pool, "stopping pool");
+ GST_DEBUG_OBJECT (pool, "stopping pool");
- if (pool->group_released_handler > 0)
- {
- g_signal_handler_disconnect(pool->vallocator,
- pool->group_released_handler);
- pool->group_released_handler = 0;
- }
+ if (pool->group_released_handler > 0)
+ {
+ g_signal_handler_disconnect (pool->vallocator,
+ pool->group_released_handler);
+ pool->group_released_handler = 0;
+ }
- gst_aml_v4l2_buffer_pool_streamoff(pool);
+ gst_aml_v4l2_buffer_pool_streamoff(pool);
- ret = GST_BUFFER_POOL_CLASS(parent_class)->stop(bpool);
+ ret = GST_BUFFER_POOL_CLASS (parent_class)->stop (bpool);
- if (ret)
- ret = gst_aml_v4l2_buffer_pool_vallocator_stop(pool);
+ if (ret)
+ ret = gst_aml_v4l2_buffer_pool_vallocator_stop(pool);
- GST_DEBUG_OBJECT(pool, "stopping other_pool");
- if (pool->other_pool)
- {
- gst_buffer_pool_set_active(pool->other_pool, FALSE);
- gst_object_unref(pool->other_pool);
- pool->other_pool = NULL;
- }
+ GST_DEBUG_OBJECT (pool, "stopping other_pool");
+ if (pool->other_pool)
+ {
+ gst_buffer_pool_set_active (pool->other_pool, FALSE);
+ gst_object_unref (pool->other_pool);
+ pool->other_pool = NULL;
+ }
- return ret;
+ return ret;
}
gboolean
gst_aml_v4l2_buffer_pool_orphan(GstBufferPool **bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(*bpool);
- gboolean ret;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(*bpool);
+ gboolean ret;
- if (!GST_AML_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(pool->vallocator))
- return FALSE;
+ if (!GST_AML_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS(pool->vallocator))
+ return FALSE;
- if (g_getenv("GST_V4L2_FORCE_DRAIN"))
- return FALSE;
+ if (g_getenv("GST_V4L2_FORCE_DRAIN"))
+ return FALSE;
- GST_DEBUG_OBJECT(pool, "orphaning pool");
+ GST_DEBUG_OBJECT (pool, "orphaning pool");
- gst_buffer_pool_set_active(*bpool, FALSE);
- /*
- * If the buffer pool has outstanding buffers, it will not be stopped
- * by the base class when set inactive. Stop it manually and mark it
- * as orphaned
- */
- ret = gst_aml_v4l2_buffer_pool_stop(*bpool);
- if (!ret)
- {
- GST_DEBUG_OBJECT(pool, "stop poll fail, try to orphaning allocator");
- ret = gst_aml_v4l2_allocator_orphan(pool->vallocator);
- }
+ gst_buffer_pool_set_active (*bpool, FALSE);
+ /*
+ * If the buffer pool has outstanding buffers, it will not be stopped
+ * by the base class when set inactive. Stop it manually and mark it
+ * as orphaned
+ */
+ ret = gst_aml_v4l2_buffer_pool_stop(*bpool);
+ if (!ret)
+ {
+ GST_DEBUG_OBJECT(pool, "stop poll fail, try to orphaning allocator");
+ ret = gst_aml_v4l2_allocator_orphan (pool->vallocator);
+ }
- if (!ret)
- goto orphan_failed;
+ if (!ret)
+ goto orphan_failed;
- pool->orphaned = TRUE;
- gst_object_unref(*bpool);
- *bpool = NULL;
+ pool->orphaned = TRUE;
+ gst_object_unref(*bpool);
+ *bpool = NULL;
orphan_failed:
- return ret;
+ return ret;
}
static void
-gst_aml_v4l2_buffer_pool_flush_start(GstBufferPool *bpool)
+gst_aml_v4l2_buffer_pool_flush_start (GstBufferPool * bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (bpool);
- GST_DEBUG_OBJECT(pool, "start flushing");
+ GST_DEBUG_OBJECT (pool, "start flushing");
- gst_poll_set_flushing(pool->poll, TRUE);
+ gst_poll_set_flushing (pool->poll, TRUE);
- GST_OBJECT_LOCK(pool);
- pool->empty = FALSE;
- g_cond_broadcast(&pool->empty_cond);
- GST_OBJECT_UNLOCK(pool);
+ GST_OBJECT_LOCK (pool);
+ pool->empty = FALSE;
+ g_cond_broadcast (&pool->empty_cond);
+ GST_OBJECT_UNLOCK (pool);
- if (pool->other_pool)
- gst_buffer_pool_set_flushing(pool->other_pool, TRUE);
+ if (pool->other_pool)
+ gst_buffer_pool_set_flushing(pool->other_pool, TRUE);
}
static void
-gst_aml_v4l2_buffer_pool_flush_stop(GstBufferPool *bpool)
+gst_aml_v4l2_buffer_pool_flush_stop (GstBufferPool * bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (bpool);
- GST_DEBUG_OBJECT(pool, "stop flushing");
+ GST_DEBUG_OBJECT (pool, "stop flushing");
- if (pool->other_pool)
- gst_buffer_pool_set_flushing(pool->other_pool, FALSE);
+ if (pool->other_pool)
+ gst_buffer_pool_set_flushing (pool->other_pool, FALSE);
- gst_poll_set_flushing(pool->poll, FALSE);
+ gst_poll_set_flushing (pool->poll, FALSE);
}
static GstFlowReturn
-gst_aml_v4l2_buffer_pool_poll(GstAmlV4l2BufferPool *pool, gboolean wait)
+gst_aml_v4l2_buffer_pool_poll (GstAmlV4l2BufferPool * pool, gboolean wait)
{
- gint ret;
- GstClockTime timeout;
- gint try_num = 0;
+ gint ret;
+ GstClockTime timeout;
+ gint try_num = 0;
+ if (wait)
+ timeout = GST_CLOCK_TIME_NONE;
+ else
+ timeout = 0;
+
+ /* In RW mode there is no queue, hence no need to wait while the queue is
+ * empty */
+
+ if ((pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ pool->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
+ {
+ GST_TRACE_OBJECT(pool, "CAPTURE DMA don't quit when empty buf");
+ timeout = 5*1000*1000; //5ms
+ }
+ else
+ {
+ if (pool->obj->mode != GST_V4L2_IO_RW)
+ {
+ GST_OBJECT_LOCK(pool);
+
+ if (!wait && pool->empty)
+ {
+ GST_OBJECT_UNLOCK(pool);
+ goto no_buffers;
+ }
+
+ while (pool->empty)
+ g_cond_wait(&pool->empty_cond, GST_OBJECT_GET_LOCK(pool));
+
+ GST_OBJECT_UNLOCK(pool);
+ }
+ }
+
+ if (!pool->can_poll_device)
+ {
if (wait)
- timeout = GST_CLOCK_TIME_NONE;
+ goto done;
else
- timeout = 0;
+ goto no_buffers;
+ }
- /* In RW mode there is no queue, hence no need to wait while the queue is
- * empty */
+ GST_TRACE_OBJECT(pool, "polling device");
+again:
+ ret = gst_poll_wait (pool->poll, timeout);
+#ifdef GST_AML_SPEC_FLOW_FOR_VBP
+ GST_TRACE_OBJECT(pool, "amlmodbuf poll timeout:%lld, ret:%d, errno:%d", timeout, ret, errno);
+#endif
+ if (G_UNLIKELY(ret < 0))
+ {
+ switch (errno)
+ {
+ case EBUSY:
+ goto stopped;
+ case EAGAIN:
+ case EINTR:
+ goto again;
+ case ENXIO:
+ GST_WARNING_OBJECT (pool,
+ "v4l2 device doesn't support polling. Disabling"
+ " using libv4l2 in this case may cause deadlocks");
+ pool->can_poll_device = FALSE;
+ goto done;
+ default:
+ goto select_error;
+ }
+ }
+
+ if (gst_poll_fd_has_error (pool->poll, &pool->pollfd))
+ {
+ //if v4l2 don't have capture buffer, we will poll a error,it cause v4l2dec loop thread exit
+ //so we should wait capture buffer release and queue it to v4l2,after this,we try poll again
if ((pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
pool->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
{
- GST_TRACE_OBJECT(pool, "CAPTURE DMA don't quit when empty buf");
- timeout = 5*1000*1000; //5ms
+ if (pool->num_queued == 0)
+ {
+ ret = 0;
+ GST_TRACE_OBJECT(pool,"ignore error when no capture buffer on v4l2");
+ g_usleep(4000);
+ goto wait_buffer_queue;
+ }
}
- else
- {
- if (pool->obj->mode != GST_V4L2_IO_RW)
- {
- GST_OBJECT_LOCK(pool);
-
- if (!wait && pool->empty)
- {
- GST_OBJECT_UNLOCK(pool);
- goto no_buffers;
- }
-
- while (pool->empty)
- g_cond_wait(&pool->empty_cond, GST_OBJECT_GET_LOCK(pool));
-
- GST_OBJECT_UNLOCK(pool);
- }
- }
-
- if (!pool->can_poll_device)
- {
- if (wait)
- goto done;
- else
- goto no_buffers;
- }
-
- GST_TRACE_OBJECT(pool, "polling device");
-
-again:
- ret = gst_poll_wait(pool->poll, timeout);
-#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- GST_TRACE_OBJECT(pool, "amlmodbuf poll timeout:%lld, ret:%d, errno:%d", timeout, ret, errno);
-#endif
- if (G_UNLIKELY(ret < 0))
- {
- switch (errno)
- {
- case EBUSY:
- goto stopped;
- case EAGAIN:
- case EINTR:
- goto again;
- case ENXIO:
- GST_WARNING_OBJECT(pool,
- "v4l2 device doesn't support polling. Disabling"
- " using libv4l2 in this case may cause deadlocks");
- pool->can_poll_device = FALSE;
- goto done;
- default:
- goto select_error;
- }
- }
-
- if (gst_poll_fd_has_error(pool->poll, &pool->pollfd))
- {
- //if v4l2 don't have capture buffer, we will poll a error,it cause v4l2dec loop thread exit
- //so we should wait capture buffer release and queue it to v4l2,after this,we try poll again
- if ((pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
- pool->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
- {
- if (pool->num_queued == 0)
- {
- ret = 0;
- GST_TRACE_OBJECT(pool,"ignore error when no capture buffer on v4l2");
- g_usleep(4000);
- goto wait_buffer_queue;
- }
- }
- goto select_error;
- }
+ goto select_error;
+ }
wait_buffer_queue:
- if (ret == 0)
- {
+ if (ret == 0)
+ {
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- if ((pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
- pool->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
- {
- GST_TRACE_OBJECT(pool, "amlmodbuf can't get buffer in capture obj dmaimport mode, try release buf from other pool");
- gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, try_num++);
- gst_aml_v4l2_buffer_pool_release_buffer_aml_patch((GstBufferPool *)pool);
- goto again;
- }
- else
-#endif
- goto no_buffers;
+ if ((pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || pool->obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ pool->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
+ {
+ GST_TRACE_OBJECT(pool, "amlmodbuf can't get buffer in capture obj dmaimport mode, try release buf from other pool");
+ gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, try_num++);
+ gst_aml_v4l2_buffer_pool_release_buffer_aml_patch((GstBufferPool *)pool);
+ goto again;
}
+ else
+#endif
+ goto no_buffers;
+ }
done:
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
- /* ERRORS */
+ /* ERRORS */
stopped:
-{
- GST_DEBUG_OBJECT(pool, "stop called");
+ {
+ GST_DEBUG_OBJECT (pool, "stop called");
return GST_FLOW_FLUSHING;
-}
+ }
select_error:
-{
- GST_ELEMENT_ERROR(pool->obj->element, RESOURCE, READ, (NULL),
- ("poll error %d: %s (%d)", ret, g_strerror(errno), errno));
+ {
+ GST_ELEMENT_ERROR (pool->obj->element, RESOURCE, READ, (NULL),
+ ("poll error %d: %s (%d)", ret, g_strerror (errno), errno));
return GST_FLOW_ERROR;
-}
+ }
no_buffers:
return GST_FLOW_CUSTOM_SUCCESS;
}
static GstFlowReturn
-gst_aml_v4l2_buffer_pool_qbuf(GstAmlV4l2BufferPool *pool, GstBuffer *buf,
+gst_aml_v4l2_buffer_pool_qbuf (GstAmlV4l2BufferPool * pool, GstBuffer * buf,
GstAmlV4l2MemoryGroup *group)
{
- const GstAmlV4l2Object *obj = pool->obj;
- GstClockTime timestamp;
- gint index;
+ const GstAmlV4l2Object *obj = pool->obj;
+ GstClockTime timestamp;
+ gint index;
- index = group->buffer.index;
+ index = group->buffer.index;
- if (pool->buffers[index] != NULL)
- goto already_queued;
+ if (pool->buffers[index] != NULL)
+ goto already_queued;
- GST_LOG_OBJECT(pool, "queuing buffer %i", index);
+ GST_LOG_OBJECT(pool, "queuing buffer %i", index);
- if (V4L2_TYPE_IS_OUTPUT(obj->type))
- {
- enum v4l2_field field;
+ if (V4L2_TYPE_IS_OUTPUT (obj->type))
+ {
+ enum v4l2_field field;
- /* Except when field is set to alternate, buffer field is the same as
- * the one defined in format */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- field = obj->format.fmt.pix_mp.field;
- else
- field = obj->format.fmt.pix.field;
-
- /* NB: At this moment, we can't have alternate mode because it not handled
- * yet */
- if (field == V4L2_FIELD_ALTERNATE)
- {
- if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_FRAME_FLAG_TFF))
- field = V4L2_FIELD_TOP;
- else
- field = V4L2_FIELD_BOTTOM;
- }
-
- group->buffer.field = field;
- }
-
- if (GST_BUFFER_TIMESTAMP_IS_VALID(buf))
- {
- timestamp = GST_BUFFER_TIMESTAMP(buf);
- GST_TIME_TO_TIMEVAL(timestamp, group->buffer.timestamp);
- }
+ /* Except when field is set to alternate, buffer field is the same as
+ * the one defined in format */
+ if (V4L2_TYPE_IS_MULTIPLANAR (obj->type))
+ field = obj->format.fmt.pix_mp.field;
else
+ field = obj->format.fmt.pix.field;
+
+
+ /* NB: At this moment, we can't have alternate mode because it not handled
+ * yet */
+ if (field == V4L2_FIELD_ALTERNATE)
{
- group->buffer.timestamp.tv_sec= -1;
- group->buffer.timestamp.tv_usec= 0;
+ if (GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_FRAME_FLAG_TFF))
+ field = V4L2_FIELD_TOP;
+ else
+ field = V4L2_FIELD_BOTTOM;
}
- GST_OBJECT_LOCK(pool);
- g_atomic_int_inc(&pool->num_queued);
- pool->buffers[index] = buf;
+ group->buffer.field = field;
+ }
- if (!gst_aml_v4l2_allocator_qbuf(pool->vallocator, group))
- goto queue_failed;
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
+ {
+ timestamp = GST_BUFFER_TIMESTAMP(buf);
+ GST_TIME_TO_TIMEVAL (timestamp, group->buffer.timestamp);
+ }
+ else
+ {
+ group->buffer.timestamp.tv_sec = -1;
+ group->buffer.timestamp.tv_usec = 0;
+ }
- if (!V4L2_TYPE_IS_OUTPUT(obj->type))
- {
- gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, 0);
- }
+ GST_OBJECT_LOCK (pool);
+ g_atomic_int_inc (&pool->num_queued);
+ pool->buffers[index] = buf;
- pool->empty = FALSE;
- g_cond_signal(&pool->empty_cond);
- GST_OBJECT_UNLOCK(pool);
+ if (!gst_aml_v4l2_allocator_qbuf (pool->vallocator, group))
+ goto queue_failed;
- return GST_FLOW_OK;
+ if (!V4L2_TYPE_IS_OUTPUT(obj->type))
+ {
+ gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, 0);
+ }
+
+ pool->empty = FALSE;
+ g_cond_signal (&pool->empty_cond);
+ GST_OBJECT_UNLOCK (pool);
+
+ return GST_FLOW_OK;
already_queued:
-{
- GST_ERROR_OBJECT(pool, "the buffer %i was already queued", index);
+ {
+ GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
return GST_FLOW_ERROR;
-}
+ }
queue_failed:
-{
- GST_ERROR_OBJECT(pool, "could not queue a buffer %i", index);
+ {
+ GST_ERROR_OBJECT (pool, "could not queue a buffer %i", index);
/* Mark broken buffer to the allocator */
- GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_TAG_MEMORY);
- g_atomic_int_add(&pool->num_queued, -1);
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_TAG_MEMORY);
+ g_atomic_int_add (&pool->num_queued, -1);
pool->buffers[index] = NULL;
- GST_OBJECT_UNLOCK(pool);
+ GST_OBJECT_UNLOCK (pool);
return GST_FLOW_ERROR;
-}
+ }
}
static GstFlowReturn
-gst_aml_v4l2_buffer_pool_dqevent(GstAmlV4l2BufferPool *pool)
+gst_aml_v4l2_buffer_pool_dqevent (GstAmlV4l2BufferPool * pool)
{
- GstAmlV4l2Object *v4l2object = pool->obj;
- struct v4l2_event evt;
- GstFlowReturn ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
+ GstAmlV4l2Object *v4l2object = pool->obj;
+ struct v4l2_event evt;
+ GstFlowReturn ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
- memset(&evt, 0x00, sizeof(struct v4l2_event));
- if (v4l2object->ioctl(pool->video_fd, VIDIOC_DQEVENT, &evt) < 0)
- goto dqevent_failed;
+ memset (&evt, 0x00, sizeof (struct v4l2_event));
+ if (v4l2object->ioctl (pool->video_fd, VIDIOC_DQEVENT, &evt) < 0)
+ goto dqevent_failed;
- switch (evt.type)
- {
+ switch (evt.type)
+ {
case V4L2_EVENT_SOURCE_CHANGE:
- if (evt.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)
- ret = GST_AML_V4L2_FLOW_SOURCE_CHANGE;
- else
- {
- GST_WARNING_OBJECT (pool, "Unknown source change 0x%x - skipped", evt.u.src_change.changes);
- ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
- }
- break;
- case V4L2_EVENT_EOS:
- ret = GST_AML_V4L2_FLOW_LAST_BUFFER;
- break;
- case V4L2_EVENT_PRIVATE_EXT_REPORT_DECINFO:
- if (evt.id == AML_DECINFO_EVENT_CC)
- {
- struct v4l2_ext_control control;
- struct v4l2_ext_controls ctrls;
- struct vdec_common_s vdec_comm;
- char cc_data[MAX_CC_LEN] = {0};
-
- memset(&ctrls, 0, sizeof(ctrls));
- memset(&control, 0, sizeof(control));
- memset(&vdec_comm, 0, sizeof(vdec_comm));
-
- vdec_comm.type = AML_DECINFO_GET_CC_TYPE;
- vdec_comm.u.usd_param.data = (void *)cc_data;
- vdec_comm.u.usd_param.data_size = MAX_CC_LEN;
-
- control.ptr = &vdec_comm;
- control.id = AML_V4L2_GET_DECINFO_SET;
- control.size = sizeof(struct vdec_common_s);
-
- ctrls.count = 1;
- ctrls.controls = &control;
-
- if (v4l2object->ioctl (pool->video_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
- {
- GST_DEBUG("VIDIOC_S_EXT_CTRLS fail");
- }
- else
- {
- if (v4l2object->ioctl (pool->video_fd, VIDIOC_G_EXT_CTRLS, &ctrls) == 0)
- {
- GstBuffer *cc_buffer = gst_buffer_new ();
- GstMemory *mem = gst_allocator_alloc (NULL, MAX_CC_LEN, NULL);
- gst_buffer_insert_memory (cc_buffer, -1, mem);
- gsize cc_size = gst_buffer_fill (cc_buffer, 0, vdec_comm.u.usd_param.data, vdec_comm.u.usd_param.data_size);
- GST_DEBUG("copy cc data size:%d",cc_size);
- cc_buffer->pts = vdec_comm.u.usd_param.meta_data.timestamp;
- pool->cc_buffer_list = g_list_append (pool->cc_buffer_list,cc_buffer);
- GST_DEBUG("cc_buffer_list size:%d",g_list_length(pool->cc_buffer_list));
- #if 0
- //dump decoder metadata
- GST_DEBUG("cc pack pts:%lld",vdec_comm.u.usd_param.meta_data.timestamp);
- int fd=open("/data/test/cc0.data",O_RDWR |O_CREAT|O_APPEND,0777);
- write(fd,vdec_comm.u.usd_param.data,vdec_comm.u.usd_param.data_size);
- close(fd);
- #endif
- }
- else
- {
- GST_DEBUG("VIDIOC_G_EXT_CTRLS fail");
- }
- }
- ret = GST_AML_V4L2_FLOW_CC_DATA;
- }
- else
- {
- GST_WARNING_OBJECT (pool, "Unknown DECINFO 0x%x - skipped", evt.id);
+ if (evt.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)
+ ret = GST_AML_V4L2_FLOW_SOURCE_CHANGE;
+ else
+ {
+ GST_WARNING_OBJECT (pool, "Unknown source change 0x%x - skipped", evt.u.src_change.changes);
ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
- }
- break;
- case V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME:
- {
- guint64 pts = 0;
- memcpy(&pts, &(evt.u.data[0]), sizeof(guint64));
- v4l2object->num_error_frames += 1;
- v4l2object->error_frame_pts = pts;
- GST_WARNING_OBJECT (pool, "decoding video frame error,pts:%" GST_TIME_FORMAT ",total %d",
- GST_TIME_ARGS(pts),v4l2object->num_error_frames);
- ret = GST_AML_V4L2_FLOW_DECODING_ERROR;
- } break;
- default:
- GST_WARNING_OBJECT (pool, "Unknown evt.type 0x%x - skipped", evt.type);
- ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
- break;
- }
+ }
+ break;
+ case V4L2_EVENT_EOS:
+ ret = GST_AML_V4L2_FLOW_LAST_BUFFER;
+ break;
+ case V4L2_EVENT_PRIVATE_EXT_REPORT_DECINFO:
+ if (evt.id == AML_DECINFO_EVENT_CC)
+ {
+ struct v4l2_ext_control control;
+ struct v4l2_ext_controls ctrls;
+ struct vdec_common_s vdec_comm;
+ char cc_data[MAX_CC_LEN] = {0};
- return ret;
+ memset(&ctrls, 0, sizeof(ctrls));
+ memset(&control, 0, sizeof(control));
+ memset(&vdec_comm, 0, sizeof(vdec_comm));
- /* ERRORS */
-dqevent_failed:
-{
- return GST_FLOW_ERROR;
-}
-}
+ vdec_comm.type = AML_DECINFO_GET_CC_TYPE;
+ vdec_comm.u.usd_param.data = (void *)cc_data;
+ vdec_comm.u.usd_param.data_size = MAX_CC_LEN;
-static GstFlowReturn
-gst_aml_v4l2_buffer_pool_dqbuf(GstAmlV4l2BufferPool *pool, GstBuffer **buffer,
- gboolean wait)
-{
- GstFlowReturn res;
- GstBuffer *outbuf = NULL;
- GstAmlV4l2Object *obj = pool->obj;
- GstClockTime timestamp;
- GstAmlV4l2MemoryGroup *group;
- GstVideoMeta *vmeta;
- gsize size;
- gint i;
+ control.ptr = &vdec_comm;
+ control.id = AML_V4L2_GET_DECINFO_SET;
+ control.size = sizeof(struct vdec_common_s);
- res = gst_aml_v4l2_allocator_dqbuf(pool->vallocator, &group);
- if (res == GST_FLOW_EOS)
- goto eos;
- if (res != GST_FLOW_OK)
- goto dqbuf_failed;
+ ctrls.count = 1;
+ ctrls.controls = &control;
- /* get our GstBuffer with that index from the pool, if the buffer was
- * outstanding we have a serious problem.
- */
- outbuf = pool->buffers[group->buffer.index];
- if (outbuf == NULL)
- goto no_buffer;
-
- /* mark the buffer outstanding */
- pool->buffers[group->buffer.index] = NULL;
- if (g_atomic_int_dec_and_test(&pool->num_queued))
- {
- GST_OBJECT_LOCK(pool);
- pool->empty = TRUE;
- GST_OBJECT_UNLOCK(pool);
- }
-
- if (-1== group->buffer.timestamp.tv_sec)
- timestamp = GST_CLOCK_TIME_NONE;
- else
- timestamp = GST_TIMEVAL_TO_TIME(group->buffer.timestamp);
-
- size = 0;
- vmeta = gst_buffer_get_video_meta(outbuf);
- for (i = 0; i < group->n_mem; i++)
- {
- GST_LOG_OBJECT(pool,
- "dequeued buffer %p seq:%d (ix=%d), mem %p used %d, plane=%d, flags %08x, ts %" GST_TIME_FORMAT ", pool-queued=%d, buffer=%p", outbuf,
- group->buffer.sequence, group->buffer.index, group->mem[i],
- group->planes[i].bytesused, i, group->buffer.flags,
- GST_TIME_ARGS(timestamp), pool->num_queued, outbuf);
-
- if (vmeta)
- {
- vmeta->offset[i] = size;
- size += gst_memory_get_sizes(group->mem[i], NULL, NULL);
- }
- }
-
- /* Ignore timestamp and field for OUTPUT device */
- if (V4L2_TYPE_IS_OUTPUT(obj->type))
- goto done;
-
- /* Check for driver bug in reporting feild */
- if (group->buffer.field == V4L2_FIELD_ANY)
- {
- /* Only warn once to avoid the spamming */
-#ifndef GST_DISABLE_GST_DEBUG
- if (!pool->has_warned_on_buggy_field)
- {
- pool->has_warned_on_buggy_field = TRUE;
- GST_WARNING_OBJECT(pool,
- "Driver should never set v4l2_buffer.field to ANY");
- }
-#endif
-
- /* Use the value from the format (works for UVC bug) */
- group->buffer.field = obj->format.fmt.pix.field;
-
- /* If driver also has buggy S_FMT, assume progressive */
- if (group->buffer.field == V4L2_FIELD_ANY)
- {
-#ifndef GST_DISABLE_GST_DEBUG
- if (!pool->has_warned_on_buggy_field)
+ if (v4l2object->ioctl (pool->video_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
+ {
+ GST_DEBUG("VIDIOC_S_EXT_CTRLS fail");
+ }
+ else
+ {
+ if (v4l2object->ioctl (pool->video_fd, VIDIOC_G_EXT_CTRLS, &ctrls) == 0)
{
- pool->has_warned_on_buggy_field = TRUE;
- GST_WARNING_OBJECT(pool,
- "Driver should never set v4l2_format.pix.field to ANY");
- }
-#endif
-
- group->buffer.field = V4L2_FIELD_NONE;
- }
- }
-
- /* set top/bottom field first if v4l2_buffer has the information */
- switch (group->buffer.field)
- {
- case V4L2_FIELD_NONE:
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- break;
- case V4L2_FIELD_INTERLACED_TB:
- GST_BUFFER_FLAG_SET(outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
- GST_BUFFER_FLAG_SET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- break;
- case V4L2_FIELD_INTERLACED_BT:
- GST_BUFFER_FLAG_SET(outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- break;
- case V4L2_FIELD_INTERLACED:
- GST_BUFFER_FLAG_SET(outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
- if (obj->tv_norm == V4L2_STD_NTSC_M ||
- obj->tv_norm == V4L2_STD_NTSC_M_JP ||
- obj->tv_norm == V4L2_STD_NTSC_M_KR)
- {
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- }
- else
- {
- GST_BUFFER_FLAG_SET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- }
- break;
- default:
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
- GST_BUFFER_FLAG_UNSET(outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
- GST_FIXME_OBJECT(pool,
- "Unhandled enum v4l2_field %d - treating as progressive",
- group->buffer.field);
- break;
- }
-
- if (GST_VIDEO_INFO_FORMAT(&obj->info) == GST_VIDEO_FORMAT_ENCODED)
- {
- if ((group->buffer.flags & V4L2_BUF_FLAG_KEYFRAME) ||
- GST_AML_V4L2_PIXELFORMAT(obj) == V4L2_PIX_FMT_MJPEG ||
- GST_AML_V4L2_PIXELFORMAT(obj) == V4L2_PIX_FMT_JPEG ||
- GST_AML_V4L2_PIXELFORMAT(obj) == V4L2_PIX_FMT_PJPG)
- GST_BUFFER_FLAG_UNSET(outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
- else
- GST_BUFFER_FLAG_SET(outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
- }
-
- if (group->buffer.flags & V4L2_BUF_FLAG_ERROR)
- GST_BUFFER_FLAG_SET(outbuf, GST_BUFFER_FLAG_CORRUPTED);
-
- GST_BUFFER_TIMESTAMP(outbuf) = timestamp;
- GST_BUFFER_OFFSET(outbuf) = group->buffer.sequence;
- GST_BUFFER_OFFSET_END(outbuf) = group->buffer.sequence + 1;
-
-done:
- *buffer = outbuf;
- if ( (group->buffer.flags & V4L2_BUF_FLAG_LAST) &&(group->buffer.bytesused == 0) )
- {
- GST_DEBUG_OBJECT (pool,"dequeued empty buffer");
- GST_BUFFER_FLAG_SET(*buffer, GST_AML_V4L2_BUFFER_FLAG_LAST_EMPTY);
- }
-
- if (!V4L2_TYPE_IS_OUTPUT(obj->type))
- {
- gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, 0);
- }
-
- return res;
-
- /* ERRORS */
-eos:
-{
- return GST_FLOW_EOS;
-}
-dqbuf_failed:
-{
- return GST_FLOW_ERROR;
-}
-no_buffer:
-{
- GST_ERROR_OBJECT(pool, "No free buffer found in the pool at index %d.",
- group->buffer.index);
- return GST_FLOW_ERROR;
-}
-}
-
-static GstFlowReturn
-gst_aml_v4l2_buffer_pool_dequeue(GstAmlV4l2BufferPool *pool, GstBuffer **buffer,
- gboolean wait)
-{
- GstFlowReturn res;
- GstAmlV4l2Object *obj = pool->obj;
-
- if ((res = gst_aml_v4l2_buffer_pool_poll(pool, wait)) != GST_FLOW_OK)
- goto poll_failed;
-
- if (obj->can_wait_event && gst_poll_fd_can_read_pri(pool->poll, &pool->pollfd))
- {
- GstFlowReturn res_event = gst_aml_v4l2_buffer_pool_dqevent(pool);
- if (res_event != GST_FLOW_OK)
- {
- /* when drive V4l2 receive cmd_stop, it will finish current decoding frame, then creat
- * a EOS event and a empty buff. if gstreamer dq EOS event first ,the last frame will be drop,
- * this a question
- */
- if (res_event == GST_AML_V4L2_FLOW_LAST_BUFFER)
- {
- GST_DEBUG_OBJECT(pool," reiceive EOS event, drop it");
+ GstBuffer *cc_buffer = gst_buffer_new ();
+ GstMemory *mem = gst_allocator_alloc (NULL, MAX_CC_LEN, NULL);
+ gst_buffer_insert_memory (cc_buffer, -1, mem);
+ gsize cc_size = gst_buffer_fill (cc_buffer, 0, vdec_comm.u.usd_param.data, vdec_comm.u.usd_param.data_size);
+ GST_DEBUG("copy cc data size:%d",cc_size);
+ cc_buffer->pts = vdec_comm.u.usd_param.meta_data.timestamp;
+ pool->cc_buffer_list = g_list_append (pool->cc_buffer_list,cc_buffer);
+ GST_DEBUG("cc_buffer_list size:%d",g_list_length(pool->cc_buffer_list));
+ #if 0
+ //dump decoder metadata
+ GST_DEBUG("cc pack pts:%lld",vdec_comm.u.usd_param.meta_data.timestamp);
+ int fd=open("/data/test/cc0.data",O_RDWR |O_CREAT|O_APPEND,0777);
+ write(fd,vdec_comm.u.usd_param.data,vdec_comm.u.usd_param.data_size);
+ close(fd);
+ #endif
}
else
- return res_event;
- }
- }
- if (res == GST_FLOW_CUSTOM_SUCCESS)
+ {
+ GST_DEBUG("VIDIOC_G_EXT_CTRLS fail");
+ }
+ }
+ ret = GST_AML_V4L2_FLOW_CC_DATA;
+ }
+ else
+ {
+ GST_WARNING_OBJECT (pool, "Unknown DECINFO 0x%x - skipped", evt.id);
+ ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
+ }
+ break;
+ case V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME:
{
- GST_LOG_OBJECT(pool, "nothing to dequeue");
- *buffer = NULL;
- return res;
- }
+ guint64 pts = 0;
+ memcpy(&pts, &(evt.u.data[0]), sizeof(guint64));
+ v4l2object->num_error_frames += 1;
+ v4l2object->error_frame_pts = pts;
+ GST_WARNING_OBJECT (pool, "decoding video frame error,pts:%" GST_TIME_FORMAT ",total %d",
+ GST_TIME_ARGS(pts),v4l2object->num_error_frames);
+ ret = GST_AML_V4L2_FLOW_DECODING_ERROR;
+ } break;
+ default:
+ GST_WARNING_OBJECT (pool, "Unknown evt.type 0x%x - skipped", evt.type);
+ ret = GST_AML_V4L2_FLOW_UNKNOWN_EVENT;
+ break;
+ }
- GST_LOG_OBJECT(pool, "dequeueing a buffer");
- return gst_aml_v4l2_buffer_pool_dqbuf(pool, buffer, wait);
+ return ret;
- /* ERRORS */
-poll_failed:
-{
- GST_DEBUG_OBJECT(pool, "poll error %s", gst_flow_get_name(res));
- return res;
-}
+ /* ERRORS */
+dqevent_failed:
+ {
+ return GST_FLOW_ERROR;
+ }
}
static GstFlowReturn
-gst_aml_v4l2_buffer_pool_acquire_buffer(GstBufferPool *bpool, GstBuffer **buffer,
- GstBufferPoolAcquireParams *params)
+gst_aml_v4l2_buffer_pool_dqbuf (GstAmlV4l2BufferPool * pool, GstBuffer ** buffer,
+ gboolean wait)
{
- GstFlowReturn ret;
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
- GstAmlV4l2Object *obj = pool->obj;
+ GstFlowReturn res;
+ GstBuffer *outbuf = NULL;
+ GstAmlV4l2Object *obj = pool->obj;
+ GstClockTime timestamp;
+ GstAmlV4l2MemoryGroup *group;
+ GstVideoMeta *vmeta;
+ gsize size;
+ gint i;
- GST_DEBUG_OBJECT(pool, "acquire");
+ res = gst_aml_v4l2_allocator_dqbuf (pool->vallocator, &group);
+ if (res == GST_FLOW_EOS)
+ goto eos;
+ if (res != GST_FLOW_OK)
+ goto dqbuf_failed;
- /* If this is being called to resurrect a lost buffer */
- if (params && params->flags & GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT)
+ /* get our GstBuffer with that index from the pool, if the buffer was
+ * outstanding we have a serious problem.
+ */
+ outbuf = pool->buffers[group->buffer.index];
+ if (outbuf == NULL)
+ goto no_buffer;
+
+ /* mark the buffer outstanding */
+ pool->buffers[group->buffer.index] = NULL;
+ if (g_atomic_int_dec_and_test (&pool->num_queued))
+ {
+ GST_OBJECT_LOCK (pool);
+ pool->empty = TRUE;
+ GST_OBJECT_UNLOCK (pool);
+ }
+
+ if (-1 == group->buffer.timestamp.tv_sec)
+ timestamp = GST_CLOCK_TIME_NONE;
+ else
+ timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp);
+
+ size = 0;
+ vmeta = gst_buffer_get_video_meta (outbuf);
+ for (i = 0; i < group->n_mem; i++)
+ {
+ GST_LOG_OBJECT(pool,
+ "dequeued buffer %p seq:%d (ix=%d), mem %p used %d, plane=%d, flags %08x, ts %" GST_TIME_FORMAT ", pool-queued=%d, buffer=%p", outbuf,
+ group->buffer.sequence, group->buffer.index, group->mem[i],
+ group->planes[i].bytesused, i, group->buffer.flags,
+ GST_TIME_ARGS(timestamp), pool->num_queued, outbuf);
+
+ if (vmeta)
{
- ret = pclass->acquire_buffer(bpool, buffer, params);
- goto done;
+ vmeta->offset[i] = size;
+ size += gst_memory_get_sizes (group->mem[i], NULL, NULL);
}
+ }
- switch (obj->type)
+ /* Ignore timestamp and field for OUTPUT device */
+ if (V4L2_TYPE_IS_OUTPUT (obj->type))
+ goto done;
+
+ /* Check for driver bug in reporting feild */
+ if (group->buffer.field == V4L2_FIELD_ANY)
+ {
+ /* Only warn once to avoid the spamming */
+#ifndef GST_DISABLE_GST_DEBUG
+ if (!pool->has_warned_on_buggy_field)
{
+ pool->has_warned_on_buggy_field = TRUE;
+ GST_WARNING_OBJECT (pool,
+ "Driver should never set v4l2_buffer.field to ANY");
+ }
+#endif
+
+ /* Use the value from the format (works for UVC bug) */
+ group->buffer.field = obj->format.fmt.pix.field;
+
+ /* If driver also has buggy S_FMT, assume progressive */
+ if (group->buffer.field == V4L2_FIELD_ANY)
+ {
+#ifndef GST_DISABLE_GST_DEBUG
+ if (!pool->has_warned_on_buggy_field)
+ {
+ pool->has_warned_on_buggy_field = TRUE;
+ GST_WARNING_OBJECT (pool,
+ "Driver should never set v4l2_format.pix.field to ANY");
+ }
+#endif
+
+ group->buffer.field = V4L2_FIELD_NONE;
+ }
+ }
+
+ /* set top/bottom field first if v4l2_buffer has the information */
+ switch (group->buffer.field)
+ {
+ case V4L2_FIELD_NONE:
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ break;
+ case V4L2_FIELD_INTERLACED_TB:
+ GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ break;
+ case V4L2_FIELD_INTERLACED_BT:
+ GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ break;
+ case V4L2_FIELD_INTERLACED:
+ GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ if (obj->tv_norm == V4L2_STD_NTSC_M ||
+ obj->tv_norm == V4L2_STD_NTSC_M_JP ||
+ obj->tv_norm == V4L2_STD_NTSC_M_KR)
+ {
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ }
+ else
+ {
+ GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ }
+ break;
+ default:
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
+ GST_FIXME_OBJECT (pool,
+ "Unhandled enum v4l2_field %d - treating as progressive",
+ group->buffer.field);
+ break;
+ }
+
+ if (GST_VIDEO_INFO_FORMAT (&obj->info) == GST_VIDEO_FORMAT_ENCODED)
+ {
+ if ((group->buffer.flags & V4L2_BUF_FLAG_KEYFRAME) ||
+ GST_AML_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_MJPEG ||
+ GST_AML_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_JPEG ||
+ GST_AML_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_PJPG)
+ GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+ else
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+ }
+
+ if (group->buffer.flags & V4L2_BUF_FLAG_ERROR)
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_CORRUPTED);
+
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+ GST_BUFFER_OFFSET (outbuf) = group->buffer.sequence;
+ GST_BUFFER_OFFSET_END (outbuf) = group->buffer.sequence + 1;
+
+done:
+ *buffer = outbuf;
+ if ((group->buffer.flags & V4L2_BUF_FLAG_LAST) &&(group->buffer.bytesused == 0))
+ {
+ GST_DEBUG_OBJECT (pool,"dequeued empty buffer");
+ GST_BUFFER_FLAG_SET(*buffer, GST_AML_V4L2_BUFFER_FLAG_LAST_EMPTY);
+ }
+
+ if (!V4L2_TYPE_IS_OUTPUT(obj->type))
+ {
+ gst_aml_v4l2_buffer_pool_dump_stat(pool, GST_DUMP_CAPTURE_BP_STAT_FILENAME, 0);
+ }
+
+ return res;
+
+ /* ERRORS */
+eos:
+ {
+ return GST_FLOW_EOS;
+ }
+dqbuf_failed:
+ {
+ return GST_FLOW_ERROR;
+ }
+no_buffer:
+ {
+ GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d.",
+ group->buffer.index);
+ return GST_FLOW_ERROR;
+ }
+}
+
+static GstFlowReturn
+gst_aml_v4l2_buffer_pool_dequeue (GstAmlV4l2BufferPool * pool, GstBuffer ** buffer,
+ gboolean wait)
+{
+ GstFlowReturn res;
+ GstAmlV4l2Object *obj = pool->obj;
+
+ if ((res = gst_aml_v4l2_buffer_pool_poll (pool, wait)) != GST_FLOW_OK)
+ goto poll_failed;
+
+ if (obj->can_wait_event && gst_poll_fd_can_read_pri (pool->poll, &pool->pollfd))
+ {
+ GstFlowReturn res_event = gst_aml_v4l2_buffer_pool_dqevent(pool);
+ if (res_event != GST_FLOW_OK)
+ {
+ /* when drive V4l2 receive cmd_stop, it will finish current decoding frame, then creat
+ * a EOS event and a empty buff. if gstreamer dq EOS event first ,the last frame will be drop,
+ * this a question
+ */
+ if (res_event == GST_AML_V4L2_FLOW_LAST_BUFFER)
+ {
+ GST_DEBUG_OBJECT(pool," reiceive EOS event, drop it");
+ }
+ else
+ return res_event;
+ }
+ }
+ if (res == GST_FLOW_CUSTOM_SUCCESS)
+ {
+ GST_LOG_OBJECT (pool, "nothing to dequeue");
+ *buffer = NULL;
+ return res;
+ }
+
+ GST_LOG_OBJECT (pool, "dequeueing a buffer");
+ return gst_aml_v4l2_buffer_pool_dqbuf(pool, buffer, wait);
+
+ /* ERRORS */
+poll_failed:
+ {
+ GST_DEBUG_OBJECT (pool, "poll error %s", gst_flow_get_name (res));
+ return res;
+ }
+}
+
+static GstFlowReturn
+gst_aml_v4l2_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
+ GstBufferPoolAcquireParams * params)
+{
+ GstFlowReturn ret;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (bpool);
+ GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
+ GstAmlV4l2Object *obj = pool->obj;
+
+ GST_DEBUG_OBJECT (pool, "acquire");
+
+ /* If this is being called to resurrect a lost buffer */
+ if (params && params->flags & GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT)
+ {
+ ret = pclass->acquire_buffer (bpool, buffer, params);
+ goto done;
+ }
+
+ switch (obj->type)
+ {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- /* capture, This function should return a buffer with new captured data */
- switch (obj->mode)
- {
+ /* capture, This function should return a buffer with new captured data */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
{
- /* take empty buffer from the pool */
- ret = pclass->acquire_buffer(bpool, buffer, params);
- break;
+ /* take empty buffer from the pool */
+ ret = pclass->acquire_buffer (bpool, buffer, params);
+ break;
}
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_USERPTR:
{
- /* just dequeue a buffer, we basically use the queue of v4l2 as the
- * storage for our buffers. This function does poll first so we can
- * interrupt it fine. */
- ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, TRUE);
+ /* just dequeue a buffer, we basically use the queue of v4l2 as the
+ * storage for our buffers. This function does poll first so we can
+ * interrupt it fine. */
+ ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, TRUE);
- break;
+ break;
}
case GST_V4L2_IO_DMABUF_IMPORT:
{
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- GST_DEBUG_OBJECT(pool, "amlmodbuf return free buf before acquire buf");
- gst_aml_v4l2_buffer_pool_release_buffer_aml_patch(bpool);
- ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, FALSE);
- GST_DEBUG_OBJECT(pool, "amlmodbuf dequeue return ret:%d", ret);
+ GST_DEBUG_OBJECT(pool, "amlmodbuf return free buf before acquire buf");
+ gst_aml_v4l2_buffer_pool_release_buffer_aml_patch(bpool);
+ ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, FALSE);
+ GST_DEBUG_OBJECT(pool, "amlmodbuf dequeue return ret:%d", ret);
#else
- /* just dequeue a buffer, we basically use the queue of v4l2 as the
- * storage for our buffers. This function does poll first so we can
- * interrupt it fine. */
- ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, TRUE);
+ /* just dequeue a buffer, we basically use the queue of v4l2 as the
+ * storage for our buffers. This function does poll first so we can
+ * interrupt it fine. */
+ ret = gst_aml_v4l2_buffer_pool_dequeue(pool, buffer, TRUE);
#endif
- break;
+ break;
}
default:
- ret = GST_FLOW_ERROR;
- g_assert_not_reached();
- break;
- }
- break;
+ ret = GST_FLOW_ERROR;
+ g_assert_not_reached ();
+ break;
+ }
+ break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- /* playback, This function should return an empty buffer */
- switch (obj->mode)
- {
+ /* playback, This function should return an empty buffer */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- /* get an empty buffer */
- ret = pclass->acquire_buffer(bpool, buffer, params);
- break;
+ /* get an empty buffer */
+ ret = pclass->acquire_buffer (bpool, buffer, params);
+ break;
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF_IMPORT:
- /* get a free unqueued buffer */
- ret = pclass->acquire_buffer(bpool, buffer, params);
- break;
+ /* get a free unqueued buffer */
+ ret = pclass->acquire_buffer (bpool, buffer, params);
+ break;
default:
- ret = GST_FLOW_ERROR;
- g_assert_not_reached();
- break;
- }
- break;
+ ret = GST_FLOW_ERROR;
+ g_assert_not_reached ();
+ break;
+ }
+ break;
default:
- ret = GST_FLOW_ERROR;
- g_assert_not_reached();
- break;
- }
+ ret = GST_FLOW_ERROR;
+ g_assert_not_reached ();
+ break;
+ }
done:
- return ret;
+ return ret;
}
static void
-gst_aml_v4l2_buffer_pool_release_buffer(GstBufferPool *bpool, GstBuffer *buffer)
+gst_aml_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
- GstAmlV4l2Object *obj = pool->obj;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (bpool);
+ GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
+ GstAmlV4l2Object *obj = pool->obj;
- GST_DEBUG_OBJECT(pool, "release buffer %p", buffer);
+ GST_DEBUG_OBJECT(pool, "release buffer %p", buffer);
- /* If the buffer's pool has been orphaned, dispose of it so that
- * the pool resources can be freed */
- if (pool->orphaned)
- {
- GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_TAG_MEMORY);
- pclass->release_buffer(bpool, buffer);
- return;
- }
+ /* If the buffer's pool has been orphaned, dispose of it so that
+ * the pool resources can be freed */
+ if (pool->orphaned)
+ {
+ GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_TAG_MEMORY);
+ pclass->release_buffer(bpool, buffer);
+ return;
+ }
- switch (obj->type)
- {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- /* capture, put the buffer back in the queue so that we can refill it
- * later. */
- switch (obj->mode)
- {
- case GST_V4L2_IO_RW:
- /* release back in the pool */
- pclass->release_buffer(bpool, buffer);
- break;
+ switch (obj->type)
+ {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ /* capture, put the buffer back in the queue so that we can refill it
+ * later. */
+ switch (obj->mode)
+ {
+ case GST_V4L2_IO_RW:
+ /* release back in the pool */
+ pclass->release_buffer(bpool, buffer);
+ break;
- case GST_V4L2_IO_DMABUF:
- case GST_V4L2_IO_MMAP:
- case GST_V4L2_IO_USERPTR:
- case GST_V4L2_IO_DMABUF_IMPORT:
- {
- GstAmlV4l2MemoryGroup *group;
- if (gst_aml_v4l2_is_buffer_valid(buffer, &group))
- {
- GstFlowReturn ret = GST_FLOW_OK;
+ case GST_V4L2_IO_DMABUF:
+ case GST_V4L2_IO_MMAP:
+ case GST_V4L2_IO_USERPTR:
+ case GST_V4L2_IO_DMABUF_IMPORT:
+ {
+ GstAmlV4l2MemoryGroup *group;
+ if (gst_aml_v4l2_is_buffer_valid(buffer, &group))
+ {
+ GstFlowReturn ret = GST_FLOW_OK;
- gst_aml_v4l2_allocator_reset_group(pool->vallocator, group);
+ gst_aml_v4l2_allocator_reset_group(pool->vallocator, group);
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- GST_DEBUG_OBJECT(pool, "amlmodbuf trace in add flow with buf:%p index:%d", buffer, group->buffer.index);
- pool->read_to_free_bufs[group->buffer.index] = buffer;
- pool->ready_to_free_buf_num++;
- if (gst_aml_v4l2_buffer_pool_release_buffer_aml_patch(bpool))
- {
- GST_DEBUG_OBJECT(pool, "amlmodbuf execute aml code logic, skip the following flow");
- return;
- }
+ GST_DEBUG_OBJECT(pool, "amlmodbuf trace in add flow with buf:%p index:%d", buffer, group->buffer.index);
+ pool->read_to_free_bufs[group->buffer.index] = buffer;
+ pool->ready_to_free_buf_num++;
+ if (gst_aml_v4l2_buffer_pool_release_buffer_aml_patch(bpool))
+ {
+ GST_DEBUG_OBJECT(pool, "amlmodbuf execute aml code logic, skip the following flow");
+ return;
+ }
#endif
- /* queue back in the device */
- if (pool->other_pool)
- ret = gst_aml_v4l2_buffer_pool_prepare_buffer(pool, buffer, NULL);
- if (ret != GST_FLOW_OK ||
- gst_aml_v4l2_buffer_pool_qbuf(pool, buffer, group) != GST_FLOW_OK)
- pclass->release_buffer(bpool, buffer);
- }
- else
- {
- /* Simply release invalide/modified buffer, the allocator will
- * give it back later */
- GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_TAG_MEMORY);
- pclass->release_buffer(bpool, buffer);
- }
- break;
- }
- default:
- g_assert_not_reached();
- break;
- }
- break;
+ /* queue back in the device */
+ if (pool->other_pool)
+ ret = gst_aml_v4l2_buffer_pool_prepare_buffer(pool, buffer, NULL);
+ if (ret != GST_FLOW_OK ||
+ gst_aml_v4l2_buffer_pool_qbuf(pool, buffer, group) != GST_FLOW_OK)
+ pclass->release_buffer(bpool, buffer);
+ }
+ else
+ {
+ /* Simply release invalide/modified buffer, the allocator will
+ * give it back later */
+ GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_TAG_MEMORY);
+ pclass->release_buffer(bpool, buffer);
+ }
+ break;
+ }
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- switch (obj->mode)
- {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
/* release back in the pool */
pclass->release_buffer(bpool, buffer);
@@ -2097,228 +2103,228 @@
}
default:
- g_assert_not_reached();
- break;
- }
- break;
+ g_assert_not_reached ();
+ break;
+ }
+ break;
default:
- g_assert_not_reached();
- break;
- }
+ g_assert_not_reached ();
+ break;
+ }
}
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
static gboolean
gst_aml_v4l2_buffer_pool_release_buffer_aml_patch(GstBufferPool *bpool)
{
- GstFlowReturn ret = GST_FLOW_OK;
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
- GstAmlV4l2Object *obj = pool->obj;
- GstBuffer *src = NULL;
- GstBufferPoolAcquireParams params;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS(parent_class);
+ GstAmlV4l2Object *obj = pool->obj;
+ GstBuffer *src = NULL;
+ GstBufferPoolAcquireParams params;
- if (!(obj->mode == GST_V4L2_IO_DMABUF_IMPORT && pool->other_pool))
- {
- GST_WARNING_OBJECT(pool,"please check GstV4l2IOMode!");
- return FALSE;
- }
+ if (!(obj->mode == GST_V4L2_IO_DMABUF_IMPORT && pool->other_pool))
+ {
+ GST_WARNING_OBJECT(pool,"please check GstV4l2IOMode!");
+ return FALSE;
+ }
- /*resolution change flow start*/
- if (obj->old_other_pool || obj->old_old_other_pool)
- {
- gint outstanding_buf_num = 0;
+ /*resolution change flow start*/
+ if (obj->old_other_pool || obj->old_old_other_pool)
+ {
+ gint outstanding_buf_num = 0;
- outstanding_buf_num = gst_aml_v4l2_object_get_outstanding_capture_buf_num(obj);
- GST_DEBUG_OBJECT(pool, "amlmodbuf oop outstanding buf num %d", outstanding_buf_num);
- if (outstanding_buf_num != obj->outstanding_buf_num)
- {
- guint update = 0, need_buf_num = 0;
- GstStructure *config = NULL;
- guint size, min_buffers = 0, old_max_buffers = 0;
+ outstanding_buf_num = gst_aml_v4l2_object_get_outstanding_capture_buf_num(obj);
+ GST_DEBUG_OBJECT(pool, "amlmodbuf oop outstanding buf num %d", outstanding_buf_num);
+ if (outstanding_buf_num != obj->outstanding_buf_num)
+ {
+ guint update = 0, need_buf_num = 0;
+ GstStructure *config = NULL;
+ guint size, min_buffers = 0, old_max_buffers = 0;
- if (outstanding_buf_num > obj->outstanding_buf_num)
- {
- GST_ERROR_OBJECT(pool, "amlmodbuf old other pool recycle buffer error, outstanding from %d to %d", obj->outstanding_buf_num, outstanding_buf_num);
- return FALSE;
- }
- GST_DEBUG_OBJECT(pool, "amlmodbuf oop outstanding buf num from %d reduce to %d", obj->outstanding_buf_num, outstanding_buf_num);
+ if (outstanding_buf_num > obj->outstanding_buf_num)
+ {
+ GST_ERROR_OBJECT(pool, "amlmodbuf old other pool recycle buffer error, outstanding from %d to %d", obj->outstanding_buf_num, outstanding_buf_num);
+ return FALSE;
+ }
+ GST_DEBUG_OBJECT(pool, "amlmodbuf oop outstanding buf num from %d reduce to %d", obj->outstanding_buf_num, outstanding_buf_num);
- /*get buffer pool config to calculate max buffer count*/
- config = gst_buffer_pool_get_config(pool->other_pool);
- if (config)
- {
- if (gst_buffer_pool_config_get_params(config, NULL, &size, &min_buffers, &old_max_buffers) != FALSE)
- {
- if (G_UNLIKELY(obj->min_buffers < old_max_buffers))
- {
- GST_ERROR("Too many drm buffers are applied");
- }
- else if (obj->min_buffers == old_max_buffers)
- {
- update = 0;
- }
- else if (obj->min_buffers > old_max_buffers)
- {
- GST_INFO("display occupy: %d,total num of buffer rotations: %u op have set max buf: %u",
- outstanding_buf_num,
- obj->min_buffers,
- old_max_buffers);
- update = obj->outstanding_buf_num - outstanding_buf_num; // available buf num
- need_buf_num = obj->min_buffers - old_max_buffers; //need buf num
- update = need_buf_num >= update ? update : need_buf_num;
- }
- }
- }
- if (update > 0 && !gst_buffer_pool_increase_max_num(pool->other_pool, update))
- {
- GST_ERROR_OBJECT(pool, "amlmodbuf update other pool max buffer num error");
- return FALSE;
- }
- obj->outstanding_buf_num = outstanding_buf_num;
- }
- }
- /*resolution change flow stop*/
+ /*get buffer pool config to calculate max buffer count*/
+ config = gst_buffer_pool_get_config(pool->other_pool);
+ if (config)
+ {
+ if (gst_buffer_pool_config_get_params(config, NULL, &size, &min_buffers, &old_max_buffers) != FALSE)
+ {
+ if (G_UNLIKELY(obj->min_buffers < old_max_buffers))
+ {
+ GST_ERROR("Too many drm buffers are applied");
+ }
+ else if (obj->min_buffers == old_max_buffers)
+ {
+ update = 0;
+ }
+ else if (obj->min_buffers > old_max_buffers)
+ {
+ GST_INFO("display occupy: %d,total num of buffer rotations: %u op have set max buf: %u",
+ outstanding_buf_num,
+ obj->min_buffers,
+ old_max_buffers);
+ update = obj->outstanding_buf_num - outstanding_buf_num; // available buf num
+ need_buf_num = obj->min_buffers - old_max_buffers; //need buf num
+ update = need_buf_num >= update ? update : need_buf_num;
+ }
+ }
+ }
+ if (update > 0 && !gst_buffer_pool_increase_max_num(pool->other_pool, update))
+ {
+ GST_ERROR_OBJECT(pool, "amlmodbuf update other pool max buffer num error");
+ return FALSE;
+ }
+ obj->outstanding_buf_num = outstanding_buf_num;
+ }
+ }
+ /*resolution change flow stop*/
- /*buffer match flow*/
- memset(¶ms, 0, sizeof(GstBufferPoolAcquireParams));
- params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
- GST_TRACE_OBJECT(pool, "before release ready_to_free_buf_num:%d", pool->ready_to_free_buf_num);
- while (pool->ready_to_free_buf_num && gst_buffer_pool_acquire_buffer(pool->other_pool, &src, ¶ms) != GST_FLOW_ERROR && src != NULL)
- {
- gint i = 0;
+ /*buffer match flow*/
+ memset(¶ms, 0, sizeof(GstBufferPoolAcquireParams));
+ params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
+ GST_TRACE_OBJECT(pool, "before release ready_to_free_buf_num:%d", pool->ready_to_free_buf_num);
+ while (pool->ready_to_free_buf_num && gst_buffer_pool_acquire_buffer(pool->other_pool, &src, ¶ms) != GST_FLOW_ERROR && src != NULL)
+ {
+ gint i = 0;
- for (; i < VIDEO_MAX_FRAME; i++)
- {
- GST_TRACE_OBJECT(pool, "amlmodbuf check index:%d", i);
- if (pool->read_to_free_bufs[i])
- {
- GstBuffer *bind_drm_buf = gst_mini_object_get_qdata(GST_MINI_OBJECT(pool->read_to_free_bufs[i]), GST_AML_V4L2_IMPORT_QUARK);
- if (bind_drm_buf == NULL)
- {
- GST_DEBUG_OBJECT(pool, "init flow, bind v4l2 capture buf[%d]:%p with drm buf:%p", i, pool->read_to_free_bufs[i], src);
- }
- else if (src != bind_drm_buf)
- {
- continue;
- }
+ for (; i < VIDEO_MAX_FRAME; i++)
+ {
+ GST_TRACE_OBJECT(pool, "amlmodbuf check index:%d", i);
+ if (pool->read_to_free_bufs[i])
+ {
+ GstBuffer *bind_drm_buf = gst_mini_object_get_qdata(GST_MINI_OBJECT(pool->read_to_free_bufs[i]), GST_AML_V4L2_IMPORT_QUARK);
+ if (bind_drm_buf == NULL)
+ {
+ GST_DEBUG_OBJECT(pool, "init flow, bind v4l2 capture buf[%d]:%p with drm buf:%p", i, pool->read_to_free_bufs[i], src);
+ }
+ else if (src != bind_drm_buf)
+ {
+ continue;
+ }
- GST_TRACE_OBJECT(pool, "v4l2 capture buf[%d]:%p found bind drm buf:%p", i, pool->read_to_free_bufs[i], src);
- GstFlowReturn isvalid = GST_FLOW_OK;
- GstAmlV4l2MemoryGroup *tmp_group = NULL;
+ GST_TRACE_OBJECT(pool, "v4l2 capture buf[%d]:%p found bind drm buf:%p", i, pool->read_to_free_bufs[i], src);
+ GstFlowReturn isvalid = GST_FLOW_OK;
+ GstAmlV4l2MemoryGroup *tmp_group = NULL;
- // bind_drm_buf= gst_mini_object_steal_qdata(GST_MINI_OBJECT(pool->read_to_free_bufs[i]), GST_AML_V4L2_IMPORT_QUARK);
- ret = gst_aml_v4l2_buffer_pool_import_dmabuf(pool, pool->read_to_free_bufs[i], src);
- gst_buffer_unref(src);
- src = NULL;
- isvalid = gst_aml_v4l2_is_buffer_valid(pool->read_to_free_bufs[i], &tmp_group);
- if ((ret != GST_FLOW_OK && isvalid) || gst_aml_v4l2_buffer_pool_qbuf(pool, pool->read_to_free_bufs[i], tmp_group) != GST_FLOW_OK)
- {
- GST_ERROR_OBJECT(pool, "amlmodbuf go into error flow");
- pclass->release_buffer(bpool, pool->read_to_free_bufs[i]);
- }
- pool->read_to_free_bufs[i] = NULL;
- pool->ready_to_free_buf_num--;
- break;
- }
- }
- if (i == VIDEO_MAX_FRAME)
- {
- GST_ERROR_OBJECT(pool, "drm buf:%p can't match any v4l2 capture buf, error", src);
- gst_buffer_unref(src);
- src = NULL;
- return FALSE;
- }
- }
- GST_TRACE_OBJECT(pool, "after release ready_to_free_buf_num:%d", pool->ready_to_free_buf_num);
- return TRUE;
+ // bind_drm_buf= gst_mini_object_steal_qdata(GST_MINI_OBJECT(pool->read_to_free_bufs[i]), GST_AML_V4L2_IMPORT_QUARK);
+ ret = gst_aml_v4l2_buffer_pool_import_dmabuf(pool, pool->read_to_free_bufs[i], src);
+ gst_buffer_unref(src);
+ src = NULL;
+ isvalid = gst_aml_v4l2_is_buffer_valid(pool->read_to_free_bufs[i], &tmp_group);
+ if ((ret != GST_FLOW_OK && isvalid) || gst_aml_v4l2_buffer_pool_qbuf(pool, pool->read_to_free_bufs[i], tmp_group) != GST_FLOW_OK)
+ {
+ GST_ERROR_OBJECT(pool, "amlmodbuf go into error flow");
+ pclass->release_buffer(bpool, pool->read_to_free_bufs[i]);
+ }
+ pool->read_to_free_bufs[i] = NULL;
+ pool->ready_to_free_buf_num--;
+ break;
+ }
+ }
+ if (i == VIDEO_MAX_FRAME)
+ {
+ GST_ERROR_OBJECT(pool, "drm buf:%p can't match any v4l2 capture buf, error", src);
+ gst_buffer_unref(src);
+ src = NULL;
+ return FALSE;
+ }
+ }
+ GST_TRACE_OBJECT(pool, "after release ready_to_free_buf_num:%d", pool->ready_to_free_buf_num);
+ return TRUE;
}
#endif
static void
-gst_aml_v4l2_buffer_pool_dispose(GObject *object)
+gst_aml_v4l2_buffer_pool_dispose (GObject * object)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(object);
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (object);
- if (pool->vallocator)
- gst_object_unref(pool->vallocator);
- pool->vallocator = NULL;
+ if (pool->vallocator)
+ gst_object_unref (pool->vallocator);
+ pool->vallocator = NULL;
- if (pool->allocator)
- gst_object_unref(pool->allocator);
- pool->allocator = NULL;
+ if (pool->allocator)
+ gst_object_unref (pool->allocator);
+ pool->allocator = NULL;
- if (pool->other_pool)
- gst_object_unref(pool->other_pool);
- pool->other_pool = NULL;
+ if (pool->other_pool)
+ gst_object_unref (pool->other_pool);
+ pool->other_pool = NULL;
- G_OBJECT_CLASS(parent_class)->dispose(object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-gst_aml_v4l2_buffer_pool_finalize(GObject *object)
+gst_aml_v4l2_buffer_pool_finalize (GObject * object)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(object);
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL (object);
- if (g_list_length (pool->cc_buffer_list) > 0)
- {
- g_list_free_full (pool->cc_buffer_list, (GDestroyNotify) gst_buffer_unref);
- pool->cc_buffer_list = NULL;
- }
-
- if (pool->video_fd >= 0)
- pool->obj->close(pool->video_fd);
-
- gst_poll_free(pool->poll);
-
- /* This can't be done in dispose method because we must not set pointer
- * to NULL as it is part of the v4l2object and dispose could be called
- * multiple times */
- gst_object_unref(pool->obj->element);
-
- g_cond_clear(&pool->empty_cond);
-
- /* FIXME have we done enough here ? */
-
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-static void
-gst_aml_v4l2_buffer_pool_init(GstAmlV4l2BufferPool *pool)
-{
- pool->poll = gst_poll_new(TRUE);
- pool->can_poll_device = TRUE;
- g_cond_init(&pool->empty_cond);
- GST_OBJECT_LOCK(pool);
- pool->empty = TRUE;
- GST_OBJECT_UNLOCK(pool);
- pool->orphaned = FALSE;
+ if (g_list_length (pool->cc_buffer_list) > 0)
+ {
+ g_list_free_full (pool->cc_buffer_list, (GDestroyNotify) gst_buffer_unref);
pool->cc_buffer_list = NULL;
+ }
+
+ if (pool->video_fd >= 0)
+ pool->obj->close (pool->video_fd);
+
+ gst_poll_free (pool->poll);
+
+ /* This can't be done in dispose method because we must not set pointer
+ * to NULL as it is part of the v4l2object and dispose could be called
+ * multiple times */
+ gst_object_unref (pool->obj->element);
+
+ g_cond_clear (&pool->empty_cond);
+
+ /* FIXME have we done enough here ? */
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-gst_aml_v4l2_buffer_pool_class_init(GstAmlV4l2BufferPoolClass *klass)
+gst_aml_v4l2_buffer_pool_init (GstAmlV4l2BufferPool * pool)
{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
- GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS(klass);
+ pool->poll = gst_poll_new (TRUE);
+ pool->can_poll_device = TRUE;
+ g_cond_init (&pool->empty_cond);
+ GST_OBJECT_LOCK(pool);
+ pool->empty = TRUE;
+ GST_OBJECT_UNLOCK(pool);
+ pool->orphaned = FALSE;
+ pool->cc_buffer_list = NULL;
+}
- object_class->dispose = gst_aml_v4l2_buffer_pool_dispose;
- object_class->finalize = gst_aml_v4l2_buffer_pool_finalize;
+static void
+gst_aml_v4l2_buffer_pool_class_init (GstAmlV4l2BufferPoolClass * klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass);
- bufferpool_class->start = gst_aml_v4l2_buffer_pool_start;
- bufferpool_class->stop = gst_aml_v4l2_buffer_pool_stop;
- bufferpool_class->set_config = gst_aml_v4l2_buffer_pool_set_config;
- bufferpool_class->alloc_buffer = gst_aml_v4l2_buffer_pool_alloc_buffer;
- bufferpool_class->acquire_buffer = gst_aml_v4l2_buffer_pool_acquire_buffer;
- bufferpool_class->release_buffer = gst_aml_v4l2_buffer_pool_release_buffer;
- bufferpool_class->flush_start = gst_aml_v4l2_buffer_pool_flush_start;
- bufferpool_class->flush_stop = gst_aml_v4l2_buffer_pool_flush_stop;
+ object_class->dispose = gst_aml_v4l2_buffer_pool_dispose;
+ object_class->finalize = gst_aml_v4l2_buffer_pool_finalize;
- GST_DEBUG_CATEGORY_INIT(amlv4l2bufferpool_debug, "amlv4l2bufferpool", 0,
- "V4L2 Buffer Pool");
- GST_DEBUG_CATEGORY_GET(CAT_PERFORMANCE, "GST_PERFORMANCE");
+ bufferpool_class->start = gst_aml_v4l2_buffer_pool_start;
+ bufferpool_class->stop = gst_aml_v4l2_buffer_pool_stop;
+ bufferpool_class->set_config = gst_aml_v4l2_buffer_pool_set_config;
+ bufferpool_class->alloc_buffer = gst_aml_v4l2_buffer_pool_alloc_buffer;
+ bufferpool_class->acquire_buffer = gst_aml_v4l2_buffer_pool_acquire_buffer;
+ bufferpool_class->release_buffer = gst_aml_v4l2_buffer_pool_release_buffer;
+ bufferpool_class->flush_start = gst_aml_v4l2_buffer_pool_flush_start;
+ bufferpool_class->flush_stop = gst_aml_v4l2_buffer_pool_flush_stop;
+
+ GST_DEBUG_CATEGORY_INIT (amlv4l2bufferpool_debug, "amlv4l2bufferpool", 0,
+ "V4L2 Buffer Pool");
+ GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE");
}
/**
@@ -2330,142 +2336,141 @@
* Returns: the new pool, use gst_object_unref() to free resources
*/
GstBufferPool *
-gst_aml_v4l2_buffer_pool_new(GstAmlV4l2Object *obj, GstCaps *caps)
+gst_aml_v4l2_buffer_pool_new (GstAmlV4l2Object * obj, GstCaps * caps)
{
- GstAmlV4l2BufferPool *pool;
- GstStructure *config;
- gchar *name, *parent_name;
- gint fd;
+ GstAmlV4l2BufferPool *pool;
+ GstStructure *config;
+ gchar *name, *parent_name;
+ gint fd;
- fd = obj->dup(obj->video_fd);
- if (fd < 0)
- goto dup_failed;
+ fd = obj->dup (obj->video_fd);
+ if (fd < 0)
+ goto dup_failed;
- /* setting a significant unique name */
- parent_name = gst_object_get_name(GST_OBJECT(obj->element));
- name = g_strconcat(parent_name, ":", "pool:",
- V4L2_TYPE_IS_OUTPUT(obj->type) ? "sink" : "src", NULL);
- g_free(parent_name);
+ /* setting a significant unique name */
+ parent_name = gst_object_get_name (GST_OBJECT (obj->element));
+ name = g_strconcat(parent_name, ":", "pool:",
+ V4L2_TYPE_IS_OUTPUT(obj->type) ? "sink" : "src", NULL);
+ g_free (parent_name);
- pool = (GstAmlV4l2BufferPool *)g_object_new(GST_TYPE_AML_V4L2_BUFFER_POOL,
- "name", name, NULL);
- g_object_ref_sink(pool);
- g_free(name);
+ pool = (GstAmlV4l2BufferPool *) g_object_new (GST_TYPE_AML_V4L2_BUFFER_POOL,
+ "name", name, NULL);
+ g_object_ref_sink (pool);
+ g_free (name);
- gst_poll_fd_init(&pool->pollfd);
- pool->pollfd.fd = fd;
- gst_poll_add_fd(pool->poll, &pool->pollfd);
- if (V4L2_TYPE_IS_OUTPUT(obj->type))
- {
- gst_poll_fd_ctl_write(pool->poll, &pool->pollfd, TRUE);
- }
- else
- {
- gst_poll_fd_ctl_read(pool->poll, &pool->pollfd, TRUE);
- gst_poll_fd_ctl_pri (pool->poll, &pool->pollfd, TRUE);
- }
+ gst_poll_fd_init (&pool->pollfd);
+ pool->pollfd.fd = fd;
+ gst_poll_add_fd (pool->poll, &pool->pollfd);
+ if (V4L2_TYPE_IS_OUTPUT (obj->type))
+ {
+ gst_poll_fd_ctl_write (pool->poll, &pool->pollfd, TRUE);
+ }
+ else
+ {
+ gst_poll_fd_ctl_read (pool->poll, &pool->pollfd, TRUE);
+ gst_poll_fd_ctl_pri (pool->poll, &pool->pollfd, TRUE);
+ }
- pool->video_fd = fd;
- pool->obj = obj;
- pool->can_poll_device = TRUE;
+ pool->video_fd = fd;
+ pool->obj = obj;
+ pool->can_poll_device = TRUE;
- pool->vallocator = gst_aml_v4l2_allocator_new(GST_OBJECT(pool), obj);
- if (pool->vallocator == NULL)
- goto allocator_failed;
+ pool->vallocator = gst_aml_v4l2_allocator_new (GST_OBJECT (pool), obj);
+ if (pool->vallocator == NULL)
+ goto allocator_failed;
- gst_object_ref(obj->element);
+ gst_object_ref (obj->element);
- config = gst_buffer_pool_get_config(GST_BUFFER_POOL_CAST(pool));
- gst_buffer_pool_config_set_params(config, caps, obj->info.size, 0, 0);
- /* This will simply set a default config, but will not configure the pool
- * because min and max are not valid */
- (void)gst_buffer_pool_set_config(GST_BUFFER_POOL_CAST(pool), config);
+ config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
+ gst_buffer_pool_config_set_params (config, caps, obj->info.size, 0, 0);
+ /* This will simply set a default config, but will not configure the pool
+ * because min and max are not valid */
+ (void)gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST(pool), config);
- return GST_BUFFER_POOL(pool);
+ return GST_BUFFER_POOL (pool);
- /* ERRORS */
+ /* ERRORS */
dup_failed:
-{
- GST_ERROR("failed to dup fd %d (%s)", errno, g_strerror(errno));
+ {
+ GST_ERROR ("failed to dup fd %d (%s)", errno, g_strerror (errno));
return NULL;
-}
+ }
allocator_failed:
-{
- GST_ERROR_OBJECT(pool, "Failed to create V4L2 allocator");
- gst_object_unref(pool);
+ {
+ GST_ERROR_OBJECT (pool, "Failed to create V4L2 allocator");
+ gst_object_unref (pool);
return NULL;
-}
+ }
}
static GstFlowReturn
-gst_aml_v4l2_do_read(GstAmlV4l2BufferPool *pool, GstBuffer *buf)
+gst_aml_v4l2_do_read (GstAmlV4l2BufferPool * pool, GstBuffer * buf)
{
- GstFlowReturn res;
- GstAmlV4l2Object *obj = pool->obj;
- gint amount;
- GstMapInfo map;
- gint toread;
+ GstFlowReturn res;
+ GstAmlV4l2Object *obj = pool->obj;
+ gint amount;
+ GstMapInfo map;
+ gint toread;
- toread = obj->info.size;
+ toread = obj->info.size;
- GST_LOG_OBJECT(pool, "reading %d bytes into buffer %p", toread, buf);
+ GST_LOG_OBJECT (pool, "reading %d bytes into buffer %p", toread, buf);
- gst_buffer_map(buf, &map, GST_MAP_WRITE);
+ gst_buffer_map (buf, &map, GST_MAP_WRITE);
- do
+ do
+ {
+ if ((res = gst_aml_v4l2_buffer_pool_poll (pool, TRUE)) != GST_FLOW_OK)
+ goto poll_error;
+
+ amount = obj->read (obj->video_fd, map.data, toread);
+
+ if (amount == toread)
{
- if ((res = gst_aml_v4l2_buffer_pool_poll(pool, TRUE)) != GST_FLOW_OK)
- goto poll_error;
+ break;
+ }
+ else if (amount == -1)
+ {
+ if (errno == EAGAIN || errno == EINTR)
+ {
+ continue;
+ }
+ else
+ goto read_error;
+ }
+ else
+ {
+ /* short reads can happen if a signal interrupts the read */
+ continue;
+ }
+ } while (TRUE);
- amount = obj->read(obj->video_fd, map.data, toread);
+ GST_LOG_OBJECT (pool, "read %d bytes", amount);
+ gst_buffer_unmap (buf, &map);
+ gst_buffer_resize (buf, 0, amount);
- if (amount == toread)
- {
- break;
- }
- else if (amount == -1)
- {
- if (errno == EAGAIN || errno == EINTR)
- {
- continue;
- }
- else
- goto read_error;
- }
- else
- {
- /* short reads can happen if a signal interrupts the read */
- continue;
- }
- } while (TRUE);
+ return GST_FLOW_OK;
- GST_LOG_OBJECT(pool, "read %d bytes", amount);
- gst_buffer_unmap(buf, &map);
- gst_buffer_resize(buf, 0, amount);
-
- return GST_FLOW_OK;
-
- /* ERRORS */
+ /* ERRORS */
poll_error:
-{
- GST_DEBUG("poll error %s", gst_flow_get_name(res));
+ {
+ GST_DEBUG ("poll error %s", gst_flow_get_name (res));
goto cleanup;
-}
+ }
read_error:
-{
- GST_ELEMENT_ERROR(obj->element, RESOURCE, READ,
- (_("Error reading %d bytes from device '%s'."),
- toread, obj->videodev),
- GST_ERROR_SYSTEM);
+ {
+ GST_ELEMENT_ERROR (obj->element, RESOURCE, READ,
+ (_("Error reading %d bytes from device '%s'."),
+ toread, obj->videodev), GST_ERROR_SYSTEM);
res = GST_FLOW_ERROR;
goto cleanup;
-}
+ }
cleanup:
-{
- gst_buffer_unmap(buf, &map);
- gst_buffer_resize(buf, 0, 0);
+ {
+ gst_buffer_unmap (buf, &map);
+ gst_buffer_resize (buf, 0, 0);
return res;
-}
+ }
}
/**
@@ -2482,386 +2487,388 @@
GstFlowReturn
gst_aml_v4l2_buffer_pool_process(GstAmlV4l2BufferPool *pool, GstBuffer **buf)
{
- GstFlowReturn ret = GST_FLOW_OK;
- GstBufferPool *bpool = GST_BUFFER_POOL_CAST(pool);
- GstAmlV4l2Object *obj = pool->obj;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstBufferPool *bpool = GST_BUFFER_POOL_CAST (pool);
+ GstAmlV4l2Object *obj = pool->obj;
- GST_DEBUG_OBJECT(pool, "process buffer %p, buf_pool:%p, v4l2 output pool:%p", *buf, (*buf)->pool, bpool);
+ GST_DEBUG_OBJECT(pool, "process buffer %p, buf_pool:%p, v4l2 output pool:%p", *buf, (*buf)->pool, bpool);
- if (GST_BUFFER_POOL_IS_FLUSHING(pool))
- return GST_FLOW_FLUSHING;
+ if (GST_BUFFER_POOL_IS_FLUSHING (pool))
+ return GST_FLOW_FLUSHING;
- switch (obj->type)
- {
+ switch (obj->type)
+ {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- /* capture */
- switch (obj->mode)
- {
+ /* capture */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- /* capture into the buffer */
- ret = gst_aml_v4l2_do_read(pool, *buf);
- break;
+ /* capture into the buffer */
+ ret = gst_aml_v4l2_do_read (pool, *buf);
+ break;
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
{
- GstBuffer *tmp;
+ GstBuffer *tmp;
- if ((*buf)->pool == bpool)
+ if ((*buf)->pool == bpool)
+ {
+ guint num_queued;
+ gsize size = gst_buffer_get_size (*buf);
+
+ /* Legacy M2M devices return empty buffer when drained */
+ if (size == 0 && GST_AML_V4L2_IS_M2M(obj->device_caps))
+ goto eos;
+
+ if (GST_VIDEO_INFO_FORMAT (&pool->caps_info) !=
+ GST_VIDEO_FORMAT_ENCODED && size < pool->size)
+ goto buffer_truncated;
+
+ num_queued = g_atomic_int_get (&pool->num_queued);
+ GST_TRACE_OBJECT (pool, "Only %i buffer left in the capture queue.",
+ num_queued);
+
+ /* If we have no more buffer, and can allocate it time to do so */
+ if (num_queued == 0)
{
- guint num_queued;
- gsize size = gst_buffer_get_size(*buf);
-
- /* Legacy M2M devices return empty buffer when drained */
- if (size == 0 && GST_AML_V4L2_IS_M2M(obj->device_caps))
- goto eos;
-
- if (GST_VIDEO_INFO_FORMAT(&pool->caps_info) !=
- GST_VIDEO_FORMAT_ENCODED &&
- size < pool->size)
- goto buffer_truncated;
-
- num_queued = g_atomic_int_get(&pool->num_queued);
- GST_TRACE_OBJECT(pool, "Only %i buffer left in the capture queue.",
- num_queued);
-
- /* If we have no more buffer, and can allocate it time to do so */
- if (num_queued == 0)
- {
- if (GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP))
- {
- ret = gst_aml_v4l2_buffer_pool_resurrect_buffer(pool);
- if (ret == GST_FLOW_OK)
- goto done;
- }
- }
-
- /* start copying buffers when we are running low on buffers */
- if (num_queued < pool->copy_threshold)
- {
- GstBuffer *copy;
-
- if (GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE(pool->vallocator, MMAP))
- {
- ret = gst_aml_v4l2_buffer_pool_resurrect_buffer(pool);
- if (ret == GST_FLOW_OK)
- goto done;
- }
-
- /* copy the buffer */
- copy = gst_buffer_copy_region(*buf,
- GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1);
- GST_LOG_OBJECT(pool, "copy buffer %p->%p", *buf, copy);
-
- /* and requeue so that we can continue capturing */
- gst_buffer_unref(*buf);
- *buf = copy;
- }
-
- ret = GST_FLOW_OK;
- /* nothing, data was inside the buffer when we did _acquire() */
- goto done;
+ if (GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP))
+ {
+ ret = gst_aml_v4l2_buffer_pool_resurrect_buffer (pool);
+ if (ret == GST_FLOW_OK)
+ goto done;
+ }
}
- /* buffer not from our pool, grab a frame and copy it into the target */
- if ((ret = gst_aml_v4l2_buffer_pool_dequeue(pool, &tmp, TRUE)) != GST_FLOW_OK)
- goto done;
-
- if (obj->dumpframefile)
+ /* start copying buffers when we are running low on buffers */
+ if (num_queued < pool->copy_threshold)
{
- FILE *pFile = fopen(obj->dumpframefile, "ab");
- if (pFile)
- {
- int n = gst_buffer_n_memory(tmp);
- int i;
- GstMapInfo map_info;
- GstMemory *mem;
+ GstBuffer *copy;
- for (i = 0; i < n; ++i)
- {
- mem = gst_buffer_peek_memory(tmp, i);
- if (gst_memory_map(mem, &map_info, GST_MAP_READ))
- {
- fwrite(map_info.data, map_info.size, 1, pFile);
- gst_memory_unmap(mem, &map_info);
- }
- }
- fclose(pFile);
- }
- }
- /* An empty buffer on capture indicates the end of stream */
- if (gst_buffer_get_size(tmp) == 0)
- {
- gst_aml_v4l2_buffer_pool_release_buffer(bpool, tmp);
+ if (GST_AML_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP))
+ {
+ ret = gst_aml_v4l2_buffer_pool_resurrect_buffer (pool);
+ if (ret == GST_FLOW_OK)
+ goto done;
+ }
- /* Legacy M2M devices return empty buffer when drained */
- if (GST_AML_V4L2_IS_M2M(obj->device_caps))
- goto eos;
+ /* copy the buffer */
+ copy = gst_buffer_copy_region (*buf,
+ GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1);
+ GST_LOG_OBJECT (pool, "copy buffer %p->%p", *buf, copy);
+
+ /* and requeue so that we can continue capturing */
+ gst_buffer_unref (*buf);
+ *buf = copy;
}
- ret = gst_aml_v4l2_buffer_pool_copy_buffer(pool, *buf, tmp);
- if (obj->mode == GST_V4L2_IO_DMABUF && (GST_VIDEO_FORMAT_NV12 == pool->caps_info.finfo->format || GST_VIDEO_FORMAT_NV21 == pool->caps_info.finfo->format) && gst_buffer_get_size (*buf) > (pool->caps_info.width * pool->caps_info.height * 3 / 2))
- {
- GST_DEBUG_OBJECT (pool, "resizebuf. format:%d [%d, %d] W:%d, H:%d", pool->caps_info.finfo->format, GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV21, pool->caps_info.width, pool->caps_info.height);
- gst_buffer_resize (*buf, 0, pool->caps_info.width * pool->caps_info.height * 3 / 2);
- }
+ ret = GST_FLOW_OK;
+ /* nothing, data was inside the buffer when we did _acquire() */
+ goto done;
+ }
+ /* buffer not from our pool, grab a frame and copy it into the target */
+ if ((ret = gst_aml_v4l2_buffer_pool_dequeue (pool, &tmp, TRUE))
+ != GST_FLOW_OK)
+ goto done;
- /* an queue the buffer again after the copy */
+ if (obj->dumpframefile)
+ {
+ FILE *pFile = fopen(obj->dumpframefile, "ab");
+ if (pFile)
+ {
+ int n = gst_buffer_n_memory(tmp);
+ int i;
+ GstMapInfo map_info;
+ GstMemory *mem;
+
+ for (i = 0; i < n; ++i)
+ {
+ mem = gst_buffer_peek_memory(tmp, i);
+ if (gst_memory_map(mem, &map_info, GST_MAP_READ))
+ {
+ fwrite(map_info.data, map_info.size, 1, pFile);
+ gst_memory_unmap(mem, &map_info);
+ }
+ }
+ fclose(pFile);
+ }
+ }
+ /* An empty buffer on capture indicates the end of stream */
+ if (gst_buffer_get_size(tmp) == 0)
+ {
gst_aml_v4l2_buffer_pool_release_buffer(bpool, tmp);
- if (ret != GST_FLOW_OK)
- goto copy_failed;
- break;
+ /* Legacy M2M devices return empty buffer when drained */
+ if (GST_AML_V4L2_IS_M2M(obj->device_caps))
+ goto eos;
+ }
+
+ ret = gst_aml_v4l2_buffer_pool_copy_buffer(pool, *buf, tmp);
+ if (obj->mode == GST_V4L2_IO_DMABUF && (GST_VIDEO_FORMAT_NV12 == pool->caps_info.finfo->format || GST_VIDEO_FORMAT_NV21 == pool->caps_info.finfo->format) && gst_buffer_get_size (*buf) > (pool->caps_info.width * pool->caps_info.height * 3 / 2))
+ {
+ GST_DEBUG_OBJECT (pool, "resizebuf. format:%d [%d, %d] W:%d, H:%d", pool->caps_info.finfo->format, GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV21, pool->caps_info.width, pool->caps_info.height);
+ gst_buffer_resize (*buf, 0, pool->caps_info.width * pool->caps_info.height * 3 / 2);
+ }
+
+
+ /* an queue the buffer again after the copy */
+ gst_aml_v4l2_buffer_pool_release_buffer(bpool, tmp);
+
+ if (ret != GST_FLOW_OK)
+ goto copy_failed;
+ break;
}
case GST_V4L2_IO_USERPTR:
{
- struct UserPtrData *data;
- GstBuffer *tmp;
+ struct UserPtrData *data;
+ GstBuffer *tmp;
- /* Replace our buffer with downstream allocated buffer */
- data = gst_mini_object_steal_qdata(GST_MINI_OBJECT(*buf),
- GST_AML_V4L2_IMPORT_QUARK);
- tmp = gst_buffer_ref(data->buffer);
- _unmap_userptr_frame(data);
+ /* Replace our buffer with downstream allocated buffer */
+ data = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
+ GST_AML_V4L2_IMPORT_QUARK);
+ tmp = gst_buffer_ref (data->buffer);
+ _unmap_userptr_frame (data);
- /* Now tmp is writable, copy the flags and timestamp */
- gst_buffer_copy_into(tmp, *buf,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+ /* Now tmp is writable, copy the flags and timestamp */
+ gst_buffer_copy_into (tmp, *buf,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
- gst_buffer_replace(buf, tmp);
- gst_buffer_unref(tmp);
- break;
+ gst_buffer_replace (buf, tmp);
+ gst_buffer_unref (tmp);
+ break;
}
case GST_V4L2_IO_DMABUF_IMPORT:
{
- GstBuffer *tmp;
+ GstBuffer *tmp;
- /* Replace our buffer with downstream allocated buffer */
- // tmp = gst_mini_object_steal_qdata(GST_MINI_OBJECT(*buf),
- // GST_AML_V4L2_IMPORT_QUARK);
- tmp = gst_mini_object_get_qdata(GST_MINI_OBJECT(*buf), GST_AML_V4L2_IMPORT_QUARK);
- GST_DEBUG("got v4l2 capture buf:%p, with qdata drm buf:%p", *buf, tmp);
+ /* Replace our buffer with downstream allocated buffer */
+ // tmp = gst_mini_object_steal_qdata(GST_MINI_OBJECT(*buf),
+ // GST_AML_V4L2_IMPORT_QUARK);
+ tmp = gst_mini_object_get_qdata(GST_MINI_OBJECT(*buf), GST_AML_V4L2_IMPORT_QUARK);
+ GST_DEBUG("got v4l2 capture buf:%p, with qdata drm buf:%p", *buf, tmp);
- gst_buffer_copy_into(tmp, *buf,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+ gst_buffer_copy_into (tmp, *buf,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
- gst_buffer_replace(buf, tmp);
- gst_buffer_unref(tmp);
- break;
+ gst_buffer_replace (buf, tmp);
+ gst_buffer_unref (tmp);
+ break;
}
default:
- g_assert_not_reached();
- break;
- }
- break;
+ g_assert_not_reached ();
+ break;
+ }
+ break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- /* playback */
- switch (obj->mode)
- {
+ /* playback */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- /* FIXME, do write() */
- GST_WARNING_OBJECT(pool, "implement write()");
- break;
+ /* FIXME, do write() */
+ GST_WARNING_OBJECT (pool, "implement write()");
+ break;
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF_IMPORT:
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_MMAP:
{
- GstBuffer *to_queue = NULL;
- GstBuffer *buffer;
- GstAmlV4l2MemoryGroup *group;
- gint index;
+ GstBuffer *to_queue = NULL;
+ GstBuffer *buffer;
+ GstAmlV4l2MemoryGroup *group;
+ gint index;
- if ((*buf)->pool != bpool)
- goto copying;
+ if ((*buf)->pool != bpool)
+ goto copying;
- if (!gst_aml_v4l2_is_buffer_valid(*buf, &group))
- goto copying;
+ if (!gst_aml_v4l2_is_buffer_valid (*buf, &group))
+ goto copying;
- index = group->buffer.index;
+ index = group->buffer.index;
- GST_LOG_OBJECT(pool, "processing buffer %i from our pool", index);
+ GST_LOG_OBJECT (pool, "processing buffer %i from our pool", index);
- if (pool->buffers[index] != NULL)
- {
- GST_LOG_OBJECT(pool, "buffer %i already queued, copying", index);
- goto copying;
- }
+ if (pool->buffers[index] != NULL)
+ {
+ GST_LOG_OBJECT (pool, "buffer %i already queued, copying", index);
+ goto copying;
+ }
- /* we can queue directly */
- to_queue = gst_buffer_ref(*buf);
+ /* we can queue directly */
+ to_queue = gst_buffer_ref (*buf);
copying:
- if (to_queue == NULL)
+ if (to_queue == NULL)
+ {
+ GstBufferPoolAcquireParams params = { 0 };
+
+ GST_LOG_OBJECT (pool, "alloc buffer from our pool");
+
+ /* this can return EOS if all buffers are outstanding which would
+ * be strange because we would expect the upstream element to have
+ * allocated them and returned to us.. */
+ params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
+ ret = gst_buffer_pool_acquire_buffer (bpool, &to_queue, ¶ms);
+ if (ret != GST_FLOW_OK)
+ goto acquire_failed;
+
+ ret = gst_aml_v4l2_buffer_pool_prepare_buffer (pool, to_queue, *buf);
+ if (ret != GST_FLOW_OK)
{
- GstBufferPoolAcquireParams params = {0};
-
- GST_LOG_OBJECT(pool, "alloc buffer from our pool");
-
- /* this can return EOS if all buffers are outstanding which would
- * be strange because we would expect the upstream element to have
- * allocated them and returned to us.. */
- params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
- ret = gst_buffer_pool_acquire_buffer(bpool, &to_queue, ¶ms);
- if (ret != GST_FLOW_OK)
- goto acquire_failed;
-
- ret = gst_aml_v4l2_buffer_pool_prepare_buffer(pool, to_queue, *buf);
- if (ret != GST_FLOW_OK)
- {
- gst_buffer_unref(to_queue);
- goto prepare_failed;
- }
-
- /* retreive the group */
- gst_aml_v4l2_is_buffer_valid(to_queue, &group);
+ gst_buffer_unref (to_queue);
+ goto prepare_failed;
}
- if ((ret = gst_aml_v4l2_buffer_pool_qbuf(pool, to_queue, group)) != GST_FLOW_OK)
- goto queue_failed;
+ /* retrieve the group */
+ gst_aml_v4l2_is_buffer_valid (to_queue, &group);
+ }
- /* if we are not streaming yet (this is the first buffer, start
- * streaming now */
- if (!gst_aml_v4l2_buffer_pool_streamon(pool))
- {
- /* don't check return value because qbuf would have failed */
- gst_aml_v4l2_is_buffer_valid(to_queue, &group);
+ if ((ret = gst_aml_v4l2_buffer_pool_qbuf(pool, to_queue, group)) != GST_FLOW_OK)
+ goto queue_failed;
- /* qbuf has stored to_queue buffer but we are not in
- * streaming state, so the flush logic won't be performed.
- * To avoid leaks, flush the allocator and restore the queued
- * buffer as non-queued */
- gst_aml_v4l2_allocator_flush(pool->vallocator);
+ /* if we are not streaming yet (this is the first buffer, start
+ * streaming now */
+ if (!gst_aml_v4l2_buffer_pool_streamon (pool))
+ {
+ /* don't check return value because qbuf would have failed */
+ gst_aml_v4l2_is_buffer_valid (to_queue, &group);
- pool->buffers[group->buffer.index] = NULL;
+ /* qbuf has stored to_queue buffer but we are not in
+ * streaming state, so the flush logic won't be performed.
+ * To avoid leaks, flush the allocator and restore the queued
+ * buffer as non-queued */
+ gst_aml_v4l2_allocator_flush (pool->vallocator);
- gst_mini_object_set_qdata(GST_MINI_OBJECT(to_queue),
- GST_AML_V4L2_IMPORT_QUARK, NULL, NULL);
- gst_buffer_unref(to_queue);
- g_atomic_int_add(&pool->num_queued, -1);
- goto start_failed;
- }
+ pool->buffers[group->buffer.index] = NULL;
- /* Remove our ref, we will still hold this buffer in acquire as needed,
- * otherwise the pool will think it is outstanding and will refuse to stop. */
- gst_buffer_unref(to_queue);
+ gst_mini_object_set_qdata (GST_MINI_OBJECT (to_queue),
+ GST_AML_V4L2_IMPORT_QUARK, NULL, NULL);
+ gst_buffer_unref (to_queue);
+ g_atomic_int_add (&pool->num_queued, -1);
+ goto start_failed;
+ }
- /* release as many buffer as possible */
- while (gst_aml_v4l2_buffer_pool_dequeue(pool, &buffer, FALSE) ==
- GST_FLOW_OK)
- {
- if (buffer->pool == NULL)
- gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
- }
+ /* Remove our ref, we will still hold this buffer in acquire as needed,
+ * otherwise the pool will think it is outstanding and will refuse to stop. */
+ gst_buffer_unref (to_queue);
- if (g_atomic_int_get(&pool->num_queued) >= pool->min_latency)
- {
- /* all buffers are queued, try to dequeue one and release it back
- * into the pool so that _acquire can get to it again. */
- ret = gst_aml_v4l2_buffer_pool_dequeue(pool, &buffer, TRUE);
- if (ret == GST_FLOW_OK && buffer->pool == NULL)
- /* release the rendered buffer back into the pool. This wakes up any
- * thread waiting for a buffer in _acquire(). */
- gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
- }
- break;
+ /* release as many buffer as possible */
+ while (gst_aml_v4l2_buffer_pool_dequeue (pool, &buffer, FALSE) ==
+ GST_FLOW_OK)
+ {
+ if (buffer->pool == NULL)
+ gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
+ }
+
+ if (g_atomic_int_get (&pool->num_queued) >= pool->min_latency)
+ {
+ /* all buffers are queued, try to dequeue one and release it back
+ * into the pool so that _acquire can get to it again. */
+ ret = gst_aml_v4l2_buffer_pool_dequeue (pool, &buffer, TRUE);
+ if (ret == GST_FLOW_OK && buffer->pool == NULL)
+ /* release the rendered buffer back into the pool. This wakes up any
+ * thread waiting for a buffer in _acquire(). */
+ gst_aml_v4l2_buffer_pool_release_buffer(bpool, buffer);
+ }
+ break;
}
default:
- g_assert_not_reached();
- break;
- }
- break;
+ g_assert_not_reached ();
+ break;
+ }
+ break;
default:
- g_assert_not_reached();
- break;
- }
+ g_assert_not_reached ();
+ break;
+ }
done:
- return ret;
+ return ret;
- /* ERRORS */
+ /* ERRORS */
copy_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to copy buffer");
+ {
+ GST_ERROR_OBJECT (pool, "failed to copy buffer");
return ret;
-}
+ }
buffer_truncated:
-{
- GST_WARNING_OBJECT(pool,
- "Dropping truncated buffer, this is likely a driver bug.");
- gst_buffer_unref(*buf);
+ {
+ GST_WARNING_OBJECT (pool,
+ "Dropping truncated buffer, this is likely a driver bug.");
+ gst_buffer_unref (*buf);
*buf = NULL;
return GST_AML_V4L2_FLOW_CORRUPTED_BUFFER;
-}
+ }
eos:
-{
- GST_DEBUG_OBJECT(pool, "end of stream reached");
- gst_buffer_unref(*buf);
+ {
+ GST_DEBUG_OBJECT (pool, "end of stream reached");
+ gst_buffer_unref (*buf);
*buf = NULL;
return GST_AML_V4L2_FLOW_LAST_BUFFER;
-}
+ }
acquire_failed:
-{
+ {
if (ret == GST_FLOW_FLUSHING)
- GST_DEBUG_OBJECT(pool, "flushing");
+ GST_DEBUG_OBJECT (pool, "flushing");
else
- GST_WARNING_OBJECT(pool, "failed to acquire a buffer: %s",
- gst_flow_get_name(ret));
+ GST_WARNING_OBJECT (pool, "failed to acquire a buffer: %s",
+ gst_flow_get_name (ret));
return ret;
-}
+ }
prepare_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to prepare data");
+ {
+ GST_ERROR_OBJECT (pool, "failed to prepare data");
return ret;
-}
+ }
queue_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to queue buffer");
+ {
+ GST_ERROR_OBJECT (pool, "failed to queue buffer");
return ret;
-}
+ }
start_failed:
-{
- GST_ERROR_OBJECT(pool, "failed to start streaming");
+ {
+ GST_ERROR_OBJECT (pool, "failed to start streaming");
return GST_FLOW_ERROR;
-}
+ }
}
-void gst_aml_v4l2_buffer_pool_set_other_pool(GstAmlV4l2BufferPool *pool,
- GstBufferPool *other_pool)
+void
+gst_aml_v4l2_buffer_pool_set_other_pool (GstAmlV4l2BufferPool * pool,
+ GstBufferPool * other_pool)
{
- g_return_if_fail(!gst_buffer_pool_is_active(GST_BUFFER_POOL(pool)));
+ g_return_if_fail (!gst_buffer_pool_is_active (GST_BUFFER_POOL (pool)));
- if (pool->other_pool)
- gst_object_unref(pool->other_pool);
- pool->other_pool = gst_object_ref(other_pool);
+ if (pool->other_pool)
+ gst_object_unref (pool->other_pool);
+ pool->other_pool = gst_object_ref (other_pool);
}
-void gst_aml_v4l2_buffer_pool_copy_at_threshold(GstAmlV4l2BufferPool *pool, gboolean copy)
+void
+gst_aml_v4l2_buffer_pool_copy_at_threshold (GstAmlV4l2BufferPool * pool, gboolean copy)
{
- GST_OBJECT_LOCK(pool);
- pool->enable_copy_threshold = copy;
- GST_OBJECT_UNLOCK(pool);
+ GST_OBJECT_LOCK (pool);
+ pool->enable_copy_threshold = copy;
+ GST_OBJECT_UNLOCK (pool);
}
gboolean
gst_aml_v4l2_buffer_pool_flush(GstBufferPool *bpool)
{
- GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
- gboolean ret = TRUE;
+ GstAmlV4l2BufferPool *pool = GST_AML_V4L2_BUFFER_POOL(bpool);
+ gboolean ret = TRUE;
- gst_aml_v4l2_buffer_pool_streamoff(pool);
+ gst_aml_v4l2_buffer_pool_streamoff (pool);
- if (!V4L2_TYPE_IS_OUTPUT(pool->obj->type))
- ret = gst_aml_v4l2_buffer_pool_streamon(pool);
+ if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type))
+ ret = gst_aml_v4l2_buffer_pool_streamon (pool);
- return ret;
+ return ret;
}
void gst_aml_v4l2_buffer_pool_dump_stat(GstAmlV4l2BufferPool *pool, const gchar *file_name, gint try_num)
diff --git a/src/gstamlv4l2bufferpool.h b/src/gstamlv4l2bufferpool.h
index 3530348..57d40b5 100644
--- a/src/gstamlv4l2bufferpool.h
+++ b/src/gstamlv4l2bufferpool.h
@@ -58,56 +58,56 @@
struct _GstAmlV4l2BufferPool
{
- GstBufferPool parent;
+ GstBufferPool parent;
- GstAmlV4l2Object *obj; /* the v4l2 object */
- gint video_fd; /* a dup(2) of the v4l2object's video_fd */
- GstPoll *poll; /* a poll for video_fd */
- GstPollFD pollfd;
- gboolean can_poll_device;
+ GstAmlV4l2Object *obj; /* the v4l2 object */
+ gint video_fd; /* a dup(2) of the v4l2object's video_fd */
+ GstPoll *poll; /* a poll for video_fd */
+ GstPollFD pollfd;
+ gboolean can_poll_device;
- gboolean empty;
- GCond empty_cond;
+ gboolean empty;
+ GCond empty_cond;
- GList *cc_buffer_list;
+ GList *cc_buffer_list;
- gboolean orphaned;
+ gboolean orphaned;
- GstAmlV4l2Allocator *vallocator;
- GstAllocator *allocator;
- GstAllocationParams params;
- GstBufferPool *other_pool;
- guint size;
- GstVideoInfo caps_info; /* Default video information */
+ GstAmlV4l2Allocator *vallocator;
+ GstAllocator *allocator;
+ GstAllocationParams params;
+ GstBufferPool *other_pool;
+ guint size;
+ GstVideoInfo caps_info; /* Default video information */
- gboolean add_videometa; /* set if video meta should be added */
- gboolean enable_copy_threshold; /* If copy_threshold should be set */
+ gboolean add_videometa; /* set if video meta should be added */
+ gboolean enable_copy_threshold; /* If copy_threshold should be set */
- guint min_latency; /* number of buffers we will hold */
- guint max_latency; /* number of buffers we can hold */
- guint num_queued; /* number of buffers queued in the driver */
- guint num_allocated; /* number of buffers allocated */
- guint copy_threshold; /* when our pool runs lower, start handing out copies */
+ guint min_latency; /* number of buffers we will hold */
+ guint max_latency; /* number of buffers we can hold */
+ guint num_queued; /* number of buffers queued in the driver */
+ guint num_allocated; /* number of buffers allocated */
+ guint copy_threshold; /* when our pool runs lower, start handing out copies */
- gboolean streaming;
- gboolean flushing;
+ gboolean streaming;
+ gboolean flushing;
- GstBuffer *buffers[VIDEO_MAX_FRAME];
+ GstBuffer *buffers[VIDEO_MAX_FRAME];
#ifdef GST_AML_SPEC_FLOW_FOR_VBP
- GstBuffer *read_to_free_bufs[VIDEO_MAX_FRAME];
- gint ready_to_free_buf_num;
+ GstBuffer *read_to_free_bufs[VIDEO_MAX_FRAME];
+ gint ready_to_free_buf_num;
#endif
- /* signal handlers */
- gulong group_released_handler;
+ /* signal handlers */
+ gulong group_released_handler;
- /* Control to warn only once on buggy feild driver bug */
- gboolean has_warned_on_buggy_field;
+ /* Control to warn only once on buggy feild driver bug */
+ gboolean has_warned_on_buggy_field;
};
struct _GstAmlV4l2BufferPoolClass
{
- GstBufferPoolClass parent_class;
+ GstBufferPoolClass parent_class;
};
GType gst_aml_v4l2_buffer_pool_get_type(void);
diff --git a/src/gstamlv4l2object.c b/src/gstamlv4l2object.c
index 425c4c9..bc14561 100644
--- a/src/gstamlv4l2object.c
+++ b/src/gstamlv4l2object.c
@@ -42,15 +42,14 @@
#include <gst/video/video.h>
#include <gst/allocators/gstdmabuf.h>
-
-GST_DEBUG_CATEGORY_EXTERN(aml_v4l2_debug);
+GST_DEBUG_CATEGORY_EXTERN (aml_v4l2_debug);
#define GST_CAT_DEFAULT aml_v4l2_debug
-#define DEFAULT_PROP_DEVICE_NAME NULL
-#define DEFAULT_PROP_DEVICE_FD -1
-#define DEFAULT_PROP_FLAGS 0
-#define DEFAULT_PROP_TV_NORM 0
-#define DEFAULT_PROP_IO_MODE GST_V4L2_IO_AUTO
+#define DEFAULT_PROP_DEVICE_NAME NULL
+#define DEFAULT_PROP_DEVICE_FD -1
+#define DEFAULT_PROP_FLAGS 0
+#define DEFAULT_PROP_TV_NORM 0
+#define DEFAULT_PROP_IO_MODE GST_V4L2_IO_AUTO
#define ENCODED_BUFFER_SIZE (4 * 1024 * 1024)
#define LOW_MEM_ENCODED_BUFFER_SIZE (1 * 1024 * 1024)
@@ -70,8 +69,8 @@
enum
{
- PROP_0,
- V4L2_STD_OBJECT_PROPS,
+ PROP_0,
+ V4L2_STD_OBJECT_PROPS,
};
/*
@@ -79,375 +78,380 @@
*/
typedef enum
{
- GST_V4L2_RAW = 1 << 0,
- GST_V4L2_CODEC = 1 << 1,
- GST_V4L2_TRANSPORT = 1 << 2,
- GST_V4L2_NO_PARSE = 1 << 3,
- GST_V4L2_ALL = 0xffff
+ GST_V4L2_RAW = 1 << 0,
+ GST_V4L2_CODEC = 1 << 1,
+ GST_V4L2_TRANSPORT = 1 << 2,
+ GST_V4L2_NO_PARSE = 1 << 3,
+ GST_V4L2_ALL = 0xffff
} GstAmlV4L2FormatFlags;
typedef struct
{
- guint32 format;
- gboolean dimensions;
- GstAmlV4L2FormatFlags flags;
+ guint32 format;
+ gboolean dimensions;
+ GstAmlV4L2FormatFlags flags;
} GstAmlV4L2FormatDesc;
static const GstAmlV4L2FormatDesc gst_aml_v4l2_formats[] = {
- /* RGB formats */
- {V4L2_PIX_FMT_RGB332, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB565, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB565X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR666, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ABGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XBGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB32, TRUE, GST_V4L2_RAW},
+ /* RGB formats */
+ {V4L2_PIX_FMT_RGB332, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_ARGB555, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_XRGB555, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_ARGB555X, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_XRGB555X, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB565, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB565X, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_BGR666, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_BGR24, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB24, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_ABGR32, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_XBGR32, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_ARGB32, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_XRGB32, TRUE, GST_V4L2_RAW},
- /* Deprecated Packed RGB Image Formats (alpha ambiguity) */
- {V4L2_PIX_FMT_RGB444, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB32, TRUE, GST_V4L2_RAW},
+ /* Deprecated Packed RGB Image Formats (alpha ambiguity) */
+ {V4L2_PIX_FMT_RGB444, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_BGR32, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_RGB32, TRUE, GST_V4L2_RAW},
- /* Grey formats */
- {V4L2_PIX_FMT_GREY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y4, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y6, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y10, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y16_BE, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y10BPACK, TRUE, GST_V4L2_RAW},
+ /* Grey formats */
+ {V4L2_PIX_FMT_GREY, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y4, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y6, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y10, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y12, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y16, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y16_BE, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y10BPACK, TRUE, GST_V4L2_RAW},
- /* Palette formats */
- {V4L2_PIX_FMT_PAL8, TRUE, GST_V4L2_RAW},
+ /* Palette formats */
+ {V4L2_PIX_FMT_PAL8, TRUE, GST_V4L2_RAW},
- /* Chrominance formats */
- {V4L2_PIX_FMT_UV8, TRUE, GST_V4L2_RAW},
+ /* Chrominance formats */
+ {V4L2_PIX_FMT_UV8, TRUE, GST_V4L2_RAW},
- /* Luminance+Chrominance formats */
- {V4L2_PIX_FMT_YVU410, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVU420, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVU420M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUYV, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_UYVY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_VYUY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV422P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV411P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y41P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV444, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV565, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV420M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_HM12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_M420, TRUE, GST_V4L2_RAW},
+ /* Luminance+Chrominance formats */
+ {V4L2_PIX_FMT_YVU410, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YVU420, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YVU420M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUYV, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_UYVY, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_VYUY, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV422P, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV411P, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_Y41P, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV444, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV555, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV565, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV32, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_YUV420M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_HM12, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_M420, TRUE, GST_V4L2_RAW},
- /* two planes -- one Y, one Cr + Cb interleaved */
- {V4L2_PIX_FMT_NV12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12MT, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12MT_16X16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV21, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV21M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV16M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV61, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV61M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV42, TRUE, GST_V4L2_RAW},
+ /* two planes -- one Y, one Cr + Cb interleaved */
+ {V4L2_PIX_FMT_NV12, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV12M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV12MT, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV12MT_16X16, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV21, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV21M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV16, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV16M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV61, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV61M, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV24, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_NV42, TRUE, GST_V4L2_RAW},
- /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
- {V4L2_PIX_FMT_SBGGR8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SGBRG8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SGRBG8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SRGGB8, TRUE, GST_V4L2_RAW},
+ /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
+ {V4L2_PIX_FMT_SBGGR8, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_SGBRG8, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_SGRBG8, TRUE, GST_V4L2_RAW},
+ {V4L2_PIX_FMT_SRGGB8, TRUE, GST_V4L2_RAW},
- /* compressed formats */
- {V4L2_PIX_FMT_MJPEG, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_DV, FALSE, GST_V4L2_TRANSPORT},
- {V4L2_PIX_FMT_MPEG, FALSE, GST_V4L2_TRANSPORT},
- {V4L2_PIX_FMT_FWHT, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_H264_NO_SC, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_H264_MVC, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_HEVC, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_MPEG1, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_MPEG2, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_MPEG4, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_XVID, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VC1_ANNEX_G, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VC1_ANNEX_L, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_VP9, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_AV1, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_AVS, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_AVS2, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_AVS3, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ /* compressed formats */
+ {V4L2_PIX_FMT_MJPEG, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_DV, FALSE, GST_V4L2_TRANSPORT},
+ {V4L2_PIX_FMT_MPEG, FALSE, GST_V4L2_TRANSPORT},
+ {V4L2_PIX_FMT_FWHT, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_H264_NO_SC, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_H264_MVC, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_HEVC, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_MPEG1, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_MPEG2, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_MPEG4, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_XVID, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_VC1_ANNEX_G, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_VC1_ANNEX_L, FALSE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_VP9, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_AV1, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_AVS, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_AVS2, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {V4L2_PIX_FMT_AVS3, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- /* Vendor-specific formats */
- {V4L2_PIX_FMT_WNVA, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
+ /* Vendor-specific formats */
+ {V4L2_PIX_FMT_WNVA, TRUE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
+ {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
};
-#define GST_AML_V4L2_FORMAT_COUNT (G_N_ELEMENTS(gst_aml_v4l2_formats))
+#define GST_AML_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_aml_v4l2_formats))
-static GSList *gst_aml_v4l2_object_get_format_list(GstAmlV4l2Object *v4l2object);
+static GSList *gst_aml_v4l2_object_get_format_list (GstAmlV4l2Object * v4l2object);
static gboolean gst_aml_v4l2_set_control(GstAmlV4l2Object *v4l2object, guint ctl);
static gboolean get_amlogic_vdec_parm(GstAmlV4l2Object *v4l2object, struct v4l2_streamparm *streamparm);
static int gst_aml_config_dw(GstAmlV4l2Object *v4l2object, guint32 pixFormat, guint width, guint height, gboolean interlace);
-#define GST_TYPE_AML_V4L2_DEVICE_FLAGS (gst_aml_v4l2_device_get_type())
+#define GST_TYPE_AML_V4L2_DEVICE_FLAGS (gst_aml_v4l2_device_get_type ())
static GType
-gst_aml_v4l2_device_get_type(void)
+gst_aml_v4l2_device_get_type (void)
{
- static GType v4l2_device_type = 0;
+ static GType v4l2_device_type = 0;
- if (v4l2_device_type == 0)
- {
- static const GFlagsValue values[] = {
- {V4L2_CAP_VIDEO_CAPTURE, "Device supports video capture", "capture"},
- {V4L2_CAP_VIDEO_OUTPUT, "Device supports video playback", "output"},
- {V4L2_CAP_VIDEO_OVERLAY, "Device supports video overlay", "overlay"},
+ if (v4l2_device_type == 0)
+ {
+ static const GFlagsValue values[] = {
+ {V4L2_CAP_VIDEO_CAPTURE, "Device supports video capture", "capture"},
+ {V4L2_CAP_VIDEO_OUTPUT, "Device supports video playback", "output"},
+ {V4L2_CAP_VIDEO_OVERLAY, "Device supports video overlay", "overlay"},
- {V4L2_CAP_VBI_CAPTURE, "Device supports the VBI capture", "vbi-capture"},
- {V4L2_CAP_VBI_OUTPUT, "Device supports the VBI output", "vbi-output"},
+ {V4L2_CAP_VBI_CAPTURE, "Device supports the VBI capture", "vbi-capture"},
+ {V4L2_CAP_VBI_OUTPUT, "Device supports the VBI output", "vbi-output"},
- {V4L2_CAP_TUNER, "Device has a tuner or modulator", "tuner"},
- {V4L2_CAP_AUDIO, "Device has audio inputs or outputs", "audio"},
+ {V4L2_CAP_TUNER, "Device has a tuner or modulator", "tuner"},
+ {V4L2_CAP_AUDIO, "Device has audio inputs or outputs", "audio"},
- {0, NULL, NULL}};
+ {0, NULL, NULL}
+ };
- v4l2_device_type =
- g_flags_register_static("GstAmlV4l2DeviceTypeFlags", values);
- }
+ v4l2_device_type =
+ g_flags_register_static ("GstAmlV4l2DeviceTypeFlags", values);
+ }
- return v4l2_device_type;
+ return v4l2_device_type;
}
-GType gst_aml_v4l2_io_mode_get_type(void)
+GType
+gst_aml_v4l2_io_mode_get_type (void)
{
- static GType v4l2_io_mode = 0;
+ static GType v4l2_io_mode = 0;
- if (!v4l2_io_mode)
- {
- static const GEnumValue io_modes[] = {
- {GST_V4L2_IO_AUTO, "GST_V4L2_IO_AUTO", "auto"},
- {GST_V4L2_IO_RW, "GST_V4L2_IO_RW", "rw"},
- {GST_V4L2_IO_MMAP, "GST_V4L2_IO_MMAP", "mmap"},
- {GST_V4L2_IO_USERPTR, "GST_V4L2_IO_USERPTR", "userptr"},
- {GST_V4L2_IO_DMABUF, "GST_V4L2_IO_DMABUF", "dmabuf"},
- {GST_V4L2_IO_DMABUF_IMPORT, "GST_V4L2_IO_DMABUF_IMPORT",
- "dmabuf-import"},
+ if (!v4l2_io_mode)
+ {
+ static const GEnumValue io_modes[] = {
+ {GST_V4L2_IO_AUTO, "GST_V4L2_IO_AUTO", "auto"},
+ {GST_V4L2_IO_RW, "GST_V4L2_IO_RW", "rw"},
+ {GST_V4L2_IO_MMAP, "GST_V4L2_IO_MMAP", "mmap"},
+ {GST_V4L2_IO_USERPTR, "GST_V4L2_IO_USERPTR", "userptr"},
+ {GST_V4L2_IO_DMABUF, "GST_V4L2_IO_DMABUF", "dmabuf"},
+ {GST_V4L2_IO_DMABUF_IMPORT, "GST_V4L2_IO_DMABUF_IMPORT",
+ "dmabuf-import"},
- {0, NULL, NULL}};
- v4l2_io_mode = g_enum_register_static("GstAmlV4l2IOMode", io_modes);
- }
- return v4l2_io_mode;
+ {0, NULL, NULL}
+ };
+ v4l2_io_mode = g_enum_register_static ("GstAmlV4l2IOMode", io_modes);
+ }
+ return v4l2_io_mode;
}
-void gst_aml_v4l2_object_install_properties_helper(GObjectClass *gobject_class,
- const char *default_device)
+void
+gst_aml_v4l2_object_install_properties_helper (GObjectClass * gobject_class,
+ const char *default_device)
{
- g_object_class_install_property(gobject_class, PROP_DEVICE,
- g_param_spec_string("device", "Device", "Device location",
- default_device, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_DEVICE_NAME,
- g_param_spec_string("device-name", "Device name",
- "Name of the device", DEFAULT_PROP_DEVICE_NAME,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_DEVICE_FD,
- g_param_spec_int("device-fd", "File descriptor",
- "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_FLAGS,
- g_param_spec_flags("flags", "Flags", "Device type flags",
- GST_TYPE_AML_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE,
+ g_param_spec_string ("device", "Device", "Device location",
+ default_device, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
+ g_param_spec_string ("device-name", "Device name",
+ "Name of the device", DEFAULT_PROP_DEVICE_NAME,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
+ g_param_spec_int ("device-fd", "File descriptor",
+ "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_FLAGS,
+ g_param_spec_flags ("flags", "Flags", "Device type flags",
+ GST_TYPE_AML_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- /**
- * GstV4l2Src:brightness:
- *
- * Picture brightness, or more precisely, the black level
- */
- g_object_class_install_property(gobject_class, PROP_BRIGHTNESS,
- g_param_spec_int("brightness", "Brightness",
- "Picture brightness, or more precisely, the black level", G_MININT,
- G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
- /**
- * GstV4l2Src:contrast:
- *
- * Picture contrast or luma gain
- */
- g_object_class_install_property(gobject_class, PROP_CONTRAST,
- g_param_spec_int("contrast", "Contrast",
- "Picture contrast or luma gain", G_MININT,
- G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
- /**
- * GstV4l2Src:saturation:
- *
- * Picture color saturation or chroma gain
- */
- g_object_class_install_property(gobject_class, PROP_SATURATION,
- g_param_spec_int("saturation", "Saturation",
- "Picture color saturation or chroma gain", G_MININT,
- G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
- /**
- * GstV4l2Src:hue:
- *
- * Hue or color balance
- */
- g_object_class_install_property(gobject_class, PROP_HUE,
- g_param_spec_int("hue", "Hue",
- "Hue or color balance", G_MININT,
- G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ /**
+ * GstV4l2Src:brightness:
+ *
+ * Picture brightness, or more precisely, the black level
+ */
+ g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
+ g_param_spec_int ("brightness", "Brightness",
+ "Picture brightness, or more precisely, the black level", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ /**
+ * GstV4l2Src:contrast:
+ *
+ * Picture contrast or luma gain
+ */
+ g_object_class_install_property (gobject_class, PROP_CONTRAST,
+ g_param_spec_int ("contrast", "Contrast",
+ "Picture contrast or luma gain", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ /**
+ * GstV4l2Src:saturation:
+ *
+ * Picture color saturation or chroma gain
+ */
+ g_object_class_install_property (gobject_class, PROP_SATURATION,
+ g_param_spec_int ("saturation", "Saturation",
+ "Picture color saturation or chroma gain", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ /**
+ * GstV4l2Src:hue:
+ *
+ * Hue or color balance
+ */
+ g_object_class_install_property (gobject_class, PROP_HUE,
+ g_param_spec_int ("hue", "Hue",
+ "Hue or color balance", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
- /**
- * GstV4l2Src:io-mode:
- *
- * IO Mode
- */
- g_object_class_install_property(gobject_class, PROP_IO_MODE,
- g_param_spec_enum("io-mode", "IO mode",
- "I/O mode",
- GST_TYPE_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstV4l2Src:io-mode:
+ *
+ * IO Mode
+ */
+ g_object_class_install_property (gobject_class, PROP_IO_MODE,
+ g_param_spec_enum ("io-mode", "IO mode",
+ "I/O mode",
+ GST_TYPE_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstV4l2Src:extra-controls:
- *
- * Additional v4l2 controls for the device. The controls are identified
- * by the control name (lowercase with '_' for any non-alphanumeric
- * characters).
- *
- * Since: 1.2
- */
- 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",
- GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstV4l2Src:extra-controls:
+ *
+ * Additional v4l2 controls for the device. The controls are identified
+ * by the control name (lowercase with '_' for any non-alphanumeric
+ * characters).
+ *
+ * Since: 1.2
+ */
+ 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",
+ GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstV4l2Src:pixel-aspect-ratio:
- *
- * The pixel aspect ratio of the device. This overwrites the pixel aspect
- * ratio queried from the device.
- *
- * Since: 1.2
- */
- g_object_class_install_property(gobject_class, PROP_PIXEL_ASPECT_RATIO,
- g_param_spec_string("pixel-aspect-ratio", "Pixel Aspect Ratio",
- "Overwrite the pixel aspect ratio of the device", "1/1",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstV4l2Src:pixel-aspect-ratio:
+ *
+ * The pixel aspect ratio of the device. This overwrites the pixel aspect
+ * ratio queried from the device.
+ *
+ * Since: 1.2
+ */
+ g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
+ g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
+ "Overwrite the pixel aspect ratio of the device", "1/1",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstV4l2Src:force-aspect-ratio:
- *
- * When enabled, the pixel aspect ratio queried from the device or set
- * with the pixel-aspect-ratio property will be enforced.
- *
- * Since: 1.2
- */
- g_object_class_install_property(gobject_class, PROP_FORCE_ASPECT_RATIO,
- g_param_spec_boolean("force-aspect-ratio", "Force aspect ratio",
- "When enabled, the pixel aspect ratio will be enforced", TRUE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstV4l2Src:force-aspect-ratio:
+ *
+ * When enabled, the pixel aspect ratio queried from the device or set
+ * with the pixel-aspect-ratio property will be enforced.
+ *
+ * Since: 1.2
+ */
+ g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
+ g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
+ "When enabled, the pixel aspect ratio will be enforced", TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
-void gst_aml_v4l2_object_install_m2m_properties_helper(GObjectClass *gobject_class)
+void
+gst_aml_v4l2_object_install_m2m_properties_helper (GObjectClass * gobject_class)
{
- g_object_class_install_property(gobject_class, PROP_DEVICE,
- g_param_spec_string("device", "Device", "Device location",
- NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE,
+ g_param_spec_string ("device", "Device", "Device location",
+ NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_DEVICE_NAME,
- g_param_spec_string("device-name", "Device name",
- "Name of the device", DEFAULT_PROP_DEVICE_NAME,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
+ g_param_spec_string ("device-name", "Device name",
+ "Name of the device", DEFAULT_PROP_DEVICE_NAME,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_DEVICE_FD,
- g_param_spec_int("device-fd", "File descriptor",
- "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
+ g_param_spec_int ("device-fd", "File descriptor",
+ "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_OUTPUT_IO_MODE,
- g_param_spec_enum("output-io-mode", "Output IO mode",
- "Output side I/O mode (matches sink pad)",
- GST_TYPE_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
+ g_object_class_install_property (gobject_class, PROP_OUTPUT_IO_MODE,
+ g_param_spec_enum ("output-io-mode", "Output IO mode",
+ "Output side I/O mode (matches sink pad)",
+ GST_TYPE_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
+ 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_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
+ 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",
+ GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property(gobject_class, PROP_DUMP_FRAME_LOCATION,
+ g_param_spec_string("dump-frame-location", "dump frame location",
+ "Location of the file to write decoder frames", NULL,
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_AML_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(gobject_class, PROP_STREAM_MODE,
+ g_param_spec_boolean("stream-mode", "Configure v4l2 stream mode",
+ "TRUE for stream mode, FALSE for frame mode",
+ FALSE,
+ 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",
- GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(gobject_class, PROP_LOW_LATENCY_MODE,
+ g_param_spec_boolean("low-latency-mode", "set low latency mode",
+ "enable is TURE, disable is FALSE, default is disable",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_DUMP_FRAME_LOCATION,
- g_param_spec_string("dump-frame-location", "dump frame location",
- "Location of the file to write decoder frames", NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_CC_DATA,
+ g_param_spec_boolean ("enable-cc-data",
+ "enable get cc data",
+ "0: disable; 1: enable", FALSE, G_PARAM_READWRITE));
- g_object_class_install_property(gobject_class, PROP_STREAM_MODE,
- g_param_spec_boolean("stream-mode", "Configure v4l2 stream mode",
- "TRUE for stream mode, FALSE for frame mode",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_ENABLE_NR,
+ g_param_spec_boolean ("enable-nr",
+ "enable nr in di",
+ "0: disable; 1: enable", FALSE, G_PARAM_READWRITE));
- g_object_class_install_property(gobject_class, PROP_LOW_LATENCY_MODE,
- g_param_spec_boolean("low-latency-mode", "set low latency mode",
- "enable is TURE, disable is FALSE, default is disable",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_CC_DATA,
- g_param_spec_boolean ("enable-cc-data",
- "enable get cc data",
- "0: disable; 1: enable", FALSE, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_ENABLE_NR,
- g_param_spec_boolean ("enable-nr",
- "enable nr in di",
- "0: disable; 1: enable", FALSE, G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_DECODING_ERROR_FRAMES,
- g_param_spec_int("decoding-error-frames", "decoding error frames",
- "get number of decoding error frames",
- 0, G_MAXINT32, 0, G_PARAM_READABLE));
- g_object_class_install_property(gobject_class, PROP_LOW_MEMORY_MODE,
- g_param_spec_boolean("low-memory", "low memory mode",
- "Reduce memory usage if possible,default is disable",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(gobject_class, PROP_I_FRAME_MODE,
- g_param_spec_boolean("iframe-mode", "use I frame mode",
- "use for speed play",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(gobject_class, PROP_DECODING_ERROR_FRAMES,
+ g_param_spec_int("decoding-error-frames", "decoding error frames",
+ "get number of decoding error frames",
+ 0, G_MAXINT32, 0, G_PARAM_READABLE));
+ g_object_class_install_property(gobject_class, PROP_LOW_MEMORY_MODE,
+ g_param_spec_boolean("low-memory", "low memory mode",
+ "Reduce memory usage if possible,default is disable",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(gobject_class, PROP_I_FRAME_MODE,
+ g_param_spec_boolean("iframe-mode", "use I frame mode",
+ "use for speed play",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
@@ -456,10 +460,10 @@
#if SIZEOF_OFF_T < 8
static gpointer
-v4l2_mmap_wrapper(gpointer start, gsize length, gint prot, gint flags, gint fd,
- off_t offset)
+v4l2_mmap_wrapper (gpointer start, gsize length, gint prot, gint flags, gint fd,
+ off_t offset)
{
- return v4l2_mmap(start, length, prot, flags, fd, (gint64)offset);
+ return v4l2_mmap (start, length, prot, flags, fd, (gint64) offset);
}
#define v4l2_mmap v4l2_mmap_wrapper
@@ -468,258 +472,259 @@
#endif /* HAVE_LIBV4L2 */
GstAmlV4l2Object *
-gst_aml_v4l2_object_new(GstElement *element,
- GstObject *debug_object,
- enum v4l2_buf_type type,
- const char *default_device,
- GstAmlV4l2GetInOutFunction get_in_out_func,
- GstAmlV4l2SetInOutFunction set_in_out_func,
- GstAmlV4l2UpdateFpsFunction update_fps_func)
+gst_aml_v4l2_object_new (GstElement * element,
+ GstObject * debug_object,
+ enum v4l2_buf_type type,
+ const char *default_device,
+ GstAmlV4l2GetInOutFunction get_in_out_func,
+ GstAmlV4l2SetInOutFunction set_in_out_func,
+ GstAmlV4l2UpdateFpsFunction update_fps_func)
{
- GstAmlV4l2Object *v4l2object;
+ GstAmlV4l2Object *v4l2object;
- /*
- * some default values
- */
- v4l2object = g_new0(GstAmlV4l2Object, 1);
+ /*
+ * some default values
+ */
+ v4l2object = g_new0 (GstAmlV4l2Object, 1);
- if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == type || V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type))
- {
- const char *default_mode = getenv("GST_DEFAULT_V4L2_BUF_MODE");
- GST_DEBUG("amlmodbuf GST_AML_DEFAULT_V4L2_BUF_MODE:%s", default_mode);
- //v4l2object->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
- if (default_mode)
- {
- if (strcmp(default_mode, "DMA_BUF_IMPORT") == 0)
- v4l2object->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
- else if (strcmp(default_mode, "DMA_BUF") == 0)
- v4l2object->req_mode = GST_V4L2_IO_DMABUF;
- GST_DEBUG("amlmodbuf set default buf default_mode:%d", v4l2object->req_mode);
- }
- }
+ if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == type || V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type))
+ {
+ const char *default_mode = getenv("GST_DEFAULT_V4L2_BUF_MODE");
+ GST_DEBUG("amlmodbuf GST_AML_DEFAULT_V4L2_BUF_MODE:%s", default_mode);
+ //v4l2object->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
+ if (default_mode)
+ {
+ if (strcmp(default_mode, "DMA_BUF_IMPORT") == 0)
+ v4l2object->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
+ else if (strcmp(default_mode, "DMA_BUF") == 0)
+ v4l2object->req_mode = GST_V4L2_IO_DMABUF;
+ GST_DEBUG("amlmodbuf set default buf default_mode:%d", v4l2object->req_mode);
+ }
+ }
- v4l2object->type = type;
- v4l2object->formats = NULL;
+ v4l2object->type = type;
+ v4l2object->formats = NULL;
- v4l2object->element = element;
- v4l2object->dbg_obj = debug_object;
- v4l2object->get_in_out_func = get_in_out_func;
- v4l2object->set_in_out_func = set_in_out_func;
- v4l2object->update_fps_func = update_fps_func;
+ v4l2object->element = element;
+ v4l2object->dbg_obj = debug_object;
+ v4l2object->get_in_out_func = get_in_out_func;
+ v4l2object->set_in_out_func = set_in_out_func;
+ v4l2object->update_fps_func = update_fps_func;
- v4l2object->video_fd = -1;
- v4l2object->active = FALSE;
- v4l2object->videodev = g_strdup(default_device);
+ v4l2object->video_fd = -1;
+ v4l2object->active = FALSE;
+ v4l2object->videodev = g_strdup (default_device);
- v4l2object->norms = NULL;
- v4l2object->channels = NULL;
- v4l2object->colors = NULL;
+ v4l2object->norms = NULL;
+ v4l2object->channels = NULL;
+ v4l2object->colors = NULL;
- v4l2object->keep_aspect = TRUE;
- v4l2object->stream_mode = FALSE;
- v4l2object->secure_es = FALSE;
- v4l2object->have_set_par = FALSE;
- v4l2object->enable_cc_data = FALSE;
- v4l2object->enable_nr = FALSE;
- v4l2object->low_latency_mode = FALSE;
- v4l2object->low_memory_mode = FALSE;
- v4l2object->iframe_mode = FALSE;
+ v4l2object->keep_aspect = TRUE;
+ v4l2object->stream_mode = FALSE;
+ v4l2object->secure_es = FALSE;
+ v4l2object->have_set_par = FALSE;
+ v4l2object->enable_cc_data = FALSE;
+ v4l2object->enable_nr = FALSE;
+ v4l2object->low_latency_mode = FALSE;
+ v4l2object->low_memory_mode = FALSE;
+ v4l2object->iframe_mode = FALSE;
- v4l2object->n_v4l2_planes = 0;
+ v4l2object->n_v4l2_planes = 0;
- v4l2object->no_initial_format = FALSE;
+ v4l2object->no_initial_format = FALSE;
- /* We now disable libv4l2 by default, but have an env to enable it. */
+ /* We now disable libv4l2 by default, but have an env to enable it. */
#ifdef HAVE_LIBV4L2
- if (g_getenv("GST_V4L2_USE_LIBV4L2"))
- {
- v4l2object->fd_open = v4l2_fd_open;
- v4l2object->close = v4l2_close;
- v4l2object->dup = v4l2_dup;
- v4l2object->ioctl = v4l2_ioctl;
- v4l2object->read = v4l2_read;
- v4l2object->mmap = v4l2_mmap;
- v4l2object->munmap = v4l2_munmap;
- }
- else
+ if (g_getenv ("GST_V4L2_USE_LIBV4L2"))
+ {
+ v4l2object->fd_open = v4l2_fd_open;
+ v4l2object->close = v4l2_close;
+ v4l2object->dup = v4l2_dup;
+ v4l2object->ioctl = v4l2_ioctl;
+ v4l2object->read = v4l2_read;
+ v4l2object->mmap = v4l2_mmap;
+ v4l2object->munmap = v4l2_munmap;
+ }
+ else
#endif
- {
- v4l2object->fd_open = NULL;
- v4l2object->close = close;
- v4l2object->dup = dup;
- v4l2object->ioctl = ioctl;
- v4l2object->read = read;
- v4l2object->mmap = mmap;
- v4l2object->munmap = munmap;
- }
- v4l2object->poll = gst_poll_new(TRUE);
- v4l2object->can_wait_event = FALSE;
- v4l2object->can_poll_device = TRUE;
- v4l2object->tvin_port = -1;
+ {
+ v4l2object->fd_open = NULL;
+ v4l2object->close = close;
+ v4l2object->dup = dup;
+ v4l2object->ioctl = ioctl;
+ v4l2object->read = read;
+ v4l2object->mmap = mmap;
+ v4l2object->munmap = munmap;
+ }
+ v4l2object->poll = gst_poll_new (TRUE);
+ v4l2object->can_wait_event = FALSE;
+ v4l2object->can_poll_device = TRUE;
+ v4l2object->tvin_port = -1;
- v4l2object->dumpframefile = NULL;
+ v4l2object->dumpframefile = NULL;
- /* jxsdbg resolution switching */
- v4l2object->old_other_pool = NULL;
- v4l2object->old_old_other_pool = NULL;
- v4l2object->outstanding_buf_num = 0;
- v4l2object->num_error_frames = 0;
- v4l2object->error_frame_pts = 0;
- return v4l2object;
+ /* jxsdbg resolution switching */
+ v4l2object->old_other_pool = NULL;
+ v4l2object->old_old_other_pool = NULL;
+ v4l2object->outstanding_buf_num = 0;
+ v4l2object->num_error_frames = 0;
+ v4l2object->error_frame_pts = 0;
+ return v4l2object;
}
-static gboolean gst_aml_v4l2_object_clear_format_list(GstAmlV4l2Object *v4l2object);
+static gboolean gst_aml_v4l2_object_clear_format_list (GstAmlV4l2Object * v4l2object);
-void gst_aml_v4l2_object_destroy(GstAmlV4l2Object *v4l2object)
+void
+gst_aml_v4l2_object_destroy (GstAmlV4l2Object * v4l2object)
{
- g_return_if_fail(v4l2object != NULL);
+ g_return_if_fail (v4l2object != NULL);
- g_free(v4l2object->videodev);
+ g_free (v4l2object->videodev);
- g_free(v4l2object->channel);
+ g_free (v4l2object->channel);
- if (v4l2object->formats)
- {
- gst_aml_v4l2_object_clear_format_list(v4l2object);
- }
+ if (v4l2object->formats)
+ {
+ gst_aml_v4l2_object_clear_format_list (v4l2object);
+ }
- if (v4l2object->probed_caps)
- {
- gst_caps_unref(v4l2object->probed_caps);
- }
+ if (v4l2object->probed_caps)
+ {
+ gst_caps_unref (v4l2object->probed_caps);
+ }
- if (v4l2object->extra_controls)
- {
- gst_structure_free(v4l2object->extra_controls);
- }
+ if (v4l2object->extra_controls)
+ {
+ gst_structure_free (v4l2object->extra_controls);
+ }
- gst_poll_free(v4l2object->poll);
+ gst_poll_free (v4l2object->poll);
- g_free(v4l2object->dumpframefile);
+ g_free(v4l2object->dumpframefile);
- /* jxsdbg resolution switching */
- if (v4l2object->old_other_pool)
- {
- gst_object_unref(v4l2object->old_other_pool);
- v4l2object->old_other_pool = NULL;
- }
- if (v4l2object->old_old_other_pool)
- {
- gst_object_unref(v4l2object->old_old_other_pool);
- v4l2object->old_old_other_pool = NULL;
- }
- v4l2object->outstanding_buf_num = 0;
+ /* jxsdbg resolution switching */
+ if (v4l2object->old_other_pool)
+ {
+ gst_object_unref(v4l2object->old_other_pool);
+ v4l2object->old_other_pool = NULL;
+ }
+ if (v4l2object->old_old_other_pool)
+ {
+ gst_object_unref(v4l2object->old_old_other_pool);
+ v4l2object->old_old_other_pool = NULL;
+ }
+ v4l2object->outstanding_buf_num = 0;
- g_free(v4l2object);
+ g_free (v4l2object);
}
static gboolean
-gst_aml_v4l2_object_clear_format_list(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_clear_format_list (GstAmlV4l2Object * v4l2object)
{
- g_slist_foreach(v4l2object->formats, (GFunc)g_free, NULL);
- g_slist_free(v4l2object->formats);
- v4l2object->formats = NULL;
+ g_slist_foreach (v4l2object->formats, (GFunc) g_free, NULL);
+ g_slist_free (v4l2object->formats);
+ v4l2object->formats = NULL;
- return TRUE;
+ return TRUE;
}
static gint
-gst_aml_v4l2_object_prop_to_cid(guint prop_id)
+gst_aml_v4l2_object_prop_to_cid (guint prop_id)
{
- gint cid = -1;
+ gint cid = -1;
- switch (prop_id)
- {
+ switch (prop_id)
+ {
case PROP_BRIGHTNESS:
- cid = V4L2_CID_BRIGHTNESS;
- break;
+ cid = V4L2_CID_BRIGHTNESS;
+ break;
case PROP_CONTRAST:
- cid = V4L2_CID_CONTRAST;
- break;
+ cid = V4L2_CID_CONTRAST;
+ break;
case PROP_SATURATION:
- cid = V4L2_CID_SATURATION;
- break;
+ cid = V4L2_CID_SATURATION;
+ break;
case PROP_HUE:
- cid = V4L2_CID_HUE;
- break;
+ cid = V4L2_CID_HUE;
+ break;
default:
- GST_WARNING("unmapped property id: %d", prop_id);
- }
- return cid;
+ GST_WARNING ("unmapped property id: %d", prop_id);
+ }
+ return cid;
}
gboolean
-gst_aml_v4l2_object_set_property_helper(GstAmlV4l2Object *v4l2object,
- guint prop_id, const GValue *value, GParamSpec *pspec)
+gst_aml_v4l2_object_set_property_helper (GstAmlV4l2Object * v4l2object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
{
- switch (prop_id)
- {
+ switch (prop_id)
+ {
case PROP_DEVICE:
- g_free(v4l2object->videodev);
- v4l2object->videodev = g_value_dup_string(value);
- break;
+ g_free (v4l2object->videodev);
+ v4l2object->videodev = g_value_dup_string (value);
+ break;
case PROP_BRIGHTNESS:
case PROP_CONTRAST:
case PROP_SATURATION:
case PROP_HUE:
{
- gint cid = gst_aml_v4l2_object_prop_to_cid(prop_id);
+ gint cid = gst_aml_v4l2_object_prop_to_cid (prop_id);
- if (cid != -1)
+ if (cid != -1)
+ {
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
{
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- {
- gst_aml_v4l2_set_attribute(v4l2object, cid, g_value_get_int(value));
- }
+ gst_aml_v4l2_set_attribute (v4l2object, cid, g_value_get_int (value));
}
- return TRUE;
+ }
+ return TRUE;
}
break;
case PROP_IO_MODE:
- v4l2object->req_mode = g_value_get_enum(value);
- break;
+ v4l2object->req_mode = g_value_get_enum (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;
+ g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+ v4l2object->req_mode = g_value_get_enum (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;
+ g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+ v4l2object->req_mode = g_value_get_enum (value);
+ break;
case PROP_EXTRA_CONTROLS:
{
- const GstStructure *s = gst_value_get_structure(value);
+ const GstStructure *s = gst_value_get_structure (value);
- if (v4l2object->extra_controls)
- gst_structure_free(v4l2object->extra_controls);
+ if (v4l2object->extra_controls)
+ gst_structure_free (v4l2object->extra_controls);
- v4l2object->extra_controls = s ? gst_structure_copy(s) : NULL;
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- gst_aml_v4l2_set_controls(v4l2object, v4l2object->extra_controls);
- break;
+ v4l2object->extra_controls = s ? gst_structure_copy (s) : NULL;
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
+ gst_aml_v4l2_set_controls (v4l2object, v4l2object->extra_controls);
+ break;
}
case PROP_PIXEL_ASPECT_RATIO:
- if (v4l2object->par)
- {
- g_value_unset(v4l2object->par);
- g_free(v4l2object->par);
- }
- v4l2object->par = g_new0(GValue, 1);
- g_value_init(v4l2object->par, GST_TYPE_FRACTION);
- if (!g_value_transform(value, v4l2object->par))
- {
- g_warning("Could not transform string to aspect ratio");
- gst_value_set_fraction(v4l2object->par, 1, 1);
- }
+ if (v4l2object->par)
+ {
+ g_value_unset (v4l2object->par);
+ g_free (v4l2object->par);
+ }
+ v4l2object->par = g_new0 (GValue, 1);
+ g_value_init (v4l2object->par, GST_TYPE_FRACTION);
+ if (!g_value_transform (value, v4l2object->par))
+ {
+ g_warning ("Could not transform string to aspect ratio");
+ gst_value_set_fraction (v4l2object->par, 1, 1);
+ }
v4l2object->have_set_par = TRUE;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "set PAR to %d/%d",
- gst_value_get_fraction_numerator(v4l2object->par),
- gst_value_get_fraction_denominator(v4l2object->par));
- break;
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "set PAR to %d/%d",
+ gst_value_get_fraction_numerator (v4l2object->par),
+ gst_value_get_fraction_denominator (v4l2object->par));
+ break;
case PROP_FORCE_ASPECT_RATIO:
- v4l2object->keep_aspect = g_value_get_boolean(value);
- break;
+ v4l2object->keep_aspect = g_value_get_boolean (value);
+ break;
case PROP_DUMP_FRAME_LOCATION:
g_free(v4l2object->dumpframefile);
v4l2object->dumpframefile = g_value_dup_string(value);
@@ -748,103 +753,103 @@
GST_DEBUG_OBJECT(v4l2object, "set I frame mode: %d",v4l2object->iframe_mode);
break;
default:
- return FALSE;
- break;
- }
- return TRUE;
+ return FALSE;
+ break;
+ }
+ return TRUE;
}
gboolean
-gst_aml_v4l2_object_get_property_helper(GstAmlV4l2Object *v4l2object,
- guint prop_id, GValue *value, GParamSpec *pspec)
+gst_aml_v4l2_object_get_property_helper (GstAmlV4l2Object * v4l2object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
{
- switch (prop_id)
- {
+ switch (prop_id)
+ {
case PROP_DEVICE:
- g_value_set_string(value, v4l2object->videodev);
- break;
+ g_value_set_string (value, v4l2object->videodev);
+ break;
case PROP_DEVICE_NAME:
{
- const guchar *name = NULL;
+ const guchar *name = NULL;
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- name = v4l2object->vcap.card;
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
+ name = v4l2object->vcap.card;
- g_value_set_string(value, (gchar *)name);
- break;
+ g_value_set_string (value, (gchar *) name);
+ break;
}
case PROP_DEVICE_FD:
{
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- g_value_set_int(value, v4l2object->video_fd);
- else
- g_value_set_int(value, DEFAULT_PROP_DEVICE_FD);
- break;
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
+ g_value_set_int (value, v4l2object->video_fd);
+ else
+ g_value_set_int (value, DEFAULT_PROP_DEVICE_FD);
+ break;
}
case PROP_FLAGS:
{
- guint flags = 0;
+ guint flags = 0;
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- {
- flags |= v4l2object->device_caps &
- (V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OUTPUT |
- V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_VBI_OUTPUT | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
+ {
+ flags |= v4l2object->device_caps &
+ (V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_VBI_CAPTURE |
+ V4L2_CAP_VBI_OUTPUT | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
- if (v4l2object->device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
- flags |= V4L2_CAP_VIDEO_CAPTURE;
+ if (v4l2object->device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
+ flags |= V4L2_CAP_VIDEO_CAPTURE;
- if (v4l2object->device_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE)
- flags |= V4L2_CAP_VIDEO_OUTPUT;
- }
- g_value_set_flags(value, flags);
- break;
+ if (v4l2object->device_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE)
+ flags |= V4L2_CAP_VIDEO_OUTPUT;
+ }
+ g_value_set_flags (value, flags);
+ break;
}
case PROP_BRIGHTNESS:
case PROP_CONTRAST:
case PROP_SATURATION:
case PROP_HUE:
{
- gint cid = gst_aml_v4l2_object_prop_to_cid(prop_id);
+ gint cid = gst_aml_v4l2_object_prop_to_cid (prop_id);
- if (cid != -1)
+ if (cid != -1)
+ {
+ if (GST_AML_V4L2_IS_OPEN (v4l2object))
{
- if (GST_AML_V4L2_IS_OPEN(v4l2object))
- {
- gint v;
- if (gst_aml_v4l2_get_attribute(v4l2object, cid, &v))
- {
- g_value_set_int(value, v);
- }
- }
+ gint v;
+ if (gst_aml_v4l2_get_attribute (v4l2object, cid, &v))
+ {
+ g_value_set_int (value, v);
+ }
}
- return TRUE;
+ }
+ return TRUE;
}
- break;
+ break;
case PROP_IO_MODE:
- g_value_set_enum(value, v4l2object->req_mode);
- break;
+ g_value_set_enum (value, v4l2object->req_mode);
+ 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;
+ g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+ g_value_set_enum (value, v4l2object->req_mode);
+ 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;
+ g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
+ g_value_set_enum (value, v4l2object->req_mode);
+ break;
case PROP_EXTRA_CONTROLS:
- gst_value_set_structure(value, v4l2object->extra_controls);
- break;
+ gst_value_set_structure (value, v4l2object->extra_controls);
+ break;
case PROP_PIXEL_ASPECT_RATIO:
- if (v4l2object->par)
- g_value_transform(v4l2object->par, value);
- break;
+ if (v4l2object->par)
+ g_value_transform (v4l2object->par, value);
+ break;
case PROP_FORCE_ASPECT_RATIO:
- g_value_set_boolean(value, v4l2object->keep_aspect);
- break;
+ g_value_set_boolean (value, v4l2object->keep_aspect);
+ break;
case PROP_DUMP_FRAME_LOCATION:
g_value_set_string(value, v4l2object->dumpframefile);
break;
@@ -867,175 +872,172 @@
g_value_set_boolean(value, v4l2object->low_memory_mode);
break;
case PROP_I_FRAME_MODE:
- g_value_set_boolean(value, v4l2object->iframe_mode);
- break;
+ g_value_set_boolean(value, v4l2object->iframe_mode);
+ break;
default:
- return FALSE;
- break;
- }
- return TRUE;
+ return FALSE;
+ break;
+ }
+ return TRUE;
}
static void
-gst_aml_v4l2_get_driver_min_buffers(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_get_driver_min_buffers (GstAmlV4l2Object * v4l2object)
{
- struct v4l2_control control = {
- 0,
- };
+ struct v4l2_control control = { 0, };
- g_return_if_fail(GST_AML_V4L2_IS_OPEN(v4l2object));
+ g_return_if_fail (GST_AML_V4L2_IS_OPEN (v4l2object));
- if (V4L2_TYPE_IS_OUTPUT(v4l2object->type))
- control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
- else
- control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
+ if (V4L2_TYPE_IS_OUTPUT (v4l2object->type))
+ control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
+ else
+ control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_CTRL, &control) == 0)
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "driver requires a minimum of %d buffers", control.value);
- v4l2object->min_buffers = control.value;
- }
- else
- {
- v4l2object->min_buffers = 0;
- }
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) == 0)
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "driver requires a minimum of %d buffers", control.value);
+ v4l2object->min_buffers = control.value;
+ }
+ else
+ {
+ v4l2object->min_buffers = 0;
+ }
}
gboolean
-gst_aml_v4l2_object_open(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_open (GstAmlV4l2Object *v4l2object)
{
- if (!gst_aml_v4l2_open(v4l2object))
- return FALSE;
+ if (!gst_aml_v4l2_open(v4l2object))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
gboolean
-gst_aml_v4l2_object_open_shared(GstAmlV4l2Object *v4l2object, GstAmlV4l2Object *other)
+gst_aml_v4l2_object_open_shared (GstAmlV4l2Object * v4l2object, GstAmlV4l2Object * other)
{
- gboolean ret;
+ gboolean ret;
- ret = gst_aml_v4l2_dup(v4l2object, other);
+ ret = gst_aml_v4l2_dup (v4l2object, other);
+ if (ret && !V4L2_TYPE_IS_OUTPUT (v4l2object->type))
+ {
+ gst_poll_fd_init (&v4l2object->pollfd);
+ v4l2object->pollfd.fd = v4l2object->video_fd;
+ gst_poll_add_fd (v4l2object->poll, &v4l2object->pollfd);
+ /* used for dequeue event */
+ gst_poll_fd_ctl_read (v4l2object->poll, &v4l2object->pollfd, TRUE);
+ gst_poll_fd_ctl_pri (v4l2object->poll, &v4l2object->pollfd, TRUE);
+ }
- if (ret && !V4L2_TYPE_IS_OUTPUT(v4l2object->type))
- {
- gst_poll_fd_init(&v4l2object->pollfd);
- v4l2object->pollfd.fd = v4l2object->video_fd;
- gst_poll_add_fd(v4l2object->poll, &v4l2object->pollfd);
- /* used for dequeue event */
- gst_poll_fd_ctl_read(v4l2object->poll, &v4l2object->pollfd, TRUE);
- gst_poll_fd_ctl_pri(v4l2object->poll, &v4l2object->pollfd, TRUE);
- }
-
- return ret;
+ return ret;
}
gboolean
-gst_aml_v4l2_object_close(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_close (GstAmlV4l2Object * v4l2object)
{
- if (!gst_aml_v4l2_close(v4l2object))
- return FALSE;
+ if (!gst_aml_v4l2_close (v4l2object))
+ return FALSE;
- gst_caps_replace(&v4l2object->probed_caps, NULL);
+ gst_caps_replace (&v4l2object->probed_caps, NULL);
- /* reset our copy of the device caps */
- v4l2object->device_caps = 0;
+ /* reset our copy of the device caps */
+ v4l2object->device_caps = 0;
- if (v4l2object->formats)
- {
- gst_aml_v4l2_object_clear_format_list(v4l2object);
- }
+ if (v4l2object->formats)
+ {
+ gst_aml_v4l2_object_clear_format_list (v4l2object);
+ }
- if (v4l2object->par)
- {
- g_value_unset(v4l2object->par);
- g_free(v4l2object->par);
- v4l2object->par = NULL;
- }
+ if (v4l2object->par)
+ {
+ g_value_unset (v4l2object->par);
+ g_free (v4l2object->par);
+ v4l2object->par = NULL;
+ }
- if (v4l2object->fps)
- {
- g_value_unset(v4l2object->fps);
- g_free(v4l2object->fps);
- v4l2object->fps = NULL;
- }
+ if (v4l2object->fps)
+ {
+ g_value_unset(v4l2object->fps);
+ g_free(v4l2object->fps);
+ v4l2object->fps = NULL;
+ }
- if (v4l2object->channel)
- {
- g_free(v4l2object->channel);
- v4l2object->channel = NULL;
- }
+ if (v4l2object->channel)
+ {
+ g_free (v4l2object->channel);
+ v4l2object->channel = NULL;
+ }
- return TRUE;
+ return TRUE;
}
static struct v4l2_fmtdesc *
-gst_aml_v4l2_object_get_format_from_fourcc(GstAmlV4l2Object *v4l2object,
- guint32 fourcc)
+gst_aml_v4l2_object_get_format_from_fourcc (GstAmlV4l2Object * v4l2object,
+ guint32 fourcc)
{
- struct v4l2_fmtdesc *fmt;
- GSList *walk;
+ struct v4l2_fmtdesc *fmt;
+ GSList *walk;
- if (fourcc == 0)
- return NULL;
-
- walk = gst_aml_v4l2_object_get_format_list(v4l2object);
- while (walk)
- {
- fmt = (struct v4l2_fmtdesc *)walk->data;
- if (fmt->pixelformat == fourcc)
- return fmt;
- /* special case for jpeg */
- if (fmt->pixelformat == V4L2_PIX_FMT_MJPEG ||
- fmt->pixelformat == V4L2_PIX_FMT_JPEG ||
- fmt->pixelformat == V4L2_PIX_FMT_PJPG)
- {
- if (fourcc == V4L2_PIX_FMT_JPEG || fourcc == V4L2_PIX_FMT_MJPEG ||
- fourcc == V4L2_PIX_FMT_PJPG)
- {
- return fmt;
- }
- }
- walk = g_slist_next(walk);
- }
-
+ if (fourcc == 0)
return NULL;
+
+ walk = gst_aml_v4l2_object_get_format_list (v4l2object);
+ while (walk)
+ {
+ fmt = (struct v4l2_fmtdesc *) walk->data;
+ if (fmt->pixelformat == fourcc)
+ return fmt;
+ /* special case for jpeg */
+ if (fmt->pixelformat == V4L2_PIX_FMT_MJPEG ||
+ fmt->pixelformat == V4L2_PIX_FMT_JPEG ||
+ fmt->pixelformat == V4L2_PIX_FMT_PJPG)
+ {
+ if (fourcc == V4L2_PIX_FMT_JPEG || fourcc == V4L2_PIX_FMT_MJPEG ||
+ fourcc == V4L2_PIX_FMT_PJPG)
+ {
+ return fmt;
+ }
+ }
+ walk = g_slist_next (walk);
+ }
+
+ return NULL;
}
/* complete made up ranking, the values themselves are meaningless */
/* These ranks MUST be X such that X<<15 fits on a signed int - see
the comment at the end of gst_aml_v4l2_object_format_get_rank. */
-#define YUV_BASE_RANK 1000
-#define JPEG_BASE_RANK 500
-#define DV_BASE_RANK 200
-#define RGB_BASE_RANK 100
-#define YUV_ODD_BASE_RANK 50
-#define RGB_ODD_BASE_RANK 25
-#define BAYER_BASE_RANK 15
-#define S910_BASE_RANK 10
-#define GREY_BASE_RANK 5
-#define PWC_BASE_RANK 1
+#define YUV_BASE_RANK 1000
+#define JPEG_BASE_RANK 500
+#define DV_BASE_RANK 200
+#define RGB_BASE_RANK 100
+#define YUV_ODD_BASE_RANK 50
+#define RGB_ODD_BASE_RANK 25
+#define BAYER_BASE_RANK 15
+#define S910_BASE_RANK 10
+#define GREY_BASE_RANK 5
+#define PWC_BASE_RANK 1
static gint
-gst_aml_v4l2_object_format_get_rank(const struct v4l2_fmtdesc *fmt)
+gst_aml_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
{
- guint32 fourcc = fmt->pixelformat;
- gboolean emulated = ((fmt->flags & V4L2_FMT_FLAG_EMULATED) != 0);
- gint rank = 0;
+ guint32 fourcc = fmt->pixelformat;
+ gboolean emulated = ((fmt->flags & V4L2_FMT_FLAG_EMULATED) != 0);
+ gint rank = 0;
- switch (fourcc)
- {
+ switch (fourcc)
+ {
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_PJPG:
- rank = JPEG_BASE_RANK;
- break;
+ rank = JPEG_BASE_RANK;
+ break;
case V4L2_PIX_FMT_JPEG:
- rank = JPEG_BASE_RANK + 1;
- break;
- case V4L2_PIX_FMT_MPEG: /* MPEG */
- rank = JPEG_BASE_RANK + 2;
- break;
+ rank = JPEG_BASE_RANK + 1;
+ break;
+ case V4L2_PIX_FMT_MPEG: /* MPEG */
+ rank = JPEG_BASE_RANK + 2;
+ break;
case V4L2_PIX_FMT_RGB332:
case V4L2_PIX_FMT_ARGB555:
@@ -1059,13 +1061,13 @@
case V4L2_PIX_FMT_NV12MT_16X16:
case V4L2_PIX_FMT_NV42:
case V4L2_PIX_FMT_H264_MVC:
- rank = RGB_ODD_BASE_RANK;
- break;
+ rank = RGB_ODD_BASE_RANK;
+ break;
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
- rank = RGB_BASE_RANK - 1;
- break;
+ rank = RGB_BASE_RANK - 1;
+ break;
case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_BGR32:
@@ -1073,112 +1075,112 @@
case V4L2_PIX_FMT_XBGR32:
case V4L2_PIX_FMT_ARGB32:
case V4L2_PIX_FMT_XRGB32:
- rank = RGB_BASE_RANK;
- break;
+ rank = RGB_BASE_RANK;
+ break;
- case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
- rank = GREY_BASE_RANK;
- break;
+ case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
+ rank = GREY_BASE_RANK;
+ break;
case V4L2_PIX_FMT_NV12: /* 12 Y/CbCr 4:2:0 */
case V4L2_PIX_FMT_NV12M: /* Same as NV12 */
- case V4L2_PIX_FMT_NV12MT: /* NV12 64x32 tile */
- case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */
- case V4L2_PIX_FMT_NV21M: /* Same as NV21 */
- case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
- case V4L2_PIX_FMT_HI240: /* 8 8-bit color */
- case V4L2_PIX_FMT_NV16: /* 16 Y/CbCr 4:2:2 */
- case V4L2_PIX_FMT_NV16M: /* Same as NV16 */
- case V4L2_PIX_FMT_NV61: /* 16 Y/CrCb 4:2:2 */
- case V4L2_PIX_FMT_NV61M: /* Same as NV61 */
- case V4L2_PIX_FMT_NV24: /* 24 Y/CrCb 4:4:4 */
- rank = YUV_ODD_BASE_RANK;
- break;
+ case V4L2_PIX_FMT_NV12MT: /* NV12 64x32 tile */
+ case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */
+ case V4L2_PIX_FMT_NV21M: /* Same as NV21 */
+ case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
+ case V4L2_PIX_FMT_HI240: /* 8 8-bit color */
+ case V4L2_PIX_FMT_NV16: /* 16 Y/CbCr 4:2:2 */
+ case V4L2_PIX_FMT_NV16M: /* Same as NV16 */
+ case V4L2_PIX_FMT_NV61: /* 16 Y/CrCb 4:2:2 */
+ case V4L2_PIX_FMT_NV61M: /* Same as NV61 */
+ case V4L2_PIX_FMT_NV24: /* 24 Y/CrCb 4:4:4 */
+ rank = YUV_ODD_BASE_RANK;
+ break;
- case V4L2_PIX_FMT_YVU410: /* YVU9, 9 bits per pixel */
- rank = YUV_BASE_RANK + 3;
- break;
- case V4L2_PIX_FMT_YUV410: /* YUV9, 9 bits per pixel */
- rank = YUV_BASE_RANK + 2;
- break;
- case V4L2_PIX_FMT_YUV420: /* I420, 12 bits per pixel */
+ case V4L2_PIX_FMT_YVU410: /* YVU9, 9 bits per pixel */
+ rank = YUV_BASE_RANK + 3;
+ break;
+ case V4L2_PIX_FMT_YUV410: /* YUV9, 9 bits per pixel */
+ rank = YUV_BASE_RANK + 2;
+ break;
+ case V4L2_PIX_FMT_YUV420: /* I420, 12 bits per pixel */
case V4L2_PIX_FMT_YUV420M:
- rank = YUV_BASE_RANK + 7;
- break;
- case V4L2_PIX_FMT_YUYV: /* YUY2, 16 bits per pixel */
- rank = YUV_BASE_RANK + 10;
- break;
- case V4L2_PIX_FMT_YVU420: /* YV12, 12 bits per pixel */
- rank = YUV_BASE_RANK + 6;
- break;
- case V4L2_PIX_FMT_UYVY: /* UYVY, 16 bits per pixel */
- rank = YUV_BASE_RANK + 9;
- break;
+ rank = YUV_BASE_RANK + 7;
+ break;
+ case V4L2_PIX_FMT_YUYV: /* YUY2, 16 bits per pixel */
+ rank = YUV_BASE_RANK + 10;
+ break;
+ case V4L2_PIX_FMT_YVU420: /* YV12, 12 bits per pixel */
+ rank = YUV_BASE_RANK + 6;
+ break;
+ case V4L2_PIX_FMT_UYVY: /* UYVY, 16 bits per pixel */
+ rank = YUV_BASE_RANK + 9;
+ break;
case V4L2_PIX_FMT_YUV444:
- rank = YUV_BASE_RANK + 6;
- break;
- case V4L2_PIX_FMT_Y41P: /* Y41P, 12 bits per pixel */
- rank = YUV_BASE_RANK + 5;
- break;
+ rank = YUV_BASE_RANK + 6;
+ break;
+ case V4L2_PIX_FMT_Y41P: /* Y41P, 12 bits per pixel */
+ rank = YUV_BASE_RANK + 5;
+ break;
case V4L2_PIX_FMT_YUV411P: /* Y41B, 12 bits per pixel */
- rank = YUV_BASE_RANK + 4;
- break;
+ rank = YUV_BASE_RANK + 4;
+ break;
case V4L2_PIX_FMT_YUV422P: /* Y42B, 16 bits per pixel */
- rank = YUV_BASE_RANK + 8;
- break;
+ rank = YUV_BASE_RANK + 8;
+ break;
case V4L2_PIX_FMT_DV:
- rank = DV_BASE_RANK;
- break;
+ rank = DV_BASE_RANK;
+ break;
- case V4L2_PIX_FMT_WNVA: /* Winnov hw compres */
- rank = 0;
- break;
+ case V4L2_PIX_FMT_WNVA: /* Winnov hw compress */
+ rank = 0;
+ break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
- rank = BAYER_BASE_RANK;
- break;
+ rank = BAYER_BASE_RANK;
+ break;
case V4L2_PIX_FMT_SN9C10X:
- rank = S910_BASE_RANK;
- break;
+ rank = S910_BASE_RANK;
+ break;
case V4L2_PIX_FMT_PWC1:
- rank = PWC_BASE_RANK;
- break;
+ rank = PWC_BASE_RANK;
+ break;
case V4L2_PIX_FMT_PWC2:
- rank = PWC_BASE_RANK;
- break;
+ rank = PWC_BASE_RANK;
+ break;
default:
- rank = 0;
- break;
- }
+ rank = 0;
+ break;
+ }
- /* All ranks are below 1<<15 so a shift by 15
- * will a) make all non-emulated formats larger
- * than emulated and b) will not overflow
- */
- if (!emulated)
- rank <<= 15;
+ /* All ranks are below 1<<15 so a shift by 15
+ * will a) make all non-emulated formats larger
+ * than emulated and b) will not overflow
+ */
+ if (!emulated)
+ rank <<= 15;
- return rank;
+ return rank;
}
static gint
-format_cmp_func(gconstpointer a, gconstpointer b)
+format_cmp_func (gconstpointer a, gconstpointer b)
{
- const struct v4l2_fmtdesc *fa = a;
- const struct v4l2_fmtdesc *fb = b;
+ const struct v4l2_fmtdesc *fa = a;
+ const struct v4l2_fmtdesc *fb = b;
- if (fa->pixelformat == fb->pixelformat)
- return 0;
+ if (fa->pixelformat == fb->pixelformat)
+ return 0;
- return gst_aml_v4l2_object_format_get_rank(fb) -
- gst_aml_v4l2_object_format_get_rank(fa);
+ return gst_aml_v4l2_object_format_get_rank (fb) -
+ gst_aml_v4l2_object_format_get_rank (fa);
}
/******************************************************
@@ -1187,92 +1189,91 @@
* return value: TRUE on success, FALSE on error
******************************************************/
static gboolean
-gst_aml_v4l2_object_fill_format_list(GstAmlV4l2Object *v4l2object,
- enum v4l2_buf_type type)
+gst_aml_v4l2_object_fill_format_list (GstAmlV4l2Object * v4l2object,
+ enum v4l2_buf_type type)
{
- gint n;
- struct v4l2_fmtdesc *format;
+ gint n;
+ struct v4l2_fmtdesc *format;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "getting src format enumerations");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "getting src format enumerations");
- /* format enumeration */
- for (n = 0;; n++)
+ /* format enumeration */
+ for (n = 0;; n++)
+ {
+ format = g_new0 (struct v4l2_fmtdesc, 1);
+
+ format->index = n;
+ format->type = type;
+
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0)
{
- format = g_new0(struct v4l2_fmtdesc, 1);
-
- format->index = n;
- format->type = type;
-
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0)
- {
- if (errno == EINVAL)
- {
- g_free(format);
- break; /* end of enumeration */
- }
- else
- {
- goto failed;
- }
- }
-
- GST_LOG_OBJECT(v4l2object->dbg_obj, "index: %u", format->index);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "type: %d", format->type);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "flags: %08x", format->flags);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "description: '%s'",
- format->description);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "pixelformat: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS(format->pixelformat));
-
-
- if (V4L2_PIX_FMT_YUV420M == format->pixelformat || V4L2_PIX_FMT_YUV420 == format->pixelformat)
- {
- GST_LOG_OBJECT(v4l2object->dbg_obj, "aml v4l2 driver didn't real support YU12 and YM12, ignore it");
- continue;
- }
-
- /* sort formats according to our preference; we do this, because caps
- * are probed in the order the formats are in the list, and the order of
- * formats in the final probed caps matters for things like fixation */
- v4l2object->formats = g_slist_insert_sorted(v4l2object->formats, format,
- (GCompareFunc)format_cmp_func);
+ if (errno == EINVAL)
+ {
+ g_free (format);
+ break; /* end of enumeration */
+ }
+ else
+ {
+ goto failed;
+ }
}
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "index: %u", format->index);
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "type: %d", format->type);
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "flags: %08x", format->flags);
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "description: '%s'",
+ format->description);
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "pixelformat: %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (format->pixelformat));
+
+
+ if (V4L2_PIX_FMT_YUV420M == format->pixelformat || V4L2_PIX_FMT_YUV420 == format->pixelformat)
+ {
+ GST_LOG_OBJECT(v4l2object->dbg_obj, "aml v4l2 driver didn't real support YU12 and YM12, ignore it");
+ continue;
+ }
+
+ /* sort formats according to our preference; we do this, because caps
+ * are probed in the order the formats are in the list, and the order of
+ * formats in the final probed caps matters for things like fixation */
+ v4l2object->formats = g_slist_insert_sorted (v4l2object->formats, format,
+ (GCompareFunc) format_cmp_func);
+ }
+
#ifndef GST_DISABLE_GST_DEBUG
+ {
+ GSList *l;
+
+ GST_INFO_OBJECT (v4l2object->dbg_obj, "got %d format(s):", n);
+ for (l = v4l2object->formats; l != NULL; l = l->next)
{
- GSList *l;
+ format = l->data;
- GST_INFO_OBJECT(v4l2object->dbg_obj, "got %d format(s):", n);
- for (l = v4l2object->formats; l != NULL; l = l->next)
- {
- format = l->data;
-
- GST_INFO_OBJECT(v4l2object->dbg_obj,
- " %" GST_FOURCC_FORMAT "%s", GST_FOURCC_ARGS(format->pixelformat),
- ((format->flags & V4L2_FMT_FLAG_EMULATED)) ? " (emulated)" : "");
- }
+ GST_INFO_OBJECT (v4l2object->dbg_obj,
+ " %" GST_FOURCC_FORMAT "%s", GST_FOURCC_ARGS (format->pixelformat),
+ ((format->flags & V4L2_FMT_FLAG_EMULATED)) ? " (emulated)" : "");
}
+ }
#endif
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
failed:
-{
- g_free(format);
+ {
+ g_free (format);
if (v4l2object->element)
- return FALSE;
+ return FALSE;
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS,
- (_("Failed to enumerate possible video formats device '%s' can work "
- "with"),
- v4l2object->videodev),
- ("Failed to get number %d in pixelformat enumeration for %s. (%d - %s)",
- n, v4l2object->videodev, errno, g_strerror(errno)));
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Failed to enumerate possible video formats device '%s' can work "
+ "with"), v4l2object->videodev),
+ ("Failed to get number %d in pixelformat enumeration for %s. (%d - %s)",
+ n, v4l2object->videodev, errno, g_strerror (errno)));
return FALSE;
-}
+ }
}
/*
@@ -1280,152 +1281,152 @@
* <code>struct v4l2_fmtdesc</code>.
*/
static GSList *
-gst_aml_v4l2_object_get_format_list(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_get_format_list (GstAmlV4l2Object * v4l2object)
{
+ if (!v4l2object->formats)
+ {
+
+ /* check usual way */
+ gst_aml_v4l2_object_fill_format_list (v4l2object, v4l2object->type);
+
+ /* if our driver supports multi-planar
+ * and if formats are still empty then we can workaround driver bug
+ * by also looking up formats as if our device was not supporting
+ * multiplanar */
if (!v4l2object->formats)
{
+ switch (v4l2object->type)
+ {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ gst_aml_v4l2_object_fill_format_list (v4l2object,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ break;
- /* check usual way */
- gst_aml_v4l2_object_fill_format_list(v4l2object, v4l2object->type);
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ gst_aml_v4l2_object_fill_format_list (v4l2object,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ break;
- /* if our driver supports multi-planar
- * and if formats are still empty then we can workaround driver bug
- * by also looking up formats as if our device was not supporting
- * multiplanar */
- if (!v4l2object->formats)
- {
- switch (v4l2object->type)
- {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- gst_aml_v4l2_object_fill_format_list(v4l2object,
- V4L2_BUF_TYPE_VIDEO_CAPTURE);
- break;
-
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- gst_aml_v4l2_object_fill_format_list(v4l2object,
- V4L2_BUF_TYPE_VIDEO_OUTPUT);
- break;
-
- default:
- break;
- }
- }
+ default:
+ break;
+ }
}
- return v4l2object->formats;
+ }
+ return v4l2object->formats;
}
static GstVideoFormat
-gst_aml_v4l2_object_v4l2fourcc_to_video_format(guint32 fourcc)
+gst_aml_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
{
- GstVideoFormat format;
+ GstVideoFormat format;
- switch (fourcc)
- {
- case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
- format = GST_VIDEO_FORMAT_GRAY8;
- break;
+ switch (fourcc)
+ {
+ case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
+ format = GST_VIDEO_FORMAT_GRAY8;
+ break;
case V4L2_PIX_FMT_Y16:
- format = GST_VIDEO_FORMAT_GRAY16_LE;
- break;
+ format = GST_VIDEO_FORMAT_GRAY16_LE;
+ break;
case V4L2_PIX_FMT_Y16_BE:
- format = GST_VIDEO_FORMAT_GRAY16_BE;
- break;
+ format = GST_VIDEO_FORMAT_GRAY16_BE;
+ break;
case V4L2_PIX_FMT_XRGB555:
case V4L2_PIX_FMT_RGB555:
- format = GST_VIDEO_FORMAT_RGB15;
- break;
+ format = GST_VIDEO_FORMAT_RGB15;
+ break;
case V4L2_PIX_FMT_XRGB555X:
case V4L2_PIX_FMT_RGB555X:
- format = GST_VIDEO_FORMAT_BGR15;
- break;
+ format = GST_VIDEO_FORMAT_BGR15;
+ break;
case V4L2_PIX_FMT_RGB565:
- format = GST_VIDEO_FORMAT_RGB16;
- break;
+ format = GST_VIDEO_FORMAT_RGB16;
+ break;
case V4L2_PIX_FMT_RGB24:
- format = GST_VIDEO_FORMAT_RGB;
- break;
+ format = GST_VIDEO_FORMAT_RGB;
+ break;
case V4L2_PIX_FMT_BGR24:
- format = GST_VIDEO_FORMAT_BGR;
- break;
+ format = GST_VIDEO_FORMAT_BGR;
+ break;
case V4L2_PIX_FMT_XRGB32:
case V4L2_PIX_FMT_RGB32:
- format = GST_VIDEO_FORMAT_xRGB;
- break;
+ format = GST_VIDEO_FORMAT_xRGB;
+ break;
case V4L2_PIX_FMT_XBGR32:
case V4L2_PIX_FMT_BGR32:
- format = GST_VIDEO_FORMAT_BGRx;
- break;
+ format = GST_VIDEO_FORMAT_BGRx;
+ break;
case V4L2_PIX_FMT_ABGR32:
- format = GST_VIDEO_FORMAT_BGRA;
- break;
+ format = GST_VIDEO_FORMAT_BGRA;
+ break;
case V4L2_PIX_FMT_ARGB32:
- format = GST_VIDEO_FORMAT_ARGB;
- break;
+ format = GST_VIDEO_FORMAT_ARGB;
+ break;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV12M:
- format = GST_VIDEO_FORMAT_NV12;
- break;
+ format = GST_VIDEO_FORMAT_NV12;
+ break;
case V4L2_PIX_FMT_NV12MT:
- format = GST_VIDEO_FORMAT_NV12_64Z32;
- break;
+ format = GST_VIDEO_FORMAT_NV12_64Z32;
+ break;
case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV21M:
- format = GST_VIDEO_FORMAT_NV21;
- break;
+ format = GST_VIDEO_FORMAT_NV21;
+ break;
case V4L2_PIX_FMT_YVU410:
- format = GST_VIDEO_FORMAT_YVU9;
- break;
+ format = GST_VIDEO_FORMAT_YVU9;
+ break;
case V4L2_PIX_FMT_YUV410:
- format = GST_VIDEO_FORMAT_YUV9;
- break;
+ format = GST_VIDEO_FORMAT_YUV9;
+ break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YUV420M:
- format = GST_VIDEO_FORMAT_I420;
- break;
+ format = GST_VIDEO_FORMAT_I420;
+ break;
case V4L2_PIX_FMT_YUYV:
- format = GST_VIDEO_FORMAT_YUY2;
- break;
+ format = GST_VIDEO_FORMAT_YUY2;
+ break;
case V4L2_PIX_FMT_YVU420:
- format = GST_VIDEO_FORMAT_YV12;
- break;
+ format = GST_VIDEO_FORMAT_YV12;
+ break;
case V4L2_PIX_FMT_UYVY:
- format = GST_VIDEO_FORMAT_UYVY;
- break;
+ format = GST_VIDEO_FORMAT_UYVY;
+ break;
case V4L2_PIX_FMT_YUV411P:
- format = GST_VIDEO_FORMAT_Y41B;
- break;
+ format = GST_VIDEO_FORMAT_Y41B;
+ break;
case V4L2_PIX_FMT_YUV422P:
- format = GST_VIDEO_FORMAT_Y42B;
- break;
+ format = GST_VIDEO_FORMAT_Y42B;
+ break;
case V4L2_PIX_FMT_YVYU:
- format = GST_VIDEO_FORMAT_YVYU;
- break;
+ format = GST_VIDEO_FORMAT_YVYU;
+ break;
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV16M:
- format = GST_VIDEO_FORMAT_NV16;
- break;
+ format = GST_VIDEO_FORMAT_NV16;
+ break;
case V4L2_PIX_FMT_NV61:
case V4L2_PIX_FMT_NV61M:
- format = GST_VIDEO_FORMAT_NV61;
- break;
+ format = GST_VIDEO_FORMAT_NV61;
+ break;
case V4L2_PIX_FMT_NV24:
- format = GST_VIDEO_FORMAT_NV24;
- break;
+ format = GST_VIDEO_FORMAT_NV24;
+ break;
default:
- format = GST_VIDEO_FORMAT_UNKNOWN;
- break;
- }
+ format = GST_VIDEO_FORMAT_UNKNOWN;
+ break;
+ }
- return format;
+ return format;
}
static gboolean
-gst_amL_v4l2_object_v4l2fourcc_is_rgb(guint32 fourcc)
+gst_aml_v4l2_object_v4l2fourcc_is_rgb (guint32 fourcc)
{
- gboolean ret = FALSE;
+ gboolean ret = FALSE;
- switch (fourcc)
- {
+ switch (fourcc)
+ {
case V4L2_PIX_FMT_XRGB555:
case V4L2_PIX_FMT_RGB555:
case V4L2_PIX_FMT_XRGB555X:
@@ -1443,76 +1444,77 @@
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
- ret = TRUE;
- break;
+ ret = TRUE;
+ break;
default:
- break;
- }
+ break;
+ }
- return ret;
+ return ret;
}
static GstStructure *
-gst_aml_v4l2_object_v4l2fourcc_to_bare_struct(guint32 fourcc)
+gst_aml_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
{
- GstStructure *structure = NULL;
+ GstStructure *structure = NULL;
- switch (fourcc)
- {
- case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */
- structure = gst_structure_new_empty("video/mjpeg");
- break;
+ switch (fourcc)
+ {
+ case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */
+ structure = gst_structure_new_empty("video/mjpeg");
+ break;
case V4L2_PIX_FMT_MPEG1:
- structure = gst_structure_new("video/mpeg",
- "mpegversion", G_TYPE_INT, 1, NULL);
- gst_structure_set(structure, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- GST_DEBUG("aml set mpeg1 systemstream to false");
- break;
+ structure = gst_structure_new ("video/mpeg",
+ "mpegversion", G_TYPE_INT, 1, NULL);
+
+ gst_structure_set(structure, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
+ GST_DEBUG("aml set mpeg1 systemstream to false");
+ break;
case V4L2_PIX_FMT_MPEG2:
- structure = gst_structure_new("video/mpeg",
- "mpegversion", G_TYPE_INT, 2, NULL);
- gst_structure_set(structure, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- GST_DEBUG("aml set mpeg2 systemstream to false");
- break;
+ structure = gst_structure_new("video/mpeg",
+ "mpegversion", G_TYPE_INT, 2, NULL);
+ gst_structure_set(structure, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
+ GST_DEBUG("aml set mpeg2 systemstream to false");
+ break;
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_XVID:
- structure = gst_structure_new("video/mpeg",
- "mpegversion", G_TYPE_INT, 4, "systemstream",
- G_TYPE_BOOLEAN, FALSE, NULL);
- break;
+ structure = gst_structure_new ("video/mpeg",
+ "mpegversion", G_TYPE_INT, 4, "systemstream",
+ G_TYPE_BOOLEAN, FALSE, NULL);
+ break;
case V4L2_PIX_FMT_FWHT:
- structure = gst_structure_new_empty("video/x-fwht");
- break;
+ structure = gst_structure_new_empty ("video/x-fwht");
+ break;
case V4L2_PIX_FMT_H263:
- structure = gst_structure_new("video/x-h263",
- "variant", G_TYPE_STRING, "itu", NULL);
- break;
- case V4L2_PIX_FMT_H264: /* H.264 */
- structure = gst_structure_new("video/x-h264",
- "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
- G_TYPE_STRING, "au", NULL);
- break;
+ structure = gst_structure_new ("video/x-h263",
+ "variant", G_TYPE_STRING, "itu", NULL);
+ break;
+ case V4L2_PIX_FMT_H264: /* H.264 */
+ structure = gst_structure_new ("video/x-h264",
+ "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
+ G_TYPE_STRING, "au", NULL);
+ break;
case V4L2_PIX_FMT_H264_NO_SC:
- structure = gst_structure_new("video/x-h264",
- "stream-format", G_TYPE_STRING, "avc", "alignment",
- G_TYPE_STRING, "au", NULL);
- break;
- case V4L2_PIX_FMT_HEVC: /* H.265 */
- structure = gst_structure_new("video/x-h265",
- "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
- G_TYPE_STRING, "au", NULL);
- break;
+ structure = gst_structure_new ("video/x-h264",
+ "stream-format", G_TYPE_STRING, "avc", "alignment",
+ G_TYPE_STRING, "au", NULL);
+ break;
+ case V4L2_PIX_FMT_HEVC: /* H.265 */
+ structure = gst_structure_new ("video/x-h265",
+ "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
+ G_TYPE_STRING, "au", NULL);
+ break;
case V4L2_PIX_FMT_VC1_ANNEX_G:
case V4L2_PIX_FMT_VC1_ANNEX_L:
- structure = gst_structure_new("video/x-wmv",
- "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
- break;
+ structure = gst_structure_new ("video/x-wmv",
+ "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
+ break;
case V4L2_PIX_FMT_VP8:
- structure = gst_structure_new_empty("video/x-vp8");
- break;
+ structure = gst_structure_new_empty ("video/x-vp8");
+ break;
case V4L2_PIX_FMT_VP9:
- structure = gst_structure_new_empty("video/x-vp9");
- break;
+ structure = gst_structure_new_empty ("video/x-vp9");
+ break;
case V4L2_PIX_FMT_AV1:
structure = gst_structure_new_empty("video/x-av1");
break;
@@ -1525,7 +1527,7 @@
case V4L2_PIX_FMT_AVS3:
structure = gst_structure_new_empty("video/x-avs3");
break;
- case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
+ case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
case V4L2_PIX_FMT_XRGB555:
@@ -1541,19 +1543,19 @@
case V4L2_PIX_FMT_BGR32:
case V4L2_PIX_FMT_XBGR32:
case V4L2_PIX_FMT_ABGR32:
- case V4L2_PIX_FMT_NV12: /* 12 Y/CbCr 4:2:0 */
+ case V4L2_PIX_FMT_NV12: /* 12 Y/CbCr 4:2:0 */
case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_NV12MT:
- case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */
+ case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */
case V4L2_PIX_FMT_NV21M:
- case V4L2_PIX_FMT_NV16: /* 16 Y/CbCr 4:2:2 */
+ case V4L2_PIX_FMT_NV16: /* 16 Y/CbCr 4:2:2 */
case V4L2_PIX_FMT_NV16M:
- case V4L2_PIX_FMT_NV61: /* 16 Y/CrCb 4:2:2 */
+ case V4L2_PIX_FMT_NV61: /* 16 Y/CrCb 4:2:2 */
case V4L2_PIX_FMT_NV61M:
- case V4L2_PIX_FMT_NV24: /* 24 Y/CrCb 4:4:4 */
+ case V4L2_PIX_FMT_NV24: /* 24 Y/CrCb 4:4:4 */
case V4L2_PIX_FMT_YVU410:
case V4L2_PIX_FMT_YUV410:
- case V4L2_PIX_FMT_YUV420: /* I420/IYUV */
+ case V4L2_PIX_FMT_YUV420: /* I420/IYUV */
case V4L2_PIX_FMT_YUV420M:
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVU420:
@@ -1562,51 +1564,50 @@
case V4L2_PIX_FMT_YVYU:
case V4L2_PIX_FMT_YUV411P:
{
- GstVideoFormat format;
- format = gst_aml_v4l2_object_v4l2fourcc_to_video_format(fourcc);
- if (format != GST_VIDEO_FORMAT_UNKNOWN)
- structure = gst_structure_new("video/x-raw",
- "format", G_TYPE_STRING, gst_video_format_to_string(format), NULL);
- break;
+ GstVideoFormat format;
+ format = gst_aml_v4l2_object_v4l2fourcc_to_video_format (fourcc);
+ if (format != GST_VIDEO_FORMAT_UNKNOWN)
+ structure = gst_structure_new ("video/x-raw",
+ "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
+ break;
}
case V4L2_PIX_FMT_DV:
- structure =
- gst_structure_new("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE,
- NULL);
- break;
- case V4L2_PIX_FMT_MPEG: /* MPEG */
- structure = gst_structure_new("video/mpegts",
- "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- case V4L2_PIX_FMT_WNVA: /* Winnov hw compres */
- break;
+ structure =
+ gst_structure_new ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE,
+ NULL);
+ break;
+ case V4L2_PIX_FMT_MPEG: /* MPEG */
+ structure = gst_structure_new ("video/mpegts",
+ "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
+ break;
+ case V4L2_PIX_FMT_WNVA: /* Winnov hw compress */
+ break;
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
- structure = gst_structure_new("video/x-bayer", "format", G_TYPE_STRING,
- fourcc == V4L2_PIX_FMT_SBGGR8 ? "bggr" : fourcc == V4L2_PIX_FMT_SGBRG8 ? "gbrg"
- : fourcc == V4L2_PIX_FMT_SGRBG8 ? "grbg"
- :
- /* fourcc == V4L2_PIX_FMT_SRGGB8 ? */ "rggb",
- NULL);
- break;
+ structure = gst_structure_new ("video/x-bayer", "format", G_TYPE_STRING,
+ fourcc == V4L2_PIX_FMT_SBGGR8 ? "bggr" :
+ fourcc == V4L2_PIX_FMT_SGBRG8 ? "gbrg" :
+ fourcc == V4L2_PIX_FMT_SGRBG8 ? "grbg" :
+ /* fourcc == V4L2_PIX_FMT_SRGGB8 ? */ "rggb", NULL);
+ break;
case V4L2_PIX_FMT_SN9C10X:
- structure = gst_structure_new_empty("video/x-sonix");
- break;
+ structure = gst_structure_new_empty ("video/x-sonix");
+ break;
case V4L2_PIX_FMT_PWC1:
- structure = gst_structure_new_empty("video/x-pwc1");
- break;
+ structure = gst_structure_new_empty ("video/x-pwc1");
+ break;
case V4L2_PIX_FMT_PWC2:
- structure = gst_structure_new_empty("video/x-pwc2");
- break;
+ structure = gst_structure_new_empty ("video/x-pwc2");
+ break;
case V4L2_PIX_FMT_RGB332:
case V4L2_PIX_FMT_BGR666:
case V4L2_PIX_FMT_ARGB555X:
case V4L2_PIX_FMT_RGB565X:
case V4L2_PIX_FMT_RGB444:
- case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
- case V4L2_PIX_FMT_HI240: /* 8 8-bit color */
+ case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
+ case V4L2_PIX_FMT_HI240: /* 8 8-bit color */
case V4L2_PIX_FMT_Y4:
case V4L2_PIX_FMT_Y6:
case V4L2_PIX_FMT_Y10:
@@ -1621,139 +1622,139 @@
case V4L2_PIX_FMT_NV42:
case V4L2_PIX_FMT_H264_MVC:
default:
- GST_DEBUG("Unsupported fourcc 0x%08x %" GST_FOURCC_FORMAT,
- fourcc, GST_FOURCC_ARGS(fourcc));
- break;
- }
+ GST_DEBUG ("Unsupported fourcc 0x%08x %" GST_FOURCC_FORMAT,
+ fourcc, GST_FOURCC_ARGS (fourcc));
+ break;
+ }
- return structure;
+ return structure;
}
GstStructure *
-gst_aml_v4l2_object_v4l2fourcc_to_structure(guint32 fourcc)
+gst_aml_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
{
- GstStructure *template;
- gint i;
+ GstStructure *template;
+ gint i;
- template = gst_aml_v4l2_object_v4l2fourcc_to_bare_struct(fourcc);
+ template = gst_aml_v4l2_object_v4l2fourcc_to_bare_struct (fourcc);
- if (template == NULL)
- goto done;
+ if (template == NULL)
+ goto done;
- for (i = 0; i < GST_AML_V4L2_FORMAT_COUNT; i++)
+ for (i = 0; i < GST_AML_V4L2_FORMAT_COUNT; i++)
+ {
+ if (gst_aml_v4l2_formats[i].format != fourcc)
+ continue;
+
+ if (gst_aml_v4l2_formats[i].dimensions)
{
- if (gst_aml_v4l2_formats[i].format != fourcc)
- continue;
-
- if (gst_aml_v4l2_formats[i].dimensions)
- {
- gst_structure_set(template,
- "width", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
- "height", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
- }
- break;
+ gst_structure_set (template,
+ "width", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
+ "height", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
}
+ break;
+ }
done:
- return template;
+ return template;
}
static GstCaps *
-gst_aml_v4l2_object_get_caps_helper(GstAmlV4L2FormatFlags flags)
+gst_aml_v4l2_object_get_caps_helper (GstAmlV4L2FormatFlags flags)
{
- GstStructure *structure;
- GstCaps *caps;
- guint i;
+ GstStructure *structure;
+ GstCaps *caps;
+ guint i;
- caps = gst_caps_new_empty();
- for (i = 0; i < GST_AML_V4L2_FORMAT_COUNT; i++)
+ caps = gst_caps_new_empty ();
+ for (i = 0; i < GST_AML_V4L2_FORMAT_COUNT; i++)
+ {
+
+ if ((gst_aml_v4l2_formats[i].flags & flags) == 0)
+ continue;
+
+ structure =
+ gst_aml_v4l2_object_v4l2fourcc_to_bare_struct (gst_aml_v4l2_formats[i].format);
+
+ if (structure)
{
+ GstStructure *alt_s = NULL;
- if ((gst_aml_v4l2_formats[i].flags & flags) == 0)
- continue;
+ if (gst_aml_v4l2_formats[i].dimensions)
+ {
+ gst_structure_set (structure,
+ "width", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
+ "height", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+ }
- structure =
- gst_aml_v4l2_object_v4l2fourcc_to_bare_struct(gst_aml_v4l2_formats[i].format);
+ switch (gst_aml_v4l2_formats[i].format)
+ {
+ case V4L2_PIX_FMT_RGB32:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
+ default:
+ break;
+ }
- if (structure)
- {
- GstStructure *alt_s = NULL;
+ gst_caps_append_structure (caps, structure);
- if (gst_aml_v4l2_formats[i].dimensions)
- {
- gst_structure_set(structure,
- "width", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
- "height", GST_TYPE_INT_RANGE, 1, GST_AML_V4L2_MAX_SIZE,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
- }
-
- switch (gst_aml_v4l2_formats[i].format)
- {
- case V4L2_PIX_FMT_RGB32:
- alt_s = gst_structure_copy(structure);
- gst_structure_set(alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
- break;
- case V4L2_PIX_FMT_BGR32:
- alt_s = gst_structure_copy(structure);
- gst_structure_set(alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
- default:
- break;
- }
-
- gst_caps_append_structure(caps, structure);
-
- if (alt_s)
- gst_caps_append_structure(caps, alt_s);
- }
+ if (alt_s)
+ gst_caps_append_structure (caps, alt_s);
}
+ }
- return gst_caps_simplify(caps);
+ return gst_caps_simplify(caps);
}
GstCaps *
-gst_aml_v4l2_object_get_all_caps(void)
+gst_aml_v4l2_object_get_all_caps (void)
{
- static GstCaps *caps = NULL;
+ static GstCaps *caps = NULL;
- if (g_once_init_enter(&caps))
- {
- GstCaps *all_caps = gst_aml_v4l2_object_get_caps_helper(GST_V4L2_ALL);
- GST_MINI_OBJECT_FLAG_SET(all_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
- g_once_init_leave(&caps, all_caps);
- }
+ if (g_once_init_enter (&caps))
+ {
+ GstCaps *all_caps = gst_aml_v4l2_object_get_caps_helper (GST_V4L2_ALL);
+ GST_MINI_OBJECT_FLAG_SET (all_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+ g_once_init_leave (&caps, all_caps);
+ }
- return caps;
+ return caps;
}
GstCaps *
-gst_aml_v4l2_object_get_raw_caps(void)
+gst_aml_v4l2_object_get_raw_caps (void)
{
- static GstCaps *caps = NULL;
+ static GstCaps *caps = NULL;
- if (g_once_init_enter(&caps))
- {
- GstCaps *raw_caps = gst_aml_v4l2_object_get_caps_helper(GST_V4L2_RAW);
- GST_MINI_OBJECT_FLAG_SET(raw_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
- g_once_init_leave(&caps, raw_caps);
- }
+ if (g_once_init_enter (&caps))
+ {
+ GstCaps *raw_caps = gst_aml_v4l2_object_get_caps_helper (GST_V4L2_RAW);
+ GST_MINI_OBJECT_FLAG_SET (raw_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+ g_once_init_leave (&caps, raw_caps);
+ }
- return caps;
+ return caps;
}
GstCaps *
-gst_aml_v4l2_object_get_codec_caps(void)
+gst_aml_v4l2_object_get_codec_caps (void)
{
- static GstCaps *caps = NULL;
+ static GstCaps *caps = NULL;
- if (g_once_init_enter(&caps))
- {
- GstCaps *codec_caps = gst_aml_v4l2_object_get_caps_helper(GST_V4L2_CODEC);
- GST_MINI_OBJECT_FLAG_SET(codec_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
- g_once_init_leave(&caps, codec_caps);
- }
+ if (g_once_init_enter (&caps))
+ {
+ GstCaps *codec_caps = gst_aml_v4l2_object_get_caps_helper (GST_V4L2_CODEC);
+ GST_MINI_OBJECT_FLAG_SET (codec_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+ g_once_init_leave (&caps, codec_caps);
+ }
- return caps;
+ return caps;
}
/* collect data for the given caps
@@ -1764,1137 +1765,1125 @@
* @size: location for expected size of the frame or 0 if unknown
*/
static gboolean
-gst_aml_v4l2_object_get_caps_info(GstAmlV4l2Object *v4l2object, GstCaps *caps,
- struct v4l2_fmtdesc **format, GstVideoInfo *info)
+gst_aml_v4l2_object_get_caps_info (GstAmlV4l2Object * v4l2object, GstCaps * caps,
+ struct v4l2_fmtdesc **format, GstVideoInfo * info)
{
- GstStructure *structure;
- guint32 fourcc = 0, fourcc_nc = 0;
- const gchar *mimetype;
- struct v4l2_fmtdesc *fmt = NULL;
+ GstStructure *structure;
+ guint32 fourcc = 0, fourcc_nc = 0;
+ const gchar *mimetype;
+ struct v4l2_fmtdesc *fmt = NULL;
- GST_DEBUG_OBJECT(v4l2object, "got caps: %" GST_PTR_FORMAT, caps);
+ GST_DEBUG_OBJECT(v4l2object, "got caps: %" GST_PTR_FORMAT, caps);
- structure = gst_caps_get_structure(caps, 0);
+ structure = gst_caps_get_structure (caps, 0);
- mimetype = gst_structure_get_name(structure);
+ mimetype = gst_structure_get_name (structure);
- if (!gst_video_info_from_caps(info, caps))
- goto invalid_format;
+ if (!gst_video_info_from_caps (info, caps))
+ goto invalid_format;
- if (g_str_equal(mimetype, "video/x-raw"))
+ if (g_str_equal (mimetype, "video/x-raw"))
+ {
+ switch (GST_VIDEO_INFO_FORMAT (info))
{
- switch (GST_VIDEO_INFO_FORMAT(info))
+ case GST_VIDEO_FORMAT_I420:
+ fourcc = V4L2_PIX_FMT_YUV420;
+ fourcc_nc = V4L2_PIX_FMT_YUV420M;
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ fourcc = V4L2_PIX_FMT_YUYV;
+ break;
+ case GST_VIDEO_FORMAT_UYVY:
+ fourcc = V4L2_PIX_FMT_UYVY;
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ fourcc = V4L2_PIX_FMT_YVU420;
+ break;
+ case GST_VIDEO_FORMAT_Y41B:
+ fourcc = V4L2_PIX_FMT_YUV411P;
+ break;
+ case GST_VIDEO_FORMAT_Y42B:
+ fourcc = V4L2_PIX_FMT_YUV422P;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ fourcc = V4L2_PIX_FMT_NV12;
+ fourcc_nc = V4L2_PIX_FMT_NV12M;
+ break;
+ case GST_VIDEO_FORMAT_NV12_64Z32:
+ fourcc_nc = V4L2_PIX_FMT_NV12MT;
+ break;
+ case GST_VIDEO_FORMAT_NV21:
+ fourcc = V4L2_PIX_FMT_NV21;
+ fourcc_nc = V4L2_PIX_FMT_NV21M;
+ break;
+ case GST_VIDEO_FORMAT_NV16:
+ fourcc = V4L2_PIX_FMT_NV16;
+ fourcc_nc = V4L2_PIX_FMT_NV16M;
+ break;
+ case GST_VIDEO_FORMAT_NV61:
+ fourcc = V4L2_PIX_FMT_NV61;
+ fourcc_nc = V4L2_PIX_FMT_NV61M;
+ break;
+ case GST_VIDEO_FORMAT_NV24:
+ fourcc = V4L2_PIX_FMT_NV24;
+ break;
+ case GST_VIDEO_FORMAT_YVYU:
+ fourcc = V4L2_PIX_FMT_YVYU;
+ break;
+ case GST_VIDEO_FORMAT_RGB15:
+ fourcc = V4L2_PIX_FMT_RGB555;
+ fourcc_nc = V4L2_PIX_FMT_XRGB555;
+ break;
+ case GST_VIDEO_FORMAT_RGB16:
+ fourcc = V4L2_PIX_FMT_RGB565;
+ break;
+ case GST_VIDEO_FORMAT_RGB:
+ fourcc = V4L2_PIX_FMT_RGB24;
+ break;
+ case GST_VIDEO_FORMAT_BGR:
+ fourcc = V4L2_PIX_FMT_BGR24;
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ fourcc = V4L2_PIX_FMT_RGB32;
+ fourcc_nc = V4L2_PIX_FMT_XRGB32;
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ fourcc = V4L2_PIX_FMT_RGB32;
+ fourcc_nc = V4L2_PIX_FMT_ARGB32;
+ break;
+ case GST_VIDEO_FORMAT_BGRx:
+ fourcc = V4L2_PIX_FMT_BGR32;
+ fourcc_nc = V4L2_PIX_FMT_XBGR32;
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ fourcc = V4L2_PIX_FMT_BGR32;
+ fourcc_nc = V4L2_PIX_FMT_ABGR32;
+ break;
+ case GST_VIDEO_FORMAT_GRAY8:
+ fourcc = V4L2_PIX_FMT_GREY;
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ fourcc = V4L2_PIX_FMT_Y16;
+ break;
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ fourcc = V4L2_PIX_FMT_Y16_BE;
+ break;
+ case GST_VIDEO_FORMAT_BGR15:
+ fourcc = V4L2_PIX_FMT_RGB555X;
+ fourcc_nc = V4L2_PIX_FMT_XRGB555X;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (g_str_equal (mimetype, "video/mpegts"))
+ {
+ fourcc = V4L2_PIX_FMT_MPEG;
+ }
+ else if (g_str_equal (mimetype, "video/x-dv"))
+ {
+ fourcc = V4L2_PIX_FMT_DV;
+ }
+ else if (g_str_equal(mimetype, "video/mjpeg"))
+ {
+ fourcc = V4L2_PIX_FMT_JPEG;
+ }
+ else if (g_str_equal (mimetype, "video/mpeg"))
+ {
+ gint version;
+ if (gst_structure_get_int (structure, "mpegversion", &version))
+ {
+ switch (version)
{
- case GST_VIDEO_FORMAT_I420:
- fourcc = V4L2_PIX_FMT_YUV420;
- fourcc_nc = V4L2_PIX_FMT_YUV420M;
+ case 1:
+ fourcc = V4L2_PIX_FMT_MPEG1;
break;
- case GST_VIDEO_FORMAT_YUY2:
- fourcc = V4L2_PIX_FMT_YUYV;
+ case 2:
+ fourcc = V4L2_PIX_FMT_MPEG2;
break;
- case GST_VIDEO_FORMAT_UYVY:
- fourcc = V4L2_PIX_FMT_UYVY;
+ case 4:
+ fourcc = V4L2_PIX_FMT_MPEG4;
+ fourcc_nc = V4L2_PIX_FMT_XVID;
break;
- case GST_VIDEO_FORMAT_YV12:
- fourcc = V4L2_PIX_FMT_YVU420;
- break;
- case GST_VIDEO_FORMAT_Y41B:
- fourcc = V4L2_PIX_FMT_YUV411P;
- break;
- case GST_VIDEO_FORMAT_Y42B:
- fourcc = V4L2_PIX_FMT_YUV422P;
- break;
- case GST_VIDEO_FORMAT_NV12:
- fourcc = V4L2_PIX_FMT_NV12;
- fourcc_nc = V4L2_PIX_FMT_NV12M;
- break;
- case GST_VIDEO_FORMAT_NV12_64Z32:
- fourcc_nc = V4L2_PIX_FMT_NV12MT;
- break;
- case GST_VIDEO_FORMAT_NV21:
- fourcc = V4L2_PIX_FMT_NV21;
- fourcc_nc = V4L2_PIX_FMT_NV21M;
- break;
- case GST_VIDEO_FORMAT_NV16:
- fourcc = V4L2_PIX_FMT_NV16;
- fourcc_nc = V4L2_PIX_FMT_NV16M;
- break;
- case GST_VIDEO_FORMAT_NV61:
- fourcc = V4L2_PIX_FMT_NV61;
- fourcc_nc = V4L2_PIX_FMT_NV61M;
- break;
- case GST_VIDEO_FORMAT_NV24:
- fourcc = V4L2_PIX_FMT_NV24;
- break;
- case GST_VIDEO_FORMAT_YVYU:
- fourcc = V4L2_PIX_FMT_YVYU;
- break;
- case GST_VIDEO_FORMAT_RGB15:
- fourcc = V4L2_PIX_FMT_RGB555;
- fourcc_nc = V4L2_PIX_FMT_XRGB555;
- break;
- case GST_VIDEO_FORMAT_RGB16:
- fourcc = V4L2_PIX_FMT_RGB565;
- break;
- case GST_VIDEO_FORMAT_RGB:
- fourcc = V4L2_PIX_FMT_RGB24;
- break;
- case GST_VIDEO_FORMAT_BGR:
- fourcc = V4L2_PIX_FMT_BGR24;
- break;
- case GST_VIDEO_FORMAT_xRGB:
- fourcc = V4L2_PIX_FMT_RGB32;
- fourcc_nc = V4L2_PIX_FMT_XRGB32;
- break;
- case GST_VIDEO_FORMAT_ARGB:
- fourcc = V4L2_PIX_FMT_RGB32;
- fourcc_nc = V4L2_PIX_FMT_ARGB32;
- break;
- case GST_VIDEO_FORMAT_BGRx:
- fourcc = V4L2_PIX_FMT_BGR32;
- fourcc_nc = V4L2_PIX_FMT_XBGR32;
- break;
- case GST_VIDEO_FORMAT_BGRA:
- fourcc = V4L2_PIX_FMT_BGR32;
- fourcc_nc = V4L2_PIX_FMT_ABGR32;
- break;
- case GST_VIDEO_FORMAT_GRAY8:
- fourcc = V4L2_PIX_FMT_GREY;
- break;
- case GST_VIDEO_FORMAT_GRAY16_LE:
- fourcc = V4L2_PIX_FMT_Y16;
- break;
- case GST_VIDEO_FORMAT_GRAY16_BE:
- fourcc = V4L2_PIX_FMT_Y16_BE;
- break;
- case GST_VIDEO_FORMAT_BGR15:
- fourcc = V4L2_PIX_FMT_RGB555X;
- fourcc_nc = V4L2_PIX_FMT_XRGB555X;
- break;
- default:
+ default:
break;
}
+ }
+ }
+ else if (g_str_equal (mimetype, "video/x-fwht"))
+ {
+ fourcc = V4L2_PIX_FMT_FWHT;
+ }
+ else if (g_str_equal (mimetype, "video/x-h263"))
+ {
+ fourcc = V4L2_PIX_FMT_H263;
+ }
+ else if (g_str_equal (mimetype, "video/x-h264"))
+ {
+ const gchar *stream_format =
+ gst_structure_get_string (structure, "stream-format");
+ if (g_str_equal (stream_format, "avc"))
+ fourcc = V4L2_PIX_FMT_H264_NO_SC;
+ else
+ fourcc = V4L2_PIX_FMT_H264;
+ }
+ else if (g_str_equal (mimetype, "video/x-h265"))
+ {
+ fourcc = V4L2_PIX_FMT_HEVC;
+ }
+ else if (g_str_equal (mimetype, "video/x-vp8"))
+ {
+ fourcc = V4L2_PIX_FMT_VP8;
+ }
+ else if (g_str_equal (mimetype, "video/x-vp9"))
+ {
+ fourcc = V4L2_PIX_FMT_VP9;
+ }
+ else if (g_str_equal(mimetype, "video/x-av1"))
+ {
+ fourcc = V4L2_PIX_FMT_AV1;
+ }
+ else if (g_str_equal(mimetype, "video/x-avs"))
+ {
+ fourcc = V4L2_PIX_FMT_AVS;
+ }
+ else if (g_str_equal(mimetype, "video/x-avs2"))
+ {
+ fourcc = V4L2_PIX_FMT_AVS2;
+ }
+ else if (g_str_equal(mimetype, "video/x-avs3"))
+ {
+ fourcc = V4L2_PIX_FMT_AVS3;
+ }
+ else if (g_str_equal (mimetype, "video/x-bayer"))
+ {
+ const gchar *vformat = gst_structure_get_string(structure, "format");
+ if (vformat)
+ {
+ if (!g_ascii_strcasecmp(vformat, "bggr"))
+ fourcc = V4L2_PIX_FMT_SBGGR8;
+ else if (!g_ascii_strcasecmp(vformat, "gbrg"))
+ fourcc = V4L2_PIX_FMT_SGBRG8;
+ else if (!g_ascii_strcasecmp(vformat, "grbg"))
+ fourcc = V4L2_PIX_FMT_SGRBG8;
+ else if (!g_ascii_strcasecmp(vformat, "rggb"))
+ fourcc = V4L2_PIX_FMT_SRGGB8;
+ }
+ }
+ else if (g_str_equal (mimetype, "video/x-sonix"))
+ {
+ fourcc = V4L2_PIX_FMT_SN9C10X;
+ }
+ else if (g_str_equal (mimetype, "video/x-pwc1"))
+ {
+ fourcc = V4L2_PIX_FMT_PWC1;
+ }
+ else if (g_str_equal (mimetype, "video/x-pwc2"))
+ {
+ fourcc = V4L2_PIX_FMT_PWC2;
}
else
{
- if (g_str_equal(mimetype, "video/mpegts"))
- {
- fourcc = V4L2_PIX_FMT_MPEG;
- }
- else if (g_str_equal(mimetype, "video/x-dv"))
- {
- fourcc = V4L2_PIX_FMT_DV;
- }
- else if (g_str_equal(mimetype, "video/mjpeg"))
- {
- fourcc = V4L2_PIX_FMT_JPEG;
- }
- else if (g_str_equal(mimetype, "video/mpeg"))
- {
- gint version;
- if (gst_structure_get_int(structure, "mpegversion", &version))
- {
- switch (version)
- {
- case 1:
- fourcc = V4L2_PIX_FMT_MPEG1;
- break;
- case 2:
- fourcc = V4L2_PIX_FMT_MPEG2;
- break;
- case 4:
- fourcc = V4L2_PIX_FMT_MPEG4;
- fourcc_nc = V4L2_PIX_FMT_XVID;
- break;
- default:
- break;
- }
- }
- }
- else if (g_str_equal(mimetype, "video/x-fwht"))
- {
- fourcc = V4L2_PIX_FMT_FWHT;
- }
- else if (g_str_equal(mimetype, "video/x-h263"))
- {
- fourcc = V4L2_PIX_FMT_H263;
- }
- else if (g_str_equal(mimetype, "video/x-h264"))
- {
- const gchar *stream_format =
- gst_structure_get_string(structure, "stream-format");
- if (g_str_equal(stream_format, "avc"))
- fourcc = V4L2_PIX_FMT_H264_NO_SC;
- else
- fourcc = V4L2_PIX_FMT_H264;
- }
- else if (g_str_equal(mimetype, "video/x-h265"))
- {
- fourcc = V4L2_PIX_FMT_HEVC;
- }
- else if (g_str_equal(mimetype, "video/x-vp8"))
- {
- fourcc = V4L2_PIX_FMT_VP8;
- }
- else if (g_str_equal(mimetype, "video/x-vp9"))
- {
- fourcc = V4L2_PIX_FMT_VP9;
- }
- else if (g_str_equal(mimetype, "video/x-av1"))
- {
- fourcc = V4L2_PIX_FMT_AV1;
- }
- else if (g_str_equal(mimetype, "video/x-avs"))
- {
- fourcc = V4L2_PIX_FMT_AVS;
- }
- else if (g_str_equal(mimetype, "video/x-avs2"))
- {
- fourcc = V4L2_PIX_FMT_AVS2;
- }
- else if (g_str_equal(mimetype, "video/x-avs3"))
- {
- fourcc = V4L2_PIX_FMT_AVS3;
- }
- else if (g_str_equal(mimetype, "video/x-bayer"))
- {
- const gchar *vformat = gst_structure_get_string(structure, "format");
- if (vformat)
- {
- if (!g_ascii_strcasecmp(vformat, "bggr"))
- fourcc = V4L2_PIX_FMT_SBGGR8;
- else if (!g_ascii_strcasecmp(vformat, "gbrg"))
- fourcc = V4L2_PIX_FMT_SGBRG8;
- else if (!g_ascii_strcasecmp(vformat, "grbg"))
- fourcc = V4L2_PIX_FMT_SGRBG8;
- else if (!g_ascii_strcasecmp(vformat, "rggb"))
- fourcc = V4L2_PIX_FMT_SRGGB8;
- }
- }
- else if (g_str_equal(mimetype, "video/x-sonix"))
- {
- fourcc = V4L2_PIX_FMT_SN9C10X;
- }
- else if (g_str_equal(mimetype, "video/x-pwc1"))
- {
- fourcc = V4L2_PIX_FMT_PWC1;
- }
- else if (g_str_equal(mimetype, "video/x-pwc2"))
- {
- fourcc = V4L2_PIX_FMT_PWC2;
- }
- else
- {
- GST_ERROR("Unknown video codec %s.", mimetype);
- }
+ GST_ERROR("Unknown video codec %s.", mimetype);
}
+ }
- /* Prefer the non-contiguous if supported */
- v4l2object->prefered_non_contiguous = TRUE;
+ /* Prefer the non-contiguous if supported */
+ v4l2object->prefered_non_contiguous = TRUE;
- if (fourcc_nc)
- fmt = gst_aml_v4l2_object_get_format_from_fourcc(v4l2object, fourcc_nc);
- else if (fourcc == 0)
- goto unhandled_format;
+ if (fourcc_nc)
+ fmt = gst_aml_v4l2_object_get_format_from_fourcc (v4l2object, fourcc_nc);
+ else if (fourcc == 0)
+ goto unhandled_format;
- if (fmt == NULL)
- {
- fmt = gst_aml_v4l2_object_get_format_from_fourcc(v4l2object, fourcc);
- v4l2object->prefered_non_contiguous = FALSE;
- }
+ if (fmt == NULL)
+ {
+ fmt = gst_aml_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
+ v4l2object->prefered_non_contiguous = FALSE;
+ }
- if (fmt == NULL)
- goto unsupported_format;
+ if (fmt == NULL)
+ goto unsupported_format;
- *format = fmt;
+ *format = fmt;
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
invalid_format:
-{
- GST_DEBUG_OBJECT(v4l2object, "invalid format");
+ {
+ GST_DEBUG_OBJECT (v4l2object, "invalid format");
return FALSE;
-}
+ }
unhandled_format:
-{
- GST_DEBUG_OBJECT(v4l2object, "unhandled format");
+ {
+ GST_DEBUG_OBJECT (v4l2object, "unhandled format");
return FALSE;
-}
+ }
unsupported_format:
-{
- GST_DEBUG_OBJECT(v4l2object, "unsupported format");
+ {
+ GST_DEBUG_OBJECT (v4l2object, "unsupported format");
return FALSE;
-}
+ }
}
static gboolean
-gst_aml_v4l2_object_get_nearest_size(GstAmlV4l2Object *v4l2object,
- guint32 pixelformat, gint *width, gint *height);
+gst_aml_v4l2_object_get_nearest_size (GstAmlV4l2Object * v4l2object,
+ guint32 pixelformat, gint * width, gint * height);
static void
-gst_aml_v4l2_object_add_aspect_ratio(GstAmlV4l2Object *v4l2object, GstStructure *s)
+gst_aml_v4l2_object_add_aspect_ratio (GstAmlV4l2Object * v4l2object, GstStructure * s)
{
- if (v4l2object->keep_aspect && v4l2object->par)
- gst_structure_set_value(s, "pixel-aspect-ratio", v4l2object->par);
+ if (v4l2object->keep_aspect && v4l2object->par)
+ gst_structure_set_value (s, "pixel-aspect-ratio", v4l2object->par);
}
/* returns TRUE if the value was changed in place, otherwise FALSE */
static gboolean
-gst_aml_v4l2src_value_simplify(GValue *val)
+gst_aml_v4l2src_value_simplify (GValue * val)
{
- /* simplify list of one value to one value */
- if (GST_VALUE_HOLDS_LIST(val) && gst_value_list_get_size(val) == 1)
- {
- const GValue *list_val;
- GValue new_val = G_VALUE_INIT;
+ /* simplify list of one value to one value */
+ if (GST_VALUE_HOLDS_LIST (val) && gst_value_list_get_size (val) == 1)
+ {
+ const GValue *list_val;
+ GValue new_val = G_VALUE_INIT;
- list_val = gst_value_list_get_value(val, 0);
- g_value_init(&new_val, G_VALUE_TYPE(list_val));
- g_value_copy(list_val, &new_val);
- g_value_unset(val);
- *val = new_val;
- return TRUE;
- }
+ list_val = gst_value_list_get_value (val, 0);
+ g_value_init (&new_val, G_VALUE_TYPE (list_val));
+ g_value_copy (list_val, &new_val);
+ g_value_unset (val);
+ *val = new_val;
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
static gboolean
-gst_aml_v4l2_object_get_interlace_mode(enum v4l2_field field,
- GstVideoInterlaceMode *interlace_mode)
+gst_aml_v4l2_object_get_interlace_mode (enum v4l2_field field,
+ GstVideoInterlaceMode * interlace_mode)
{
- switch (field)
- {
- case V4L2_FIELD_ANY:
- GST_ERROR("Driver bug detected - check driver with v4l2-compliance from http://git.linuxtv.org/v4l-utils.git\n");
- /* fallthrough */
+ switch (field)
+ {
+ case V4L2_FIELD_ANY:
+ GST_ERROR("Driver bug detected - check driver with v4l2-compliance from http://git.linuxtv.org/v4l-utils.git\n");
+ /* fallthrough */
case V4L2_FIELD_NONE:
- *interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
- return TRUE;
+ *interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
+ return TRUE;
case V4L2_FIELD_INTERLACED:
case V4L2_FIELD_INTERLACED_TB:
case V4L2_FIELD_INTERLACED_BT:
- *interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
- return TRUE;
+ *interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
+ return TRUE;
default:
- GST_ERROR("Unknown enum v4l2_field %d", field);
- return FALSE;
- }
+ GST_ERROR ("Unknown enum v4l2_field %d", field);
+ return FALSE;
+ }
}
static gboolean
gst_aml_v4l2_object_get_colorspace(struct v4l2_format *fmt,
GstVideoColorimetry *cinfo)
{
- gboolean is_rgb =
- gst_amL_v4l2_object_v4l2fourcc_is_rgb(fmt->fmt.pix.pixelformat);
- enum v4l2_colorspace colorspace;
- enum v4l2_quantization range;
- enum v4l2_ycbcr_encoding matrix;
- enum v4l2_xfer_func transfer;
- gboolean ret = TRUE;
+ gboolean is_rgb =
+ gst_aml_v4l2_object_v4l2fourcc_is_rgb (fmt->fmt.pix.pixelformat);
+ enum v4l2_colorspace colorspace;
+ enum v4l2_quantization range;
+ enum v4l2_ycbcr_encoding matrix;
+ enum v4l2_xfer_func transfer;
+ gboolean ret = TRUE;
- if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type))
- {
- colorspace = fmt->fmt.pix_mp.colorspace;
- range = fmt->fmt.pix_mp.quantization;
- matrix = fmt->fmt.pix_mp.ycbcr_enc;
- transfer = fmt->fmt.pix_mp.xfer_func;
- }
- else
- {
- colorspace = fmt->fmt.pix.colorspace;
- range = fmt->fmt.pix.quantization;
- matrix = fmt->fmt.pix.ycbcr_enc;
- transfer = fmt->fmt.pix.xfer_func;
- }
- GST_DEBUG("colorspace:%d, range:%d, matrix:%d, transfer:%d", colorspace, range, matrix, transfer);
- GST_DEBUG("cinfo update 1 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
+ if (V4L2_TYPE_IS_MULTIPLANAR (fmt->type))
+ {
+ colorspace = fmt->fmt.pix_mp.colorspace;
+ range = fmt->fmt.pix_mp.quantization;
+ matrix = fmt->fmt.pix_mp.ycbcr_enc;
+ transfer = fmt->fmt.pix_mp.xfer_func;
+ }
+ else
+ {
+ colorspace = fmt->fmt.pix.colorspace;
+ range = fmt->fmt.pix.quantization;
+ matrix = fmt->fmt.pix.ycbcr_enc;
+ transfer = fmt->fmt.pix.xfer_func;
+ }
+ GST_DEBUG("colorspace:%d, range:%d, matrix:%d, transfer:%d", colorspace, range, matrix, transfer);
+ GST_DEBUG("cinfo update 1 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
- /* First step, set the defaults for each primaries */
- switch (colorspace)
- {
+ /* First step, set the defaults for each primaries */
+ switch (colorspace)
+ {
case V4L2_COLORSPACE_SMPTE170M:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
+ break;
case V4L2_COLORSPACE_REC709:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT709;
- cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT709;
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
+ break;
case V4L2_COLORSPACE_SRGB:
case V4L2_COLORSPACE_JPEG:
- cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- cinfo->transfer = GST_VIDEO_TRANSFER_SRGB;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ cinfo->transfer = GST_VIDEO_TRANSFER_SRGB;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
+ break;
case V4L2_COLORSPACE_OPRGB:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- cinfo->transfer = GST_VIDEO_TRANSFER_ADOBERGB;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_ADOBERGB;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ cinfo->transfer = GST_VIDEO_TRANSFER_ADOBERGB;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_ADOBERGB;
+ break;
case V4L2_COLORSPACE_BT2020:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
- cinfo->transfer = GST_VIDEO_TRANSFER_BT2020_12;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT2020_12;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
+ break;
case V4L2_COLORSPACE_SMPTE240M:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
- cinfo->transfer = GST_VIDEO_TRANSFER_SMPTE240M;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
+ cinfo->transfer = GST_VIDEO_TRANSFER_SMPTE240M;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
+ break;
case V4L2_COLORSPACE_470_SYSTEM_M:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
+ break;
case V4L2_COLORSPACE_470_SYSTEM_BG:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
+ break;
case V4L2_COLORSPACE_RAW:
- /* Explicitly unknown */
- cinfo->range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
- cinfo->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
- cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
- break;
+ /* Explicitly unknown */
+ cinfo->range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
+ cinfo->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
+ cinfo->primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
+ break;
default:
- GST_DEBUG("Unknown enum v4l2_colorspace %d", colorspace);
- ret = FALSE;
- break;
+ GST_DEBUG ("Unknown enum v4l2_colorspace %d", colorspace);
+ ret = FALSE;
+ break;
}
GST_DEBUG("cinfo update 2 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
- if (!ret)
- goto done;
+ if (!ret)
+ goto done;
- /* Second step, apply any custom variation */
- switch (range)
- {
+ /* Second step, apply any custom variation */
+ switch (range)
+ {
case V4L2_QUANTIZATION_FULL_RANGE:
- cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
+ break;
case V4L2_QUANTIZATION_LIM_RANGE:
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- break;
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ break;
case V4L2_QUANTIZATION_DEFAULT:
- /* replicated V4L2_MAP_QUANTIZATION_DEFAULT macro behavior */
- if (is_rgb && colorspace == V4L2_COLORSPACE_BT2020)
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- else if (is_rgb || matrix == V4L2_YCBCR_ENC_XV601 || matrix == V4L2_YCBCR_ENC_XV709 || colorspace == V4L2_COLORSPACE_JPEG)
- cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
- else
- cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
- break;
+ /* replicated V4L2_MAP_QUANTIZATION_DEFAULT macro behavior */
+ if (is_rgb && colorspace == V4L2_COLORSPACE_BT2020)
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ else if (is_rgb || matrix == V4L2_YCBCR_ENC_XV601
+ || matrix == V4L2_YCBCR_ENC_XV709
+ || colorspace == V4L2_COLORSPACE_JPEG)
+ cinfo->range = GST_VIDEO_COLOR_RANGE_0_255;
+ else
+ cinfo->range = GST_VIDEO_COLOR_RANGE_16_235;
+ break;
default:
- GST_WARNING("Unknown enum v4l2_quantization value %d", range);
- cinfo->range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
- break;
- }
+ GST_WARNING ("Unknown enum v4l2_quantization value %d", range);
+ cinfo->range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
+ break;
+ }
GST_DEBUG("cinfo update 3 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
- switch (matrix)
- {
+ switch (matrix)
+ {
case V4L2_YCBCR_ENC_XV601:
case V4L2_YCBCR_ENC_SYCC:
- GST_FIXME("XV601 and SYCC not defined, assuming 601");
- /* fallthrough */
+ GST_FIXME ("XV601 and SYCC not defined, assuming 601");
+ /* fallthrough */
case V4L2_YCBCR_ENC_601:
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
- break;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ break;
case V4L2_YCBCR_ENC_XV709:
- GST_FIXME("XV709 not defined, assuming 709");
- /* fallthrough */
+ GST_FIXME ("XV709 not defined, assuming 709");
+ /* fallthrough */
case V4L2_YCBCR_ENC_709:
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT709;
- break;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT709;
+ break;
case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
- GST_FIXME("BT2020 with constant luma is not defined, assuming BT2020");
- /* fallthrough */
+ GST_FIXME ("BT2020 with constant luma is not defined, assuming BT2020");
+ /* fallthrough */
case V4L2_YCBCR_ENC_BT2020:
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
- break;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
+ break;
case V4L2_YCBCR_ENC_SMPTE240M:
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
- break;
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
+ break;
case V4L2_YCBCR_ENC_DEFAULT:
- /* nothing, just use defaults for colorspace */
- break;
+ /* nothing, just use defaults for colorspace */
+ break;
default:
- GST_WARNING("Unknown enum v4l2_ycbcr_encoding value %d", matrix);
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
- break;
- }
+ GST_WARNING ("Unknown enum v4l2_ycbcr_encoding value %d", matrix);
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
+ break;
+ }
GST_DEBUG("cinfo update 4 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
- /* Set identity matrix for R'G'B' formats to avoid creating
- * confusion. This though is cosmetic as it's now properly ignored by
- * the video info API and videoconvert. */
- if (is_rgb)
- cinfo->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
+ /* Set identity matrix for R'G'B' formats to avoid creating
+ * confusion. This though is cosmetic as it's now properly ignored by
+ * the video info API and videoconvert. */
+ if (is_rgb)
+ cinfo->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
- switch (transfer)
- {
+ switch (transfer)
+ {
case V4L2_XFER_FUNC_709:
- if (colorspace == V4L2_COLORSPACE_BT2020 && fmt->fmt.pix.height >= 2160)
- cinfo->transfer = GST_VIDEO_TRANSFER_BT2020_12;
- else
- cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
- break;
+ if (colorspace == V4L2_COLORSPACE_BT2020 && fmt->fmt.pix.height >= 2160)
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT2020_12;
+ else
+ cinfo->transfer = GST_VIDEO_TRANSFER_BT709;
+ break;
case V4L2_XFER_FUNC_SRGB:
- cinfo->transfer = GST_VIDEO_TRANSFER_SRGB;
- break;
+ cinfo->transfer = GST_VIDEO_TRANSFER_SRGB;
+ break;
case V4L2_XFER_FUNC_OPRGB:
- cinfo->transfer = GST_VIDEO_TRANSFER_ADOBERGB;
- break;
+ cinfo->transfer = GST_VIDEO_TRANSFER_ADOBERGB;
+ break;
case V4L2_XFER_FUNC_SMPTE240M:
- cinfo->transfer = GST_VIDEO_TRANSFER_SMPTE240M;
- break;
+ cinfo->transfer = GST_VIDEO_TRANSFER_SMPTE240M;
+ break;
case V4L2_XFER_FUNC_NONE:
- cinfo->transfer = GST_VIDEO_TRANSFER_GAMMA10;
- break;
+ cinfo->transfer = GST_VIDEO_TRANSFER_GAMMA10;
+ break;
case V4L2_XFER_FUNC_DEFAULT:
- /* nothing, just use defaults for colorspace */
- break;
+ /* nothing, just use defaults for colorspace */
+ break;
default:
- GST_WARNING("Unknown enum v4l2_xfer_func value %d", transfer);
- cinfo->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
- break;
- }
+ GST_WARNING ("Unknown enum v4l2_xfer_func value %d", transfer);
+ cinfo->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
+ break;
+ }
GST_DEBUG("cinfo update 5 time | range:%d, matrix:%d, transfer:%d, primaries:%d", cinfo->range, cinfo->matrix, cinfo->transfer, cinfo->primaries);
done:
- return ret;
+ return ret;
}
static int
-gst_aml_v4l2_object_try_fmt(GstAmlV4l2Object *v4l2object,
- struct v4l2_format *try_fmt)
+gst_aml_v4l2_object_try_fmt (GstAmlV4l2Object * v4l2object,
+ struct v4l2_format *try_fmt)
{
- int fd = v4l2object->video_fd;
- struct v4l2_format fmt;
- int r;
+ int fd = v4l2object->video_fd;
+ struct v4l2_format fmt;
+ int r;
- memcpy(&fmt, try_fmt, sizeof(fmt));
- r = v4l2object->ioctl(fd, VIDIOC_TRY_FMT, &fmt);
+ memcpy (&fmt, try_fmt, sizeof (fmt));
+ r = v4l2object->ioctl (fd, VIDIOC_TRY_FMT, &fmt);
- if (r < 0 && errno == ENOTTY)
- {
- /* The driver might not implement TRY_FMT, in which case we will try
- S_FMT to probe */
- if (GST_AML_V4L2_IS_ACTIVE(v4l2object))
- goto error;
+ if (r < 0 && errno == ENOTTY)
+ {
+ /* The driver might not implement TRY_FMT, in which case we will try
+ S_FMT to probe */
+ if (GST_AML_V4L2_IS_ACTIVE (v4l2object))
+ goto error;
- memcpy(&fmt, try_fmt, sizeof(fmt));
- r = v4l2object->ioctl(fd, VIDIOC_S_FMT, &fmt);
- }
- memcpy(try_fmt, &fmt, sizeof(fmt));
+ memcpy (&fmt, try_fmt, sizeof (fmt));
+ r = v4l2object->ioctl (fd, VIDIOC_S_FMT, &fmt);
+ }
+ memcpy (try_fmt, &fmt, sizeof (fmt));
- return r;
+ return r;
error:
- memcpy(try_fmt, &fmt, sizeof(fmt));
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unable to try format: %s", g_strerror(errno));
- return r;
+ memcpy (try_fmt, &fmt, sizeof (fmt));
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unable to try format: %s", g_strerror (errno));
+ return r;
}
static void
-gst_aml_v4l2_object_add_interlace_mode(GstAmlV4l2Object *v4l2object,
- GstStructure *s, guint32 width, guint32 height, guint32 pixelformat)
+gst_aml_v4l2_object_add_interlace_mode (GstAmlV4l2Object * v4l2object,
+ GstStructure * s, guint32 width, guint32 height, guint32 pixelformat)
{
- struct v4l2_format fmt;
- GValue interlace_formats = {
- 0,
- };
- enum v4l2_field formats[] = {V4L2_FIELD_NONE, V4L2_FIELD_INTERLACED};
- gsize i;
- GstVideoInterlaceMode interlace_mode, prev = -1;
+ struct v4l2_format fmt;
+ GValue interlace_formats = { 0, };
- if (!g_str_equal(gst_structure_get_name(s), "video/x-raw"))
- return;
+ enum v4l2_field formats[] = {V4L2_FIELD_NONE, V4L2_FIELD_INTERLACED};
+ gsize i;
+ GstVideoInterlaceMode interlace_mode, prev = -1;
- if (v4l2object->never_interlaced)
- {
- gst_structure_set(s, "interlace-mode", G_TYPE_STRING, "progressive", NULL);
- return;
- }
-
- g_value_init(&interlace_formats, GST_TYPE_LIST);
-
- /* Try twice - once for NONE, once for INTERLACED. */
- for (i = 0; i < G_N_ELEMENTS(formats); i++)
- {
- memset(&fmt, 0, sizeof(fmt));
- fmt.type = v4l2object->type;
- fmt.fmt.pix.width = width;
- fmt.fmt.pix.height = height;
- fmt.fmt.pix.pixelformat = pixelformat;
- fmt.fmt.pix.field = formats[i];
-
- if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0 &&
- gst_aml_v4l2_object_get_interlace_mode(fmt.fmt.pix.field, &interlace_mode) && prev != interlace_mode)
- {
- GValue interlace_enum = {
- 0,
- };
- const gchar *mode_string;
- g_value_init(&interlace_enum, G_TYPE_STRING);
- mode_string = gst_video_interlace_mode_to_string(interlace_mode);
- g_value_set_string(&interlace_enum, mode_string);
- gst_value_list_append_and_take_value(&interlace_formats,
- &interlace_enum);
- prev = interlace_mode;
- }
- }
-
- if (gst_aml_v4l2src_value_simplify(&interlace_formats) || gst_value_list_get_size(&interlace_formats) > 0)
- gst_structure_take_value(s, "interlace-mode", &interlace_formats);
- else
- GST_WARNING_OBJECT(v4l2object, "Failed to determine interlace mode");
-
+ if (!g_str_equal (gst_structure_get_name (s), "video/x-raw"))
return;
-}
-static void
-gst_aml_v4l2_object_fill_colorimetry_list(GValue *list,
- GstVideoColorimetry *cinfo)
-{
- GValue colorimetry = G_VALUE_INIT;
- guint size;
- guint i;
- gboolean found = FALSE;
+ if (v4l2object->never_interlaced)
+ {
+ gst_structure_set (s, "interlace-mode", G_TYPE_STRING, "progressive", NULL);
+ return;
+ }
- g_value_init(&colorimetry, G_TYPE_STRING);
- g_value_take_string(&colorimetry, gst_video_colorimetry_to_string(cinfo));
- GST_DEBUG("fill colorimetry:%s into list", gst_video_colorimetry_to_string(cinfo));
+ g_value_init (&interlace_formats, GST_TYPE_LIST);
- /* only insert if no duplicate */
- size = gst_value_list_get_size(list);
- for (i = 0; i < size; i++)
- {
- const GValue *tmp;
-
- tmp = gst_value_list_get_value(list, i);
- if (gst_value_compare(&colorimetry, tmp) == GST_VALUE_EQUAL)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- gst_value_list_append_and_take_value(list, &colorimetry);
- else
- g_value_unset(&colorimetry);
-}
-
-static void
-gst_aml_v4l2_object_add_colorspace(GstAmlV4l2Object *v4l2object, GstStructure *s,
- guint32 width, guint32 height, guint32 pixelformat)
-{
- struct v4l2_format fmt;
- GValue list = G_VALUE_INIT;
- GstVideoColorimetry cinfo;
- enum v4l2_colorspace req_cspace;
-
- memset(&fmt, 0, sizeof(fmt));
+ /* Try twice - once for NONE, once for INTERLACED. */
+ for (i = 0; i < G_N_ELEMENTS (formats); i++)
+ {
+ memset (&fmt, 0, sizeof (fmt));
fmt.type = v4l2object->type;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = formats[i];
- g_value_init(&list, GST_TYPE_LIST);
-
- /* step 1: get device default colorspace and insert it first as
- * it should be the preferred one */
- GST_DEBUG("try for pixl format");
- if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0)
- {
- if (gst_aml_v4l2_object_get_colorspace(&fmt, &cinfo))
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0 &&
+ gst_aml_v4l2_object_get_interlace_mode(fmt.fmt.pix.field, &interlace_mode) && prev != interlace_mode)
+ {
+ GValue interlace_enum = { 0, };
+ const gchar *mode_string;
+ g_value_init (&interlace_enum, G_TYPE_STRING);
+ mode_string = gst_video_interlace_mode_to_string (interlace_mode);
+ g_value_set_string (&interlace_enum, mode_string);
+ gst_value_list_append_and_take_value (&interlace_formats,
+ &interlace_enum);
+ prev = interlace_mode;
}
+ }
- /* step 2: probe all colorspace other than default
- * We don't probe all colorspace, range, matrix and transfer combination to
- * avoid ioctl flooding which could greatly increase initialization time
- * with low-speed devices (UVC...) */
- for (req_cspace = V4L2_COLORSPACE_SMPTE170M;
- req_cspace <= V4L2_COLORSPACE_RAW; req_cspace++)
+ if (gst_aml_v4l2src_value_simplify (&interlace_formats)
+ || gst_value_list_get_size (&interlace_formats) > 0)
+ gst_structure_take_value (s, "interlace-mode", &interlace_formats);
+ else
+ GST_WARNING_OBJECT (v4l2object, "Failed to determine interlace mode");
+
+ return;
+}
+
+static void
+gst_aml_v4l2_object_fill_colorimetry_list (GValue * list,
+ GstVideoColorimetry * cinfo)
+{
+ GValue colorimetry = G_VALUE_INIT;
+ guint size;
+ guint i;
+ gboolean found = FALSE;
+
+ g_value_init (&colorimetry, G_TYPE_STRING);
+ g_value_take_string (&colorimetry, gst_video_colorimetry_to_string (cinfo));
+ GST_DEBUG("fill colorimetry:%s into list", gst_video_colorimetry_to_string(cinfo));
+
+ /* only insert if no duplicate */
+ size = gst_value_list_get_size (list);
+ for (i = 0; i < size; i++)
+ {
+ const GValue *tmp;
+
+ tmp = gst_value_list_get_value (list, i);
+ if (gst_value_compare (&colorimetry, tmp) == GST_VALUE_EQUAL)
{
- GST_DEBUG("try for pixl format in while loop :%d", req_cspace);
- /* V4L2_COLORSPACE_BT878 is deprecated and shall not be used, so skip */
- if (req_cspace == V4L2_COLORSPACE_BT878)
- continue;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type))
- fmt.fmt.pix_mp.colorspace = req_cspace;
- else
- fmt.fmt.pix.colorspace = req_cspace;
-
- if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) == 0)
- {
- GST_DEBUG("try for pixl format in while loop :%d tried ok", req_cspace);
- enum v4l2_colorspace colorspace;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type))
- colorspace = fmt.fmt.pix_mp.colorspace;
- else
- colorspace = fmt.fmt.pix.colorspace;
-
- if (colorspace == req_cspace)
- {
- if (gst_aml_v4l2_object_get_colorspace(&fmt, &cinfo))
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
- }
- }
+ found = TRUE;
+ break;
}
+ }
- GST_DEBUG("deal: caps with colorimetry 2,3,14,7");
- cinfo.range = 2;
- cinfo.matrix = 3;
- cinfo.transfer = 14;
- cinfo.primaries = 7;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ if (!found)
+ gst_value_list_append_and_take_value (list, &colorimetry);
+ else
+ g_value_unset (&colorimetry);
+}
- GST_DEBUG("deal: caps with colorimetry 2,6,13,7");
- cinfo.range = 2;
- cinfo.matrix = 6;
- cinfo.transfer = 13;
- cinfo.primaries = 7;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+static void
+gst_aml_v4l2_object_add_colorspace (GstAmlV4l2Object * v4l2object, GstStructure * s,
+ guint32 width, guint32 height, guint32 pixelformat)
+{
+ struct v4l2_format fmt;
+ GValue list = G_VALUE_INIT;
+ GstVideoColorimetry cinfo;
+ enum v4l2_colorspace req_cspace;
- GST_DEBUG("deal: caps with colorimetry 2,6,14,7");
- cinfo.range = 2;
- cinfo.matrix = 6;
- cinfo.transfer = 14;
- cinfo.primaries = 7;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ memset (&fmt, 0, sizeof (fmt));
+ fmt.type = v4l2object->type;
+ fmt.fmt.pix.width = width;
+ fmt.fmt.pix.height = height;
+ fmt.fmt.pix.pixelformat = pixelformat;
- GST_DEBUG("deal: caps with colorimetry 2,6,0,7");
- cinfo.range = 2;
- cinfo.matrix = 6;
- cinfo.transfer = 0;
- cinfo.primaries = 7;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ g_value_init (&list, GST_TYPE_LIST);
- GST_DEBUG("deal: caps with colorimetry 0,6,0,7");
- cinfo.range = 0;
- cinfo.matrix = 6;
- cinfo.transfer = 0;
- cinfo.primaries = 7;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ /* step 1: get device default colorspace and insert it first as
+ * it should be the preferred one */
+ GST_DEBUG("try for pixl format");
+ if (gst_aml_v4l2_object_try_fmt (v4l2object, &fmt) == 0)
+ {
+ if (gst_aml_v4l2_object_get_colorspace(&fmt, &cinfo))
+ gst_aml_v4l2_object_fill_colorimetry_list (&list, &cinfo);
+ }
- GST_DEBUG("deal: caps with colorimetry 2,3,0,0");
- cinfo.range = 2;
- cinfo.matrix = 3;
- cinfo.transfer = 0;
- cinfo.primaries = 0;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ /* step 2: probe all colorspace other than default
+ * We don't probe all colorspace, range, matrix and transfer combination to
+ * avoid ioctl flooding which could greatly increase initialization time
+ * with low-speed devices (UVC...) */
+ for (req_cspace = V4L2_COLORSPACE_SMPTE170M;
+ req_cspace <= V4L2_COLORSPACE_RAW; req_cspace++)
+ {
+ GST_DEBUG("try for pixl format in while loop :%d", req_cspace);
+ /* V4L2_COLORSPACE_BT878 is deprecated and shall not be used, so skip */
+ if (req_cspace == V4L2_COLORSPACE_BT878)
+ continue;
- GST_DEBUG("deal: caps with colorimetry 2,6,14,0");
- cinfo.range = 2;
- cinfo.matrix = 6;
- cinfo.transfer = 14;
- cinfo.primaries = 0;
- gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
-
- if (gst_value_list_get_size(&list) > 0)
- gst_structure_take_value(s, "colorimetry", &list);
+ if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+ fmt.fmt.pix_mp.colorspace = req_cspace;
else
- g_value_unset(&list);
+ fmt.fmt.pix.colorspace = req_cspace;
- return;
+ if (gst_aml_v4l2_object_try_fmt (v4l2object, &fmt) == 0)
+ {
+ GST_DEBUG("try for pixl format in while loop :%d tried ok", req_cspace);
+ enum v4l2_colorspace colorspace;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+ colorspace = fmt.fmt.pix_mp.colorspace;
+ else
+ colorspace = fmt.fmt.pix.colorspace;
+
+ if (colorspace == req_cspace)
+ {
+ if (gst_aml_v4l2_object_get_colorspace(&fmt, &cinfo))
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+ }
+ }
+ }
+
+ GST_DEBUG("deal: caps with colorimetry 2,3,14,7");
+ cinfo.range = 2;
+ cinfo.matrix = 3;
+ cinfo.transfer = 14;
+ cinfo.primaries = 7;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 2,6,13,7");
+ cinfo.range = 2;
+ cinfo.matrix = 6;
+ cinfo.transfer = 13;
+ cinfo.primaries = 7;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 2,6,14,7");
+ cinfo.range = 2;
+ cinfo.matrix = 6;
+ cinfo.transfer = 14;
+ cinfo.primaries = 7;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 2,6,0,7");
+ cinfo.range = 2;
+ cinfo.matrix = 6;
+ cinfo.transfer = 0;
+ cinfo.primaries = 7;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 0,6,0,7");
+ cinfo.range = 0;
+ cinfo.matrix = 6;
+ cinfo.transfer = 0;
+ cinfo.primaries = 7;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 2,3,0,0");
+ cinfo.range = 2;
+ cinfo.matrix = 3;
+ cinfo.transfer = 0;
+ cinfo.primaries = 0;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ GST_DEBUG("deal: caps with colorimetry 2,6,14,0");
+ cinfo.range = 2;
+ cinfo.matrix = 6;
+ cinfo.transfer = 14;
+ cinfo.primaries = 0;
+ gst_aml_v4l2_object_fill_colorimetry_list(&list, &cinfo);
+
+ if (gst_value_list_get_size (&list) > 0)
+ gst_structure_take_value (s, "colorimetry", &list);
+ else
+ g_value_unset (&list);
+
+ return;
}
/* The frame interval enumeration code first appeared in Linux 2.6.19. */
static GstStructure *
-gst_aml_v4l2_object_probe_caps_for_format_and_size(GstAmlV4l2Object *v4l2object,
- guint32 pixelformat,
- guint32 width, guint32 height, const GstStructure *template)
+gst_aml_v4l2_object_probe_caps_for_format_and_size (GstAmlV4l2Object * v4l2object,
+ guint32 pixelformat,
+ guint32 width, guint32 height, const GstStructure * template)
{
- gint fd = v4l2object->video_fd;
- struct v4l2_frmivalenum ival;
- guint32 num, denom;
- GstStructure *s;
- GValue rates = {
- 0,
- };
+ gint fd = v4l2object->video_fd;
+ struct v4l2_frmivalenum ival;
+ guint32 num, denom;
+ GstStructure *s;
+ GValue rates = { 0, };
- memset(&ival, 0, sizeof(struct v4l2_frmivalenum));
- ival.index = 0;
- ival.pixel_format = pixelformat;
- ival.width = width;
- ival.height = height;
+ memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
+ ival.index = 0;
+ ival.pixel_format = pixelformat;
+ ival.width = width;
+ ival.height = height;
- GST_LOG_OBJECT(v4l2object->dbg_obj,
- "get frame interval for %ux%u, %" GST_FOURCC_FORMAT, width, height,
- GST_FOURCC_ARGS(pixelformat));
+ GST_LOG_OBJECT (v4l2object->dbg_obj,
+ "get frame interval for %ux%u, %" GST_FOURCC_FORMAT, width, height,
+ GST_FOURCC_ARGS (pixelformat));
- /* keep in mind that v4l2 gives us frame intervals (durations); we invert the
- * fraction to get framerate */
- if (v4l2object->ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
- goto enum_frameintervals_failed;
+ /* keep in mind that v4l2 gives us frame intervals (durations); we invert the
+ * fraction to get framerate */
+ if (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
+ goto enum_frameintervals_failed;
- if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE)
+ if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE)
+ {
+ GValue rate = { 0, };
+
+ g_value_init (&rates, GST_TYPE_LIST);
+ g_value_init (&rate, GST_TYPE_FRACTION);
+
+ do
{
- GValue rate = {
- 0,
- };
+ num = ival.discrete.numerator;
+ denom = ival.discrete.denominator;
- g_value_init(&rates, GST_TYPE_LIST);
- g_value_init(&rate, GST_TYPE_FRACTION);
+ if (num > G_MAXINT || denom > G_MAXINT)
+ {
+ /* let us hope we don't get here... */
+ num >>= 1;
+ denom >>= 1;
+ }
- do
- {
- num = ival.discrete.numerator;
- denom = ival.discrete.denominator;
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "adding discrete framerate: %d/%d",
+ denom, num);
- if (num > G_MAXINT || denom > G_MAXINT)
- {
- /* let us hope we don't get here... */
- num >>= 1;
- denom >>= 1;
- }
+ /* swap to get the framerate */
+ gst_value_set_fraction (&rate, denom, num);
+ gst_value_list_append_value (&rates, &rate);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "adding discrete framerate: %d/%d",
- denom, num);
+ ival.index++;
+ } while (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
+ }
+ else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE)
+ {
+ GValue min = { 0, };
+ GValue step = { 0, };
+ GValue max = { 0, };
+ gboolean added = FALSE;
+ guint32 minnum, mindenom;
+ guint32 maxnum, maxdenom;
- /* swap to get the framerate */
- gst_value_set_fraction(&rate, denom, num);
- gst_value_list_append_value(&rates, &rate);
+ g_value_init (&rates, GST_TYPE_LIST);
- ival.index++;
- } while (v4l2object->ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
- }
- else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE)
+ g_value_init (&min, GST_TYPE_FRACTION);
+ g_value_init (&step, GST_TYPE_FRACTION);
+ g_value_init (&max, GST_TYPE_FRACTION);
+
+ /* get the min */
+ minnum = ival.stepwise.min.numerator;
+ mindenom = ival.stepwise.min.denominator;
+ if (minnum > G_MAXINT || mindenom > G_MAXINT)
{
- GValue min = {
- 0,
- };
- GValue step = {
- 0,
- };
- GValue max = {
- 0,
- };
- gboolean added = FALSE;
- guint32 minnum, mindenom;
- guint32 maxnum, maxdenom;
-
- g_value_init(&rates, GST_TYPE_LIST);
-
- g_value_init(&min, GST_TYPE_FRACTION);
- g_value_init(&step, GST_TYPE_FRACTION);
- g_value_init(&max, GST_TYPE_FRACTION);
-
- /* get the min */
- minnum = ival.stepwise.min.numerator;
- mindenom = ival.stepwise.min.denominator;
- if (minnum > G_MAXINT || mindenom > G_MAXINT)
- {
- minnum >>= 1;
- mindenom >>= 1;
- }
- GST_LOG_OBJECT(v4l2object->dbg_obj, "stepwise min frame interval: %d/%d",
- minnum, mindenom);
- gst_value_set_fraction(&min, minnum, mindenom);
-
- /* get the max */
- maxnum = ival.stepwise.max.numerator;
- maxdenom = ival.stepwise.max.denominator;
- if (maxnum > G_MAXINT || maxdenom > G_MAXINT)
- {
- maxnum >>= 1;
- maxdenom >>= 1;
- }
-
- GST_LOG_OBJECT(v4l2object->dbg_obj, "stepwise max frame interval: %d/%d",
- maxnum, maxdenom);
- gst_value_set_fraction(&max, maxnum, maxdenom);
-
- /* get the step */
- num = ival.stepwise.step.numerator;
- denom = ival.stepwise.step.denominator;
- if (num > G_MAXINT || denom > G_MAXINT)
- {
- num >>= 1;
- denom >>= 1;
- }
-
- if (num == 0 || denom == 0)
- {
- /* in this case we have a wrong fraction or no step, set the step to max
- * so that we only add the min value in the loop below */
- num = maxnum;
- denom = maxdenom;
- }
-
- /* since we only have gst_value_fraction_subtract and not add, negate the
- * numerator */
- GST_LOG_OBJECT(v4l2object->dbg_obj, "stepwise step frame interval: %d/%d",
- num, denom);
- gst_value_set_fraction(&step, -num, denom);
-
- while (gst_value_compare(&min, &max) != GST_VALUE_GREATER_THAN)
- {
- GValue rate = {
- 0,
- };
-
- num = gst_value_get_fraction_numerator(&min);
- denom = gst_value_get_fraction_denominator(&min);
- GST_LOG_OBJECT(v4l2object->dbg_obj, "adding stepwise framerate: %d/%d",
- denom, num);
-
- /* invert to get the framerate */
- g_value_init(&rate, GST_TYPE_FRACTION);
- gst_value_set_fraction(&rate, denom, num);
- gst_value_list_append_value(&rates, &rate);
- added = TRUE;
-
- /* we're actually adding because step was negated above. This is because
- * there is no _add function... */
- if (!gst_value_fraction_subtract(&min, &min, &step))
- {
- GST_WARNING_OBJECT(v4l2object->dbg_obj, "could not step fraction!");
- break;
- }
- }
- if (!added)
- {
- /* no range was added, leave the default range from the template */
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "no range added, leaving default");
- g_value_unset(&rates);
- }
+ minnum >>= 1;
+ mindenom >>= 1;
}
- else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "stepwise min frame interval: %d/%d",
+ minnum, mindenom);
+ gst_value_set_fraction (&min, minnum, mindenom);
+
+ /* get the max */
+ maxnum = ival.stepwise.max.numerator;
+ maxdenom = ival.stepwise.max.denominator;
+ if (maxnum > G_MAXINT || maxdenom > G_MAXINT)
{
- guint32 maxnum, maxdenom;
-
- g_value_init(&rates, GST_TYPE_FRACTION_RANGE);
-
- num = ival.stepwise.min.numerator;
- denom = ival.stepwise.min.denominator;
- if (num > G_MAXINT || denom > G_MAXINT)
- {
- num >>= 1;
- denom >>= 1;
- }
-
- maxnum = ival.stepwise.max.numerator;
- maxdenom = ival.stepwise.max.denominator;
- if (maxnum > G_MAXINT || maxdenom > G_MAXINT)
- {
- maxnum >>= 1;
- maxdenom >>= 1;
- }
-
- GST_LOG_OBJECT(v4l2object->dbg_obj,
- "continuous frame interval %d/%d to %d/%d", maxdenom, maxnum, denom,
- num);
-
- gst_value_set_fraction_range_full(&rates, maxdenom, maxnum, denom, num);
+ maxnum >>= 1;
+ maxdenom >>= 1;
}
- else
+
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "stepwise max frame interval: %d/%d",
+ maxnum, maxdenom);
+ gst_value_set_fraction (&max, maxnum, maxdenom);
+
+ /* get the step */
+ num = ival.stepwise.step.numerator;
+ denom = ival.stepwise.step.denominator;
+ if (num > G_MAXINT || denom > G_MAXINT)
{
- goto unknown_type;
+ num >>= 1;
+ denom >>= 1;
}
+ if (num == 0 || denom == 0)
+ {
+ /* in this case we have a wrong fraction or no step, set the step to max
+ * so that we only add the min value in the loop below */
+ num = maxnum;
+ denom = maxdenom;
+ }
+
+ /* since we only have gst_value_fraction_subtract and not add, negate the
+ * numerator */
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "stepwise step frame interval: %d/%d",
+ num, denom);
+ gst_value_set_fraction (&step, -num, denom);
+
+ while (gst_value_compare (&min, &max) != GST_VALUE_GREATER_THAN)
+ {
+ GValue rate = { 0, };
+
+ num = gst_value_get_fraction_numerator (&min);
+ denom = gst_value_get_fraction_denominator (&min);
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "adding stepwise framerate: %d/%d",
+ denom, num);
+
+ /* invert to get the framerate */
+ g_value_init (&rate, GST_TYPE_FRACTION);
+ gst_value_set_fraction (&rate, denom, num);
+ gst_value_list_append_value (&rates, &rate);
+ added = TRUE;
+
+ /* we're actually adding because step was negated above. This is because
+ * there is no _add function... */
+ if (!gst_value_fraction_subtract (&min, &min, &step))
+ {
+ GST_WARNING_OBJECT (v4l2object->dbg_obj, "could not step fraction!");
+ break;
+ }
+ }
+ if (!added)
+ {
+ /* no range was added, leave the default range from the template */
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "no range added, leaving default");
+ g_value_unset (&rates);
+ }
+ }
+ else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)
+ {
+ guint32 maxnum, maxdenom;
+
+ g_value_init (&rates, GST_TYPE_FRACTION_RANGE);
+
+ num = ival.stepwise.min.numerator;
+ denom = ival.stepwise.min.denominator;
+ if (num > G_MAXINT || denom > G_MAXINT)
+ {
+ num >>= 1;
+ denom >>= 1;
+ }
+
+ maxnum = ival.stepwise.max.numerator;
+ maxdenom = ival.stepwise.max.denominator;
+ if (maxnum > G_MAXINT || maxdenom > G_MAXINT)
+ {
+ maxnum >>= 1;
+ maxdenom >>= 1;
+ }
+
+ GST_LOG_OBJECT (v4l2object->dbg_obj,
+ "continuous frame interval %d/%d to %d/%d", maxdenom, maxnum, denom,
+ num);
+
+ gst_value_set_fraction_range_full (&rates, maxdenom, maxnum, denom, num);
+ }
+ else
+ {
+ goto unknown_type;
+ }
+
return_data:
- s = gst_structure_copy(template);
- gst_structure_set(s, "width", G_TYPE_INT, (gint)width,
- "height", G_TYPE_INT, (gint)height, NULL);
+ s = gst_structure_copy (template);
+ gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
+ "height", G_TYPE_INT, (gint) height, NULL);
- gst_aml_v4l2_object_add_aspect_ratio(v4l2object, s);
+ gst_aml_v4l2_object_add_aspect_ratio (v4l2object, s);
- if (!v4l2object->skip_try_fmt_probes)
- {
- gst_aml_v4l2_object_add_interlace_mode(v4l2object, s, width, height,
- pixelformat);
- // gst_aml_v4l2_object_add_colorspace(v4l2object, s, width, height, pixelformat);
- }
+ if (!v4l2object->skip_try_fmt_probes)
+ {
+ gst_aml_v4l2_object_add_interlace_mode (v4l2object, s, width, height,
+ pixelformat);
+ // gst_aml_v4l2_object_add_colorspace(v4l2object, s, width, height, pixelformat);
+ }
- if (G_IS_VALUE(&rates))
- {
- gst_aml_v4l2src_value_simplify(&rates);
- /* only change the framerate on the template when we have a valid probed new
- * value */
- gst_structure_take_value(s, "framerate", &rates);
- }
- else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- {
- gst_structure_set(s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT,
- 1, NULL);
- }
- return s;
+ if (G_IS_VALUE (&rates))
+ {
+ gst_aml_v4l2src_value_simplify (&rates);
+ /* only change the framerate on the template when we have a valid probed new
+ * value */
+ gst_structure_take_value (s, "framerate", &rates);
+ }
+ else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ {
+ gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT,
+ 1, NULL);
+ }
+ return s;
- /* ERRORS */
+ /* ERRORS */
enum_frameintervals_failed:
-{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Unable to enumerate intervals for %" GST_FOURCC_FORMAT "@%ux%u",
- GST_FOURCC_ARGS(pixelformat), width, height);
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Unable to enumerate intervals for %" GST_FOURCC_FORMAT "@%ux%u",
+ GST_FOURCC_ARGS (pixelformat), width, height);
goto return_data;
-}
+ }
unknown_type:
-{
+ {
/* I don't see how this is actually an error, we ignore the format then */
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown frame interval type at %" GST_FOURCC_FORMAT "@%ux%u: %u",
- GST_FOURCC_ARGS(pixelformat), width, height, ival.type);
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown frame interval type at %" GST_FOURCC_FORMAT "@%ux%u: %u",
+ GST_FOURCC_ARGS (pixelformat), width, height, ival.type);
return NULL;
-}
+ }
}
static gint
-sort_by_frame_size(GstStructure *s1, GstStructure *s2)
+sort_by_frame_size (GstStructure * s1, GstStructure * s2)
{
- int w1, h1, w2, h2;
+ int w1, h1, w2, h2;
- gst_structure_get_int(s1, "width", &w1);
- gst_structure_get_int(s1, "height", &h1);
- gst_structure_get_int(s2, "width", &w2);
- gst_structure_get_int(s2, "height", &h2);
+ gst_structure_get_int (s1, "width", &w1);
+ gst_structure_get_int (s1, "height", &h1);
+ gst_structure_get_int (s2, "width", &w2);
+ gst_structure_get_int (s2, "height", &h2);
- /* I think it's safe to assume that this won't overflow for a while */
- return ((w2 * h2) - (w1 * h1));
+ /* I think it's safe to assume that this won't overflow for a while */
+ return ((w2 * h2) - (w1 * h1));
}
static void
-gst_aml_v4l2_object_update_and_append(GstAmlV4l2Object *v4l2object,
- guint32 format, GstCaps *caps, GstStructure *s)
+gst_aml_v4l2_object_update_and_append (GstAmlV4l2Object * v4l2object,
+ guint32 format, GstCaps * caps, GstStructure * s)
{
- GstStructure *alt_s = NULL;
+ GstStructure *alt_s = NULL;
- /* Encoded stream on output buffer need to be parsed */
- if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ /* Encoded stream on output buffer need to be parsed */
+ if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+ v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ {
+ gint i = 0;
+
+ for (; i < GST_AML_V4L2_FORMAT_COUNT; i++)
{
- gint i = 0;
-
- for (; i < GST_AML_V4L2_FORMAT_COUNT; i++)
- {
- if (format == gst_aml_v4l2_formats[i].format &&
- gst_aml_v4l2_formats[i].flags & GST_V4L2_CODEC &&
- !(gst_aml_v4l2_formats[i].flags & GST_V4L2_NO_PARSE))
- {
- gst_structure_set(s, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
- break;
- }
- }
+ if (format == gst_aml_v4l2_formats[i].format &&
+ gst_aml_v4l2_formats[i].flags & GST_V4L2_CODEC &&
+ !(gst_aml_v4l2_formats[i].flags & GST_V4L2_NO_PARSE))
+ {
+ gst_structure_set (s, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
+ break;
+ }
}
+ }
- if (v4l2object->has_alpha_component &&
- (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
+ if (v4l2object->has_alpha_component &&
+ (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
+ {
+ switch (format)
{
- switch (format)
- {
- case V4L2_PIX_FMT_RGB32:
- alt_s = gst_structure_copy(s);
- gst_structure_set(alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
- break;
- case V4L2_PIX_FMT_BGR32:
- alt_s = gst_structure_copy(s);
- gst_structure_set(alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
- break;
- default:
- break;
- }
+ case V4L2_PIX_FMT_RGB32:
+ alt_s = gst_structure_copy (s);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ alt_s = gst_structure_copy (s);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
+ break;
+ default:
+ break;
}
+ }
- gst_caps_append_structure(caps, s);
+ gst_caps_append_structure(caps, s);
- if (alt_s)
- gst_caps_append_structure(caps, alt_s);
+ if (alt_s)
+ gst_caps_append_structure(caps, alt_s);
}
static GstCaps *
-gst_aml_v4l2_object_probe_caps_for_format(GstAmlV4l2Object *v4l2object,
- guint32 pixelformat, const GstStructure *template)
+gst_aml_v4l2_object_probe_caps_for_format (GstAmlV4l2Object * v4l2object,
+ guint32 pixelformat, const GstStructure * template)
{
- GstCaps *ret = gst_caps_new_empty();
- GstStructure *tmp;
- gint fd = v4l2object->video_fd;
- struct v4l2_frmsizeenum size;
- GList *results = NULL;
- guint32 w, h;
+ GstCaps *ret = gst_caps_new_empty ();
+ GstStructure *tmp;
+ gint fd = v4l2object->video_fd;
+ struct v4l2_frmsizeenum size;
+ GList *results = NULL;
+ guint32 w, h;
- if (pixelformat == GST_MAKE_FOURCC('M', 'P', 'E', 'G'))
+ if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G'))
+ {
+ gst_caps_append_structure (ret, gst_structure_copy (template));
+ return ret;
+ }
+
+ memset (&size, 0, sizeof (struct v4l2_frmsizeenum));
+ size.index = 0;
+ size.pixel_format = pixelformat;
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Enumerating frame sizes for %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (pixelformat));
+
+ if (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
+ goto enum_framesizes_failed;
+
+ if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE)
+ {
+ do
{
- gst_caps_append_structure(ret, gst_structure_copy(template));
- return ret;
- }
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "got discrete frame size %dx%d",
+ size.discrete.width, size.discrete.height);
- memset(&size, 0, sizeof(struct v4l2_frmsizeenum));
- size.index = 0;
- size.pixel_format = pixelformat;
+ w = MIN (size.discrete.width, G_MAXINT);
+ h = MIN (size.discrete.height, G_MAXINT);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Enumerating frame sizes for %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS(pixelformat));
+ if (w && h)
+ {
+ tmp =
+ gst_aml_v4l2_object_probe_caps_for_format_and_size (v4l2object,
+ pixelformat, w, h, template);
- if (v4l2object->ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
- goto enum_framesizes_failed;
+ if (tmp)
+ results = g_list_prepend (results, tmp);
+ }
- if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE)
- {
- do
- {
- GST_LOG_OBJECT(v4l2object->dbg_obj, "got discrete frame size %dx%d",
- size.discrete.width, size.discrete.height);
+ size.index++;
+ } while (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "done iterating discrete frame sizes");
+ }
+ else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE)
+ {
+ guint32 maxw, maxh, step_w, step_h;
- w = MIN(size.discrete.width, G_MAXINT);
- h = MIN(size.discrete.height, G_MAXINT);
-
- if (w && h)
- {
- tmp =
- gst_aml_v4l2_object_probe_caps_for_format_and_size(v4l2object,
- pixelformat, w, h, template);
-
- if (tmp)
- results = g_list_prepend(results, tmp);
- }
-
- size.index++;
- } while (v4l2object->ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "done iterating discrete frame sizes");
- }
- else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE)
- {
- guint32 maxw, maxh, step_w, step_h;
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "we have stepwise frame sizes:");
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min width: %d",
- size.stepwise.min_width);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min height: %d",
- size.stepwise.min_height);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "max width: %d",
- size.stepwise.max_width);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min height: %d",
- size.stepwise.max_height);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "step width: %d",
- size.stepwise.step_width);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "step height: %d",
- size.stepwise.step_height);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "we have stepwise frame sizes:");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min width: %d",
+ size.stepwise.min_width);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min height: %d",
+ size.stepwise.min_height);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "max width: %d",
+ size.stepwise.max_width);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min height: %d",
+ size.stepwise.max_height);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "step width: %d",
+ size.stepwise.step_width);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "step height: %d",
+ size.stepwise.step_height);
if (pixelformat == V4L2_PIX_FMT_NV12 ||
pixelformat == V4L2_PIX_FMT_NV21 ||
@@ -2909,128 +2898,126 @@
w = MAX(size.stepwise.min_width, 1);
h = MAX(size.stepwise.min_height, 1);
}
- maxw = MIN(size.stepwise.max_width, G_MAXINT);
- maxh = MIN(size.stepwise.max_height, G_MAXINT);
+ maxw = MIN (size.stepwise.max_width, G_MAXINT);
+ maxh = MIN (size.stepwise.max_height, G_MAXINT);
- /* in this position,updating resolution only to pass the negotiation
- * actually, the details about resolution refer to function:
- * gst_aml_v4l2_object_set_format_full for checking.
- */
- GST_DEBUG_OBJECT (v4l2object->dbg_obj, "update maxw_maxh to MAX(maxw,maxh)_MAX(maxw,maxh)");
- maxh = MAX (maxw, maxh);
- maxw = maxh;
+ /* in this position,updating resolution only to pass the negotiation
+ * actually, the details about resolution refer to function:
+ * gst_aml_v4l2_object_set_format_full for checking.
+ */
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "update maxw_maxh to MAX(maxw,maxh)_MAX(maxw,maxh)");
+ maxh = MAX (maxw, maxh);
+ maxw = maxh;
- step_w = MAX(size.stepwise.step_width, 1);
- step_h = MAX(size.stepwise.step_height, 1);
+ step_w = MAX (size.stepwise.step_width, 1);
+ step_h = MAX (size.stepwise.step_height, 1);
- /* FIXME: check for sanity and that min/max are multiples of the steps */
+ /* FIXME: check for sanity and that min/max are multiples of the steps */
- /* we only query details for the max width/height since it's likely the
- * most restricted if there are any resolution-dependent restrictions */
- tmp = gst_aml_v4l2_object_probe_caps_for_format_and_size(v4l2object,
- pixelformat, maxw, maxh, template);
+ /* we only query details for the max width/height since it's likely the
+ * most restricted if there are any resolution-dependent restrictions */
+ tmp = gst_aml_v4l2_object_probe_caps_for_format_and_size (v4l2object,
+ pixelformat, maxw, maxh, template);
- if (tmp)
- {
- GValue step_range = G_VALUE_INIT;
-
- g_value_init(&step_range, GST_TYPE_INT_RANGE);
- gst_value_set_int_range_step(&step_range, w, maxw, step_w);
- gst_structure_set_value(tmp, "width", &step_range);
-
- gst_value_set_int_range_step(&step_range, h, maxh, step_h);
- gst_structure_take_value(tmp, "height", &step_range);
-
- /* no point using the results list here, since there's only one struct */
- gst_aml_v4l2_object_update_and_append(v4l2object, pixelformat, ret, tmp);
- }
- }
- else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS)
+ if (tmp)
{
- guint32 maxw, maxh;
+ GValue step_range = G_VALUE_INIT;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "we have continuous frame sizes:");
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min width: %d",
- size.stepwise.min_width);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min height: %d",
- size.stepwise.min_height);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "max width: %d",
- size.stepwise.max_width);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "min height: %d",
- size.stepwise.max_height);
+ g_value_init (&step_range, GST_TYPE_INT_RANGE);
+ gst_value_set_int_range_step (&step_range, w, maxw, step_w);
+ gst_structure_set_value (tmp, "width", &step_range);
- w = MAX(size.stepwise.min_width, 1);
- h = MAX(size.stepwise.min_height, 1);
- maxw = MIN(size.stepwise.max_width, G_MAXINT);
- maxh = MIN(size.stepwise.max_height, G_MAXINT);
+ gst_value_set_int_range_step (&step_range, h, maxh, step_h);
+ gst_structure_take_value (tmp, "height", &step_range);
- tmp =
- gst_aml_v4l2_object_probe_caps_for_format_and_size(v4l2object, pixelformat,
- w, h, template);
- if (tmp)
- {
- gst_structure_set(tmp, "width", GST_TYPE_INT_RANGE, (gint)w,
- (gint)maxw, "height", GST_TYPE_INT_RANGE, (gint)h, (gint)maxh,
- NULL);
-
- /* no point using the results list here, since there's only one struct */
- gst_aml_v4l2_object_update_and_append(v4l2object, pixelformat, ret, tmp);
- }
+ /* no point using the results list here, since there's only one struct */
+ gst_aml_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
}
- else
+ }
+ else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS)
+ {
+ guint32 maxw, maxh;
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "we have continuous frame sizes:");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min width: %d",
+ size.stepwise.min_width);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min height: %d",
+ size.stepwise.min_height);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "max width: %d",
+ size.stepwise.max_width);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "min height: %d",
+ size.stepwise.max_height);
+
+ w = MAX (size.stepwise.min_width, 1);
+ h = MAX (size.stepwise.min_height, 1);
+ maxw = MIN (size.stepwise.max_width, G_MAXINT);
+ maxh = MIN (size.stepwise.max_height, G_MAXINT);
+
+ tmp =
+ gst_aml_v4l2_object_probe_caps_for_format_and_size (v4l2object, pixelformat,
+ w, h, template);
+ if (tmp)
{
- goto unknown_type;
+ gst_structure_set (tmp, "width", GST_TYPE_INT_RANGE, (gint) w,
+ (gint) maxw, "height", GST_TYPE_INT_RANGE, (gint) h, (gint) maxh,
+ NULL);
+
+ /* no point using the results list here, since there's only one struct */
+ gst_aml_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
}
+ }
+ else
+ {
+ goto unknown_type;
+ }
- /* we use an intermediary list to store and then sort the results of the
- * probing because we can't make any assumptions about the order in which
- * the driver will give us the sizes, but we want the final caps to contain
- * the results starting with the highest resolution and having the lowest
- * resolution last, since order in caps matters for things like fixation. */
- results = g_list_sort(results, (GCompareFunc)sort_by_frame_size);
- while (results != NULL)
- {
- gst_aml_v4l2_object_update_and_append(v4l2object, pixelformat, ret,
- results->data);
- results = g_list_delete_link(results, results);
- }
+ /* we use an intermediary list to store and then sort the results of the
+ * probing because we can't make any assumptions about the order in which
+ * the driver will give us the sizes, but we want the final caps to contain
+ * the results starting with the highest resolution and having the lowest
+ * resolution last, since order in caps matters for things like fixation. */
+ results = g_list_sort (results, (GCompareFunc) sort_by_frame_size);
+ while (results != NULL)
+ {
+ gst_aml_v4l2_object_update_and_append (v4l2object, pixelformat, ret,
+ results->data);
+ results = g_list_delete_link (results, results);
+ }
- if (gst_caps_is_empty(ret))
- goto enum_framesizes_no_results;
+ if (gst_caps_is_empty (ret))
+ goto enum_framesizes_no_results;
- return ret;
+ return ret;
- /* ERRORS */
+ /* ERRORS */
enum_framesizes_failed:
-{
+ {
/* I don't see how this is actually an error */
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Failed to enumerate frame sizes for pixelformat %" GST_FOURCC_FORMAT
- " (%s)",
- GST_FOURCC_ARGS(pixelformat), g_strerror(errno));
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Failed to enumerate frame sizes for pixelformat %" GST_FOURCC_FORMAT
+ " (%s)", GST_FOURCC_ARGS (pixelformat), g_strerror (errno));
goto default_frame_sizes;
-}
+ }
enum_framesizes_no_results:
-{
+ {
/* it's possible that VIDIOC_ENUM_FRAMESIZES is defined but the driver in
* question doesn't actually support it yet */
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "No results for pixelformat %" GST_FOURCC_FORMAT
- " enumerating frame sizes, trying fallback",
- GST_FOURCC_ARGS(pixelformat));
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "No results for pixelformat %" GST_FOURCC_FORMAT
+ " enumerating frame sizes, trying fallback",
+ GST_FOURCC_ARGS (pixelformat));
goto default_frame_sizes;
-}
+ }
unknown_type:
-{
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown frame sizeenum type for pixelformat %" GST_FOURCC_FORMAT
- ": %u",
- GST_FOURCC_ARGS(pixelformat), size.type);
+ {
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown frame sizeenum type for pixelformat %" GST_FOURCC_FORMAT
+ ": %u", GST_FOURCC_ARGS (pixelformat), size.type);
goto default_frame_sizes;
-}
+ }
default_frame_sizes:
-{
+ {
gint min_w, max_w, min_h, max_h;
#ifdef DELETE_FOR_LGE
@@ -3040,652 +3027,654 @@
/* This code is for Linux < 2.6.19 */
min_w = min_h = 1;
max_w = max_h = GST_AML_V4L2_MAX_SIZE;
- if (!gst_aml_v4l2_object_get_nearest_size(v4l2object, pixelformat, &min_w,
- &min_h))
+ if (!gst_aml_v4l2_object_get_nearest_size (v4l2object, pixelformat, &min_w,
+ &min_h))
{
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Could not probe minimum capture size for pixelformat %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(pixelformat));
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Could not probe minimum capture size for pixelformat %"
+ GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
}
- if (!gst_aml_v4l2_object_get_nearest_size(v4l2object, pixelformat, &max_w,
- &max_h))
+ if (!gst_aml_v4l2_object_get_nearest_size (v4l2object, pixelformat, &max_w,
+ &max_h))
{
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Could not probe maximum capture size for pixelformat %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(pixelformat));
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Could not probe maximum capture size for pixelformat %"
+ GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
}
- tmp = gst_structure_copy(template);
+
+ tmp = gst_structure_copy (template);
#ifdef DELETE_FOR_LGE
if (fix_num)
{
- gst_structure_set(tmp, "framerate", GST_TYPE_FRACTION, fix_num,
- fix_denom, NULL);
+ gst_structure_set (tmp, "framerate", GST_TYPE_FRACTION, fix_num,
+ fix_denom, NULL);
}
else
#endif
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
{
- /* if norm can't be used, copy the template framerate */
- gst_structure_set(tmp, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
- G_MAXINT, 1, NULL);
+ /* if norm can't be used, copy the template framerate */
+ gst_structure_set (tmp, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
+ G_MAXINT, 1, NULL);
}
if (min_w == max_w)
- gst_structure_set(tmp, "width", G_TYPE_INT, max_w, NULL);
+ gst_structure_set (tmp, "width", G_TYPE_INT, max_w, NULL);
else
- gst_structure_set(tmp, "width", GST_TYPE_INT_RANGE, min_w, max_w, NULL);
+ gst_structure_set (tmp, "width", GST_TYPE_INT_RANGE, min_w, max_w, NULL);
if (min_h == max_h)
- gst_structure_set(tmp, "height", G_TYPE_INT, max_h, NULL);
+ gst_structure_set (tmp, "height", G_TYPE_INT, max_h, NULL);
else
- gst_structure_set(tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
+ gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
- gst_aml_v4l2_object_add_aspect_ratio(v4l2object, tmp);
+ gst_aml_v4l2_object_add_aspect_ratio (v4l2object, tmp);
if (!v4l2object->skip_try_fmt_probes)
{
- /* We could consider setting interlace mode from min and max. */
- gst_aml_v4l2_object_add_interlace_mode(v4l2object, tmp, max_w, max_h,
- pixelformat);
- /* We could consider to check colorspace for min too, in case it depends on
- * the size. But in this case, min and max could not be enough */
- gst_aml_v4l2_object_add_colorspace(v4l2object, tmp, max_w, max_h,
- pixelformat);
+ /* We could consider setting interlace mode from min and max. */
+ gst_aml_v4l2_object_add_interlace_mode(v4l2object, tmp, max_w, max_h,
+ pixelformat);
+ /* We could consider to check colorspace for min too, in case it depends on
+ * the size. But in this case, min and max could not be enough */
+ gst_aml_v4l2_object_add_colorspace(v4l2object, tmp, max_w, max_h,
+ pixelformat);
}
- gst_aml_v4l2_object_update_and_append(v4l2object, pixelformat, ret, tmp);
+ gst_aml_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
return ret;
-}
+ }
}
static gboolean
-gst_aml_v4l2_object_get_nearest_size(GstAmlV4l2Object *v4l2object,
- guint32 pixelformat, gint *width, gint *height)
+gst_aml_v4l2_object_get_nearest_size (GstAmlV4l2Object * v4l2object,
+ guint32 pixelformat, gint * width, gint * height)
{
- struct v4l2_format fmt;
- gboolean ret = FALSE;
- GstVideoInterlaceMode interlace_mode;
+ struct v4l2_format fmt;
+ gboolean ret = FALSE;
+ GstVideoInterlaceMode interlace_mode;
- g_return_val_if_fail(width != NULL, FALSE);
- g_return_val_if_fail(height != NULL, FALSE);
+ g_return_val_if_fail (width != NULL, FALSE);
+ g_return_val_if_fail (height != NULL, FALSE);
- GST_LOG_OBJECT(v4l2object->dbg_obj,
- "getting nearest size to %dx%d with format %" GST_FOURCC_FORMAT,
- *width, *height, GST_FOURCC_ARGS(pixelformat));
+ GST_LOG_OBJECT (v4l2object->dbg_obj,
+ "getting nearest size to %dx%d with format %" GST_FOURCC_FORMAT,
+ *width, *height, GST_FOURCC_ARGS (pixelformat));
- memset(&fmt, 0, sizeof(struct v4l2_format));
+ memset (&fmt, 0, sizeof (struct v4l2_format));
- /* get size delimiters */
- memset(&fmt, 0, sizeof(fmt));
- fmt.type = v4l2object->type;
- fmt.fmt.pix.width = *width;
- fmt.fmt.pix.height = *height;
- fmt.fmt.pix.pixelformat = pixelformat;
- fmt.fmt.pix.field = V4L2_FIELD_ANY;
+ /* get size delimiters */
+ memset (&fmt, 0, sizeof (fmt));
+ fmt.type = v4l2object->type;
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = V4L2_FIELD_ANY;
- if (gst_aml_v4l2_object_try_fmt(v4l2object, &fmt) < 0)
- goto error;
+ if (gst_aml_v4l2_object_try_fmt (v4l2object, &fmt) < 0)
+ goto error;
- GST_LOG_OBJECT(v4l2object->dbg_obj,
- "got nearest size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
+ GST_LOG_OBJECT (v4l2object->dbg_obj,
+ "got nearest size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
- *width = fmt.fmt.pix.width;
- *height = fmt.fmt.pix.height;
+ *width = fmt.fmt.pix.width;
+ *height = fmt.fmt.pix.height;
- if (!gst_aml_v4l2_object_get_interlace_mode(fmt.fmt.pix.field, &interlace_mode))
- {
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u: %u",
- GST_FOURCC_ARGS(pixelformat), *width, *height, fmt.fmt.pix.field);
- goto error;
- }
+ if (!gst_aml_v4l2_object_get_interlace_mode (fmt.fmt.pix.field, &interlace_mode))
+ {
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u: %u",
+ GST_FOURCC_ARGS (pixelformat), *width, *height, fmt.fmt.pix.field);
+ goto error;
+ }
- ret = TRUE;
+ ret = TRUE;
error:
- if (!ret)
- {
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unable to try format: %s", g_strerror(errno));
- }
+ if (!ret)
+ {
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unable to try format: %s", g_strerror (errno));
+ }
- return ret;
+ return ret;
}
static gboolean
-gst_aml_v4l2_object_is_dmabuf_supported(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_is_dmabuf_supported (GstAmlV4l2Object * v4l2object)
{
- gboolean ret = TRUE;
- struct v4l2_exportbuffer expbuf = {
- .type = v4l2object->type,
- .index = -1,
- .plane = -1,
- .flags = O_CLOEXEC | O_RDWR,
- };
+ gboolean ret = TRUE;
+ struct v4l2_exportbuffer expbuf = {
+ .type = v4l2object->type,
+ .index = -1,
+ .plane = -1,
+ .flags = O_CLOEXEC | O_RDWR,
+ };
- if (v4l2object->fmtdesc->flags & V4L2_FMT_FLAG_EMULATED)
- {
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "libv4l2 converter detected, disabling DMABuf");
- ret = FALSE;
- }
+ if (v4l2object->fmtdesc->flags & V4L2_FMT_FLAG_EMULATED)
+ {
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "libv4l2 converter detected, disabling DMABuf");
+ ret = FALSE;
+ }
- /* Expected to fail, but ENOTTY tells us that it is not implemented. */
- v4l2object->ioctl(v4l2object->video_fd, VIDIOC_EXPBUF, &expbuf);
- if (errno == ENOTTY)
- ret = FALSE;
+ /* Expected to fail, but ENOTTY tells us that it is not implemented. */
+ v4l2object->ioctl (v4l2object->video_fd, VIDIOC_EXPBUF, &expbuf);
+ if (errno == ENOTTY)
+ ret = FALSE;
- return ret;
+ return ret;
}
static gboolean
-gst_aml_v4l2_object_setup_pool(GstAmlV4l2Object *v4l2object, GstCaps *caps)
+gst_aml_v4l2_object_setup_pool (GstAmlV4l2Object * v4l2object, GstCaps * caps)
{
- GstAmlV4l2IOMode mode;
+ GstAmlV4l2IOMode mode;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "initializing the %s system",
- V4L2_TYPE_IS_OUTPUT(v4l2object->type) ? "output" : "capture");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "initializing the %s system",
+ V4L2_TYPE_IS_OUTPUT (v4l2object->type) ? "output" : "capture");
- GST_AML_V4L2_CHECK_OPEN(v4l2object);
- GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
+ GST_AML_V4L2_CHECK_OPEN (v4l2object);
+ GST_AML_V4L2_CHECK_NOT_ACTIVE (v4l2object);
- /* find transport */
- mode = v4l2object->req_mode;
+ /* find transport */
+ mode = v4l2object->req_mode;
- if (v4l2object->device_caps & V4L2_CAP_READWRITE)
+ if (v4l2object->device_caps & V4L2_CAP_READWRITE)
+ {
+ if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
+ mode = GST_V4L2_IO_RW;
+ }
+ else if (v4l2object->req_mode == GST_V4L2_IO_RW)
+ goto method_not_supported;
+
+ if (v4l2object->device_caps & V4L2_CAP_STREAMING)
+ {
+ if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
{
- if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
- mode = GST_V4L2_IO_RW;
+ if (!V4L2_TYPE_IS_OUTPUT (v4l2object->type) &&
+ gst_aml_v4l2_object_is_dmabuf_supported (v4l2object))
+ {
+ mode = GST_V4L2_IO_DMABUF;
+ }
+ else
+ {
+ mode = GST_V4L2_IO_MMAP;
+ }
}
- else if (v4l2object->req_mode == GST_V4L2_IO_RW)
- goto method_not_supported;
+ }
+ else if (v4l2object->req_mode == GST_V4L2_IO_MMAP ||
+ v4l2object->req_mode == GST_V4L2_IO_DMABUF)
+ goto method_not_supported;
- if (v4l2object->device_caps & V4L2_CAP_STREAMING)
- {
- if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
- {
- if (!V4L2_TYPE_IS_OUTPUT(v4l2object->type) &&
- gst_aml_v4l2_object_is_dmabuf_supported(v4l2object))
- {
- mode = GST_V4L2_IO_DMABUF;
- }
- else
- {
- mode = GST_V4L2_IO_MMAP;
- }
- }
- }
- else if (v4l2object->req_mode == GST_V4L2_IO_MMAP ||
- v4l2object->req_mode == GST_V4L2_IO_DMABUF)
- goto method_not_supported;
+ /* if still no transport selected, error out */
+ if (mode == GST_V4L2_IO_AUTO)
+ goto no_supported_capture_method;
- /* if still no transport selected, error out */
- if (mode == GST_V4L2_IO_AUTO)
- goto no_supported_capture_method;
+ GST_INFO_OBJECT (v4l2object->dbg_obj, "accessing buffers via mode %d", mode);
+ v4l2object->mode = mode;
- GST_INFO_OBJECT(v4l2object->dbg_obj, "accessing buffers via mode %d", mode);
- v4l2object->mode = mode;
+ /* If min_buffers is not set, the driver either does not support the control or
+ it has not been asked yet via propose_allocation/decide_allocation. */
+ if (!v4l2object->min_buffers)
+ gst_aml_v4l2_get_driver_min_buffers (v4l2object);
- /* If min_buffers is not set, the driver either does not support the control or
- it has not been asked yet via propose_allocation/decide_allocation. */
- if (!v4l2object->min_buffers)
- gst_aml_v4l2_get_driver_min_buffers(v4l2object);
-
- /* Map the buffers */
- GST_LOG_OBJECT(v4l2object->dbg_obj, "initiating buffer pool");
+ /* Map the buffers */
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "initiating buffer pool");
if (!(v4l2object->pool = gst_aml_v4l2_buffer_pool_new(v4l2object, caps)))
- goto buffer_pool_new_failed;
+ goto buffer_pool_new_failed;
- GST_AML_V4L2_SET_ACTIVE(v4l2object);
+ GST_AML_V4L2_SET_ACTIVE (v4l2object);
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
buffer_pool_new_failed:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, READ,
- (_("Could not map buffers from device '%s'"),
- v4l2object->videodev),
- ("Failed to create buffer pool: %s", g_strerror(errno)));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
+ (_("Could not map buffers from device '%s'"),
+ v4l2object->videodev),
+ ("Failed to create buffer pool: %s", g_strerror (errno)));
return FALSE;
-}
+ }
method_not_supported:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, READ,
- (_("The driver of device '%s' does not support the IO method %d"),
- v4l2object->videodev, mode),
- (NULL));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
+ (_("The driver of device '%s' does not support the IO method %d"),
+ v4l2object->videodev, mode), (NULL));
return FALSE;
-}
+ }
no_supported_capture_method:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, READ,
- (_("The driver of device '%s' does not support any known IO "
- "method."),
- v4l2object->videodev),
- (NULL));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
+ (_("The driver of device '%s' does not support any known IO "
+ "method."), v4l2object->videodev), (NULL));
return FALSE;
-}
+ }
}
static void
-gst_aml_v4l2_object_set_stride(GstVideoInfo *info, GstVideoAlignment *align,
- gint plane, gint stride)
+gst_aml_v4l2_object_set_stride (GstVideoInfo * info, GstVideoAlignment * align,
+ gint plane, gint stride)
{
- const GstVideoFormatInfo *finfo = info->finfo;
+ const GstVideoFormatInfo *finfo = info->finfo;
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(finfo))
- {
- gint x_tiles, y_tiles, ws, hs, tile_height, padded_height;
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
+ {
+ gint x_tiles, y_tiles, ws, hs, tile_height, padded_height;
- ws = GST_VIDEO_FORMAT_INFO_TILE_WS(finfo);
- hs = GST_VIDEO_FORMAT_INFO_TILE_HS(finfo);
- tile_height = 1 << hs;
+ ws = GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
+ hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
+ tile_height = 1 << hs;
- padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(finfo, plane,
- info->height + align->padding_top + align->padding_bottom);
- padded_height = GST_ROUND_UP_N(padded_height, tile_height);
+ padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
+ info->height + align->padding_top + align->padding_bottom);
+ padded_height = GST_ROUND_UP_N (padded_height, tile_height);
- x_tiles = stride >> ws;
- y_tiles = padded_height >> hs;
- info->stride[plane] = GST_VIDEO_TILE_MAKE_STRIDE(x_tiles, y_tiles);
- }
- else
- {
- info->stride[plane] = stride;
- }
+ x_tiles = stride >> ws;
+ y_tiles = padded_height >> hs;
+ info->stride[plane] = GST_VIDEO_TILE_MAKE_STRIDE (x_tiles, y_tiles);
+ }
+ else
+ {
+ info->stride[plane] = stride;
+ }
}
static void
-gst_aml_v4l2_object_extrapolate_info(GstAmlV4l2Object *v4l2object,
- GstVideoInfo *info, GstVideoAlignment *align, gint stride)
+gst_aml_v4l2_object_extrapolate_info (GstAmlV4l2Object * v4l2object,
+ GstVideoInfo * info, GstVideoAlignment * align, gint stride)
{
- const GstVideoFormatInfo *finfo = info->finfo;
- gint i, estride, padded_height;
- gsize offs = 0;
+ const GstVideoFormatInfo *finfo = info->finfo;
+ gint i, estride, padded_height;
+ gsize offs = 0;
- g_return_if_fail(v4l2object->n_v4l2_planes == 1);
+ g_return_if_fail (v4l2object->n_v4l2_planes == 1);
- padded_height = info->height + align->padding_top + align->padding_bottom;
+ padded_height = info->height + align->padding_top + align->padding_bottom;
+ for (i = 0; i < finfo->n_planes; i++)
+ {
+ estride = gst_aml_v4l2_object_extrapolate_stride (finfo, i, stride);
+
+ gst_aml_v4l2_object_set_stride (info, align, i, estride);
+
+ info->offset[i] = offs;
+ offs += estride *
+ GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, padded_height);
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Extrapolated for plane %d with base stride %d: "
+ "stride %d, offset %" G_GSIZE_FORMAT, i, stride, info->stride[i],
+ info->offset[i]);
+ }
+
+ /* Update the image size according the amount of data we are going to
+ * read/write. This workaround bugs in driver where the sizeimage provided
+ * by TRY/S_FMT represent the buffer length (maximum size) rather then the expected
+ * bytesused (buffer size). */
+ if (offs < info->size)
+ info->size = offs;
+}
+
+static void
+gst_aml_v4l2_object_save_format (GstAmlV4l2Object * v4l2object,
+ struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format,
+ GstVideoInfo * info, GstVideoAlignment * align)
+{
+ const GstVideoFormatInfo *finfo = info->finfo;
+ gboolean standard_stride = TRUE;
+ gint stride, pstride, padded_width, padded_height, i;
+
+ if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_ENCODED)
+ {
+ v4l2object->n_v4l2_planes = 1;
+ info->size = format->fmt.pix.sizeimage;
+ goto store_info;
+ }
+
+ /* adjust right padding */
+ if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+ stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
+ else
+ stride = format->fmt.pix.bytesperline;
+
+ pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (finfo, 0);
+ if (pstride)
+ {
+ padded_width = stride / pstride;
+ }
+ else
+ {
+ /* pstride can be 0 for complex formats */
+ GST_WARNING_OBJECT (v4l2object->element,
+ "format %s has a pstride of 0, cannot compute padded with",
+ gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
+ padded_width = stride;
+ }
+
+ if (padded_width < format->fmt.pix.width)
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Driver bug detected, stride (%d) is too small for the width (%d)",
+ padded_width, format->fmt.pix.width);
+
+ align->padding_right = padded_width - info->width - align->padding_left;
+
+ /* adjust bottom padding */
+ padded_height = format->fmt.pix.height;
+
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
+ {
+ guint hs, tile_height;
+
+ hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
+ tile_height = 1 << hs;
+
+ padded_height = GST_ROUND_UP_N (padded_height, tile_height);
+ }
+
+ align->padding_bottom = padded_height - info->height - align->padding_top;
+
+ /* setup the strides and offset */
+ if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+ {
+ struct v4l2_pix_format_mplane *pix_mp = &format->fmt.pix_mp;
+
+ /* figure out the frame layout */
+ v4l2object->n_v4l2_planes = MAX (1, pix_mp->num_planes);
+ info->size = 0;
+ for (i = 0; i < v4l2object->n_v4l2_planes; i++)
+ {
+ stride = pix_mp->plane_fmt[i].bytesperline;
+
+ if (info->stride[i] != stride)
+ standard_stride = FALSE;
+
+ gst_aml_v4l2_object_set_stride (info, align, i, stride);
+ info->offset[i] = info->size;
+ info->size += pix_mp->plane_fmt[i].sizeimage;
+ }
+
+ /* Extrapolate stride if planar format are being set in 1 v4l2 plane */
+ if (v4l2object->n_v4l2_planes < finfo->n_planes)
+ {
+ stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
+ gst_aml_v4l2_object_extrapolate_info (v4l2object, info, align, stride);
+ }
+ }
+ else
+ {
+ /* only one plane in non-MPLANE mode */
+ v4l2object->n_v4l2_planes = 1;
+ info->size = format->fmt.pix.sizeimage;
+ stride = format->fmt.pix.bytesperline;
+
+ if (info->stride[0] != stride)
+ standard_stride = FALSE;
+
+ gst_aml_v4l2_object_extrapolate_info (v4l2object, info, align, stride);
+ }
+
+ /* adjust the offset to take into account left and top */
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
+ {
+ if ((align->padding_left + align->padding_top) > 0)
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Left and top padding is not permitted for tiled formats");
+ }
+ else
+ {
for (i = 0; i < finfo->n_planes; i++)
{
- estride = gst_aml_v4l2_object_extrapolate_stride(finfo, i, stride);
+ gint vedge, hedge;
- gst_aml_v4l2_object_set_stride(info, align, i, estride);
+ /* FIXME we assume plane as component as this is true for all supported
+ * format we support. */
- info->offset[i] = offs;
- offs += estride *
- GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(finfo, i, padded_height);
+ hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, i, align->padding_left);
+ vedge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, align->padding_top);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Extrapolated for plane %d with base stride %d: "
- "stride %d, offset %" G_GSIZE_FORMAT,
- i, stride, info->stride[i],
- info->offset[i]);
+ info->offset[i] += (vedge * info->stride[i]) +
+ (hedge * GST_VIDEO_INFO_COMP_PSTRIDE (info, i));
}
-
- /* Update the image size according the amount of data we are going to
- * read/write. This workaround bugs in driver where the sizeimage provided
- * by TRY/S_FMT represent the buffer length (maximum size) rather then the expected
- * bytesused (buffer size). */
- if (offs < info->size)
- info->size = offs;
-}
-
-static void
-gst_aml_v4l2_object_save_format(GstAmlV4l2Object *v4l2object,
- struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format,
- GstVideoInfo *info, GstVideoAlignment *align)
-{
- const GstVideoFormatInfo *finfo = info->finfo;
- gboolean standard_stride = TRUE;
- gint stride, pstride, padded_width, padded_height, i;
-
- if (GST_VIDEO_INFO_FORMAT(info) == GST_VIDEO_FORMAT_ENCODED)
- {
- v4l2object->n_v4l2_planes = 1;
- info->size = format->fmt.pix.sizeimage;
- goto store_info;
- }
-
- /* adjust right padding */
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type))
- stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
- else
- stride = format->fmt.pix.bytesperline;
-
- pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE(finfo, 0);
- if (pstride)
- {
- padded_width = stride / pstride;
- }
- else
- {
- /* pstride can be 0 for complex formats */
- GST_WARNING_OBJECT(v4l2object->element,
- "format %s has a pstride of 0, cannot compute padded with",
- gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(info)));
- padded_width = stride;
- }
-
- if (padded_width < format->fmt.pix.width)
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Driver bug detected, stride (%d) is too small for the width (%d)",
- padded_width, format->fmt.pix.width);
-
- align->padding_right = padded_width - info->width - align->padding_left;
-
- /* adjust bottom padding */
- padded_height = format->fmt.pix.height;
-
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(finfo))
- {
- guint hs, tile_height;
-
- hs = GST_VIDEO_FORMAT_INFO_TILE_HS(finfo);
- tile_height = 1 << hs;
-
- padded_height = GST_ROUND_UP_N(padded_height, tile_height);
- }
-
- align->padding_bottom = padded_height - info->height - align->padding_top;
-
- /* setup the strides and offset */
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type))
- {
- struct v4l2_pix_format_mplane *pix_mp = &format->fmt.pix_mp;
-
- /* figure out the frame layout */
- v4l2object->n_v4l2_planes = MAX(1, pix_mp->num_planes);
- info->size = 0;
- for (i = 0; i < v4l2object->n_v4l2_planes; i++)
- {
- stride = pix_mp->plane_fmt[i].bytesperline;
-
- if (info->stride[i] != stride)
- standard_stride = FALSE;
-
- gst_aml_v4l2_object_set_stride(info, align, i, stride);
- info->offset[i] = info->size;
- info->size += pix_mp->plane_fmt[i].sizeimage;
- }
-
- /* Extrapolate stride if planar format are being set in 1 v4l2 plane */
- if (v4l2object->n_v4l2_planes < finfo->n_planes)
- {
- stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
- gst_aml_v4l2_object_extrapolate_info(v4l2object, info, align, stride);
- }
- }
- else
- {
- /* only one plane in non-MPLANE mode */
- v4l2object->n_v4l2_planes = 1;
- info->size = format->fmt.pix.sizeimage;
- stride = format->fmt.pix.bytesperline;
-
- if (info->stride[0] != stride)
- standard_stride = FALSE;
-
- gst_aml_v4l2_object_extrapolate_info(v4l2object, info, align, stride);
- }
-
- /* adjust the offset to take into account left and top */
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(finfo))
- {
- if ((align->padding_left + align->padding_top) > 0)
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Left and top padding is not permitted for tiled formats");
- }
- else
- {
- for (i = 0; i < finfo->n_planes; i++)
- {
- gint vedge, hedge;
-
- /* FIXME we assume plane as component as this is true for all supported
- * format we support. */
-
- hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(finfo, i, align->padding_left);
- vedge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(finfo, i, align->padding_top);
-
- info->offset[i] += (vedge * info->stride[i]) +
- (hedge * GST_VIDEO_INFO_COMP_PSTRIDE(info, i));
- }
- }
+ }
store_info:
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Got sizeimage %" G_GSIZE_FORMAT,
- info->size);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got sizeimage %" G_GSIZE_FORMAT,
+ info->size);
- /* to avoid copies we need video meta if there is padding */
- v4l2object->need_video_meta =
- ((align->padding_top + align->padding_left + align->padding_right +
+ /* to avoid copies we need video meta if there is padding */
+ v4l2object->need_video_meta =
+ ((align->padding_top + align->padding_left + align->padding_right +
align->padding_bottom) != 0);
- /* ... or if stride is non "standard" */
- if (!standard_stride)
- v4l2object->need_video_meta = TRUE;
+ /* ... or if stride is non "standard" */
+ if (!standard_stride)
+ v4l2object->need_video_meta = TRUE;
- /* ... or also video meta if we use multiple, non-contiguous, planes */
- if (v4l2object->n_v4l2_planes > 1)
- v4l2object->need_video_meta = TRUE;
+ /* ... or also video meta if we use multiple, non-contiguous, planes */
+ if (v4l2object->n_v4l2_planes > 1)
+ v4l2object->need_video_meta = TRUE;
- v4l2object->info = *info;
- v4l2object->align = *align;
- v4l2object->format = *format;
- v4l2object->fmtdesc = fmtdesc;
+ v4l2object->info = *info;
+ v4l2object->align = *align;
+ v4l2object->format = *format;
+ v4l2object->fmtdesc = fmtdesc;
- /* if we have a framerate pre-calculate duration */
- if (info->fps_n > 0 && info->fps_d > 0)
- {
- v4l2object->duration = gst_util_uint64_scale_int(GST_SECOND, info->fps_d,
- info->fps_n);
- }
- else
- {
- v4l2object->duration = GST_CLOCK_TIME_NONE;
- }
+ /* if we have a framerate pre-calculate duration */
+ if (info->fps_n > 0 && info->fps_d > 0)
+ {
+ v4l2object->duration = gst_util_uint64_scale_int (GST_SECOND, info->fps_d,
+ info->fps_n);
+ }
+ else
+ {
+ v4l2object->duration = GST_CLOCK_TIME_NONE;
+ }
}
-gint gst_aml_v4l2_object_extrapolate_stride(const GstVideoFormatInfo *finfo,
- gint plane, gint stride)
+gint
+gst_aml_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
+ gint plane, gint stride)
{
- gint estride;
+ gint estride;
- switch (finfo->format)
- {
+ switch (finfo->format)
+ {
case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV12_64Z32:
case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV61:
case GST_VIDEO_FORMAT_NV24:
- estride = (plane == 0 ? 1 : 2) *
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(finfo, plane, stride);
- break;
+ estride = (plane == 0 ? 1 : 2) *
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, plane, stride);
+ break;
default:
- estride = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH(finfo, plane, stride);
- break;
- }
+ estride = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, plane, stride);
+ break;
+ }
- return estride;
+ return estride;
}
static gboolean
-gst_aml_v4l2_video_colorimetry_matches(const GstVideoColorimetry *cinfo,
+gst_aml_v4l2_video_colorimetry_matches (const GstVideoColorimetry * cinfo,
const gchar *color)
{
- GstVideoColorimetry ci;
- static const GstVideoColorimetry ci_likely_jpeg = {
- GST_VIDEO_COLOR_RANGE_0_255, GST_VIDEO_COLOR_MATRIX_BT601,
- GST_VIDEO_TRANSFER_UNKNOWN, GST_VIDEO_COLOR_PRIMARIES_UNKNOWN};
- static const GstVideoColorimetry ci_jpeg = {
- GST_VIDEO_COLOR_RANGE_0_255, GST_VIDEO_COLOR_MATRIX_BT601,
- GST_VIDEO_TRANSFER_SRGB, GST_VIDEO_COLOR_PRIMARIES_BT709};
+ GstVideoColorimetry ci;
+ static const GstVideoColorimetry ci_likely_jpeg = {
+ GST_VIDEO_COLOR_RANGE_0_255, GST_VIDEO_COLOR_MATRIX_BT601,
+ GST_VIDEO_TRANSFER_UNKNOWN, GST_VIDEO_COLOR_PRIMARIES_UNKNOWN
+ };
+ static const GstVideoColorimetry ci_jpeg = {
+ GST_VIDEO_COLOR_RANGE_0_255, GST_VIDEO_COLOR_MATRIX_BT601,
+ GST_VIDEO_TRANSFER_SRGB, GST_VIDEO_COLOR_PRIMARIES_BT709
+ };
- if (!gst_video_colorimetry_from_string(&ci, color))
- return FALSE;
-
- if (gst_video_colorimetry_is_equal(&ci, cinfo))
- return TRUE;
-
- /* Allow 1:4:0:0 (produced by jpegdec) if the device expects 1:4:7:1 */
- if (gst_video_colorimetry_is_equal(&ci, &ci_likely_jpeg) && gst_video_colorimetry_is_equal(cinfo, &ci_jpeg))
- return TRUE;
-
+ if (!gst_video_colorimetry_from_string(&ci, color))
return FALSE;
+
+ if (gst_video_colorimetry_is_equal(&ci, cinfo))
+ return TRUE;
+
+ /* Allow 1:4:0:0 (produced by jpegdec) if the device expects 1:4:7:1 */
+ if (gst_video_colorimetry_is_equal(&ci, &ci_likely_jpeg) && gst_video_colorimetry_is_equal(cinfo, &ci_jpeg))
+ return TRUE;
+
+ return FALSE;
}
static gboolean needSpecConfigForFg(GstAmlV4l2Object *v4l2object)
{
- gboolean result= FALSE;
- int fd = -1;
- char valstr[64];
- const char* path= "/sys/class/video/film_grain_support";
- uint32_t val= 0;
- struct v4l2_control ctl;
+ gboolean result= FALSE;
+ int fd = -1;
+ char valstr[64];
+ const char* path= "/sys/class/video/film_grain_support";
+ uint32_t val= 0;
+ struct v4l2_control ctl;
- GST_LOG("configForFilmGrain: enter");
- fd = open(path, O_RDONLY|O_CLOEXEC);
- if ( fd < 0 )
- {
- GST_DEBUG("unable to open file (%s)", path);
- goto exit;
- }
+ GST_LOG("configForFilmGrain: enter");
+ fd = open(path, O_RDONLY|O_CLOEXEC);
+ if ( fd < 0 )
+ {
+ GST_DEBUG("unable to open file (%s)", path);
+ goto exit;
+ }
- memset(valstr, 0, sizeof(valstr));
- if (read(fd, valstr, sizeof(valstr) - 1) == -1 )
- {
- GST_DEBUG("unable to read fg flag");
- goto exit;
- }
+ memset(valstr, 0, sizeof(valstr));
+ if (read(fd, valstr, sizeof(valstr) - 1) == -1 )
+ {
+ GST_DEBUG("unable to read fg flag");
+ goto exit;
+ }
- valstr[strlen(valstr)] = '\0';
+ valstr[strlen(valstr)] = '\0';
- if ( sscanf(valstr, "%u", &val) < 1)
- {
- GST_DEBUG("unable to get flag from: (%s)", valstr);
- goto exit;
- }
+ if ( sscanf(valstr, "%u", &val) < 1)
+ {
+ GST_DEBUG("unable to get flag from: (%s)", valstr);
+ goto exit;
+ }
- GST_LOG("got film_grain_support:%d from node", val);
- if (val != 0)
- {
- goto exit;
- }
+ GST_LOG("got film_grain_support:%d from node", val);
+ if (val != 0)
+ {
+ goto exit;
+ }
- memset( &ctl, 0, sizeof(ctl));
- ctl.id= AML_V4L2_GET_FILMGRAIN_INFO;
- v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_CTRL, ctl);
- GST_LOG("got VIDIOC_G_CTRL value: %d", ctl.value);
- if (ctl.value == 0)
- {
- goto exit;
- }
+ memset( &ctl, 0, sizeof(ctl));
+ ctl.id= AML_V4L2_GET_FILMGRAIN_INFO;
+ v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_CTRL, ctl);
+ GST_LOG("got VIDIOC_G_CTRL value: %d", ctl.value);
+ if (ctl.value == 0)
+ {
+ goto exit;
+ }
- result= TRUE;
+ result= TRUE;
exit:
- if ( fd >= 0 )
- {
- close(fd);
- }
- GST_LOG("configForFilmGrain: exit: result %d", result);
- return result;
+ if ( fd >= 0 )
+ {
+ close(fd);
+ }
+ GST_LOG("configForFilmGrain: exit: result %d", result);
+ return result;
}
static gboolean
get_amlogic_vdec_parm(GstAmlV4l2Object *v4l2object, struct v4l2_streamparm *streamparm)
{
- struct v4l2_ext_control control;
- struct v4l2_ext_controls ctrls;
- gboolean use_ext_config = FALSE;
- int major = 0,minor = 0;
- struct utsname info;
- struct aml_dec_params *pdecParm = (struct aml_dec_params *)streamparm->parm.raw_data;
+ struct v4l2_ext_control control;
+ struct v4l2_ext_controls ctrls;
+ gboolean use_ext_config = FALSE;
+ int major = 0,minor = 0;
+ struct utsname info;
+ struct aml_dec_params *pdecParm = (struct aml_dec_params *)streamparm->parm.raw_data;
- if (uname(&info) || sscanf(info.release, "%d.%d", &major, &minor) <= 0)
- {
- GST_DEBUG("get linux version failed");
- return FALSE;
- }
- GST_DEBUG("linux major version %d %d", major,minor);
- use_ext_config = ((major == 5 && minor >= 15) || major >= 6) ? TRUE: FALSE;
+ if (uname(&info) || sscanf(info.release, "%d.%d", &major, &minor) <= 0)
+ {
+ GST_DEBUG("get linux version failed");
+ return FALSE;
+ }
+ GST_DEBUG("linux major version %d %d", major,minor);
+ use_ext_config = ((major == 5 && minor >= 15) || major >= 6) ? TRUE: FALSE;
- if (use_ext_config)
- {
- memset(&ctrls, 0, sizeof(ctrls));
- memset(&control, 0, sizeof(control));
- control.id = AML_V4L2_DEC_PARMS_CONFIG;
- control.ptr = pdecParm;
- control.size = sizeof(struct aml_dec_params);
- ctrls.count = 1;
- ctrls.controls = &control;
- if (v4l2object->ioctl( v4l2object->video_fd, VIDIOC_G_EXT_CTRLS, &ctrls ) <0)
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "get vdec parm fail");
- return FALSE;
- }
- GST_DEBUG("dw: %d, flag: %d, status: %d, margin: %d",pdecParm->cfg.double_write_mode,
- pdecParm->cfg.metadata_config_flag, pdecParm->parms_status, pdecParm->cfg.ref_buf_margin);
- }
- else
- {
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_PARM, streamparm) < 0)
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "get vdec parm fail");
- return FALSE;
- }
- }
- return TRUE;
+ if (use_ext_config)
+ {
+ memset(&ctrls, 0, sizeof(ctrls));
+ memset(&control, 0, sizeof(control));
+ control.id = AML_V4L2_DEC_PARMS_CONFIG;
+ control.ptr = pdecParm;
+ control.size = sizeof(struct aml_dec_params);
+ ctrls.count = 1;
+ ctrls.controls = &control;
+ if (v4l2object->ioctl( v4l2object->video_fd, VIDIOC_G_EXT_CTRLS, &ctrls ) <0)
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "get vdec parm fail");
+ return FALSE;
+ }
+ GST_DEBUG("dw: %d, flag: %d, status: %d, margin: %d",pdecParm->cfg.double_write_mode,
+ pdecParm->cfg.metadata_config_flag, pdecParm->parms_status, pdecParm->cfg.ref_buf_margin);
+ }
+ else
+ {
+ if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_PARM, streamparm) < 0)
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "get vdec parm fail");
+ return FALSE;
+ }
+ }
+ return TRUE;
}
static int gst_aml_config_dw(GstAmlV4l2Object *v4l2object, guint32 pixFormat, guint width, guint height, gboolean interlace)
{
- const char *env_dw;
- int double_write = VDEC_DW_NO_AFBC;
+ const char *env_dw;
+ int double_write = VDEC_DW_NO_AFBC;
- GST_DEBUG("pixFormat: %d", pixFormat);
- switch (pixFormat)
- {
- case V4L2_PIX_FMT_MPEG:
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- case V4L2_PIX_FMT_MPEG4:
- double_write = VDEC_DW_NO_AFBC;
- break;
- case V4L2_PIX_FMT_H264:
- {
- if (width > 1920 && height > 1080 && !interlace)
- double_write = VDEC_DW_AFBC_1_4_DW;
- else
- double_write = VDEC_DW_NO_AFBC;
- break;
- }
- case V4L2_PIX_FMT_HEVC:
- double_write = VDEC_DW_AFBC_AUTO_1_4;
- if (interlace)
- double_write = VDEC_DW_AFBC_1_1_DW;
- if (v4l2object->low_memory_mode)
- double_write = VDEC_DW_AFBC_ONLY;
- break;
- case V4L2_PIX_FMT_VP9:
- case V4L2_PIX_FMT_AV1:
- double_write = v4l2object->low_memory_mode ? VDEC_DW_AFBC_ONLY:VDEC_DW_AFBC_AUTO_1_4;
- break;
- default:
- GST_WARNING("unknown video format %d", pixFormat);
- break;
- }
+ GST_DEBUG("pixFormat: %d", pixFormat);
+ switch (pixFormat)
+ {
+ case V4L2_PIX_FMT_MPEG:
+ case V4L2_PIX_FMT_MPEG1:
+ case V4L2_PIX_FMT_MPEG2:
+ case V4L2_PIX_FMT_MPEG4:
+ double_write = VDEC_DW_NO_AFBC;
+ break;
+ case V4L2_PIX_FMT_H264:
+ {
+ if (width > 1920 && height > 1080 && !interlace)
+ double_write = VDEC_DW_AFBC_1_4_DW;
+ else
+ double_write = VDEC_DW_NO_AFBC;
+ break;
+ }
+ case V4L2_PIX_FMT_HEVC:
+ double_write = VDEC_DW_AFBC_AUTO_1_4;
+ if (interlace)
+ double_write = VDEC_DW_AFBC_1_1_DW;
+ if (v4l2object->low_memory_mode)
+ double_write = VDEC_DW_AFBC_ONLY;
+ break;
+ case V4L2_PIX_FMT_VP9:
+ case V4L2_PIX_FMT_AV1:
+ double_write = v4l2object->low_memory_mode ? VDEC_DW_AFBC_ONLY:VDEC_DW_AFBC_AUTO_1_4;
+ break;
+ default:
+ GST_WARNING("unknown video format %d", pixFormat);
+ break;
+ }
- env_dw = getenv("V4L2_SET_AMLOGIC_DW_MODE");
- if (env_dw)
- double_write = atoi(env_dw);
+ env_dw = getenv("V4L2_SET_AMLOGIC_DW_MODE");
+ if (env_dw)
+ double_write = atoi(env_dw);
- return double_write;
+ return double_write;
}
static void
@@ -4078,49 +4067,48 @@
}
static gboolean
-gst_aml_v4l2_object_set_format_full(GstAmlV4l2Object *v4l2object, GstCaps *caps,
- gboolean try_only, GstAmlV4l2Error *error)
+gst_aml_v4l2_object_set_format_full (GstAmlV4l2Object * v4l2object, GstCaps * caps,
+ gboolean try_only, GstAmlV4l2Error * error)
{
- gint fd = v4l2object->video_fd;
- struct v4l2_format format;
- struct v4l2_streamparm streamparm;
- enum v4l2_field field;
- guint32 pixelformat;
- struct v4l2_fmtdesc *fmtdesc;
- GstVideoInfo info;
- GstVideoAlignment align;
- gint width, height, fps_n, fps_d;
- gint n_v4l_planes;
- gint i = 0;
- gboolean is_mplane;
- enum v4l2_colorspace colorspace = 0;
- enum v4l2_quantization range = 0;
- enum v4l2_ycbcr_encoding matrix = 0;
- enum v4l2_xfer_func transfer = 0;
- GstStructure *s;
- gboolean disable_colorimetry = FALSE;
+ gint fd = v4l2object->video_fd;
+ struct v4l2_format format;
+ struct v4l2_streamparm streamparm;
+ enum v4l2_field field;
+ guint32 pixelformat;
+ struct v4l2_fmtdesc *fmtdesc;
+ GstVideoInfo info;
+ GstVideoAlignment align;
+ gint width, height, fps_n, fps_d;
+ gint n_v4l_planes;
+ gint i = 0;
+ gboolean is_mplane;
+ enum v4l2_colorspace colorspace = 0;
+ enum v4l2_quantization range = 0;
+ enum v4l2_ycbcr_encoding matrix = 0;
+ enum v4l2_xfer_func transfer = 0;
+ GstStructure *s;
+ gboolean disable_colorimetry = FALSE;
- g_return_val_if_fail(!v4l2object->skip_try_fmt_probes ||
- gst_caps_is_writable(caps),
- FALSE);
+ g_return_val_if_fail (!v4l2object->skip_try_fmt_probes ||
+ gst_caps_is_writable (caps), FALSE);
- GST_AML_V4L2_CHECK_OPEN(v4l2object);
- if (!try_only)
- GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object);
+ GST_AML_V4L2_CHECK_OPEN (v4l2object);
+ if (!try_only)
+ GST_AML_V4L2_CHECK_NOT_ACTIVE (v4l2object);
- is_mplane = V4L2_TYPE_IS_MULTIPLANAR(v4l2object->type);
+ is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);
- gst_video_info_init(&info);
- gst_video_alignment_reset(&align);
+ gst_video_info_init (&info);
+ gst_video_alignment_reset (&align);
- if (!gst_aml_v4l2_object_get_caps_info(v4l2object, caps, &fmtdesc, &info))
- goto invalid_caps;
+ if (!gst_aml_v4l2_object_get_caps_info (v4l2object, caps, &fmtdesc, &info))
+ goto invalid_caps;
- pixelformat = fmtdesc->pixelformat;
- width = GST_VIDEO_INFO_WIDTH(&info);
- height = GST_VIDEO_INFO_HEIGHT(&info);
- fps_n = GST_VIDEO_INFO_FPS_N(&info);
- fps_d = GST_VIDEO_INFO_FPS_D(&info);
+ pixelformat = fmtdesc->pixelformat;
+ width = GST_VIDEO_INFO_WIDTH (&info);
+ height = GST_VIDEO_INFO_HEIGHT (&info);
+ fps_n = GST_VIDEO_INFO_FPS_N (&info);
+ fps_d = GST_VIDEO_INFO_FPS_D (&info);
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Check image size");
struct v4l2_frmsizeenum size;
@@ -4128,2016 +4116,2019 @@
size.index = 0;
size.pixel_format = pixelformat;
if (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
- return FALSE;
+ return FALSE;
if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE)
{
- guint32 maxw, maxh;
- maxw = MIN (size.stepwise.max_width, G_MAXINT);
- maxh = MIN (size.stepwise.max_height, G_MAXINT);
- GST_DEBUG_OBJECT (v4l2object->dbg_obj, "image from caps w_h:%d_%d", width, height);
- GST_DEBUG_OBJECT (v4l2object->dbg_obj, "v4l2 support max w_h:%d_%d", maxw, maxh);
- if (width*height > maxw*maxh)
- return FALSE;
- GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Check image size ok");
+ guint32 maxw, maxh;
+ maxw = MIN (size.stepwise.max_width, G_MAXINT);
+ maxh = MIN (size.stepwise.max_height, G_MAXINT);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "image from caps w_h:%d_%d", width, height);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "v4l2 support max w_h:%d_%d", maxw, maxh);
+ if (width*height > maxw*maxh)
+ return FALSE;
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Check image size ok");
}
- //set amlogic params here,because we need pix format to set dw mode
- memset(&streamparm, 0x00, sizeof(struct v4l2_streamparm));
- set_amlogic_vdec_parm(v4l2object, &streamparm, caps, pixelformat);
+ //set amlogic params here,because we need pix format to set dw mode
+ memset (&streamparm, 0x00, sizeof (struct v4l2_streamparm));
+ set_amlogic_vdec_parm(v4l2object, &streamparm, caps, pixelformat);
- /* if encoded format (GST_VIDEO_INFO_N_PLANES return 0)
- * or if contiguous is prefered */
- n_v4l_planes = GST_VIDEO_INFO_N_PLANES(&info);
- if (!n_v4l_planes || !v4l2object->prefered_non_contiguous)
- n_v4l_planes = 1;
+ /* if encoded format (GST_VIDEO_INFO_N_PLANES return 0)
+ * or if contiguous is preferred */
+ n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info);
+ if (!n_v4l_planes || !v4l2object->prefered_non_contiguous)
+ n_v4l_planes = 1;
- if (GST_VIDEO_INFO_IS_INTERLACED(&info))
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "interlaced video");
- /* ideally we would differentiate between types of interlaced video
- * but there is not sufficient information in the caps..
- */
- field = V4L2_FIELD_INTERLACED;
- }
- else
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "progressive video");
- field = V4L2_FIELD_NONE;
- }
+ if (GST_VIDEO_INFO_IS_INTERLACED(&info))
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "interlaced video");
+ /* ideally we would differentiate between types of interlaced video
+ * but there is not sufficient information in the caps..
+ */
+ field = V4L2_FIELD_INTERLACED;
+ }
+ else
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "progressive video");
+ field = V4L2_FIELD_NONE;
+ }
- /* We first pick the main colorspace from the primaries */
- switch (info.colorimetry.primaries)
- {
+ /* We first pick the main colorspace from the primaries */
+ switch (info.colorimetry.primaries)
+ {
case GST_VIDEO_COLOR_PRIMARIES_BT709:
- /* There is two colorspaces using these primaries, use the range to
- * differentiate */
- if (info.colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235)
- colorspace = V4L2_COLORSPACE_REC709;
- else
- colorspace = V4L2_COLORSPACE_SRGB;
- break;
+ /* There is two colorspaces using these primaries, use the range to
+ * differentiate */
+ if (info.colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235)
+ colorspace = V4L2_COLORSPACE_REC709;
+ else
+ colorspace = V4L2_COLORSPACE_SRGB;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_BT2020:
- colorspace = V4L2_COLORSPACE_BT2020;
- break;
+ colorspace = V4L2_COLORSPACE_BT2020;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_BT470M:
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
+ colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_BT470BG:
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
+ colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
- colorspace = V4L2_COLORSPACE_SMPTE170M;
- break;
+ colorspace = V4L2_COLORSPACE_SMPTE170M;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_SMPTE240M:
- colorspace = V4L2_COLORSPACE_SMPTE240M;
- break;
+ colorspace = V4L2_COLORSPACE_SMPTE240M;
+ break;
case GST_VIDEO_COLOR_PRIMARIES_FILM:
case GST_VIDEO_COLOR_PRIMARIES_UNKNOWN:
- /* We don't know, we will guess */
- break;
+ /* We don't know, we will guess */
+ break;
default:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown colorimetry primaries %d", info.colorimetry.primaries);
- break;
- }
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown colorimetry primaries %d", info.colorimetry.primaries);
+ break;
+ }
- switch (info.colorimetry.range)
- {
+ switch (info.colorimetry.range)
+ {
case GST_VIDEO_COLOR_RANGE_0_255:
- range = V4L2_QUANTIZATION_FULL_RANGE;
- break;
+ range = V4L2_QUANTIZATION_FULL_RANGE;
+ break;
case GST_VIDEO_COLOR_RANGE_16_235:
- range = V4L2_QUANTIZATION_LIM_RANGE;
- break;
+ range = V4L2_QUANTIZATION_LIM_RANGE;
+ break;
case GST_VIDEO_COLOR_RANGE_UNKNOWN:
- /* We let the driver pick a default one */
- break;
+ /* We let the driver pick a default one */
+ break;
default:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown colorimetry range %d", info.colorimetry.range);
- break;
- }
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown colorimetry range %d", info.colorimetry.range);
+ break;
+ }
- switch (info.colorimetry.matrix)
- {
+ switch (info.colorimetry.matrix)
+ {
case GST_VIDEO_COLOR_MATRIX_RGB:
- /* Unspecified, leave to default */
- break;
- /* FCC is about the same as BT601 with less digit */
+ /* Unspecified, leave to default */
+ break;
+ /* FCC is about the same as BT601 with less digit */
case GST_VIDEO_COLOR_MATRIX_FCC:
case GST_VIDEO_COLOR_MATRIX_BT601:
- matrix = V4L2_YCBCR_ENC_601;
- break;
+ matrix = V4L2_YCBCR_ENC_601;
+ break;
case GST_VIDEO_COLOR_MATRIX_BT709:
- matrix = V4L2_YCBCR_ENC_709;
- break;
+ matrix = V4L2_YCBCR_ENC_709;
+ break;
case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
- matrix = V4L2_YCBCR_ENC_SMPTE240M;
- break;
+ matrix = V4L2_YCBCR_ENC_SMPTE240M;
+ break;
case GST_VIDEO_COLOR_MATRIX_BT2020:
- matrix = V4L2_YCBCR_ENC_BT2020;
- break;
+ matrix = V4L2_YCBCR_ENC_BT2020;
+ break;
case GST_VIDEO_COLOR_MATRIX_UNKNOWN:
- /* We let the driver pick a default one */
- break;
+ /* We let the driver pick a default one */
+ break;
default:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown colorimetry matrix %d", info.colorimetry.matrix);
- break;
- }
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown colorimetry matrix %d", info.colorimetry.matrix);
+ break;
+ }
- switch (info.colorimetry.transfer)
- {
+ switch (info.colorimetry.transfer)
+ {
case GST_VIDEO_TRANSFER_GAMMA18:
case GST_VIDEO_TRANSFER_GAMMA20:
case GST_VIDEO_TRANSFER_GAMMA22:
case GST_VIDEO_TRANSFER_GAMMA28:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "GAMMA 18, 20, 22, 28 transfer functions not supported");
- /* fallthrough */
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "GAMMA 18, 20, 22, 28 transfer functions not supported");
+ /* fallthrough */
case GST_VIDEO_TRANSFER_GAMMA10:
- transfer = V4L2_XFER_FUNC_NONE;
- break;
+ transfer = V4L2_XFER_FUNC_NONE;
+ break;
case GST_VIDEO_TRANSFER_BT2020_12:
case GST_VIDEO_TRANSFER_BT709:
- transfer = V4L2_XFER_FUNC_709;
- break;
+ transfer = V4L2_XFER_FUNC_709;
+ break;
case GST_VIDEO_TRANSFER_SMPTE240M:
- transfer = V4L2_XFER_FUNC_SMPTE240M;
- break;
+ transfer = V4L2_XFER_FUNC_SMPTE240M;
+ break;
case GST_VIDEO_TRANSFER_SRGB:
- transfer = V4L2_XFER_FUNC_SRGB;
- break;
+ transfer = V4L2_XFER_FUNC_SRGB;
+ break;
case GST_VIDEO_TRANSFER_LOG100:
case GST_VIDEO_TRANSFER_LOG316:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "LOG 100, 316 transfer functions not supported");
- /* FIXME No known sensible default, maybe AdobeRGB ? */
- break;
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "LOG 100, 316 transfer functions not supported");
+ /* FIXME No known sensible default, maybe AdobeRGB ? */
+ break;
case GST_VIDEO_TRANSFER_UNKNOWN:
- /* We let the driver pick a default one */
- break;
+ /* We let the driver pick a default one */
+ break;
default:
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Unknown colorimetry tranfer %d", info.colorimetry.transfer);
- break;
- }
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Unknown colorimetry transfer %d", info.colorimetry.transfer);
+ break;
+ }
- if (colorspace == 0)
+ if (colorspace == 0)
+ {
+ /* Try to guess colorspace according to pixelformat and size */
+ if (GST_VIDEO_INFO_IS_YUV (&info))
{
- /* Try to guess colorspace according to pixelformat and size */
- if (GST_VIDEO_INFO_IS_YUV(&info))
- {
- if (range == V4L2_QUANTIZATION_FULL_RANGE && matrix == V4L2_YCBCR_ENC_601 && transfer == 0)
- {
- /* Full range BT.601 YCbCr encoding with unknown primaries and transfer
- * function most likely is JPEG */
- colorspace = V4L2_COLORSPACE_JPEG;
- transfer = V4L2_XFER_FUNC_SRGB;
- }
- else
- {
- /* SD streams likely use SMPTE170M and HD streams REC709 */
- if (width <= 720 && height <= 576)
- colorspace = V4L2_COLORSPACE_SMPTE170M;
- else
- colorspace = V4L2_COLORSPACE_REC709;
- }
- }
- else if (GST_VIDEO_INFO_IS_RGB(&info))
- {
- colorspace = V4L2_COLORSPACE_SRGB;
- transfer = V4L2_XFER_FUNC_NONE;
- }
+ if (range == V4L2_QUANTIZATION_FULL_RANGE
+ && matrix == V4L2_YCBCR_ENC_601 && transfer == 0)
+ {
+ /* Full range BT.601 YCbCr encoding with unknown primaries and transfer
+ * function most likely is JPEG */
+ colorspace = V4L2_COLORSPACE_JPEG;
+ transfer = V4L2_XFER_FUNC_SRGB;
+ }
+ else
+ {
+ /* SD streams likely use SMPTE170M and HD streams REC709 */
+ if (width <= 720 && height <= 576)
+ colorspace = V4L2_COLORSPACE_SMPTE170M;
+ else
+ colorspace = V4L2_COLORSPACE_REC709;
+ }
+ }
+ else if (GST_VIDEO_INFO_IS_RGB (&info))
+ {
+ colorspace = V4L2_COLORSPACE_SRGB;
+ transfer = V4L2_XFER_FUNC_NONE;
+ }
+ }
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired format %dx%d, format "
+ "%" GST_FOURCC_FORMAT " stride: %d", width, height,
+ GST_FOURCC_ARGS (pixelformat), GST_VIDEO_INFO_PLANE_STRIDE (&info, 0));
+
+ memset (&format, 0x00, sizeof (struct v4l2_format));
+ format.type = v4l2object->type;
+
+ if (is_mplane)
+ {
+ format.type = v4l2object->type;
+ format.fmt.pix_mp.pixelformat = pixelformat;
+ format.fmt.pix_mp.width = width;
+ format.fmt.pix_mp.height = height;
+ format.fmt.pix_mp.field = field;
+ format.fmt.pix_mp.num_planes = n_v4l_planes;
+
+ /* try to ask our preferred stride but it's not a failure if not
+ * accepted */
+ for (i = 0; i < n_v4l_planes; i++)
+ {
+ gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, i);
+
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
+ stride = GST_VIDEO_TILE_X_TILES (stride) <<
+ GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);
+
+ format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
}
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Desired format %dx%d, format "
- "%" GST_FOURCC_FORMAT " stride: %d",
- width, height,
- GST_FOURCC_ARGS(pixelformat), GST_VIDEO_INFO_PLANE_STRIDE(&info, 0));
+ if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
+ {
+ if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT)
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = 1;
+ else
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = v4l2object->low_memory_mode ? LOW_MEM_ENCODED_BUFFER_SIZE : ENCODED_BUFFER_SIZE;
+ }
+ }
+ else
+ {
+ gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, 0);
- memset(&format, 0x00, sizeof(struct v4l2_format));
format.type = v4l2object->type;
- if (is_mplane)
+ format.fmt.pix.width = width;
+ format.fmt.pix.height = height;
+ format.fmt.pix.pixelformat = pixelformat;
+ format.fmt.pix.field = field;
+
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
+ stride = GST_VIDEO_TILE_X_TILES (stride) <<
+ GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);
+
+ /* try to ask our preferred stride */
+ format.fmt.pix.bytesperline = stride;
+
+ if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
{
- format.type = v4l2object->type;
- format.fmt.pix_mp.pixelformat = pixelformat;
- format.fmt.pix_mp.width = width;
- format.fmt.pix_mp.height = height;
- format.fmt.pix_mp.field = field;
- format.fmt.pix_mp.num_planes = n_v4l_planes;
-
- /* try to ask our prefered stride but it's not a failure if not
- * accepted */
- for (i = 0; i < n_v4l_planes; i++)
- {
- gint stride = GST_VIDEO_INFO_PLANE_STRIDE(&info, i);
-
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(info.finfo))
- stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(info.finfo);
-
- format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
- }
-
- if (GST_VIDEO_INFO_FORMAT(&info) == GST_VIDEO_FORMAT_ENCODED)
- {
- if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT)
- format.fmt.pix_mp.plane_fmt[0].sizeimage = 1;
- else
- format.fmt.pix_mp.plane_fmt[0].sizeimage = v4l2object->low_memory_mode ? LOW_MEM_ENCODED_BUFFER_SIZE : ENCODED_BUFFER_SIZE;
- }
+ if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT)
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = 1;
+ else
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = v4l2object->low_memory_mode ? LOW_MEM_ENCODED_BUFFER_SIZE : ENCODED_BUFFER_SIZE;
}
- else
- {
- gint stride = GST_VIDEO_INFO_PLANE_STRIDE(&info, 0);
+ }
- format.type = v4l2object->type;
-
- format.fmt.pix.width = width;
- format.fmt.pix.height = height;
- format.fmt.pix.pixelformat = pixelformat;
- format.fmt.pix.field = field;
-
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(info.finfo))
- stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(info.finfo);
-
- /* try to ask our prefered stride */
- format.fmt.pix.bytesperline = stride;
-
- if (GST_VIDEO_INFO_FORMAT(&info) == GST_VIDEO_FORMAT_ENCODED)
- {
- if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT)
- format.fmt.pix_mp.plane_fmt[0].sizeimage = 1;
- else
- format.fmt.pix_mp.plane_fmt[0].sizeimage = v4l2object->low_memory_mode ? LOW_MEM_ENCODED_BUFFER_SIZE : ENCODED_BUFFER_SIZE;
- }
- }
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Desired format is %dx%d, format "
- "%" GST_FOURCC_FORMAT ", nb planes %d",
- format.fmt.pix.width,
- format.fmt.pix_mp.height,
- GST_FOURCC_ARGS(format.fmt.pix.pixelformat),
- is_mplane ? format.fmt.pix_mp.num_planes : 1);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired format is %dx%d, format "
+ "%" GST_FOURCC_FORMAT ", nb planes %d", format.fmt.pix.width,
+ format.fmt.pix_mp.height,
+ GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
+ is_mplane ? format.fmt.pix_mp.num_planes : 1);
#ifndef GST_DISABLE_GST_DEBUG
- if (is_mplane)
- {
- for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, " stride %d",
- format.fmt.pix_mp.plane_fmt[i].bytesperline);
- }
- else
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, " stride %d",
- format.fmt.pix.bytesperline);
- }
+ if (is_mplane)
+ {
+ for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, " stride %d",
+ format.fmt.pix_mp.plane_fmt[i].bytesperline);
+ }
+ else
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, " stride %d",
+ format.fmt.pix.bytesperline);
+ }
#endif
- if (is_mplane)
- {
- format.fmt.pix_mp.colorspace = colorspace;
- format.fmt.pix_mp.quantization = range;
- format.fmt.pix_mp.ycbcr_enc = matrix;
- format.fmt.pix_mp.xfer_func = transfer;
- }
- else
- {
- format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
- format.fmt.pix.colorspace = colorspace;
- format.fmt.pix.quantization = range;
- format.fmt.pix.ycbcr_enc = matrix;
- format.fmt.pix.xfer_func = transfer;
- }
+ if (is_mplane)
+ {
+ format.fmt.pix_mp.colorspace = colorspace;
+ format.fmt.pix_mp.quantization = range;
+ format.fmt.pix_mp.ycbcr_enc = matrix;
+ format.fmt.pix_mp.xfer_func = transfer;
+ }
+ else
+ {
+ format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ format.fmt.pix.colorspace = colorspace;
+ format.fmt.pix.quantization = range;
+ format.fmt.pix.ycbcr_enc = matrix;
+ format.fmt.pix.xfer_func = transfer;
+ }
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Desired colorspace is %d:%d:%d:%d",
- colorspace, range, matrix, transfer);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired colorspace is %d:%d:%d:%d",
+ colorspace, range, matrix, transfer);
- if (try_only)
- {
- if (v4l2object->ioctl(fd, VIDIOC_TRY_FMT, &format) < 0)
- goto try_fmt_failed;
- }
- else
- {
- if (v4l2object->ioctl(fd, VIDIOC_S_FMT, &format) < 0)
- goto set_fmt_failed;
- }
+ if (try_only)
+ {
+ if (v4l2object->ioctl (fd, VIDIOC_TRY_FMT, &format) < 0)
+ goto try_fmt_failed;
+ }
+ else
+ {
+ if (v4l2object->ioctl (fd, VIDIOC_S_FMT, &format) < 0)
+ goto set_fmt_failed;
+ }
- if (is_mplane)
- {
- colorspace = format.fmt.pix_mp.colorspace;
- range = format.fmt.pix_mp.quantization;
- matrix = format.fmt.pix_mp.ycbcr_enc;
- transfer = format.fmt.pix_mp.xfer_func;
- }
- else
- {
- colorspace = format.fmt.pix.colorspace;
- range = format.fmt.pix.quantization;
- matrix = format.fmt.pix.ycbcr_enc;
- transfer = format.fmt.pix.xfer_func;
- }
+ if (is_mplane)
+ {
+ colorspace = format.fmt.pix_mp.colorspace;
+ range = format.fmt.pix_mp.quantization;
+ matrix = format.fmt.pix_mp.ycbcr_enc;
+ transfer = format.fmt.pix_mp.xfer_func;
+ }
+ else
+ {
+ colorspace = format.fmt.pix.colorspace;
+ range = format.fmt.pix.quantization;
+ matrix = format.fmt.pix.ycbcr_enc;
+ transfer = format.fmt.pix.xfer_func;
+ }
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Got format of %dx%d, format "
- "%" GST_FOURCC_FORMAT ", nb planes %d, colorspace %d:%d:%d:%d",
- format.fmt.pix.width, format.fmt.pix_mp.height,
- GST_FOURCC_ARGS(format.fmt.pix.pixelformat),
- is_mplane ? format.fmt.pix_mp.num_planes : 1,
- colorspace, range, matrix, transfer);
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Got format of %dx%d, format "
+ "%" GST_FOURCC_FORMAT ", nb planes %d, colorspace %d:%d:%d:%d",
+ format.fmt.pix.width, format.fmt.pix_mp.height,
+ GST_FOURCC_ARGS(format.fmt.pix.pixelformat),
+ is_mplane ? format.fmt.pix_mp.num_planes : 1,
+ colorspace, range, matrix, transfer);
#ifndef GST_DISABLE_GST_DEBUG
- if (is_mplane)
- {
- for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, " stride %d, sizeimage %d",
- format.fmt.pix_mp.plane_fmt[i].bytesperline,
- format.fmt.pix_mp.plane_fmt[i].sizeimage);
- }
- else
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, " stride %d, sizeimage %d",
- format.fmt.pix.bytesperline, format.fmt.pix.sizeimage);
- }
+ if (is_mplane)
+ {
+ for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, " stride %d, sizeimage %d",
+ format.fmt.pix_mp.plane_fmt[i].bytesperline,
+ format.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+ else
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, " stride %d, sizeimage %d",
+ format.fmt.pix.bytesperline, format.fmt.pix.sizeimage);
+ }
#endif
- if (format.fmt.pix.pixelformat != pixelformat)
- goto invalid_pixelformat;
+ if (format.fmt.pix.pixelformat != pixelformat)
+ goto invalid_pixelformat;
- /* Only negotiate size with raw data.
- * For some codecs the dimensions are *not* in the bitstream, IIRC VC1
- * in ASF mode for example, there is also not reason for a driver to
- * change the size. */
- if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED)
+ /* Only negotiate size with raw data.
+ * For some codecs the dimensions are *not* in the bitstream, IIRC VC1
+ * in ASF mode for example, there is also not reason for a driver to
+ * change the size. */
+ if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED)
+ {
+ /* We can crop larger images */
+ if (format.fmt.pix.width < width || format.fmt.pix.height < height)
+ goto invalid_dimensions;
+
+ /* Note, this will be adjusted if upstream has non-centered cropping. */
+ align.padding_top = 0;
+ align.padding_bottom = format.fmt.pix.height - height;
+ align.padding_left = 0;
+ align.padding_right = format.fmt.pix.width - width;
+ }
+
+ if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
+ goto invalid_planes;
+
+ /* used to check colorimetry and interlace mode fields presence */
+ s = gst_caps_get_structure (caps, 0);
+
+ if (!gst_aml_v4l2_object_get_interlace_mode(format.fmt.pix.field,
+ &info.interlace_mode))
+ goto invalid_field;
+ if (gst_structure_has_field(s, "interlace-mode"))
+ {
+ if (format.fmt.pix.field != field)
+ goto invalid_field;
+ }
+
+ if (gst_aml_v4l2_object_get_colorspace(&format, &info.colorimetry))
+ {
+ if (gst_structure_has_field(s, "colorimetry"))
+ {
+ if (!gst_aml_v4l2_video_colorimetry_matches(&info.colorimetry, gst_structure_get_string(s, "colorimetry")))
+ {
+ // goto invalid_colorimetry;
+ }
+ }
+ }
+ else
+ {
+ /* The driver (or libv4l2) is miss-behaving, just ignore colorimetry from
+ * the TRY_FMT */
+ disable_colorimetry = TRUE;
+ if (gst_structure_has_field (s, "colorimetry"))
+ gst_structure_remove_field (s, "colorimetry");
+ }
+
+ /* In case we have skipped the try_fmt probes, we'll need to set the
+ * colorimetry and interlace-mode back into the caps. */
+ if (v4l2object->skip_try_fmt_probes)
+ {
+ if (!disable_colorimetry && !gst_structure_has_field (s, "colorimetry"))
{
- /* We can crop larger images */
- if (format.fmt.pix.width < width || format.fmt.pix.height < height)
- goto invalid_dimensions;
-
- /* Note, this will be adjusted if upstream has non-centered cropping. */
- align.padding_top = 0;
- align.padding_bottom = format.fmt.pix.height - height;
- align.padding_left = 0;
- align.padding_right = format.fmt.pix.width - width;
+ gchar *str = gst_video_colorimetry_to_string (&info.colorimetry);
+ gst_structure_set (s, "colorimetry", G_TYPE_STRING, str, NULL);
+ g_free (str);
}
- if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
- goto invalid_planes;
+ if (!gst_structure_has_field(s, "interlace-mode"))
+ gst_structure_set(s, "interlace-mode", G_TYPE_STRING,
+ gst_video_interlace_mode_to_string(info.interlace_mode), NULL);
+ }
- /* used to check colorimetry and interlace mode fields presence */
- s = gst_caps_get_structure(caps, 0);
-
- if (!gst_aml_v4l2_object_get_interlace_mode(format.fmt.pix.field,
- &info.interlace_mode))
- goto invalid_field;
- if (gst_structure_has_field(s, "interlace-mode"))
- {
- if (format.fmt.pix.field != field)
- goto invalid_field;
- }
-
- if (gst_aml_v4l2_object_get_colorspace(&format, &info.colorimetry))
- {
- if (gst_structure_has_field(s, "colorimetry"))
- {
- if (!gst_aml_v4l2_video_colorimetry_matches(&info.colorimetry, gst_structure_get_string(s, "colorimetry")))
- {
- // goto invalid_colorimetry;
- }
- }
- }
- else
- {
- /* The driver (or libv4l2) is miss-behaving, just ignore colorimetry from
- * the TRY_FMT */
- disable_colorimetry = TRUE;
- if (gst_structure_has_field(s, "colorimetry"))
- gst_structure_remove_field(s, "colorimetry");
- }
-
- /* In case we have skipped the try_fmt probes, we'll need to set the
- * colorimetry and interlace-mode back into the caps. */
- if (v4l2object->skip_try_fmt_probes)
- {
- if (!disable_colorimetry && !gst_structure_has_field(s, "colorimetry"))
- {
- gchar *str = gst_video_colorimetry_to_string(&info.colorimetry);
- gst_structure_set(s, "colorimetry", G_TYPE_STRING, str, NULL);
- g_free(str);
- }
-
- if (!gst_structure_has_field(s, "interlace-mode"))
- gst_structure_set(s, "interlace-mode", G_TYPE_STRING,
- gst_video_interlace_mode_to_string(info.interlace_mode), NULL);
- }
-
- if (try_only) /* good enough for trying only */
- return TRUE;
-
- if (GST_VIDEO_INFO_HAS_ALPHA(&info))
- {
- struct v4l2_control ctl = {
- 0,
- };
- ctl.id = V4L2_CID_ALPHA_COMPONENT;
- ctl.value = 0xff;
-
- if (v4l2object->ioctl(fd, VIDIOC_S_CTRL, &ctl) < 0)
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Failed to set alpha component value");
- }
-
- /* Is there a reason we require the caller to always specify a framerate? */
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Desired framerate: %u/%u", fps_n,
- fps_d);
-
- if (v4l2object->ioctl(fd, VIDIOC_G_PARM, &streamparm) < 0)
- goto get_parm_failed;
-
- if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- {
- GST_VIDEO_INFO_FPS_N(&info) =
- streamparm.parm.capture.timeperframe.denominator;
- GST_VIDEO_INFO_FPS_D(&info) =
- streamparm.parm.capture.timeperframe.numerator;
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Got capture framerate: %u/%u",
- streamparm.parm.capture.timeperframe.denominator,
- streamparm.parm.capture.timeperframe.numerator);
-
- /* We used to skip frame rate setup if the camera was already setup
- * with the requested frame rate. This breaks some cameras though,
- * causing them to not output data (several models of Thinkpad cameras
- * have this problem at least).
- * So, don't skip. */
- GST_LOG_OBJECT(v4l2object->dbg_obj, "Setting capture framerate to %u/%u",
- fps_n, fps_d);
- /* We want to change the frame rate, so check whether we can. Some cheap USB
- * cameras don't have the capability */
- if ((streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0)
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Not setting capture framerate (not supported)");
- goto done;
- }
-
- /* Note: V4L2 wants the frame interval, we have the frame rate */
- streamparm.parm.capture.timeperframe.numerator = fps_d;
- streamparm.parm.capture.timeperframe.denominator = fps_n;
-
- if (streamparm.parm.capture.timeperframe.numerator > 0 &&
- streamparm.parm.capture.timeperframe.denominator > 0)
- {
- /* get new values */
- fps_d = streamparm.parm.capture.timeperframe.numerator;
- fps_n = streamparm.parm.capture.timeperframe.denominator;
-
- GST_INFO_OBJECT(v4l2object->dbg_obj, "Set capture framerate to %u/%u",
- fps_n, fps_d);
- }
- else
- {
- /* fix v4l2 capture driver to provide framerate values */
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
- }
-
- GST_VIDEO_INFO_FPS_N(&info) = fps_n;
- GST_VIDEO_INFO_FPS_D(&info) = fps_d;
- }
- else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- {
- GST_VIDEO_INFO_FPS_N(&info) =
- streamparm.parm.output.timeperframe.denominator;
- GST_VIDEO_INFO_FPS_D(&info) =
- streamparm.parm.output.timeperframe.numerator;
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Got output framerate: %u/%u",
- streamparm.parm.output.timeperframe.denominator,
- streamparm.parm.output.timeperframe.numerator);
-
- GST_LOG_OBJECT(v4l2object->dbg_obj, "Setting output framerate to %u/%u",
- fps_n, fps_d);
- if ((streamparm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) == 0)
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "Not setting output framerate (not supported)");
- goto done;
- }
-
- /* Note: V4L2 wants the frame interval, we have the frame rate */
- streamparm.parm.output.timeperframe.numerator = fps_d;
- streamparm.parm.output.timeperframe.denominator = fps_n;
-
- if (streamparm.parm.output.timeperframe.numerator > 0 &&
- streamparm.parm.output.timeperframe.denominator > 0)
- {
- /* get new values */
- fps_d = streamparm.parm.output.timeperframe.numerator;
- fps_n = streamparm.parm.output.timeperframe.denominator;
-
- GST_INFO_OBJECT(v4l2object->dbg_obj, "Set output framerate to %u/%u",
- fps_n, fps_d);
- }
- else
- {
- /* fix v4l2 output driver to provide framerate values */
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Reuse caps framerate %u/%u - fix v4l2 output driver", fps_n, fps_d);
- }
-
- GST_VIDEO_INFO_FPS_N(&info) = fps_n;
- GST_VIDEO_INFO_FPS_D(&info) = fps_d;
- }
-
-done:
- /* add boolean return, so we can fail on drivers bugs */
- gst_aml_v4l2_object_save_format(v4l2object, fmtdesc, &format, &info, &align);
-
- /* now configure the pool */
- if (!gst_aml_v4l2_object_setup_pool(v4l2object, caps))
- goto pool_failed;
-
+ if (try_only) /* good enough for trying only */
return TRUE;
- /* ERRORS */
-invalid_caps:
-{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "can't parse caps %" GST_PTR_FORMAT,
- caps);
+ if (GST_VIDEO_INFO_HAS_ALPHA (&info))
+ {
+ struct v4l2_control ctl = { 0, };
+ ctl.id = V4L2_CID_ALPHA_COMPONENT;
+ ctl.value = 0xff;
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Invalid caps")), ("Can't parse caps %" GST_PTR_FORMAT, caps));
- return FALSE;
-}
-try_fmt_failed:
-{
- if (errno == EINVAL)
+ if (v4l2object->ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Failed to set alpha component value");
+ }
+
+ /* Is there a reason we require the caller to always specify a framerate? */
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired framerate: %u/%u", fps_n,
+ fps_d);
+
+ if (v4l2object->ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
+ goto get_parm_failed;
+
+ if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ {
+ GST_VIDEO_INFO_FPS_N (&info) =
+ streamparm.parm.capture.timeperframe.denominator;
+ GST_VIDEO_INFO_FPS_D (&info) =
+ streamparm.parm.capture.timeperframe.numerator;
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got capture framerate: %u/%u",
+ streamparm.parm.capture.timeperframe.denominator,
+ streamparm.parm.capture.timeperframe.numerator);
+
+ /* We used to skip frame rate setup if the camera was already setup
+ * with the requested frame rate. This breaks some cameras though,
+ * causing them to not output data (several models of Thinkpad cameras
+ * have this problem at least).
+ * So, don't skip. */
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "Setting capture framerate to %u/%u",
+ fps_n, fps_d);
+ /* We want to change the frame rate, so check whether we can. Some cheap USB
+ * cameras don't have the capability */
+ if ((streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0)
{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' has no supported format"), v4l2object->videodev),
- ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
- GST_FOURCC_ARGS(pixelformat), width, height,
- g_strerror(errno)));
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Not setting capture framerate (not supported)");
+ goto done;
+ }
+
+ /* Note: V4L2 wants the frame interval, we have the frame rate */
+ streamparm.parm.capture.timeperframe.numerator = fps_d;
+ streamparm.parm.capture.timeperframe.denominator = fps_n;
+
+ if (streamparm.parm.capture.timeperframe.numerator > 0 &&
+ streamparm.parm.capture.timeperframe.denominator > 0)
+ {
+ /* get new values */
+ fps_d = streamparm.parm.capture.timeperframe.numerator;
+ fps_n = streamparm.parm.capture.timeperframe.denominator;
+
+ GST_INFO_OBJECT (v4l2object->dbg_obj, "Set capture framerate to %u/%u",
+ fps_n, fps_d);
}
else
{
- GST_AML_V4L2_ERROR(error, RESOURCE, FAILED,
- (_("Device '%s' failed during initialization"),
- v4l2object->videodev),
- ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
- GST_FOURCC_ARGS(pixelformat), width, height,
- g_strerror(errno)));
+ /* fix v4l2 capture driver to provide framerate values */
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
+ }
+
+ GST_VIDEO_INFO_FPS_N (&info) = fps_n;
+ GST_VIDEO_INFO_FPS_D (&info) = fps_d;
+ }
+ else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
+ || v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ {
+ GST_VIDEO_INFO_FPS_N (&info) =
+ streamparm.parm.output.timeperframe.denominator;
+ GST_VIDEO_INFO_FPS_D (&info) =
+ streamparm.parm.output.timeperframe.numerator;
+
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got output framerate: %u/%u",
+ streamparm.parm.output.timeperframe.denominator,
+ streamparm.parm.output.timeperframe.numerator);
+
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "Setting output framerate to %u/%u",
+ fps_n, fps_d);
+ if ((streamparm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) == 0)
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "Not setting output framerate (not supported)");
+ goto done;
+ }
+
+ /* Note: V4L2 wants the frame interval, we have the frame rate */
+ streamparm.parm.output.timeperframe.numerator = fps_d;
+ streamparm.parm.output.timeperframe.denominator = fps_n;
+
+ if (streamparm.parm.output.timeperframe.numerator > 0 &&
+ streamparm.parm.output.timeperframe.denominator > 0)
+ {
+ /* get new values */
+ fps_d = streamparm.parm.output.timeperframe.numerator;
+ fps_n = streamparm.parm.output.timeperframe.denominator;
+
+ GST_INFO_OBJECT (v4l2object->dbg_obj, "Set output framerate to %u/%u",
+ fps_n, fps_d);
+ }
+ else
+ {
+ /* fix v4l2 output driver to provide framerate values */
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Reuse caps framerate %u/%u - fix v4l2 output driver", fps_n, fps_d);
+ }
+
+ GST_VIDEO_INFO_FPS_N (&info) = fps_n;
+ GST_VIDEO_INFO_FPS_D (&info) = fps_d;
+ }
+
+done:
+ /* add boolean return, so we can fail on drivers bugs */
+ gst_aml_v4l2_object_save_format (v4l2object, fmtdesc, &format, &info, &align);
+
+ /* now configure the pool */
+ if (!gst_aml_v4l2_object_setup_pool (v4l2object, caps))
+ goto pool_failed;
+
+ return TRUE;
+
+ /* ERRORS */
+invalid_caps:
+ {
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "can't parse caps %" GST_PTR_FORMAT,
+ caps);
+
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Invalid caps")), ("Can't parse caps %" GST_PTR_FORMAT, caps));
+ return FALSE;
+ }
+try_fmt_failed:
+ {
+ if (errno == EINVAL)
+ {
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' has no supported format"), v4l2object->videodev),
+ ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
+ GST_FOURCC_ARGS (pixelformat), width, height,
+ g_strerror (errno)));
+ }
+ else
+ {
+ GST_AML_V4L2_ERROR (error, RESOURCE, FAILED,
+ (_("Device '%s' failed during initialization"),
+ v4l2object->videodev),
+ ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
+ GST_FOURCC_ARGS (pixelformat), width, height,
+ g_strerror (errno)));
}
return FALSE;
-}
+ }
set_fmt_failed:
-{
+ {
if (errno == EBUSY)
{
- GST_AML_V4L2_ERROR(error, RESOURCE, BUSY,
- (_("Device '%s' is busy"), v4l2object->videodev),
- ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
- GST_FOURCC_ARGS(pixelformat), width, height,
- g_strerror(errno)));
+ GST_AML_V4L2_ERROR (error, RESOURCE, BUSY,
+ (_("Device '%s' is busy"), v4l2object->videodev),
+ ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
+ GST_FOURCC_ARGS (pixelformat), width, height,
+ g_strerror (errno)));
}
else if (errno == EINVAL)
{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' has no supported format"), v4l2object->videodev),
- ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
- GST_FOURCC_ARGS(pixelformat), width, height,
- g_strerror(errno)));
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' has no supported format"), v4l2object->videodev),
+ ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
+ GST_FOURCC_ARGS (pixelformat), width, height,
+ g_strerror (errno)));
}
else
{
- GST_AML_V4L2_ERROR(error, RESOURCE, FAILED,
- (_("Device '%s' failed during initialization"),
- v4l2object->videodev),
- ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
- GST_FOURCC_ARGS(pixelformat), width, height,
- g_strerror(errno)));
+ GST_AML_V4L2_ERROR (error, RESOURCE, FAILED,
+ (_("Device '%s' failed during initialization"),
+ v4l2object->videodev),
+ ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
+ GST_FOURCC_ARGS (pixelformat), width, height,
+ g_strerror (errno)));
}
return FALSE;
-}
+ }
invalid_dimensions:
-{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' cannot capture at %dx%d"),
- v4l2object->videodev, width, height),
- ("Tried to capture at %dx%d, but device returned size %dx%d",
- width, height, format.fmt.pix.width, format.fmt.pix.height));
+ {
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' cannot capture at %dx%d"),
+ v4l2object->videodev, width, height),
+ ("Tried to capture at %dx%d, but device returned size %dx%d",
+ width, height, format.fmt.pix.width, format.fmt.pix.height));
return FALSE;
-}
+ }
invalid_pixelformat:
-{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' cannot capture in the specified format"),
- v4l2object->videodev),
- ("Tried to capture in %" GST_FOURCC_FORMAT
- ", but device returned format"
- " %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS(pixelformat),
- GST_FOURCC_ARGS(format.fmt.pix.pixelformat)));
+ {
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' cannot capture in the specified format"),
+ v4l2object->videodev),
+ ("Tried to capture in %" GST_FOURCC_FORMAT
+ ", but device returned format" " %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (pixelformat),
+ GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
return FALSE;
-}
+ }
invalid_planes:
-{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' does support non-contiguous planes"),
- v4l2object->videodev),
- ("Device wants %d planes", format.fmt.pix_mp.num_planes));
+ {
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' does support non-contiguous planes"),
+ v4l2object->videodev),
+ ("Device wants %d planes", format.fmt.pix_mp.num_planes));
return FALSE;
-}
+ }
invalid_field:
-{
+ {
enum v4l2_field wanted_field;
if (is_mplane)
- wanted_field = format.fmt.pix_mp.field;
+ wanted_field = format.fmt.pix_mp.field;
else
- wanted_field = format.fmt.pix.field;
+ wanted_field = format.fmt.pix.field;
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' does not support %s interlacing"),
- v4l2object->videodev,
- field == V4L2_FIELD_NONE ? "progressive" : "interleaved"),
- ("Device wants %s interlacing",
- wanted_field == V4L2_FIELD_NONE ? "progressive" : "interleaved"));
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' does not support %s interlacing"),
+ v4l2object->videodev,
+ field == V4L2_FIELD_NONE ? "progressive" : "interleaved"),
+ ("Device wants %s interlacing",
+ wanted_field == V4L2_FIELD_NONE ? "progressive" : "interleaved"));
return FALSE;
-}
+ }
#ifdef DELETE_FOR_LGE
invalid_colorimetry:
-{
+ {
gchar *wanted_colorimetry;
- wanted_colorimetry = gst_video_colorimetry_to_string(&info.colorimetry);
+ wanted_colorimetry = gst_video_colorimetry_to_string (&info.colorimetry);
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Device '%s' does not support %s colorimetry"),
- v4l2object->videodev, gst_structure_get_string(s, "colorimetry")),
- ("Device wants %s colorimetry", wanted_colorimetry));
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Device '%s' does not support %s colorimetry"),
+ v4l2object->videodev, gst_structure_get_string (s, "colorimetry")),
+ ("Device wants %s colorimetry", wanted_colorimetry));
- g_free(wanted_colorimetry);
+ g_free (wanted_colorimetry);
return FALSE;
-}
+ }
#endif
get_parm_failed:
-{
+ {
/* it's possible that this call is not supported */
if (errno != EINVAL && errno != ENOTTY)
{
- GST_AML_V4L2_ERROR(error, RESOURCE, SETTINGS,
- (_("Could not get parameters on device '%s'"),
- v4l2object->videodev),
- GST_ERROR_SYSTEM);
+ GST_AML_V4L2_ERROR (error, RESOURCE, SETTINGS,
+ (_("Could not get parameters on device '%s'"),
+ v4l2object->videodev), GST_ERROR_SYSTEM);
}
goto done;
-}
+ }
pool_failed:
-{
+ {
/* setup_pool already send the error */
return FALSE;
-}
+ }
}
gboolean
-gst_aml_v4l2_object_set_format(GstAmlV4l2Object *v4l2object, GstCaps *caps,
- GstAmlV4l2Error *error)
+gst_aml_v4l2_object_set_format (GstAmlV4l2Object * v4l2object, GstCaps * caps,
+ GstAmlV4l2Error * error)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Setting format to %" GST_PTR_FORMAT,
- caps);
- return gst_aml_v4l2_object_set_format_full(v4l2object, caps, FALSE, error);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Setting format to %" GST_PTR_FORMAT,
+ caps);
+ return gst_aml_v4l2_object_set_format_full (v4l2object, caps, FALSE, error);
}
gboolean
-gst_aml_v4l2_object_try_format(GstAmlV4l2Object *v4l2object, GstCaps *caps,
- GstAmlV4l2Error *error)
+gst_aml_v4l2_object_try_format (GstAmlV4l2Object * v4l2object, GstCaps * caps,
+ GstAmlV4l2Error * error)
{
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "Trying format %" GST_PTR_FORMAT,
- caps);
- return gst_aml_v4l2_object_set_format_full(v4l2object, caps, TRUE, error);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying format %" GST_PTR_FORMAT,
+ caps);
+ return gst_aml_v4l2_object_set_format_full (v4l2object, caps, TRUE, error);
}
GstFlowReturn
-gst_aml_v4l2_object_poll(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_poll (GstAmlV4l2Object * v4l2object)
{
- gint ret;
+ gint ret;
- if (!v4l2object->can_poll_device)
- goto done;
+ if (!v4l2object->can_poll_device)
+ goto done;
- GST_LOG_OBJECT(v4l2object, "polling device");
+ GST_LOG_OBJECT (v4l2object, "polling device");
again:
- ret = gst_poll_wait(v4l2object->poll, GST_CLOCK_TIME_NONE);
- if (G_UNLIKELY(ret < 0))
+ ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
+ if (G_UNLIKELY (ret < 0))
+ {
+ switch (errno)
{
- switch (errno)
- {
- case EBUSY:
- goto stopped;
- case EAGAIN:
- case EINTR:
- goto again;
- case ENXIO:
- GST_WARNING_OBJECT(v4l2object,
- "v4l2 device doesn't support polling. Disabling"
- " using libv4l2 in this case may cause deadlocks");
- v4l2object->can_poll_device = FALSE;
- goto done;
- default:
- goto select_error;
- }
+ case EBUSY:
+ goto stopped;
+ case EAGAIN:
+ case EINTR:
+ goto again;
+ case ENXIO:
+ GST_WARNING_OBJECT (v4l2object,
+ "v4l2 device doesn't support polling. Disabling"
+ " using libv4l2 in this case may cause deadlocks");
+ v4l2object->can_poll_device = FALSE;
+ goto done;
+ default:
+ goto select_error;
}
+ }
done:
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
- /* ERRORS */
+ /* ERRORS */
stopped:
-{
- GST_DEBUG_OBJECT(v4l2object, "stop called");
+ {
+ GST_DEBUG_OBJECT (v4l2object, "stop called");
return GST_FLOW_FLUSHING;
-}
+ }
select_error:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, READ, (NULL),
- ("poll error %d: %s (%d)", ret, g_strerror(errno), errno));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ, (NULL),
+ ("poll error %d: %s (%d)", ret, g_strerror (errno), errno));
return GST_FLOW_ERROR;
-}
+ }
}
GstFlowReturn
-gst_aml_v4l2_object_dqevent(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_dqevent (GstAmlV4l2Object * v4l2object)
{
- GstFlowReturn res;
- struct v4l2_event evt;
+ GstFlowReturn res;
+ struct v4l2_event evt;
- if ((res = gst_aml_v4l2_object_poll(v4l2object)) != GST_FLOW_OK)
- goto poll_failed;
+ if ((res = gst_aml_v4l2_object_poll (v4l2object)) != GST_FLOW_OK)
+ goto poll_failed;
- //only read v4l2 pri event
- if (!gst_poll_fd_can_read_pri(v4l2object->poll, &v4l2object->pollfd))
- {
- GST_DEBUG_OBJECT(v4l2object, "not v4l2 pri event");
- return GST_FLOW_OK;
- }
- memset(&evt, 0x00, sizeof(struct v4l2_event));
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_DQEVENT, &evt) < 0)
- goto dqevent_failed;
+ //only read v4l2 pri event
+ if (!gst_poll_fd_can_read_pri(v4l2object->poll, &v4l2object->pollfd))
+ {
+ GST_DEBUG_OBJECT(v4l2object, "not v4l2 pri event");
+ return GST_FLOW_OK;
+ }
+ memset (&evt, 0x00, sizeof (struct v4l2_event));
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_DQEVENT, &evt) < 0)
+ goto dqevent_failed;
- switch (evt.type)
- {
+ switch (evt.type)
+ {
case V4L2_EVENT_SOURCE_CHANGE:
- return GST_AML_V4L2_FLOW_SOURCE_CHANGE;
- break;
+ return GST_AML_V4L2_FLOW_SOURCE_CHANGE;
+ break;
case V4L2_EVENT_EOS:
- return GST_AML_V4L2_FLOW_LAST_BUFFER;
- break;
+ return GST_AML_V4L2_FLOW_LAST_BUFFER;
+ break;
default:
- break;
- }
+ break;
+ }
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
- /* ERRORS */
+ /* ERRORS */
poll_failed:
-{
- GST_DEBUG_OBJECT(v4l2object, "poll error %s", gst_flow_get_name(res));
+ {
+ GST_DEBUG_OBJECT (v4l2object, "poll error %s", gst_flow_get_name (res));
return res;
-}
+ }
dqevent_failed:
-{
+ {
GST_DEBUG_OBJECT(v4l2object, "dqevent failed");
return GST_FLOW_ERROR;
-}
+ }
}
/**
* gst_aml_v4l2_object_acquire_format:
- * @v4l2object the object
- * @info a GstVideoInfo to be filled
+ * @v4l2object: the object
+ * @info: a GstVideoInfo to be filled
*
- * Acquire the driver choosen format. This is useful in decoder or encoder elements where
- * the output format is choosen by the HW.
+ * Acquire the driver chosen format. This is useful in decoder or encoder elements where
+ * the output format is chosen by the HW.
*
* Returns: %TRUE on success, %FALSE on failure.
*/
gboolean
-gst_aml_v4l2_object_acquire_format(GstAmlV4l2Object *v4l2object, GstVideoInfo *info)
+gst_aml_v4l2_object_acquire_format (GstAmlV4l2Object * v4l2object, GstVideoInfo * info)
{
- struct v4l2_fmtdesc *fmtdesc;
- struct v4l2_format fmt;
- struct v4l2_crop crop;
- struct v4l2_selection sel;
- struct v4l2_cropcap cropcap;
- struct v4l2_rect *r = NULL;
- GstVideoFormat format;
- guint width, height;
- GstVideoAlignment align;
- gdouble pixelAspectRatio = 0.0;
+ struct v4l2_fmtdesc *fmtdesc;
+ struct v4l2_format fmt;
+ struct v4l2_crop crop;
+ struct v4l2_selection sel;
+ struct v4l2_cropcap cropcap;
+ struct v4l2_rect *r = NULL;
+ GstVideoFormat format;
+ guint width, height;
+ GstVideoAlignment align;
+ gdouble pixelAspectRatio = 0.0;
- gst_video_info_init(info);
- gst_video_alignment_reset(&align);
+ gst_video_info_init (info);
+ gst_video_alignment_reset (&align);
- memset(&fmt, 0x00, sizeof(struct v4l2_format));
- fmt.type = v4l2object->type;
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "fmt.type:%d", fmt.type);
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_FMT, &fmt) < 0)
- goto get_fmt_failed;
+ memset (&fmt, 0x00, sizeof (struct v4l2_format));
+ fmt.type = v4l2object->type;
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "fmt.type:%d", fmt.type);
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_FMT, &fmt) < 0)
+ goto get_fmt_failed;
- fmtdesc = gst_aml_v4l2_object_get_format_from_fourcc(v4l2object,
- fmt.fmt.pix.pixelformat);
- if (fmtdesc == NULL)
- goto unsupported_format;
+ fmtdesc = gst_aml_v4l2_object_get_format_from_fourcc (v4l2object,
+ fmt.fmt.pix.pixelformat);
+ if (fmtdesc == NULL)
+ goto unsupported_format;
- /* No need to care about mplane, the four first params are the same */
- format = gst_aml_v4l2_object_v4l2fourcc_to_video_format(fmt.fmt.pix.pixelformat);
+ /* No need to care about mplane, the four first params are the same */
+ format = gst_aml_v4l2_object_v4l2fourcc_to_video_format (fmt.fmt.pix.pixelformat);
- /* fails if we do no translate the fmt.pix.pixelformat to GstVideoFormat */
- if (format == GST_VIDEO_FORMAT_UNKNOWN)
- goto unsupported_format;
+ /* fails if we do no translate the fmt.pix.pixelformat to GstVideoFormat */
+ if (format == GST_VIDEO_FORMAT_UNKNOWN)
+ goto unsupported_format;
- if (fmt.fmt.pix.width == 0 || fmt.fmt.pix.height == 0)
- goto invalid_dimensions;
+ if (fmt.fmt.pix.width == 0 || fmt.fmt.pix.height == 0)
+ goto invalid_dimensions;
- width = fmt.fmt.pix.width;
- height = fmt.fmt.pix.height;
- /* Use the default compose rectangle */
- memset(&sel, 0, sizeof(struct v4l2_selection));
- sel.type = v4l2object->type;
- sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_SELECTION, &sel) >= 0)
+ width = fmt.fmt.pix.width;
+ height = fmt.fmt.pix.height;
+
+ /* Use the default compose rectangle */
+ memset (&sel, 0, sizeof (struct v4l2_selection));
+ sel.type = v4l2object->type;
+ sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_SELECTION, &sel) >= 0)
+ {
+ r = &sel.r;
+ }
+ else
+ {
+ /* For ancient kernels, fall back to G_CROP */
+ memset (&crop, 0, sizeof (struct v4l2_crop));
+ crop.type = v4l2object->type;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0)
+ r = &crop.c;
+ }
+
+ if (r)
+ {
+ GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec*) v4l2object->element;
+
+ align.padding_left = r->left;
+ align.padding_top = r->top;
+ align.padding_right = width - r->width - r->left;
+ align.padding_bottom = height - r->height - r->top;
+ width = r->width;
+ height = r->height;
+
+ if (self->v4l2output->dw_mode >= 0 && self->v4l2output->dw_mode != VDEC_DW_NO_AFBC)
{
- r = &sel.r;
- }
- else
- {
- /* For ancient kernels, fall back to G_CROP */
- memset(&crop, 0, sizeof(struct v4l2_crop));
- crop.type = v4l2object->type;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0)
- r = &crop.c;
+ width = (width/2) *2; // align for dw
+ height = (height/2) *2; // align for dw
}
- if (r)
- {
- GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec*) v4l2object->element;
+ if (self->v4l2output->dw_mode == VDEC_DW_AFBC_ONLY)
+ height = width = 64; //because driver return src w,h when AFBC_ONLY
+ }
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "final w:%d, h:%d", width, height);
- align.padding_left = r->left;
- align.padding_top = r->top;
- align.padding_right = width - r->width - r->left;
- align.padding_bottom = height - r->height - r->top;
- width = r->width;
- height = r->height;
+ gst_video_info_set_format(info, format, width, height);
- if (self->v4l2output->dw_mode >= 0 && self->v4l2output->dw_mode != VDEC_DW_NO_AFBC)
- {
- width = (width/2) *2; // align for dw
- height = (height/2) *2; // align for dw
- }
-
- if (self->v4l2output->dw_mode == VDEC_DW_AFBC_ONLY)
- height = width = 64; //because driver return src w,h when AFBC_ONLY
- }
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "final w:%d, h:%d", width, height);
-
- gst_video_info_set_format(info, format, width, height);
-
- switch (fmt.fmt.pix.field)
- {
+ switch (fmt.fmt.pix.field)
+ {
case V4L2_FIELD_ANY:
case V4L2_FIELD_NONE:
- info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
- break;
+ info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
+ break;
case V4L2_FIELD_INTERLACED:
case V4L2_FIELD_INTERLACED_TB:
case V4L2_FIELD_INTERLACED_BT:
- info->interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
- break;
+ info->interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
+ break;
default:
- goto unsupported_field;
- }
+ goto unsupported_field;
+ }
- gst_aml_v4l2_object_get_colorspace(&fmt, &info->colorimetry);
+ gst_aml_v4l2_object_get_colorspace(&fmt, &info->colorimetry);
- gst_aml_v4l2_object_save_format(v4l2object, fmtdesc, &fmt, info, &align);
+ gst_aml_v4l2_object_save_format(v4l2object, fmtdesc, &fmt, info, &align);
- if (v4l2object->par)
- {
- width = gst_value_get_fraction_numerator(v4l2object->par);
- height = gst_value_get_fraction_denominator(v4l2object->par);
- pixelAspectRatio = (gdouble)width/(gdouble)height;
- }
+ if (v4l2object->par)
+ {
+ width = gst_value_get_fraction_numerator(v4l2object->par);
+ height = gst_value_get_fraction_denominator(v4l2object->par);
+ pixelAspectRatio = (gdouble)width/(gdouble)height;
+ }
- if (!v4l2object->par || pixelAspectRatio == 1.0)
- {
- memset(&cropcap, 0, sizeof(cropcap));
- width= height= 1;
- cropcap.type = v4l2object->type;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) >= 0)
- {
- width= cropcap.pixelaspect.denominator;
- height= cropcap.pixelaspect.numerator;
- GST_DEBUG("cropcap: pixel aspect ratio %d:%d", width, height);
- if ( !width || !height )
- {
- GST_DEBUG("force pixel aspect of 1:1");
- width= height= 1;
- }
- }
- }
+ if (!v4l2object->par || pixelAspectRatio == 1.0)
+ {
+ memset(&cropcap, 0, sizeof(cropcap));
+ width= height= 1;
+ cropcap.type = v4l2object->type;
+ if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) >= 0)
+ {
+ width= cropcap.pixelaspect.denominator;
+ height= cropcap.pixelaspect.numerator;
+ GST_DEBUG("cropcap: pixel aspect ratio %d:%d", width, height);
+ if ( !width || !height )
+ {
+ GST_DEBUG("force pixel aspect of 1:1");
+ width= height= 1;
+ }
+ }
+ }
- GST_VIDEO_INFO_PAR_N(info) = width;
- GST_VIDEO_INFO_PAR_D(info) = height;
+ GST_VIDEO_INFO_PAR_N(info) = width;
+ GST_VIDEO_INFO_PAR_D(info) = height;
- if (v4l2object->fps)
- {
- GST_VIDEO_INFO_FPS_N(info) = gst_value_get_fraction_numerator(v4l2object->fps);
- GST_VIDEO_INFO_FPS_D(info) = gst_value_get_fraction_denominator(v4l2object->fps);
- }
- /* Shall we setup the pool ? */
+ if (v4l2object->fps)
+ {
+ GST_VIDEO_INFO_FPS_N(info) = gst_value_get_fraction_numerator(v4l2object->fps);
+ GST_VIDEO_INFO_FPS_D(info) = gst_value_get_fraction_denominator(v4l2object->fps);
+ }
+ /* Shall we setup the pool ? */
- return TRUE;
+ return TRUE;
get_fmt_failed:
-{
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Video device did not provide output format.")), GST_ERROR_SYSTEM);
+ {
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Video device did not provide output format.")), GST_ERROR_SYSTEM);
return FALSE;
-}
+ }
invalid_dimensions:
-{
- GST_ELEMENT_WARNING(v4l2object->element, RESOURCE, SETTINGS,
- (_("Video device returned invalid dimensions.")),
- ("Expected non 0 dimensions, got %dx%d", fmt.fmt.pix.width,
- fmt.fmt.pix.height));
+ {
+ GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Video device returned invalid dimensions.")),
+ ("Expected non 0 dimensions, got %dx%d", fmt.fmt.pix.width,
+ fmt.fmt.pix.height));
return FALSE;
-}
+ }
unsupported_field:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS,
- (_("Video device uses an unsupported interlacing method.")),
- ("V4L2 field type %d not supported", fmt.fmt.pix.field));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Video device uses an unsupported interlacing method.")),
+ ("V4L2 field type %d not supported", fmt.fmt.pix.field));
return FALSE;
-}
+ }
unsupported_format:
-{
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS,
- (_("Video device uses an unsupported pixel format.")),
- ("V4L2 format %" GST_FOURCC_FORMAT " not supported",
- GST_FOURCC_ARGS(fmt.fmt.pix.pixelformat)));
+ {
+ GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+ (_("Video device uses an unsupported pixel format.")),
+ ("V4L2 format %" GST_FOURCC_FORMAT " not supported",
+ GST_FOURCC_ARGS (fmt.fmt.pix.pixelformat)));
return FALSE;
-}
+ }
}
gboolean
gst_aml_v4l2_object_set_crop(GstAmlV4l2Object *obj)
{
- struct v4l2_selection sel = {0};
- struct v4l2_crop crop = {0};
+ struct v4l2_selection sel = { 0 };
+ struct v4l2_crop crop = { 0 };
- sel.type = obj->type;
- sel.target = V4L2_SEL_TGT_CROP;
- sel.flags = 0;
- sel.r.left = obj->align.padding_left;
- sel.r.top = obj->align.padding_top;
- sel.r.width = obj->info.width;
- sel.r.height = obj->info.height;
+ sel.type = obj->type;
+ sel.target = V4L2_SEL_TGT_CROP;
+ sel.flags = 0;
+ sel.r.left = obj->align.padding_left;
+ sel.r.top = obj->align.padding_top;
+ sel.r.width = obj->info.width;
+ sel.r.height = obj->info.height;
- crop.type = obj->type;
- crop.c = sel.r;
+ crop.type = obj->type;
+ crop.c = sel.r;
- if (obj->align.padding_left + obj->align.padding_top +
- obj->align.padding_right + obj->align.padding_bottom ==
- 0)
+ if (obj->align.padding_left + obj->align.padding_top +
+ obj->align.padding_right + obj->align.padding_bottom ==
+ 0)
+ {
+ GST_DEBUG_OBJECT(obj->dbg_obj, "no cropping needed");
+ return TRUE;
+ }
+
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
+ crop.c.width, crop.c.height);
+
+ if (obj->ioctl (obj->video_fd, VIDIOC_S_SELECTION, &sel) < 0)
+ {
+ if (errno != ENOTTY)
{
- GST_DEBUG_OBJECT(obj->dbg_obj, "no cropping needed");
- return TRUE;
+ GST_WARNING_OBJECT (obj->dbg_obj,
+ "Failed to set crop rectangle with VIDIOC_S_SELECTION: %s",
+ g_strerror (errno));
+ return FALSE;
}
-
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
- crop.c.width, crop.c.height);
-
- if (obj->ioctl(obj->video_fd, VIDIOC_S_SELECTION, &sel) < 0)
+ else
{
- if (errno != ENOTTY)
- {
- GST_WARNING_OBJECT(obj->dbg_obj,
- "Failed to set crop rectangle with VIDIOC_S_SELECTION: %s",
- g_strerror(errno));
- return FALSE;
- }
- else
- {
- if (obj->ioctl(obj->video_fd, VIDIOC_S_CROP, &crop) < 0)
- {
- GST_WARNING_OBJECT(obj->dbg_obj, "VIDIOC_S_CROP failed");
- return FALSE;
- }
+ if (obj->ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0)
+ {
+ GST_WARNING_OBJECT (obj->dbg_obj, "VIDIOC_S_CROP failed");
+ return FALSE;
+ }
- if (obj->ioctl(obj->video_fd, VIDIOC_G_CROP, &crop) < 0)
- {
- GST_WARNING_OBJECT(obj->dbg_obj, "VIDIOC_G_CROP failed");
- return FALSE;
- }
+ if (obj->ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0)
+ {
+ GST_WARNING_OBJECT (obj->dbg_obj, "VIDIOC_G_CROP failed");
+ return FALSE;
+ }
- sel.r = crop.c;
- }
+ sel.r = crop.c;
}
+ }
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "Got cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
- crop.c.width, crop.c.height);
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "Got cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
+ crop.c.width, crop.c.height);
- return TRUE;
+ return TRUE;
}
gboolean
-gst_aml_v4l2_object_caps_equal(GstAmlV4l2Object *v4l2object, GstCaps *caps)
+gst_aml_v4l2_object_caps_equal (GstAmlV4l2Object * v4l2object, GstCaps * caps)
{
- GstStructure *config;
- GstCaps *oldcaps;
- gboolean ret;
+ GstStructure *config;
+ GstCaps *oldcaps;
+ gboolean ret;
- if (!v4l2object->pool)
- return FALSE;
+ if (!v4l2object->pool)
+ return FALSE;
- config = gst_buffer_pool_get_config(v4l2object->pool);
- gst_buffer_pool_config_get_params(config, &oldcaps, NULL, NULL, NULL);
+ config = gst_buffer_pool_get_config(v4l2object->pool);
+ gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
- ret = oldcaps && gst_caps_is_equal(caps, oldcaps);
+ ret = oldcaps && gst_caps_is_equal (caps, oldcaps);
- gst_structure_free(config);
+ gst_structure_free (config);
- return ret;
+ return ret;
}
gboolean
-gst_aml_v4l2_object_caps_is_subset(GstAmlV4l2Object *v4l2object, GstCaps *caps)
+gst_aml_v4l2_object_caps_is_subset (GstAmlV4l2Object * v4l2object, GstCaps * caps)
{
- GstStructure *config;
- GstCaps *oldcaps;
- gboolean ret;
+ GstStructure *config;
+ GstCaps *oldcaps;
+ gboolean ret;
- if (!v4l2object->pool)
- return FALSE;
+ if (!v4l2object->pool)
+ return FALSE;
- config = gst_buffer_pool_get_config(v4l2object->pool);
- gst_buffer_pool_config_get_params(config, &oldcaps, NULL, NULL, NULL);
+ config = gst_buffer_pool_get_config(v4l2object->pool);
+ gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
- ret = oldcaps && gst_caps_is_subset(oldcaps, caps);
+ ret = oldcaps && gst_caps_is_subset (oldcaps, caps);
- gst_structure_free(config);
+ gst_structure_free (config);
- return ret;
+ return ret;
}
GstCaps *
-gst_aml_v4l2_object_get_current_caps(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_get_current_caps (GstAmlV4l2Object * v4l2object)
{
- GstStructure *config;
- GstCaps *oldcaps;
+ GstStructure *config;
+ GstCaps *oldcaps;
- if (!v4l2object->pool)
- return NULL;
+ if (!v4l2object->pool)
+ return NULL;
- config = gst_buffer_pool_get_config(v4l2object->pool);
- gst_buffer_pool_config_get_params(config, &oldcaps, NULL, NULL, NULL);
+ config = gst_buffer_pool_get_config(v4l2object->pool);
+ gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
- if (oldcaps)
- gst_caps_ref(oldcaps);
+ if (oldcaps)
+ gst_caps_ref (oldcaps);
- gst_structure_free(config);
+ gst_structure_free (config);
- return oldcaps;
+ return oldcaps;
}
gboolean
gst_aml_v4l2_object_flush_start(GstAmlV4l2Object *v4l2object)
{
- gboolean ret = TRUE;
+ gboolean ret = TRUE;
- GST_LOG_OBJECT(v4l2object->dbg_obj, "start flushing");
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "start flushing");
- gst_poll_set_flushing(v4l2object->poll, TRUE);
+ gst_poll_set_flushing (v4l2object->poll, TRUE);
- if (v4l2object->pool && gst_buffer_pool_is_active(v4l2object->pool))
- gst_buffer_pool_set_flushing(v4l2object->pool, TRUE);
+ if (v4l2object->pool && gst_buffer_pool_is_active(v4l2object->pool))
+ gst_buffer_pool_set_flushing(v4l2object->pool, TRUE);
- return ret;
+ return ret;
}
gboolean
gst_aml_v4l2_object_flush_stop(GstAmlV4l2Object *v4l2object)
{
- gboolean ret = TRUE;
+ gboolean ret = TRUE;
- GST_LOG_OBJECT(v4l2object->dbg_obj, "stop flushing");
+ GST_LOG_OBJECT (v4l2object->dbg_obj, "stop flushing");
- if (v4l2object->pool && gst_buffer_pool_is_active(v4l2object->pool))
- gst_buffer_pool_set_flushing(v4l2object->pool, FALSE);
+ if (v4l2object->pool && gst_buffer_pool_is_active(v4l2object->pool))
+ gst_buffer_pool_set_flushing(v4l2object->pool, FALSE);
- gst_poll_set_flushing(v4l2object->poll, FALSE);
+ gst_poll_set_flushing(v4l2object->poll, FALSE);
- return ret;
+ return ret;
}
gboolean
-gst_aml_v4l2_object_stop(GstAmlV4l2Object *v4l2object)
+gst_aml_v4l2_object_stop (GstAmlV4l2Object * v4l2object)
{
- GstAmlV4l2BufferPool *bpool = GST_AML_V4L2_BUFFER_POOL(v4l2object->pool);
+ GstAmlV4l2BufferPool *bpool = GST_AML_V4L2_BUFFER_POOL(v4l2object->pool);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "stopping");
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "stopping");
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- goto done;
- if (!GST_AML_V4L2_IS_ACTIVE(v4l2object))
- goto done;
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
+ goto done;
+ if (!GST_AML_V4L2_IS_ACTIVE (v4l2object))
+ goto done;
- if (bpool && bpool->other_pool) /* jxsdbg for resolution switch */
+ if (bpool && bpool->other_pool) /* jxsdbg for resolution switch */
+ {
+ if (v4l2object->old_other_pool)
{
- if (v4l2object->old_other_pool)
- {
- /* this case indicate 1st switch did not wait all old pool buf recycle and 2nd switch is coming.
- so save 1st old pool */
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "switching occurs during last switching buf recycle flow");
- v4l2object->old_old_other_pool = v4l2object->old_other_pool;
- }
-
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "switching flow, ref old drmbufferpool");
- v4l2object->old_other_pool = bpool->other_pool;
- gst_object_ref(v4l2object->old_other_pool);
+ /* this case indicate 1st switch did not wait all old pool buf recycle and 2nd switch is coming.
+ so save 1st old pool */
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "switching occurs during last switching buf recycle flow");
+ v4l2object->old_old_other_pool = v4l2object->old_other_pool;
}
- if (v4l2object->pool)
- {
- if (!gst_aml_v4l2_buffer_pool_orphan(&v4l2object->pool))
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "deactivating pool");
- gst_buffer_pool_set_active(v4l2object->pool, FALSE);
- gst_object_unref(v4l2object->pool);
- }
- v4l2object->pool = NULL;
- }
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "switching flow, ref old drmbufferpool");
+ v4l2object->old_other_pool = bpool->other_pool;
+ gst_object_ref(v4l2object->old_other_pool);
+ }
- GST_AML_V4L2_SET_INACTIVE(v4l2object);
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "stopped");
+ if (v4l2object->pool)
+ {
+ if (!gst_aml_v4l2_buffer_pool_orphan(&v4l2object->pool))
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "deactivating pool");
+ gst_buffer_pool_set_active(v4l2object->pool, FALSE);
+ gst_object_unref(v4l2object->pool);
+ }
+ v4l2object->pool = NULL;
+ }
+
+ GST_AML_V4L2_SET_INACTIVE (v4l2object);
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "stopped");
done:
- return TRUE;
+ return TRUE;
}
GstCaps *
-gst_aml_v4l2_object_probe_caps(GstAmlV4l2Object *v4l2object, GstCaps *filter)
+gst_aml_v4l2_object_probe_caps (GstAmlV4l2Object * v4l2object, GstCaps * filter)
{
- GstCaps *ret;
- GSList *walk;
- GSList *formats;
+ GstCaps *ret;
+ GSList *walk;
+ GSList *formats;
- GST_INFO_OBJECT(v4l2object->dbg_obj, "filter caps: %" GST_PTR_FORMAT, filter);
- formats = gst_aml_v4l2_object_get_format_list(v4l2object);
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "filter caps: %" GST_PTR_FORMAT, filter);
+ formats = gst_aml_v4l2_object_get_format_list (v4l2object);
- ret = gst_caps_new_empty();
+ ret = gst_caps_new_empty ();
// At this time, decoder will return defult aspect, and it is not usful.
// so, do not probe cropcap at this time and do this action after decoding.
#if 0
- if (v4l2object->keep_aspect && !v4l2object->par)
+ if (v4l2object->keep_aspect && !v4l2object->par)
+ {
+ struct v4l2_cropcap cropcap;
+
+ memset (&cropcap, 0, sizeof (cropcap));
+
+ cropcap.type = v4l2object->type;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0)
{
- struct v4l2_cropcap cropcap;
-
- memset(&cropcap, 0, sizeof(cropcap));
-
- cropcap.type = v4l2object->type;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0)
- {
- if (errno != ENOTTY)
- GST_WARNING_OBJECT(v4l2object->dbg_obj,
- "Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s",
- g_strerror(errno));
- }
- else if (cropcap.pixelaspect.numerator && cropcap.pixelaspect.denominator)
- {
- v4l2object->par = g_new0(GValue, 1);
- g_value_init(v4l2object->par, GST_TYPE_FRACTION);
- gst_value_set_fraction(v4l2object->par, cropcap.pixelaspect.numerator,
- cropcap.pixelaspect.denominator);
- }
+ if (errno != ENOTTY)
+ GST_WARNING_OBJECT (v4l2object->dbg_obj,
+ "Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s",
+ g_strerror (errno));
}
+ else if (cropcap.pixelaspect.numerator && cropcap.pixelaspect.denominator)
+ {
+ v4l2object->par = g_new0 (GValue, 1);
+ g_value_init (v4l2object->par, GST_TYPE_FRACTION);
+ gst_value_set_fraction (v4l2object->par, cropcap.pixelaspect.numerator,
+ cropcap.pixelaspect.denominator);
+ }
+ }
#endif
- for (walk = formats; walk; walk = walk->next)
+ for (walk = formats; walk; walk = walk->next)
+ {
+ struct v4l2_fmtdesc *format;
+ GstStructure *template;
+ GstCaps *tmp, *tmp2;
+
+ format = (struct v4l2_fmtdesc *) walk->data;
+
+ template = gst_aml_v4l2_object_v4l2fourcc_to_bare_struct (format->pixelformat);
+
+ if (!template)
{
- struct v4l2_fmtdesc *format;
- GstStructure *template;
- GstCaps *tmp, *tmp2;
-
- format = (struct v4l2_fmtdesc *)walk->data;
-
- template = gst_aml_v4l2_object_v4l2fourcc_to_bare_struct(format->pixelformat);
-
- if (!template)
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj,
- "unknown format %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS(format->pixelformat));
- continue;
- }
-
- /* If we have a filter, check if we need to probe this format or not */
- if (filter)
- {
- GstCaps *format_caps = gst_caps_new_empty();
-
- gst_caps_append_structure(format_caps, gst_structure_copy(template));
- GST_INFO_OBJECT(v4l2object->dbg_obj, "format_caps: %" GST_PTR_FORMAT, format_caps);
-
- if (!gst_caps_can_intersect(format_caps, filter))
- {
- gst_caps_unref(format_caps);
- gst_structure_free(template);
- continue;
- }
-
- gst_caps_unref(format_caps);
- }
-
- tmp = gst_aml_v4l2_object_probe_caps_for_format(v4l2object,
- format->pixelformat, template);
- GST_INFO_OBJECT(v4l2object->dbg_obj, "tmp caps: %" GST_PTR_FORMAT, tmp);
-
- if (tmp)
- {
- tmp2 = gst_caps_copy(tmp);
- gst_caps_set_features_simple(tmp2, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
- gst_caps_append(ret, tmp);
- gst_caps_append(ret, tmp2);
- }
-
- gst_structure_free(template);
+ GST_DEBUG_OBJECT (v4l2object->dbg_obj,
+ "unknown format %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (format->pixelformat));
+ continue;
}
+ /* If we have a filter, check if we need to probe this format or not */
if (filter)
{
- GstCaps *tmp;
+ GstCaps *format_caps = gst_caps_new_empty ();
- tmp = ret;
- ret = gst_caps_intersect_full(filter, ret, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref(tmp);
+ gst_caps_append_structure (format_caps, gst_structure_copy (template));
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "format_caps: %" GST_PTR_FORMAT, format_caps);
+
+ if (!gst_caps_can_intersect (format_caps, filter))
+ {
+ gst_caps_unref (format_caps);
+ gst_structure_free (template);
+ continue;
+ }
+
+ gst_caps_unref (format_caps);
}
- if (v4l2object->stream_mode)
+ tmp = gst_aml_v4l2_object_probe_caps_for_format (v4l2object,
+ format->pixelformat, template);
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "tmp caps: %" GST_PTR_FORMAT, tmp);
+
+ if (tmp)
{
- GST_INFO_OBJECT(v4l2object->dbg_obj, "ret caps: %" GST_PTR_FORMAT, ret);
- for (guint i = 0; i < gst_caps_get_size(ret); i++)
- {
- GstStructure *s = gst_caps_get_structure(ret, i);
- if (s)
- gst_structure_remove_field(s, "alignment");
-
- GST_DEBUG("i:%d, s:%p", i, s);
- }
- GST_INFO_OBJECT(v4l2object->dbg_obj, "new ret caps: %" GST_PTR_FORMAT, ret);
+ tmp2 = gst_caps_copy(tmp);
+ gst_caps_set_features_simple(tmp2, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
+ gst_caps_append (ret, tmp);
+ gst_caps_append (ret, tmp2);
}
- GST_INFO_OBJECT(v4l2object->dbg_obj, "probed caps: %" GST_PTR_FORMAT, ret);
+ gst_structure_free (template);
+ }
- return ret;
+ if (filter)
+ {
+ GstCaps *tmp;
+
+ tmp = ret;
+ ret = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (tmp);
+ }
+
+ if (v4l2object->stream_mode)
+ {
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "ret caps: %" GST_PTR_FORMAT, ret);
+ for (guint i = 0; i < gst_caps_get_size(ret); i++)
+ {
+ GstStructure *s = gst_caps_get_structure(ret, i);
+ if (s)
+ gst_structure_remove_field(s, "alignment");
+
+ GST_DEBUG("i:%d, s:%p", i, s);
+ }
+ GST_INFO_OBJECT(v4l2object->dbg_obj, "new ret caps: %" GST_PTR_FORMAT, ret);
+ }
+
+ GST_INFO_OBJECT (v4l2object->dbg_obj, "probed caps: %" GST_PTR_FORMAT, ret);
+
+ return ret;
}
GstCaps *
-gst_aml_v4l2_object_get_caps(GstAmlV4l2Object *v4l2object, GstCaps *filter)
+gst_aml_v4l2_object_get_caps (GstAmlV4l2Object * v4l2object, GstCaps * filter)
{
- GstCaps *ret;
+ GstCaps *ret;
- if (v4l2object->probed_caps == NULL)
- v4l2object->probed_caps = gst_aml_v4l2_object_probe_caps(v4l2object, NULL);
+ if (v4l2object->probed_caps == NULL)
+ v4l2object->probed_caps = gst_aml_v4l2_object_probe_caps (v4l2object, NULL);
- if (filter)
- {
- ret = gst_caps_intersect_full(filter, v4l2object->probed_caps,
- GST_CAPS_INTERSECT_FIRST);
- }
- else
- {
- ret = gst_caps_ref(v4l2object->probed_caps);
- }
+ if (filter)
+ {
+ ret = gst_caps_intersect_full (filter, v4l2object->probed_caps,
+ GST_CAPS_INTERSECT_FIRST);
+ }
+ else
+ {
+ ret = gst_caps_ref (v4l2object->probed_caps);
+ }
- return ret;
+ return ret;
}
gboolean
-gst_aml_v4l2_object_decide_allocation(GstAmlV4l2Object *obj, GstQuery *query)
+gst_aml_v4l2_object_decide_allocation (GstAmlV4l2Object * obj, GstQuery * query)
{
- GstCaps *caps;
- GstBufferPool *pool = NULL, *other_pool = NULL;
- GstStructure *config;
- guint size, min, max, own_min = 0;
- gboolean update;
- gboolean has_video_meta;
- gboolean can_share_own_pool, pushing_from_our_pool = FALSE;
- GstAllocator *allocator = NULL;
- GstAllocationParams params = {0};
+ GstCaps *caps;
+ GstBufferPool *pool = NULL, *other_pool = NULL;
+ GstStructure *config;
+ guint size, min, max, own_min = 0;
+ gboolean update;
+ gboolean has_video_meta;
+ gboolean can_share_own_pool, pushing_from_our_pool = FALSE;
+ GstAllocator *allocator = NULL;
+ GstAllocationParams params = { 0 };
- GST_DEBUG_OBJECT(obj->dbg_obj, "decide allocation");
+ GST_DEBUG_OBJECT (obj->dbg_obj, "decide allocation");
- g_return_val_if_fail(obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- FALSE);
+ g_return_val_if_fail (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, FALSE);
- gst_query_parse_allocation(query, &caps, NULL);
+ gst_query_parse_allocation (query, &caps, NULL);
- if (obj->pool == NULL)
- {
- if (!gst_aml_v4l2_object_setup_pool(obj, caps))
- goto pool_failed;
- }
+ if (obj->pool == NULL)
+ {
+ if (!gst_aml_v4l2_object_setup_pool (obj, caps))
+ goto pool_failed;
+ }
- if (gst_query_get_n_allocation_params(query) > 0)
- gst_query_parse_nth_allocation_param(query, 0, &allocator, ¶ms);
+ if (gst_query_get_n_allocation_params (query) > 0)
+ gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
- if (gst_query_get_n_allocation_pools(query) > 0)
- {
- gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max);
- update = TRUE;
- }
- else
- {
- pool = NULL;
- min = max = 0;
- size = 0;
- update = FALSE;
- }
+ if (gst_query_get_n_allocation_pools (query) > 0)
+ {
+ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+ update = TRUE;
+ }
+ else
+ {
+ pool = NULL;
+ min = max = 0;
+ size = 0;
+ update = FALSE;
+ }
- GST_DEBUG_OBJECT(obj->dbg_obj, "allocation: size:%u min:%u max:%u pool:%" GST_PTR_FORMAT, size, min, max, pool);
+ GST_DEBUG_OBJECT (obj->dbg_obj, "allocation: size:%u min:%u max:%u pool:%"
+ GST_PTR_FORMAT, size, min, max, pool);
- has_video_meta =
- gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL);
+ has_video_meta =
+ gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL);
- can_share_own_pool = (has_video_meta || !obj->need_video_meta);
+ can_share_own_pool = (has_video_meta || !obj->need_video_meta);
- gst_aml_v4l2_get_driver_min_buffers(obj);
- /* We can't share our own pool, if it exceed V4L2 capacity */
- if (min + obj->min_buffers + 1 > VIDEO_MAX_FRAME)
- can_share_own_pool = FALSE;
+ gst_aml_v4l2_get_driver_min_buffers (obj);
+ /* We can't share our own pool, if it exceed V4L2 capacity */
+ if (min + obj->min_buffers + 1 > VIDEO_MAX_FRAME)
+ can_share_own_pool = FALSE;
- /* select a pool */
- switch (obj->mode)
- {
+ /* select a pool */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_RW:
- if (pool)
- {
- /* in READ/WRITE mode, prefer a downstream pool because our own pool
- * doesn't help much, we have to write to it as well */
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "read/write mode: using downstream pool");
- /* use the bigest size, when we use our own pool we can't really do any
- * other size than what the hardware gives us but for downstream pools
- * we can try */
- size = MAX(size, obj->info.size);
- }
- else if (can_share_own_pool)
- {
- /* no downstream pool, use our own then */
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "read/write mode: no downstream pool, using our own");
- pool = gst_object_ref(obj->pool);
- size = obj->info.size;
- pushing_from_our_pool = TRUE;
- }
- break;
+ if (pool)
+ {
+ /* in READ/WRITE mode, prefer a downstream pool because our own pool
+ * doesn't help much, we have to write to it as well */
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "read/write mode: using downstream pool");
+ /* use the bigest size, when we use our own pool we can't really do any
+ * other size than what the hardware gives us but for downstream pools
+ * we can try */
+ size = MAX (size, obj->info.size);
+ }
+ else if (can_share_own_pool)
+ {
+ /* no downstream pool, use our own then */
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "read/write mode: no downstream pool, using our own");
+ pool = gst_object_ref(obj->pool);
+ size = obj->info.size;
+ pushing_from_our_pool = TRUE;
+ }
+ break;
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF_IMPORT:
- /* in importing mode, prefer our own pool, and pass the other pool to
- * our own, so it can serve itself */
- if (pool == NULL)
- goto no_downstream_pool;
- gst_aml_v4l2_buffer_pool_set_other_pool(GST_AML_V4L2_BUFFER_POOL(obj->pool), pool);
- other_pool = pool;
- gst_object_unref(pool);
- pool = gst_object_ref(obj->pool);
- size = obj->info.size;
- break;
+ /* in importing mode, prefer our own pool, and pass the other pool to
+ * our own, so it can serve itself */
+ if (pool == NULL)
+ goto no_downstream_pool;
+ gst_aml_v4l2_buffer_pool_set_other_pool(GST_AML_V4L2_BUFFER_POOL(obj->pool), pool);
+ other_pool = pool;
+ gst_object_unref (pool);
+ pool = gst_object_ref(obj->pool);
+ size = obj->info.size;
+ break;
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
- /* in streaming mode, prefer our own pool */
- /* Check if we can use it ... */
- if (can_share_own_pool)
- {
- if (pool)
- gst_object_unref(pool);
- pool = gst_object_ref(obj->pool);
- size = obj->info.size;
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
- pushing_from_our_pool = TRUE;
- }
- else if (pool)
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "streaming mode: copying to downstream pool %" GST_PTR_FORMAT,
- pool);
- }
- else
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "streaming mode: no usable pool, copying to generic pool");
- size = MAX(size, obj->info.size);
- }
- break;
+ /* in streaming mode, prefer our own pool */
+ /* Check if we can use it ... */
+ if (can_share_own_pool)
+ {
+ if (pool)
+ gst_object_unref (pool);
+ pool = gst_object_ref (obj->pool);
+ size = obj->info.size;
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
+ pushing_from_our_pool = TRUE;
+ }
+ else if (pool)
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "streaming mode: copying to downstream pool %" GST_PTR_FORMAT,
+ pool);
+ }
+ else
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "streaming mode: no usable pool, copying to generic pool");
+ size = MAX (size, obj->info.size);
+ }
+ break;
case GST_V4L2_IO_AUTO:
default:
- GST_WARNING_OBJECT(obj->dbg_obj, "unhandled mode");
- break;
- }
+ GST_WARNING_OBJECT (obj->dbg_obj, "unhandled mode");
+ break;
+ }
- if (size == 0)
- goto no_size;
+ if (size == 0)
+ goto no_size;
- /* If pushing from our own pool, configure it with queried minimum,
- * otherwise use the minimum required */
- if (pushing_from_our_pool)
+ /* If pushing from our own pool, configure it with queried minimum,
+ * otherwise use the minimum required */
+ if (pushing_from_our_pool)
+ {
+ /* When pushing from our own pool, we need what downstream one, to be able
+ * to fill the pipeline, the minimum required to decoder according to the
+ * driver and 2 more, so we don't endup up with everything downstream or
+ * held by the decoder. We account 2 buffers for v4l2 so when one is being
+ * pushed downstream the other one can already be queued for the next
+ * frame. */
+ own_min = min + obj->min_buffers + 2;
+
+ /* If no allocation parameters where provided, allow for a little more
+ * buffers and enable copy threshold */
+ if (!update)
{
- /* When pushing from our own pool, we need what downstream one, to be able
- * to fill the pipeline, the minimum required to decoder according to the
- * driver and 2 more, so we don't endup up with everything downstream or
- * held by the decoder. We account 2 buffers for v4l2 so when one is being
- * pushed downstream the other one can already be queued for the next
- * frame. */
- own_min = min + obj->min_buffers + 2;
-
- /* If no allocation parameters where provided, allow for a little more
- * buffers and enable copy threshold */
- if (!update)
- {
- own_min += 2;
- gst_aml_v4l2_buffer_pool_copy_at_threshold(GST_AML_V4L2_BUFFER_POOL(pool),
- TRUE);
- }
- else
- {
- gst_aml_v4l2_buffer_pool_copy_at_threshold(GST_AML_V4L2_BUFFER_POOL(pool),
- FALSE);
- }
+ own_min += 2;
+ gst_aml_v4l2_buffer_pool_copy_at_threshold (GST_AML_V4L2_BUFFER_POOL (pool),
+ TRUE);
}
else
{
- min = obj->min_buffers;
- max = min;
+ gst_aml_v4l2_buffer_pool_copy_at_threshold (GST_AML_V4L2_BUFFER_POOL (pool),
+ FALSE);
}
- /* Request a bigger max, if one was suggested but it's too small */
- if (max != 0)
- max = MAX(min, max);
+ }
+ else
+ {
+ min = obj->min_buffers;
+ max = min;
+ }
- /* First step, configure our own pool */
+ /* Request a bigger max, if one was suggested but it's too small */
+ if (max != 0)
+ max = MAX (min, max);
+
+ /* First step, configure our own pool */
+ config = gst_buffer_pool_get_config(obj->pool);
+
+ if (obj->need_video_meta || has_video_meta)
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj, "activate Video Meta");
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
+ }
+
+ gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
+ gst_buffer_pool_config_set_params(config, caps, size, min, max);
+
+ GST_DEBUG_OBJECT (obj->dbg_obj, "setting own pool config to %"
+ GST_PTR_FORMAT, config);
+
+ /* Our pool often need to adjust the value */
+ if (!gst_buffer_pool_set_config (obj->pool, config))
+ {
config = gst_buffer_pool_get_config(obj->pool);
- if (obj->need_video_meta || has_video_meta)
- {
- GST_DEBUG_OBJECT(obj->dbg_obj, "activate Video Meta");
- gst_buffer_pool_config_add_option(config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
- }
+ GST_DEBUG_OBJECT (obj->dbg_obj, "own pool config changed to %"
+ GST_PTR_FORMAT, config);
- gst_buffer_pool_config_set_allocator(config, allocator, ¶ms);
- gst_buffer_pool_config_set_params(config, caps, size, min, max);
-
- GST_DEBUG_OBJECT(obj->dbg_obj, "setting own pool config to %" GST_PTR_FORMAT, config);
-
- /* Our pool often need to adjust the value */
+ /* our pool will adjust the maximum buffer, which we are fine with */
if (!gst_buffer_pool_set_config(obj->pool, config))
+ goto config_failed;
+ }
+
+ /* Now configure the other pool if different */
+ if (obj->pool != pool)
+ other_pool = pool;
+
+ if (other_pool)
+ {
+ GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)obj->element;
+ guint other_min = min;
+ guint other_max = max;
+
+ if (obj->old_other_pool || obj->old_old_other_pool) //jxsdbg for switching
+ {
+ obj->outstanding_buf_num = gst_aml_v4l2_object_get_outstanding_capture_buf_num(obj);
+ if (obj->outstanding_buf_num > 0) {
+ if (obj->outstanding_buf_num >= obj->min_buffers)
+ {
+ other_min = 1;
+ }
+ else
+ {
+ other_min = other_max = obj->min_buffers - obj->outstanding_buf_num;
+ }
+ }
+ GST_DEBUG_OBJECT(obj, "oop:%p, ooop:%p, outstanding buf num:%d, set min, max to %d,%d",
+ obj->old_other_pool, obj->old_old_other_pool,
+ obj->outstanding_buf_num, other_min, other_max);
+ }
+
+ if (self->is_secure_path)
+ {
+ params.flags |= GST_MEMORY_FLAG_LAST << 1; // in drmallocator GST_MEMORY_FLAG_LAST << 1 represent GST_MEMORY_FLAG_SECURE
+ GST_DEBUG_OBJECT(obj, "set secure flag for drmbufferpool flag:0x%x", params.flags);
+ }
+ config = gst_buffer_pool_get_config (other_pool);
+ gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
+ gst_buffer_pool_config_set_params (config, caps, size, other_min, other_max);
+ gst_buffer_pool_config_set_video_alignment(config, &obj->align);
+
+ GST_DEBUG_OBJECT (obj->dbg_obj, "setting other pool config to %"
+ GST_PTR_FORMAT, config);
+
+ /* if downstream supports video metadata, add this to the pool config */
+ if (has_video_meta)
{
- config = gst_buffer_pool_get_config(obj->pool);
-
- GST_DEBUG_OBJECT(obj->dbg_obj, "own pool config changed to %" GST_PTR_FORMAT, config);
-
- /* our pool will adjust the maximum buffer, which we are fine with */
- if (!gst_buffer_pool_set_config(obj->pool, config))
- goto config_failed;
+ GST_DEBUG_OBJECT (obj->dbg_obj, "activate Video Meta");
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
}
- /* Now configure the other pool if different */
- if (obj->pool != pool)
- other_pool = pool;
-
- if (other_pool)
+ if (!gst_buffer_pool_set_config (other_pool, config))
{
- GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)obj->element;
- guint other_min = min;
- guint other_max = max;
+ config = gst_buffer_pool_get_config (other_pool);
- if (obj->old_other_pool || obj->old_old_other_pool) //jxsdbg for switching
- {
- obj->outstanding_buf_num = gst_aml_v4l2_object_get_outstanding_capture_buf_num(obj);
- if (obj->outstanding_buf_num > 0) {
- if (obj->outstanding_buf_num >= obj->min_buffers)
- {
- other_min = 1;
- }
- else
- {
- other_min = other_max = obj->min_buffers - obj->outstanding_buf_num;
- }
- }
- GST_DEBUG_OBJECT(obj, "oop:%p, ooop:%p, outstanding buf num:%d, set min, max to %d,%d",
- obj->old_other_pool, obj->old_old_other_pool,
- obj->outstanding_buf_num, other_min, other_max);
- }
+ if (!gst_buffer_pool_config_validate_params (config, caps, size, min,
+ max))
+ {
+ gst_structure_free (config);
+ goto config_failed;
+ }
- if (self->is_secure_path)
- {
- params.flags |= GST_MEMORY_FLAG_LAST << 1; // in drmallocator GST_MEMORY_FLAG_LAST << 1 represent GST_MEMORY_FLAG_SECURE
- GST_DEBUG_OBJECT(obj, "set secure flag for drmbufferpool flag:0x%x", params.flags);
- }
- config = gst_buffer_pool_get_config(other_pool);
- gst_buffer_pool_config_set_allocator(config, allocator, ¶ms);
- gst_buffer_pool_config_set_params (config, caps, size, other_min, other_max);
- gst_buffer_pool_config_set_video_alignment(config, &obj->align);
-
- GST_DEBUG_OBJECT(obj->dbg_obj, "setting other pool config to %" GST_PTR_FORMAT, config);
-
- /* if downstream supports video metadata, add this to the pool config */
- if (has_video_meta)
- {
- GST_DEBUG_OBJECT(obj->dbg_obj, "activate Video Meta");
- gst_buffer_pool_config_add_option(config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
- }
-
- if (!gst_buffer_pool_set_config(other_pool, config))
- {
- config = gst_buffer_pool_get_config(other_pool);
-
- if (!gst_buffer_pool_config_validate_params(config, caps, size, min,
- max))
- {
- gst_structure_free(config);
- goto config_failed;
- }
-
- if (!gst_buffer_pool_set_config(other_pool, config))
- goto config_failed;
- }
+ if (!gst_buffer_pool_set_config (other_pool, config))
+ goto config_failed;
}
+ }
- if (pool)
- {
- /* For simplicity, simply read back the active configuration, so our base
- * class get the right information */
- config = gst_buffer_pool_get_config(pool);
- gst_buffer_pool_config_get_params(config, NULL, &size, &min, &max);
- gst_structure_free(config);
- }
+ if (pool)
+ {
+ /* For simplicity, simply read back the active configuration, so our base
+ * class get the right information */
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max);
+ gst_structure_free (config);
+ }
- if (update)
- gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max);
- else
- gst_query_add_allocation_pool(query, pool, size, min, max);
+ if (update)
+ gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+ else
+ gst_query_add_allocation_pool (query, pool, size, min, max);
- if (allocator)
- gst_object_unref(allocator);
+ if (allocator)
+ gst_object_unref (allocator);
- if (pool)
- gst_object_unref(pool);
+ if (pool)
+ gst_object_unref (pool);
- return TRUE;
+ return TRUE;
pool_failed:
-{
+ {
/* setup_pool already send the error */
goto cleanup;
-}
+ }
config_failed:
-{
- GST_ELEMENT_ERROR(obj->element, RESOURCE, SETTINGS,
- (_("Failed to configure internal buffer pool.")), (NULL));
+ {
+ GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
+ (_("Failed to configure internal buffer pool.")), (NULL));
goto cleanup;
-}
+ }
no_size:
-{
- GST_ELEMENT_ERROR(obj->element, RESOURCE, SETTINGS,
- (_("Video device did not suggest any buffer size.")), (NULL));
+ {
+ GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
+ (_("Video device did not suggest any buffer size.")), (NULL));
goto cleanup;
-}
+ }
cleanup:
-{
+ {
if (allocator)
- gst_object_unref(allocator);
+ gst_object_unref (allocator);
if (pool)
- gst_object_unref(pool);
+ gst_object_unref (pool);
return FALSE;
-}
+ }
no_downstream_pool:
-{
+ {
GST_ELEMENT_ERROR(obj->element, RESOURCE, SETTINGS,
(_("No downstream pool to import from.")),
("When importing DMABUF or USERPTR, we need a pool to import from"));
return FALSE;
-}
+ }
}
gboolean
-gst_aml_v4l2_object_propose_allocation(GstAmlV4l2Object *obj, GstQuery *query)
+gst_aml_v4l2_object_propose_allocation (GstAmlV4l2Object * obj, GstQuery * query)
{
- GstBufferPool *pool;
- /* we need at least 2 buffers to operate */
- guint size, min, max;
- GstCaps *caps;
- gboolean need_pool;
+ GstBufferPool *pool = NULL;
+ /* we need at least 2 buffers to operate */
+ guint size, min, max;
+ GstCaps *caps;
+ gboolean need_pool;
- /* Set defaults allocation parameters */
- size = obj->info.size;
- min = GST_AML_V4L2_MIN_BUFFERS;
- max = VIDEO_MAX_FRAME;
+ /* Set defaults allocation parameters */
+ size = obj->info.size;
+ min = GST_AML_V4L2_MIN_BUFFERS;
+ max = VIDEO_MAX_FRAME;
- gst_query_parse_allocation(query, &caps, &need_pool);
+ gst_query_parse_allocation (query, &caps, &need_pool);
- if (caps == NULL)
- goto no_caps;
+ if (caps == NULL)
+ goto no_caps;
- switch (obj->mode)
- {
+ switch (obj->mode)
+ {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
- if ((pool = obj->pool))
- gst_object_ref(pool);
- break;
+ if ((pool = obj->pool))
+ gst_object_ref(pool);
+ break;
default:
- pool = NULL;
- break;
- }
+ pool = NULL;
+ break;
+ }
- if (pool != NULL)
+ if (pool != NULL)
+ {
+ GstCaps *pcaps;
+ GstStructure *config;
+
+ /* we had a pool, check caps */
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_get_params (config, &pcaps, NULL, NULL, NULL);
+
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "we had a pool with caps %" GST_PTR_FORMAT, pcaps);
+ if (!gst_caps_is_equal (caps, pcaps))
{
- GstCaps *pcaps;
- GstStructure *config;
-
- /* we had a pool, check caps */
- config = gst_buffer_pool_get_config(pool);
- gst_buffer_pool_config_get_params(config, &pcaps, NULL, NULL, NULL);
-
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "we had a pool with caps %" GST_PTR_FORMAT, pcaps);
- if (!gst_caps_is_equal(caps, pcaps))
- {
- gst_structure_free(config);
- gst_object_unref(pool);
- goto different_caps;
- }
- gst_structure_free(config);
+ gst_structure_free (config);
+ gst_object_unref (pool);
+ goto different_caps;
}
- gst_aml_v4l2_get_driver_min_buffers(obj);
+ gst_structure_free (config);
+ }
+ gst_aml_v4l2_get_driver_min_buffers (obj);
- min = MAX(obj->min_buffers, GST_AML_V4L2_MIN_BUFFERS);
+ min = MAX(obj->min_buffers, GST_AML_V4L2_MIN_BUFFERS);
- gst_query_add_allocation_pool(query, pool, size, min, max);
+ gst_query_add_allocation_pool (query, pool, size, min, max);
- /* we also support various metadata */
- gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL);
+ /* we also support various metadata */
+ gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
- if (pool)
- gst_object_unref(pool);
+ if (pool)
+ gst_object_unref (pool);
- return TRUE;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
no_caps:
-{
- GST_DEBUG_OBJECT(obj->dbg_obj, "no caps specified");
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj, "no caps specified");
return FALSE;
-}
+ }
different_caps:
-{
+ {
/* different caps, we can't use this pool */
- GST_DEBUG_OBJECT(obj->dbg_obj, "pool has different caps");
+ GST_DEBUG_OBJECT (obj->dbg_obj, "pool has different caps");
return FALSE;
-}
+ }
}
gboolean
-gst_aml_v4l2_object_try_import(GstAmlV4l2Object *obj, GstBuffer *buffer)
+gst_aml_v4l2_object_try_import (GstAmlV4l2Object * obj, GstBuffer * buffer)
{
- GstVideoMeta *vmeta;
- guint n_mem = gst_buffer_n_memory(buffer);
+ GstVideoMeta *vmeta;
+ guint n_mem = gst_buffer_n_memory (buffer);
- /* only import if requested */
- switch (obj->mode)
- {
+ /* only import if requested */
+ switch (obj->mode)
+ {
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF_IMPORT:
- break;
+ break;
default:
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "The io-mode does not enable importation");
+ GST_DEBUG_OBJECT (obj->dbg_obj,
+ "The io-mode does not enable importation");
+ return FALSE;
+ }
+
+ vmeta = gst_buffer_get_video_meta (buffer);
+ if (!vmeta && obj->need_video_meta)
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj, "Downstream buffer uses standard "
+ "stride/offset while the driver does not.");
+ return FALSE;
+ }
+
+ /* we need matching strides/offsets and size */
+ if (vmeta)
+ {
+ guint p;
+ gboolean need_fmt_update = FALSE;
+
+ if (vmeta->n_planes != GST_VIDEO_INFO_N_PLANES(&obj->info))
+ {
+ GST_WARNING_OBJECT(obj->dbg_obj,
+ "Cannot import buffers with different number planes");
+ return FALSE;
+ }
+
+ for (p = 0; p < vmeta->n_planes; p++)
+ {
+ if (vmeta->stride[p] < obj->info.stride[p])
+ {
+ GST_DEBUG_OBJECT(obj->dbg_obj,
+ "Not importing as remote stride %i is smaller then %i on plane %u",
+ vmeta->stride[p], obj->info.stride[p], p);
+ return FALSE;
+ }
+ else if (vmeta->stride[p] > obj->info.stride[p])
+ {
+ need_fmt_update = TRUE;
+ }
+
+ if (vmeta->offset[p] < obj->info.offset[p])
+ {
+ GST_DEBUG_OBJECT(obj->dbg_obj,
+ "Not importing as offset %" G_GSIZE_FORMAT
+ " is smaller then %" G_GSIZE_FORMAT " on plane %u",
+ vmeta->offset[p], obj->info.offset[p], p);
+ return FALSE;
+ }
+ else if (vmeta->offset[p] > obj->info.offset[p])
+ {
+ need_fmt_update = TRUE;
+ }
+ }
+
+ if (need_fmt_update)
+ {
+ struct v4l2_format format;
+ gint wanted_stride[GST_VIDEO_MAX_PLANES] = {
+ 0,
+ };
+
+ format = obj->format;
+
+ /* update the current format with the stride we want to import from */
+ if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ guint i;
+
+ GST_DEBUG_OBJECT(obj->dbg_obj, "Wanted strides:");
+
+ for (i = 0; i < obj->n_v4l2_planes; i++)
+ {
+ gint stride = vmeta->stride[i];
+
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED(obj->info.finfo))
+ stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(obj->info.finfo);
+
+ format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
+ wanted_stride[i] = stride;
+ GST_DEBUG_OBJECT(obj->dbg_obj, " [%u] %i", i, wanted_stride[i]);
+ }
+ }
+ else
+ {
+ gint stride = vmeta->stride[0];
+
+ GST_DEBUG_OBJECT(obj->dbg_obj, "Wanted stride: %i", stride);
+
+ if (GST_VIDEO_FORMAT_INFO_IS_TILED(obj->info.finfo))
+ stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(obj->info.finfo);
+
+ format.fmt.pix.bytesperline = stride;
+ wanted_stride[0] = stride;
+ }
+
+ if (obj->ioctl(obj->video_fd, VIDIOC_S_FMT, &format) < 0)
+ {
+ GST_WARNING_OBJECT(obj->dbg_obj,
+ "Something went wrong trying to update current format: %s",
+ g_strerror(errno));
+ return FALSE;
+ }
+
+ gst_aml_v4l2_object_save_format(obj, obj->fmtdesc, &format, &obj->info,
+ &obj->align);
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
+ {
+ guint i;
+
+ for (i = 0; i < obj->n_v4l2_planes; i++)
+ {
+ if (format.fmt.pix_mp.plane_fmt[i].bytesperline != wanted_stride[i])
+ {
+ GST_DEBUG_OBJECT(obj->dbg_obj,
+ "[%i] Driver did not accept the new stride (wants %i, got %i)",
+ i, format.fmt.pix_mp.plane_fmt[i].bytesperline,
+ wanted_stride[i]);
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ if (format.fmt.pix.bytesperline != wanted_stride[0])
+ {
+ GST_DEBUG_OBJECT(obj->dbg_obj,
+ "Driver did not accept the new stride (wants %i, got %i)",
+ format.fmt.pix.bytesperline, wanted_stride[0]);
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ /* we can always import single memory buffer, but otherwise we need the same
+ * amount of memory object. */
+ if (n_mem != 1 && n_mem != obj->n_v4l2_planes)
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj, "Can only import %i memory, "
+ "buffers contains %u memory", obj->n_v4l2_planes, n_mem);
+ return FALSE;
+ }
+
+ /* For DMABuf importation we need DMABuf of course */
+ if (obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
+ {
+ guint i;
+
+ for (i = 0; i < n_mem; i++)
+ {
+ GstMemory *mem = gst_buffer_peek_memory (buffer, i);
+
+ if (!gst_is_dmabuf_memory (mem))
+ {
+ GST_DEBUG_OBJECT (obj->dbg_obj, "Cannot import non-DMABuf memory.");
return FALSE;
+ }
}
+ }
- vmeta = gst_buffer_get_video_meta(buffer);
- if (!vmeta && obj->need_video_meta)
- {
- GST_DEBUG_OBJECT(obj->dbg_obj, "Downstream buffer uses standard "
- "stride/offset while the driver does not.");
- return FALSE;
- }
-
- /* we need matching strides/offsets and size */
- if (vmeta)
- {
- guint p;
- gboolean need_fmt_update = FALSE;
-
- if (vmeta->n_planes != GST_VIDEO_INFO_N_PLANES(&obj->info))
- {
- GST_WARNING_OBJECT(obj->dbg_obj,
- "Cannot import buffers with different number planes");
- return FALSE;
- }
-
- for (p = 0; p < vmeta->n_planes; p++)
- {
- if (vmeta->stride[p] < obj->info.stride[p])
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "Not importing as remote stride %i is smaller then %i on plane %u",
- vmeta->stride[p], obj->info.stride[p], p);
- return FALSE;
- }
- else if (vmeta->stride[p] > obj->info.stride[p])
- {
- need_fmt_update = TRUE;
- }
-
- if (vmeta->offset[p] < obj->info.offset[p])
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "Not importing as offset %" G_GSIZE_FORMAT
- " is smaller then %" G_GSIZE_FORMAT " on plane %u",
- vmeta->offset[p], obj->info.offset[p], p);
- return FALSE;
- }
- else if (vmeta->offset[p] > obj->info.offset[p])
- {
- need_fmt_update = TRUE;
- }
- }
-
- if (need_fmt_update)
- {
- struct v4l2_format format;
- gint wanted_stride[GST_VIDEO_MAX_PLANES] = {
- 0,
- };
-
- format = obj->format;
-
- /* update the current format with the stride we want to import from */
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- guint i;
-
- GST_DEBUG_OBJECT(obj->dbg_obj, "Wanted strides:");
-
- for (i = 0; i < obj->n_v4l2_planes; i++)
- {
- gint stride = vmeta->stride[i];
-
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(obj->info.finfo))
- stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(obj->info.finfo);
-
- format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
- wanted_stride[i] = stride;
- GST_DEBUG_OBJECT(obj->dbg_obj, " [%u] %i", i, wanted_stride[i]);
- }
- }
- else
- {
- gint stride = vmeta->stride[0];
-
- GST_DEBUG_OBJECT(obj->dbg_obj, "Wanted stride: %i", stride);
-
- if (GST_VIDEO_FORMAT_INFO_IS_TILED(obj->info.finfo))
- stride = GST_VIDEO_TILE_X_TILES(stride) << GST_VIDEO_FORMAT_INFO_TILE_WS(obj->info.finfo);
-
- format.fmt.pix.bytesperline = stride;
- wanted_stride[0] = stride;
- }
-
- if (obj->ioctl(obj->video_fd, VIDIOC_S_FMT, &format) < 0)
- {
- GST_WARNING_OBJECT(obj->dbg_obj,
- "Something went wrong trying to update current format: %s",
- g_strerror(errno));
- return FALSE;
- }
-
- gst_aml_v4l2_object_save_format(obj, obj->fmtdesc, &format, &obj->info,
- &obj->align);
-
- if (V4L2_TYPE_IS_MULTIPLANAR(obj->type))
- {
- guint i;
-
- for (i = 0; i < obj->n_v4l2_planes; i++)
- {
- if (format.fmt.pix_mp.plane_fmt[i].bytesperline != wanted_stride[i])
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "[%i] Driver did not accept the new stride (wants %i, got %i)",
- i, format.fmt.pix_mp.plane_fmt[i].bytesperline,
- wanted_stride[i]);
- return FALSE;
- }
- }
- }
- else
- {
- if (format.fmt.pix.bytesperline != wanted_stride[0])
- {
- GST_DEBUG_OBJECT(obj->dbg_obj,
- "Driver did not accept the new stride (wants %i, got %i)",
- format.fmt.pix.bytesperline, wanted_stride[0]);
- return FALSE;
- }
- }
- }
- }
-
- /* we can always import single memory buffer, but otherwise we need the same
- * amount of memory object. */
- if (n_mem != 1 && n_mem != obj->n_v4l2_planes)
- {
- GST_DEBUG_OBJECT(obj->dbg_obj, "Can only import %i memory, "
- "buffers contains %u memory",
- obj->n_v4l2_planes, n_mem);
- return FALSE;
- }
-
- /* For DMABuf importation we need DMABuf of course */
- if (obj->mode == GST_V4L2_IO_DMABUF_IMPORT)
- {
- guint i;
-
- for (i = 0; i < n_mem; i++)
- {
- GstMemory *mem = gst_buffer_peek_memory(buffer, i);
-
- if (!gst_is_dmabuf_memory(mem))
- {
- GST_DEBUG_OBJECT(obj->dbg_obj, "Cannot import non-DMABuf memory.");
- return FALSE;
- }
- }
- }
-
- /* for the remaining, only the kernel driver can tell */
- return TRUE;
+ /* for the remaining, only the kernel driver can tell */
+ return TRUE;
}
static gboolean gst_aml_v4l2_set_control(GstAmlV4l2Object *v4l2object, guint ctl)
{
- int rc;
- struct v4l2_queryctrl queryctrl;
- struct v4l2_control control;
+ int rc;
+ struct v4l2_queryctrl queryctrl;
+ struct v4l2_control control;
- memset(&queryctrl, 0, sizeof(queryctrl));
- queryctrl.id = ctl;
+ memset(&queryctrl, 0, sizeof(queryctrl));
+ queryctrl.id = ctl;
- rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_QUERYCTRL, &queryctrl);
- if (rc == 0)
- {
- if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED))
- {
- memset(&control, 0, sizeof(control));
- control.id = ctl;
- control.value = 1;
- rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_CTRL, &control);
- if (rc != 0)
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "set ctl:0x%x fail rc %d", ctl, rc);
- return FALSE;
- }
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "set ctl:0x%x succ", ctl);
- return TRUE;
- }
- else
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "ctl:0x%x is disabled", ctl);
- return TRUE;
- }
- }
- else
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "VIDIOC_QUERYCTRL for 0x:%x fail", ctl);
- return FALSE;
- }
+ rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_QUERYCTRL, &queryctrl);
+ if (rc == 0)
+ {
+ if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED))
+ {
+ memset(&control, 0, sizeof(control));
+ control.id = ctl;
+ control.value = 1;
+ rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_CTRL, &control);
+ if (rc != 0)
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "set ctl:0x%x fail rc %d", ctl, rc);
+ return FALSE;
+ }
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "set ctl:0x%x succ", ctl);
+ return TRUE;
+ }
+ else
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "ctl:0x%x is disabled", ctl);
+ return TRUE;
+ }
+ }
+ else
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "VIDIOC_QUERYCTRL for 0x:%x fail", ctl);
+ return FALSE;
+ }
}
gboolean gst_aml_v4l2_set_I_frame_mode(GstAmlV4l2Object *v4l2object)
{
- if (v4l2object->iframe_mode)
- {
- int rc;
- struct v4l2_control control;
- memset(&control, 0, sizeof(control));
- control.id = AML_V4L2_SET_I_FRAME;
- control.value = 1;
- rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_CTRL, &control);
- if (rc != 0)
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "rc: %d", rc);
- return FALSE;
- }
- }
- GST_DEBUG("set I frame ok");
- return TRUE;
+ if (v4l2object->iframe_mode)
+ {
+ int rc;
+ struct v4l2_control control;
+ memset(&control, 0, sizeof(control));
+ control.id = AML_V4L2_SET_I_FRAME;
+ control.value = 1;
+ rc = v4l2object->ioctl(v4l2object->video_fd, VIDIOC_S_CTRL, &control);
+ if (rc != 0)
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "rc: %d", rc);
+ return FALSE;
+ }
+ }
+ GST_DEBUG("set I frame ok");
+ return TRUE;
}
gboolean gst_aml_v4l2_set_drm_mode(GstAmlV4l2Object *v4l2object)
{
- /* On AmLogic, output obj use of GST_V4L2_IO_DMABUF_IMPORT implies secure memory */
- if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT && v4l2object->secure_es)
- {
- GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)v4l2object->element;
- self->is_secure_path = TRUE;
+ /* On AmLogic, output obj use of GST_V4L2_IO_DMABUF_IMPORT implies secure memory */
+ if (v4l2object->req_mode == GST_V4L2_IO_DMABUF_IMPORT && v4l2object->secure_es)
+ {
+ GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)v4l2object->element;
+ self->is_secure_path = TRUE;
- if (gst_aml_v4l2_set_control(v4l2object, AML_V4L2_SET_DRMMODE))
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_DRMMODE set succ");
- return TRUE;
- }
- else
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_DRMMODE set fail");
- return FALSE;
- }
- }
- return TRUE;
+ if (gst_aml_v4l2_set_control(v4l2object, AML_V4L2_SET_DRMMODE))
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_DRMMODE set succ");
+ return TRUE;
+ }
+ else
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_DRMMODE set fail");
+ return FALSE;
+ }
+ }
+ return TRUE;
}
gboolean gst_aml_v4l2_set_stream_mode(GstAmlV4l2Object *v4l2object)
{
- if (v4l2object->stream_mode)
- {
- if (gst_aml_v4l2_set_control(v4l2object, AML_V4L2_SET_STREAM_MODE))
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_STREAM_MODE set succ");
- return TRUE;
- }
- else
- {
- GST_ERROR_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_STREAM_MODE set fail");
- return FALSE;
- }
- }
- else
- {
- GST_DEBUG_OBJECT(v4l2object->dbg_obj, "req mode is not stream mode, frame mode in configured by default");
- return TRUE;
- }
+ if (v4l2object->stream_mode)
+ {
+ if (gst_aml_v4l2_set_control(v4l2object, AML_V4L2_SET_STREAM_MODE))
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_STREAM_MODE set succ");
+ return TRUE;
+ }
+ else
+ {
+ GST_ERROR_OBJECT(v4l2object->dbg_obj, "AML_V4L2_SET_STREAM_MODE set fail");
+ return FALSE;
+ }
+ }
+ else
+ {
+ GST_DEBUG_OBJECT(v4l2object->dbg_obj, "req mode is not stream mode, frame mode in configured by default");
+ return TRUE;
+ }
}
gint gst_aml_v4l2_object_get_outstanding_capture_buf_num(GstAmlV4l2Object *obj)
{
- gint ret = 0;
- gint count = 0;
+ gint ret = 0;
+ gint count = 0;
- if (obj->old_other_pool)
- {
- count = gst_buffer_pool_get_outstanding_num(obj->old_other_pool);
- if (count)
- {
- ret += count;
- }
- else
- {
- gst_object_unref(obj->old_other_pool);
- obj->old_other_pool = NULL;
- }
- }
+ if (obj->old_other_pool)
+ {
+ count = gst_buffer_pool_get_outstanding_num(obj->old_other_pool);
+ if (count)
+ {
+ ret += count;
+ }
+ else
+ {
+ gst_object_unref(obj->old_other_pool);
+ obj->old_other_pool = NULL;
+ }
+ }
- count = 0;
- if (obj->old_old_other_pool)
- {
- count = gst_buffer_pool_get_outstanding_num(obj->old_old_other_pool);
- if (count)
- {
- ret += count;
- }
- else
- {
- gst_object_unref(obj->old_old_other_pool);
- obj->old_old_other_pool = NULL;
- }
- }
+ count = 0;
+ if (obj->old_old_other_pool)
+ {
+ count = gst_buffer_pool_get_outstanding_num(obj->old_old_other_pool);
+ if (count)
+ {
+ ret += count;
+ }
+ else
+ {
+ gst_object_unref(obj->old_old_other_pool);
+ obj->old_old_other_pool = NULL;
+ }
+ }
- return ret;
+ return ret;
}
\ No newline at end of file
diff --git a/src/gstamlv4l2object.h b/src/gstamlv4l2object.h
index 1c2651c..7d99876 100644
--- a/src/gstamlv4l2object.h
+++ b/src/gstamlv4l2object.h
@@ -59,12 +59,12 @@
typedef enum
{
- GST_V4L2_IO_AUTO = 0,
- GST_V4L2_IO_RW = 1,
- GST_V4L2_IO_MMAP = 2,
- GST_V4L2_IO_USERPTR = 3,
- GST_V4L2_IO_DMABUF = 4,
- GST_V4L2_IO_DMABUF_IMPORT = 5
+ GST_V4L2_IO_AUTO = 0,
+ GST_V4L2_IO_RW = 1,
+ GST_V4L2_IO_MMAP = 2,
+ GST_V4L2_IO_USERPTR = 3,
+ GST_V4L2_IO_DMABUF = 4,
+ GST_V4L2_IO_DMABUF_IMPORT = 5
} GstAmlV4l2IOMode;
typedef gboolean (*GstAmlV4l2GetInOutFunction)(GstAmlV4l2Object *v4l2object, gint *input);
@@ -92,196 +92,196 @@
/* checks whether the current v4lv4l2object has already been open()'ed or not */
#define GST_AML_V4L2_CHECK_OPEN(v4l2object) \
- if (!GST_AML_V4L2_IS_OPEN(v4l2object)) \
- { \
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
- (_("Device is not open.")), (NULL)); \
- return FALSE; \
- }
+ if (!GST_AML_V4L2_IS_OPEN(v4l2object)) \
+ { \
+ GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
+ (_("Device is not open.")), (NULL)); \
+ return FALSE; \
+ }
/* checks whether the current v4lv4l2object is close()'ed or whether it is still open */
#define GST_AML_V4L2_CHECK_NOT_OPEN(v4l2object) \
- if (GST_AML_V4L2_IS_OPEN(v4l2object)) \
- { \
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
- (_("Device is open.")), (NULL)); \
- return FALSE; \
- }
+ if (GST_AML_V4L2_IS_OPEN(v4l2object)) \
+ { \
+ GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
+ (_("Device is open.")), (NULL)); \
+ return FALSE; \
+ }
/* checks whether we're out of capture mode or not */
#define GST_AML_V4L2_CHECK_NOT_ACTIVE(v4l2object) \
- if (GST_AML_V4L2_IS_ACTIVE(v4l2object)) \
- { \
- GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
- (NULL), ("Device is in streaming mode")); \
- return FALSE; \
- }
+ if (GST_AML_V4L2_IS_ACTIVE(v4l2object)) \
+ { \
+ GST_ELEMENT_ERROR(v4l2object->element, RESOURCE, SETTINGS, \
+ (NULL), ("Device is in streaming mode")); \
+ return FALSE; \
+ }
struct _GstAmlV4l2Object
{
- GstElement *element;
- GstObject *dbg_obj;
+ GstElement * element;
+ GstObject * dbg_obj;
- enum v4l2_buf_type type; /* V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_OUTPUT */
+ enum v4l2_buf_type type; /* V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_OUTPUT */
- /* the video device */
- char *videodev;
+ /* the video device */
+ char *videodev;
- /* the video-device's file descriptor */
- gint video_fd;
- GstAmlV4l2IOMode mode;
+ /* the video-device's file descriptor */
+ gint video_fd;
+ GstAmlV4l2IOMode mode;
- GstPoll *poll; /* a poll for video_fd */
- GstPollFD pollfd;
- gboolean can_poll_device;
+ GstPoll *poll; /* a poll for video_fd */
+ GstPollFD pollfd;
+ gboolean can_poll_device;
- gboolean active;
- gboolean streaming;
+ gboolean active;
+ gboolean streaming;
- /* the current format */
- struct v4l2_fmtdesc *fmtdesc;
- struct v4l2_format format;
- GstVideoInfo info;
- GstVideoAlignment align;
+ /* the current format */
+ struct v4l2_fmtdesc *fmtdesc;
+ struct v4l2_format format;
+ GstVideoInfo info;
+ GstVideoAlignment align;
- /* Features */
- gboolean need_video_meta;
- gboolean has_alpha_component;
+ /* Features */
+ gboolean need_video_meta;
+ gboolean has_alpha_component;
- /* only used if the device supports MPLANE
- * nb planes is meaning of v4l2 planes
- * the gstreamer equivalent is gst_buffer_n_memory
- */
- gint n_v4l2_planes;
+ /* only used if the device supports MPLANE
+ * nb planes is meaning of v4l2 planes
+ * the gstreamer equivalent is gst_buffer_n_memory
+ */
+ gint n_v4l2_planes;
- /* We cache the frame duration if known */
- GstClockTime duration;
+ /* We cache the frame duration if known */
+ GstClockTime duration;
- /* if the MPLANE device support both contiguous and non contiguous
- * it allows to select which one we want. But we prefered_non_contiguous
- * non contiguous mode.
- */
- gboolean prefered_non_contiguous;
+ /* if the MPLANE device support both contiguous and non contiguous
+ * it allows to select which one we want. But we prefered_non_contiguous
+ * non contiguous mode.
+ */
+ gboolean prefered_non_contiguous;
- /* This will be set if supported in decide_allocation. It can be used to
- * calculate the minimum latency. */
- guint32 min_buffers;
+ /* This will be set if supported in decide_allocation. It can be used to
+ * calculate the minimum latency. */
+ guint32 min_buffers;
- /* wanted mode */
- GstAmlV4l2IOMode req_mode;
+ /* wanted mode */
+ GstAmlV4l2IOMode req_mode;
- /* optional pool */
- GstBufferPool *pool;
+ /* optional pool */
+ GstBufferPool *pool;
- /* jxsdbg for resolution switch */
- GstBufferPool *old_other_pool;
- GstBufferPool *old_old_other_pool;
- gint outstanding_buf_num;
+ /* jxsdbg for resolution switch */
+ GstBufferPool *old_other_pool;
+ GstBufferPool *old_old_other_pool;
+ gint outstanding_buf_num;
- /* the video device's capabilities */
- struct v4l2_capability vcap;
- /* opened device specific capabilities */
- guint32 device_caps;
+ /* the video device's capabilities */
+ struct v4l2_capability vcap;
+ /* opened device specific capabilities */
+ guint32 device_caps;
- /* lists... */
- GSList *formats; /* list of available capture formats */
- GstCaps *probed_caps;
+ /* lists... */
+ GSList *formats; /* list of available capture formats */
+ GstCaps *probed_caps;
- GList *colors;
- GList *norms;
- GList *channels;
- GData *controls;
+ GList *colors;
+ GList *norms;
+ GList *channels;
+ GData *controls;
- /* properties */
- v4l2_std_id tv_norm;
- gchar *channel;
- gulong frequency;
- GstStructure *extra_controls;
- gboolean keep_aspect;
- gboolean low_latency_mode;
- gboolean low_memory_mode;
- gboolean stream_mode;
- gboolean iframe_mode;
- gboolean secure_es;
- GValue *par;
- gboolean have_set_par;
- GValue *fps;
- gboolean enable_cc_data;
- gboolean enable_nr;
- uint32_t dw_mode;
+ /* properties */
+ v4l2_std_id tv_norm;
+ gchar *channel;
+ gulong frequency;
+ GstStructure *extra_controls;
+ gboolean keep_aspect;
+ gboolean low_latency_mode;
+ gboolean low_memory_mode;
+ gboolean stream_mode;
+ gboolean iframe_mode;
+ gboolean secure_es;
+ GValue *par;
+ gboolean have_set_par;
+ GValue *fps;
+ gboolean enable_cc_data;
+ gboolean enable_nr;
+ uint32_t dw_mode;
- /* funcs */
- GstAmlV4l2GetInOutFunction get_in_out_func;
- GstAmlV4l2SetInOutFunction set_in_out_func;
- GstAmlV4l2UpdateFpsFunction update_fps_func;
+ /* funcs */
+ GstAmlV4l2GetInOutFunction get_in_out_func;
+ GstAmlV4l2SetInOutFunction set_in_out_func;
+ GstAmlV4l2UpdateFpsFunction update_fps_func;
- /* syscalls */
- gint (*fd_open)(gint fd, gint v4l2_flags);
- gint (*close)(gint fd);
- gint (*dup)(gint fd);
- gint (*ioctl)(gint fd, ioctl_req_t request, ...);
- gssize (*read)(gint fd, gpointer buffer, gsize n);
- gpointer (*mmap)(gpointer start, gsize length, gint prot, gint flags,
- gint fd, off_t offset);
- gint (*munmap)(gpointer _start, gsize length);
+ /* syscalls */
+ gint (*fd_open) (gint fd, gint v4l2_flags);
+ gint (*close) (gint fd);
+ gint (*dup) (gint fd);
+ gint (*ioctl) (gint fd, ioctl_req_t request, ...);
+ gssize (*read) (gint fd, gpointer buffer, gsize n);
+ gpointer (*mmap) (gpointer start, gsize length, gint prot, gint flags,
+ gint fd, off_t offset);
+ gint (*munmap) (gpointer _start, gsize length);
- /* Quirks */
- /* Skips interlacing probes */
- gboolean never_interlaced;
- /* Allow to skip reading initial format through G_FMT. Some devices
- * just fails if you don't call S_FMT first. (ex: M2M decoders) */
- gboolean no_initial_format;
- /* Avoid any try_fmt probe. This is used by v4l2src to speedup start up time
- * on slow USB firmwares. When this is set, gst_v4l2_set_format() will modify
- * the caps to reflect what was negotiated during fixation */
- gboolean skip_try_fmt_probes;
- gboolean can_wait_event;
- gboolean need_wait_event;
- gboolean need_drop_event;
+ /* Quirks */
+ /* Skips interlacing probes */
+ gboolean never_interlaced;
+ /* Allow to skip reading initial format through G_FMT. Some devices
+ * just fails if you don't call S_FMT first. (ex: M2M decoders) */
+ gboolean no_initial_format;
+ /* Avoid any try_fmt probe. This is used by v4l2src to speedup start up time
+ * on slow USB firmwares. When this is set, gst_v4l2_set_format() will modify
+ * the caps to reflect what was negotiated during fixation */
+ gboolean skip_try_fmt_probes;
+ gboolean can_wait_event;
+ gboolean need_wait_event;
+ gboolean need_drop_event;
- gboolean is_svp;
+ gboolean is_svp;
- guint tvin_port;
+ guint tvin_port;
- /* the file to store dumped decoder frames */
- char *dumpframefile;
+ /* the file to store dumped decoder frames */
+ char *dumpframefile;
- /*number of frames those decoded error*/
- gint num_error_frames;
- guint64 error_frame_pts;
+ /*number of frames those decoded error*/
+ gint num_error_frames;
+ guint64 error_frame_pts;
};
struct _GstAmlV4l2ObjectClassHelper
{
- /* probed devices */
- GList *devices;
+ /* probed devices */
+ GList *devices;
};
-GType gst_v4l2_object_get_type(void);
+GType gst_v4l2_object_get_type (void);
-#define V4L2_STD_OBJECT_PROPS \
- PROP_DEVICE, \
- PROP_DEVICE_NAME, \
- PROP_DEVICE_FD, \
- PROP_FLAGS, \
- PROP_BRIGHTNESS, \
- PROP_CONTRAST, \
- PROP_SATURATION, \
- PROP_HUE, \
- PROP_IO_MODE, \
- PROP_OUTPUT_IO_MODE, \
- PROP_CAPTURE_IO_MODE, \
- PROP_EXTRA_CONTROLS, \
- PROP_PIXEL_ASPECT_RATIO, \
- PROP_FORCE_ASPECT_RATIO, \
- PROP_DUMP_FRAME_LOCATION, \
- PROP_STREAM_MODE, \
- PROP_LOW_LATENCY_MODE, \
- PROP_CC_DATA, \
- PROP_ENABLE_NR, \
- PROP_DECODING_ERROR_FRAMES, \
- PROP_LOW_MEMORY_MODE, \
- PROP_I_FRAME_MODE
+#define V4L2_STD_OBJECT_PROPS \
+ PROP_DEVICE, \
+ PROP_DEVICE_NAME, \
+ PROP_DEVICE_FD, \
+ PROP_FLAGS, \
+ PROP_BRIGHTNESS, \
+ PROP_CONTRAST, \
+ PROP_SATURATION, \
+ PROP_HUE, \
+ PROP_IO_MODE, \
+ PROP_OUTPUT_IO_MODE, \
+ PROP_CAPTURE_IO_MODE, \
+ PROP_EXTRA_CONTROLS, \
+ PROP_PIXEL_ASPECT_RATIO, \
+ PROP_FORCE_ASPECT_RATIO, \
+ PROP_DUMP_FRAME_LOCATION, \
+ PROP_STREAM_MODE, \
+ PROP_LOW_LATENCY_MODE, \
+ PROP_CC_DATA, \
+ PROP_ENABLE_NR, \
+ PROP_DECODING_ERROR_FRAMES, \
+ PROP_LOW_MEMORY_MODE, \
+ PROP_I_FRAME_MODE
/* create/destroy */
GstAmlV4l2Object *gst_aml_v4l2_object_new(GstElement *element,
@@ -365,9 +365,6 @@
gboolean gst_aml_v4l2_get_output(GstAmlV4l2Object *v4l2object, gint *output);
gboolean gst_aml_v4l2_set_output(GstAmlV4l2Object *v4l2object, gint output);
-/* frequency control */
-gboolean gst_aml_v4l2_signal_strength(GstAmlV4l2Object *v4l2object, gint tunernum, gulong *signal);
-
/* attribute control */
gboolean gst_aml_v4l2_get_attribute(GstAmlV4l2Object *v4l2object, int attribute, int *value);
gboolean gst_aml_v4l2_set_attribute(GstAmlV4l2Object *v4l2object, int attribute, const int value);
diff --git a/src/gstamlv4l2videodec.c b/src/gstamlv4l2videodec.c
index 505fc68..c2fdffe 100644
--- a/src/gstamlv4l2videodec.c
+++ b/src/gstamlv4l2videodec.c
@@ -65,23 +65,23 @@
typedef struct
{
- gchar *device;
- GstCaps *sink_caps;
- GstCaps *src_caps;
- const gchar *longname;
- const gchar *description;
+ gchar *device;
+ GstCaps *sink_caps;
+ GstCaps *src_caps;
+ const gchar *longname;
+ const gchar *description;
} GstAmlV4l2VideoDecCData;
enum
{
- PROP_0,
- V4L2_STD_OBJECT_PROPS,
+ PROP_0,
+ V4L2_STD_OBJECT_PROPS,
#if GST_IMPORT_LGE_PROP
- LGE_RESOURCE_INFO,
- LGE_DECODE_SIZE,
- LGE_UNDECODE_SIZE,
- LGE_APP_TYPE,
- LGE_CLIP_MODE
+ LGE_RESOURCE_INFO,
+ LGE_DECODE_SIZE,
+ LGE_UNDECODE_SIZE,
+ LGE_APP_TYPE,
+ LGE_CLIP_MODE
#endif
};
@@ -96,7 +96,7 @@
#define gst_aml_v4l2_video_dec_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE(GstAmlV4l2VideoDec, gst_aml_v4l2_video_dec,
- GST_AML_TYPE_VIDEO_DECODER);
+ GST_AML_TYPE_VIDEO_DECODER);
static GstFlowReturn gst_aml_v4l2_video_dec_finish(GstAmlVideoDecoder *decoder);
#if GST_IMPORT_LGE_PROP
@@ -107,572 +107,568 @@
static void
gst_aml_v4l2_video_dec_set_property(GObject *object,
- guint prop_id, const GValue *value, GParamSpec *pspec)
+ guint prop_id, const GValue * value, GParamSpec * pspec)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
- switch (prop_id)
- {
+ switch (prop_id)
+ {
case PROP_CAPTURE_IO_MODE:
case PROP_DUMP_FRAME_LOCATION:
case PROP_CC_DATA:
- if (!gst_aml_v4l2_object_set_property_helper(self->v4l2capture,
- prop_id, value, pspec))
- {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- }
- break;
+ if (!gst_aml_v4l2_object_set_property_helper(self->v4l2capture,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+ break;
#if GST_IMPORT_LGE_PROP
- case LGE_RESOURCE_INFO:
- {
- GST_DEBUG_OBJECT(self, "LGE up layer set res info");
- GstStructure *r_info = g_value_get_object(value);
- if (r_info)
- {
- if (gst_structure_has_field(r_info, "coretype"))
- {
- if (self->lge_ctxt->res_info.coretype)
- g_free(self->lge_ctxt->res_info.coretype);
- self->lge_ctxt->res_info.coretype = g_strdup(gst_structure_get_string(r_info, "coretype"));
- }
- if (gst_structure_has_field(r_info, "videoport"))
- gst_structure_get_int(r_info, "videoport", &(self->lge_ctxt->res_info.videoport));
- if (gst_structure_has_field(r_info, "audioport"))
- gst_structure_get_int(r_info, "audioport", &(self->lge_ctxt->res_info.audioport));
- if (gst_structure_has_field(r_info, "maxwidth"))
- gst_structure_get_int(r_info, "maxwidth", &(self->lge_ctxt->res_info.maxwidth));
- if (gst_structure_has_field(r_info, "maxheight"))
- gst_structure_get_int(r_info, "maxheight", &(self->lge_ctxt->res_info.maxheight));
- if (gst_structure_has_field(r_info, "mixerport"))
- gst_structure_get_int(r_info, "mixerport", &(self->lge_ctxt->res_info.mixerport));
- }
- break;
- }
- case LGE_APP_TYPE:
- {
- GST_DEBUG_OBJECT(self, "LGE up layer set app type");
- if (self->lge_ctxt->app_type)
- g_free(self->lge_ctxt->app_type);
- self->lge_ctxt->app_type = g_strdup(g_value_get_string(value));
- break;
- }
- case LGE_CLIP_MODE:
- {
- GST_DEBUG_OBJECT(self, "LGE up layer set clip mode");
- self->lge_ctxt->clip_mode = g_strdup(g_value_get_boolean(value));
- break;
- }
+ case LGE_RESOURCE_INFO:
+ {
+ GST_DEBUG_OBJECT(self, "LGE up layer set res info");
+ GstStructure *r_info = g_value_get_object(value);
+ if (r_info)
+ {
+ if (gst_structure_has_field(r_info, "coretype"))
+ {
+ if (self->lge_ctxt->res_info.coretype)
+ g_free(self->lge_ctxt->res_info.coretype);
+ self->lge_ctxt->res_info.coretype = g_strdup(gst_structure_get_string(r_info, "coretype"));
+ }
+ if (gst_structure_has_field(r_info, "videoport"))
+ gst_structure_get_int(r_info, "videoport", &(self->lge_ctxt->res_info.videoport));
+ if (gst_structure_has_field(r_info, "audioport"))
+ gst_structure_get_int(r_info, "audioport", &(self->lge_ctxt->res_info.audioport));
+ if (gst_structure_has_field(r_info, "maxwidth"))
+ gst_structure_get_int(r_info, "maxwidth", &(self->lge_ctxt->res_info.maxwidth));
+ if (gst_structure_has_field(r_info, "maxheight"))
+ gst_structure_get_int(r_info, "maxheight", &(self->lge_ctxt->res_info.maxheight));
+ if (gst_structure_has_field(r_info, "mixerport"))
+ gst_structure_get_int(r_info, "mixerport", &(self->lge_ctxt->res_info.mixerport));
+ }
+ break;
+ }
+ case LGE_APP_TYPE:
+ {
+ GST_DEBUG_OBJECT(self, "LGE up layer set app type");
+ if (self->lge_ctxt->app_type)
+ g_free(self->lge_ctxt->app_type);
+ self->lge_ctxt->app_type = g_strdup(g_value_get_string(value));
+ break;
+ }
+ case LGE_CLIP_MODE:
+ {
+ GST_DEBUG_OBJECT(self, "LGE up layer set clip mode");
+ self->lge_ctxt->clip_mode = g_strdup(g_value_get_boolean(value));
+ break;
+ }
#endif
- /* By default, only set on output */
+ /* By default, only set on output */
default:
- if (!gst_aml_v4l2_object_set_property_helper(self->v4l2output,
- prop_id, value, pspec))
- {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- }
- break;
- }
+ if (!gst_aml_v4l2_object_set_property_helper (self->v4l2output,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+ break;
+ }
}
static void
gst_aml_v4l2_video_dec_get_property(GObject *object,
guint prop_id, GValue *value, GParamSpec *pspec)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
- switch (prop_id)
- {
+ switch (prop_id)
+ {
case PROP_CAPTURE_IO_MODE:
case PROP_CC_DATA:
case PROP_DECODING_ERROR_FRAMES:
- if (!gst_aml_v4l2_object_get_property_helper(self->v4l2capture,
- prop_id, value, pspec))
- {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- }
- break;
+ if (!gst_aml_v4l2_object_get_property_helper (self->v4l2capture,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+ break;
#if GST_IMPORT_LGE_PROP
case LGE_DECODE_SIZE:
{
- GST_DEBUG_OBJECT(self, "LGE up layer get dec size");
- self->lge_ctxt->dec_size = -1;
- g_value_set_int(value, self->lge_ctxt->dec_size);
- break;
+ GST_DEBUG_OBJECT(self, "LGE up layer get dec size");
+ self->lge_ctxt->dec_size = -1;
+ g_value_set_int(value, self->lge_ctxt->dec_size);
+ break;
}
case LGE_UNDECODE_SIZE:
{
- GST_DEBUG_OBJECT(self, "LGE up layer get undec size");
- self->lge_ctxt->undec_size = -1;
- g_value_set_int(value, self->lge_ctxt->undec_size);
- break;
+ GST_DEBUG_OBJECT(self, "LGE up layer get undec size");
+ self->lge_ctxt->undec_size = -1;
+ g_value_set_int(value, self->lge_ctxt->undec_size);
+ break;
}
#endif
- /* By default read from output */
- default:
- if (!gst_aml_v4l2_object_get_property_helper(self->v4l2output,
- prop_id, value, pspec))
- {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- }
- break;
+ /* By default read from output */
+ default:
+ if (!gst_aml_v4l2_object_get_property_helper (self->v4l2output,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
+ break;
+ }
}
static gboolean
gst_aml_v4l2_video_dec_open(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstCaps *codec_caps;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstCaps *codec_caps;
- GST_DEBUG_OBJECT(self, "Opening");
+ GST_DEBUG_OBJECT (self, "Opening");
- if (!gst_aml_v4l2_object_open(self->v4l2output))
- goto failure;
-
- if (!gst_aml_v4l2_object_open_shared(self->v4l2capture, self->v4l2output))
- goto failure;
-
- codec_caps = gst_pad_get_pad_template_caps(decoder->sinkpad);
- self->probed_sinkcaps = gst_aml_v4l2_object_probe_caps(self->v4l2output,
- codec_caps);
- gst_caps_unref(codec_caps);
-
- if (gst_caps_is_empty(self->probed_sinkcaps))
- goto no_encoded_format;
-
- return TRUE;
-
-no_encoded_format:
- GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
- (_("Decoder on device %s has no supported input format"),
- self->v4l2output->videodev),
- (NULL));
+ if (!gst_aml_v4l2_object_open (self->v4l2output))
goto failure;
+ if (!gst_aml_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
+ goto failure;
+
+ codec_caps = gst_pad_get_pad_template_caps (decoder->sinkpad);
+ self->probed_sinkcaps = gst_aml_v4l2_object_probe_caps (self->v4l2output,
+ codec_caps);
+ gst_caps_unref (codec_caps);
+
+ if (gst_caps_is_empty (self->probed_sinkcaps))
+ goto no_encoded_format;
+
+ return TRUE;
+
+no_encoded_format:
+ GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ (_("Decoder on device %s has no supported input format"),
+ self->v4l2output->videodev), (NULL));
+ goto failure;
+
failure:
- if (GST_AML_V4L2_IS_OPEN(self->v4l2output))
- gst_aml_v4l2_object_close(self->v4l2output);
+ if (GST_AML_V4L2_IS_OPEN (self->v4l2output))
+ gst_aml_v4l2_object_close (self->v4l2output);
- if (GST_AML_V4L2_IS_OPEN(self->v4l2capture))
- gst_aml_v4l2_object_close(self->v4l2capture);
+ if (GST_AML_V4L2_IS_OPEN (self->v4l2capture))
+ gst_aml_v4l2_object_close (self->v4l2capture);
- gst_caps_replace(&self->probed_srccaps, NULL);
- gst_caps_replace(&self->probed_sinkcaps, NULL);
+ gst_caps_replace (&self->probed_srccaps, NULL);
+ gst_caps_replace (&self->probed_sinkcaps, NULL);
- return FALSE;
+ return FALSE;
}
static gboolean
gst_aml_v4l2_video_dec_close(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GST_DEBUG_OBJECT(self, "Closing");
+ GST_DEBUG_OBJECT (self, "Closing");
- gst_aml_v4l2_object_close(self->v4l2output);
- gst_aml_v4l2_object_close(self->v4l2capture);
- gst_caps_replace(&self->probed_srccaps, NULL);
- gst_caps_replace(&self->probed_sinkcaps, NULL);
+ gst_aml_v4l2_object_close(self->v4l2output);
+ gst_aml_v4l2_object_close(self->v4l2capture);
+ gst_caps_replace (&self->probed_srccaps, NULL);
+ gst_caps_replace (&self->probed_sinkcaps, NULL);
- return TRUE;
+ return TRUE;
}
static gboolean
gst_aml_v4l2_video_dec_start(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GST_DEBUG_OBJECT(self, "Starting");
+ GST_DEBUG_OBJECT (self, "Starting");
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- g_atomic_int_set(&self->active, TRUE);
- self->output_flow = GST_FLOW_OK;
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ g_atomic_int_set (&self->active, TRUE);
+ self->output_flow = GST_FLOW_OK;
- return TRUE;
+ return TRUE;
}
static gboolean
gst_aml_v4l2_video_dec_stop(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GST_DEBUG_OBJECT(self, "Stopping");
+ GST_DEBUG_OBJECT (self, "Stopping");
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- gst_aml_v4l2_object_flush_start(self->v4l2capture);
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ gst_aml_v4l2_object_flush_start (self->v4l2capture);
- /* Wait for capture thread to stop */
- gst_pad_stop_task(decoder->srcpad);
+ /* Wait for capture thread to stop */
+ gst_pad_stop_task (decoder->srcpad);
- GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
- self->output_flow = GST_FLOW_OK;
- GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
+ GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
+ self->output_flow = GST_FLOW_OK;
+ GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
- /* Should have been flushed already */
- g_assert(g_atomic_int_get(&self->active) == FALSE);
+ /* Should have been flushed already */
+ g_assert (g_atomic_int_get (&self->active) == FALSE);
- gst_aml_v4l2_object_stop(self->v4l2output);
- gst_aml_v4l2_object_stop(self->v4l2capture);
+ gst_aml_v4l2_object_stop(self->v4l2output);
+ gst_aml_v4l2_object_stop(self->v4l2capture);
- if (self->input_state)
- {
- gst_aml_video_codec_state_unref(self->input_state);
- self->input_state = NULL;
- }
+ if (self->input_state)
+ {
+ gst_aml_video_codec_state_unref(self->input_state);
+ self->input_state = NULL;
+ }
- GST_DEBUG_OBJECT(self, "Stopped");
+ GST_DEBUG_OBJECT (self, "Stopped");
- return TRUE;
+ return TRUE;
}
static gboolean
gst_aml_v4l2_video_dec_codec_chg(GstAmlVideoDecoder *decoder,
GstAmlVideoCodecState *state)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstStructure *s_old = NULL;
- GstStructure *s_new = NULL;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstStructure *s_old = NULL;
+ GstStructure *s_new = NULL;
- // first play, must set foramt;
- if (!self->input_state)
- return TRUE;
+ // first play, must set foramt;
+ if (!self->input_state)
+ return TRUE;
- if (self->input_state->caps)
- s_old = gst_caps_get_structure(self->input_state->caps,0);
- if (state->caps)
- s_new = gst_caps_get_structure(state->caps,0);
+ if (self->input_state->caps)
+ s_old = gst_caps_get_structure(self->input_state->caps,0);
+ if (state->caps)
+ s_new = gst_caps_get_structure(state->caps,0);
- if (s_new && s_old && strcmp(gst_structure_get_name(s_new),gst_structure_get_name(s_old)))
- return TRUE;
- return FALSE;
+ if (s_new && s_old && strcmp(gst_structure_get_name(s_new),gst_structure_get_name(s_old)))
+ return TRUE;
+ return FALSE;
}
static gboolean
gst_aml_v4l2_video_dec_res_chg(GstAmlVideoDecoder *decoder,
GstAmlVideoCodecState *state)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- gboolean ret = FALSE;
- gint width_new = -1,height_new = -1,width_old = -1,height_old = -1;
- GstStructure *s_old = NULL;
- GstStructure *s_new = NULL;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ gboolean ret = FALSE;
+ gint width_new = -1,height_new = -1,width_old = -1,height_old = -1;
+ GstStructure *s_old = NULL;
+ GstStructure *s_new = NULL;
- // first play, must set foramt;
- if (!self->input_state)
- {
- ret = TRUE;
- goto done;
- }
+ // first play, must set foramt;
+ if (!self->input_state)
+ {
+ ret = TRUE;
+ goto done;
+ }
- if (self->input_state->caps)
- s_old = gst_caps_get_structure(self->input_state->caps,0);
- if (state->caps)
- s_new = gst_caps_get_structure(state->caps,0);
+ if (self->input_state->caps)
+ s_old = gst_caps_get_structure(self->input_state->caps,0);
+ if (state->caps)
+ s_new = gst_caps_get_structure(state->caps,0);
- if (s_new && gst_structure_has_field(s_new,"width") && gst_structure_has_field(s_new,"height"))
- {
- gst_structure_get_int(s_new,"width",&width_new);
- gst_structure_get_int(s_new,"height",&height_new);
- }
- if (s_old && gst_structure_has_field(s_old,"width") && gst_structure_has_field(s_old,"height"))
- {
- gst_structure_get_int(s_old,"width",&width_old);
- gst_structure_get_int(s_old,"height",&height_old);
- }
+ if (s_new && gst_structure_has_field(s_new,"width") && gst_structure_has_field(s_new,"height"))
+ {
+ gst_structure_get_int(s_new,"width",&width_new);
+ gst_structure_get_int(s_new,"height",&height_new);
+ }
+ if (s_old && gst_structure_has_field(s_old,"width") && gst_structure_has_field(s_old,"height"))
+ {
+ gst_structure_get_int(s_old,"width",&width_old);
+ gst_structure_get_int(s_old,"height",&height_old);
+ }
- if (width_new != width_old || height_new != height_old)
- ret = TRUE;
+ if (width_new != width_old || height_new != height_old)
+ ret = TRUE;
done:
- GST_DEBUG_OBJECT(self, "ret is %d",ret);
- return ret;
+ GST_DEBUG_OBJECT(self, "ret is %d",ret);
+ return ret;
}
static gboolean
gst_aml_v4l2_video_dec_set_format(GstAmlVideoDecoder *decoder,
GstAmlVideoCodecState *state)
{
- GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
- gboolean ret = TRUE;
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstCaps *caps;
+ GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
+ gboolean ret = TRUE;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstCaps *caps;
- GST_DEBUG_OBJECT(self, "Setting format: %" GST_PTR_FORMAT, state->caps);
- if (self->input_state)
- {
- if (gst_aml_v4l2_video_dec_res_chg(decoder,state) || gst_aml_v4l2_video_dec_codec_chg(decoder,state))
- GST_DEBUG_OBJECT(self, "resolution or codec changed");
- else
- goto done;
- }
-
- GstCapsFeatures *const features = gst_caps_get_features(state->caps, 0);
- GstStructure *s = gst_caps_get_structure(state->caps,0);
- if (s && gst_structure_has_field(s,"format"))
- {
- if (!strcmp("XVID",gst_structure_get_string(s,"format")))
- {
- GST_DEBUG_OBJECT(self, "This is a DIVX file, cannot support");
- ret = FALSE;
- goto done;
- }
- }
-
- if (gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF))
- self->v4l2output->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
-
- if (self->input_state)
- {
- if (gst_aml_v4l2_object_caps_equal(self->v4l2output, state->caps))
- {
- GST_DEBUG_OBJECT(self, "Compatible caps");
- goto done;
- }
-
- gst_aml_v4l2_video_dec_finish(decoder);
- gst_aml_v4l2_object_stop(self->v4l2output);
-
- gst_aml_video_codec_state_unref(self->input_state);
- self->input_state = NULL;
-
- /* The renegotiation flow don't blend with the base class flow. To properly
- * stop the capture pool, if the buffers can't be orphaned, we need to
- * reclaim our buffers, which will happend through the allocation query.
- * The allocation query is triggered by gst_aml_video_decoder_negotiate() which
- * requires the output caps to be set, but we can't know this information
- * as we rely on the decoder, which requires the capture queue to be
- * stopped.
- *
- * To workaround this issue, we simply run an allocation query with the
- * old negotiated caps in order to drain/reclaim our buffers. That breaks
- * the complexity and should not have much impact in performance since the
- * following allocation query will happen on a drained pipeline and won't
- * block. */
- if (self->v4l2capture->pool &&
- !gst_aml_v4l2_buffer_pool_orphan(&self->v4l2capture->pool))
- {
- GstCaps *caps = gst_pad_get_current_caps(decoder->srcpad);
- if (caps)
- {
- GstQuery *query = gst_query_new_allocation(caps, FALSE);
- gst_pad_peer_query(decoder->srcpad, query);
- gst_query_unref(query);
- gst_caps_unref(caps);
- }
- }
-
- gst_aml_v4l2_object_stop(self->v4l2capture);
- self->output_flow = GST_FLOW_OK;
- }
- if ((ret = gst_aml_v4l2_set_drm_mode(self->v4l2output)) == FALSE)
- {
- GST_ERROR_OBJECT(self, "config output drm mode error");
- goto done;
- }
-
- if ((ret = gst_aml_v4l2_set_stream_mode(self->v4l2output)) == FALSE)
- {
- GST_ERROR_OBJECT(self, "config output stream mode error");
- goto done;
- }
-
- if (!gst_aml_v4l2_object_set_format(self->v4l2output, state->caps, &error))
- {
- GST_ERROR_OBJECT(self, "set format error");
- goto done;
- }
-
- // MUST: aml v4l2 drive request set I frame after VIDIOC_S_FMT.
- if ((ret = gst_aml_v4l2_set_I_frame_mode(self->v4l2output)) == FALSE)
- {
- GST_ERROR_OBJECT(self, "config I frame mode error");
- goto done;
- }
-
- gst_caps_replace(&self->probed_srccaps, NULL);
- self->probed_srccaps = gst_aml_v4l2_object_probe_caps(self->v4l2capture,
- gst_aml_v4l2_object_get_raw_caps());
-
- if (gst_caps_is_empty(self->probed_srccaps))
- goto no_raw_format;
-
- caps = gst_caps_copy(self->probed_srccaps);
- gst_caps_set_features_simple(caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
- gst_caps_append(self->probed_srccaps, caps);
-
- if (ret)
- self->input_state = gst_aml_video_codec_state_ref(state);
+ GST_DEBUG_OBJECT (self, "Setting format: %" GST_PTR_FORMAT, state->caps);
+ if (self->input_state)
+ {
+ if (gst_aml_v4l2_video_dec_res_chg(decoder,state) || gst_aml_v4l2_video_dec_codec_chg(decoder,state))
+ GST_DEBUG_OBJECT(self, "resolution or codec changed");
else
- gst_aml_v4l2_error(self, &error);
+ goto done;
+ }
+
+ GstCapsFeatures *const features = gst_caps_get_features(state->caps, 0);
+ GstStructure *s = gst_caps_get_structure(state->caps,0);
+ if (s && gst_structure_has_field(s,"format"))
+ {
+ if (!strcmp("XVID",gst_structure_get_string(s,"format")))
+ {
+ GST_DEBUG_OBJECT(self, "This is a DIVX file, cannot support");
+ ret = FALSE;
+ goto done;
+ }
+ }
+
+ if (gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF))
+ self->v4l2output->req_mode = GST_V4L2_IO_DMABUF_IMPORT;
+
+ if (self->input_state)
+ {
+ if (gst_aml_v4l2_object_caps_equal(self->v4l2output, state->caps))
+ {
+ GST_DEBUG_OBJECT (self, "Compatible caps");
+ goto done;
+ }
+
+ gst_aml_v4l2_video_dec_finish (decoder);
+ gst_aml_v4l2_object_stop (self->v4l2output);
+
+ gst_aml_video_codec_state_unref(self->input_state);
+ self->input_state = NULL;
+
+ /* The renegotiation flow don't blend with the base class flow. To properly
+ * stop the capture pool, if the buffers can't be orphaned, we need to
+ * reclaim our buffers, which will happend through the allocation query.
+ * The allocation query is triggered by gst_aml_video_decoder_negotiate() which
+ * requires the output caps to be set, but we can't know this information
+ * as we rely on the decoder, which requires the capture queue to be
+ * stopped.
+ *
+ * To workaround this issue, we simply run an allocation query with the
+ * old negotiated caps in order to drain/reclaim our buffers. That breaks
+ * the complexity and should not have much impact in performance since the
+ * following allocation query will happen on a drained pipeline and won't
+ * block. */
+ if (self->v4l2capture->pool &&
+ !gst_aml_v4l2_buffer_pool_orphan(&self->v4l2capture->pool))
+ {
+ GstCaps *caps = gst_pad_get_current_caps (decoder->srcpad);
+ if (caps)
+ {
+ GstQuery *query = gst_query_new_allocation (caps, FALSE);
+ gst_pad_peer_query (decoder->srcpad, query);
+ gst_query_unref (query);
+ gst_caps_unref (caps);
+ }
+ }
+
+ gst_aml_v4l2_object_stop (self->v4l2capture);
+ self->output_flow = GST_FLOW_OK;
+ }
+ if ((ret = gst_aml_v4l2_set_drm_mode(self->v4l2output)) == FALSE)
+ {
+ GST_ERROR_OBJECT(self, "config output drm mode error");
+ goto done;
+ }
+
+ if ((ret = gst_aml_v4l2_set_stream_mode(self->v4l2output)) == FALSE)
+ {
+ GST_ERROR_OBJECT(self, "config output stream mode error");
+ goto done;
+ }
+
+ if (!gst_aml_v4l2_object_set_format (self->v4l2output, state->caps, &error))
+ {
+ GST_ERROR_OBJECT(self, "set format error");
+ goto done;
+ }
+
+ // MUST: aml v4l2 drive request set I frame after VIDIOC_S_FMT.
+ if ((ret = gst_aml_v4l2_set_I_frame_mode(self->v4l2output)) == FALSE)
+ {
+ GST_ERROR_OBJECT(self, "config I frame mode error");
+ goto done;
+ }
+
+ gst_caps_replace (&self->probed_srccaps, NULL);
+ self->probed_srccaps = gst_aml_v4l2_object_probe_caps (self->v4l2capture,
+ gst_aml_v4l2_object_get_raw_caps ());
+
+ if (gst_caps_is_empty (self->probed_srccaps))
+ goto no_raw_format;
+
+ caps = gst_caps_copy(self->probed_srccaps);
+ gst_caps_set_features_simple(caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
+ gst_caps_append(self->probed_srccaps, caps);
+ if (ret)
+ self->input_state = gst_aml_video_codec_state_ref (state);
+ else
+ gst_aml_v4l2_error (self, &error);
done:
- return ret;
+ return ret;
no_raw_format:
- GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
- (_("Decoder on device %s has no supported output format"),
- self->v4l2output->videodev),
- (NULL));
- return GST_FLOW_ERROR;
+ GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ (_("Decoder on device %s has no supported output format"),
+ self->v4l2output->videodev), (NULL));
+ return GST_FLOW_ERROR;
}
static gboolean
gst_aml_v4l2_video_dec_flush(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GST_DEBUG_OBJECT(self, "Flushed");
+ GST_DEBUG_OBJECT(self, "Flushed");
- /* Ensure the processing thread has stopped for the reverse playback
- * discount case */
- if (gst_pad_get_task_state(decoder->srcpad) == GST_TASK_STARTED)
- {
- GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
+ /* Ensure the processing thread has stopped for the reverse playback
+ * discount case */
+ if (gst_pad_get_task_state (decoder->srcpad) == GST_TASK_STARTED)
+ {
+ GST_AML_VIDEO_DECODER_STREAM_UNLOCK (decoder);
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- gst_aml_v4l2_object_flush_start(self->v4l2capture);
- gst_pad_stop_task(decoder->srcpad);
- GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
- }
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ gst_aml_v4l2_object_flush_start (self->v4l2capture);
+ gst_pad_stop_task (decoder->srcpad);
+ GST_AML_VIDEO_DECODER_STREAM_LOCK (decoder);
+ }
- self->output_flow = GST_FLOW_OK;
+ self->output_flow = GST_FLOW_OK;
- gst_aml_v4l2_object_flush_stop(self->v4l2output);
- gst_aml_v4l2_object_flush_stop(self->v4l2capture);
+ gst_aml_v4l2_object_flush_stop (self->v4l2output);
+ gst_aml_v4l2_object_flush_stop (self->v4l2capture);
- if (self->v4l2output->pool)
- gst_aml_v4l2_buffer_pool_flush(self->v4l2output->pool);
+ if (self->v4l2output->pool)
+ gst_aml_v4l2_buffer_pool_flush (self->v4l2output->pool);
- /* gst_aml_v4l2_buffer_pool_flush() calls streamon the capture pool and must be
- * called after gst_aml_v4l2_object_flush_stop() stopped flushing the buffer
- * pool. */
- if (self->v4l2capture->pool)
- gst_aml_v4l2_buffer_pool_flush(self->v4l2capture->pool);
+ /* gst_aml_v4l2_buffer_pool_flush() calls streamon the capture pool and must be
+ * called after gst_aml_v4l2_object_flush_stop() stopped flushing the buffer
+ * pool. */
+ if (self->v4l2capture->pool)
+ gst_aml_v4l2_buffer_pool_flush (self->v4l2capture->pool);
- return TRUE;
+ return TRUE;
}
static gboolean
gst_aml_v4l2_video_dec_negotiate(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- if (TRUE == self->v4l2output->is_svp)
- {
- GstStructure *s;
- GstEvent *event;
+ if (TRUE == self->v4l2output->is_svp)
+ {
+ GstStructure *s;
+ GstEvent *event;
- s = gst_structure_new_empty ("IS_SVP");
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s);
- GST_DEBUG_OBJECT(self, "before Send SVP Event :%p", event);
- gst_pad_push_event (decoder->srcpad, event);
- GST_DEBUG_OBJECT(self, "after Send SVP Event :%p", event);
- }
+ s = gst_structure_new_empty ("IS_SVP");
+ event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s);
+ GST_DEBUG_OBJECT(self, "before Send SVP Event :%p", event);
+ gst_pad_push_event (decoder->srcpad, event);
+ GST_DEBUG_OBJECT(self, "after Send SVP Event :%p", event);
+ }
- /* We don't allow renegotiation without carefull disabling the pool */
- if (self->v4l2capture->pool &&
- gst_buffer_pool_is_active(GST_BUFFER_POOL(self->v4l2capture->pool)))
- return TRUE;
+ /* We don't allow renegotiation without carefull disabling the pool */
+ if (self->v4l2capture->pool &&
+ gst_buffer_pool_is_active(GST_BUFFER_POOL(self->v4l2capture->pool)))
+ return TRUE;
- return GST_AML_VIDEO_DECODER_CLASS(parent_class)->negotiate(decoder);
+ return GST_AML_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
}
static gboolean
gst_aml_v4l2_decoder_cmd(GstAmlV4l2Object *v4l2object, guint cmd, guint flags)
{
- struct v4l2_decoder_cmd dcmd = {
- 0,
- };
+ struct v4l2_decoder_cmd dcmd = { 0, };
- GST_DEBUG_OBJECT(v4l2object->element,
- "sending v4l2 decoder command %u with flags %u", cmd, flags);
+ GST_DEBUG_OBJECT (v4l2object->element,
+ "sending v4l2 decoder command %u with flags %u", cmd, flags);
- if (!GST_AML_V4L2_IS_OPEN(v4l2object))
- return FALSE;
+ if (!GST_AML_V4L2_IS_OPEN (v4l2object))
+ return FALSE;
- dcmd.cmd = cmd;
- dcmd.flags = flags;
- if (v4l2object->ioctl(v4l2object->video_fd, VIDIOC_DECODER_CMD, &dcmd) < 0)
- goto dcmd_failed;
+ dcmd.cmd = cmd;
+ dcmd.flags = flags;
+ if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_DECODER_CMD, &dcmd) < 0)
+ goto dcmd_failed;
- return TRUE;
+ return TRUE;
dcmd_failed:
- if (errno == ENOTTY)
- {
- GST_INFO_OBJECT(v4l2object->element,
- "Failed to send decoder command %u with flags %u for '%s'. (%s)",
- cmd, flags, v4l2object->videodev, g_strerror(errno));
- }
- else
- {
- GST_ERROR_OBJECT(v4l2object->element,
- "Failed to send decoder command %u with flags %u for '%s'. (%s)",
- cmd, flags, v4l2object->videodev, g_strerror(errno));
- }
- return FALSE;
+ if (errno == ENOTTY)
+ {
+ GST_INFO_OBJECT (v4l2object->element,
+ "Failed to send decoder command %u with flags %u for '%s'. (%s)",
+ cmd, flags, v4l2object->videodev, g_strerror (errno));
+ }
+ else
+ {
+ GST_ERROR_OBJECT (v4l2object->element,
+ "Failed to send decoder command %u with flags %u for '%s'. (%s)",
+ cmd, flags, v4l2object->videodev, g_strerror (errno));
+ }
+ return FALSE;
}
static GstFlowReturn
gst_aml_v4l2_video_dec_finish(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstFlowReturn ret = GST_FLOW_OK;
- GstBuffer *buffer;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (decoder);
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstBuffer *buffer;
- if (gst_pad_get_task_state(decoder->srcpad) != GST_TASK_STARTED)
- goto done;
+ if (gst_pad_get_task_state (decoder->srcpad) != GST_TASK_STARTED)
+ goto done;
- GST_DEBUG_OBJECT(self, "Finishing decoding");
+ GST_DEBUG_OBJECT (self, "Finishing decoding");
- GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
+ GST_AML_VIDEO_DECODER_STREAM_UNLOCK (decoder);
- if (gst_aml_v4l2_decoder_cmd(self->v4l2output, V4L2_DEC_CMD_STOP, 0))
+ if (gst_aml_v4l2_decoder_cmd (self->v4l2output, V4L2_DEC_CMD_STOP, 0))
+ {
+ GstTask *task = decoder->srcpad->task;
+
+ /* If the decoder stop command succeeded, just wait until processing is
+ * finished */
+ GST_DEBUG_OBJECT (self, "Waiting for decoder stop");
+ GST_OBJECT_LOCK (task);
+ while (GST_TASK_STATE (task) == GST_TASK_STARTED)
+ GST_TASK_WAIT (task);
+ GST_OBJECT_UNLOCK (task);
+
+ ret = GST_FLOW_FLUSHING;
+ }
+ else
+ {
+ /* otherwise keep queuing empty buffers until the processing thread has
+ * stopped, _pool_process() will return FLUSHING when that happened */
+ while (ret == GST_FLOW_OK)
{
- GstTask *task = decoder->srcpad->task;
-
- /* If the decoder stop command succeeded, just wait until processing is
- * finished */
- GST_DEBUG_OBJECT(self, "Waiting for decoder stop");
- GST_OBJECT_LOCK(task);
- while (GST_TASK_STATE(task) == GST_TASK_STARTED)
- GST_TASK_WAIT(task);
- GST_OBJECT_UNLOCK(task);
- ret = GST_FLOW_FLUSHING;
+ GST_DEBUG_OBJECT(self, "queue empty output buf");
+ buffer = gst_buffer_new ();
+ ret =
+ gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &buffer);
+ gst_buffer_unref (buffer);
}
- else
- {
- /* otherwise keep queuing empty buffers until the processing thread has
- * stopped, _pool_process() will return FLUSHING when that happened */
- while (ret == GST_FLOW_OK)
- {
- GST_DEBUG_OBJECT(self, "queue empty output buf");
- buffer = gst_buffer_new();
- ret =
- gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &buffer);
- gst_buffer_unref(buffer);
- }
- }
+ }
- /* and ensure the processing thread has stopped in case another error
- * occured. */
- gst_aml_v4l2_object_flush_start(self->v4l2capture);
- gst_pad_stop_task(decoder->srcpad);
- GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
+ /* and ensure the processing thread has stopped in case another error
+ * occurred. */
+ gst_aml_v4l2_object_flush_start (self->v4l2capture);
+ gst_pad_stop_task (decoder->srcpad);
+ GST_AML_VIDEO_DECODER_STREAM_LOCK (decoder);
- if (ret == GST_FLOW_FLUSHING)
- ret = self->output_flow;
+ if (ret == GST_FLOW_FLUSHING)
+ ret = self->output_flow;
- /*if V4L2_DEC_CMD_STOP called,indicate decoder will stop.
- should reset need_wait_event=true to wait source change event*/
- self->v4l2capture->need_wait_event = TRUE;
- GST_DEBUG_OBJECT(decoder, "Done draining buffers");
+ /*if V4L2_DEC_CMD_STOP called,indicate decoder will stop.
+ should reset need_wait_event=true to wait source change event*/
+ self->v4l2capture->need_wait_event = TRUE;
+ GST_DEBUG_OBJECT (decoder, "Done draining buffers");
- /* TODO Shall we cleanup any reffed frame to workaround broken decoders ? */
+ /* TODO Shall we cleanup any reffed frame to workaround broken decoders ? */
done:
- return ret;
+ return ret;
}
static GstFlowReturn
@@ -680,172 +676,172 @@
{
GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GST_DEBUG_OBJECT(self, "Draining...");
- gst_aml_v4l2_video_dec_finish(decoder);
- gst_aml_v4l2_video_dec_flush(decoder);
+ GST_DEBUG_OBJECT (self, "Draining...");
+ gst_aml_v4l2_video_dec_finish (decoder);
+ gst_aml_v4l2_video_dec_flush (decoder);
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
}
static GstAmlVideoCodecFrame *
gst_aml_v4l2_video_dec_get_right_frame_for_frame_mode(GstAmlVideoDecoder *decoder, GstClockTime pts)
{
- GstAmlVideoCodecFrame *frame = NULL;
- GList *frames, *l;
- gint count = 0;
+ GstAmlVideoCodecFrame *frame = NULL;
+ GList *frames, *l;
+ gint count = 0;
- GST_LOG_OBJECT (decoder, "trace in with pts: %" GST_TIME_FORMAT, GST_TIME_ARGS(pts));
+ GST_LOG_OBJECT (decoder, "trace in with pts: %" GST_TIME_FORMAT, GST_TIME_ARGS(pts));
- frames = gst_aml_video_decoder_get_frames(decoder);
+ frames = gst_aml_video_decoder_get_frames(decoder);
- for (l = frames; l != NULL; l = l->next)
- {
- GstAmlVideoCodecFrame *f = l->data;
+ for (l = frames; l != NULL; l = l->next)
+ {
+ GstAmlVideoCodecFrame *f = l->data;
- if (GST_CLOCK_TIME_IS_VALID(pts) && (ABSDIFF(f->pts,pts)) < 1000) {
- frame = f;
- }
- count++;
- }
+ if (GST_CLOCK_TIME_IS_VALID(pts) && (ABSDIFF(f->pts,pts)) < 1000) {
+ frame = f;
+ }
+ count++;
+ }
- if (!frame)
- {
- for (l = frames; l != NULL; l = l->next)
- {
- GstAmlVideoCodecFrame *f = l->data;
- if (!GST_CLOCK_TIME_IS_VALID(f->pts))
- {
- frame = f;
- GST_DEBUG("The pts of the expected output frame is invalid");
- break;
- }
- }
- }
+ if (!frame)
+ {
+ for (l = frames; l != NULL; l = l->next)
+ {
+ GstAmlVideoCodecFrame *f = l->data;
+ if (!GST_CLOCK_TIME_IS_VALID(f->pts))
+ {
+ frame = f;
+ GST_DEBUG("The pts of the expected output frame is invalid");
+ break;
+ }
+ }
+ }
- if (frame)
- {
- GST_LOG_OBJECT(decoder,
- "frame %p is %d %" GST_TIME_FORMAT " and %d frames left",
- frame, frame->system_frame_number, GST_TIME_ARGS(frame->pts), count - 1);
- gst_aml_video_codec_frame_ref(frame);
- }
- else
- {
- GST_LOG_OBJECT(decoder,
- "buffer %" GST_TIME_FORMAT " unmatch, create new frame", GST_TIME_ARGS(pts));
- frame = gst_aml_video_decoder_v4l2_new_frame (decoder);
- }
+ if (frame)
+ {
+ GST_LOG_OBJECT(decoder,
+ "frame %p is %d %" GST_TIME_FORMAT " and %d frames left",
+ frame, frame->system_frame_number, GST_TIME_ARGS(frame->pts), count - 1);
+ gst_aml_video_codec_frame_ref(frame);
+ }
+ else
+ {
+ GST_LOG_OBJECT(decoder,
+ "buffer %" GST_TIME_FORMAT " unmatch, create new frame", GST_TIME_ARGS(pts));
+ frame = gst_aml_video_decoder_v4l2_new_frame (decoder);
+ }
- g_list_free_full(frames, (GDestroyNotify)gst_aml_video_codec_frame_unref);
+ g_list_free_full(frames, (GDestroyNotify)gst_aml_video_codec_frame_unref);
- return frame;
+ return frame;
}
static GstAmlVideoCodecFrame *
gst_aml_v4l2_video_dec_get_right_frame_for_stream_mode(GstAmlVideoDecoder *decoder, GstClockTime pts)
{
- GstAmlVideoCodecFrame *frame = NULL;
- GList *frames, *l;
- guint frames_len = 0;
- GST_LOG_OBJECT (decoder, "trace in with pts: %" GST_TIME_FORMAT, GST_TIME_ARGS(pts));
+ GstAmlVideoCodecFrame *frame = NULL;
+ GList *frames, *l;
+ guint frames_len = 0;
+ GST_LOG_OBJECT (decoder, "trace in with pts: %" GST_TIME_FORMAT, GST_TIME_ARGS(pts));
- if (!(frames = gst_aml_video_decoder_get_frames(decoder)))
- goto done;
+ if (!(frames = gst_aml_video_decoder_get_frames(decoder)))
+ goto done;
- frames_len = g_list_length(frames);
- GST_LOG_OBJECT (decoder, "got frames list len:%d", frames_len);
+ frames_len = g_list_length(frames);
+ GST_LOG_OBJECT (decoder, "got frames list len:%d", frames_len);
- for (l = frames; l != NULL; l = l->next)
- {
- GstAmlVideoCodecFrame *f = l->data;
+ for (l = frames; l != NULL; l = l->next)
+ {
+ GstAmlVideoCodecFrame *f = l->data;
- if (GST_CLOCK_TIME_IS_VALID(pts) && (ABSDIFF(f->pts, pts)) < 1000)
- {
- /* found the right frame */
- GST_LOG_OBJECT(decoder,
- "found frame %" GST_TIME_FORMAT "with pts %" GST_TIME_FORMAT,
- GST_TIME_ARGS(f->pts), GST_TIME_ARGS(pts));
- frame = f;
- break;
- }
- else if(GST_CLOCK_TIME_IS_VALID(pts) && (f->pts < pts))
- {
- GST_LOG_OBJECT(decoder,
- "stream mode drop frame %d %" GST_TIME_FORMAT,
- f->system_frame_number, GST_TIME_ARGS(f->pts));
+ if (GST_CLOCK_TIME_IS_VALID(pts) && (ABSDIFF(f->pts, pts)) < 1000)
+ {
+ /* found the right frame */
+ GST_LOG_OBJECT(decoder,
+ "found frame %" GST_TIME_FORMAT "with pts %" GST_TIME_FORMAT,
+ GST_TIME_ARGS(f->pts), GST_TIME_ARGS(pts));
+ frame = f;
+ break;
+ }
+ else if(GST_CLOCK_TIME_IS_VALID(pts) && (f->pts < pts))
+ {
+ GST_LOG_OBJECT(decoder,
+ "stream mode drop frame %d %" GST_TIME_FORMAT,
+ f->system_frame_number, GST_TIME_ARGS(f->pts));
- gst_aml_video_codec_frame_ref(f);
- // gst_aml_video_decoder_drop_frame(decoder, f);
- gst_aml_video_decoder_release_frame(decoder, f);
- }
- else
- {
- GST_LOG_OBJECT (decoder, "dbg");
- }
- }
+ gst_aml_video_codec_frame_ref(f);
+ // gst_aml_video_decoder_drop_frame(decoder, f);
+ gst_aml_video_decoder_release_frame(decoder, f);
+ }
+ else
+ {
+ GST_LOG_OBJECT (decoder, "dbg");
+ }
+ }
- if (frame)
- {
- guint l_len = 0;
- l = gst_aml_video_decoder_get_frames(decoder);
- l_len = g_list_length(l);
- g_list_free_full(l, (GDestroyNotify)gst_aml_video_codec_frame_unref);
+ if (frame)
+ {
+ guint l_len = 0;
+ l = gst_aml_video_decoder_get_frames(decoder);
+ l_len = g_list_length(l);
+ g_list_free_full(l, (GDestroyNotify)gst_aml_video_codec_frame_unref);
- GST_LOG_OBJECT(decoder,
- "frame %p is %d %" GST_TIME_FORMAT " and %d frames left",
- frame, frame->system_frame_number, GST_TIME_ARGS(frame->pts), l_len);
- gst_aml_video_codec_frame_ref(frame);
- }
+ GST_LOG_OBJECT(decoder,
+ "frame %p is %d %" GST_TIME_FORMAT " and %d frames left",
+ frame, frame->system_frame_number, GST_TIME_ARGS(frame->pts), l_len);
+ gst_aml_video_codec_frame_ref(frame);
+ }
- g_list_free_full(frames, (GDestroyNotify)gst_aml_video_codec_frame_unref);
+ g_list_free_full(frames, (GDestroyNotify)gst_aml_video_codec_frame_unref);
done:
- return frame;
+ return frame;
}
static GstAmlVideoCodecFrame *
gst_aml_v4l2_video_dec_get_right_frame(GstAmlVideoDecoder *decoder, GstClockTime pts)
{
- GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)decoder;
- if (self->v4l2output->stream_mode)
- return gst_aml_v4l2_video_dec_get_right_frame_for_stream_mode(decoder, pts);
- else
- return gst_aml_v4l2_video_dec_get_right_frame_for_frame_mode(decoder, pts);
+ GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec *)decoder;
+ if (self->v4l2output->stream_mode)
+ return gst_aml_v4l2_video_dec_get_right_frame_for_stream_mode(decoder, pts);
+ else
+ return gst_aml_v4l2_video_dec_get_right_frame_for_frame_mode(decoder, pts);
}
static gboolean
gst_aml_v4l2_video_remove_padding(GstCapsFeatures *features,
GstStructure *structure, gpointer user_data)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(user_data);
- GstVideoAlignment *align = &self->v4l2capture->align;
- GstVideoInfo *info = &self->v4l2capture->info;
- int width, height;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(user_data);
+ GstVideoAlignment *align = &self->v4l2capture->align;
+ GstVideoInfo *info = &self->v4l2capture->info;
+ int width, height;
- if (!gst_structure_get_int(structure, "width", &width))
- return TRUE;
+ if (!gst_structure_get_int(structure, "width", &width))
+ return TRUE;
- if (!gst_structure_get_int(structure, "height", &height))
- return TRUE;
+ if (!gst_structure_get_int(structure, "height", &height))
+ return TRUE;
- if (align->padding_left != 0 || align->padding_top != 0 ||
- height != info->height + align->padding_bottom)
- return TRUE;
+ if (align->padding_left != 0 || align->padding_top != 0 ||
+ height != info->height + align->padding_bottom)
+ return TRUE;
- if (height == info->height + align->padding_bottom)
- {
- /* Some drivers may round up width to the padded with */
- if (width == info->width + align->padding_right)
- gst_structure_set(structure,
- "width", G_TYPE_INT, width - align->padding_right,
- "height", G_TYPE_INT, height - align->padding_bottom, NULL);
- /* Some drivers may keep visible width and only round up bytesperline */
- else if (width == info->width)
- gst_structure_set(structure,
- "height", G_TYPE_INT, height - align->padding_bottom, NULL);
- }
+ if (height == info->height + align->padding_bottom)
+ {
+ /* Some drivers may round up width to the padded with */
+ if (width == info->width + align->padding_right)
+ gst_structure_set(structure,
+ "width", G_TYPE_INT, width - align->padding_right,
+ "height", G_TYPE_INT, height - align->padding_bottom, NULL);
+ /* Some drivers may keep visible width and only round up bytesperline */
+ else if (width == info->width)
+ gst_structure_set(structure,
+ "height", G_TYPE_INT, height - align->padding_bottom, NULL);
+ }
- return TRUE;
+ return TRUE;
}
static void
@@ -880,44 +876,44 @@
static void
gst_aml_v4l2_video_dec_set_output_status(GstAmlVideoDecoder *decoder,GstVideoInfo info)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstAmlVideoCodecState *output_state;
- struct v4l2_selection sel;
- struct v4l2_rect *r = NULL;
- GstStructure *s;
- gint width = 0;
- gint height = 0;
- GST_DEBUG("%d %d",info.width, info.height);
- output_state = gst_aml_video_decoder_set_output_state(decoder,
- info.finfo->format, info.width, info.height, self->input_state);
- memset(&sel, 0, sizeof(struct v4l2_selection));
- sel.type = self->v4l2capture->type;
- sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
- if (self->v4l2capture->ioctl(self->v4l2capture->video_fd, VIDIOC_G_SELECTION, &sel) >= 0)
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlVideoCodecState *output_state;
+ struct v4l2_selection sel;
+ struct v4l2_rect *r = NULL;
+ GstStructure *s;
+ gint width = 0;
+ gint height = 0;
+ GST_DEBUG("%d %d",info.width, info.height);
+ output_state = gst_aml_video_decoder_set_output_state(decoder,
+ info.finfo->format, info.width, info.height, self->input_state);
+ memset(&sel, 0, sizeof(struct v4l2_selection));
+ sel.type = self->v4l2capture->type;
+ sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+ if (self->v4l2capture->ioctl(self->v4l2capture->video_fd, VIDIOC_G_SELECTION, &sel) >= 0)
+ {
+ r = &sel.r;
+ width = (r->width/2)*2;
+ height = (r->height/2)*2;
+ GST_DEBUG_OBJECT(self, "w:%d h:%d ",width,height);
+ }
+ else
+ GST_DEBUG_OBJECT(self, "iotcl error");
+ if (output_state)
+ {
+ output_state->info.interlace_mode = info.interlace_mode;
+ output_state->allocation_caps =gst_video_info_to_caps(&info);
+ output_state->caps =gst_video_info_to_caps(&info);
+ s = gst_caps_get_structure(output_state->caps, 0);
+ if (s)
{
- r = &sel.r;
- width = (r->width/2)*2;
- height = (r->height/2)*2;
- GST_DEBUG_OBJECT(self, "w:%d h:%d ",width,height);
+ gst_structure_set(s,"src_width",G_TYPE_INT,width,NULL);
+ gst_structure_set(s,"src_height",G_TYPE_INT,height,NULL);
+ gst_structure_set(s,"width",G_TYPE_INT,info.width,NULL);
+ gst_structure_set(s,"height",G_TYPE_INT,info.height,NULL);
+ GST_DEBUG_OBJECT(self, "output_state->caps: %" GST_PTR_FORMAT, output_state->caps);
+ gst_aml_video_codec_state_unref(output_state);
}
- else
- GST_DEBUG_OBJECT(self, "iotcl error");
- if (output_state)
- {
- output_state->info.interlace_mode = info.interlace_mode;
- output_state->allocation_caps =gst_video_info_to_caps(&info);
- output_state->caps =gst_video_info_to_caps(&info);
- s = gst_caps_get_structure(output_state->caps, 0);
- if (s)
- {
- gst_structure_set(s,"src_width",G_TYPE_INT,width,NULL);
- gst_structure_set(s,"src_height",G_TYPE_INT,height,NULL);
- gst_structure_set(s,"width",G_TYPE_INT,info.width,NULL);
- gst_structure_set(s,"height",G_TYPE_INT,info.height,NULL);
- GST_DEBUG_OBJECT(self, "output_state->caps: %" GST_PTR_FORMAT, output_state->caps);
- gst_aml_video_codec_state_unref(output_state);
- }
- }
+ }
}
static GQuark
@@ -934,61 +930,61 @@
static gboolean
foreach_cc_buffer_list_match_pts_func(GList *list , GstAmlVideoCodecFrame *frame)
{
- GList *l;
- if (g_list_length (list) > 0)
+ GList *l;
+ if (g_list_length (list) > 0)
+ {
+ for (l = list; l != NULL; l = l->next)
{
- for (l = list; l != NULL; l = l->next)
- {
- GstBuffer *cc_buffer = l->data;
- if (GST_BUFFER_TIMESTAMP (frame->output_buffer) == GST_BUFFER_TIMESTAMP (cc_buffer))
- {
- gst_mini_object_set_qdata (GST_MINI_OBJECT (frame->output_buffer), GST_AML_V4L2_CC_IMPORT_QUARK,
- gst_buffer_ref(cc_buffer), (GDestroyNotify) gst_buffer_unref);
- #if 0
- //Debug code:dump cc data
- GstMapInfo gst_map;
- gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
- int fd=open("/data/test/cc1.data",O_RDWR |O_CREAT|O_APPEND,0777);
- if (gst_map.size>0)
- write(fd,gst_map.data,gst_map.size);
- close(fd);
- gst_buffer_unmap(cc_buffer,&gst_map);
- #endif
- GST_DEBUG("match success");
- return TRUE;
- }
- else
- {
- GST_DEBUG("match fail");
- }
- }
- GST_WARNING("no match frame in the bufferlist");
+ GstBuffer *cc_buffer = l->data;
+ if (GST_BUFFER_TIMESTAMP (frame->output_buffer) == GST_BUFFER_TIMESTAMP (cc_buffer))
+ {
+ gst_mini_object_set_qdata (GST_MINI_OBJECT (frame->output_buffer), GST_AML_V4L2_CC_IMPORT_QUARK,
+ gst_buffer_ref(cc_buffer), (GDestroyNotify) gst_buffer_unref);
+ #if 0
+ //Debug code:dump cc data
+ GstMapInfo gst_map;
+ gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
+ int fd=open("/data/test/cc1.data",O_RDWR |O_CREAT|O_APPEND,0777);
+ if (gst_map.size>0)
+ write(fd,gst_map.data,gst_map.size);
+ close(fd);
+ gst_buffer_unmap(cc_buffer,&gst_map);
+ #endif
+ GST_DEBUG("match success");
+ return TRUE;
+ }
+ else
+ {
+ GST_DEBUG("match fail");
+ }
}
- else
- {
- GST_WARNING("list is null,can not foreach");
- }
- return FALSE;
+ GST_WARNING("no match frame in the bufferlist");
+ }
+ else
+ {
+ GST_WARNING("list is null,can not foreach");
+ }
+ return FALSE;
}
static GstClockTime
gst_aml_v4l2_video_dec_calc_output_buffer_pts(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstClockTime pts = GST_CLOCK_TIME_NONE;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstClockTime pts = GST_CLOCK_TIME_NONE;
- if (GST_CLOCK_TIME_IS_VALID (self->last_out_pts) && GST_CLOCK_TIME_IS_VALID(self->frame_duration)) {
- pts = self->last_out_pts + self->frame_duration;
- GST_LOG_OBJECT (decoder,
- "calculate PTS %" GST_TIME_FORMAT " by duration: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (pts), GST_TIME_ARGS (self->frame_duration));
- }
- else
- {
- pts = 0;
- GST_INFO_OBJECT (decoder,"Set PTS=0");
- }
- return pts;
+ if (GST_CLOCK_TIME_IS_VALID (self->last_out_pts) && GST_CLOCK_TIME_IS_VALID(self->frame_duration)) {
+ pts = self->last_out_pts + self->frame_duration;
+ GST_LOG_OBJECT (decoder,
+ "calculate PTS %" GST_TIME_FORMAT " by duration: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (pts), GST_TIME_ARGS (self->frame_duration));
+ }
+ else
+ {
+ pts = 0;
+ GST_INFO_OBJECT (decoder,"Set PTS=0");
+ }
+ return pts;
}
static GstClockTime
@@ -1018,1141 +1014,1137 @@
static void
gst_aml_v4l2_video_dec_loop(GstAmlVideoDecoder *decoder)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstAmlV4l2BufferPool *v4l2_pool;
- GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
- GstBufferPool *pool;
- GstAmlVideoCodecFrame *frame;
- GstBuffer *buffer = NULL;
- GstFlowReturn ret;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstAmlV4l2BufferPool *v4l2_pool;
+ GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
+ GstBufferPool *pool;
+ GstAmlVideoCodecFrame *frame;
+ GstBuffer *buffer = NULL;
+ GstFlowReturn ret;
- if (G_UNLIKELY(!GST_AML_V4L2_IS_ACTIVE(self->v4l2capture)))
+ if (G_UNLIKELY (!GST_AML_V4L2_IS_ACTIVE (self->v4l2capture)))
+ {
+ GstVideoInfo info;
+ GstCaps *acquired_caps, *available_caps, *caps, *filter;
+ GstStructure *st;
+ GST_DEBUG_OBJECT(self, "waitting source change event");
+ /* Wait until received SOURCE_CHANGE event to get right video format */
+ while (self->v4l2capture->can_wait_event && self->v4l2capture->need_wait_event)
{
- GstVideoInfo info;
- GstCaps *acquired_caps, *available_caps, *caps, *filter;
- GstStructure *st;
- GST_DEBUG_OBJECT(self, "waitting source change event");
- /* Wait until received SOURCE_CHANGE event to get right video format */
- while (self->v4l2capture->can_wait_event && self->v4l2capture->need_wait_event)
+ ret = gst_aml_v4l2_object_dqevent (self->v4l2capture);
+ if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
+ {
+ //let flush start event blocked until capture buffer pool actived
+ self->is_res_chg = TRUE;
+ GST_DEBUG_OBJECT (self, "Received source change event");
+ break;
+ }
+ else if (ret == GST_AML_V4L2_FLOW_LAST_BUFFER)
+ {
+ GST_DEBUG_OBJECT (self, "Received eos event");
+ goto beach;
+ }
+ else if (ret != GST_FLOW_OK)
+ {
+ GST_ERROR_OBJECT (self, "dqevent error");
+ goto beach;
+ }
+ }
+ self->v4l2capture->need_wait_event = FALSE;
+
+ if (TRUE == self->v4l2output->is_svp)
+ {
+ GstPad *peer;
+ GstStructure *s;
+ GstEvent *event;
+
+ peer = gst_pad_get_peer (decoder->srcpad);
+ if (peer)
+ {
+ s = gst_structure_new_empty ("IS_SVP");
+ if (s)
{
- ret = gst_aml_v4l2_object_dqevent(self->v4l2capture);
- if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
- {
- //let flush start event blocked until capture buffer pool actived
- self->is_res_chg = TRUE;
- GST_DEBUG_OBJECT(self, "Received source change event");
- break;
- }
- else if (ret == GST_AML_V4L2_FLOW_LAST_BUFFER)
- {
- GST_DEBUG_OBJECT(self, "Received eos event");
- goto beach;
- }
- else if (ret != GST_FLOW_OK)
- {
- GST_ERROR_OBJECT(self, "dqevent error");
- goto beach;
- }
+ event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+ gst_pad_send_event (peer, event);
+ GST_DEBUG_OBJECT(self, "Send SVP Event");
}
- self->v4l2capture->need_wait_event = FALSE;
-
- if (TRUE == self->v4l2output->is_svp)
- {
- GstPad *peer;
- GstStructure *s;
- GstEvent *event;
-
- peer = gst_pad_get_peer (decoder->srcpad);
- if (peer)
- {
- s = gst_structure_new_empty ("IS_SVP");
- if (s)
- {
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
- gst_pad_send_event (peer, event);
- GST_DEBUG_OBJECT(self, "Send SVP Event");
- }
- gst_object_unref (peer);
- }
- }
-
- if (self->v4l2capture->need_drop_event)
- {
- // drop V4L2_EVENT_SOURCE_CHANGE
- gst_v4l2_drop_event(self->v4l2capture);
- self->v4l2capture->need_drop_event = FALSE;
- }
-
- if (!gst_aml_v4l2_object_acquire_format(self->v4l2capture, &info))
- goto not_negotiated;
-
- /* Create caps from the acquired format, remove the format field */
- acquired_caps = gst_video_info_to_caps(&info);
- GST_DEBUG_OBJECT(self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps);
- st = gst_caps_get_structure(acquired_caps, 0);
- gst_structure_remove_fields(st, "format", "colorimetry", "chroma-site", NULL);
-
- /* Probe currently available pixel formats */
- available_caps = gst_caps_copy(self->probed_srccaps);
- GST_DEBUG_OBJECT(self, "Available caps: %" GST_PTR_FORMAT, available_caps);
-
- /* Replace coded size with visible size, we want to negotiate visible size
- * with downstream, not coded size. */
- gst_caps_map_in_place(available_caps, gst_aml_v4l2_video_remove_padding, self);
-
- filter = gst_caps_intersect_full(available_caps, acquired_caps, GST_CAPS_INTERSECT_FIRST);
- caps = gst_caps_copy(filter);
- gst_caps_set_features_simple(caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
- gst_caps_append(filter, caps);
-
- GST_DEBUG_OBJECT(self, "Filtered caps: %" GST_PTR_FORMAT, filter);
- gst_caps_unref(acquired_caps);
- gst_caps_unref(available_caps);
- caps = gst_pad_peer_query_caps(decoder->srcpad, filter);
- gst_caps_unref(filter);
-
- GST_DEBUG_OBJECT(self, "Possible decoded caps: %" GST_PTR_FORMAT, caps);
- if (gst_caps_is_empty(caps))
- {
- gst_caps_unref(caps);
- goto not_negotiated;
- }
-
- /* Fixate pixel format */
- caps = gst_caps_fixate(caps);
-
- GST_DEBUG_OBJECT(self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
-
- /* Try to set negotiated format, on success replace acquired format */
- if (gst_aml_v4l2_object_set_format(self->v4l2capture, caps, &error))
- gst_video_info_from_caps(&info, caps);
- else
- gst_aml_v4l2_clear_error(&error);
- gst_caps_unref(caps);
- gst_aml_v4l2_video_dec_set_output_status(decoder,info);
- if (!gst_aml_video_decoder_negotiate(decoder))
- {
- if (GST_PAD_IS_FLUSHING(decoder->srcpad))
- goto flushing;
- else
- goto not_negotiated;
- }
-
- /* Ensure our internal pool is activated */
- if (!gst_buffer_pool_set_active(GST_BUFFER_POOL(self->v4l2capture->pool),
- TRUE))
- goto activate_failed;
-
- //cal duration when got resolution event
- self->frame_duration = gst_aml_v4l2_video_dec_calc_duration(decoder);
-
- g_mutex_lock(&self->res_chg_lock);
- GST_LOG_OBJECT(decoder, "signal resolution changed");
- self->is_res_chg = FALSE;
- g_cond_signal(&self->res_chg_cond);
- g_mutex_unlock(&self->res_chg_lock);
+ gst_object_unref (peer);
+ }
}
- GST_LOG_OBJECT(decoder, "Allocate output buffer");
-
- v4l2_pool = GST_AML_V4L2_BUFFER_POOL(self->v4l2capture->pool);
-
- self->output_flow = GST_FLOW_OK;
- do
+ if (self->v4l2capture->need_drop_event)
{
- /* We cannot use the base class allotate helper since it taking the internal
- * stream lock. we know that the acquire may need to poll until more frames
- * comes in and holding this lock would prevent that.
- */
- pool = gst_aml_video_decoder_get_buffer_pool(decoder);
-
- /* Pool may be NULL if we started going to READY state */
- if (pool == NULL)
- {
- GST_WARNING_OBJECT(decoder, "gst_aml_video_decoder_get_buffer_pool goto beach");
- ret = GST_FLOW_FLUSHING;
- goto beach;
- }
-
- ret = gst_buffer_pool_acquire_buffer(pool, &buffer, NULL);
-
- g_object_unref(pool);
-
- if (ret == GST_FLOW_OK && GST_BUFFER_FLAG_IS_SET(buffer,GST_AML_V4L2_BUFFER_FLAG_LAST_EMPTY)) {
- GST_LOG_OBJECT(decoder, "Get GST_AML_V4L2_FLOW_LAST_BUFFER");
- self->v4l2capture->need_drop_event = TRUE;
- gst_aml_v4l2_buffer_pool_process(v4l2_pool, &buffer);
- if (self->is_res_chg) {
- //we must release last buffer
- gst_buffer_unref(buffer);
- //if resolution changed event received,we should set need_drop_event to false
- self->v4l2capture->need_drop_event = FALSE;
- gst_aml_v4l2_object_stop(self->v4l2capture);
- //unblock flush start event
- g_mutex_lock(&self->res_chg_lock);
- self->is_res_chg = FALSE;
- g_cond_signal(&self->res_chg_cond);
- g_mutex_unlock(&self->res_chg_lock);
- return;
- } else {
- goto beach;
- }
- }
-
- if (ret == GST_AML_V4L2_FLOW_CC_DATA)
- {
- GST_DEBUG_OBJECT(decoder, "already got cc data, just continue.");
- continue;
- }
-
- if (ret == GST_AML_V4L2_FLOW_UNKNOWN_EVENT)
- {
- GST_DEBUG_OBJECT(decoder, "unknow event, just continue.");
- continue;
- }
-
- if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
- {
- GST_LOG_OBJECT(decoder, "Get GST_AML_V4L2_FLOW_SOURCE_CHANGE");
-
- g_mutex_lock (&self->res_chg_lock);
- self->is_res_chg = TRUE;
- g_mutex_unlock (&self->res_chg_lock);
- return;
- }
-
- //decoding error happened
- if (ret == GST_AML_V4L2_FLOW_DECODING_ERROR)
- {
- GST_DEBUG("send error pts:%llu - %" GST_TIME_FORMAT, v4l2_pool->obj->error_frame_pts, GST_TIME_ARGS(v4l2_pool->obj->error_frame_pts));
- g_signal_emit (self, g_signals[SIGNAL_DECODED_ERROR_PTS], 0, v4l2_pool->obj->error_frame_pts, NULL);
- g_signal_emit (self, g_signals[SIGNAL_DECODED_PTS], 0, v4l2_pool->obj->error_frame_pts);
- continue;
- }
-
- if (ret != GST_FLOW_OK) {
- GST_WARNING_OBJECT(decoder, "gst_buffer_pool_acquire_buffer goto beach ret:%d",ret);
- goto beach;
- }
-
- GST_LOG_OBJECT(decoder, "Process output buffer (switching flow outstanding num:%d)", self->v4l2capture->outstanding_buf_num);
- ret = gst_aml_v4l2_buffer_pool_process(v4l2_pool, &buffer);
-
- GST_DEBUG_OBJECT(decoder, "decoded pts:%lld - %" GST_TIME_FORMAT, GST_BUFFER_PTS(buffer), GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
- g_signal_emit (self, g_signals[SIGNAL_DECODED_PTS], 0, GST_BUFFER_PTS(buffer));
-
- if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
- {
- gst_aml_v4l2_object_stop(self->v4l2capture);
- return;
- }
-
- } while ((ret == GST_AML_V4L2_FLOW_CORRUPTED_BUFFER) ||
- (ret == GST_AML_V4L2_FLOW_CC_DATA) ||
- (ret == GST_AML_V4L2_FLOW_UNKNOWN_EVENT) ||
- (ret == GST_AML_V4L2_FLOW_DECODING_ERROR));
-
- if (ret != GST_FLOW_OK)
- goto beach;
-
- if (!GST_BUFFER_PTS_IS_VALID (buffer)
- || (GST_BUFFER_TIMESTAMP(buffer) == 0 && self->v4l2capture->info.interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED))
- {
- GST_BUFFER_TIMESTAMP(buffer) = gst_aml_v4l2_video_dec_calc_output_buffer_pts(decoder);
+ // drop V4L2_EVENT_SOURCE_CHANGE
+ gst_v4l2_drop_event(self->v4l2capture);
+ self->v4l2capture->need_drop_event = FALSE;
}
- if (self->v4l2capture->info.interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED)
+ if (!gst_aml_v4l2_object_acquire_format (self->v4l2capture, &info))
+ goto not_negotiated;
+
+ /* Create caps from the acquired format, remove the format field */
+ acquired_caps = gst_video_info_to_caps (&info);
+ GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps);
+ st = gst_caps_get_structure (acquired_caps, 0);
+ gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", NULL);
+
+ /* Probe currently available pixel formats */
+ available_caps = gst_caps_copy (self->probed_srccaps);
+ GST_DEBUG_OBJECT (self, "Available caps: %" GST_PTR_FORMAT, available_caps);
+
+ /* Replace coded size with visible size, we want to negotiate visible size
+ * with downstream, not coded size. */
+ gst_caps_map_in_place (available_caps, gst_aml_v4l2_video_remove_padding, self);
+
+ filter = gst_caps_intersect_full (available_caps, acquired_caps, GST_CAPS_INTERSECT_FIRST);
+ caps = gst_caps_copy(filter);
+ gst_caps_set_features_simple(caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
+ gst_caps_append(filter, caps);
+
+ GST_DEBUG_OBJECT (self, "Filtered caps: %" GST_PTR_FORMAT, filter);
+ gst_caps_unref (acquired_caps);
+ gst_caps_unref (available_caps);
+ caps = gst_pad_peer_query_caps (decoder->srcpad, filter);
+ gst_caps_unref (filter);
+
+ GST_DEBUG_OBJECT (self, "Possible decoded caps: %" GST_PTR_FORMAT, caps);
+ if (gst_caps_is_empty (caps))
{
- GST_BUFFER_DURATION(buffer) = self->frame_duration; // got at resolution event.
- GST_BUFFER_FLAG_UNSET(buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ gst_caps_unref (caps);
+ goto not_negotiated;
}
- frame = gst_aml_v4l2_video_dec_get_right_frame(decoder, GST_BUFFER_TIMESTAMP (buffer));
- if (frame)
- {
- self->last_out_pts = GST_BUFFER_TIMESTAMP(buffer);
- frame->output_buffer = buffer;
- frame->pts = GST_BUFFER_TIMESTAMP(buffer);
- frame->duration = GST_BUFFER_DURATION(buffer);
+ /* Fixate pixel format */
+ caps = gst_caps_fixate (caps);
- buffer = NULL;
+ GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
- if (self->v4l2capture->enable_cc_data)
- {
- if (foreach_cc_buffer_list_match_pts_func(v4l2_pool->cc_buffer_list, frame))
- {
- GST_DEBUG("cc buffer and frame bind success");
- GstBuffer *cc_buffer = gst_mini_object_get_qdata (GST_MINI_OBJECT (frame->output_buffer),
- GST_AML_V4L2_CC_IMPORT_QUARK);
- #if 0
- //Debug code:dump cc data
- GstMapInfo gst_map;
- gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
- int fd=open("/data/test/cc2.data",O_RDWR |O_CREAT|O_APPEND,0777);
- if (gst_map.size>0)
- write(fd,gst_map.data,gst_map.size);
- close(fd);
- gst_buffer_unmap(cc_buffer,&gst_map);
- #endif
- v4l2_pool->cc_buffer_list = g_list_remove(v4l2_pool->cc_buffer_list,cc_buffer);
- gst_buffer_unref(cc_buffer);
- }
- else
- {
- GST_WARNING("bufferlist is empty or no match frame in the bufferlist");
- }
- }
- ret = gst_aml_video_decoder_finish_frame(decoder, frame);
-
- if (ret != GST_FLOW_OK)
- goto beach;
- }
+ /* Try to set negotiated format, on success replace acquired format */
+ if (gst_aml_v4l2_object_set_format (self->v4l2capture, caps, &error))
+ gst_video_info_from_caps (&info, caps);
else
+ gst_aml_v4l2_clear_error (&error);
+ gst_caps_unref (caps);
+ gst_aml_v4l2_video_dec_set_output_status(decoder,info);
+ if (!gst_aml_video_decoder_negotiate (decoder))
{
- GST_WARNING_OBJECT(decoder, "Unmatch buffer, should be push, need refine");
- //gst_pad_push (decoder->srcpad, buffer);
- gst_buffer_unref(buffer);
+ if (GST_PAD_IS_FLUSHING (decoder->srcpad))
+ goto flushing;
+ else
+ goto not_negotiated;
}
- return;
- /* ERRORS */
-not_negotiated:
-{
- GST_ERROR_OBJECT(self, "not negotiated");
- ret = GST_FLOW_NOT_NEGOTIATED;
- goto beach;
-}
-activate_failed:
-{
- GST_ERROR_OBJECT(self, "Buffer pool activation failed");
- GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
- (_("Failed to allocate required memory.")),
- ("Buffer pool activation failed"));
- ret = GST_FLOW_ERROR;
- goto beach;
-}
-flushing:
-{
- ret = GST_FLOW_FLUSHING;
- goto beach;
-}
-beach:
- GST_DEBUG_OBJECT(decoder, "Leaving output thread: %s",
- gst_flow_get_name(ret));
- if (self->is_res_chg) {
+ /* Ensure our internal pool is activated */
+ if (!gst_buffer_pool_set_active (GST_BUFFER_POOL (self->v4l2capture->pool),
+ TRUE))
+ goto activate_failed;
+
+ //cal duration when got resolution event
+ self->frame_duration = gst_aml_v4l2_video_dec_calc_duration(decoder);
+
+ g_mutex_lock(&self->res_chg_lock);
+ GST_LOG_OBJECT(decoder, "signal resolution changed");
+ self->is_res_chg = FALSE;
+ g_cond_signal(&self->res_chg_cond);
+ g_mutex_unlock(&self->res_chg_lock);
+ }
+
+ GST_LOG_OBJECT (decoder, "Allocate output buffer");
+ v4l2_pool = GST_AML_V4L2_BUFFER_POOL(self->v4l2capture->pool);
+
+ self->output_flow = GST_FLOW_OK;
+ do
+ {
+ /* We cannot use the base class allotate helper since it taking the internal
+ * stream lock. we know that the acquire may need to poll until more frames
+ * comes in and holding this lock would prevent that.
+ */
+ pool = gst_aml_video_decoder_get_buffer_pool (decoder);
+
+ /* Pool may be NULL if we started going to READY state */
+ if (pool == NULL)
+ {
+ GST_WARNING_OBJECT(decoder, "gst_aml_video_decoder_get_buffer_pool goto beach");
+ ret = GST_FLOW_FLUSHING;
+ goto beach;
+ }
+
+ ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
+
+ g_object_unref (pool);
+
+ if (ret == GST_FLOW_OK && GST_BUFFER_FLAG_IS_SET(buffer,GST_AML_V4L2_BUFFER_FLAG_LAST_EMPTY)) {
+ GST_LOG_OBJECT(decoder, "Get GST_AML_V4L2_FLOW_LAST_BUFFER");
+ self->v4l2capture->need_drop_event = TRUE;
+ gst_aml_v4l2_buffer_pool_process(v4l2_pool, &buffer);
+ if (self->is_res_chg) {
+ //we must release last buffer
+ gst_buffer_unref(buffer);
+ //if resolution changed event received,we should set need_drop_event to false
+ self->v4l2capture->need_drop_event = FALSE;
+ gst_aml_v4l2_object_stop(self->v4l2capture);
//unblock flush start event
g_mutex_lock(&self->res_chg_lock);
self->is_res_chg = FALSE;
g_cond_signal(&self->res_chg_cond);
g_mutex_unlock(&self->res_chg_lock);
+ return;
+ } else {
+ goto beach;
+ }
}
- gst_buffer_replace(&buffer, NULL);
- self->output_flow = ret;
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- gst_pad_pause_task(decoder->srcpad);
+
+ if (ret == GST_AML_V4L2_FLOW_CC_DATA)
+ {
+ GST_DEBUG_OBJECT(decoder, "already got cc data, just continue.");
+ continue;
+ }
+
+ if (ret == GST_AML_V4L2_FLOW_UNKNOWN_EVENT)
+ {
+ GST_DEBUG_OBJECT(decoder, "unknow event, just continue.");
+ continue;
+ }
+
+ if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
+ {
+ GST_LOG_OBJECT(decoder, "Get GST_AML_V4L2_FLOW_SOURCE_CHANGE");
+
+ g_mutex_lock (&self->res_chg_lock);
+ self->is_res_chg = TRUE;
+ g_mutex_unlock (&self->res_chg_lock);
+ return;
+ }
+
+ //decoding error happened
+ if (ret == GST_AML_V4L2_FLOW_DECODING_ERROR)
+ {
+ GST_DEBUG("send error pts:%llu - %" GST_TIME_FORMAT, v4l2_pool->obj->error_frame_pts, GST_TIME_ARGS(v4l2_pool->obj->error_frame_pts));
+ g_signal_emit (self, g_signals[SIGNAL_DECODED_ERROR_PTS], 0, v4l2_pool->obj->error_frame_pts, NULL);
+ g_signal_emit (self, g_signals[SIGNAL_DECODED_PTS], 0, v4l2_pool->obj->error_frame_pts);
+ continue;
+ }
+
+ if (ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT(decoder, "gst_buffer_pool_acquire_buffer goto beach ret:%d",ret);
+ goto beach;
+ }
+
+ GST_LOG_OBJECT(decoder, "Process output buffer (switching flow outstanding num:%d)", self->v4l2capture->outstanding_buf_num);
+ ret = gst_aml_v4l2_buffer_pool_process(v4l2_pool, &buffer);
+
+ GST_DEBUG_OBJECT(decoder, "decoded pts:%lld - %" GST_TIME_FORMAT, GST_BUFFER_PTS(buffer), GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
+ g_signal_emit (self, g_signals[SIGNAL_DECODED_PTS], 0, GST_BUFFER_PTS(buffer));
+
+ if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
+ {
+ gst_aml_v4l2_object_stop (self->v4l2capture);
+ return;
+ }
+
+ } while ((ret == GST_AML_V4L2_FLOW_CORRUPTED_BUFFER) ||
+ (ret == GST_AML_V4L2_FLOW_CC_DATA) ||
+ (ret == GST_AML_V4L2_FLOW_UNKNOWN_EVENT) ||
+ (ret == GST_AML_V4L2_FLOW_DECODING_ERROR));
+
+ if (ret != GST_FLOW_OK)
+ goto beach;
+
+ if (!GST_BUFFER_PTS_IS_VALID (buffer)
+ || (GST_BUFFER_TIMESTAMP(buffer) == 0 && self->v4l2capture->info.interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED))
+ {
+ GST_BUFFER_TIMESTAMP(buffer) = gst_aml_v4l2_video_dec_calc_output_buffer_pts(decoder);
+ }
+
+ if (self->v4l2capture->info.interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED)
+ {
+ GST_BUFFER_DURATION(buffer) = self->frame_duration; // got at resolution event.
+ GST_BUFFER_FLAG_UNSET(buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ }
+
+ frame = gst_aml_v4l2_video_dec_get_right_frame(decoder, GST_BUFFER_TIMESTAMP (buffer));
+ if (frame)
+ {
+ self->last_out_pts = GST_BUFFER_TIMESTAMP(buffer);
+ frame->output_buffer = buffer;
+ frame->pts = GST_BUFFER_TIMESTAMP(buffer);
+ frame->duration = GST_BUFFER_DURATION(buffer);
+
+ buffer = NULL;
+
+ if (self->v4l2capture->enable_cc_data)
+ {
+ if (foreach_cc_buffer_list_match_pts_func(v4l2_pool->cc_buffer_list, frame))
+ {
+ GST_DEBUG("cc buffer and frame bind success");
+ GstBuffer *cc_buffer = gst_mini_object_get_qdata (GST_MINI_OBJECT (frame->output_buffer),
+ GST_AML_V4L2_CC_IMPORT_QUARK);
+ #if 0
+ //Debug code:dump cc data
+ GstMapInfo gst_map;
+ gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
+ int fd=open("/data/test/cc2.data",O_RDWR |O_CREAT|O_APPEND,0777);
+ if (gst_map.size>0)
+ write(fd,gst_map.data,gst_map.size);
+ close(fd);
+ gst_buffer_unmap(cc_buffer,&gst_map);
+ #endif
+ v4l2_pool->cc_buffer_list = g_list_remove(v4l2_pool->cc_buffer_list,cc_buffer);
+ gst_buffer_unref(cc_buffer);
+ }
+ else
+ {
+ GST_WARNING("bufferlist is empty or no match frame in the bufferlist");
+ }
+ }
+ ret = gst_aml_video_decoder_finish_frame (decoder, frame);
+
+ if (ret != GST_FLOW_OK)
+ goto beach;
+ }
+ else
+ {
+ GST_WARNING_OBJECT(decoder, "Unmatch buffer, should be push, need refine");
+ //gst_pad_push (decoder->srcpad, buffer);
+ gst_buffer_unref (buffer);
+ }
+
+ return;
+ /* ERRORS */
+not_negotiated:
+ {
+ GST_ERROR_OBJECT (self, "not negotiated");
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ goto beach;
+ }
+activate_failed:
+ {
+ GST_ERROR_OBJECT (self, "Buffer pool activation failed");
+ GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ (_("Failed to allocate required memory.")),
+ ("Buffer pool activation failed"));
+ ret = GST_FLOW_ERROR;
+ goto beach;
+ }
+flushing:
+ {
+ ret = GST_FLOW_FLUSHING;
+ goto beach;
+ }
+beach:
+ GST_DEBUG_OBJECT (decoder, "Leaving output thread: %s",
+ gst_flow_get_name (ret));
+ if (self->is_res_chg) {
+ //unblock flush start event
+ g_mutex_lock(&self->res_chg_lock);
+ self->is_res_chg = FALSE;
+ g_cond_signal(&self->res_chg_cond);
+ g_mutex_unlock(&self->res_chg_lock);
+ }
+ gst_buffer_replace (&buffer, NULL);
+ self->output_flow = ret;
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ gst_pad_pause_task (decoder->srcpad);
}
static GstFlowReturn
-gst_aml_v4l2_video_dec_handle_frame(GstAmlVideoDecoder *decoder,
- GstAmlVideoCodecFrame *frame)
+gst_aml_v4l2_video_dec_handle_frame (GstAmlVideoDecoder * decoder,
+ GstAmlVideoCodecFrame * frame)
{
- GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstBufferPool *pool = GST_BUFFER_POOL(self->v4l2output->pool);
- GstFlowReturn ret = GST_FLOW_OK;
- gboolean processed = FALSE;
- GstBuffer *tmp;
- GstTaskState task_state;
+ GstAmlV4l2Error error = GST_AML_V4L2_ERROR_INIT;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstBufferPool *pool = GST_BUFFER_POOL(self->v4l2output->pool);
+ GstFlowReturn ret = GST_FLOW_OK;
+ gboolean processed = FALSE;
+ GstBuffer *tmp;
+ GstTaskState task_state;
- GST_DEBUG_OBJECT(self, "Handling frame %d", frame->system_frame_number);
+ GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
- if (G_UNLIKELY(!g_atomic_int_get(&self->active)))
- goto flushing;
+ if (G_UNLIKELY (!g_atomic_int_get (&self->active)))
+ goto flushing;
- if (G_UNLIKELY(!GST_CLOCK_TIME_IS_VALID(self->frame_duration)))
- self->frame_duration = frame->duration;
+ if (G_UNLIKELY(!GST_CLOCK_TIME_IS_VALID(self->frame_duration)))
+ self->frame_duration = frame->duration;
- if (G_UNLIKELY(!GST_AML_V4L2_IS_ACTIVE(self->v4l2output)))
+ if (G_UNLIKELY (!GST_AML_V4L2_IS_ACTIVE (self->v4l2output)))
+ {
+ if (!self->input_state)
+ goto not_negotiated;
+ if (!gst_aml_v4l2_object_set_format (self->v4l2output, self->input_state->caps,
+ &error))
+ goto not_negotiated;
+ }
+
+ if (G_UNLIKELY (!GST_AML_V4L2_IS_ACTIVE (self->v4l2capture)))
+ {
+ GstBuffer *codec_data;
+ GstCapsFeatures *features = NULL;
+
+ features = gst_caps_get_features(self->input_state->caps, 0);
+ if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF) && self->v4l2output->secure_es)
{
- if (!self->input_state)
- goto not_negotiated;
- if (!gst_aml_v4l2_object_set_format(self->v4l2output, self->input_state->caps,
- &error))
- goto not_negotiated;
+ GST_DEBUG_OBJECT(self, "Is SVP");
+ //TODO:need rm is_svp flag and just using secure_es flag
+ self->v4l2output->is_svp = TRUE;
}
- if (G_UNLIKELY(!GST_AML_V4L2_IS_ACTIVE(self->v4l2capture)))
+ GST_DEBUG_OBJECT (self, "Sending header");
+
+ codec_data = self->input_state->codec_data;
+
+ /* We are running in byte-stream mode, so we don't know the headers, but
+ * we need to send something, otherwise the decoder will refuse to
+ * initialize.
+ */
+ if (codec_data)
{
- GstBuffer *codec_data;
- GstCapsFeatures *features = NULL;
-
- features = gst_caps_get_features(self->input_state->caps, 0);
- if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF) && self->v4l2output->secure_es)
- {
- GST_DEBUG_OBJECT(self, "Is SVP");
- //TODO:need rm is_svp flag and just using secure_es flag
- self->v4l2output->is_svp = TRUE;
- }
-
- GST_DEBUG_OBJECT(self, "Sending header");
-
- codec_data = self->input_state->codec_data;
-
- /* We are running in byte-stream mode, so we don't know the headers, but
- * we need to send something, otherwise the decoder will refuse to
- * intialize.
- */
- if (codec_data)
- {
- gst_buffer_ref(codec_data);
- }
- else
- {
- codec_data = gst_buffer_ref(frame->input_buffer);
- processed = TRUE;
- }
-
- /* Ensure input internal pool is active */
- if (!gst_buffer_pool_is_active(pool))
- {
- GstStructure *config = gst_buffer_pool_get_config(pool);
- // guint min = MAX(self->v4l2output->min_buffers, GST_AML_V4L2_MIN_BUFFERS);
- // guint max = VIDEO_MAX_FRAME;
- // gst_buffer_pool_config_set_params (config, self->input_state->caps,
- // self->v4l2output->info.size, min, max);
- gst_buffer_pool_config_set_params(config, self->input_state->caps, self->v4l2output->info.size, self->v4l2output->min_buffers, self->v4l2output->min_buffers);
-
- /* There is no reason to refuse this config */
- if (!gst_buffer_pool_set_config(pool, config))
- goto activate_failed;
- GST_DEBUG_OBJECT(self, "setting output pool config to %" GST_PTR_FORMAT, config);
-
- if (!gst_buffer_pool_set_active(pool, TRUE))
- goto activate_failed;
- }
-
- GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
- ret =
- gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &codec_data);
- self->codec_data_inject = TRUE;
- GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
-
- gst_buffer_unref(codec_data);
-
- /* For decoders G_FMT returns coded size, G_SELECTION returns visible size
- * in the compose rectangle. gst_aml_v4l2_object_acquire_format() checks both
- * and returns the visible size as with/height and the coded size as
- * padding. */
- }
-
- task_state = gst_pad_get_task_state(GST_AML_VIDEO_DECODER_SRC_PAD(self));
- if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED)
- {
- /* It's possible that the processing thread stopped due to an error */
- if (self->output_flow != GST_FLOW_OK &&
- self->output_flow != GST_FLOW_FLUSHING)
- {
- GST_DEBUG_OBJECT(self, "Processing loop stopped with error, leaving");
- ret = self->output_flow;
- goto drop;
- }
-
- GST_DEBUG_OBJECT(self, "Starting decoding thread");
-
- /* Start the processing task, when it quits, the task will disable input
- * processing to unlock input if draining, or prevent potential block */
- self->output_flow = GST_FLOW_FLUSHING;
- /*reset poll and need_drop_event before start decoding loop thread*/
- self->v4l2capture->need_drop_event = FALSE;
- gst_poll_set_flushing(self->v4l2capture->poll, FALSE);
- if (!gst_pad_start_task(decoder->srcpad,
- (GstTaskFunction)gst_aml_v4l2_video_dec_loop, self, NULL))
- goto start_task_failed;
- }
-
- if (!processed)
- {
- GST_AML_VIDEO_DECODER_STREAM_UNLOCK(decoder);
- if (!self->codec_data_inject && self->input_state->codec_data)
- {
- ret = gst_aml_v4l2_buffer_pool_process
- (GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &self->input_state->codec_data);
- self->codec_data_inject = TRUE;
- if (ret != GST_FLOW_OK)
- goto send_codec_failed;
- }
- ret =
- gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &frame->input_buffer);
- GST_AML_VIDEO_DECODER_STREAM_LOCK(decoder);
-
- if (ret == GST_FLOW_FLUSHING)
- {
- if (gst_pad_get_task_state(GST_AML_VIDEO_DECODER_SRC_PAD(self)) !=
- GST_TASK_STARTED)
- ret = self->output_flow;
- goto drop;
- }
- else if (ret != GST_FLOW_OK)
- {
- goto process_failed;
- }
- }
-
- /* No need to keep input arround */
- tmp = frame->input_buffer;
- frame->input_buffer = gst_buffer_new();
- gst_buffer_copy_into(frame->input_buffer, tmp,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
- GST_BUFFER_COPY_META,
- 0, 0);
- gst_buffer_unref(tmp);
-
- gst_aml_video_codec_frame_unref(frame);
- return ret;
-
- /* ERRORS */
-send_codec_failed:
- GST_ERROR_OBJECT(self, "send codec_date fialed.ret is %d",ret);
- goto drop;
-not_negotiated:
-{
- GST_ERROR_OBJECT(self, "not negotiated");
- ret = GST_FLOW_NOT_NEGOTIATED;
- gst_aml_v4l2_error(self, &error);
- goto drop;
-}
-activate_failed:
-{
- GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
- (_("Failed to allocate required memory.")),
- ("Buffer pool activation failed"));
- ret = GST_FLOW_ERROR;
- goto drop;
-}
-flushing:
-{
- ret = GST_FLOW_FLUSHING;
- goto drop;
-}
-
-start_task_failed:
-{
- GST_ELEMENT_ERROR(self, RESOURCE, FAILED,
- (_("Failed to start decoding thread.")), (NULL));
- ret = GST_FLOW_ERROR;
- goto drop;
-}
-process_failed:
-{
- GST_ELEMENT_ERROR(self, RESOURCE, FAILED,
- (_("Failed to process frame.")),
- ("Maybe be due to not enough memory or failing driver"));
- ret = GST_FLOW_ERROR;
- goto drop;
-}
-drop:
-{
- gst_aml_video_decoder_drop_frame(decoder, frame);
- return ret;
-}
-}
-
-static gboolean
-gst_aml_v4l2_video_dec_decide_allocation(GstAmlVideoDecoder *decoder,
- GstQuery *query)
-{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstClockTime latency;
- gboolean ret = FALSE;
-
- if (gst_aml_v4l2_object_decide_allocation(self->v4l2capture, query))
- ret = GST_AML_VIDEO_DECODER_CLASS(parent_class)->decide_allocation(decoder, query);
-
- if (GST_CLOCK_TIME_IS_VALID(self->v4l2capture->duration))
- {
- latency = self->v4l2capture->min_buffers * self->v4l2capture->duration;
- GST_DEBUG_OBJECT(self, "Setting latency: %" GST_TIME_FORMAT " (%" G_GUINT32_FORMAT " * %" G_GUINT64_FORMAT, GST_TIME_ARGS(latency),
- self->v4l2capture->min_buffers, self->v4l2capture->duration);
- gst_aml_video_decoder_set_latency(decoder, latency, latency);
+ gst_buffer_ref (codec_data);
}
else
{
- GST_WARNING_OBJECT(self, "Duration invalid, not setting latency");
+ codec_data = gst_buffer_ref (frame->input_buffer);
+ processed = TRUE;
}
+ /* Ensure input internal pool is active */
+ if (!gst_buffer_pool_is_active (pool))
+ {
+ GstStructure *config = gst_buffer_pool_get_config (pool);
+ // guint min = MAX(self->v4l2output->min_buffers, GST_AML_V4L2_MIN_BUFFERS);
+ // guint max = VIDEO_MAX_FRAME;
+ // gst_buffer_pool_config_set_params (config, self->input_state->caps,
+ // self->v4l2output->info.size, min, max);
+ gst_buffer_pool_config_set_params(config, self->input_state->caps, self->v4l2output->info.size, self->v4l2output->min_buffers, self->v4l2output->min_buffers);
+
+ /* There is no reason to refuse this config */
+ if (!gst_buffer_pool_set_config (pool, config))
+ goto activate_failed;
+ GST_DEBUG_OBJECT(self, "setting output pool config to %" GST_PTR_FORMAT, config);
+
+ if (!gst_buffer_pool_set_active (pool, TRUE))
+ goto activate_failed;
+ }
+
+ GST_AML_VIDEO_DECODER_STREAM_UNLOCK (decoder);
+ ret =
+ gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &codec_data);
+ self->codec_data_inject = TRUE;
+ GST_AML_VIDEO_DECODER_STREAM_LOCK (decoder);
+
+ gst_buffer_unref (codec_data);
+
+ /* For decoders G_FMT returns coded size, G_SELECTION returns visible size
+ * in the compose rectangle. gst_aml_v4l2_object_acquire_format() checks both
+ * and returns the visible size as with/height and the coded size as
+ * padding. */
+ }
+
+ task_state = gst_pad_get_task_state (GST_AML_VIDEO_DECODER_SRC_PAD (self));
+ if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED)
+ {
+ /* It's possible that the processing thread stopped due to an error */
+ if (self->output_flow != GST_FLOW_OK &&
+ self->output_flow != GST_FLOW_FLUSHING)
+ {
+ GST_DEBUG_OBJECT (self, "Processing loop stopped with error, leaving");
+ ret = self->output_flow;
+ goto drop;
+ }
+
+ GST_DEBUG_OBJECT (self, "Starting decoding thread");
+
+ /* Start the processing task, when it quits, the task will disable input
+ * processing to unlock input if draining, or prevent potential block */
+ self->output_flow = GST_FLOW_FLUSHING;
+ /*reset poll and need_drop_event before start decoding loop thread*/
+ self->v4l2capture->need_drop_event = FALSE;
+ gst_poll_set_flushing(self->v4l2capture->poll, FALSE);
+ if (!gst_pad_start_task(decoder->srcpad,
+ (GstTaskFunction) gst_aml_v4l2_video_dec_loop, self, NULL))
+ goto start_task_failed;
+ }
+
+ if (!processed)
+ {
+ GST_AML_VIDEO_DECODER_STREAM_UNLOCK (decoder);
+ if (!self->codec_data_inject && self->input_state->codec_data)
+ {
+ ret = gst_aml_v4l2_buffer_pool_process
+ (GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &self->input_state->codec_data);
+ self->codec_data_inject = TRUE;
+ if (ret != GST_FLOW_OK)
+ goto send_codec_failed;
+ }
+ ret =
+ gst_aml_v4l2_buffer_pool_process(GST_AML_V4L2_BUFFER_POOL(self->v4l2output->pool), &frame->input_buffer);
+ GST_AML_VIDEO_DECODER_STREAM_LOCK (decoder);
+
+ if (ret == GST_FLOW_FLUSHING)
+ {
+ if (gst_pad_get_task_state (GST_AML_VIDEO_DECODER_SRC_PAD (self)) !=
+ GST_TASK_STARTED)
+ ret = self->output_flow;
+ goto drop;
+ }
+ else if (ret != GST_FLOW_OK)
+ {
+ goto process_failed;
+ }
+ }
+
+ /* No need to keep input around */
+ tmp = frame->input_buffer;
+ frame->input_buffer = gst_buffer_new ();
+ gst_buffer_copy_into (frame->input_buffer, tmp,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
+ GST_BUFFER_COPY_META, 0, 0);
+ gst_buffer_unref (tmp);
+
+ gst_aml_video_codec_frame_unref (frame);
+ return ret;
+
+ /* ERRORS */
+send_codec_failed:
+ GST_ERROR_OBJECT(self, "send codec_date fialed.ret is %d",ret);
+ goto drop;
+not_negotiated:
+ {
+ GST_ERROR_OBJECT (self, "not negotiated");
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ gst_aml_v4l2_error (self, &error);
+ goto drop;
+ }
+activate_failed:
+ {
+ GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ (_("Failed to allocate required memory.")),
+ ("Buffer pool activation failed"));
+ ret = GST_FLOW_ERROR;
+ goto drop;
+ }
+flushing:
+ {
+ ret = GST_FLOW_FLUSHING;
+ goto drop;
+ }
+
+start_task_failed:
+ {
+ GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
+ (_("Failed to start decoding thread.")), (NULL));
+ ret = GST_FLOW_ERROR;
+ goto drop;
+ }
+process_failed:
+ {
+ GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
+ (_("Failed to process frame.")),
+ ("Maybe be due to not enough memory or failing driver"));
+ ret = GST_FLOW_ERROR;
+ goto drop;
+ }
+drop:
+ {
+ gst_aml_video_decoder_drop_frame (decoder, frame);
return ret;
+ }
+}
+
+static gboolean
+gst_aml_v4l2_video_dec_decide_allocation (GstAmlVideoDecoder * decoder,
+ GstQuery * query)
+{
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (decoder);
+ GstClockTime latency;
+ gboolean ret = FALSE;
+
+ if (gst_aml_v4l2_object_decide_allocation (self->v4l2capture, query))
+ ret = GST_AML_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder, query);
+
+ if (GST_CLOCK_TIME_IS_VALID (self->v4l2capture->duration))
+ {
+ latency = self->v4l2capture->min_buffers * self->v4l2capture->duration;
+ GST_DEBUG_OBJECT (self, "Setting latency: %" GST_TIME_FORMAT " (%"
+ G_GUINT32_FORMAT " * %" G_GUINT64_FORMAT, GST_TIME_ARGS (latency),
+ self->v4l2capture->min_buffers, self->v4l2capture->duration);
+ gst_aml_video_decoder_set_latency (decoder, latency, latency);
+ }
+ else
+ {
+ GST_WARNING_OBJECT (self, "Duration invalid, not setting latency");
+ }
+
+ return ret;
}
static gboolean
gst_aml_v4l2_video_dec_src_query(GstAmlVideoDecoder *decoder, GstQuery *query)
{
- gboolean ret = TRUE;
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ gboolean ret = TRUE;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (decoder);
- switch (GST_QUERY_TYPE(query))
- {
+ switch (GST_QUERY_TYPE (query))
+ {
case GST_QUERY_CAPS:
{
- GstCaps *filter, *result = NULL;
- GstPad *pad = GST_AML_VIDEO_DECODER_SRC_PAD(decoder);
+ GstCaps *filter, *result = NULL;
+ GstPad *pad = GST_AML_VIDEO_DECODER_SRC_PAD (decoder);
- gst_query_parse_caps(query, &filter);
+ gst_query_parse_caps (query, &filter);
- if (self->probed_srccaps)
- result = gst_caps_ref(self->probed_srccaps);
- else
- result = gst_pad_get_pad_template_caps(pad);
+ if (self->probed_srccaps)
+ result = gst_caps_ref (self->probed_srccaps);
+ else
+ result = gst_pad_get_pad_template_caps (pad);
- if (filter)
- {
- GstCaps *tmp = result;
- result =
- gst_caps_intersect_full(filter, tmp, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref(tmp);
- }
+ if (filter)
+ {
+ GstCaps *tmp = result;
+ result =
+ gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (tmp);
+ }
- GST_DEBUG_OBJECT(self, "Returning src caps %" GST_PTR_FORMAT, result);
+ GST_DEBUG_OBJECT (self, "Returning src caps %" GST_PTR_FORMAT, result);
- gst_query_set_caps_result(query, result);
- gst_caps_unref(result);
- break;
+ gst_query_set_caps_result (query, result);
+ gst_caps_unref (result);
+ break;
}
default:
- ret = GST_AML_VIDEO_DECODER_CLASS(parent_class)->src_query(decoder, query);
- break;
- }
+ ret = GST_AML_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
+ break;
+ }
- return ret;
+ return ret;
}
static GstCaps *
gst_aml_v4l2_video_dec_sink_getcaps(GstAmlVideoDecoder *decoder, GstCaps *filter)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- GstCaps *result;
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
+ GstCaps *result;
- result = gst_aml_video_decoder_proxy_getcaps(decoder, self->probed_sinkcaps,
- filter);
+ result = gst_aml_video_decoder_proxy_getcaps (decoder, self->probed_sinkcaps,
+ filter);
- GST_DEBUG_OBJECT(self, "Returning sink caps %" GST_PTR_FORMAT, result);
+ GST_DEBUG_OBJECT (self, "Returning sink caps %" GST_PTR_FORMAT, result);
- return result;
+ return result;
}
static gboolean
-gst_aml_v4l2_video_dec_sink_event(GstAmlVideoDecoder *decoder, GstEvent *event)
+gst_aml_v4l2_video_dec_sink_event (GstAmlVideoDecoder *decoder, GstEvent *event)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(decoder);
- gboolean ret;
- GstEventType type = GST_EVENT_TYPE(event);
- GST_DEBUG_OBJECT (self, "received event %p %" GST_PTR_FORMAT, event, event);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (decoder);
+ gboolean ret;
+ GstEventType type = GST_EVENT_TYPE (event);
+ GST_DEBUG_OBJECT (self, "received event %p %" GST_PTR_FORMAT, event, event);
- switch (type)
- {
+ switch (type)
+ {
case GST_EVENT_STREAM_START:
{
- GstStructure *s;
- GstEvent *event;
- s = gst_structure_new("private_signal", "obj_ptr", G_TYPE_POINTER, self, "sig_name", G_TYPE_STRING, "decoded-pts", NULL);
- event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s);
- GST_DEBUG_OBJECT(self, "before Send private_signal Event :%p", event);
- gst_pad_push_event (decoder->sinkpad, event);
- GST_DEBUG_OBJECT(self, "after Send private_signal Event :%p", event);
- break;
+ GstStructure *s;
+ GstEvent *event;
+ s = gst_structure_new("private_signal", "obj_ptr", G_TYPE_POINTER, self, "sig_name", G_TYPE_STRING, "decoded-pts", NULL);
+ event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s);
+ GST_DEBUG_OBJECT(self, "before Send private_signal Event :%p", event);
+ gst_pad_push_event (decoder->sinkpad, event);
+ GST_DEBUG_OBJECT(self, "after Send private_signal Event :%p", event);
+ break;
}
case GST_EVENT_CAPS:
{
- GstCaps *caps;
- GstStructure *structure;
- gint num, denom;
+ GstCaps *caps;
+ GstStructure *structure;
+ gint num, denom;
- gst_event_parse_caps (event, &caps);
+ gst_event_parse_caps (event, &caps);
- structure= gst_caps_get_structure(caps, 0);
- if ( gst_structure_has_field(structure, "parsed") )
+ structure= gst_caps_get_structure(caps, 0);
+ if ( gst_structure_has_field(structure, "parsed") )
+ {
+ gboolean parsed = TRUE;
+ if ( gst_structure_get_boolean( structure, "parsed", &parsed ) )
{
- gboolean parsed = TRUE;
- if ( gst_structure_get_boolean( structure, "parsed", &parsed ) )
- {
- self->v4l2output->stream_mode = !parsed;
- GST_DEBUG("frame parsed:%d, set stream_mode to %d", parsed, self->v4l2output->stream_mode);
- }
+ self->v4l2output->stream_mode = !parsed;
+ GST_DEBUG("frame parsed:%d, set stream_mode to %d", parsed, self->v4l2output->stream_mode);
+ }
+ }
+
+ if ( gst_structure_has_field(structure, "secure") )
+ {
+ gboolean is_secure = FALSE;
+ if ( gst_structure_get_boolean( structure, "secure", &is_secure ) )
+ {
+ self->v4l2output->secure_es = is_secure;
+ GST_DEBUG("is secure es:%d", self->v4l2output->secure_es);
+ }
+ }
+ else
+ {
+ GstCapsFeatures *const features = gst_caps_get_features(caps, 0);
+ if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF))
+ {
+ self->v4l2output->secure_es = TRUE;
+ GST_DEBUG("If there is no secure field in caps, consider dma es is secure");
+ }
+ }
+
+ if ( gst_structure_get_fraction( structure, "framerate", &num, &denom ) )
+ {
+ if ( denom == 0 ) denom= 1;
+
+ if (self->v4l2capture->fps)
+ {
+ g_value_unset(self->v4l2capture->fps);
+ g_free(self->v4l2capture->fps);
}
- if ( gst_structure_has_field(structure, "secure") )
+ self->v4l2capture->fps = g_new0(GValue, 1);
+ g_value_init(self->v4l2capture->fps, GST_TYPE_FRACTION);
+ gst_value_set_fraction(self->v4l2capture->fps, num, denom);
+
+ GST_DEBUG_OBJECT(self, "get framerate ratio %d:%d", num, denom);
+ }
+
+ if (( gst_structure_get_fraction( structure, "pixel-aspect-ratio", &num, &denom ) ) &&
+ ( !self->v4l2capture->have_set_par ) )
+ {
+ if ( (num <= 0) || (denom <= 0) )
{
- gboolean is_secure = FALSE;
- if ( gst_structure_get_boolean( structure, "secure", &is_secure ) )
- {
- self->v4l2output->secure_es = is_secure;
- GST_DEBUG("is secure es:%d", self->v4l2output->secure_es);
- }
- }
- else
- {
- GstCapsFeatures *const features = gst_caps_get_features(caps, 0);
- if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_DMABUF))
- {
- self->v4l2output->secure_es = TRUE;
- GST_DEBUG("If there is no secure field in caps, consider dma es is secure");
- }
+ num= denom= 1;
}
- if ( gst_structure_get_fraction( structure, "framerate", &num, &denom ) )
+ if ( self->v4l2capture->par )
{
- if ( denom == 0 ) denom= 1;
-
- if (self->v4l2capture->fps)
- {
- g_value_unset(self->v4l2capture->fps);
- g_free(self->v4l2capture->fps);
- }
-
- self->v4l2capture->fps = g_new0(GValue, 1);
- g_value_init(self->v4l2capture->fps, GST_TYPE_FRACTION);
- gst_value_set_fraction(self->v4l2capture->fps, num, denom);
-
- GST_DEBUG_OBJECT(self, "get framerate ratio %d:%d", num, denom);
+ g_value_unset(self->v4l2capture->par);
+ g_free(self->v4l2capture->par);
}
- if (( gst_structure_get_fraction( structure, "pixel-aspect-ratio", &num, &denom ) ) &&
- ( !self->v4l2capture->have_set_par ) )
- {
- if ( (num <= 0) || (denom <= 0) )
- {
- num= denom= 1;
- }
-
- if ( self->v4l2capture->par )
- {
- g_value_unset(self->v4l2capture->par);
- g_free(self->v4l2capture->par);
- }
-
- self->v4l2capture->par = g_new0(GValue, 1);
- g_value_init(self->v4l2capture->par, GST_TYPE_FRACTION);
- gst_value_set_fraction(self->v4l2capture->par, num, denom);
- GST_DEBUG_OBJECT(self, "get pixel aspect ratio %d:%d", num, denom);
- }
- break;
+ self->v4l2capture->par = g_new0(GValue, 1);
+ g_value_init(self->v4l2capture->par, GST_TYPE_FRACTION);
+ gst_value_set_fraction(self->v4l2capture->par, num, denom);
+ GST_DEBUG_OBJECT(self, "get pixel aspect ratio %d:%d", num, denom);
+ }
+ break;
}
case GST_EVENT_FLUSH_START:
- GST_DEBUG_OBJECT(self, "flush start");
+ GST_DEBUG_OBJECT (self, "flush start");
- g_mutex_lock (&self->res_chg_lock);
- while (self->is_res_chg)
- {
- GST_LOG_OBJECT(decoder, "wait resolution change finish");
- g_cond_wait(&self->res_chg_cond, &self->res_chg_lock);
- }
- g_mutex_unlock (&self->res_chg_lock);
+ g_mutex_lock (&self->res_chg_lock);
+ while (self->is_res_chg)
+ {
+ GST_LOG_OBJECT(decoder, "wait resolution change finish");
+ g_cond_wait(&self->res_chg_cond, &self->res_chg_lock);
+ }
+ g_mutex_unlock (&self->res_chg_lock);
- self->last_out_pts = GST_CLOCK_TIME_NONE;
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- gst_aml_v4l2_object_flush_start(self->v4l2capture);
- break;
+ self->last_out_pts = GST_CLOCK_TIME_NONE;
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ gst_aml_v4l2_object_flush_start (self->v4l2capture);
+ break;
default:
- break;
- }
+ break;
+ }
- ret = GST_AML_VIDEO_DECODER_CLASS(parent_class)->sink_event(decoder, event);
+ ret = GST_AML_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event);
- switch (type)
- {
+ switch (type)
+ {
case GST_EVENT_FLUSH_START:
- /* The processing thread should stop now, wait for it */
- gst_pad_stop_task(decoder->srcpad);
- self->codec_data_inject = FALSE;
- GST_DEBUG_OBJECT(self, "flush start done");
- break;
+ /* The processing thread should stop now, wait for it */
+ gst_pad_stop_task (decoder->srcpad);
+ self->codec_data_inject = FALSE;
+ GST_DEBUG_OBJECT (self, "flush start done");
+ break;
default:
- break;
- }
+ break;
+ }
- return ret;
+ return ret;
}
static GstStateChangeReturn
-gst_aml_v4l2_video_dec_change_state(GstElement *element,
- GstStateChange transition)
+gst_aml_v4l2_video_dec_change_state (GstElement * element,
+ GstStateChange transition)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(element);
- GstAmlVideoDecoder *decoder = GST_AML_VIDEO_DECODER(element);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(element);
+ GstAmlVideoDecoder *decoder = GST_AML_VIDEO_DECODER(element);
- GST_DEBUG_OBJECT(element, "change state from %s to %s",
- gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
- gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
+ GST_DEBUG_OBJECT(element, "change state from %s to %s",
+ gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
+ gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
- if (transition == GST_STATE_CHANGE_PAUSED_TO_READY)
- {
- g_atomic_int_set(&self->active, FALSE);
- gst_aml_v4l2_object_flush_start(self->v4l2output);
- gst_aml_v4l2_object_flush_start(self->v4l2capture);
- gst_pad_stop_task(decoder->srcpad);
- }
+ if (transition == GST_STATE_CHANGE_PAUSED_TO_READY)
+ {
+ g_atomic_int_set (&self->active, FALSE);
+ gst_aml_v4l2_object_flush_start (self->v4l2output);
+ gst_aml_v4l2_object_flush_start (self->v4l2capture);
+ gst_pad_stop_task (decoder->srcpad);
+ }
- return GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
}
static void
-gst_aml_v4l2_video_dec_dispose(GObject *object)
+gst_aml_v4l2_video_dec_dispose (GObject * object)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (object);
- gst_caps_replace(&self->probed_sinkcaps, NULL);
- gst_caps_replace(&self->probed_srccaps, NULL);
+ gst_caps_replace (&self->probed_sinkcaps, NULL);
+ gst_caps_replace (&self->probed_srccaps, NULL);
- G_OBJECT_CLASS(parent_class)->dispose(object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-gst_aml_v4l2_video_dec_finalize(GObject *object)
+gst_aml_v4l2_video_dec_finalize (GObject * object)
{
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(object);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (object);
- gst_aml_v4l2_object_destroy(self->v4l2capture);
- gst_aml_v4l2_object_destroy(self->v4l2output);
+ gst_aml_v4l2_object_destroy (self->v4l2capture);
+ gst_aml_v4l2_object_destroy (self->v4l2output);
- g_mutex_clear(&self->res_chg_lock);
- g_cond_clear(&self->res_chg_cond);
+ g_mutex_clear(&self->res_chg_lock);
+ g_cond_clear(&self->res_chg_cond);
#if GST_IMPORT_LGE_PROP
- if (self->lge_ctxt)
- {
- if (self->lge_ctxt->app_type)
- g_free(self->lge_ctxt->app_type);
- if (self->lge_ctxt->res_info.coretype)
- g_free(self->lge_ctxt->res_info.coretype);
- free(self->lge_ctxt);
- }
+ if (self->lge_ctxt)
+ {
+ if (self->lge_ctxt->app_type)
+ g_free(self->lge_ctxt->app_type);
+ if (self->lge_ctxt->res_info.coretype)
+ g_free(self->lge_ctxt->res_info.coretype);
+ free(self->lge_ctxt);
+ }
#endif
- G_OBJECT_CLASS(parent_class)->finalize(object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-gst_aml_v4l2_video_dec_init(GstAmlV4l2VideoDec *self)
+gst_aml_v4l2_video_dec_init (GstAmlV4l2VideoDec * self)
{
- /* V4L2 object are created in subinstance_init */
- self->last_out_pts = GST_CLOCK_TIME_NONE;
- self->frame_duration = GST_CLOCK_TIME_NONE;
- self->is_secure_path = FALSE;
- self->is_res_chg = FALSE;
- self->codec_data_inject = FALSE;
- g_mutex_init(&self->res_chg_lock);
- g_cond_init(&self->res_chg_cond);
+ /* V4L2 object are created in subinstance_init */
+ self->last_out_pts = GST_CLOCK_TIME_NONE;
+ self->frame_duration = GST_CLOCK_TIME_NONE;
+ self->is_secure_path = FALSE;
+ self->is_res_chg = FALSE;
+ self->codec_data_inject = FALSE;
+ g_mutex_init(&self->res_chg_lock);
+ g_cond_init(&self->res_chg_cond);
#if GST_IMPORT_LGE_PROP
- self->lge_ctxt = malloc(sizeof(GstAmlV4l2VideoDecLgeCtxt));
- memset(self->lge_ctxt, 0, sizeof(GstAmlV4l2VideoDecLgeCtxt));
+ self->lge_ctxt = malloc(sizeof(GstAmlV4l2VideoDecLgeCtxt));
+ memset(self->lge_ctxt, 0, sizeof(GstAmlV4l2VideoDecLgeCtxt));
#endif
}
static void
-gst_aml_v4l2_video_dec_subinstance_init(GTypeInstance *instance, gpointer g_class)
+gst_aml_v4l2_video_dec_subinstance_init (GTypeInstance * instance, gpointer g_class)
{
- GstAmlV4l2VideoDecClass *klass = GST_AML_V4L2_VIDEO_DEC_CLASS(g_class);
- GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC(instance);
- GstAmlVideoDecoder *decoder = GST_AML_VIDEO_DECODER(instance);
+ GstAmlV4l2VideoDecClass *klass = GST_AML_V4L2_VIDEO_DEC_CLASS (g_class);
+ GstAmlV4l2VideoDec *self = GST_AML_V4L2_VIDEO_DEC (instance);
+ GstAmlVideoDecoder *decoder = GST_AML_VIDEO_DECODER (instance);
- gst_aml_video_decoder_set_packetized(decoder, TRUE);
+ gst_aml_video_decoder_set_packetized (decoder, TRUE);
- self->v4l2output = gst_aml_v4l2_object_new(GST_ELEMENT(self),
- GST_OBJECT(GST_AML_VIDEO_DECODER_SINK_PAD(self)),
- V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
- gst_aml_v4l2_get_output, gst_aml_v4l2_set_output, NULL);
- self->v4l2output->no_initial_format = TRUE;
- self->v4l2output->keep_aspect = FALSE;
- self->v4l2output->is_svp = FALSE;
+ self->v4l2output = gst_aml_v4l2_object_new (GST_ELEMENT (self),
+ GST_OBJECT (GST_AML_VIDEO_DECODER_SINK_PAD (self)),
+ V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
+ gst_aml_v4l2_get_output, gst_aml_v4l2_set_output, NULL);
+ self->v4l2output->no_initial_format = TRUE;
+ self->v4l2output->keep_aspect = FALSE;
+ self->v4l2output->is_svp = FALSE;
- self->v4l2capture = gst_aml_v4l2_object_new(GST_ELEMENT(self),
- GST_OBJECT(GST_AML_VIDEO_DECODER_SRC_PAD(self)),
- V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
- gst_aml_v4l2_get_input, gst_aml_v4l2_set_input, NULL);
- self->v4l2capture->need_wait_event = TRUE;
- self->v4l2capture->need_drop_event = FALSE;
+ self->v4l2capture = gst_aml_v4l2_object_new (GST_ELEMENT (self),
+ GST_OBJECT (GST_AML_VIDEO_DECODER_SRC_PAD (self)),
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
+ gst_aml_v4l2_get_input, gst_aml_v4l2_set_input, NULL);
+ self->v4l2capture->need_wait_event = TRUE;
+ self->v4l2capture->need_drop_event = FALSE;
}
static void
-gst_aml_v4l2_video_dec_class_init(GstAmlV4l2VideoDecClass *klass)
+gst_aml_v4l2_video_dec_class_init (GstAmlV4l2VideoDecClass * klass)
{
- GstElementClass *element_class;
- GObjectClass *gobject_class;
- GstAmlVideoDecoderClass *video_decoder_class;
+ GstElementClass *element_class;
+ GObjectClass *gobject_class;
+ GstAmlVideoDecoderClass *video_decoder_class;
- parent_class = g_type_class_peek_parent(klass);
+ parent_class = g_type_class_peek_parent (klass);
- element_class = (GstElementClass *)klass;
- gobject_class = (GObjectClass *)klass;
- video_decoder_class = (GstAmlVideoDecoderClass *)klass;
+ element_class = (GstElementClass *) klass;
+ gobject_class = (GObjectClass *) klass;
+ video_decoder_class = (GstAmlVideoDecoderClass *) klass;
- GST_DEBUG_CATEGORY_INIT(gst_aml_v4l2_video_dec_debug, "amlv4l2videodec", 0,
- "AML V4L2 Video Decoder");
+ GST_DEBUG_CATEGORY_INIT (gst_aml_v4l2_video_dec_debug, "amlv4l2videodec", 0,
+ "AML V4L2 Video Decoder");
- gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_dispose);
- gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_finalize);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_get_property);
+ gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_dispose);
+ gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_finalize);
+ gobject_class->set_property =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_set_property);
+ gobject_class->get_property =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_get_property);
- video_decoder_class->open = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_open);
- video_decoder_class->close = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_close);
- video_decoder_class->start = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_start);
- video_decoder_class->stop = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_stop);
- video_decoder_class->finish = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_finish);
- video_decoder_class->flush = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_flush);
- video_decoder_class->drain = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_drain);
- video_decoder_class->set_format =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_set_format);
- video_decoder_class->negotiate =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_negotiate);
- video_decoder_class->decide_allocation =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_decide_allocation);
- /* FIXME propose_allocation or not ? */
- video_decoder_class->handle_frame =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_handle_frame);
- video_decoder_class->getcaps =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_sink_getcaps);
- video_decoder_class->src_query =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_src_query);
- video_decoder_class->sink_event =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_sink_event);
+ video_decoder_class->open = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_open);
+ video_decoder_class->close = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_close);
+ video_decoder_class->start = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_start);
+ video_decoder_class->stop = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_stop);
+ video_decoder_class->finish = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_finish);
+ video_decoder_class->flush = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_flush);
+ video_decoder_class->drain = GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_drain);
+ video_decoder_class->set_format =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_set_format);
+ video_decoder_class->negotiate =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_negotiate);
+ video_decoder_class->decide_allocation =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_decide_allocation);
+ /* FIXME propose_allocation or not ? */
+ video_decoder_class->handle_frame =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_handle_frame);
+ video_decoder_class->getcaps =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_sink_getcaps);
+ video_decoder_class->src_query =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_src_query);
+ video_decoder_class->sink_event =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_sink_event);
- element_class->change_state =
- GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_change_state);
+ element_class->change_state =
+ GST_DEBUG_FUNCPTR(gst_aml_v4l2_video_dec_change_state);
g_signals[SIGNAL_DECODED_PTS] = g_signal_new ("decoded-pts",
- G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
- G_SIGNAL_RUN_LAST,
- 0, /* class offset */
- NULL, /* accumulator */
- NULL, /* accu data */
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1,
- G_TYPE_UINT64);
- g_signals[SIGNAL_DECODED_ERROR_PTS] = g_signal_new ("decoded-error-pts",
- G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
- G_SIGNAL_RUN_LAST,
- 0, /* class offset */
- NULL, /* accumulator */
- NULL, /* accu data */
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1,
- G_TYPE_UINT64);
+ G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
+ G_SIGNAL_RUN_LAST,
+ 0, /* class offset */
+ NULL, /* accumulator */
+ NULL, /* accu data */
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_UINT64);
+ g_signals[SIGNAL_DECODED_ERROR_PTS] = g_signal_new ("decoded-error-pts",
+ G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
+ G_SIGNAL_RUN_LAST,
+ 0, /* class offset */
+ NULL, /* accumulator */
+ NULL, /* accu data */
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_UINT64);
- gst_aml_v4l2_object_install_m2m_properties_helper(gobject_class);
+ gst_aml_v4l2_object_install_m2m_properties_helper (gobject_class);
#if GST_IMPORT_LGE_PROP
- gst_aml_v4l2_video_dec_install_lge_properties_helper(gobject_class);
+ gst_aml_v4l2_video_dec_install_lge_properties_helper(gobject_class);
#endif
}
static void
-gst_aml_v4l2_video_dec_subclass_init(gpointer g_class, gpointer data)
+gst_aml_v4l2_video_dec_subclass_init (gpointer g_class, gpointer data)
{
- GstAmlV4l2VideoDecClass *klass = GST_AML_V4L2_VIDEO_DEC_CLASS(g_class);
- GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
- GstAmlV4l2VideoDecCData *cdata = data;
+ GstAmlV4l2VideoDecClass *klass = GST_AML_V4L2_VIDEO_DEC_CLASS (g_class);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ GstAmlV4l2VideoDecCData *cdata = data;
- klass->default_device = cdata->device;
+ klass->default_device = cdata->device;
- /* Note: gst_pad_template_new() take the floating ref from the caps */
- gst_element_class_add_pad_template(element_class,
- gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
- cdata->sink_caps));
- gst_element_class_add_pad_template(element_class,
- gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS,
- cdata->src_caps));
+ /* Note: gst_pad_template_new() take the floating ref from the caps */
+ gst_element_class_add_pad_template (element_class,
+ gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
+ cdata->sink_caps));
+ gst_element_class_add_pad_template (element_class,
+ gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ cdata->src_caps));
- gst_element_class_set_metadata(element_class, cdata->longname,
- "Codec/Decoder/Video/Hardware", cdata->description,
- "Xuesong Jiang <Xuesong.Jiang@amlogic.com>");
+ gst_element_class_set_metadata (element_class, cdata->longname,
+ "Codec/Decoder/Video/Hardware", cdata->description,
+ "Xuesong Jiang <Xuesong.Jiang@amlogic.com>");
- gst_caps_unref(cdata->sink_caps);
- gst_caps_unref(cdata->src_caps);
- g_free(cdata);
+ gst_caps_unref (cdata->sink_caps);
+ gst_caps_unref (cdata->src_caps);
+ g_free (cdata);
}
/* Probing functions */
gboolean
-gst_aml_v4l2_is_video_dec(GstCaps *sink_caps, GstCaps *src_caps)
+gst_aml_v4l2_is_video_dec (GstCaps * sink_caps, GstCaps * src_caps)
{
- gboolean ret = FALSE;
+ gboolean ret = FALSE;
- if (gst_caps_is_subset(sink_caps, gst_aml_v4l2_object_get_codec_caps()) && gst_caps_is_subset(src_caps, gst_aml_v4l2_object_get_raw_caps()))
- ret = TRUE;
+ if (gst_caps_is_subset (sink_caps, gst_aml_v4l2_object_get_codec_caps ())
+ && gst_caps_is_subset (src_caps, gst_aml_v4l2_object_get_raw_caps ()))
+ ret = TRUE;
- return ret;
+ return ret;
}
static gchar *
-gst_aml_v4l2_video_dec_set_metadata(GstStructure *s, GstAmlV4l2VideoDecCData *cdata,
- const gchar *basename)
+gst_aml_v4l2_video_dec_set_metadata (GstStructure * s, GstAmlV4l2VideoDecCData * cdata,
+ const gchar * basename)
{
- gchar *codec_name = NULL;
- gchar *type_name = NULL;
+ gchar *codec_name = NULL;
+ gchar *type_name = NULL;
-#define SET_META(codec) \
- G_STMT_START \
- { \
- cdata->longname = "AML V4L2 " codec " Decoder"; \
- cdata->description = "Decodes " codec " streams via V4L2 API"; \
- codec_name = g_ascii_strdown(codec, -1); \
- } \
- G_STMT_END
+#define SET_META(codec) \
+G_STMT_START { \
+ cdata->longname = "AML V4L2 " codec " Decoder"; \
+ cdata->description = "Decodes " codec " streams via V4L2 API"; \
+ codec_name = g_ascii_strdown (codec, -1); \
+} G_STMT_END
- if (gst_structure_has_name(s, "video/mjpeg"))
+ if (gst_structure_has_name(s, "video/mjpeg"))
+ {
+ SET_META("MJPEG");
+ }
+ else if (gst_structure_has_name (s, "video/mpeg"))
+ {
+ //include mpeg1, mpeg2, mpeg4
+ SET_META("MPEG4");
+ }
+ else if (gst_structure_has_name (s, "video/x-h263"))
+ {
+ SET_META ("H263");
+ }
+ else if (gst_structure_has_name (s, "video/x-fwht"))
+ {
+ SET_META ("FWHT");
+ }
+ else if (gst_structure_has_name (s, "video/x-h264"))
+ {
+ SET_META ("H264");
+ }
+ else if (gst_structure_has_name (s, "video/x-h265"))
+ {
+ SET_META ("H265");
+ }
+ else if (gst_structure_has_name (s, "video/x-wmv"))
+ {
+ SET_META ("VC1");
+ }
+ else if (gst_structure_has_name (s, "video/x-vp8"))
+ {
+ SET_META ("VP8");
+ }
+ else if (gst_structure_has_name (s, "video/x-vp9"))
+ {
+ SET_META ("VP9");
+ }
+ else if (gst_structure_has_name(s, "video/x-av1"))
+ {
+ SET_META("AV1");
+ }
+ else if (gst_structure_has_name(s, "video/x-avs"))
+ {
+ SET_META("AVS");
+ }
+ else if (gst_structure_has_name(s, "video/x-avs2"))
+ {
+ SET_META("AVS2");
+ }
+ else if (gst_structure_has_name(s, "video/x-avs3"))
+ {
+ SET_META("AVS3");
+ }
+ else if (gst_structure_has_name (s, "video/x-bayer"))
+ {
+ SET_META ("BAYER");
+ }
+ else if (gst_structure_has_name (s, "video/x-sonix"))
+ {
+ SET_META ("SONIX");
+ }
+ else if (gst_structure_has_name (s, "video/x-pwc1"))
+ {
+ SET_META ("PWC1");
+ }
+ else if (gst_structure_has_name (s, "video/x-pwc2"))
+ {
+ SET_META ("PWC2");
+ }
+ else
+ {
+ /* This code should be kept on sync with the exposed CODEC type of format
+ * from gstamlv4l2object.c. This warning will only occur in case we forget
+ * to also add a format here. */
+ gchar *s_str = gst_structure_to_string (s);
+ g_warning ("Missing fixed name mapping for caps '%s', this is a GStreamer "
+ "bug, please report at https://bugs.gnome.org", s_str);
+ g_free (s_str);
+ }
+
+ if (codec_name)
+ {
+ type_name = g_strdup_printf ("amlv4l2%sdec", codec_name);
+ if (g_type_from_name (type_name) != 0)
{
- SET_META("MJPEG");
- }
- else if (gst_structure_has_name(s, "video/mpeg"))
- {
- //include mpeg1, mpeg2, mpeg4
- SET_META("MPEG4");
- }
- else if (gst_structure_has_name(s, "video/x-h263"))
- {
- SET_META("H263");
- }
- else if (gst_structure_has_name(s, "video/x-fwht"))
- {
- SET_META("FWHT");
- }
- else if (gst_structure_has_name(s, "video/x-h264"))
- {
- SET_META("H264");
- }
- else if (gst_structure_has_name(s, "video/x-h265"))
- {
- SET_META("H265");
- }
- else if (gst_structure_has_name(s, "video/x-wmv"))
- {
- SET_META("VC1");
- }
- else if (gst_structure_has_name(s, "video/x-vp8"))
- {
- SET_META("VP8");
- }
- else if (gst_structure_has_name(s, "video/x-vp9"))
- {
- SET_META("VP9");
- }
- else if (gst_structure_has_name(s, "video/x-av1"))
- {
- SET_META("AV1");
- }
- else if (gst_structure_has_name(s, "video/x-avs"))
- {
- SET_META("AVS");
- }
- else if (gst_structure_has_name(s, "video/x-avs2"))
- {
- SET_META("AVS2");
- }
- else if (gst_structure_has_name(s, "video/x-avs3"))
- {
- SET_META("AVS3");
- }
- else if (gst_structure_has_name(s, "video/x-bayer"))
- {
- SET_META("BAYER");
- }
- else if (gst_structure_has_name(s, "video/x-sonix"))
- {
- SET_META("SONIX");
- }
- else if (gst_structure_has_name(s, "video/x-pwc1"))
- {
- SET_META("PWC1");
- }
- else if (gst_structure_has_name(s, "video/x-pwc2"))
- {
- SET_META("PWC2");
- }
- else
- {
- /* This code should be kept on sync with the exposed CODEC type of format
- * from gstamlv4l2object.c. This warning will only occure in case we forget
- * to also add a format here. */
- gchar *s_str = gst_structure_to_string(s);
- g_warning("Missing fixed name mapping for caps '%s', this is a GStreamer "
- "bug, please report at https://bugs.gnome.org",
- s_str);
- g_free(s_str);
+ g_free (type_name);
+ type_name = g_strdup_printf ("amlv4l2%s%sdec", basename, codec_name);
}
- if (codec_name)
- {
- type_name = g_strdup_printf("amlv4l2%sdec", codec_name);
- if (g_type_from_name(type_name) != 0)
- {
- g_free(type_name);
- type_name = g_strdup_printf("amlv4l2%s%sdec", basename, codec_name);
- }
+ g_free (codec_name);
+ }
- g_free(codec_name);
- }
-
- return type_name;
+ return type_name;
#undef SET_META
}
-void gst_aml_v4l2_video_dec_register(GstPlugin *plugin, const gchar *basename,
+void
+gst_aml_v4l2_video_dec_register(GstPlugin *plugin, const gchar *basename,
const gchar *device_path, GstCaps *sink_caps, GstCaps *src_caps)
{
- gint i;
+ gint i;
- for (i = 0; i < gst_caps_get_size(sink_caps); i++)
+ for (i = 0; i < gst_caps_get_size (sink_caps); i++)
+ {
+ GstAmlV4l2VideoDecCData *cdata;
+ GstStructure *s;
+ GTypeQuery type_query;
+ GTypeInfo type_info = { 0, };
+ GType type, subtype;
+ gchar *type_name;
+
+ s = gst_caps_get_structure (sink_caps, i);
+
+ cdata = g_new0 (GstAmlV4l2VideoDecCData, 1);
+ cdata->device = g_strdup (device_path);
+ cdata->sink_caps = gst_caps_new_empty ();
+ gst_caps_append_structure (cdata->sink_caps, gst_structure_copy (s));
+ gst_caps_append_structure (cdata->sink_caps, gst_structure_copy (s));
+ gst_caps_set_features(cdata->sink_caps, 0, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
+ cdata->src_caps = gst_caps_copy(src_caps);
+ gst_caps_set_features_simple(cdata->src_caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
+ gst_caps_append(cdata->src_caps, gst_caps_copy (src_caps));
+ type_name = gst_aml_v4l2_video_dec_set_metadata (s, cdata, basename);
+
+ /* Skip over if we hit an unmapped type */
+ if (!type_name)
{
- GstAmlV4l2VideoDecCData *cdata;
- GstStructure *s;
- GTypeQuery type_query;
- GTypeInfo type_info = {
- 0,
- };
- GType type, subtype;
- gchar *type_name;
-
- s = gst_caps_get_structure(sink_caps, i);
-
- cdata = g_new0(GstAmlV4l2VideoDecCData, 1);
- cdata->device = g_strdup(device_path);
- cdata->sink_caps = gst_caps_new_empty();
- gst_caps_append_structure(cdata->sink_caps, gst_structure_copy(s));
- gst_caps_append_structure(cdata->sink_caps, gst_structure_copy(s));
- gst_caps_set_features(cdata->sink_caps, 0, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
- cdata->src_caps = gst_caps_copy(src_caps);
- gst_caps_set_features_simple(cdata->src_caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
- gst_caps_append(cdata->src_caps, gst_caps_copy(src_caps));
- type_name = gst_aml_v4l2_video_dec_set_metadata(s, cdata, basename);
-
- /* Skip over if we hit an unmapped type */
- if (!type_name)
- {
- g_free(cdata);
- continue;
- }
-
- type = gst_aml_v4l2_video_dec_get_type();
- g_type_query(type, &type_query);
- memset(&type_info, 0, sizeof(type_info));
- type_info.class_size = type_query.class_size;
- type_info.instance_size = type_query.instance_size;
- type_info.class_init = gst_aml_v4l2_video_dec_subclass_init;
- type_info.class_data = cdata;
- type_info.instance_init = gst_aml_v4l2_video_dec_subinstance_init;
-
- subtype = g_type_register_static(type, type_name, &type_info, 0);
- if (!gst_element_register(plugin, type_name, GST_RANK_PRIMARY + 1,
- subtype))
- GST_WARNING("Failed to register plugin '%s'", type_name);
-
- g_free(type_name);
+ g_free (cdata);
+ continue;
}
+
+ type = gst_aml_v4l2_video_dec_get_type ();
+ g_type_query (type, &type_query);
+ memset (&type_info, 0, sizeof (type_info));
+ type_info.class_size = type_query.class_size;
+ type_info.instance_size = type_query.instance_size;
+ type_info.class_init = gst_aml_v4l2_video_dec_subclass_init;
+ type_info.class_data = cdata;
+ type_info.instance_init = gst_aml_v4l2_video_dec_subinstance_init;
+
+ subtype = g_type_register_static (type, type_name, &type_info, 0);
+ if (!gst_element_register (plugin, type_name, GST_RANK_PRIMARY + 1,
+ subtype))
+ GST_WARNING ("Failed to register plugin '%s'", type_name);
+
+ g_free (type_name);
+ }
}
#if GST_IMPORT_LGE_PROP
diff --git a/src/gstamlv4l2videodec.h b/src/gstamlv4l2videodec.h
index 731e00e..854b070 100644
--- a/src/gstamlv4l2videodec.h
+++ b/src/gstamlv4l2videodec.h
@@ -51,44 +51,44 @@
struct _GstAmlV4l2VideoDec
{
- GstAmlVideoDecoder parent;
+ GstAmlVideoDecoder parent;
- /* < private > */
- GstAmlV4l2Object *v4l2output;
- GstAmlV4l2Object *v4l2capture;
+ /* < private > */
+ GstAmlV4l2Object *v4l2output;
+ GstAmlV4l2Object *v4l2capture;
- /* pads */
- GstCaps *probed_srccaps;
- GstCaps *probed_sinkcaps;
+ /* pads */
+ GstCaps *probed_srccaps;
+ GstCaps *probed_sinkcaps;
- /* State */
- GstAmlVideoCodecState *input_state;
- gboolean active;
- GstFlowReturn output_flow;
+ /* State */
+ GstAmlVideoCodecState *input_state;
+ gboolean active;
+ GstFlowReturn output_flow;
- /* flags */
- gboolean is_secure_path;
- gboolean is_res_chg;
+ /* flags */
+ gboolean is_secure_path;
+ gboolean is_res_chg;
- /* resolution change lock */
- GMutex res_chg_lock;
- GCond res_chg_cond;
+ /* resolution change lock */
+ GMutex res_chg_lock;
+ GCond res_chg_cond;
- GstClockTime last_out_pts;
- GstClockTime frame_duration;
- gboolean codec_data_inject;
+ GstClockTime last_out_pts;
+ GstClockTime frame_duration;
+ gboolean codec_data_inject;
#if GST_IMPORT_LGE_PROP
- /* LGE context */
- GstAmlV4l2VideoDecLgeCtxt *lge_ctxt;
+ /* LGE context */
+ GstAmlV4l2VideoDecLgeCtxt *lge_ctxt;
#endif
};
struct _GstAmlV4l2VideoDecClass
{
- GstAmlVideoDecoderClass parent_class;
+ GstAmlVideoDecoderClass parent_class;
- gchar *default_device;
+ gchar *default_device;
};
GType gst_aml_v4l2_video_dec_get_type(void);