camerabin2: Adding v4l2camerasrc from robclark's branch

Adds 3-pad v4l2 camera source from Rob Clark's camerabin
branch on http://gitorious.org/robclark-gstreamer/gst-plugins-bad
This commit is contained in:
Thiago Santos 2010-11-25 13:00:50 -03:00
parent 12245366d8
commit 94da473ba7
10 changed files with 2397 additions and 3 deletions

View file

@ -2,17 +2,28 @@ plugin_LTLIBRARIES = libgstcamerabin2.la
libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \ libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \
gstimagecapturebin.c \ gstimagecapturebin.c \
camerabingeneral.c \
gstbasecamerasrc.c \
gstcamerabin-enum.c \
gstv4l2camerasrc.c \
gstplugin.c gstplugin.c
libgstcamerabin2_la_CFLAGS = \ libgstcamerabin2_la_CFLAGS = \
$(GST_PLUGINS_BAD_CFLAGS) \ $(GST_PLUGINS_BAD_CFLAGS) \
$(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
-DGST_USE_UNSTABLE_API
libgstcamerabin2_la_LIBADD = \ libgstcamerabin2_la_LIBADD = \
$(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-$(GST_MAJORMINOR).la \
$(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \
-lgstinterfaces-$(GST_MAJORMINOR) -lgsttag-$(GST_MAJORMINOR)
libgstcamerabin2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstcamerabin2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstcamerabin2_la_LIBTOOLFLAGS = --tag=disable-static libgstcamerabin2_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstviewfinderbin.h \ noinst_HEADERS = gstviewfinderbin.h \
gstimagecapturebin.h gstimagecapturebin.h \
camerabingeneral.h \
gstbasecamerasrc.h \
gstv4l2camerasrc.h \
gstcamerabin-enum.h

View file

@ -0,0 +1,276 @@
/*
* GStreamer
* Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:camerabingeneral
* @short_description: helper functions for #GstCameraBin and it's modules
*
* Common helper functions for #GstCameraBin, #GstCameraBinImage and
* #GstCameraBinVideo.
*
*/
#include <string.h>
#include "camerabingeneral.h"
#include <glib.h>
GST_DEBUG_CATEGORY (gst_camerabin_debug);
/**
* gst_camerabin_add_element:
* @bin: add an element to this bin
* @new_elem: new element to be added
*
* Adds given element to given @bin. Looks for an unconnected src pad
* from the @bin and links the element to it. Raises an error if adding
* or linking failed. Unrefs the element in the case of an error.
*
* Returns: %TRUE if adding and linking succeeded, %FALSE otherwise.
*/
gboolean
gst_camerabin_add_element (GstBin * bin, GstElement * new_elem)
{
return gst_camerabin_add_element_full (bin, NULL, new_elem, NULL);
}
/**
* gst_camerabin_add_element_full:
* @bin: add an element to this bin
* @srcpad: src pad name, or NULL for any
* @new_elem: new element to be added
* @dstpad: dst pad name, or NULL for any
*
* Adds given element to given @bin. Looks for an unconnected src pad
* (with name @srcpad, if specified) from the @bin and links the element
* to it. Raises an error if adding or linking failed. Unrefs the element
* in the case of an error.
*
* Returns: %TRUE if adding and linking succeeded, %FALSE otherwise.
*/
gboolean
gst_camerabin_add_element_full (GstBin * bin, const gchar * srcpad,
GstElement * new_elem, const gchar * dstpad)
{
gboolean ret;
g_return_val_if_fail (bin, FALSE);
g_return_val_if_fail (new_elem, FALSE);
ret = gst_camerabin_try_add_element (bin, srcpad, new_elem, dstpad);
if (!ret) {
gchar *elem_name = gst_element_get_name (new_elem);
GST_ELEMENT_ERROR (bin, CORE, NEGOTIATION, (NULL),
("linking %s failed", elem_name));
g_free (elem_name);
gst_object_unref (new_elem);
}
return ret;
}
/**
* gst_camerabin_try_add_element:
* @bin: tries adding an element to this bin
* @srcpad: src pad name, or NULL for any
* @new_elem: new element to be added
* @dstpad: dst pad name, or NULL for any
*
* Adds given element to given @bin. Looks for an unconnected src pad
* (with name @srcpad, if specified) from the @bin and links the element to
* it.
*
* Returns: %TRUE if adding and linking succeeded, %FALSE otherwise.
*/
gboolean
gst_camerabin_try_add_element (GstBin * bin, const gchar * srcpad,
GstElement * new_elem, const gchar * dstpad)
{
GstPad *bin_pad;
GstElement *bin_elem;
gboolean ret = TRUE;
g_return_val_if_fail (bin, FALSE);
g_return_val_if_fail (new_elem, FALSE);
/* Get pads for linking */
bin_pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC);
/* Add to bin */
gst_bin_add (GST_BIN (bin), new_elem);
/* Link, if unconnected pad was found, otherwise just add it to bin */
if (bin_pad) {
GST_DEBUG_OBJECT (bin, "linking %s to %s:%s", GST_OBJECT_NAME (new_elem),
GST_DEBUG_PAD_NAME (bin_pad));
bin_elem = gst_pad_get_parent_element (bin_pad);
gst_object_unref (bin_pad);
if (!gst_element_link_pads (bin_elem, srcpad, new_elem, dstpad)) {
gst_object_ref (new_elem);
gst_bin_remove (bin, new_elem);
ret = FALSE;
}
gst_object_unref (bin_elem);
} else {
GST_INFO_OBJECT (bin, "no unlinked source pad in bin");
}
return ret;
}
/**
* gst_camerabin_create_and_add_element:
* @bin: tries adding an element to this bin
* @elem_name: name of the element to be created
*
* Creates an element according to given name and
* adds it to given @bin. Looks for an unconnected src pad
* from the @bin and links the element to it.
*
* Returns: pointer to the new element if successful, NULL otherwise.
*/
GstElement *
gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name)
{
GstElement *new_elem;
g_return_val_if_fail (bin, FALSE);
g_return_val_if_fail (elem_name, FALSE);
new_elem = gst_element_factory_make (elem_name, NULL);
if (!new_elem) {
GST_ELEMENT_ERROR (bin, CORE, MISSING_PLUGIN, (NULL),
("could not create \"%s\" element.", elem_name));
} else if (!gst_camerabin_add_element (bin, new_elem)) {
new_elem = NULL;
}
return new_elem;
}
/* try to change the state of an element. This function returns the element when
* the state change could be performed. When this function returns NULL an error
* occured and the element is unreffed if @unref is TRUE. */
static GstElement *
try_element (GstElement * bin, GstElement * element, gboolean unref)
{
GstStateChangeReturn ret;
if (element) {
ret = gst_element_set_state (element, GST_STATE_READY);
if (ret == GST_STATE_CHANGE_FAILURE) {
GST_DEBUG_OBJECT (bin, "failed state change..");
gst_element_set_state (element, GST_STATE_NULL);
if (unref)
gst_object_unref (element);
element = NULL;
}
}
return element;
}
GstElement *
gst_camerabin_setup_default_element (GstBin * bin, GstElement * user_elem,
const gchar * auto_elem_name, const gchar * default_elem_name)
{
GstElement *elem;
if (user_elem) {
GST_DEBUG_OBJECT (bin, "trying configured element");
elem = try_element (GST_ELEMENT_CAST (bin), user_elem, FALSE);
} else {
/* only try fallback if no specific sink was chosen */
GST_DEBUG_OBJECT (bin, "trying %s", auto_elem_name);
elem = gst_element_factory_make (auto_elem_name, NULL);
elem = try_element (GST_ELEMENT_CAST (bin), elem, TRUE);
if (elem == NULL) {
/* if default sink from config.h is different then try it too */
if (strcmp (default_elem_name, auto_elem_name)) {
GST_DEBUG_OBJECT (bin, "trying %s", default_elem_name);
elem = gst_element_factory_make (default_elem_name, NULL);
elem = try_element (GST_ELEMENT_CAST (bin), elem, TRUE);
}
}
}
return elem;
}
/**
* gst_camerabin_remove_elements_from_bin:
* @bin: removes all elements from this bin
*
* Removes all elements from this @bin.
*/
void
gst_camerabin_remove_elements_from_bin (GstBin * bin)
{
GstIterator *iter = NULL;
gpointer data = NULL;
GstElement *elem = NULL;
gboolean done = FALSE;
iter = gst_bin_iterate_elements (bin);
while (!done) {
switch (gst_iterator_next (iter, &data)) {
case GST_ITERATOR_OK:
elem = GST_ELEMENT (data);
gst_bin_remove (bin, elem);
gst_element_set_state (GST_ELEMENT (elem), GST_STATE_NULL);
/* Iterator increased the element refcount, so unref */
gst_object_unref (elem);
break;
case GST_ITERATOR_RESYNC:
gst_iterator_resync (iter);
break;
case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (bin, "error in iterating elements");
done = TRUE;
break;
case GST_ITERATOR_DONE:
done = TRUE;
break;
}
}
gst_iterator_free (iter);
}
/**
* gst_camerabin_drop_eos_probe:
* @pad: pad receiving the event
* @event: received event
* @u_data: not used
*
* Event probe that drop all eos events.
*
* Returns: FALSE to drop the event, TRUE otherwise
*/
gboolean
gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data)
{
gboolean ret = TRUE;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
GST_DEBUG ("dropping eos in %s:%s", GST_DEBUG_PAD_NAME (pad));
ret = FALSE;
break;
default:
break;
}
return ret;
}

