summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b14e905)
raw | patch | inline | side by side (parent: b14e905)
author | Harinarayan Bhatta <harinarayan@ti.com> | |
Wed, 28 Jan 2015 11:22:32 +0000 (16:52 +0530) | ||
committer | Harinarayan Bhatta <harinarayan@ti.com> | |
Tue, 3 Feb 2015 09:32:02 +0000 (15:02 +0530) |
Various changes as suggested by gstreamer 1.x porting
guide.
Signed-off-by: Pooja Prajod <poojaprajod@ti.com>
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
guide.
Signed-off-by: Pooja Prajod <poojaprajod@ti.com>
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
Makefile.am | patch | blob | history | |
configure.ac | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/gstvpe.c | patch | blob | history | |
src/gstvpe.h | patch | blob | history | |
src/gstvpebins.c | patch | blob | history | |
src/gstvpebins.h | patch | blob | history | |
src/gstvpebuffer.c | patch | blob | history | |
src/gstvpebufferpool.c | patch | blob | history |
diff --git a/Makefile.am b/Makefile.am
index d7de68a35435bc83fa2fe5b08e1782995710355c..120fc1106d440344ddc8e8b4ee5f51b875098c2c 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
-SUBDIRS = src tests/vpetest tests/perf
-
+SUBDIRS = src
+# tests/vpetest tests/perf
EXTRA_DIST = autogen.sh m4 po
diff --git a/configure.ac b/configure.ac
index d2480213ba2ead3e9c0b8b9964b4c430c51a8048..7c95086040baea5c7b61466295cc8f0d4bd1a793 100644 (file)
--- a/configure.ac
+++ b/configure.ac
AC_PREREQ([2.53])
dnl TODO: fill in your package name and package version here
-AC_INIT([gst-vpe],[0.10.0])
+AC_INIT([gst-vpe],[1.0.0])
dnl required versions of gstreamer and plugins-base
-GST_MAJORMINOR=0.10
-GST_REQUIRED=0.10.30
+GST_MAJORMINOR=1.0
+GST_REQUIRED=1.2.3
AC_CONFIG_SRCDIR([src/gstvpe.c])
AC_CONFIG_HEADERS([config.h])
dnl Check for the required version of GStreamer core (and gst-plugins-base)
dnl This will export GST_CFLAGS and GST_LIBS variables for use in Makefile.am
PKG_CHECK_MODULES(GST, [
- gstreamer-0.10 >= $GST_REQUIRED
- gstreamer-base-0.10 >= $GST_REQUIRED
- gstreamer-plugins-base-0.10 >= $GST_REQUIRED
- gstreamer-plugins-bad-0.10
+ gstreamer-1.0 >= $GST_REQUIRED
+ gstreamer-base-1.0 >= $GST_REQUIRED
+ gstreamer-plugins-base-1.0 >= $GST_REQUIRED
+ gstreamer-plugins-bad-1.0
], [
AC_SUBST(GST_CFLAGS)
AC_SUBST(GST_LIBS)
GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS"
AC_SUBST(GST_PLUGIN_LDFLAGS)
-AC_CONFIG_FILES([Makefile src/Makefile tests/vpetest/Makefile tests/perf/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 6797778d261d9ad54dec5cb5c003f16b69df0550..e047bd5d6e37b4b6e06b100ff11c856cda81382f 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
# headers we need but don't want installed
noinst_HEADERS = \
- gstvpebins.h \
gstvpe.h
+# gstvpebins.h
# sources used to compile this plug-in
libgstvpe_la_SOURCES = \
gstvpe.c \
gstvpebuffer.c \
gstvpebufferpool.c \
- gstvpebins.c \
$(noinst_HEADERS)
+# gstvpebins.c
# compiler and linker flags used to compile this plugin, set in configure.ac
libgstvpe_la_CFLAGS = \
$(GST_CFLAGS) \
libgstvpe_la_LIBADD = \
$(GST_LIBS) \
$(LIBDCE_LIBS) \
- -lgstdmabuf-0.10 \
- -lgstdrm-0.10 \
- -lgstvideo-0.10 \
- -lgstbasevideo-0.10
+ -lgstdmabuf-1.0 \
+ -lgstdrm-1.0 \
+ -lgstvideo-1.0
libgstvpe_la_LDFLAGS = \
$(GST_PLUGIN_LDFLAGS) \
diff --git a/src/gstvpe.c b/src/gstvpe.c
index eaf9c842a89dbdd9e1c438246a6b36b784321e30..bd8e80973c771f4764839bf4aa6640ca95dd01e3 100644 (file)
--- a/src/gstvpe.c
+++ b/src/gstvpe.c
#endif
-GST_BOILERPLATE (GstVpe, gst_vpe, GstElement, GST_TYPE_ELEMENT);
+static void gst_vpe_class_init (GstVpeClass * klass);
+static void gst_vpe_init (GstVpe * self, gpointer klass);
+static void gst_vpe_base_init (gpointer gclass);
+static GstElementClass *parent_class = NULL;
+
+static gboolean gst_vpe_set_output_caps (GstVpe * self);
+
+GType
+gst_vpe_get_type (void)
+{
+ static GType vpe_type = 0;
+
+ if (!vpe_type) {
+ static const GTypeInfo vpe_info = {
+ sizeof (GstVpeClass),
+ (GBaseInitFunc) gst_vpe_base_init,
+ NULL,
+ (GClassInitFunc) gst_vpe_class_init,
+ NULL,
+ NULL,
+ sizeof (GstVpe),
+ 0,
+ (GInstanceInitFunc) gst_vpe_init,
+ };
+
+ vpe_type = g_type_register_static (GST_TYPE_ELEMENT,
+ "GstVpe", &vpe_info, 0);
+ }
+ return vpe_type;
+}
+
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12") ";"
- GST_VIDEO_CAPS_YUV ("YUYV") ";" GST_VIDEO_CAPS_YUV ("YUY2")));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12")
+ ";" GST_VIDEO_CAPS_MAKE ("YUYV")
+ ";" GST_VIDEO_CAPS_MAKE ("YUY2")));
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12") ";"
- GST_VIDEO_CAPS_YUV ("YUYV") ";" GST_VIDEO_CAPS_YUV ("YUY2")));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12")
+ ";" GST_VIDEO_CAPS_MAKE ("YUYV")
+ ";" GST_VIDEO_CAPS_MAKE ("YUY2")));
enum
{
gboolean match;
GstStructure *s;
gint w, h;
- guint32 fourcc;
+ guint32 fourcc = 0;
+ const gchar *fmt = NULL;
+
+ GST_DEBUG_OBJECT (self, "Input caps: %s", gst_caps_to_string (input_caps));
if (self->input_caps) {
match = gst_caps_is_strictly_equal (self->input_caps, input_caps);
s = gst_caps_get_structure (input_caps, 0);
- if (!gst_structure_get_fourcc (s, "format", &fourcc)) {
+ fmt = gst_structure_get_string (s, "format");
+ if (!fmt) {
return FALSE;
}
-
+ fourcc = GST_STR_FOURCC (fmt);
/* For interlaced streams, ducati decoder sets caps without the interlaced
* at first, and then changes it to set it as true or false, so if interlaced
* is false, we cannot assume that the stream is pass-through
{
GstCaps *outcaps;
GstStructure *s, *out_s;
- gboolean fixed_caps;
gint fps_n, fps_d;
gint par_width, par_height;
+ const gchar *fmt = NULL;
if (!self->input_caps)
return FALSE;
- s = gst_caps_get_structure (self->input_caps, 0);
+ if (self->fixed_caps)
+ return TRUE;
- fixed_caps = FALSE;
+ s = gst_caps_get_structure (self->input_caps, 0);
outcaps = gst_pad_get_allowed_caps (self->srcpad);
- if (outcaps) {
+ if (outcaps && !(self->output_caps
+ && gst_caps_is_strictly_equal (outcaps, self->output_caps))) {
GST_DEBUG_OBJECT (self, "Downstream allowed caps: %s",
gst_caps_to_string (outcaps));
out_s = gst_caps_get_structure (outcaps, 0);
+ fmt = gst_structure_get_string (out_s, "format");
+
if (out_s &&
gst_structure_get_int (out_s, "width", &self->output_width) &&
- gst_structure_get_int (out_s, "height", &self->output_height) &&
- gst_structure_get_fourcc (out_s, "format", &self->output_fourcc)) {
- fixed_caps = TRUE;
+ gst_structure_get_int (out_s, "height", &self->output_height) && fmt) {
+ self->output_fourcc = GST_STR_FOURCC (fmt);
+ GST_DEBUG_OBJECT (self, "Using downstream caps, fixed_caps = TRUE");
+ self->fixed_caps = TRUE;
}
}
- if (!fixed_caps) {
+ if (!self->fixed_caps) {
if (self->input_crop.c.width && self->interlaced) {
/* Ducati decoder had the habit of setting height as half frame hight for
* interlaced streams */
- self->output_height = (self->interlaced) ? self->input_crop.c.height * 2 :
- self->input_crop.c.height;
+ self->output_height =
+ (self->interlaced) ? self->input_crop.c.height *
+ 2 : self->input_crop.c.height;
self->output_width = self->input_crop.c.width;
} else {
self->output_height = self->input_height;
gst_caps_unref (outcaps);
- outcaps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, self->output_fourcc, NULL);
+ outcaps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING,
+ gst_video_format_to_string
+ (gst_video_format_from_fourcc (self->output_fourcc)), NULL);
out_s = gst_caps_get_structure (outcaps, 0);
gst_vpe_init_output_buffers (GstVpe * self)
{
int i;
- GstVpeBuffer *buf;
+ GstBuffer *buf;
+ if (!self->output_caps) {
+ GST_DEBUG_OBJECT (self,
+ "Output caps should be set before init output buffer");
+ return FALSE;
+ }
self->output_pool =
gst_vpe_buffer_pool_new (TRUE, self->num_output_buffers,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, self->output_caps);
if (!self->output_pool) {
return FALSE;
}
if (!buf) {
return FALSE;
}
- gst_buffer_set_caps (GST_BUFFER (buf), self->output_caps);
+
gst_vpe_buffer_pool_put (self->output_pool, buf);
/* gst_vpe_buffer_pool_put keeps a reference of the buffer,
- * so, unref ours */
- gst_buffer_unref (GST_BUFFER (buf));
+ * so, unref ours
+ gst_buffer_unref (GST_BUFFER (buf)); */
}
return TRUE;
}
gst_vpe_init_input_buffers (GstVpe * self, gint num_input_buffers)
{
int i;
- GstVpeBuffer *buf;
+ GstBuffer *buf;
+ if (!self->input_caps) {
+ GST_DEBUG_OBJECT (self,
+ "Input caps should be set before init input buffer");
+ return FALSE;
+ }
self->input_pool =
gst_vpe_buffer_pool_new (FALSE, num_input_buffers,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, self->input_caps);
if (!self->input_pool) {
return FALSE;
}
if (!gst_vpe_buffer_pool_put (self->input_pool, buf))
return FALSE;
- /* gst_vpe_buffer_pool_put function keeps a reference, so give up ours */
- gst_buffer_unref (GST_BUFFER (buf));
}
return TRUE;
}
GST_DEBUG_OBJECT (self,
"input S_FMT field: %d, image: %dx%d, numbufs: %d",
- fmt.fmt.pix_mp.field, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
- self->num_input_buffers);
+ fmt.fmt.pix_mp.field, fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height, self->num_input_buffers);
ret = ioctl (self->video_fd, VIDIOC_S_FMT, &fmt);
if (ret < 0) {
GST_ERROR_OBJECT (self, "VIDIOC_S_FMT failed");
}
if (self->input_crop.c.width != 0) {
+ GST_DEBUG_OBJECT (self,
+ "Crop values: top: %d, left: %d, width: %d, height: %d",
+ self->input_crop.c.top, self->input_crop.c.left,
+ self->input_crop.c.width, self->input_crop.c.height);
+
ret = ioctl (self->video_fd, VIDIOC_S_CROP, &self->input_crop);
if (ret < 0) {
GST_ERROR_OBJECT (self, "VIDIOC_S_CROP failed");
return TRUE;
}
-static void
-gst_vpe_try_dequeue (GstVpeBufferPool * pool)
-{
- GstVpeBuffer *buf;
- while (1) {
- buf = gst_vpe_buffer_pool_dequeue (pool);
- if (buf) {
- gst_buffer_unref (GST_BUFFER (buf));
- } else
- break;
- }
-}
static void
gst_vpe_output_loop (gpointer data)
{
GstVpe *self = (GstVpe *) data;
- GstVpeBuffer *buf = NULL;
+ GstBuffer *buf = NULL;
GST_OBJECT_LOCK (self);
if (self->output_pool)
- buf = gst_vpe_buffer_pool_dequeue (self->output_pool);
+ (void) gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (self->output_pool),
+ &buf, NULL);
GST_OBJECT_UNLOCK (self);
if (buf) {
- GST_DEBUG_OBJECT (self, "push: %" GST_TIME_FORMAT " (%d bytes, ptr %p)",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_SIZE (buf), buf);
+ GST_DEBUG_OBJECT (self, "push: %" GST_TIME_FORMAT " (ptr %p)",
+ GST_TIME_ARGS (GST_BUFFER_PTS (buf)), buf);
gst_pad_push (self->srcpad, GST_BUFFER (buf));
} else
usleep (10000);
gst_vpe_input_set_fmt (self);
gst_vpe_output_set_fmt (self);
if (self->input_pool)
- gst_vpe_buffer_pool_set_streaming (self->input_pool, self->video_fd,
- streaming, self->interlaced);
+ gst_vpe_buffer_pool_set_streaming (self->input_pool,
+ self->video_fd, streaming, self->interlaced);
if (self->output_pool)
- gst_vpe_buffer_pool_set_streaming (self->output_pool, self->video_fd,
- streaming, FALSE);
+ gst_vpe_buffer_pool_set_streaming (self->output_pool,
+ self->video_fd, streaming, FALSE);
} else {
GST_DEBUG_OBJECT (self, "streaming already on");
}
} else {
if (self->video_fd >= 0) {
if (self->input_pool)
- gst_vpe_buffer_pool_set_streaming (self->input_pool, self->video_fd,
- streaming, self->interlaced);
+ gst_vpe_buffer_pool_set_streaming (self->input_pool,
+ self->video_fd, streaming, self->interlaced);
if (self->output_pool)
- gst_vpe_buffer_pool_set_streaming (self->output_pool, self->video_fd,
- streaming, FALSE);
+ gst_vpe_buffer_pool_set_streaming (self->output_pool,
+ self->video_fd, streaming, FALSE);
close (self->video_fd);
self->video_fd = -1;
} else {
if (self->output_caps)
gst_caps_unref (self->output_caps);
self->output_caps = NULL;
+ self->fixed_caps = FALSE;
if (self->input_pool) {
gst_vpe_buffer_pool_destroy (self->input_pool);
GST_DEBUG_OBJECT (self, "gst_vpe_buffer_pool_destroy(input) done");
}
static gboolean
-gst_vpe_activate_push (GstPad * pad, gboolean active)
+gst_vpe_activate_mode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
- gboolean result = TRUE;
- GstVpe *self;
- self = GST_VPE (GST_OBJECT_PARENT (pad));
- GST_DEBUG_OBJECT (self, "gst_vpe_activate_push (active = %d)", active);
- if (!active) {
- result = gst_pad_stop_task (self->srcpad);
- GST_DEBUG_OBJECT (self, "task gst_vpe_output_loop stopped");
- } else {
- result = gst_pad_start_task (self->srcpad, gst_vpe_output_loop, self);
- GST_DEBUG_OBJECT (self, "gst_pad_start_task returned %d", result);
+ if (mode == GST_PAD_MODE_PUSH) {
+ gboolean result = TRUE;
+ GstVpe *self;
+ self = GST_VPE (parent);
+ GST_DEBUG_OBJECT (self, "gst_vpe_activate_mode (active = %d)", active);
+ if (!active) {
+ result = gst_pad_stop_task (self->srcpad);
+ GST_DEBUG_OBJECT (self, "task gst_vpe_output_loop stopped");
+ } else {
+ result =
+ gst_pad_start_task (self->srcpad, gst_vpe_output_loop, self, NULL);
+ GST_DEBUG_OBJECT (self, "gst_pad_start_task returned %d", result);
+ }
+ return result;
}
- return result;
+ return FALSE;
}
static gboolean
GstVpe *self = GST_VPE (gst_pad_get_parent (pad));
if (caps) {
GST_OBJECT_LOCK (self);
- ret = gst_vpe_parse_input_caps (self, caps);
+ if (TRUE == (ret = gst_vpe_parse_input_caps (self, caps))) {
+ ret = gst_vpe_set_output_caps (self);
+ }
GST_OBJECT_UNLOCK (self);
+
+ if (TRUE == ret) {
+ gst_pad_set_caps (self->srcpad, self->output_caps);
+ }
+
GST_INFO_OBJECT (self, "set caps done %d", ret);
}
gst_object_unref (self);
return ret;
}
-
static GstCaps *
-gst_vpe_src_getcaps (GstPad * pad)
+gst_vpe_getcaps (GstPad * pad)
{
GstCaps *caps = NULL;
- caps = GST_PAD_CAPS (pad);
+ caps = gst_pad_get_current_caps (pad);
if (caps == NULL) {
- return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ GstCaps *fil = gst_pad_get_pad_template_caps (pad);
+ return gst_caps_copy (fil);
} else {
return gst_caps_copy (caps);
}
}
static gboolean
-gst_vpe_query (GstVpe * self, GstPad * pad,
- GstQuery * query, gboolean * forward)
+gst_vpe_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
- gboolean res = TRUE;
- *forward = TRUE;
+ GstVpe *self = GST_VPE (parent);
+
switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_BUFFERS:
- /* TODO: */
- break;
- case GST_QUERY_LATENCY:
- /* TODO: */
- break;
- default:
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *caps;
+ caps = gst_vpe_getcaps (pad);
+ gst_query_set_caps_result (query, caps);
+ return TRUE;
break;
- }
- return res;
-}
+ }
+ case GST_QUERY_ALLOCATION:
+ {
+ GstCaps *caps;
+ gst_query_parse_allocation (query, &caps, NULL);
-static gboolean
-gst_vpe_src_query (GstPad * pad, GstQuery * query)
-{
- gboolean res = TRUE, forward = TRUE;
- GstVpe *self = GST_VPE (GST_OBJECT_PARENT (pad));
- GstVpeClass *klass = GST_VPE_GET_CLASS (self);
- GST_DEBUG_OBJECT (self, "query: %" GST_PTR_FORMAT, query);
- res = gst_vpe_query (self, pad, query, &forward);
- if (res && forward)
- res = gst_pad_query_default (pad, query);
- return res;
-}
+ if (caps == NULL)
+ return FALSE;
-static GstFlowReturn
-gst_vpe_bufferalloc (GstPad * pad, guint64 offset, guint size,
- GstCaps * caps, GstBuffer ** buf)
-{
- GstVpe *self;
- self = GST_VPE (GST_OBJECT_PARENT (pad));
- do {
- GST_OBJECT_LOCK (self);
- if (G_UNLIKELY (self->state == GST_VPE_ST_DEINIT)) {
- GST_OBJECT_UNLOCK (self);
- GST_WARNING_OBJECT (self,
- "Plugin is shutting down, returning GST_FLOW_WRONG_STATE");
- return GST_FLOW_WRONG_STATE;
- }
- if (G_UNLIKELY (NULL == self->input_pool)) {
- if (!gst_vpe_init_input_bufs (self, caps)) {
+ GST_OBJECT_LOCK (self);
+ if (G_UNLIKELY (self->state == GST_VPE_ST_DEINIT)) {
GST_OBJECT_UNLOCK (self);
- return GST_FLOW_ERROR;
+ GST_WARNING_OBJECT (self, "Plugin is shutting down, returning FALSE");
+ return FALSE;
}
- }
-
- /* Try dequeueing some buffers */
- gst_vpe_try_dequeue (self->input_pool);
- *buf = GST_BUFFER (gst_vpe_buffer_pool_get (self->input_pool));
- if (*buf) {
+ if (G_UNLIKELY (NULL == self->input_pool)) {
+ if (!gst_vpe_init_input_bufs (self, caps)) {
+ GST_OBJECT_UNLOCK (self);
+ return FALSE;
+ }
+ }
+ gst_query_add_allocation_pool (query,
+ GST_BUFFER_POOL (self->input_pool), 1, 0, self->num_input_buffers);
GST_OBJECT_UNLOCK (self);
- gst_buffer_set_caps (*buf, caps);
- return GST_FLOW_OK;
+ return TRUE;
+ break;
}
- GST_OBJECT_UNLOCK (self);
- usleep (10000);
- } while (1);
+ case GST_QUERY_LATENCY:
+ /* TODO: */
+ break;
+ default:
+ break;
+ }
+ return gst_pad_query_default (pad, parent, query);
}
-
static GstFlowReturn
-gst_vpe_chain (GstPad * pad, GstBuffer * buf)
+gst_vpe_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
- GstVpe *self = GST_VPE (GST_OBJECT_PARENT (pad));
- GstEvent *e = NULL;
+ GstVpe *self = GST_VPE (parent);
+ GstMetaVpeBuffer *vpe_buf = gst_buffer_get_vpe_buffer_meta (buf);
- GST_DEBUG_OBJECT (self, "chain: %" GST_TIME_FORMAT " (%d bytes, ptr %p)",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_SIZE (buf), buf);
+ GST_DEBUG_OBJECT (self, "chain: %" GST_TIME_FORMAT " ( ptr %p)",
+ GST_TIME_ARGS (GST_BUFFER_PTS (buf)), buf);
GST_OBJECT_LOCK (self);
if (G_UNLIKELY (self->state != GST_VPE_ST_ACTIVE)) {
gst_buffer_unref (buf);
return GST_FLOW_OK;
} else {
- if (gst_vpe_start (self, GST_BUFFER_CAPS (buf))) {
- if (self->passthrough && self->input_crop.c.width != 0) {
- /* If passthrough, use original crop event to send downstream */
- e = gst_event_new_crop (self->input_crop.c.top,
- self->input_crop.c.left, self->input_crop.c.width,
- self->input_crop.c.height);
- } else {
- e = gst_event_new_crop (0, 0, self->output_width,
- self->output_height);
+ if (self->input_crop.c.width == 0) {
+ GstVideoCropMeta *crop = gst_buffer_get_video_crop_meta (buf);
+ if (crop) {
+ self->input_crop.c.left = crop->y;
+ self->input_crop.c.top = crop->x;
+ self->input_crop.c.width = crop->width;
+ self->input_crop.c.height = crop->height;
}
+ }
+ if (gst_vpe_start (self, gst_pad_get_current_caps (pad))) {
GST_OBJECT_UNLOCK (self);
/* Set output caps, this should be done outside the lock */
gst_pad_set_caps (self->srcpad, self->output_caps);
- gst_pad_push_event (self->srcpad, e);
GST_OBJECT_LOCK (self);
} else {
GST_OBJECT_UNLOCK (self);
GST_DEBUG_OBJECT (self, "Passthrough for VPE");
return gst_pad_push (self->srcpad, buf);
}
- if (GST_IS_VPE_BUFFER (buf)) {
- GstVpeBuffer *vpe_buf = GST_VPE_BUFFER (buf);
+ if (vpe_buf) {
/* Push the buffer into the V4L2 driver */
- if (!gst_vpe_buffer_pool_queue (self->input_pool, vpe_buf)) {
+ if (!gst_vpe_buffer_pool_queue (self->input_pool, buf)) {
GST_OBJECT_UNLOCK (self);
return GST_FLOW_ERROR;
}
}
static gboolean
-gst_vpe_event (GstPad * pad, GstEvent * event)
+gst_vpe_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
- GstVpe *self = GST_VPE (GST_OBJECT_PARENT (pad));
+ GstVpe *self = GST_VPE (parent);
gboolean ret = TRUE;
GST_DEBUG_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_CAPS:
{
- gboolean update;
- GstFormat fmt;
- gint64 start, stop, time;
- gdouble rate, arate;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
- &start, &stop, &time);
- gst_segment_set_newsegment_full (&self->segment, update,
- rate, arate, fmt, start, stop, time);
- GST_DEBUG_OBJECT (self, "newsegment: start %" GST_TIME_FORMAT ", stop: %"
- GST_TIME_FORMAT ", rate: %2.2f", GST_TIME_ARGS (start),
- GST_TIME_ARGS (stop), rate);
- }
+ GstCaps *caps;
+ gst_event_parse_caps (event, &caps);
+ return gst_vpe_sink_setcaps (pad, caps);
break;
- case GST_EVENT_CROP:
+ }
+ case GST_EVENT_SEGMENT:
{
- gint left, top, width, height;
- gst_event_parse_crop (event, &top, &left, &width, &height);
- GST_OBJECT_LOCK (self);
- if (width == -1)
- width = self->input_width - left;
- if (height == -1)
- height = self->input_height - top;
- self->input_crop.c.top = top;
- self->input_crop.c.left = left;
- self->input_crop.c.width = width;
- self->input_crop.c.height = height;
- if (self->video_fd >= 0) {
- /* Set the crop value to the driver */
- ioctl (self->video_fd, VIDIOC_S_CROP, &self->input_crop);
- }
- GST_OBJECT_UNLOCK (self);
- gst_event_unref (event);
- return TRUE;
+ gst_event_copy_segment (event, &self->segment);
}
+ break;
+
case GST_EVENT_EOS:
break;
case GST_EVENT_FLUSH_STOP:
}
static gboolean
-gst_vpe_src_event (GstPad * pad, GstEvent * event)
+gst_vpe_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
- GstVpe *self = GST_VPE (GST_OBJECT_PARENT (pad));
+ GstVpe *self = GST_VPE (parent);
gboolean ret = TRUE;
GST_DEBUG_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
gst_vpe_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
- gst_element_class_set_details_simple (element_class,
+ gst_element_class_set_static_metadata (element_class,
"vpe",
"Filter/Converter/Video",
"Video processing adapter", "Harinarayan Bhatta <harinarayan@ti.com>");
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_vpe_get_property);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_vpe_set_property);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_vpe_finalize);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_vpe_change_state);
g_object_class_install_property (gobject_class,
- PROP_NUM_INPUT_BUFFERS, g_param_spec_int ("num-input-buffers",
+ PROP_NUM_INPUT_BUFFERS,
+ g_param_spec_int ("num-input-buffers",
"Number of input buffers that are allocated and used by this plugin.",
"The number if input buffers allocated should be specified based on "
"the upstream element's requirement. For example, if gst-ducati-plugin "
"is the upstream element, this value should be based on max-reorder-frames "
- "property of that element. 0 => decide automatically", 0,
- MAX_NUM_INBUFS, DEFAULT_NUM_INBUFS,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ "property of that element. 0 => decide automatically",
+ 0, MAX_NUM_INBUFS,
+ DEFAULT_NUM_INBUFS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_NUM_OUTPUT_BUFFERS,
g_param_spec_int ("num-output-buffers",
"Number of output buffers that are allocated and used by this plugin.",
"The number if output buffers allocated should be specified based on "
"the downstream element's requirement. It is generally set to the minimum "
"value acceptable to the downstream element to reduce memory usage.",
- 3, MAX_NUM_OUTBUFS, DEFAULT_NUM_OUTBUFS,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ 3, MAX_NUM_OUTBUFS,
+ DEFAULT_NUM_OUTBUFS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
-gst_vpe_init (GstVpe * self, GstVpeClass * klass)
+gst_vpe_init (GstVpe * self, gpointer klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
self->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
- gst_pad_set_setcaps_function (self->sinkpad,
- GST_DEBUG_FUNCPTR (gst_vpe_sink_setcaps));
gst_pad_set_chain_function (self->sinkpad, GST_DEBUG_FUNCPTR (gst_vpe_chain));
gst_pad_set_event_function (self->sinkpad, GST_DEBUG_FUNCPTR (gst_vpe_event));
- gst_pad_set_bufferalloc_function (self->sinkpad,
- GST_DEBUG_FUNCPTR (gst_vpe_bufferalloc));
self->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_event_function (self->srcpad,
GST_DEBUG_FUNCPTR (gst_vpe_src_event));
- gst_pad_set_query_function (self->srcpad,
- GST_DEBUG_FUNCPTR (gst_vpe_src_query));
- gst_pad_set_getcaps_function (self->srcpad,
- GST_DEBUG_FUNCPTR (gst_vpe_src_getcaps));
- gst_pad_set_activatepush_function (self->srcpad, gst_vpe_activate_push);
+ gst_pad_set_query_function (self->srcpad, GST_DEBUG_FUNCPTR (gst_vpe_query));
+ gst_pad_set_query_function (self->sinkpad, GST_DEBUG_FUNCPTR (gst_vpe_query));
+ gst_pad_set_activatemode_function (self->srcpad, gst_vpe_activate_mode);
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
self->input_width = 0;
self->video_fd = -1;
self->input_caps = NULL;
self->output_caps = NULL;
+ self->fixed_caps = FALSE;
self->num_input_buffers = DEFAULT_NUM_INBUFS;
self->num_output_buffers = DEFAULT_NUM_OUTBUFS;
gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
}
GST_DEBUG_CATEGORY (gst_vpe_debug);
-#include "gstvpebins.h"
+/* #include "gstvpebins.h" */
static gboolean
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gst_vpe_debug, "vpe", 0, "vpe");
- return (gst_element_register (plugin, "vpe", GST_RANK_NONE, GST_TYPE_VPE)
- && gst_element_register (plugin, "ducatih264decvpe",
- GST_RANK_PRIMARY + 1, gst_vpe_ducatih264dec_get_type ())
- && gst_element_register (plugin, "ducatimpeg2decvpe",
- GST_RANK_PRIMARY + 1, gst_vpe_ducatimpeg2dec_get_type ())
- && gst_element_register (plugin, "ducatimpeg4decvpe",
- GST_RANK_PRIMARY + 1, gst_vpe_ducatimpeg4dec_get_type ())
- && gst_element_register (plugin, "ducatijpegdecvpe",
- GST_RANK_PRIMARY + 2, gst_vpe_ducatijpegdec_get_type ())
- && gst_element_register (plugin, "ducativc1decvpe",
- GST_RANK_PRIMARY + 1, gst_vpe_ducativc1dec_get_type ()));
+ return (gst_element_register (plugin, "vpe", GST_RANK_NONE, GST_TYPE_VPE));
+ /* && gst_element_register (plugin, "ducatih264decvpe",
+ GST_RANK_PRIMARY + 1, gst_vpe_ducatih264dec_get_type ())
+ && gst_element_register (plugin, "ducatimpeg2decvpe",
+ GST_RANK_PRIMARY + 1, gst_vpe_ducatimpeg2dec_get_type ())
+ && gst_element_register (plugin, "ducatimpeg4decvpe",
+ GST_RANK_PRIMARY + 1, gst_vpe_ducatimpeg4dec_get_type ())
+ && gst_element_register (plugin, "ducatijpegdecvpe",
+ GST_RANK_PRIMARY + 2, gst_vpe_ducatijpegdec_get_type ())
+ && gst_element_register (plugin, "ducativc1decvpe",
+ GST_RANK_PRIMARY + 1, gst_vpe_ducativc1dec_get_type ())); */
}
/* PACKAGE: this is usually set by autotools depending on some _INIT macro
#define PACKAGE "vpeplugin"
#endif
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "vpeplugin",
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, vpeplugin,
"Hardware accelerated video porst-processing using TI VPE (V4L2-M2M) driver on DRA7x SoC",
plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
diff --git a/src/gstvpe.h b/src/gstvpe.h
index ddb34089213df85fcff7b5d5e1bd12d5795f91e7..d1233f5eea013a6779691276f9577cbca3607fd1 100644 (file)
--- a/src/gstvpe.h
+++ b/src/gstvpe.h
#include <omap_drm.h>
#include <omap_drmif.h>
#include <gst/video/video.h>
-#include <gst/video/video-crop.h>
+#include <gst/video/gstvideometa.h>
#include <linux/videodev2.h>
#include <linux/v4l2-controls.h>
typedef struct _GstVpe GstVpe;
typedef struct _GstVpeClass GstVpeClass;
-GType gst_vpe_buffer_get_type (void);
-#define GST_TYPE_VPE_BUFFER (gst_vpe_buffer_get_type())
-#define GST_IS_VPE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VPE_BUFFER))
-#define GST_VPE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VPE_BUFFER, GstVpeBuffer))
-#define GST_VPE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VPE_BUFFER, GstVpeBufferClass))
GType gst_vpe_buffer_pool_get_type (void);
#define GST_TYPE_VPE_BUFFER_POOL (gst_vpe_buffer_pool_get_type())
#define GST_VPE_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VPE_BUFFER_POOL, GstVpeBufferPoolClass))
typedef struct _GstVpeBufferPool GstVpeBufferPool;
-typedef struct _GstVpeBuffer GstVpeBuffer;
typedef struct _GstVpeBufferPoolClass GstVpeBufferPoolClass;
-typedef struct _GstVpeBufferClass GstVpeBufferClass;
struct _GstVpeBufferPool
{
- GstMiniObject parent;
+ GstBufferPool parent;
gboolean output_port; /* if true, unusued buffers are automatically re-QBUF'd */
GMutex lock;
guint32 last_field_pushed; /* Was the last field sent to the dirver top of bottom */
struct GstVpeBufferPoolBufTracking
{
- GstVpeBuffer *buf; /* Buffers that are part of this pool */
+ GstBuffer *buf; /* Buffers that are part of this pool */
gint state; /* state of the buffer, FREE, ALLOCATED, WITH_DRIVER */
gint q_cnt; /* Number of times this buffer is queued into the driver */
} *buf_tracking;
struct _GstVpeBufferPoolClass
{
- GstMiniObjectClass parent_class;
+ GstBufferPoolClass parent_class;
};
-struct _GstVpeBuffer
+typedef struct
{
- GstBuffer buffer;
+ GstMeta meta;
+
+ int size;
struct omap_bo *bo;
struct v4l2_buffer v4l2_buf;
struct v4l2_plane v4l2_planes[2];
GstVpeBufferPool *pool;
-};
+} GstMetaVpeBuffer;
-struct _GstVpeBufferClass
-{
- GstBufferClass parent_class;
-};
-GstVpeBuffer *gst_vpe_buffer_new (struct omap_device *dev,
+GstBuffer *gst_vpe_buffer_new (struct omap_device *dev,
guint32 fourcc, gint width, gint height, int index, guint32 v4l2_type);
+GstMetaVpeBuffer *gst_buffer_add_vpe_buffer_meta (GstBuffer * buf,
+ struct omap_device *dev, guint32 fourcc, gint width, gint height, int index,
+ guint32 v4l2_type);
+
+GstMetaVpeBuffer *gst_buffer_get_vpe_buffer_meta (GstBuffer * buf);
+
GstVpeBufferPool *gst_vpe_buffer_pool_new (gboolean output_port,
- guint buffer_count, guint32 v4l2_type);
+ guint buffer_count, guint32 v4l2_type, GstCaps * caps);
-gboolean gst_vpe_buffer_pool_put (GstVpeBufferPool * pool, GstVpeBuffer * buf);
+gboolean gst_vpe_buffer_pool_put (GstVpeBufferPool * pool, GstBuffer * buf);
-gboolean gst_vpe_buffer_pool_queue (GstVpeBufferPool * pool,
- GstVpeBuffer * buf);
+gboolean gst_vpe_buffer_pool_queue (GstVpeBufferPool * pool, GstBuffer * buf);
-GstVpeBuffer *gst_vpe_buffer_pool_dequeue (GstVpeBufferPool * pool);
+GstBuffer *gst_vpe_buffer_pool_dequeue (GstVpeBufferPool * pool);
-GstVpeBuffer *gst_vpe_buffer_pool_get (GstVpeBufferPool * pool);
+GstBuffer *gst_vpe_buffer_pool_get (GstVpeBufferPool * pool);
void gst_vpe_buffer_pool_destroy (GstVpeBufferPool * pool);
guint32 output_fourcc;
struct v4l2_crop input_crop;
gboolean interlaced;
+ gboolean fixed_caps;
gboolean passthrough;
GstSegment segment;
enum
diff --git a/src/gstvpebins.c b/src/gstvpebins.c
index cbf0174204463c19c1d381bcb24e72a36f1d9b74..f753699cb6b8b896b03f925fc765272546079ab5 100644 (file)
--- a/src/gstvpebins.c
+++ b/src/gstvpebins.c
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12")));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12")));
/* HACK!!: The following sink caps are copied from gst-plugins-ducati source
* If something changes there, the same should be changed here as well !!
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-wmv, "
"wmvversion = (int) 3, "
- "format = (fourcc){ WVC1, WMV3 }, "
+ "format = (string){ WVC1, WMV3 }, "
"width = (int)[ 16, 2048 ], "
"height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];")
);
static void gst_vpe_ ## decoder_name ## _base_init (gpointer gclass) \
{ \
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); \
- gst_element_class_set_details_simple (element_class, \
+ gst_element_class_set_static_metadata (element_class, \
#decoder_name "vpe", \
"Codec/Decoder/Video", \
#decoder_name " + vpe bin", "Harinarayan Bhatta <harinarayan@ti.com>");\
static volatile gsize gonce_data = 0; \
if (g_once_init_enter (&gonce_data)) { \
GType _type; \
- _type = gst_type_register_static_full (GST_TYPE_BIN, \
+ _type = g_type_register_static_simple (GST_TYPE_BIN, \
g_intern_static_string (#type), \
sizeof (type ## Class), \
gst_vpe_ ## decoder_name ## _base_init, \
diff --git a/src/gstvpebins.h b/src/gstvpebins.h
index 928b2cbb59eaaf4777de8637ee9a164d008e1029..9dcb0f66898f0509f1740e42068764daec20c274 100644 (file)
--- a/src/gstvpebins.h
+++ b/src/gstvpebins.h
#include <omap_drm.h>
#include <omap_drmif.h>
#include <gst/video/video.h>
-#include <gst/video/video-crop.h>
+#include <gst/video/gstvideometa.h>
#include <linux/videodev2.h>
#include <linux/v4l2-controls.h>
diff --git a/src/gstvpebuffer.c b/src/gstvpebuffer.c
index 115e8e22b6b96a09b7b1bbfb10915d68e9342e6a..8a1cbda5433f316774ff54db229c78a5a85b3509 100644 (file)
--- a/src/gstvpebuffer.c
+++ b/src/gstvpebuffer.c
#include <unistd.h>
#include <gst/dmabuf/dmabuf.h>
-static GstBufferClass *parent_class;
-static void gst_vpe_buffer_finalize (GObject * obj);
+static GType gst_meta_vpe_buffer_api_get_type (void);
+#define GST_META_VPE_BUFFER_API_TYPE (gst_meta_vpe_buffer_api_get_type())
-G_DEFINE_TYPE (GstVpeBuffer, gst_vpe_buffer, GST_TYPE_BUFFER);
+static const GstMetaInfo *gst_meta_vpe_buffer_get_info (void);
+#define GST_META_VPE_BUFFER_INFO (gst_meta_vpe_buffer_get_info())
+#define GST_META_VPE_BUFFER_GET(buf) ((GstMetaVpeBuffer *)gst_buffer_get_meta(buf,GST_META_VPE_BUFFER_API_TYPE))
+#define GST_META_VPE_BUFFER_ADD(buf) ((GstMetaVpeBuffer *)gst_buffer_add_meta(buf,GST_META_VPE_BUFFER_INFO,NULL))
-static void
-gst_vpe_buffer_init (GstVpeBuffer * self)
-{
-}
-static void
-gst_vpe_buffer_class_init (GstVpeBufferClass * klass)
+static gboolean
+vpebuffer_init_func (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
- parent_class = g_type_class_peek_parent (klass);
-
- /* Override the mini-object's finalize routine so we can do cleanup when
- * a GstVpeBufferClass is unref'd.
- */
- klass->parent_class.mini_object_class.finalize =
- (GstMiniObjectFinalizeFunction) gst_vpe_buffer_finalize;
+ GST_DEBUG ("init called on buffer %p, meta %p", buffer, meta);
+ /* nothing to init really, the init function is mostly for allocating
+ * additional memory or doing special setup as part of adding the metadata to
+ * the buffer*/
+ return TRUE;
}
static void
-gst_vpe_buffer_finalize (GObject * obj)
+vpebuffer_free_func (GstMeta * vpemeta, GstBuffer * buffer)
{
- GstVpeBuffer *buf = GST_VPE_BUFFER (obj);
-
- if (buf->pool) {
- /* Put the buffer back into the pool */
- if (gst_vpe_buffer_pool_put (buf->pool, buf)) {
- VPE_DEBUG ("Recycled VPE buffer, index: %d, type: %d fd: %d",
- buf->v4l2_buf.index, buf->v4l2_buf.type, buf->v4l2_planes[0].m.fd);
- return;
- }
- }
+ GstMetaVpeBuffer *meta = (GstMetaVpeBuffer *) vpemeta;
+
VPE_DEBUG ("Free VPE buffer, index: %d, type: %d fd: %d",
- buf->v4l2_buf.index, buf->v4l2_buf.type, buf->v4l2_planes[0].m.fd);
+ meta->v4l2_buf.index, meta->v4l2_buf.type, meta->v4l2_planes[0].m.fd);
/* No pool to put back to buffer into, so delete it completely */
- if (buf->bo) {
+ if (meta->bo) {
/* Close the dmabuff fd */
- close (buf->v4l2_planes[0].m.fd);
+ close (meta->v4l2_planes[0].m.fd);
/* Free the DRM buffer */
- omap_bo_del (buf->bo);
+ omap_bo_del (meta->bo);
}
- GST_BUFFER_CLASS (parent_class)->
- mini_object_class.finalize (GST_MINI_OBJECT (buf));
}
-GstVpeBuffer *
-gst_vpe_buffer_new (struct omap_device *dev,
- guint32 fourcc, gint width, gint height, int index, guint32 v4l2_type)
+static gboolean
+vpebuffer_transform_func (GstBuffer * transbuf, GstMeta * meta,
+ GstBuffer * buffer, GQuark type, gpointer data)
{
- GstVpeBuffer *buf;
- GstDmaBuf *dmabuf;
- int size;
+ return FALSE;
+}
+
+static GType
+gst_meta_vpe_buffer_api_get_type (void)
+{
+ static volatile GType type;
+ static const gchar *tags[] = { "vpebuffer", NULL };
- buf = (GstVpeBuffer *) gst_mini_object_new (GST_TYPE_VPE_BUFFER);
+ if (g_once_init_enter (&type)) {
+ GType _type = gst_meta_api_type_register ("GstMetaVpeBufferAPI", tags);
+ g_once_init_leave (&type, _type);
+ }
+ return type;
+}
- g_return_val_if_fail (buf != NULL, NULL);
+static const GstMetaInfo *
+gst_meta_vpe_buffer_get_info (void)
+{
+ static const GstMetaInfo *meta_vpe_buffer_info = NULL;
+
+ if (g_once_init_enter (&meta_vpe_buffer_info)) {
+ const GstMetaInfo *mi = gst_meta_register (GST_META_VPE_BUFFER_API_TYPE,
+ "GstMetaVpeBuffer",
+ sizeof (GstMetaVpeBuffer),
+ vpebuffer_init_func, vpebuffer_free_func, vpebuffer_transform_func);
+ g_once_init_leave (&meta_vpe_buffer_info, mi);
+ }
+ return meta_vpe_buffer_info;
+}
- buf->pool = NULL;
- buf->bo = NULL;
- memset (&buf->v4l2_buf, 0, sizeof (buf->v4l2_buf));
- memset (&buf->v4l2_planes, 0, sizeof (buf->v4l2_planes));
+GstMetaVpeBuffer *
+gst_buffer_add_vpe_buffer_meta (GstBuffer * buf, struct omap_device * dev,
+ guint32 fourcc, gint width, gint height, int index, guint32 v4l2_type)
+{
+ GstMetaVpeBuffer *vpebuf;
- buf->v4l2_buf.type = v4l2_type;
- buf->v4l2_buf.index = index;
- buf->v4l2_buf.m.planes = buf->v4l2_planes;
- buf->v4l2_buf.memory = V4L2_MEMORY_DMABUF;
+ vpebuf = GST_META_VPE_BUFFER_ADD (buf);
+ if (!vpebuf)
+ goto fail;
+
+ vpebuf->size = 0;
+ vpebuf->pool = NULL;
+ vpebuf->bo = NULL;
+ memset (&vpebuf->v4l2_buf, 0, sizeof (vpebuf->v4l2_buf));
+ memset (&vpebuf->v4l2_planes, 0, sizeof (vpebuf->v4l2_planes));
+
+ vpebuf->v4l2_buf.type = v4l2_type;
+ vpebuf->v4l2_buf.index = index;
+ vpebuf->v4l2_buf.m.planes = vpebuf->v4l2_planes;
+ vpebuf->v4l2_buf.memory = V4L2_MEMORY_DMABUF;
switch (fourcc) {
case GST_MAKE_FOURCC ('A', 'R', '2', '4'):
- size = width * height * 4;
- buf->bo = omap_bo_new (dev, size, OMAP_BO_WC);
- buf->v4l2_buf.length = 1;
- buf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (buf->bo);
+ vpebuf->size = width * height * 4;
+ vpebuf->bo = omap_bo_new (dev, vpebuf->size, OMAP_BO_WC);
+ vpebuf->v4l2_buf.length = 1;
+ vpebuf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (vpebuf->bo);
break;
case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
case GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V'):
- size = width * height * 2;
- buf->bo = omap_bo_new (dev, size, OMAP_BO_WC);
- buf->v4l2_buf.length = 1;
- buf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (buf->bo);
+ vpebuf->size = width * height * 2;
+ vpebuf->bo = omap_bo_new (dev, vpebuf->size, OMAP_BO_WC);
+ vpebuf->v4l2_buf.length = 1;
+ vpebuf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (vpebuf->bo);
break;
case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
- size = (width * height * 3) / 2;
- buf->bo = omap_bo_new (dev, size, OMAP_BO_WC);
- buf->v4l2_buf.length = 2;
- buf->v4l2_buf.m.planes[1].m.fd =
- buf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (buf->bo);
- buf->v4l2_buf.m.planes[1].data_offset = width * height;
+ vpebuf->size = (width * height * 3) / 2;
+ vpebuf->bo = omap_bo_new (dev, vpebuf->size, OMAP_BO_WC);
+ vpebuf->v4l2_buf.length = 2;
+ vpebuf->v4l2_buf.m.planes[1].m.fd =
+ vpebuf->v4l2_buf.m.planes[0].m.fd = omap_bo_dmabuf (vpebuf->bo);
+ vpebuf->v4l2_buf.m.planes[1].data_offset = width * height;
break;
default:
VPE_ERROR ("invalid format: 0x%08x", fourcc);
goto fail;
}
+ return vpebuf;
+fail:
+ gst_buffer_unref (buf);
+ return NULL;
+}
+
+GstMetaVpeBuffer *
+gst_buffer_get_vpe_buffer_meta (GstBuffer * buf)
+{
+ GstMetaVpeBuffer *vpebuf;
+ vpebuf = GST_META_VPE_BUFFER_GET (buf);
+ return vpebuf;
+}
- GST_BUFFER_DATA (GST_BUFFER (buf)) = omap_bo_map (buf->bo);
- GST_BUFFER_SIZE (GST_BUFFER (buf)) = size;
+
+GstBuffer *
+gst_vpe_buffer_new (struct omap_device * dev,
+ guint32 fourcc, gint width, gint height, int index, guint32 v4l2_type)
+{
+ GstMetaVpeBuffer *vpemeta;
+ GstMetaDmaBuf *dmabuf;
+ GstVideoCropMeta *crop;
+ int size;
+ GstBuffer *buf;
+
+ buf = gst_buffer_new ();
+ if (!buf)
+ return NULL;
+
+ vpemeta = gst_buffer_add_vpe_buffer_meta (buf, dev,
+ fourcc, width, height, index, v4l2_type);
+ if (!vpemeta) {
+ VPE_ERROR ("Failed to add vpe metadata");
+ gst_buffer_unref (buf);
+ return NULL;
+ }
+
+ gst_buffer_append_memory (buf,
+ gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE,
+ omap_bo_map (vpemeta->bo), vpemeta->size, 0, vpemeta->size, NULL,
+ NULL));
/* attach dmabuf handle to buffer so that elements from other
* plugins can access for zero copy hw accel:
*/
- // XXX buffer doesn't take ownership of the GstDmaBuf...
- dmabuf = gst_dma_buf_new (omap_bo_dmabuf (buf->bo));
- gst_buffer_set_dma_buf (GST_BUFFER (buf), dmabuf);
- gst_dma_buf_unref (dmabuf);
+ dmabuf =
+ gst_buffer_add_dma_buf_meta (GST_BUFFER (buf),
+ omap_bo_dmabuf (vpemeta->bo));
+ if (!dmabuf) {
+ VPE_DEBUG ("Failed to attach dmabuf to buffer");
+ gst_buffer_unref (buf);
+ return NULL;
+ }
- VPE_DEBUG ("Allocated a new VPE buffer, index: %d, type: %d",
- index, v4l2_type);
+ crop = gst_buffer_add_video_crop_meta (buf);
+ if (!crop) {
+ VPE_DEBUG ("Failed to add crop meta to buffer");
+ } else {
+ crop->x = 0;
+ crop->y = 0;
+ crop->height = height;
+ crop->width = width;
+ }
+
+ VPE_DEBUG ("Allocated a new VPE buffer, %dx%d, index: %d, type: %d",
+ width, height, index, v4l2_type);
return buf;
-fail:
- gst_buffer_unref (GST_BUFFER (buf));
- return NULL;
}
diff --git a/src/gstvpebufferpool.c b/src/gstvpebufferpool.c
index bfbce6d0a18dc8f2793e7395e789ec3e34e6f0e3..715dd661f800dc0599ff97ceb118f8b8dd6f575b 100644 (file)
--- a/src/gstvpebufferpool.c
+++ b/src/gstvpebufferpool.c
BUF_WITH_DRIVER,
};
-static GstMiniObjectClass *parent_class;
-
static void gst_vpe_buffer_pool_finalize (GObject * obj);
+static GstFlowReturn gst_vpe_buffer_pool_alloc_buffer (GstBufferPool * bufpool,
+ GstBuffer ** buf, GstBufferPoolAcquireParams * params);
+static void gst_vpe_buffer_pool_release_buffer (GstBufferPool * pool,
+ GstBuffer * buffer);
-G_DEFINE_TYPE (GstVpeBufferPool, gst_vpe_buffer_pool, GST_TYPE_MINI_OBJECT);
+#define gst_vpe_buffer_pool_parent_class parent_class
+G_DEFINE_TYPE (GstVpeBufferPool, gst_vpe_buffer_pool, GST_TYPE_BUFFER_POOL);
static void
gst_vpe_buffer_pool_init (GstVpeBufferPool * self)
static void
gst_vpe_buffer_pool_class_init (GstVpeBufferPoolClass * klass)
{
- GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (klass);
+ GObjectClass *mo_class = G_OBJECT_CLASS (klass);
+ GstBufferPoolClass *bclass = GST_BUFFER_POOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
- mo_class->finalize =
- (GstMiniObjectFinalizeFunction) gst_vpe_buffer_pool_finalize;
+ bclass->alloc_buffer = gst_vpe_buffer_pool_alloc_buffer;
+ bclass->release_buffer = gst_vpe_buffer_pool_release_buffer;
+
+ mo_class->finalize = gst_vpe_buffer_pool_finalize;
}
static void
g_free (pool->buf_tracking);
g_mutex_clear (&pool->lock);
- GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (pool));
+ G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (pool));
}
GstVpeBufferPool *
gst_vpe_buffer_pool_new (gboolean output_port, guint buffer_count,
- guint32 v4l2_type)
+ guint32 v4l2_type, GstCaps * caps)
{
GstVpeBufferPool *pool;
+ GstStructure *conf;
+ int size;
+ GstVideoInfo info;
- pool = (GstVpeBufferPool *) gst_mini_object_new (GST_TYPE_VPE_BUFFER_POOL);
+ g_return_val_if_fail (caps != NULL, NULL);
+ pool = (GstVpeBufferPool *) g_object_new (GST_TYPE_VPE_BUFFER_POOL, NULL);
g_return_val_if_fail (pool != NULL, NULL);
pool->output_port = output_port;
pool->buf_tracking =
(struct GstVpeBufferPoolBufTracking *) g_malloc0 (buffer_count *
sizeof (struct GstVpeBufferPoolBufTracking));
+
+ /* get the present config of the buffer pool */
+ conf = gst_buffer_pool_get_config (GST_BUFFER_POOL (pool));
+ if (conf == NULL) {
+ VPE_ERROR ("NULL config obtained after get_config on the pool");
+ goto fail;
+ }
+
+ if (!gst_video_info_from_caps (&info, caps)) {
+ VPE_ERROR ("gst_video_info_from_caps failed");
+ goto fail;
+ }
+
+ /* set the config params : caps, size of the buffers, min number of buffers,
+ max number of buffers (0 for unlimited) */
+ gst_buffer_pool_config_set_params (conf, caps, GST_VIDEO_INFO_SIZE (&info), 0,
+ 0);
+ if (conf == NULL) {
+ VPE_ERROR ("NULL config after set_params");
+ goto fail;
+ }
+
+ /* set config of the pool */
+ gst_buffer_pool_set_config (GST_BUFFER_POOL (pool), conf);
+
+ gst_buffer_pool_set_active (GST_BUFFER_POOL (pool), TRUE);
+
return pool;
+fail:
+ gst_object_unref (G_OBJECT (pool));
+ return FALSE;
}
/* Put a buffer back into the pool
* Called either from the application or from buffer finalize handler
*/
gboolean
-gst_vpe_buffer_pool_put (GstVpeBufferPool * pool, GstVpeBuffer * buf)
+gst_vpe_buffer_pool_put (GstVpeBufferPool * pool, GstBuffer * buffer)
{
GstVpeBufferPool *p;
gboolean ret = TRUE;
+ GstMetaVpeBuffer *buf = gst_buffer_get_vpe_buffer_meta (buffer);
GST_VPE_BUFFER_POOL_LOCK (pool);
- VPE_DEBUG ("gst_vpe_buffer_pool_put: %p", buf);
+ VPE_DEBUG ("Entered for %s Q, buf=%p", pool->output_port ? "output" : "input",
+ buffer);
if (pool->shutting_down) {
p = buf->pool;
buf->pool = NULL;
GST_VPE_BUFFER_POOL_UNLOCK (pool);
if (p)
- gst_mini_object_unref (GST_MINI_OBJECT (p));
+ gst_object_unref (G_OBJECT (p));
return FALSE;
} else {
/* Each buffer that belongs to a pool has a reference to the
* are freed */
if (buf->pool == NULL) {
buf->pool = (GstVpeBufferPool *)
- gst_mini_object_ref (GST_MINI_OBJECT (pool));
+ gst_object_ref (G_OBJECT (pool));
}
if (pool->output_port && pool->streaming) {
int r;
/* QUEUE this buffer into the driver */
r = ioctl (pool->video_fd, VIDIOC_QBUF, &buf->v4l2_buf);
if (r < 0) {
- VPE_ERROR ("vpebufferpool: op QBUF failed: %s, index = %d",
+ VPE_ERROR ("vpebufferpool: output QBUF failed: %s, index = %d",
strerror (errno), buf->v4l2_buf.index);
ret = FALSE;
} else {
- VPE_DEBUG ("vpebufferpool: op QBUF succeeded: index = %d",
+ VPE_DEBUG ("vpebufferpool: output QBUF succeeded: index = %d",
buf->v4l2_buf.index);
pool->buf_tracking[buf->v4l2_buf.index].state = BUF_WITH_DRIVER;
- pool->buf_tracking[buf->v4l2_buf.index].buf =
- (GstVpeBuffer *) gst_buffer_ref (GST_BUFFER (buf));
+ pool->buf_tracking[buf->v4l2_buf.index].buf = GST_BUFFER (buffer);
pool->buf_tracking[buf->v4l2_buf.index].q_cnt = 1;
}
} else {
- VPE_DEBUG ("vpebufferpool: buf marked free: index = %d",
- buf->v4l2_buf.index);
+ VPE_DEBUG ("vpebufferpool: buf marked free: index = %d, q_cnt = %d",
+ buf->v4l2_buf.index, pool->buf_tracking[buf->v4l2_buf.index].q_cnt);
pool->buf_tracking[buf->v4l2_buf.index].state = BUF_FREE;
- pool->buf_tracking[buf->v4l2_buf.index].buf =
- (GstVpeBuffer *) gst_buffer_ref (GST_BUFFER (buf));
+ pool->buf_tracking[buf->v4l2_buf.index].buf = GST_BUFFER (buffer);
pool->buf_tracking[buf->v4l2_buf.index].q_cnt = 1;
}
}
/* Called to queue the buffer into the driver, if output_port flag is
* not set
*/
-GstVpeBuffer *
+GstBuffer *
gst_vpe_buffer_pool_dequeue (GstVpeBufferPool * pool)
{
int ret, i;
struct v4l2_buffer buf;
struct v4l2_plane planes[2];
- GstVpeBuffer *dqbuf = NULL;
+ GstBuffer *dqbuf = NULL;
- VPE_LOG ("Entered gst_vpe_buffer_pool_dequeue");
+ VPE_LOG ("Entered for %s Q", pool->output_port ? "output" : "input");
GST_VPE_BUFFER_POOL_LOCK (pool);
for (i = 0; i < pool->buffer_count; i++) {
}
}
if (i < pool->buffer_count) {
+ GstMetaVpeBuffer *vpebuf =
+ gst_buffer_get_vpe_buffer_meta (pool->buf_tracking[i].buf);
memset (&planes, 0, sizeof planes);
- buf = pool->buf_tracking[i].buf->v4l2_buf;
+ buf = vpebuf->v4l2_buf;
buf.m.planes = planes;
// VPE_DEBUG("try de-queueing buffers from the driver");
ret = ioctl (pool->video_fd, VIDIOC_DQBUF, &buf);
if (ret < 0) {
if (errno == EAGAIN)
- VPE_LOG ("Non-blocking DQBUF, try again");
+ VPE_LOG ("No buffers to DQBUF from %s Q, try again",
+ pool->output_port ? "output" : "input");
else
- VPE_ERROR ("vpebufferpool: DQBUF failed: %s, index = %d",
+ VPE_ERROR ("vpebufferpool: DQBUF for %s failed: %s, index = %d",
+ pool->output_port ? "output" : "input",
strerror (errno), buf.index);
GST_VPE_BUFFER_POOL_UNLOCK (pool);
return NULL;
}
-
- VPE_LOG ("DQBUF succeeded, index: %d, type: %d, field: %d",
- buf.index, buf.type, buf.field);
#ifdef GST_VPE_USE_FIELD_ALTERNATE
if (!pool->output_port && pool->interlaced)
buf.index = (buf.index >> 2);
dqbuf = NULL;
} else {
dqbuf = pool->buf_tracking[buf.index].buf;
+ VPE_LOG
+ ("DQBUF for %s succeeded, index: %d, type: %d, field: %d, q_cnt: %d",
+ pool->output_port ? "output" : "input", buf.index, buf.type,
+ buf.field, pool->buf_tracking[buf.index].q_cnt);
}
if (0 < pool->buf_tracking[buf.index].q_cnt)
pool->buf_tracking[buf.index].q_cnt--;
if (dqbuf) {
if (buf.timestamp.tv_sec == (time_t) - 1) {
- GST_BUFFER_TIMESTAMP (GST_BUFFER (dqbuf)) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_PTS (dqbuf) = GST_CLOCK_TIME_NONE;
} else {
/* Assign a timestamp, propogated by the driver */
- GST_BUFFER_TIMESTAMP (GST_BUFFER (dqbuf)) =
- GST_TIMEVAL_TO_TIME (buf.timestamp);
+ GST_BUFFER_PTS (dqbuf) = GST_TIMEVAL_TO_TIME (buf.timestamp);
}
}
} else {
- VPE_LOG ("No buffers to dequeue");
+ VPE_LOG ("No buffers to dequeue from %s Q",
+ pool->output_port ? "output" : "input");
GST_VPE_BUFFER_POOL_UNLOCK (pool);
}
return dqbuf;
* not set
*/
gboolean
-gst_vpe_buffer_pool_queue (GstVpeBufferPool * pool, GstVpeBuffer * buf)
+gst_vpe_buffer_pool_queue (GstVpeBufferPool * pool, GstBuffer * buff)
{
int ret = 0;
gint q_cnt = 0;
+ GstMetaVpeBuffer *buf = gst_buffer_get_vpe_buffer_meta (buff);
GST_VPE_BUFFER_POOL_LOCK (pool);
if (pool->streaming) {
VPE_DEBUG ("Queueing buffer, fd: %d", buf->v4l2_buf.m.planes[0].m.fd);
- GST_TIME_TO_TIMEVAL (GST_BUFFER_TIMESTAMP (GST_BUFFER (buf)),
- buf->v4l2_buf.timestamp);
+ GST_TIME_TO_TIMEVAL (GST_BUFFER_PTS (buff), buf->v4l2_buf.timestamp);
do {
if (pool->interlaced) {
#ifdef GST_VPE_USE_FIELD_ALTERNATE
field_offset = buf_planes[1].data_offset >> 1;
base_index = (buffer.index << 2);
- if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buf), GST_VIDEO_BUFFER_TFF)) {
+ if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buff),
+ GST_VIDEO_BUFFER_FLAG_TFF)) {
if (pool->last_field_pushed == 0)
pool->last_field_pushed = V4L2_FIELD_BOTTOM;
if (pool->last_field_pushed == V4L2_FIELD_TOP) {
break;
}
q_cnt++;
- gst_buffer_ref (GST_BUFFER (buf));
- if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buf), GST_VIDEO_BUFFER_RFF)) {
+ gst_buffer_ref (GST_BUFFER (buff));
+ if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buff),
+ GST_VIDEO_BUFFER_FLAG_RFF)) {
VPE_DEBUG ("Queueing V4L2_FIELD_TOP (repeating)");
buffer = buf->v4l2_buf;
buffer.timestamp.tv_sec = (time_t) - 1;
break;
}
q_cnt++;
- gst_buffer_ref (GST_BUFFER (buf));
+ gst_buffer_ref (GST_BUFFER (buff));
}
} else {
if (pool->last_field_pushed == 0)
break;
}
q_cnt++;
- gst_buffer_ref (GST_BUFFER (buf));
- if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buf), GST_VIDEO_BUFFER_RFF)) {
+ gst_buffer_ref (GST_BUFFER (buff));
+ if (GST_BUFFER_FLAG_IS_SET (GST_BUFFER (buff),
+ GST_VIDEO_BUFFER_FLAG_RFF)) {
VPE_DEBUG ("Queueing V4L2_FIELD_BOTTOM (repeating)");
buffer = buf->v4l2_buf;
buffer.timestamp.tv_sec = (time_t) - 1;
break;
}
q_cnt++;
- gst_buffer_ref (GST_BUFFER (buf));
+ gst_buffer_ref (GST_BUFFER (buff));
}
}
#else
strerror (errno), buf->v4l2_buf.index);
break;
}
+ q_cnt++;
}
- q_cnt++;
} while (0);
- if (q_cnt) {
- pool->buf_tracking[buf->v4l2_buf.index].state = BUF_WITH_DRIVER;
- pool->buf_tracking[buf->v4l2_buf.index].q_cnt = q_cnt;
- }
}
+ if (q_cnt) {
+ pool->buf_tracking[buf->v4l2_buf.index].state = BUF_WITH_DRIVER;
+ }
+ pool->buf_tracking[buf->v4l2_buf.index].q_cnt = q_cnt;
+ VPE_LOG ("Q_CNT after QBUF index = %d, q_cnt: %d",
+ buf->v4l2_buf.index, q_cnt);
GST_VPE_BUFFER_POOL_UNLOCK (pool);
if (0 == q_cnt)
- gst_buffer_unref (GST_BUFFER (buf));
+ gst_buffer_unref (GST_BUFFER (buff));
return (ret == 0) ? TRUE : FALSE;
}
/* Called to get a free buffer from the pool
*/
-GstVpeBuffer *
+GstBuffer *
gst_vpe_buffer_pool_get (GstVpeBufferPool * pool)
{
int r, i;
- GstVpeBuffer *ret = NULL;
+ GstBuffer *ret = NULL;
VPE_DEBUG ("Entered gst_vpe_buffer_pool_get");
GST_VPE_BUFFER_POOL_LOCK (pool);
gst_vpe_buffer_pool_destroy (GstVpeBufferPool * pool)
{
int i, q_cnt;
- GstVpeBuffer *buf;
+ GstBuffer *buf;
GST_VPE_BUFFER_POOL_LOCK (pool);
GST_VPE_BUFFER_POOL_LOCK (pool);
}
GST_VPE_BUFFER_POOL_UNLOCK (pool);
-
- gst_mini_object_unref (GST_MINI_OBJECT (pool));
+ gst_buffer_pool_set_active (GST_BUFFER_POOL (pool), FALSE);
+ gst_object_unref (pool);
}
static gboolean
{
gboolean ret = FALSE;
int i, q_cnt, r, index;
- GstVpeBuffer *buf;
+ GstBuffer *buf;
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buffer;
struct v4l2_plane buf_planes[2];
int req_buf_count;
int field_offset;
+ GstMetaVpeBuffer *vpebuf;
+
GST_VPE_BUFFER_POOL_LOCK (pool);
if (streaming && !pool->streaming) {
ret = FALSE;
goto DONE;
}
- field_offset = pool->buf_tracking[0].buf->v4l2_planes[1].data_offset >> 1;
+ vpebuf = gst_buffer_get_vpe_buffer_meta (pool->buf_tracking[0].buf);
+ field_offset = vpebuf->v4l2_planes[1].data_offset >> 1;
for (i = 0; i < req_buf_count; i++) {
+ GstMetaVpeBuffer *vbuf;
index = i;
#ifdef GST_VPE_USE_FIELD_ALTERNATE
if (!pool->output_port && pool->interlaced)
index = (i >> 2);
#endif
- buffer = pool->buf_tracking[index].buf->v4l2_buf;
+ vbuf = gst_buffer_get_vpe_buffer_meta (pool->buf_tracking[index].buf);
+ buffer = vbuf->v4l2_buf;
buffer.m.planes = buf_planes;
buffer.index = i;
- buf_planes[0] = pool->buf_tracking[index].buf->v4l2_planes[0];
- buf_planes[1] = pool->buf_tracking[index].buf->v4l2_planes[1];
+ buf_planes[0] = vbuf->v4l2_planes[0];
+ buf_planes[1] = vbuf->v4l2_planes[1];
#ifdef GST_VPE_USE_FIELD_ALTERNATE
if (!pool->output_port && pool->interlaced) {
if (i & 1) {
if (pool->output_port) {
for (i = 0; i < pool->buffer_count; i++) {
+ GstMetaVpeBuffer *vbuf =
+ gst_buffer_get_vpe_buffer_meta (pool->buf_tracking[i].buf);
if (pool->buf_tracking[i].state != BUF_FREE)
continue;
/* QUEUE all free buffers into the driver */
- r = ioctl (pool->video_fd, VIDIOC_QBUF,
- &pool->buf_tracking[i].buf->v4l2_buf);
+ r = ioctl (pool->video_fd, VIDIOC_QBUF, &vbuf->v4l2_buf);
if (r < 0) {
VPE_ERROR ("vpebufferpool: op QBUF failed: %s, index = %d",
- strerror (errno), pool->buf_tracking[i].buf->v4l2_buf.index);
+ strerror (errno), vbuf->v4l2_buf.index);
ret = FALSE;
goto DONE;
}
VPE_DEBUG ("vpebufferpool: op QBUF succeeded: index = %d",
- pool->buf_tracking[i].buf->v4l2_buf.index);
+ vbuf->v4l2_buf.index);
pool->buf_tracking[i].state = BUF_WITH_DRIVER;
pool->buf_tracking[i].q_cnt = 1;
}
} else { // not pool->output_port
for (i = 0; i < pool->buffer_count; i++) {
- pool->buf_tracking[i].buf->v4l2_buf.bytesused = 0;
- pool->buf_tracking[i].buf->v4l2_planes[0].bytesused = 0;
- pool->buf_tracking[i].buf->v4l2_planes[1].bytesused = 0;
+ GstMetaVpeBuffer *vbuf =
+ gst_buffer_get_vpe_buffer_meta (pool->buf_tracking[i].buf);
+ vbuf->v4l2_buf.bytesused = 0;
+ vbuf->v4l2_planes[0].bytesused = 0;
+ vbuf->v4l2_planes[1].bytesused = 0;
}
}
VPE_DEBUG ("Start streaming for type: %d", pool->v4l2_type);
GST_VPE_BUFFER_POOL_UNLOCK (pool);
return ret;
}
+
+static void
+gst_vpe_buffer_pool_try_dequeue (GstVpeBufferPool * pool)
+{
+ GstBuffer *buf;
+ while (1) {
+ buf = gst_vpe_buffer_pool_dequeue (pool);
+ if (buf) {
+ gst_buffer_unref (GST_BUFFER (buf));
+ } else
+ break;
+ }
+}
+
+static GstFlowReturn
+gst_vpe_buffer_pool_alloc_buffer (GstBufferPool * bufpool,
+ GstBuffer ** buf, GstBufferPoolAcquireParams * params)
+{
+ GstVpeBufferPool *pool = GST_VPE_BUFFER_POOL (bufpool);
+ if (pool->output_port)
+ do {
+ /* Try dequeueing some buffers */
+ *buf = gst_vpe_buffer_pool_dequeue (pool);
+ if (*buf) {
+ return GST_FLOW_OK;
+ }
+ } while (0);
+ else
+ do {
+ /* Try dequeueing some buffers */
+ gst_vpe_buffer_pool_try_dequeue (pool);
+ *buf = GST_BUFFER (gst_vpe_buffer_pool_get (pool));
+ if (*buf) {
+ return GST_FLOW_OK;
+ }
+ usleep (10000);
+ } while (1);
+ return GST_FLOW_ERROR;
+}
+
+static void
+gst_vpe_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
+{
+ if (!gst_vpe_buffer_pool_put (GST_VPE_BUFFER_POOL (pool), buffer)) {
+ VPE_DEBUG ("Failed to put the buffer to pool");
+ }
+}