summaryrefslogtreecommitdiff
path: root/sys/uvch264
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd@greynoise.nl>2013-01-18 22:49:19 +0100
committerSjoerd Simons <sjoerd@luon.net>2013-02-11 22:04:59 +0100
commit14637e2a271222ae04356cfa7b88cb34775d2d0d (patch)
tree2e8e8c0bb888d5ae217638244f70762ec20db6cb /sys/uvch264
parent381fcda68b079b59f6d68b4f47f24e4885d592ba (diff)
downloadgstreamer-plugins-bad-14637e2a271222ae04356cfa7b88cb34775d2d0d.tar.gz
uvch264src: Port to gstreamer 1.0
Diffstat (limited to 'sys/uvch264')
-rw-r--r--sys/uvch264/Makefile.am5
-rw-r--r--sys/uvch264/gstuvch264.c2
-rw-r--r--sys/uvch264/gstuvch264_mjpgdemux.c230
-rw-r--r--sys/uvch264/gstuvch264_src.c274
4 files changed, 237 insertions, 274 deletions
diff --git a/sys/uvch264/Makefile.am b/sys/uvch264/Makefile.am
index a647fa998..be99159c3 100644
--- a/sys/uvch264/Makefile.am
+++ b/sys/uvch264/Makefile.am
@@ -1,6 +1,3 @@
-glib_gen_prefix = __gst_uvc_h264
-glib_gen_basename = gstuvch264
-
plugin_LTLIBRARIES = libgstuvch264.la
libgstuvch264_la_SOURCES = gstuvch264.c \
@@ -27,7 +24,7 @@ libgstuvch264_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
$(GST_LIBS) \
$(G_UDEV_LIBS) \
$(LIBUSB_LIBS) \
- $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-$(GST_MAJORMINOR).la
+ $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la
noinst_HEADERS = gstuvch264_mjpgdemux.h \
gstuvch264_src.h \
diff --git a/sys/uvch264/gstuvch264.c b/sys/uvch264/gstuvch264.c
index 665f04a4f..96f544f99 100644
--- a/sys/uvch264/gstuvch264.c
+++ b/sys/uvch264/gstuvch264.c
@@ -45,6 +45,6 @@ plugin_init (GstPlugin * plugin)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
- "uvch264",
+ uvch264,
"UVC compliant H264 encoding cameras plugin",
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/sys/uvch264/gstuvch264_mjpgdemux.c b/sys/uvch264/gstuvch264_mjpgdemux.c
index ff768cb4f..28f9ce5d5 100644
--- a/sys/uvch264/gstuvch264_mjpgdemux.c
+++ b/sys/uvch264/gstuvch264_mjpgdemux.c
@@ -96,8 +96,8 @@ static GstStaticPadTemplate yuy2src_pad_template =
GST_STATIC_PAD_TEMPLATE ("yuy2",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, "
- "format = (fourcc) YUY2, "
+ GST_STATIC_CAPS ("video/x-raw, "
+ "format = (string) YUY2, "
"width = (int) [ 0, MAX ], "
"height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0/1, MAX ] ")
);
@@ -105,8 +105,8 @@ static GstStaticPadTemplate nv12src_pad_template =
GST_STATIC_PAD_TEMPLATE ("nv12",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, "
- "format = (fourcc) NV21, "
+ GST_STATIC_CAPS ("video/x-raw, "
+ "format = (string) NV21, "
"width = (int) [ 0, MAX ], "
"height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0/1, MAX ] ")
);
@@ -164,53 +164,22 @@ static void gst_uvc_h264_mjpg_demux_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_uvc_h264_mjpg_demux_dispose (GObject * object);
static GstFlowReturn gst_uvc_h264_mjpg_demux_chain (GstPad * pad,
- GstBuffer * buffer);
-static gboolean gst_uvc_h264_mjpg_demux_sink_setcaps (GstPad * pad,
- GstCaps * caps);
-static GstCaps *gst_uvc_h264_mjpg_demux_getcaps (GstPad * pad);
+ GstObject * parent, GstBuffer * buffer);
+static gboolean gst_uvc_h264_mjpg_demux_sink_event (GstPad * pad,
+ GstObject * parent, GstEvent * event);
+static gboolean gst_uvc_h264_mjpg_demux_query (GstPad * pad,
+ GstObject * parent, GstQuery * query);
-#define _do_init(x) \
- GST_DEBUG_CATEGORY_INIT (uvc_h264_mjpg_demux_debug, \
- "uvch264_mjpgdemux", 0, "UVC H264 MJPG Demuxer");
-
-GST_BOILERPLATE_FULL (GstUvcH264MjpgDemux, gst_uvc_h264_mjpg_demux, GstElement,
- GST_TYPE_ELEMENT, _do_init);
-
-static void
-gst_uvc_h264_mjpg_demux_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- GstPadTemplate *pt;
-
- /* do not use gst_element_class_add_static_pad_template to stay compatible
- * with gstreamer 0.10.35 */
- pt = gst_static_pad_template_get (&mjpgsink_pad_template);
- gst_element_class_add_pad_template (element_class, pt);
- gst_object_unref (pt);
- pt = gst_static_pad_template_get (&jpegsrc_pad_template);
- gst_element_class_add_pad_template (element_class, pt);
- gst_object_unref (pt);
- pt = gst_static_pad_template_get (&h264src_pad_template);
- gst_element_class_add_pad_template (element_class, pt);
- gst_object_unref (pt);
- pt = gst_static_pad_template_get (&yuy2src_pad_template);
- gst_element_class_add_pad_template (element_class, pt);
- gst_object_unref (pt);
- pt = gst_static_pad_template_get (&nv12src_pad_template);
- gst_element_class_add_pad_template (element_class, pt);
- gst_object_unref (pt);
-
- gst_element_class_set_static_metadata (element_class,
- "UVC H264 MJPG Demuxer",
- "Video/Demuxer",
- "Demux UVC H264 auxiliary streams from MJPG images",
- "Youness Alaoui <youness.alaoui@collabora.co.uk>");
-}
+#define gst_uvc_h264_mjpg_demux_parent_class parent_class
+G_DEFINE_TYPE (GstUvcH264MjpgDemux, gst_uvc_h264_mjpg_demux, GST_TYPE_ELEMENT);
static void
gst_uvc_h264_mjpg_demux_class_init (GstUvcH264MjpgDemuxClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstElementClass *element_class = (GstElementClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (gobject_class, sizeof (GstUvcH264MjpgDemuxPrivate));
@@ -218,6 +187,26 @@ gst_uvc_h264_mjpg_demux_class_init (GstUvcH264MjpgDemuxClass * klass)
gobject_class->get_property = gst_uvc_h264_mjpg_demux_get_property;
gobject_class->dispose = gst_uvc_h264_mjpg_demux_dispose;
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&mjpgsink_pad_template));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&jpegsrc_pad_template));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&h264src_pad_template));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&yuy2src_pad_template));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&nv12src_pad_template));
+
+ gst_element_class_set_static_metadata (element_class,
+ "UVC H264 MJPG Demuxer",
+ "Video/Demuxer",
+ "Demux UVC H264 auxiliary streams from MJPG images",
+ "Youness Alaoui <youness.alaoui@collabora.co.uk>");
g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
g_param_spec_int ("device-fd", "device-fd",
@@ -230,11 +219,13 @@ gst_uvc_h264_mjpg_demux_class_init (GstUvcH264MjpgDemuxClass * klass)
" (-1 = unlimited)",
0, G_MAXINT, DEFAULT_NUM_CLOCK_SAMPLES,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
+
+ GST_DEBUG_CATEGORY_INIT (uvc_h264_mjpg_demux_debug,
+ "uvch264_mjpgdemux", 0, "UVC H264 MJPG Demuxer");
}
static void
-gst_uvc_h264_mjpg_demux_init (GstUvcH264MjpgDemux * self,
- GstUvcH264MjpgDemuxClass * g_class)
+gst_uvc_h264_mjpg_demux_init (GstUvcH264MjpgDemux * self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_UVC_H264_MJPG_DEMUX,
GstUvcH264MjpgDemuxPrivate);
@@ -247,17 +238,17 @@ gst_uvc_h264_mjpg_demux_init (GstUvcH264MjpgDemux * self,
gst_pad_new_from_static_template (&mjpgsink_pad_template, "sink");
gst_pad_set_chain_function (self->priv->sink_pad,
GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_chain));
- gst_pad_set_setcaps_function (self->priv->sink_pad,
- GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_sink_setcaps));
- gst_pad_set_getcaps_function (self->priv->sink_pad,
- GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_getcaps));
+ gst_pad_set_event_function (self->priv->sink_pad,
+ GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_sink_event));
+ gst_pad_set_query_function (self->priv->sink_pad,
+ GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_query));
gst_element_add_pad (GST_ELEMENT (self), self->priv->sink_pad);
/* JPEG */
self->priv->jpeg_pad =
gst_pad_new_from_static_template (&jpegsrc_pad_template, "jpeg");
- gst_pad_set_getcaps_function (self->priv->jpeg_pad,
- GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_getcaps));
+ gst_pad_set_query_function (self->priv->jpeg_pad,
+ GST_DEBUG_FUNCPTR (gst_uvc_h264_mjpg_demux_query));
gst_element_add_pad (GST_ELEMENT (self), self->priv->jpeg_pad);
/* H264 */
@@ -278,11 +269,11 @@ gst_uvc_h264_mjpg_demux_init (GstUvcH264MjpgDemux * self,
gst_pad_use_fixed_caps (self->priv->nv12_pad);
gst_element_add_pad (GST_ELEMENT (self), self->priv->nv12_pad);
- self->priv->h264_caps = gst_caps_new_simple ("video/x-h264", NULL);
- self->priv->yuy2_caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'), NULL);
- self->priv->nv12_caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('N', 'V', '1', '2'), NULL);
+ self->priv->h264_caps = gst_caps_new_empty_simple ("video/x-h264");
+ self->priv->yuy2_caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "YUY2", NULL);
+ self->priv->nv12_caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "NV12", NULL);
self->priv->h264_width = self->priv->h264_height = 0;
self->priv->yuy2_width = self->priv->yuy2_height = 0;
self->priv->nv12_width = self->priv->nv12_height = 0;
@@ -369,31 +360,40 @@ gst_uvc_h264_mjpg_demux_get_property (GObject * object,
}
}
-
static gboolean
-gst_uvc_h264_mjpg_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
+gst_uvc_h264_mjpg_demux_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
- GstUvcH264MjpgDemux *self = GST_UVC_H264_MJPG_DEMUX (GST_OBJECT_PARENT (pad));
+ GstUvcH264MjpgDemux *self = GST_UVC_H264_MJPG_DEMUX (parent);
- return gst_pad_set_caps (self->priv->jpeg_pad, caps);
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ return gst_pad_push_event (self->priv->jpeg_pad, event);
+ default:
+ break;
+ }
+ return gst_pad_event_default (pad, parent, event);
}
-static GstCaps *
-gst_uvc_h264_mjpg_demux_getcaps (GstPad * pad)
+static gboolean
+gst_uvc_h264_mjpg_demux_query (GstPad * pad, GstObject * parent,
+ GstQuery * query)
{
- GstUvcH264MjpgDemux *self = GST_UVC_H264_MJPG_DEMUX (GST_OBJECT_PARENT (pad));
- GstCaps *result = NULL;
-
- if (pad == self->priv->jpeg_pad)
- result = gst_pad_peer_get_caps (self->priv->sink_pad);
- else if (pad == self->priv->sink_pad)
- result = gst_pad_peer_get_caps (self->priv->jpeg_pad);
-
- /* TODO: intersect with template and fixate caps */
- if (result == NULL)
- result = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ GstUvcH264MjpgDemux *self = GST_UVC_H264_MJPG_DEMUX (parent);
+ gboolean ret = FALSE;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ if (pad == self->priv->sink_pad)
+ ret = gst_pad_peer_query (self->priv->jpeg_pad, query);
+ else
+ ret = gst_pad_peer_query (self->priv->sink_pad, query);
+ break;
+ default:
+ ret = gst_pad_query_default (pad, parent, query);
+ }
- return result;
+ return ret;
}
static gboolean
@@ -456,35 +456,37 @@ _pts_to_timestamp (GstUvcH264MjpgDemux * self, GstBuffer * buf, guint32 pts)
}
static GstFlowReturn
-gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
+gst_uvc_h264_mjpg_demux_chain (GstPad * pad,
+ GstObject * parent, GstBuffer * buf)
{
GstUvcH264MjpgDemux *self;
GstFlowReturn ret = GST_FLOW_OK;
- GstBufferList *jpeg_buf = gst_buffer_list_new ();
- GstBufferListIterator *jpeg_it = gst_buffer_list_iterate (jpeg_buf);
- GstBufferList *aux_buf = NULL;
- GstBufferListIterator *aux_it = NULL;
+ GstBuffer *jpeg_buf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_METADATA,
+ 0, 0);
+ GstBuffer *aux_buf = NULL;
AuxiliaryStreamHeader aux_header = { 0 };
- GstBuffer *sub_buffer = NULL;
guint32 aux_size = 0;
GstPad *aux_pad = NULL;
GstCaps **aux_caps = NULL;
guint last_offset;
guint i;
guchar *data;
- guint size;
+ gsize size;
+ GstMapInfo info;
self = GST_UVC_H264_MJPG_DEMUX (GST_PAD_PARENT (pad));
last_offset = 0;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
- if (data == NULL || size == 0) {
+ size = gst_buffer_get_size (buf);
+ if (size == 0) {
ret = gst_pad_push (self->priv->jpeg_pad, buf);
goto done;
}
- gst_buffer_list_iterator_add_group (jpeg_it);
+ gst_buffer_map (buf, &info, GST_MAP_READ);
+
+ data = info.data;
+
for (i = 0; i < size - 1; i++) {
/* Check for APP4 (0xe4) marker in the jpeg */
if (data[i] == 0xff && data[i + 1] == 0xe4) {
@@ -511,9 +513,9 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
/* Add JPEG data between the last offset and this market */
if (i - last_offset > 0) {
- sub_buffer = gst_buffer_create_sub (buf, last_offset, i - last_offset);
- gst_buffer_copy_metadata (sub_buffer, buf, GST_BUFFER_COPY_ALL);
- gst_buffer_list_iterator_add (jpeg_it, sub_buffer);
+ GstMemory *m = gst_memory_copy (info.memory, last_offset,
+ i - last_offset);
+ gst_buffer_append_memory (jpeg_buf, m);
}
last_offset = i + 2 + segment_size;
@@ -584,16 +586,18 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
goto done;
if (*width != aux_header.width || *height != aux_header.height) {
- GstCaps *peercaps = gst_pad_peer_get_caps (aux_pad);
+ GstCaps *peercaps = gst_pad_peer_query_caps (aux_pad, NULL);
GstStructure *s = NULL;
gint fps_num = 1000000000 / aux_header.frame_interval;
gint fps_den = 100;
/* TODO: intersect with pad template */
GST_DEBUG ("peercaps : %" GST_PTR_FORMAT, peercaps);
- if (peercaps && !gst_caps_is_any (peercaps))
+ if (peercaps && !gst_caps_is_any (peercaps)) {
+ peercaps = gst_caps_make_writable (peercaps);
s = gst_caps_get_structure (peercaps, 0);
- if (s) {
+ }
+ if (s && gst_structure_has_field (s, "framerate")) {
/* TODO: make sure it contains the right format/width/height */
gst_structure_fixate_field_nearest_fraction (s, "framerate",
fps_num, fps_den);
@@ -619,9 +623,7 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
}
/* Create new auxiliary buffer list and adjust i/segment size */
- aux_buf = gst_buffer_list_new ();
- aux_it = gst_buffer_list_iterate (aux_buf);
- gst_buffer_list_iterator_add_group (aux_it);
+ aux_buf = gst_buffer_new ();
}
i += sizeof (aux_header) + sizeof (aux_size);
@@ -637,26 +639,24 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
}
if (segment_size > 0) {
- sub_buffer = gst_buffer_create_sub (buf, i, segment_size);
- GST_BUFFER_DURATION (sub_buffer) =
+ GstMemory *m;
+ m = gst_memory_copy (info.memory, i, segment_size);
+
+ GST_BUFFER_DURATION (aux_buf) =
aux_header.frame_interval * 100 * GST_NSECOND;
- gst_buffer_copy_metadata (sub_buffer, buf, GST_BUFFER_COPY_TIMESTAMPS);
- gst_buffer_set_caps (sub_buffer, *aux_caps);
- _pts_to_timestamp (self, sub_buffer, aux_header.pts);
+ _pts_to_timestamp (self, aux_buf, aux_header.pts);
- gst_buffer_list_iterator_add (aux_it, sub_buffer);
+ gst_buffer_append_memory (aux_buf, m);
aux_size -= segment_size;
/* Push completed aux data */
if (aux_size == 0) {
- gst_buffer_list_iterator_free (aux_it);
- aux_it = NULL;
GST_DEBUG_OBJECT (self, "Pushing %" GST_FOURCC_FORMAT
" auxiliary buffer %" GST_PTR_FORMAT,
GST_FOURCC_ARGS (aux_header.type), *aux_caps);
- ret = gst_pad_push_list (aux_pad, aux_buf);
+ ret = gst_pad_push (aux_pad, aux_buf);
aux_buf = NULL;
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Error pushing %" GST_FOURCC_FORMAT
@@ -668,19 +668,17 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
i += segment_size - 1;
} else if (data[i] == 0xff && data[i + 1] == 0xda) {
+ GstMemory *m;
/* The APP4 markers must be before the SOS marker, so this is the end */
GST_DEBUG_OBJECT (self, "Found SOS marker.");
- sub_buffer = gst_buffer_create_sub (buf, last_offset, size - last_offset);
- gst_buffer_copy_metadata (sub_buffer, buf, GST_BUFFER_COPY_ALL);
- gst_buffer_list_iterator_add (jpeg_it, sub_buffer);
+ m = gst_memory_copy (info.memory, last_offset, size - last_offset);
+ gst_buffer_append_memory (jpeg_buf, m);
last_offset = size;
break;
}
}
- gst_buffer_list_iterator_free (jpeg_it);
- jpeg_it = NULL;
if (aux_buf != NULL) {
GST_ELEMENT_ERROR (self, STREAM, DEMUX,
@@ -693,10 +691,10 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
/* this means there was no SOS marker in the jpg, so we assume the JPG was
just a container */
GST_DEBUG_OBJECT (self, "SOS marker wasn't found. MJPG is container only");
- gst_buffer_list_unref (jpeg_buf);
+ gst_buffer_unref (jpeg_buf);
jpeg_buf = NULL;
} else {
- ret = gst_pad_push_list (self->priv->jpeg_pad, jpeg_buf);
+ ret = gst_pad_push (self->priv->jpeg_pad, jpeg_buf);
jpeg_buf = NULL;
}
@@ -707,14 +705,10 @@ gst_uvc_h264_mjpg_demux_chain (GstPad * pad, GstBuffer * buf)
done:
/* In case of error, unref whatever was left */
- if (aux_it)
- gst_buffer_list_iterator_free (aux_it);
if (aux_buf)
- gst_buffer_list_unref (aux_buf);
- if (jpeg_it)
- gst_buffer_list_iterator_free (jpeg_it);
+ gst_buffer_unref (aux_buf);
if (jpeg_buf)
- gst_buffer_list_unref (jpeg_buf);
+ gst_buffer_unref (jpeg_buf);
/* We must always unref the input buffer since we never push it out */
gst_buffer_unref (buf);
diff --git a/sys/uvch264/gstuvch264_src.c b/sys/uvch264/gstuvch264_src.c
index a42039ac3..1e8e1319b 100644
--- a/sys/uvch264/gstuvch264_src.c
+++ b/sys/uvch264/gstuvch264_src.c
@@ -41,7 +41,6 @@
#include <string.h>
#include "gstuvch264_src.h"
-#include "gstuvch264-marshal.h"
#include <gudev/gudev.h>
#include <libusb.h>
#ifndef LIBUSB_CLASS_VIDEO
@@ -154,40 +153,11 @@ static guint _signals[LAST_SIGNAL];
GST_DEBUG_CATEGORY (uvc_h264_src_debug);
#define GST_CAT_DEFAULT uvc_h264_src_debug
-GST_BOILERPLATE (GstUvcH264Src, gst_uvc_h264_src,
- GstBaseCameraSrc, GST_TYPE_BASE_CAMERA_SRC);
-
-#define GST_UVC_H264_SRC_VF_CAPS_STR \
- GST_VIDEO_CAPS_RGB ";" \
- GST_VIDEO_CAPS_RGB";" \
- GST_VIDEO_CAPS_BGR";" \
- GST_VIDEO_CAPS_RGBx";" \
- GST_VIDEO_CAPS_xRGB";" \
- GST_VIDEO_CAPS_BGRx";" \
- GST_VIDEO_CAPS_xBGR";" \
- GST_VIDEO_CAPS_RGBA";" \
- GST_VIDEO_CAPS_ARGB";" \
- GST_VIDEO_CAPS_BGRA";" \
- GST_VIDEO_CAPS_ABGR";" \
- GST_VIDEO_CAPS_RGB_16";" \
- GST_VIDEO_CAPS_RGB_15";" \
- "video/x-raw-rgb, bpp = (int)8, depth = (int)8, " \
- "width = "GST_VIDEO_SIZE_RANGE" , " \
- "height = " GST_VIDEO_SIZE_RANGE ", " \
- "framerate = "GST_VIDEO_FPS_RANGE ";" \
- GST_VIDEO_CAPS_GRAY8";" \
- GST_VIDEO_CAPS_GRAY16("BIG_ENDIAN")";" \
- GST_VIDEO_CAPS_GRAY16("LITTLE_ENDIAN")";" \
- GST_VIDEO_CAPS_YUV ("{ I420 , NV12 , NV21 , YV12 , YUY2 ," \
- " Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY ," \
- " Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, A420}") ";" \
- "image/jpeg, " \
- "width = " GST_VIDEO_SIZE_RANGE ", " \
- "height = " GST_VIDEO_SIZE_RANGE ", " \
- "framerate = " GST_VIDEO_FPS_RANGE
+#define gst_uvc_h264_src_parent_class parent_class
+G_DEFINE_TYPE (GstUvcH264Src, gst_uvc_h264_src, GST_TYPE_BASE_CAMERA_SRC);
#define GST_UVC_H264_SRC_VID_CAPS_STR \
- GST_UVC_H264_SRC_VF_CAPS_STR ";" \
+ GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \
"video/x-h264, " \
"width = " GST_VIDEO_SIZE_RANGE ", " \
"height = " GST_VIDEO_SIZE_RANGE ", " \
@@ -200,7 +170,7 @@ static GstStaticPadTemplate vfsrc_template =
GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_UVC_H264_SRC_VF_CAPS_STR));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
static GstStaticPadTemplate imgsrc_template =
GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME,
@@ -220,7 +190,8 @@ static void gst_uvc_h264_src_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_uvc_h264_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
-static gboolean gst_uvc_h264_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_uvc_h264_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
static gboolean gst_uvc_h264_src_send_event (GstElement * element,
GstEvent * event);
static gboolean gst_uvc_h264_src_construct_pipeline (GstBaseCameraSrc *
@@ -231,17 +202,18 @@ static gboolean gst_uvc_h264_src_start_capture (GstBaseCameraSrc * camerasrc);
static void gst_uvc_h264_src_stop_capture (GstBaseCameraSrc * camerasrc);
static GstStateChangeReturn gst_uvc_h264_src_change_state (GstElement * element,
GstStateChange trans);
-static gboolean gst_uvc_h264_src_buffer_probe (GstPad * pad,
- GstBuffer * buffer, gpointer user_data);
-static gboolean gst_uvc_h264_src_event_probe (GstPad * pad,
- GstEvent * event, gpointer user_data);
+static GstPadProbeReturn gst_uvc_h264_src_buffer_probe (GstPad * pad,
+ GstPadProbeInfo * info, gpointer user_data);
+static GstPadProbeReturn gst_uvc_h264_src_event_probe (GstPad * pad,
+ GstPadProbeInfo * info, gpointer user_data);
static void gst_uvc_h264_src_pad_linking_cb (GstPad * pad,
GstPad * peer, gpointer user_data);
-static GstCaps *gst_uvc_h264_src_getcaps (GstPad * pad);
+static gboolean gst_uvc_h264_src_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
-static void v4l2src_prepare_format (GstElement * v4l2src, gint fd, guint fourcc,
- guint width, guint height, gpointer user_data);
+static void v4l2src_prepare_format (GstElement * v4l2src, gint fd,
+ GstCaps * caps, gpointer user_data);
static void fill_probe_commit (GstUvcH264Src * self,
uvcx_video_config_probe_commit_t * probe, guint32 frame_interval,
guint32 width, guint32 height, guint32 profile,
@@ -268,42 +240,14 @@ static gboolean gst_uvc_h264_src_get_int_setting (GstUvcH264Src * self,
gchar * property, gint * min, gint * def, gint * max);
static void
-gst_uvc_h264_src_base_init (gpointer g_class)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
- GstPadTemplate *pt;
-
- GST_DEBUG_CATEGORY_INIT (uvc_h264_src_debug, "uvch264_src",
- 0, "UVC H264 Compliant camera bin source");
-
- gst_element_class_set_static_metadata (gstelement_class,
- "UVC H264 Source",
- "Source/Video",
- "UVC H264 Encoding camera source",
- "Youness Alaoui <youness.alaoui@collabora.co.uk>");
-
- /* Don't use gst_element_class_add_static_pad_template in order to keep
- * the plugin compatible with gst 0.10.35 */
- pt = gst_static_pad_template_get (&vidsrc_template);
- gst_element_class_add_pad_template (gstelement_class, pt);
- gst_object_unref (pt);
-
- pt = gst_static_pad_template_get (&imgsrc_template);
- gst_element_class_add_pad_template (gstelement_class, pt);
- gst_object_unref (pt);
-
- pt = gst_static_pad_template_get (&vfsrc_template);
- gst_element_class_add_pad_template (gstelement_class, pt);
- gst_object_unref (pt);
-}
-
-static void
gst_uvc_h264_src_class_init (GstUvcH264SrcClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseCameraSrcClass *gstbasecamerasrc_class;
+ parent_class = g_type_class_peek_parent (klass);
+
gobject_class = G_OBJECT_CLASS (klass);
gstelement_class = GST_ELEMENT_CLASS (klass);
gstbasecamerasrc_class = GST_BASE_CAMERA_SRC_CLASS (klass);
@@ -321,6 +265,24 @@ gst_uvc_h264_src_class_init (GstUvcH264SrcClass * klass)
gstbasecamerasrc_class->start_capture = gst_uvc_h264_src_start_capture;
gstbasecamerasrc_class->stop_capture = gst_uvc_h264_src_stop_capture;
+ GST_DEBUG_CATEGORY_INIT (uvc_h264_src_debug, "uvch264_src",
+ 0, "UVC H264 Compliant camera bin source");
+
+ gst_element_class_set_static_metadata (gstelement_class,
+ "UVC H264 Source",
+ "Source/Video",
+ "UVC H264 Encoding camera source",
+ "Youness Alaoui <youness.alaoui@collabora.co.uk>");
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&vidsrc_template));
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&imgsrc_template));
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&vfsrc_template));
+
/* Properties */
g_object_class_install_property (gobject_class, PROP_COLORSPACE_NAME,
g_param_spec_string ("colorspace-name", "colorspace element name",
@@ -519,17 +481,16 @@ gst_uvc_h264_src_class_init (GstUvcH264SrcClass * klass)
G_CALLBACK (gst_uvc_h264_src_get_int_setting), NULL, NULL, NULL,
G_TYPE_BOOLEAN, 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER,
G_TYPE_POINTER, 0);
-
}
static void
-gst_uvc_h264_src_init (GstUvcH264Src * self, GstUvcH264SrcClass * klass)
+gst_uvc_h264_src_init (GstUvcH264Src * self)
{
self->vfsrc =
gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
GST_PAD_SRC);
- gst_pad_set_getcaps_function (self->vfsrc,
- GST_DEBUG_FUNCPTR (gst_uvc_h264_src_getcaps));
+ gst_pad_set_query_function (self->vfsrc,
+ GST_DEBUG_FUNCPTR (gst_uvc_h264_src_query));
gst_element_add_pad (GST_ELEMENT (self), self->vfsrc);
self->imgsrc =
@@ -540,15 +501,15 @@ gst_uvc_h264_src_init (GstUvcH264Src * self, GstUvcH264SrcClass * klass)
self->vidsrc =
gst_ghost_pad_new_no_target (GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME,
GST_PAD_SRC);
- gst_pad_set_getcaps_function (self->vidsrc,
- GST_DEBUG_FUNCPTR (gst_uvc_h264_src_getcaps));
+ gst_pad_set_query_function (self->vidsrc,
+ GST_DEBUG_FUNCPTR (gst_uvc_h264_src_query));
gst_element_add_pad (GST_ELEMENT (self), self->vidsrc);
- gst_pad_add_buffer_probe (self->vidsrc,
- (GCallback) gst_uvc_h264_src_buffer_probe, self);
- gst_pad_add_event_probe (self->vfsrc,
- (GCallback) gst_uvc_h264_src_event_probe, self);
- gst_pad_add_event_probe (self->vidsrc,
- (GCallback) gst_uvc_h264_src_event_probe, self);
+ gst_pad_add_probe (self->vidsrc, GST_PAD_PROBE_TYPE_BUFFER,
+ gst_uvc_h264_src_buffer_probe, self, NULL);
+ gst_pad_add_probe (self->vfsrc, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
+ gst_uvc_h264_src_event_probe, self, NULL);
+ gst_pad_add_probe (self->vidsrc, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
+ gst_uvc_h264_src_event_probe, self, NULL);
self->srcpad_event_func = GST_PAD_EVENTFUNC (self->vfsrc);
@@ -1536,23 +1497,24 @@ gst_uvc_h264_src_get_int_setting (GstUvcH264Src * self, gchar * property,
return ret;
}
-static gboolean
-gst_uvc_h264_src_event_probe (GstPad * pad, GstEvent * event,
+static GstPadProbeReturn
+gst_uvc_h264_src_event_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer user_data)
{
GstUvcH264Src *self = GST_UVC_H264_SRC (user_data);
- gboolean ret = TRUE;
+ GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+ GstEvent *event = info->data;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
- ret = !self->reconfiguring;
+ ret = self->reconfiguring ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK;
break;
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
if (pad == self->vidsrc) {
- ret = !self->vid_newseg;
+ ret = self->vid_newseg ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK;
self->vid_newseg = TRUE;
} else if (pad == self->vfsrc) {
- ret = !self->vf_newseg;
+ ret = self->vf_newseg ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK;
self->vf_newseg = TRUE;
}
break;
@@ -1563,11 +1525,12 @@ gst_uvc_h264_src_event_probe (GstPad * pad, GstEvent * event,
return ret;
}
-static gboolean
-gst_uvc_h264_src_buffer_probe (GstPad * pad, GstBuffer * buffer,
+static GstPadProbeReturn
+gst_uvc_h264_src_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer user_data)
{
GstUvcH264Src *self = GST_UVC_H264_SRC (user_data);
+ GstBuffer *buffer = info->data;
/* TODO: Check the NALU type and make sure it is a keyframe */
if (self->key_unit_event) {
@@ -1760,22 +1723,17 @@ gst_uvc_h264_src_send_event (GstElement * element, GstEvent * event)
}
static gboolean
-gst_uvc_h264_src_event (GstPad * pad, GstEvent * event)
+gst_uvc_h264_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstUvcH264Src *self = GST_UVC_H264_SRC (GST_PAD_PARENT (pad));
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
if (!self->vid_newseg && pad == self->vidsrc) {
- gboolean update;
- gdouble rate, applied_rate;
- GstFormat format;
- gint64 start, stop, position;
-
- gst_event_parse_new_segment_full (event, &update, &rate,
- &applied_rate, &format, &start, &stop, &position);
- gst_segment_set_newsegment (&self->segment, update, rate, format,
- start, stop, position);
+ const GstSegment *s;
+
+ gst_event_parse_segment (event, &s);
+ gst_segment_copy_into (s, &self->segment);
}
break;
case GST_EVENT_FLUSH_STOP:
@@ -1791,7 +1749,7 @@ gst_uvc_h264_src_event (GstPad * pad, GstEvent * event)
return TRUE;
break;
}
- return self->srcpad_event_func (pad, event);
+ return self->srcpad_event_func (pad, parent, event);
}
static guint8
@@ -2094,14 +2052,11 @@ configure_h264 (GstUvcH264Src * self, gint fd)
}
static void
-v4l2src_prepare_format (GstElement * v4l2src, gint fd, guint fourcc,
- guint width, guint height, gpointer user_data)
+v4l2src_prepare_format (GstElement * v4l2src, gint fd, GstCaps * caps,
+ gpointer user_data)
{
GstUvcH264Src *self = GST_UVC_H264_SRC (user_data);
- GST_DEBUG_OBJECT (self, "v4l2src prepare-format with FCC %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
-
if (self->main_format == UVC_H264_SRC_FORMAT_H264) {
/* TODO: update static controls and g_object_notify those that changed */
configure_h264 (self, fd);
@@ -2237,7 +2192,7 @@ _transform_caps (GstUvcH264Src * self, GstCaps * caps, const gchar * name)
goto error_remove;
GST_DEBUG_OBJECT (self, "Transforming: %" GST_PTR_FORMAT, caps);
- out_caps = gst_pad_get_caps (sink);
+ caps = gst_pad_query_caps (sink, NULL);
gst_object_unref (sink);
GST_DEBUG_OBJECT (self, "Result: %" GST_PTR_FORMAT, out_caps);
@@ -2257,33 +2212,30 @@ done:
static GstCaps *
gst_uvc_h264_src_transform_caps (GstUvcH264Src * self, GstCaps * caps)
{
- GstCaps *h264 = gst_caps_new_simple ("video/x-h264", NULL);
- GstCaps *jpg = gst_caps_new_simple ("image/jpeg", NULL);
+ GstCaps *h264 = gst_caps_new_empty_simple ("video/x-h264");
+ GstCaps *jpg = gst_caps_new_empty_simple ("image/jpeg");
GstCaps *h264_caps = gst_caps_intersect (h264, caps);
GstCaps *jpg_caps = gst_caps_intersect (jpg, caps);
/* TODO: Keep caps order after transformation */
caps = _transform_caps (self, caps, self->colorspace_name);
+ caps = gst_caps_make_writable (caps);
if (!gst_caps_is_empty (h264_caps)) {
- GstCaps *temp = gst_caps_union (caps, h264_caps);
- gst_caps_unref (caps);
- caps = temp;
+ gst_caps_append (caps, h264_caps);
+ } else {
+ gst_caps_unref (h264_caps);
}
+
if (!gst_caps_is_empty (jpg_caps)) {
- GstCaps *temp = gst_caps_union (caps, jpg_caps);
- gst_caps_unref (caps);
- caps = temp;
+ gst_caps_append (caps, jpg_caps);
+ } else {
+ gst_caps_unref (jpg_caps);
}
- if (h264_caps)
- gst_caps_unref (h264_caps);
- if (jpg_caps)
- gst_caps_unref (jpg_caps);
gst_caps_unref (h264);
gst_caps_unref (jpg);
-
return caps;
}
@@ -2305,7 +2257,6 @@ gst_uvc_h264_src_fixate_caps (GstUvcH264Src * self, GstPad * v4l_pad,
GST_CAPS_INTERSECT_FIRST);
GST_DEBUG_OBJECT (self, "intersect: %" GST_PTR_FORMAT, tcaps);
icaps = gst_caps_normalize (tcaps);
- gst_caps_unref (tcaps);
/* Prefer the first caps we are compatible with that the peer proposed */
for (i = 0; i < gst_caps_get_size (icaps); i++) {
@@ -2358,14 +2309,14 @@ gst_uvc_h264_src_fixate_caps (GstUvcH264Src * self, GstPad * v4l_pad,
guint32 interval;
if (_extract_caps_info (s, &width, &height, &interval)) {
- if (gst_structure_has_name (s, "video/x-raw-yuv")) {
- guint32 fcc = 0;
+ if (gst_structure_has_name (s, "video/x-raw")) {
guint8 mux = 0;
+ const gchar *format = gst_structure_get_string (s, "format");
- if (gst_structure_get_fourcc (s, "format", &fcc)) {
- if (fcc == GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'))
+ if ((format = gst_structure_get_string (s, "format"))) {
+ if (g_strcmp0 (format, "YUY2") == 0)
mux = 4;
- else if (fcc == GST_MAKE_FOURCC ('N', 'V', '1', '2'))
+ else if (g_strcmp0 (format, "NV12") == 0)
mux = 8;
}
if (mux != 0) {
@@ -2416,11 +2367,10 @@ gst_uvc_h264_src_fixate_caps (GstUvcH264Src * self, GstPad * v4l_pad,
if (caps) {
caps = gst_caps_make_writable (caps);
- gst_caps_truncate (caps);
/* now fixate */
if (!gst_caps_is_empty (caps)) {
- gst_pad_fixate_caps (v4l_pad, caps);
+ caps = gst_caps_fixate (caps);
GST_DEBUG_OBJECT (self, "fixated to: %" GST_PTR_FORMAT, caps);
}
@@ -2474,16 +2424,19 @@ gst_uvc_h264_src_destroy_pipeline (GstUvcH264Src * self, gboolean v4l2src)
iter = gst_bin_iterate_elements (GST_BIN (self));
done = FALSE;
while (!done) {
- GstElement *item = NULL;
+ GValue data = { 0, };
- switch (gst_iterator_next (iter, (gpointer *) & item)) {
+ switch (gst_iterator_next (iter, &data)) {
case GST_ITERATOR_OK:
- if (item != self->v4l2_src) {
- gst_bin_remove (GST_BIN (self), item);
- gst_element_set_state (item, GST_STATE_NULL);
+ {
+ GstElement *child = g_value_get_object (&data);
+ if (child != self->v4l2_src) {
+ gst_bin_remove (GST_BIN (self), child);
+ gst_element_set_state (child, GST_STATE_NULL);
}
- gst_object_unref (item);
+ g_value_reset (&data);
break;
+ }
case GST_ITERATOR_RESYNC:
gst_iterator_resync (iter);
break;
@@ -2608,8 +2561,8 @@ gst_uvc_h264_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), NULL);
gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), NULL);
- vf_caps = gst_pad_peer_get_caps (self->vfsrc);
- vid_caps = gst_pad_peer_get_caps (self->vidsrc);
+ vf_caps = gst_pad_peer_query_caps (self->vfsrc, NULL);
+ vid_caps = gst_pad_peer_query_caps (self->vidsrc, NULL);
GST_DEBUG_OBJECT (self, "vfsrc caps : %" GST_PTR_FORMAT, vf_caps);
GST_DEBUG_OBJECT (self, "vidsrc caps : %" GST_PTR_FORMAT, vid_caps);
@@ -2621,7 +2574,7 @@ gst_uvc_h264_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
}
v4l_pad = gst_element_get_static_pad (self->v4l2_src, "src");
- v4l_caps = gst_pad_get_caps (v4l_pad);
+ v4l_caps = gst_pad_query_caps (v4l_pad, NULL);
GST_DEBUG_OBJECT (self, "v4l2src caps : %" GST_PTR_FORMAT, v4l_caps);
if (vid_caps) {
GstCaps *trans_caps = gst_uvc_h264_src_transform_caps (self, vid_caps);
@@ -2926,8 +2879,8 @@ gst_uvc_h264_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
}
if (!gst_element_link (self->v4l2_src, tee))
goto error_remove_all;
- vf_pad = gst_element_get_request_pad (tee, "src%d");
- vid_pad = gst_element_get_request_pad (tee, "src%d");
+ vf_pad = gst_element_get_request_pad (tee, "src_%u");
+ vid_pad = gst_element_get_request_pad (tee, "src_%u");
}
break;
}
@@ -2968,16 +2921,18 @@ gst_uvc_h264_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
iter = gst_bin_iterate_elements (GST_BIN (self));
iter_done = FALSE;
while (!iter_done) {
- GstElement *item = NULL;
+ GstElement *child = NULL;
+ GValue data = { 0, };
- switch (gst_iterator_next (iter, (gpointer *) & item)) {
+ switch (gst_iterator_next (iter, &data)) {
case GST_ITERATOR_OK:
- if (!gst_element_sync_state_with_parent (item)) {
- gst_object_unref (item);
+ child = g_value_get_object (&data);
+ if (!gst_element_sync_state_with_parent (child)) {
+ g_value_reset (&data);
gst_iterator_free (iter);
goto error_remove_all;
}
- gst_object_unref (item);
+ g_value_reset (&data);
break;
case GST_ITERATOR_RESYNC:
gst_iterator_resync (iter);
@@ -3039,9 +2994,9 @@ error:
}
static GstCaps *
-gst_uvc_h264_src_getcaps (GstPad * pad)
+gst_uvc_h264_src_getcaps (GstPad * pad, GstObject * parent)
{
- GstUvcH264Src *self = GST_UVC_H264_SRC (GST_OBJECT_PARENT (pad));
+ GstUvcH264Src *self = GST_UVC_H264_SRC (parent);
GstCaps *template = NULL;
GstCaps *result = NULL;
@@ -3054,7 +3009,7 @@ gst_uvc_h264_src_getcaps (GstPad * pad)
if (self->v4l2_src) {
GstPad *v4l_pad = gst_element_get_static_pad (self->v4l2_src, "src");
- GstCaps *v4l_caps = gst_pad_get_caps (v4l_pad);
+ GstCaps *v4l_caps = gst_pad_query_caps (v4l_pad, NULL);
GstCaps *new_caps = gst_uvc_h264_src_transform_caps (self, v4l_caps);
result = gst_caps_intersect (new_caps, template);
@@ -3070,6 +3025,23 @@ gst_uvc_h264_src_getcaps (GstPad * pad)
}
static gboolean
+gst_uvc_h264_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+ gboolean ret = FALSE;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ gst_query_set_caps_result (query, gst_uvc_h264_src_getcaps (pad, parent));
+ ret = TRUE;
+ default:
+ ret = gst_pad_query_default (pad, parent, query);
+ break;
+ }
+ return ret;
+}
+
+
+static gboolean
gst_uvc_h264_src_set_mode (GstBaseCameraSrc * bcamsrc, GstCameraBinMode mode)
{
GstUvcH264Src *self = GST_UVC_H264_SRC (bcamsrc);