View file

@ -0,0 +1,42 @@
/*
* GStreamer
* Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __CAMERABIN_GENERAL_H_
#define __CAMERABIN_GENERAL_H_
#include <gst/gst.h>
gboolean gst_camerabin_try_add_element (GstBin * bin, const gchar * srcpad, GstElement * new_elem, const gchar * dstpad);
gboolean gst_camerabin_add_element (GstBin * bin, GstElement * new_elem);
gboolean gst_camerabin_add_element_full (GstBin * bin, const gchar * srcpad, GstElement * new_elem, const gchar * dstpad);
GstElement *gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name);
GstElement * gst_camerabin_setup_default_element (GstBin * bin, GstElement *user_elem, const gchar *auto_elem_name, const gchar *default_elem_name);
void gst_camerabin_remove_elements_from_bin (GstBin * bin);
gboolean gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data);
/* debug logging category */
GST_DEBUG_CATEGORY_EXTERN (gst_camerabin_debug);
#define GST_CAT_DEFAULT gst_camerabin_debug
#endif /* #ifndef __CAMERABIN_GENERAL_H_ */

View file

@ -0,0 +1,509 @@
/*
* GStreamer
* Copyright (C) 2010 Texas Instruments, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:element-basecamerasrc
*
* Base class for the camera src bin used by camerabin. Indented to be
* subclassed when plugging in more sophisticated cameras.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "gstbasecamerasrc.h"
GST_DEBUG_CATEGORY (base_camera_src_debug);
#define GST_CAT_DEFAULT base_camera_src_debug
GST_BOILERPLATE (GstBaseCameraSrc, gst_base_camera_src, GstBin, GST_TYPE_BIN);
static GstStaticPadTemplate vfsrc_template = GST_STATIC_PAD_TEMPLATE ("vfsrc",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate imgsrc_template = GST_STATIC_PAD_TEMPLATE ("imgsrc",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate vidsrc_template = GST_STATIC_PAD_TEMPLATE ("vidsrc",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
/* note: we could provide a vmethod for derived class to overload to provide
* it's own implementation of interface.. but in all cases I can think of at
* moment, either the camerasrc itself, or some element within the bin, will
* be implementing the interface..
*/
/**
* gst_base_camera_src_get_photography:
* @self: the camerasrc bin
*
* Get object implementing photography interface, if there is one. Otherwise
* returns NULL.
*/
GstPhotography *
gst_base_camera_src_get_photography (GstBaseCameraSrc * self)
{
GstElement *elem;
if (GST_IS_PHOTOGRAPHY (self)) {
elem = GST_ELEMENT (self);
} else {
elem = gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_PHOTOGRAPHY);
}
if (elem) {
return GST_PHOTOGRAPHY (self);
}
return NULL;
}
/**
* gst_base_camera_src_get_colorbalance:
* @self: the camerasrc bin
*
* Get object implementing colorbalance interface, if there is one. Otherwise
* returns NULL.
*/
GstColorBalance *
gst_base_camera_src_get_color_balance (GstBaseCameraSrc * self)
{
GstElement *elem;
if (GST_IS_COLOR_BALANCE (self)) {
elem = GST_ELEMENT (self);
} else {
elem = gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_COLOR_BALANCE);
}
if (elem) {
return GST_COLOR_BALANCE (self);
}
return NULL;
}
/**
* gst_base_camera_src_set_mode:
* @self: the camerasrc bin
* @mode: the mode
*
* XXX
*/
gboolean
gst_base_camera_src_set_mode (GstBaseCameraSrc * self, GstCameraBinMode mode)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
g_return_val_if_fail (bclass->set_mode, FALSE);
return bclass->set_mode (self, mode);
}
/**
* gst_base_camera_src_setup_zoom:
* @self: camerasrc object
*
* Apply zoom configured to camerabin to capture.
*/
void
gst_base_camera_src_setup_zoom (GstBaseCameraSrc * self)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
gint zoom;
zoom = g_atomic_int_get (&self->zoom);
g_return_if_fail (zoom);
g_return_if_fail (bclass->set_zoom);
bclass->set_zoom (self, zoom);
}
/**
* gst_base_camera_src_get_allowed_input_caps:
* @self: the camerasrc bin
*
* Retrieve caps from videosrc describing formats it supports
*
* Returns: caps object from videosrc
*/
GstCaps *
gst_base_camera_src_get_allowed_input_caps (GstBaseCameraSrc * self)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
g_return_val_if_fail (bclass->get_allowed_input_caps, NULL);
return bclass->get_allowed_input_caps (self);
}
/**
* gst_base_camera_src_finish_image_capture:
* @self: camerasrc object
*
* Perform finishing operations after image capture is done and
* returning back to view finder mode.
*/
void
gst_base_camera_src_finish_image_capture (GstBaseCameraSrc * self)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
if (bclass->finish_image_capture) {
bclass->finish_image_capture (self);
}
}
/**
* gst_base_camera_src_find_better_framerate:
* @self: camerasrc object
* @st: structure that contains framerate candidates
* @orig_framerate: best framerate so far
*
* Looks for framerate better than @orig_framerate from @st structure.
* In night mode lowest framerate is considered best, otherwise highest is
* best.
*
* Returns: @orig_framerate or better if found
*/
const GValue *
gst_base_camera_src_find_better_framerate (GstBaseCameraSrc * self,
GstStructure * st, const GValue * orig_framerate)
{
const GValue *framerate = NULL;
guint i, i_best, list_size;
gint res, comparison;
if (self->night_mode) {
GST_LOG_OBJECT (self, "finding min framerate in %" GST_PTR_FORMAT, st);
comparison = GST_VALUE_LESS_THAN;
} else {
GST_LOG_OBJECT (self, "finding max framerate in %" GST_PTR_FORMAT, st);
comparison = GST_VALUE_GREATER_THAN;
}
if (gst_structure_has_field (st, "framerate")) {
framerate = gst_structure_get_value (st, "framerate");
/* Handle framerate lists */
if (GST_VALUE_HOLDS_LIST (framerate)) {
list_size = gst_value_list_get_size (framerate);
GST_LOG_OBJECT (self, "finding framerate from list");
for (i = 0, i_best = 0; i < list_size; i++) {
res = gst_value_compare (gst_value_list_get_value (framerate, i),
gst_value_list_get_value (framerate, i_best));
if (comparison == res) {
i_best = i;
}
}
GST_LOG_OBJECT (self, "found best framerate from index %d", i_best);
framerate = gst_value_list_get_value (framerate, i_best);
}
/* Handle framerate ranges */
if (GST_VALUE_HOLDS_FRACTION_RANGE (framerate)) {
if (self->night_mode) {
GST_LOG_OBJECT (self, "getting min framerate from range");
framerate = gst_value_get_fraction_range_min (framerate);
} else {
GST_LOG_OBJECT (self, "getting max framerate from range");
framerate = gst_value_get_fraction_range_max (framerate);
}
}
}
/* Check if we found better framerate */
if (orig_framerate && framerate) {
res = gst_value_compare (orig_framerate, framerate);
if (comparison == res) {
GST_LOG_OBJECT (self, "original framerate was the best");
framerate = orig_framerate;
}
}
return framerate;
}
/**
*
*/
static void
gst_base_camera_src_dispose (GObject * object)
{
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_base_camera_src_finalize (GstBaseCameraSrc * self)
{
G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (self));
}
static void
gst_base_camera_src_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
GstBaseCameraSrc *self = GST_BASE_CAMERA_SRC (object);
switch (prop_id) {
case ARG_ZOOM:{
g_atomic_int_set (&self->zoom, g_value_get_int (value));
/* does not set it if in NULL, the src is not created yet */
if (GST_STATE (self) != GST_STATE_NULL)
gst_base_camera_src_setup_zoom (self);
break;
}
case ARG_IMAGE_CAPTURE_WIDTH:{
gint width = g_value_get_int (value);
if (width != self->image_capture_width) {
self->image_capture_width = width;
//XXX self->image_capture_caps_update = TRUE;
}
break;
}
case ARG_IMAGE_CAPTURE_HEIGHT:{
gint height = g_value_get_int (value);
if (height != self->image_capture_height) {
self->image_capture_height = height;
//XXX self->image_capture_caps_update = TRUE;
}
break;
}
case ARG_VIDEO_CAPTURE_WIDTH:{
gint width = g_value_get_int (value);
if (width != self->width) {
self->width = width;
//XXX self->video_capture_caps_update = TRUE;
}
break;
}
case ARG_VIDEO_CAPTURE_HEIGHT:{
gint height = g_value_get_int (value);
if (height != self->height) {
self->height = height;
//XXX self->video_capture_caps_update = TRUE;
}
break;
}
case ARG_VIDEO_CAPTURE_FRAMERATE:{
gint fps_n, fps_d;
fps_n = gst_value_get_fraction_numerator (value);
fps_d = gst_value_get_fraction_denominator (value);
if (fps_n != self->fps_n || fps_d != self->fps_d) {
self->fps_n = fps_n;
self->fps_d = fps_d;
//XXX self->video_capture_caps_update = TRUE;
}
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
break;
}
}
static void
gst_base_camera_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstBaseCameraSrc *self = GST_BASE_CAMERA_SRC (object);
switch (prop_id) {
case ARG_ZOOM:
g_value_set_int (value, g_atomic_int_get (&self->zoom));
break;
case ARG_IMAGE_CAPTURE_WIDTH:
g_value_set_int (value, self->image_capture_width);
break;
case ARG_IMAGE_CAPTURE_HEIGHT:
g_value_set_int (value, self->image_capture_height);
break;
case ARG_VIDEO_CAPTURE_WIDTH:
g_value_set_int (value, self->width);
break;
case ARG_VIDEO_CAPTURE_HEIGHT:
g_value_set_int (value, self->height);
break;
case ARG_VIDEO_CAPTURE_FRAMERATE:
gst_value_set_fraction (value, self->fps_n, self->fps_d);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
break;
}
}
static gboolean
construct_pipeline (GstBaseCameraSrc * self)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
GstPad *vfsrc = NULL;
GstPad *imgsrc = NULL;
GstPad *vidsrc = NULL;
g_return_val_if_fail (bclass->construct_pipeline, FALSE);
if (!bclass->construct_pipeline (self, &vfsrc, &imgsrc, &vidsrc)) {
GST_ERROR_OBJECT (self, "pipeline construction failed");
return FALSE;
}
if (!vfsrc || !imgsrc || !vidsrc) {
GST_ERROR_OBJECT (self, "derived class must return src pads");
return FALSE;
}
GST_DEBUG_OBJECT (self, "vfsrc: %" GST_PTR_FORMAT, vfsrc);
GST_DEBUG_OBJECT (self, "imgsrc: %" GST_PTR_FORMAT, imgsrc);
GST_DEBUG_OBJECT (self, "vidsrc: %" GST_PTR_FORMAT, vidsrc);
/* hook-up the ghostpads */
gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vfsrc);
gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc), imgsrc);
gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), vidsrc);
gst_pad_set_active (self->vfsrc, TRUE);
gst_pad_set_active (self->imgsrc, TRUE); /* XXX ??? */
gst_pad_set_active (self->vidsrc, TRUE); /* XXX ??? */
return TRUE;
}
static gboolean
setup_pipeline (GstBaseCameraSrc * self)
{
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
if (bclass->setup_pipeline)
return bclass->setup_pipeline (self);
return TRUE;
}
static GstStateChangeReturn
gst_base_camera_src_change_state (GstElement * element,
GstStateChange transition)
{
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GstBaseCameraSrc *self = GST_BASE_CAMERA_SRC (element);
GST_DEBUG_OBJECT (self, "%d -> %d",
GST_STATE_TRANSITION_CURRENT (transition),
GST_STATE_TRANSITION_NEXT (transition));
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
if (!construct_pipeline (self))
return GST_STATE_CHANGE_FAILURE;
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!setup_pipeline (self))
return GST_STATE_CHANGE_FAILURE;
break;
default:
break;
}
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
return ret;
}
static void
gst_base_camera_src_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GST_DEBUG_CATEGORY_INIT (base_camera_src_debug, "base_camera_src", 0,
"Base camera src");
gst_element_class_set_details_simple (gstelement_class,
"Base class for camerabin src bin", "Source/Video",
"Abstracts capture device for camerabin", "Rob Clark <rob@ti.com>");
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&vfsrc_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 (&vidsrc_template));
}
static void
gst_base_camera_src_class_init (GstBaseCameraSrcClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = G_OBJECT_CLASS (klass);
gstelement_class = GST_ELEMENT_CLASS (klass);
gobject_class->dispose = gst_base_camera_src_dispose;
gobject_class->finalize = (GObjectFinalizeFunc) gst_base_camera_src_finalize;
gobject_class->set_property = gst_base_camera_src_set_property;
gobject_class->get_property = gst_base_camera_src_get_property;
// g_object_class_install_property ....
gstelement_class->change_state = gst_base_camera_src_change_state;
}
static void
gst_base_camera_src_init (GstBaseCameraSrc * self,
GstBaseCameraSrcClass * klass)
{
self->vfsrc = gst_ghost_pad_new_no_target ("vfsrc", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (self), self->vfsrc);
self->imgsrc = gst_ghost_pad_new_no_target ("imgsrc", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (self), self->imgsrc);
self->vidsrc = gst_ghost_pad_new_no_target ("vidsrc", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (self), self->vidsrc);
self->width = DEFAULT_WIDTH;
self->height = DEFAULT_HEIGHT;
self->zoom = DEFAULT_ZOOM;
self->image_capture_width = 0;
self->image_capture_height = 0;
self->night_mode = FALSE;
self->fps_n = DEFAULT_FPS_N;
self->fps_d = DEFAULT_FPS_D;
}

View file

@ -0,0 +1,146 @@
/*
* GStreamer
* Copyright (C) 2010 Texas Instruments, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_BASE_CAMERA_SRC_H__
#define __GST_BASE_CAMERA_SRC_H__
#include <gst/gst.h>
#include <gst/gstbin.h>
#include <gst/interfaces/photography.h>
#include <gst/interfaces/colorbalance.h>
#include "gstcamerabin-enum.h"
G_BEGIN_DECLS
#define GST_TYPE_BASE_CAMERA_SRC \
(gst_base_camera_src_get_type())
#define GST_BASE_CAMERA_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_CAMERA_SRC,GstBaseCameraSrc))
#define GST_BASE_CAMERA_SRC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BASE_CAMERA_SRC, GstBaseCameraSrcClass))
#define GST_BASE_CAMERA_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_CAMERA_SRC,GstBaseCameraSrcClass))
#define GST_IS_BASE_CAMERA_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_CAMERA_SRC))
#define GST_IS_BASE_CAMERA_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_CAMERA_SRC))
GType gst_base_camera_src_get_type (void);
typedef struct _GstBaseCameraSrc GstBaseCameraSrc;
typedef struct _GstBaseCameraSrcClass GstBaseCameraSrcClass;
/**
* GstBaseCameraSrc:
*/
struct _GstBaseCameraSrc
{
GstBin parent;
GstPad *vfsrc;
GstPad *imgsrc;
GstPad *vidsrc;
/* XXX preview pads? */
/* Resolution of the buffers configured to camerabin */
gint width;
gint height;
/* The digital zoom (from 100% to 1000%) */
gint zoom;
/* Image capture resolution */
gint image_capture_width;
gint image_capture_height;
/* Frames per second configured to camerabin */
gint fps_n;
gint fps_d;
/* Night mode handling */
gboolean night_mode;
gint pre_night_fps_n;
gint pre_night_fps_d;
gpointer _gst_reserved[GST_PADDING_LARGE];
};
/**
* GstBaseCameraSrcClass:
* @construct_pipeline: construct pipeline must be implemented by derived
* class, and return by reference vfsrc, imgsrc, and vidsrc pads of the
* contained pipeline, which will be ghosted to the src pads of the
* camerasrc bin (and optionally the preview src pads?)
* @setup_pipeline:
* @set_zoom: set the zoom
* @set_mode: set the mode
*/
struct _GstBaseCameraSrcClass
{
GstBinClass parent;
/* construct pipeline must be implemented by derived class, and return by
* reference vfsrc, imgsrc, and vidsrc pads of the contained pipeline, which
* will be ghosted to the src pads of the camerasrc bin (and optionally the
* preview src pads?) */
gboolean (*construct_pipeline) (GstBaseCameraSrc *self,
GstPad **vfsrc, GstPad **imgsrc,
GstPad **vidsrc);
/* optional */
gboolean (*setup_pipeline) (GstBaseCameraSrc *self);
/* set the zoom */
void (*set_zoom) (GstBaseCameraSrc *self, gint zoom);
/* set the mode */
gboolean (*set_mode) (GstBaseCameraSrc *self,
GstCameraBinMode mode);
/* */
GstCaps * (*get_allowed_input_caps) (GstBaseCameraSrc * self);
/* optional */
void (*finish_image_capture) (GstBaseCameraSrc * self);
gpointer _gst_reserved[GST_PADDING_LARGE];
};
#define MIN_ZOOM 100
#define MAX_ZOOM 1000
#define ZOOM_1X MIN_ZOOM
GstPhotography * gst_base_camera_src_get_photography (GstBaseCameraSrc *self);
GstColorBalance * gst_base_camera_src_get_color_balance (GstBaseCameraSrc *self);
gboolean gst_base_camera_src_set_mode (GstBaseCameraSrc *self, GstCameraBinMode mode);
void gst_base_camera_src_setup_zoom (GstBaseCameraSrc * self);
GstCaps * gst_base_camera_src_get_allowed_input_caps (GstBaseCameraSrc * self);
void gst_base_camera_src_finish_image_capture (GstBaseCameraSrc * self);
const GValue * gst_base_camera_src_find_better_framerate (
GstBaseCameraSrc * self, GstStructure * st, const GValue * orig_framerate);
// XXX add methods to get/set img capture and vid capture caps..
#endif /* __GST_BASE_CAMERA_SRC_H__ */

View file

@ -0,0 +1,78 @@
/*
* GStreamer
* Copyright (C) 2009 Nokia Corporation <multimedia@maemo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstcamerabin-enum.h"
#define C_FLAGS(v) ((guint) v)
static void
register_gst_camerabin_flags (GType * id)
{
static const GFlagsValue values[] = {
{C_FLAGS (GST_CAMERABIN_FLAG_SOURCE_RESIZE),
"Enable source crop and scale", "source-resize"},
{C_FLAGS (GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION),
"Enable colorspace conversion for video source",
"source-colorspace-conversion"},
{C_FLAGS (GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION),
"Enable colorspace conversion for viewfinder",
"viewfinder-colorspace-conversion"},
{C_FLAGS (GST_CAMERABIN_FLAG_VIEWFINDER_SCALE),
"Enable scale for viewfinder", "viewfinder-scale"},
{C_FLAGS (GST_CAMERABIN_FLAG_AUDIO_CONVERSION),
"Enable audio conversion for video capture", "audio-conversion"},
{C_FLAGS (GST_CAMERABIN_FLAG_DISABLE_AUDIO),
"Disable audio elements for video capture", "disable-audio"},
{C_FLAGS (GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION),
"Enable colorspace conversion for still image",
"image-colorspace-conversion"},
{0, NULL, NULL}
};
*id = g_flags_register_static ("GstCameraBinFlags", values);
}
GType
gst_camerabin_flags_get_type (void)
{
static GType id;
static GOnce once = G_ONCE_INIT;
g_once (&once, (GThreadFunc) register_gst_camerabin_flags, &id);
return id;
}
GType
gst_camerabin_mode_get_type (void)
{
static GType gtype = 0;
if (gtype == 0) {
static const GEnumValue values[] = {
{MODE_PREVIEW, "Preview mode (should be default?)", "mode-preview"},
{MODE_IMAGE, "Still image capture (default)", "mode-image"},
{MODE_VIDEO, "Video recording", "mode-video"},
{0, NULL, NULL}
};
gtype = g_enum_register_static ("GstCameraBinMode", values);
}
return gtype;
}

View file

@ -0,0 +1,140 @@
/*
* GStreamer
* Copyright (C) 2009 Nokia Corporation <multimedia@maemo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_CAMERABIN_ENUM_H__
#define __GST_CAMERABIN_ENUM_H__
#include <gst/gst.h>
G_BEGIN_DECLS
/* XXX find better place for property related enum/defaults */
enum
{
ARG_0,
ARG_FILENAME,
ARG_MODE,
ARG_FLAGS,
ARG_MUTE,
ARG_ZOOM,
ARG_IMAGE_POST,
ARG_IMAGE_ENC,
ARG_VIDEO_POST,
ARG_VIDEO_ENC,
ARG_AUDIO_ENC,
ARG_VIDEO_MUX,
ARG_VF_SINK,
ARG_VIDEO_SRC,
ARG_AUDIO_SRC,
ARG_INPUT_CAPS,
ARG_FILTER_CAPS,
ARG_PREVIEW_CAPS,
ARG_WB_MODE,
ARG_COLOUR_TONE,
ARG_SCENE_MODE,
ARG_FLASH_MODE,
ARG_FOCUS_STATUS,
ARG_CAPABILITIES,
ARG_SHAKE_RISK,
ARG_EV_COMP,
ARG_ISO_SPEED,
ARG_APERTURE,
ARG_EXPOSURE,
ARG_VIDEO_SOURCE_FILTER,
ARG_IMAGE_CAPTURE_SUPPORTED_CAPS,
ARG_VIEWFINDER_FILTER,
ARG_FLICKER_MODE,
ARG_FOCUS_MODE,
ARG_BLOCK_VIEWFINDER,
ARG_IMAGE_CAPTURE_WIDTH,
ARG_IMAGE_CAPTURE_HEIGHT,
ARG_VIDEO_CAPTURE_WIDTH,
ARG_VIDEO_CAPTURE_HEIGHT,
ARG_VIDEO_CAPTURE_FRAMERATE
};
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480
#define DEFAULT_CAPTURE_WIDTH 800
#define DEFAULT_CAPTURE_HEIGHT 600
#define DEFAULT_FPS_N 0 /* makes it use the default */
#define DEFAULT_FPS_D 1
#define DEFAULT_ZOOM MIN_ZOOM
/**
* GstCameraBinFlags:
* @GST_CAMERABIN_FLAG_SOURCE_RESIZE: enable video crop and scale
* after capture
* @GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION: enable conversion
* of native video format by enabling ffmpegcolorspace
* @GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION: enable color
* conversion for viewfinder element
* @GST_CAMERABIN_FLAG_VIEWFINDER_SCALE: enable scaling in
* viewfinder element retaining aspect ratio
* @GST_CAMERABIN_FLAG_AUDIO_CONVERSION: enable audioconvert and
* audioresample elements
* @GST_CAMERABIN_FLAG_DISABLE_AUDIO: disable audio elements
* @GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION: enable color
* conversion for image output element
*
* Extra flags to configure the behaviour of the sinks.
*/
typedef enum {
GST_CAMERABIN_FLAG_SOURCE_RESIZE = (1 << 0),
GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION = (1 << 1),
GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION = (1 << 2),
GST_CAMERABIN_FLAG_VIEWFINDER_SCALE = (1 << 3),
GST_CAMERABIN_FLAG_AUDIO_CONVERSION = (1 << 4),
GST_CAMERABIN_FLAG_DISABLE_AUDIO = (1 << 5),
GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION = (1 << 6)
} GstCameraBinFlags;
#define GST_TYPE_CAMERABIN_FLAGS (gst_camerabin_flags_get_type())
GType gst_camerabin_flags_get_type (void);
/**
* GstCameraBinMode:
* @MODE_PREVIEW: preview only (no capture) mode
* @MODE_IMAGE: image capture
* @MODE_VIDEO: video capture
*
* Capture mode to use.
*/
typedef enum
{
/* note: changed to align with 'capture-mode' property (even though
* I have no idea where this property comes from..) But it somehow
* seems more logical for preview to be mode==0 even if it is an ABI
* break..
*/
MODE_PREVIEW = 0,
MODE_IMAGE = 1,
MODE_VIDEO = 2,
} GstCameraBinMode;
#define GST_TYPE_CAMERABIN_MODE (gst_camerabin_mode_get_type ())
GType gst_camerabin_mode_get_type (void);
G_END_DECLS
#endif /* #ifndef __GST_CAMERABIN_ENUM_H__ */

View file

@ -25,6 +25,7 @@
#include "gstviewfinderbin.h" #include "gstviewfinderbin.h"
#include "gstimagecapturebin.h" #include "gstimagecapturebin.h"
#include "gstv4l2camerasrc.h"
static gboolean static gboolean
plugin_init (GstPlugin * plugin) plugin_init (GstPlugin * plugin)
@ -33,6 +34,8 @@ plugin_init (GstPlugin * plugin)
return FALSE; return FALSE;
if (!gst_image_capture_bin_plugin_init (plugin)) if (!gst_image_capture_bin_plugin_init (plugin))
return FALSE; return FALSE;
if (!gst_v4l2_camera_src_plugin_init (plugin))
return FALSE;
return TRUE; return TRUE;
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,112 @@
/*
* GStreamer
* Copyright (C) 2010 Texas Instruments, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_V4L2_CAMERA_SRC_H__
#define __GST_V4L2_CAMERA_SRC_H__
#include <gst/gst.h>
#include "gstbasecamerasrc.h"
G_BEGIN_DECLS
#define GST_TYPE_V4L2_CAMERA_SRC \
(gst_v4l2_camera_src_get_type())
#define GST_V4L2_CAMERA_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2_CAMERA_SRC,GstV4l2CameraSrc))
#define GST_V4L2_CAMERA_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2_CAMERA_SRC,GstV4l2CameraSrcClass))
#define GST_IS_V4L2_CAMERA_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2_CAMERA_SRC))
#define GST_IS_V4L2_CAMERA_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2_CAMERA_SRC))
GType gst_v4l2_camera_src_get_type (void);
typedef struct _GstV4l2CameraSrc GstV4l2CameraSrc;
typedef struct _GstV4l2CameraSrcClass GstV4l2CameraSrcClass;
/**
* GstV4l2CameraSrc:
*
*/
struct _GstV4l2CameraSrc
{
GstBaseCameraSrc parent;
GstCameraBinMode mode;
/* source elements */
GstElement *src_vid_src;
GstElement *src_filter;
GstElement *src_zoom_crop;
GstElement *src_zoom_scale;
GstElement *src_zoom_filter;
GstElement *src_out_sel;
/* srcpads of tee */
GstPad *tee_vf_srcpad;
GstPad *tee_image_srcpad;
GstPad *tee_video_srcpad;
/* Application configurable elements */
GstElement *app_vid_src;
GstElement *app_video_filter;
/* Caps that videosrc supports */
GstCaps *allowed_caps;
/* Optional base crop for frames. Used to crop frames e.g.
due to wrong aspect ratio, before the crop related to zooming. */
gint base_crop_top;
gint base_crop_bottom;
gint base_crop_left;
gint base_crop_right;
/* Caps applied to capsfilters when in view finder mode */
GstCaps *view_finder_caps;
/* Caps applied to capsfilters when taking still image */
GstCaps *image_capture_caps;
gboolean image_capture_caps_update; // XXX where does this get set..
/* if GstV4l2CameraSrc is moved into camerabin plugin, then this isn't
* needed:
*/
gpointer _gst_reserved[GST_PADDING_LARGE];
};
/**
* GstV4l2CameraSrcClass:
*
*/
struct _GstV4l2CameraSrcClass
{
GstBaseCameraSrcClass parent;
/* if GstV4l2CameraSrc is moved into camerabin plugin, then this isn't
* needed:
*/
gpointer _gst_reserved[GST_PADDING_LARGE];
};
gboolean gst_v4l2_camera_src_plugin_init (GstPlugin * plugin);
#endif /* __GST_V4L2_CAMERA_SRC_H__ */