Remove old camerabin
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 30 Apr 2012 16:44:34 +0000 (17:44 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 30 Apr 2012 16:44:34 +0000 (17:44 +0100)
39 files changed:
configure.ac
docs/plugins/Makefile.am
docs/plugins/gst-plugins-bad-plugins-docs.sgml
docs/plugins/gst-plugins-bad-plugins-sections.txt
docs/plugins/inspect/plugin-camerabin.xml [deleted file]
docs/plugins/inspect/plugin-camerabin2.xml [deleted file]
gst/camerabin/.gitignore [deleted file]
gst/camerabin/Makefile.am [deleted file]
gst/camerabin/TODO [deleted file]
gst/camerabin/camerabindebug.h [deleted file]
gst/camerabin/camerabingeneral.c [deleted file]
gst/camerabin/camerabingeneral.h [deleted file]
gst/camerabin/camerabinimage.c [deleted file]
gst/camerabin/camerabinimage.h [deleted file]
gst/camerabin/camerabinpreview.c [deleted file]
gst/camerabin/camerabinpreview.h [deleted file]
gst/camerabin/camerabinvideo.c [deleted file]
gst/camerabin/camerabinvideo.h [deleted file]
gst/camerabin/gstcamerabin-enum.c [deleted file]
gst/camerabin/gstcamerabin-enum.h [deleted file]
gst/camerabin/gstcamerabin-marshal.list [deleted file]
gst/camerabin/gstcamerabin.c [deleted file]
gst/camerabin/gstcamerabin.h [deleted file]
gst/camerabin/gstcamerabincolorbalance.c [deleted file]
gst/camerabin/gstcamerabincolorbalance.h [deleted file]
gst/camerabin/gstinputselector.c [deleted file]
gst/camerabin/gstinputselector.h [deleted file]
tests/check/Makefile.am
tests/check/elements/camerabin.c
tests/check/elements/camerabin2.c [deleted file]
tests/examples/Makefile.am
tests/examples/camerabin/.gitignore [deleted file]
tests/examples/camerabin/Makefile.am [deleted file]
tests/examples/camerabin/gst-camera-perf.c [deleted file]
tests/examples/camerabin/gst-camera-perf.ui [deleted file]
tests/examples/camerabin/gst-camera.c [deleted file]
tests/examples/camerabin/gst-camera.h [deleted file]
tests/examples/camerabin/gst-camera.ui [deleted file]
tests/examples/camerabin/gst-camerabin-test.c [deleted file]

index c8d2a2b..92eb1c4 100644 (file)
@@ -147,7 +147,6 @@ if test "x$HAVE_UNISTD_H" != "xyes"; then
   GST_PLUGINS_SELECTED=`echo $GST_PLUGINS_SELECTED | $SED -e s/festival//`
 fi
 
-dnl used by camerabin
 AC_CHECK_HEADERS([sys/time.h])
 
 dnl used by ext/dts
@@ -301,7 +300,7 @@ dnl *** plug-ins to include ***
 dnl Non ported plugins (non-dependant, then dependant)
 dnl Make sure you have a space before and after all plugins
 GST_PLUGINS_NONPORTED=" aiff \
- camerabin cdxaparse \
+ cdxaparse \
  dccp faceoverlay festival \
  fieldanalysis freeverb freeze frei0r gaudieffects \
  hdvparse id3tag inter interlace ivfparse jpegformat jp2kdecimator \
@@ -325,7 +324,6 @@ AG_GST_CHECK_PLUGIN(asfmux)
 AG_GST_CHECK_PLUGIN(audiovisualizers)
 AG_GST_CHECK_PLUGIN(autoconvert)
 AG_GST_CHECK_PLUGIN(bayer)
-AG_GST_CHECK_PLUGIN(camerabin)
 AG_GST_CHECK_PLUGIN(camerabin2)
 AG_GST_CHECK_PLUGIN(cdxaparse)
 AG_GST_CHECK_PLUGIN(coloreffects)
@@ -2013,7 +2011,6 @@ gst/asfmux/Makefile
 gst/audiovisualizers/Makefile
 gst/autoconvert/Makefile
 gst/bayer/Makefile
-gst/camerabin/Makefile
 gst/camerabin2/Makefile
 gst/cdxaparse/Makefile
 gst/coloreffects/Makefile
@@ -2113,7 +2110,6 @@ tests/Makefile
 tests/check/Makefile
 tests/files/Makefile
 tests/examples/Makefile
-tests/examples/camerabin/Makefile
 tests/examples/camerabin2/Makefile
 tests/examples/directfb/Makefile
 tests/examples/mxf/Makefile
index 0dbff8d..c34f435 100644 (file)
@@ -115,7 +115,6 @@ EXTRA_HFILES = \
        $(top_srcdir)/gst/audiovisualizers/gstspectrascope.h \
        $(top_srcdir)/gst/audiovisualizers/gstsynaescope.h \
        $(top_srcdir)/gst/audiovisualizers/gstwavescope.h \
-       $(top_srcdir)/gst/camerabin/gstcamerabin.h \
        $(top_srcdir)/gst/camerabin2/gstcamerabin2.h \
        $(top_srcdir)/gst/coloreffects/gstcoloreffects.h \
        $(top_srcdir)/gst/dataurisrc/gstdataurisrc.h \
index 606c8ea..16d8d7c 100644 (file)
@@ -24,7 +24,6 @@
     <xi:include href="xml/element-bulge.xml" />
     <xi:include href="xml/element-burn.xml" />
     <xi:include href="xml/element-camerabin.xml" />
-    <xi:include href="xml/element-camerabin2.xml" />
     <xi:include href="xml/element-celtdec.xml" />
     <xi:include href="xml/element-celtenc.xml" />
     <xi:include href="xml/element-chromium.xml" />
     <xi:include href="xml/plugin-bayer.xml" />
     <xi:include href="xml/plugin-bz2.xml" />
     <xi:include href="xml/plugin-camerabin.xml" />
-    <xi:include href="xml/plugin-camerabin2.xml" />
     <xi:include href="xml/plugin-cdaudio.xml" />
     <xi:include href="xml/plugin-cdxaparse.xml" />
     <xi:include href="xml/plugin-celt.xml" />
index b01e198..575c440 100644 (file)
@@ -104,29 +104,14 @@ gst_burn_plugin_init
 <FILE>element-camerabin</FILE>
 <TITLE>camerabin</TITLE>
 GstCameraBin
-GstCameraBinMode
 <SUBSECTION Standard>
 GstCameraBinClass
-GST_CAMERABIN
-GST_IS_CAMERABIN
-GST_TYPE_CAMERABIN
-GST_CAMERABIN_CLASS
-GST_IS_CAMERABIN_CLASS
-gst_camerabin_get_type
-</SECTION>
-
-<SECTION>
-<FILE>element-camerabin2</FILE>
-<TITLE>camerabin2</TITLE>
-GstCameraBin2
-<SUBSECTION Standard>
-GstCameraBin2Class
-GST_CAMERA_BIN2
-GST_IS_CAMERA_BIN2
-GST_TYPE_CAMERA_BIN2
-GST_CAMERA_BIN2_CLASS
-GST_IS_CAMERA_BIN2_CLASS
-gst_camera_bin2_get_type
+GST_CAMERA_BIN
+GST_IS_CAMERA_BIN
+GST_TYPE_CAMERA_BIN
+GST_CAMERA_BIN_CLASS
+GST_IS_CAMERA_BIN_CLASS
+gst_camera_bin_get_type
 </SECTION>
 
 <SECTION>
diff --git a/docs/plugins/inspect/plugin-camerabin.xml b/docs/plugins/inspect/plugin-camerabin.xml
deleted file mode 100644 (file)
index b9d6b0e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<plugin>
-  <name>camerabin</name>
-  <description>High level api for DC (Digital Camera) application</description>
-  <filename>../../gst/camerabin/.libs/libgstcamerabin.so</filename>
-  <basename>libgstcamerabin.so</basename>
-  <version>0.10.23.1</version>
-  <license>LGPL</license>
-  <source>gst-plugins-bad</source>
-  <package>GStreamer Bad Plug-ins git</package>
-  <origin>Unknown package origin</origin>
-  <elements>
-    <element>
-      <name>camerabin</name>
-      <longname>Camera Bin</longname>
-      <class>Generic/Bin/Camera</class>
-      <description>Handle lot of features present in DSC</description>
-      <author>Nokia Corporation &lt;multimedia@maemo.org&gt;, Edgard Lima &lt;edgard.lima@indt.org.br&gt;</author>
-      <pads>
-      </pads>
-    </element>
-  </elements>
-</plugin>
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-camerabin2.xml b/docs/plugins/inspect/plugin-camerabin2.xml
deleted file mode 100644 (file)
index 2245e37..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-<plugin>
-  <name>camerabin2</name>
-  <description>camerabin2</description>
-  <filename>../../gst/camerabin2/.libs/libgstcamerabin2.so</filename>
-  <basename>libgstcamerabin2.so</basename>
-  <version>0.11.90</version>
-  <license>LGPL</license>
-  <source>gst-plugins-bad</source>
-  <package>GStreamer Bad Plug-ins source release</package>
-  <origin>Unknown package origin</origin>
-  <elements>
-    <element>
-      <name>camerabin2</name>
-      <longname>CameraBin2</longname>
-      <class>Generic/Bin/Camera</class>
-      <description>CameraBin2</description>
-      <author>Thiago Santos &lt;thiago.sousa.santos@collabora.co.uk&gt;</author>
-      <pads>
-      </pads>
-    </element>
-    <element>
-      <name>viewfinderbin</name>
-      <longname>Viewfinder Bin</longname>
-      <class>Sink/Video</class>
-      <description>Viewfinder Bin used in camerabin2</description>
-      <author>Thiago Santos &lt;thiago.sousa.santos@collabora.com&gt;</author>
-      <pads>
-        <caps>
-          <name>sink</name>
-          <direction>sink</direction>
-          <presence>always</presence>
-          <details>video/x-raw</details>
-        </caps>
-      </pads>
-    </element>
-    <element>
-      <name>wrappercamerabinsrc</name>
-      <longname>Wrapper camera src element for camerabin2</longname>
-      <class>Source/Video</class>
-      <description>Wrapper camera src element for camerabin2</description>
-      <author>Thiago Santos &lt;thiago.sousa.santos@collabora.com&gt;</author>
-      <pads>
-        <caps>
-          <name>imgsrc</name>
-          <direction>source</direction>
-          <presence>always</presence>
-          <details>ANY</details>
-        </caps>
-        <caps>
-          <name>vfsrc</name>
-          <direction>source</direction>
-          <presence>always</presence>
-          <details>ANY</details>
-        </caps>
-        <caps>
-          <name>vidsrc</name>
-          <direction>source</direction>
-          <presence>always</presence>
-          <details>ANY</details>
-        </caps>
-      </pads>
-    </element>
-  </elements>
-</plugin>
\ No newline at end of file
diff --git a/gst/camerabin/.gitignore b/gst/camerabin/.gitignore
deleted file mode 100644 (file)
index 36a1833..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-gstcamerabin-marshal.c
-gstcamerabin-marshal.h
diff --git a/gst/camerabin/Makefile.am b/gst/camerabin/Makefile.am
deleted file mode 100644 (file)
index 58147bc..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-glib_gen_prefix = __gst_camerabin
-glib_gen_basename = gstcamerabin
-
-include $(top_srcdir)/common/gst-glib-gen.mak
-
-built_sources = gstcamerabin-marshal.c
-built_headers = gstcamerabin-marshal.h
-
-BUILT_SOURCES = $(built_sources) $(built_headers)
-
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = gstcamerabin-marshal.list
-
-plugin_LTLIBRARIES = libgstcamerabin.la
-
-libgstcamerabin_la_SOURCES = gstcamerabin.c             \
-                         gstcamerabincolorbalance.c \
-                         gstinputselector.c         \
-                         camerabinimage.c           \
-                         camerabinvideo.c           \
-                         camerabingeneral.c         \
-                         camerabinpreview.c         \
-                         gstcamerabin-enum.c
-
-nodist_libgstcamerabin_la_SOURCES = $(built_sources)
-libgstcamerabin_la_CFLAGS = \
-       $(GST_PLUGINS_BAD_CFLAGS) \
-       $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
-       -DGST_USE_UNSTABLE_API
-libgstcamerabin_la_LIBADD = \
-       $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-$(GST_API_VERSION).la \
-       $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \
-       -lgstinterfaces-$(GST_API_VERSION) -lgsttag-$(GST_API_VERSION)
-
-libgstcamerabin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstcamerabin_la_LIBTOOLFLAGS = --tag=disable-static
-
-noinst_HEADERS = gstcamerabin.h             \
-                gstcamerabincolorbalance.h \
-                gstinputselector.h         \
-                camerabinimage.h           \
-                camerabinvideo.h           \
-                camerabindebug.h           \
-                camerabingeneral.h         \
-                camerabinpreview.h         \
-                gstcamerabin-enum.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-       androgenizer \
-       -:PROJECT libgstcamerabin -:SHARED libgstcamerabin \
-        -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-        -:SOURCES $(libgstcamerabin_la_SOURCES) \
-        -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcamerabin_la_CFLAGS) \
-        -:LDFLAGS $(libgstcamerabin_la_LDFLAGS) \
-                  $(libgstcamerabin_la_LIBADD) \
-                  -ldl \
-        -:LIBFILTER_STATIC gstphotography-@GST_API_VERSION@ \
-                 gstbasecamerabinsrc-@GST_API_VERSION@ \
-        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-                      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-       > $@
diff --git a/gst/camerabin/TODO b/gst/camerabin/TODO
deleted file mode 100644 (file)
index 423c062..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-= Cleanups =
-* often two g_object_set for same object one after the other
-* use GST_*_OBJECT () more often
-* there are two gst_element_set_state() one after each other
-
-= Renaming =
-* internal use of img->image, vid->video
-
-= Refactorisation =
-* gstcamerabin:gst_camerabin_rewrite_tags
-  - sounds fishy, should use normal tagsetter method
-  - gst_camerabin_rewrite_tags_to_bin(9 why don't we just send a tag-event?
-
-* file-name property
-  - supplying an already opened filedeskriptor would be more safe
-  - need to check what filesink does if the file exists and cannot be overwritten
-
-* imagbin
-  - we want async operation here (especialy for burst mode capture)
-  - right now, its a bit fragile as we muck with locked_state
-  - main problem is that the location for filesink can only be set in NULL/READY
-    and we need to do that sync'ed with the dataflow. we can't use multifilesink
-    as it does a file per pad_push
-  - one problem of the current approach is that we can't have an image in e.g,
-    postprocessing while anotherone is beeing saved
-  - we could use a pool of imagebins:
-    - configure one (set filename)
-    - push_buffer
-    - on eos, put it back to the pool
-    - for this we need to check that we can have multiple instances of e.g.
-      dsp jpeg encoders
diff --git a/gst/camerabin/camerabindebug.h b/gst/camerabin/camerabindebug.h
deleted file mode 100644 (file)
index 9b16ac5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2010 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_DEBUG_H_
-#define __CAMERABIN_DEBUG_H_
-
-#include <gst/gst.h>
-
-/* debug logging category */
-GST_DEBUG_CATEGORY_EXTERN (gst_camerabin_debug);
-#define GST_CAT_DEFAULT gst_camerabin_debug
-
-#endif /* #ifndef __CAMERABIN_DEBUG_H_ */
diff --git a/gst/camerabin/camerabingeneral.c b/gst/camerabin/camerabingeneral.c
deleted file mode 100644 (file)
index f47b9d2..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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 <glib.h>
-
-#include "camerabingeneral.h"
-#include "gstinputselector.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)
-{
-  gboolean ret;
-
-  g_return_val_if_fail (bin, FALSE);
-  g_return_val_if_fail (new_elem, FALSE);
-
-  ret = gst_camerabin_try_add_element (bin, new_elem);
-
-  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
- * @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.
- *
- * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise.
- */
-gboolean
-gst_camerabin_try_add_element (GstBin * bin, GstElement * new_elem)
-{
-  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_full (bin_elem, NULL, new_elem, NULL,
-            GST_PAD_LINK_CHECK_CAPS)) {
-      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
- * @instance_name: name of the instance 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,
-    const gchar * instance_name)
-{
-  GstElement *new_elem;
-
-  g_return_val_if_fail (bin, FALSE);
-  g_return_val_if_fail (elem_name, FALSE);
-
-  if (strcmp (elem_name, "input-selector") == 0) {
-    /* we ship our own copy of input-selector because we still use the
-     * "select-all" property which was removed when input-selector was
-     * moved to core */
-    new_elem = g_object_new (GST_TYPE_INPUT_SELECTOR, NULL);
-  } else {
-    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;
-}
diff --git a/gst/camerabin/camerabingeneral.h b/gst/camerabin/camerabingeneral.h
deleted file mode 100644 (file)
index 12a4d46..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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, GstElement * new_elem);
-gboolean gst_camerabin_add_element (GstBin * bin, GstElement * new_elem);
-GstElement *gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name, const gchar * instance_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);
-
-#endif /* #ifndef __CAMERABIN_GENERAL_H_ */
diff --git a/gst/camerabin/camerabinimage.c b/gst/camerabin/camerabinimage.c
deleted file mode 100644 (file)
index ab82b40..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * 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:camerabinimage
- * @short_description: image capturing module of #GstCameraBin
- *
- * <refsect2>
- * <para>
- *
- * The pipeline for this module is:
- *
- * <informalexample>
- * <programlisting>
- *-----------------------------------------------------------------------------
- *
- * -> [post proc] -> csp -> imageenc -> metadatamuxer -> filesink
- *
- *-----------------------------------------------------------------------------
- * </programlisting>
- * </informalexample>
- *
- * The image bin opens file for image writing in READY to PAUSED state change.
- * The image bin closes the file in PAUSED to READY state change.
- *
- * </para>
- * </refsect2>
- */
-
-/*
- * includes
- */
-
-#include <gst/gst.h>
-
-#include "camerabinimage.h"
-#include "camerabindebug.h"
-#include "camerabingeneral.h"
-#include "gstcamerabin-enum.h"
-
-#include "string.h"
-
-/* default internal element names */
-
-#define DEFAULT_SINK "filesink"
-#define DEFAULT_ENC "jpegenc"
-#define DEFAULT_FORMATTER "jifmux"
-#define DEFAULT_FLAGS GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION
-
-enum
-{
-  PROP_0,
-  PROP_FILENAME
-};
-
-static gboolean gst_camerabin_image_create_elements (GstCameraBinImage * img);
-static void gst_camerabin_image_destroy_elements (GstCameraBinImage * img);
-
-static void gst_camerabin_image_dispose (GstCameraBinImage * sink);
-static GstStateChangeReturn
-gst_camerabin_image_change_state (GstElement * element,
-    GstStateChange transition);
-static gboolean gst_camerabin_image_send_event (GstElement * element,
-    GstEvent * event);
-static void gst_camerabin_image_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_camerabin_image_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static gboolean metadata_write_probe (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data);
-static gboolean prepare_element (GList ** result,
-    const gchar * default_element_name, GstElement * app_elem,
-    GstElement ** res_elem);
-
-
-GST_BOILERPLATE (GstCameraBinImage, gst_camerabin_image, GstBin, GST_TYPE_BIN);
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
-
-static void
-gst_camerabin_image_base_init (gpointer klass)
-{
-  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (eklass,
-      gst_static_pad_template_get (&sink_template));
-  gst_element_class_set_details_simple (eklass,
-      "Image capture bin for camerabin", "Bin/Image",
-      "Process and store image data",
-      "Edgard Lima <edgard.lima@indt.org.br>, "
-      "Nokia Corporation <multimedia@maemo.org>");
-}
-
-static void
-gst_camerabin_image_class_init (GstCameraBinImageClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
-  gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->dispose =
-      (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_camerabin_image_dispose);
-  eklass->change_state = GST_DEBUG_FUNCPTR (gst_camerabin_image_change_state);
-  eklass->send_event = GST_DEBUG_FUNCPTR (gst_camerabin_image_send_event);
-
-  gobject_class->set_property =
-      GST_DEBUG_FUNCPTR (gst_camerabin_image_set_property);
-  gobject_class->get_property =
-      GST_DEBUG_FUNCPTR (gst_camerabin_image_get_property);
-
-  /**
-   * GstCameraBinImage:filename
-   *
-   * This property can be used to specify the filename of the image.
-   *
-   **/
-  g_object_class_install_property (gobject_class, PROP_FILENAME,
-      g_param_spec_string ("filename", "Filename",
-          "Filename of the image to save", NULL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_camerabin_image_init (GstCameraBinImage * img,
-    GstCameraBinImageClass * g_class)
-{
-  img->filename = g_string_new ("");
-
-  img->post = NULL;
-  img->csp = NULL;
-  img->enc = NULL;
-  img->app_enc = NULL;
-  img->formatter = NULL;
-  img->app_formatter = NULL;
-  img->sink = NULL;
-
-  /* Create src and sink ghost pads */
-  img->sinkpad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
-  gst_element_add_pad (GST_ELEMENT (img), img->sinkpad);
-
-  img->flags = DEFAULT_FLAGS;
-}
-
-static void
-gst_camerabin_image_dispose (GstCameraBinImage * img)
-{
-  GST_DEBUG_OBJECT (img, "disposing");
-
-  g_string_free (img->filename, TRUE);
-  img->filename = NULL;
-
-  if (img->elements) {
-    g_list_free (img->elements);
-    img->elements = NULL;
-  }
-
-  if (img->sink) {
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->sink), GST_OBJECT_REFCOUNT_VALUE (img->sink));
-    gst_object_unref (img->sink);
-    img->sink = NULL;
-  }
-
-  if (img->formatter) {
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->formatter),
-        GST_OBJECT_REFCOUNT_VALUE (img->formatter));
-    gst_object_unref (img->formatter);
-    img->formatter = NULL;
-  }
-
-  if (img->app_formatter) {
-    gst_object_sink (img->app_formatter);
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->app_formatter),
-        GST_OBJECT_REFCOUNT_VALUE (img->app_formatter));
-    gst_object_unref (img->app_formatter);
-    img->app_formatter = NULL;
-  }
-
-  if (img->enc) {
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->enc), GST_OBJECT_REFCOUNT_VALUE (img->enc));
-    gst_object_unref (img->enc);
-    img->enc = NULL;
-  }
-
-  if (img->csp) {
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->csp), GST_OBJECT_REFCOUNT_VALUE (img->csp));
-    gst_object_unref (img->csp);
-    img->csp = NULL;
-  }
-
-  /* Note: if imagebin was never set to READY state the
-     ownership of elements created by application were never
-     taken by bin and therefore gst_object_sink is called for
-     these elements (they may still be in floating state
-     and not unreffed properly without sinking first)
-     FIXME, something else is wrong if you have to sink here
-   */
-  if (img->app_enc) {
-    //gst_object_ref_sink (img->app_enc);
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->app_enc),
-        GST_OBJECT_REFCOUNT_VALUE (img->app_enc));
-    gst_object_unref (img->app_enc);
-    img->app_enc = NULL;
-  }
-
-  if (img->post) {
-    //gst_object_ref_sink (img->post);
-    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
-        GST_ELEMENT_NAME (img->post), GST_OBJECT_REFCOUNT_VALUE (img->post));
-    gst_object_unref (img->post);
-    img->post = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose ((GObject *) img);
-}
-
-static GstStateChangeReturn
-gst_camerabin_image_change_state (GstElement * element,
-    GstStateChange transition)
-{
-  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-  GstCameraBinImage *img = GST_CAMERABIN_IMAGE (element);
-
-  GST_DEBUG_OBJECT (element, "changing state: %s -> %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
-
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!gst_camerabin_image_create_elements (img)) {
-        return GST_STATE_CHANGE_FAILURE;
-      }
-      /* Allow setting filename when image bin in READY state */
-      gst_element_set_locked_state (img->sink, TRUE);
-      GST_INFO_OBJECT (img, "locking imagebin->sink state to %s",
-          gst_element_state_get_name (GST_STATE (img->sink)));
-      break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      if (!g_str_equal (img->filename->str, "")) {
-        GST_INFO_OBJECT (img, "preparing image with filename: %s",
-            img->filename->str);
-        gst_element_set_locked_state (img->sink, FALSE);
-      } else {
-        GST_INFO_OBJECT (img, "keep sink locked, we have no filename yet");
-      }
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* Set sink to NULL in order to write the file _now_ */
-      GST_INFO_OBJECT (img, "write image with filename: %s",
-          img->filename->str);
-      gst_element_set_locked_state (img->sink, TRUE);
-      gst_element_set_state (img->sink, GST_STATE_NULL);
-      g_string_assign (img->filename, "");
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (GST_ELEMENT_PARENT (img)),
-          GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE |
-          GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS, "imagebin.playing");
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      gst_camerabin_image_destroy_elements (img);
-      break;
-    default:
-      break;
-  }
-
-  GST_DEBUG_OBJECT (element, "changed state: %s -> %s = %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)),
-      gst_element_state_change_return_get_name (ret));
-
-  return ret;
-}
-
-gboolean
-gst_camerabin_image_send_event (GstElement * element, GstEvent * event)
-{
-  GstCameraBinImage *bin = GST_CAMERABIN_IMAGE (element);
-  gboolean ret = FALSE;
-
-  GST_INFO ("got %s event", GST_EVENT_TYPE_NAME (event));
-
-  if (GST_EVENT_IS_DOWNSTREAM (event)) {
-    ret = gst_pad_send_event (bin->sinkpad, event);
-  } else {
-    if (bin->sink) {
-      ret = gst_element_send_event (bin->sink, event);
-    } else {
-      GST_WARNING ("upstream event handling failed");
-    }
-  }
-
-  return ret;
-}
-
-static void
-gst_camerabin_image_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstCameraBinImage *bin = GST_CAMERABIN_IMAGE (object);
-
-  switch (prop_id) {
-    case PROP_FILENAME:
-      g_string_assign (bin->filename, g_value_get_string (value));
-      GST_INFO_OBJECT (bin, "received filename: '%s'", bin->filename->str);
-      if (bin->sink) {
-        if (!g_str_equal (bin->filename->str, "")) {
-          g_object_set (G_OBJECT (bin->sink), "location", bin->filename->str,
-              NULL);
-          gst_element_set_locked_state (bin->sink, FALSE);
-          gst_element_sync_state_with_parent (bin->sink);
-        } else {
-          GST_INFO_OBJECT (bin, "empty filename");
-        }
-      } else {
-        GST_INFO_OBJECT (bin, "no sink, not setting name yet");
-      }
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_camerabin_image_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstCameraBinImage *bin = GST_CAMERABIN_IMAGE (object);
-
-  switch (prop_id) {
-    case PROP_FILENAME:
-      g_value_set_string (value, bin->filename->str);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/*
- * gst_camerabin_image_prepare_elements:
- * @imagebin: a pointer to #GstCameraBinImage object
- *
- * This function creates an ordered list of elements configured for imagebin
- * pipeline and creates the elements if necessary. It also stores pointers
- * to created elements for re-using them.
- *
- * Image bin:
- *  img->sinkpad ! [ post process !] [ csp !] encoder ! metadata ! filesink
- *
- * Returns: %FALSE if there was error creating element, %TRUE otherwise
- */
-gboolean
-gst_camerabin_image_prepare_elements (GstCameraBinImage * imagebin)
-{
-  gboolean ret = FALSE;
-  GstPad *sinkpad = NULL;
-
-  g_return_val_if_fail (imagebin != NULL, FALSE);
-
-  GST_DEBUG_OBJECT (imagebin, "preparing image capture elements");
-
-  if (imagebin->elements != NULL) {
-    g_list_free (imagebin->elements);
-    imagebin->elements = NULL;
-  }
-
-  /* Create file sink element */
-  if (!prepare_element (&imagebin->elements, DEFAULT_SINK, NULL,
-          &imagebin->sink)) {
-    goto done;
-  } else {
-    g_object_set (G_OBJECT (imagebin->sink), "location",
-        imagebin->filename->str, "async", FALSE, "buffer-mode", 2,
-        /* non buffered io */ NULL);
-  }
-
-  /* Create metadata muxer element */
-  if (!prepare_element (&imagebin->elements, DEFAULT_FORMATTER,
-          imagebin->app_formatter, &imagebin->formatter)) {
-    goto done;
-  } else if (!imagebin->metadata_probe_id) {
-    /* Add probe for default XMP metadata writing */
-    sinkpad = gst_element_get_static_pad (imagebin->formatter, "sink");
-    imagebin->metadata_probe_id =
-        gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (metadata_write_probe),
-        imagebin);
-    gst_object_unref (sinkpad);
-  }
-
-  /* Create image encoder element */
-  if (!prepare_element (&imagebin->elements, DEFAULT_ENC, imagebin->app_enc,
-          &imagebin->enc)) {
-    goto done;
-  }
-
-  /* Create optional colorspace conversion element */
-  if (imagebin->flags & GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION) {
-    if (!prepare_element (&imagebin->elements, "ffmpegcolorspace", NULL,
-            &imagebin->csp)) {
-      goto done;
-    }
-  }
-
-  /* Add optional image post processing element */
-  if (!prepare_element (&imagebin->elements, NULL, imagebin->post,
-          &imagebin->post)) {
-    goto done;
-  }
-
-  ret = TRUE;
-
-done:
-  GST_DEBUG_OBJECT (imagebin, "preparing finished %s", ret ? "OK" : "NOK");
-  return ret;
-}
-
-
-/*
- * static helper functions implementation
- */
-
-/*
- * metadata_write_probe:
- * @pad: sink pad of metadata muxer
- * @buffer: received buffer
- * @u_data: image bin object
- *
- * Buffer probe that sets Xmp.dc.type and Xmp.dc.format tags
- * to metadata muxer based on preceding element src pad caps.
- *
- * Returns: TRUE always
- */
-static gboolean
-metadata_write_probe (GstPad * pad, GstBuffer * buffer, gpointer u_data)
-{
-  /* Add XMP tags */
-  GstCameraBinImage *img = NULL;
-  GstTagSetter *setter = NULL;
-  GstPad *srcpad = NULL;
-  GstCaps *caps = NULL;
-  GstStructure *st = NULL;
-
-  img = GST_CAMERABIN_IMAGE (u_data);
-
-  g_return_val_if_fail (img != NULL, TRUE);
-
-  if (GST_IS_TAG_SETTER (img->formatter)) {
-    setter = GST_TAG_SETTER (img->formatter);
-  }
-
-  if (!setter) {
-    GST_WARNING_OBJECT (img, "setting tags failed");
-    goto done;
-  }
-
-  /* Xmp.dc.type tag */
-  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
-      GST_TAG_CODEC, "Image", NULL);
-  /* Xmp.dc.format tag */
-  if (img->enc) {
-    srcpad = gst_element_get_static_pad (img->enc, "src");
-  }
-  GST_LOG_OBJECT (img, "srcpad:%" GST_PTR_FORMAT, srcpad);
-  if (srcpad) {
-    caps = gst_pad_get_negotiated_caps (srcpad);
-    GST_LOG_OBJECT (img, "caps:%" GST_PTR_FORMAT, caps);
-    if (caps) {
-      /* If there are many structures, we can't know which one to use */
-      if (gst_caps_get_size (caps) != 1) {
-        GST_WARNING_OBJECT (img, "can't decide structure for format tag");
-        goto done;
-      }
-      st = gst_caps_get_structure (caps, 0);
-      if (st) {
-        GST_DEBUG_OBJECT (img, "Xmp.dc.format:%s", gst_structure_get_name (st));
-        gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
-            GST_TAG_VIDEO_CODEC, gst_structure_get_name (st), NULL);
-      }
-    }
-  }
-done:
-  if (caps)
-    gst_caps_unref (caps);
-  if (srcpad)
-    gst_object_unref (srcpad);
-
-  return TRUE;
-}
-
-/*
- * prepare_element:
- * @result: result list address
- * @default_element_name: name of default element to be created
- * @app_elem: pointer to application set element
- * @res_elem: pointer to current element to be replaced if needed
- *
- * This function chooses given image capture element or creates a new one and
- * and prepends it to @result list.
- *
- * Returns: %FALSE if there was error creating new element, %TRUE otherwise
- */
-static gboolean
-prepare_element (GList ** result, const gchar * default_element_name,
-    GstElement * app_elem, GstElement ** res_elem)
-{
-  GstElement *elem = NULL;
-  gboolean ret = TRUE;
-
-  if (app_elem) {
-    /* Prefer application set element */
-    elem = app_elem;
-  } else if (*res_elem) {
-    /* Use existing element if any */
-    elem = *res_elem;
-  } else if (default_element_name) {
-    /* Create new element */
-    if (!(elem = gst_element_factory_make (default_element_name, NULL))) {
-      GST_WARNING ("creating %s failed", default_element_name);
-      ret = FALSE;
-    }
-  }
-
-  if (*res_elem != elem) {
-    /* Keep reference and store pointer to chosen element, which can be re-used
-       until imagebin is disposed or new image capture element is chosen. */
-    gst_object_replace ((GstObject **) res_elem, (GstObject *) elem);
-  }
-  if (elem) {
-    *result = g_list_prepend (*result, elem);
-  }
-
-  return ret;
-}
-
-/*
- * gst_camerabin_image_link_first_element:
- * @img: a pointer to #GstCameraBinImage object
- * @elem: first element to be linked on imagebin
- *
- * Adds given element to imagebin and links it to imagebin's ghost sink pad.
- *
- * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise
- */
-static gboolean
-gst_camerabin_image_link_first_element (GstCameraBinImage * imagebin,
-    GstElement * elem)
-{
-  GstPad *first_sinkpad = NULL;
-  gboolean ret = FALSE;
-
-  g_return_val_if_fail (imagebin != NULL, FALSE);
-  /* Link given element to imagebin ghost sink pad */
-  if (gst_bin_add (GST_BIN (imagebin), elem)) {
-    first_sinkpad = gst_element_get_static_pad (elem, "sink");
-    if (first_sinkpad) {
-      if (gst_ghost_pad_set_target (GST_GHOST_PAD (imagebin->sinkpad),
-              first_sinkpad)) {
-        ret = TRUE;
-      } else {
-        GST_WARNING ("linking first element failed");
-      }
-      gst_object_unref (first_sinkpad);
-    } else {
-      GST_WARNING ("no sink pad in first element");
-    }
-  } else {
-    GST_WARNING ("adding element failed");
-  }
-  return ret;
-}
-
-/*
- * gst_camerabin_image_link_elements:
- * @imagebin: a pointer to #GstCameraBinImage object
- *
- * Link elements configured to imagebin elements list.
- *
- * Returns %TRUE if linking succeeded, %FALSE otherwise.
- */
-static gboolean
-gst_camerabin_image_link_elements (GstCameraBinImage * imagebin)
-{
-  GList *prev = NULL;
-  GList *next = NULL;
-  gboolean ret = FALSE;
-
-  GST_DEBUG_OBJECT (imagebin, "linking image elements");
-
-  if (!imagebin->elements) {
-    GST_WARNING ("no elements to link");
-    goto done;
-  }
-
-  /* Link the elements in list */
-  prev = imagebin->elements;
-  next = g_list_next (imagebin->elements);
-  for (; next != NULL; next = g_list_next (next)) {
-    /* Link first element in list to imagebin ghost sink pad */
-    if (prev == imagebin->elements
-        && !gst_camerabin_image_link_first_element (imagebin,
-            GST_ELEMENT (prev->data))) {
-      goto done;
-    }
-    if (!gst_bin_add (GST_BIN (imagebin), GST_ELEMENT (next->data))) {
-      GST_WARNING_OBJECT (imagebin, "adding element failed");
-      goto done;
-    }
-    GST_LOG_OBJECT (imagebin, "linking %s - %s",
-        GST_ELEMENT_NAME (GST_ELEMENT (prev->data)),
-        GST_ELEMENT_NAME (GST_ELEMENT (next->data)));
-    if (!gst_element_link (GST_ELEMENT (prev->data), GST_ELEMENT (next->data))) {
-      GST_WARNING_OBJECT (imagebin, "linking element failed");
-      goto done;
-    }
-
-    prev = next;
-  }
-
-  ret = TRUE;
-
-done:
-
-  if (!ret) {
-    gst_camerabin_remove_elements_from_bin (GST_BIN (imagebin));
-  }
-
-  GST_DEBUG_OBJECT (imagebin, "linking finished %s", ret ? "OK" : "NOK");
-
-  return ret;
-}
-
-/*
- * gst_camerabin_image_create_elements:
- * @img: a pointer to #GstCameraBinImage object
- *
- * This function creates needed elements, adds them to
- * imagebin and links them.
- *
- * Returns %TRUE if success, %FALSE otherwise.
- */
-static gboolean
-gst_camerabin_image_create_elements (GstCameraBinImage * img)
-{
-  gboolean ret = FALSE;
-  g_return_val_if_fail (img != NULL, FALSE);
-
-  if (gst_camerabin_image_prepare_elements (img)) {
-    ret = gst_camerabin_image_link_elements (img);
-  }
-
-  return ret;
-}
-
-/*
- * gst_camerabin_image_destroy_elements:
- * @img: a pointer to #GstCameraBinImage object
- *
- * This function releases resources allocated in
- * gst_camerabin_image_create_elements.
- *
- */
-static void
-gst_camerabin_image_destroy_elements (GstCameraBinImage * img)
-{
-  GST_LOG ("destroying image elements");
-
-  gst_ghost_pad_set_target (GST_GHOST_PAD (img->sinkpad), NULL);
-
-  gst_camerabin_remove_elements_from_bin (GST_BIN (img));
-}
-
-void
-gst_camerabin_image_set_encoder (GstCameraBinImage * img, GstElement * encoder)
-{
-  GST_DEBUG ("setting image encoder %" GST_PTR_FORMAT, encoder);
-  if (img->app_enc)
-    gst_object_unref (img->app_enc);
-  if (encoder)
-    gst_object_ref (encoder);
-
-  img->app_enc = encoder;
-}
-
-void
-gst_camerabin_image_set_postproc (GstCameraBinImage * img,
-    GstElement * postproc)
-{
-  GST_DEBUG ("setting image postprocessing element %" GST_PTR_FORMAT, postproc);
-  if (img->post)
-    gst_object_unref (img->post);
-  if (postproc)
-    gst_object_ref (postproc);
-
-  img->post = postproc;
-}
-
-void
-gst_camerabin_image_set_formatter (GstCameraBinImage * img,
-    GstElement * formatter)
-{
-  GstElement **app_formatter;
-  GST_DEBUG ("setting image formatter %" GST_PTR_FORMAT, formatter);
-
-  app_formatter = &img->app_formatter;
-  GST_OBJECT_LOCK (img);
-  gst_object_replace ((GstObject **) app_formatter, GST_OBJECT (formatter));
-  GST_OBJECT_UNLOCK (img);
-}
-
-void
-gst_camerabin_image_set_flags (GstCameraBinImage * img, GstCameraBinFlags flags)
-{
-  GST_DEBUG_OBJECT (img, "setting image flags: %d", flags);
-  img->flags = flags;
-}
-
-GstElement *
-gst_camerabin_image_get_encoder (GstCameraBinImage * img)
-{
-  GstElement *enc;
-
-  if (img->app_enc) {
-    enc = img->app_enc;
-  } else {
-    enc = img->enc;
-  }
-
-  return enc;
-}
-
-GstElement *
-gst_camerabin_image_get_formatter (GstCameraBinImage * img)
-{
-  /* Prefer formatter that is currently in use */
-  return img->formatter ? img->formatter : img->app_formatter;
-}
-
-GstElement *
-gst_camerabin_image_get_postproc (GstCameraBinImage * img)
-{
-  return img->post;
-}
diff --git a/gst/camerabin/camerabinimage.h b/gst/camerabin/camerabinimage.h
deleted file mode 100644 (file)
index 754c4bb..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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_IMAGE_H__
-#define __CAMERABIN_IMAGE_H__
-
-#include <gst/gstbin.h>
-
-#include "gstcamerabin-enum.h"
-
-G_BEGIN_DECLS
-#define GST_TYPE_CAMERABIN_IMAGE             (gst_camerabin_image_get_type())
-#define GST_CAMERABIN_IMAGE_CAST(obj)        ((GstCameraBinImage*)(obj))
-#define GST_CAMERABIN_IMAGE(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERABIN_IMAGE,GstCameraBinImage))
-#define GST_CAMERABIN_IMAGE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERABIN_IMAGE,GstCameraBinImageClass))
-#define GST_IS_CAMERABIN_IMAGE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERABIN_IMAGE))
-#define GST_IS_CAMERABIN_IMAGE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERABIN_IMAGE))
-/**
- * GstCameraBinImage:
- *
- * The opaque #GstCameraBinImage structure.
- */
-typedef struct _GstCameraBinImage GstCameraBinImage;
-typedef struct _GstCameraBinImageClass GstCameraBinImageClass;
-
-struct _GstCameraBinImage
-{
-  GstBin parent;
-  GString *filename;
-
-  /* Ghost pads of image bin */
-  GstPad *sinkpad;
-
-  /* Ordered list of elements configured to imagebin */
-  GList *elements;
-  /* Imagebin elements */
-  GstElement *post;
-  GstElement *csp;
-  GstElement *enc;
-  GstElement *app_enc;
-  GstElement *formatter;
-  GstElement *app_formatter;
-  GstElement *sink;
-
-  GstCameraBinFlags flags;
-  gulong metadata_probe_id;
-};
-
-struct _GstCameraBinImageClass
-{
-  GstBinClass parent_class;
-};
-
-GType gst_camerabin_image_get_type (void);
-
-void
-gst_camerabin_image_set_encoder (GstCameraBinImage * img, GstElement * encoder);
-
-void
-gst_camerabin_image_set_postproc (GstCameraBinImage * img,
-    GstElement * postproc);
-
-void
-gst_camerabin_image_set_formatter (GstCameraBinImage * img, GstElement * formatter);
-
-void
-gst_camerabin_image_set_flags (GstCameraBinImage * img,
-    GstCameraBinFlags flags);
-
-GstElement *gst_camerabin_image_get_encoder (GstCameraBinImage * img);
-
-GstElement *gst_camerabin_image_get_postproc (GstCameraBinImage * img);
-
-GstElement *gst_camerabin_image_get_formatter (GstCameraBinImage * img);
-
-gboolean gst_camerabin_image_prepare_elements (GstCameraBinImage * imagebin);
-
-G_END_DECLS
-#endif /* #ifndef __CAMERABIN_IMAGE_H__ */
diff --git a/gst/camerabin/camerabinpreview.c b/gst/camerabin/camerabinpreview.c
deleted file mode 100644 (file)
index e7e5fe4..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-* 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.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <string.h>
-
-#include "camerabindebug.h"
-#include "camerabingeneral.h"
-#include "camerabinpreview.h"
-
-static void
-save_result (GstElement * sink, GstBuffer * buf, GstPad * pad, gpointer data)
-{
-  GstBuffer **p_buf = (GstBuffer **) data;
-
-  *p_buf = gst_buffer_ref (buf);
-
-  GST_DEBUG ("received converted buffer %p with caps %" GST_PTR_FORMAT,
-      *p_buf, GST_BUFFER_CAPS (*p_buf));
-}
-
-static gboolean
-create_element (const gchar * factory_name, const gchar * elem_name,
-    GstElement ** element, GError ** err)
-{
-  *element = gst_element_factory_make (factory_name, elem_name);
-  if (*element)
-    return TRUE;
-
-  if (err && *err == NULL) {
-    *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
-        "cannot create element '%s' - please check your GStreamer installation",
-        factory_name);
-  }
-
-  return FALSE;
-}
-
-
-/**
- * gst_camerabin_preview_create_pipeline:
- * @element: #GstCameraBin element
- * @caps: pointer to the caps used in pipeline
- * @src_filter: source filter element
- *
- * Create a preview converter pipeline that outputs the format defined in
- * @caps parameter.
- *
- * Returns: New pipeline data structure, or NULL if error occured.
- */
-GstCameraBinPreviewPipelineData *
-gst_camerabin_preview_create_pipeline (GstElement * element, GstCaps * caps,
-    GstElement * src_filter)
-{
-  GstElement *csp = NULL, *vscale = NULL;
-  GError *error = NULL;
-  GstCameraBinPreviewPipelineData *data;
-
-  g_return_val_if_fail (caps != NULL, NULL);
-
-  GST_DEBUG ("creating elements");
-
-  data = g_new (GstCameraBinPreviewPipelineData, 1);
-
-  /* We have multiple pipelines created by using this function, so we can't
-   * give a name to them. Another way would to ensure the uniqueness of the
-   * name here*/
-  data->pipeline = gst_pipeline_new (NULL);
-  if (!data->pipeline)
-    goto create_error;
-
-  if (!create_element ("appsrc", "prev_src", &data->appsrc, &error) ||
-      !create_element ("videoscale", NULL, &vscale, &error) ||
-      !create_element ("ffmpegcolorspace", NULL, &csp, &error) ||
-      !create_element ("capsfilter", NULL, &data->capsfilter, &error) ||
-      !create_element ("fakesink", "prev_sink", &data->appsink, &error))
-    goto create_error;
-
-  GST_DEBUG ("adding elements");
-  gst_bin_add_many (GST_BIN (data->pipeline), data->appsrc, csp,
-      data->capsfilter, vscale, data->appsink, NULL);
-  if (src_filter) {
-    gst_bin_add (GST_BIN (data->pipeline), src_filter);
-  }
-
-  data->element = element;
-
-  GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, caps);
-
-  g_object_set (data->capsfilter, "caps", caps, NULL);
-  g_object_set (data->appsink, "preroll-queue-len", 1, "signal-handoffs", TRUE,
-      NULL);
-  g_object_set (vscale, "method", 0, NULL);
-
-  GST_DEBUG ("linking src->vscale");
-  if (!gst_element_link_pads (data->appsrc, "src", vscale, "sink"))
-    goto link_error;
-
-  if (src_filter) {
-    GST_DEBUG ("linking vscale->src_filter");
-    if (!gst_element_link_pads (vscale, "src", src_filter, "sink")) {
-      goto link_error;
-    }
-    GST_DEBUG ("linking filter->csp");
-    if (!gst_element_link_pads (src_filter, "src", csp, "sink")) {
-      goto link_error;
-    }
-  } else {
-    GST_DEBUG ("linking vscale->csp");
-    if (!gst_element_link_pads (vscale, "src", csp, "sink"))
-      goto link_error;
-  }
-
-  GST_DEBUG ("linking csp->capsfilter");
-  if (!gst_element_link_pads (csp, "src", data->capsfilter, "sink"))
-    goto link_error;
-
-  GST_DEBUG ("linking capsfilter->sink");
-  if (!gst_element_link_pads (data->capsfilter, "src", data->appsink, "sink"))
-    goto link_error;
-
-  return data;
-
-create_error:
-  if (error) {
-    GST_WARNING ("Preview pipeline element creation failed: %s",
-        error->message);
-    g_error_free (error);
-  }
-  if (csp)
-    gst_object_unref (csp);
-  if (vscale)
-    gst_object_unref (vscale);
-  if (data->appsrc)
-    gst_object_unref (data->appsrc);
-  if (data->capsfilter)
-    gst_object_unref (data->capsfilter);
-  if (data->appsink)
-    gst_object_unref (data->appsink);
-
-link_error:
-  GST_WARNING ("Could not create preview pipeline");
-  gst_camerabin_preview_destroy_pipeline (data);
-
-  return NULL;
-}
-
-
-/**
- * gst_camerabin_preview_destroy_pipeline:
- * @data: the pipeline data to be destroyed
- *
- * Destroy preview converter pipeline.
- */
-void
-gst_camerabin_preview_destroy_pipeline (GstCameraBinPreviewPipelineData * data)
-{
-  if (data->pipeline) {
-    gst_element_set_state (data->pipeline, GST_STATE_NULL);
-    gst_object_unref (data->pipeline);
-  }
-  g_free (data);
-}
-
-
-/**
- * gst_camerabin_preview_convert:
- * @data: preview pipeline data to use
- * @buf: #GstBuffer that contains the frame to be converted
- *
- * Create a preview image of the given frame.
- *
- * Returns: converted preview image, or NULL if operation failed.
- */
-GstBuffer *
-gst_camerabin_preview_convert (GstCameraBinPreviewPipelineData * data,
-    GstBuffer * buf)
-{
-  GstMessage *msg;
-  GstBuffer *result = NULL;
-  GError *error = NULL;
-  GstBus *bus;
-  GstElement *src, *sink;
-  GstBufferFlag bflags;
-  GstFlowReturn fret;
-
-  g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
-  g_return_val_if_fail (data != NULL, NULL);
-
-  if (data->pipeline == NULL) {
-    GST_WARNING ("pipeline is NULL");
-    goto no_pipeline;
-  }
-
-  src = gst_bin_get_by_name (GST_BIN (data->pipeline), "prev_src");
-  sink = gst_bin_get_by_name (GST_BIN (data->pipeline), "prev_sink");
-
-  if (!src || !sink) {
-    GST_WARNING ("pipeline doesn't have src / sink elements");
-    goto missing_elements;
-  }
-
-  g_object_set (src, "size", (gint64) GST_BUFFER_SIZE (buf),
-      "blocksize", (guint32) GST_BUFFER_SIZE (buf),
-      "caps", GST_BUFFER_CAPS (buf), "num-buffers", 1, NULL);
-
-  g_signal_connect (sink, "handoff", G_CALLBACK (save_result), &result);
-
-  bflags = GST_BUFFER_FLAGS (buf);
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
-
-  GST_DEBUG ("running conversion pipeline, source is: %" GST_PTR_FORMAT,
-      GST_BUFFER_CAPS (buf));
-  gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
-
-  g_signal_emit_by_name (src, "push-buffer", buf, &fret);
-
-  bus = gst_element_get_bus (data->pipeline);
-  msg = gst_bus_timed_pop_filtered (bus, (25 * GST_SECOND),
-      GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
-  gst_object_unref (bus);
-
-  if (msg) {
-    switch (GST_MESSAGE_TYPE (msg)) {
-      case GST_MESSAGE_EOS:{
-        if (result) {
-          GST_DEBUG ("preview image successful: result = %p", result);
-        } else {
-          GST_WARNING ("EOS but no result frame?!");
-        }
-        break;
-      }
-      case GST_MESSAGE_ERROR:{
-        gchar *dbg = NULL;
-
-        gst_message_parse_error (msg, &error, &dbg);
-        if (error) {
-          g_warning ("Could not make preview image: %s", error->message);
-          GST_DEBUG ("%s [debug: %s]", error->message, GST_STR_NULL (dbg));
-          g_error_free (error);
-        } else {
-          g_warning ("Could not make preview image (and NULL error!)");
-        }
-        g_free (dbg);
-        result = NULL;
-        break;
-      }
-      default:{
-        g_return_val_if_reached (NULL);
-      }
-    }
-    gst_message_unref (msg);
-  } else {
-    g_warning ("Could not make preview image: %s", "timeout during conversion");
-    result = NULL;
-  }
-
-  g_signal_handlers_disconnect_by_func (sink, G_CALLBACK (save_result),
-      &result);
-  gst_element_set_state (data->pipeline, GST_STATE_READY);
-
-  GST_BUFFER_FLAGS (buf) = bflags;
-
-done:
-  if (src)
-    gst_object_unref (src);
-  if (sink)
-    gst_object_unref (sink);
-
-  return result;
-
-  /* ERRORS */
-missing_elements:
-  {
-    g_warning ("Could not make preview image: %s",
-        "missing elements in pipeline (unknown error)");
-    goto done;
-  }
-no_pipeline:
-  {
-    g_warning ("Could not make preview image: %s",
-        "no pipeline (unknown error)");
-    return NULL;
-  }
-}
-
-/**
- * gst_camerabin_preview_send_event:
- * @data: preview pipeline data to use
- * @evt: The #GstEvent to be pushed, takes ownership
- *
- * Pushes an event to the preview pipeline.
- *
- * Returns: True if the event was handled
- */
-gboolean
-gst_camerabin_preview_send_event (GstCameraBinPreviewPipelineData * data,
-    GstEvent * evt)
-{
-  GstElement *src;
-
-  src = gst_bin_get_by_name (GST_BIN (data->pipeline), "prev_src");
-  if (!src) {
-    GST_WARNING ("Preview pipeline doesn't have src element, can't push event");
-    gst_event_unref (evt);
-    return FALSE;
-  }
-
-  GST_DEBUG_OBJECT (data->element, "Pushing event %p to preview pipeline", evt);
-
-  return gst_element_send_event (src, evt);
-}
-
-/**
- * gst_camerabin_preview_set_caps:
- * @data: preview pipeline data to use
- * @caps: New #GstCaps to be set for the pipeline
- *
- * Sets new caps for the preview pipeline
- */
-void
-gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * data,
-    GstCaps * caps)
-{
-  GstState state, pending;
-  GstStateChangeReturn ret;
-
-  g_return_if_fail (data->pipeline != NULL);
-  g_return_if_fail (caps != NULL);
-
-  ret = gst_element_get_state (data->pipeline, &state, &pending, 0);
-  if (ret == GST_STATE_CHANGE_FAILURE) {
-    /* make it try again */
-    state = GST_STATE_PLAYING;
-    pending = GST_STATE_VOID_PENDING;
-  }
-
-  gst_element_set_state (data->pipeline, GST_STATE_NULL);
-  g_object_set (data->capsfilter, "caps", caps, NULL);
-  if (pending != GST_STATE_VOID_PENDING)
-    state = pending;
-  gst_element_set_state (data->pipeline, state);
-}
diff --git a/gst/camerabin/camerabinpreview.h b/gst/camerabin/camerabinpreview.h
deleted file mode 100644 (file)
index 3da9a05..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* 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 __CAMERABINPREVIEW_H__
-#define __CAMERABINPREVIEW_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-typedef struct
-{
-  GstElement *pipeline;
-
-  GstElement *appsrc;
-  GstElement *capsfilter;
-  GstElement *appsink;
-
-  GstElement *element;
-} GstCameraBinPreviewPipelineData;
-
-
-GstCameraBinPreviewPipelineData * gst_camerabin_preview_create_pipeline (
-    GstElement *element, GstCaps *caps, GstElement *src_filter);
-
-void gst_camerabin_preview_destroy_pipeline (
-    GstCameraBinPreviewPipelineData *data);
-
-GstBuffer *gst_camerabin_preview_convert (
-    GstCameraBinPreviewPipelineData *data, GstBuffer *buf);
-
-gboolean gst_camerabin_preview_send_event (
-    GstCameraBinPreviewPipelineData *pipeline, GstEvent *event);
-
-void gst_camerabin_preview_set_caps (
-    GstCameraBinPreviewPipelineData *pipeline, GstCaps *caps);
-
-G_END_DECLS
-
-#endif                          /* __CAMERABINPREVIEW_H__ */
diff --git a/gst/camerabin/camerabinvideo.c b/gst/camerabin/camerabinvideo.c
deleted file mode 100644 (file)
index 0a81e0c..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * 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:camerabinvideo
- * @short_description: video recording module of #GstCameraBin
- *
- * <refsect2>
- * <para>
- *
- * The pipeline for this module is:
- *
- * <informalexample>
- * <programlisting>
- *-----------------------------------------------------------------------------
- * audiosrc -> audio_queue -> audioconvert -> volume -> audioenc
- *                                                       > videomux -> filesink
- *                       video_queue -> [timeoverlay] -> [csp] -> videoenc -> queue
- * -> [post proc] -> tee <
- *                       queue ->
- *-----------------------------------------------------------------------------
- * </programlisting>
- * </informalexample>
- *
- * The properties of elements are:
- *
- * queue - "leaky", 2 (Leaky on downstream (old buffers))
- *
- * </para>
- * </refsect2>
- */
-
-/*
- * includes
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include "camerabindebug.h"
-#include "camerabingeneral.h"
-
-#include "camerabinvideo.h"
-
-/*
- * defines and static global vars
- */
-
-/* internal element names */
-
-#define DEFAULT_AUD_ENC "vorbisenc"
-#define DEFAULT_VID_ENC "theoraenc"
-#define DEFAULT_MUX "oggmux"
-#define DEFAULT_SINK "filesink"
-
-#define DEFAULT_FLAGS 0
-
-enum
-{
-  PROP_0,
-  PROP_FILENAME
-};
-
-static void gst_camerabin_video_dispose (GstCameraBinVideo * sink);
-static void gst_camerabin_video_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_camerabin_video_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static GstStateChangeReturn
-gst_camerabin_video_change_state (GstElement * element,
-    GstStateChange transition);
-
-static
-    gboolean camerabin_video_pad_tee_src0_have_buffer (GstPad * pad,
-    GstBuffer * buffer, gpointer u_data);
-static gboolean camerabin_video_sink_have_event (GstPad * pad, GstEvent * event,
-    gpointer u_data);
-static gboolean gst_camerabin_video_create_elements (GstCameraBinVideo * vid);
-static void gst_camerabin_video_destroy_elements (GstCameraBinVideo * vid);
-
-GST_BOILERPLATE (GstCameraBinVideo, gst_camerabin_video, GstBin, GST_TYPE_BIN);
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
-
-
-/* GObject methods implementation */
-
-static void
-gst_camerabin_video_base_init (gpointer klass)
-{
-  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (eklass,
-      gst_static_pad_template_get (&sink_template));
-  gst_element_class_add_pad_template (eklass,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_set_details_simple (eklass,
-      "Video capture bin for camerabin", "Bin/Video",
-      "Process and store video data",
-      "Edgard Lima <edgard.lima@indt.org.br>, "
-      "Nokia Corporation <multimedia@maemo.org>");
-}
-
-static void
-gst_camerabin_video_class_init (GstCameraBinVideoClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
-
-  gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->dispose =
-      (GObjectFinalizeFunc) GST_DEBUG_FUNCPTR (gst_camerabin_video_dispose);
-  eklass->change_state = GST_DEBUG_FUNCPTR (gst_camerabin_video_change_state);
-
-  gobject_class->set_property =
-      GST_DEBUG_FUNCPTR (gst_camerabin_video_set_property);
-  gobject_class->get_property =
-      GST_DEBUG_FUNCPTR (gst_camerabin_video_get_property);
-
-  /**
-   * GstCameraBinVideo:filename:
-   *
-   * This property can be used to specify the filename of the video.
-   *
-   **/
-  g_object_class_install_property (gobject_class, PROP_FILENAME,
-      g_param_spec_string ("filename", "Filename",
-          "Filename of the video to save", NULL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_camerabin_video_init (GstCameraBinVideo * vid,
-    GstCameraBinVideoClass * g_class)
-{
-  vid->filename = g_string_new ("");
-
-  vid->app_post = NULL;
-  vid->app_vid_enc = NULL;
-  vid->app_aud_enc = NULL;
-  vid->app_aud_src = NULL;
-  vid->app_mux = NULL;
-
-  vid->aud_src = NULL;
-  vid->sink = NULL;
-  vid->tee = NULL;
-  vid->volume = NULL;
-  vid->video_queue = NULL;
-
-  vid->tee_video_srcpad = NULL;
-  vid->tee_vf_srcpad = NULL;
-
-  vid->pending_eos = NULL;
-
-  vid->mute = ARG_DEFAULT_MUTE;
-  vid->flags = DEFAULT_FLAGS;
-
-  vid->vid_src_probe_id = 0;
-  vid->vid_tee_probe_id = 0;
-  vid->vid_sink_probe_id = 0;
-
-  /* Create src and sink ghost pads */
-  vid->sinkpad = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
-  gst_element_add_pad (GST_ELEMENT (vid), vid->sinkpad);
-
-  vid->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
-  gst_element_add_pad (GST_ELEMENT (vid), vid->srcpad);
-
-  /* Add probe for handling eos when stopping recording */
-  vid->vid_sink_probe_id = gst_pad_add_event_probe (vid->sinkpad,
-      G_CALLBACK (camerabin_video_sink_have_event), vid);
-}
-
-static void
-gst_camerabin_video_dispose (GstCameraBinVideo * vid)
-{
-  GST_DEBUG_OBJECT (vid, "disposing");
-
-  g_string_free (vid->filename, TRUE);
-  vid->filename = NULL;
-
-  if (vid->vid_sink_probe_id) {
-    gst_pad_remove_event_probe (vid->sinkpad, vid->vid_sink_probe_id);
-    vid->vid_sink_probe_id = 0;
-  }
-
-  /* Note: if videobin was never set to READY state the
-     ownership of elements created by application were never
-     taken by bin and therefore gst_object_sink is called for
-     these elements (they may still be in floating state
-     and not unreffed properly without sinking first)
-     FIXME, something else is wrong when you have to sink here
-   */
-  if (vid->app_post) {
-    //gst_object_sink (vid->app_post);
-    gst_object_unref (vid->app_post);
-    vid->app_post = NULL;
-  }
-
-  if (vid->app_vid_enc) {
-    //gst_object_sink (vid->app_vid_enc);
-    gst_object_unref (vid->app_vid_enc);
-    vid->app_vid_enc = NULL;
-  }
-
-  if (vid->app_aud_enc) {
-    //gst_object_sink (vid->app_aud_enc);
-    gst_object_unref (vid->app_aud_enc);
-    vid->app_aud_enc = NULL;
-  }
-
-  if (vid->app_aud_src) {
-    //gst_object_sink (vid->app_aud_src);
-    gst_object_unref (vid->app_aud_src);
-    vid->app_aud_src = NULL;
-  }
-
-  if (vid->app_mux) {
-    //gst_object_sink (vid->app_mux);
-    gst_object_unref (vid->app_mux);
-    vid->app_mux = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose ((GObject *) vid);
-}
-
-
-static void
-gst_camerabin_video_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstCameraBinVideo *bin = GST_CAMERABIN_VIDEO (object);
-
-  switch (prop_id) {
-    case PROP_FILENAME:
-      g_string_assign (bin->filename, g_value_get_string (value));
-      GST_INFO_OBJECT (bin, "received filename: '%s'", bin->filename->str);
-      if (bin->sink) {
-        g_object_set (G_OBJECT (bin->sink), "location", bin->filename->str,
-            NULL);
-      } else {
-        GST_INFO_OBJECT (bin, "no sink, not setting name yet");
-      }
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_camerabin_video_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstCameraBinVideo *bin = GST_CAMERABIN_VIDEO (object);
-
-  switch (prop_id) {
-    case PROP_FILENAME:
-      g_value_set_string (value, bin->filename->str);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static GstStateChangeReturn
-gst_camerabin_video_change_state (GstElement * element,
-    GstStateChange transition)
-{
-  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-  GstCameraBinVideo *vid = GST_CAMERABIN_VIDEO (element);
-
-  GST_DEBUG_OBJECT (element, "changing state: %s -> %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
-
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!gst_camerabin_video_create_elements (vid)) {
-        return GST_STATE_CHANGE_FAILURE;
-      }
-      /* Don't change sink to READY yet to allow changing the
-         filename in READY state. */
-      gst_element_set_locked_state (vid->sink, TRUE);
-      break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      vid->calculate_adjust_ts_video = TRUE;
-      g_object_set (G_OBJECT (vid->sink), "async", FALSE, NULL);
-      gst_element_set_locked_state (vid->sink, FALSE);
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      vid->calculate_adjust_ts_video = TRUE;
-      break;
-
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* Set sink to NULL in order to write the file _now_ */
-      GST_INFO ("write video file: %s", vid->filename->str);
-      gst_element_set_locked_state (vid->sink, TRUE);
-      gst_element_set_state (vid->sink, GST_STATE_NULL);
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (GST_ELEMENT_PARENT (vid)),
-          GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE |
-          GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS, "videobin.playing");
-
-      if (vid->pending_eos) {
-        /* Video bin is still paused, so push eos directly to video queue */
-        GST_DEBUG_OBJECT (vid, "pushing pending eos");
-        gst_pad_push_event (vid->tee_video_srcpad, vid->pending_eos);
-        vid->pending_eos = NULL;
-      }
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* Reset counters related to timestamp rewriting */
-      vid->adjust_ts_video = 0;
-      vid->last_ts_video = 0;
-
-      if (vid->pending_eos) {
-        gst_event_unref (vid->pending_eos);
-        vid->pending_eos = NULL;
-      }
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      gst_camerabin_video_destroy_elements (vid);
-      break;
-    default:
-      break;
-  }
-
-  GST_DEBUG_OBJECT (element, "changed state: %s -> %s = %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)),
-      gst_element_state_change_return_get_name (ret));
-
-  return ret;
-}
-
-/*
- * static helper functions implementation
- */
-
-/*
- * camerabin_video_pad_tee_src0_have_buffer:
- * @pad: tee src pad leading to video encoding
- * @event: received buffer
- * @u_data: video bin object
- *
- * Buffer probe for rewriting video buffer timestamps.
- *
- * Returns: TRUE always
- */
-static gboolean
-camerabin_video_pad_tee_src0_have_buffer (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data)
-{
-  GstCameraBinVideo *vid = (GstCameraBinVideo *) u_data;
-
-  GST_LOG ("buffer in with size %d ts %" GST_TIME_FORMAT,
-      GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
-
-  if (G_UNLIKELY (vid->calculate_adjust_ts_video)) {
-    GstEvent *event;
-    GstObject *tee;
-    GstPad *sinkpad;
-
-    vid->adjust_ts_video = GST_BUFFER_TIMESTAMP (buffer) - vid->last_ts_video;
-    vid->calculate_adjust_ts_video = FALSE;
-    event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
-        0, GST_CLOCK_TIME_NONE, vid->last_ts_video);
-    /* Send the newsegment to both view finder and video bin */
-    tee = gst_pad_get_parent (pad);
-    sinkpad = gst_element_get_static_pad (GST_ELEMENT (tee), "sink");
-    gst_pad_send_event (sinkpad, event);
-    gst_object_unref (tee);
-    gst_object_unref (sinkpad);
-    GST_LOG_OBJECT (vid, "vid ts adjustment: %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (vid->adjust_ts_video));
-    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
-  }
-  GST_BUFFER_TIMESTAMP (buffer) -= vid->adjust_ts_video;
-  vid->last_ts_video = GST_BUFFER_TIMESTAMP (buffer);
-  if (GST_BUFFER_DURATION_IS_VALID (buffer))
-    vid->last_ts_video += GST_BUFFER_DURATION (buffer);
-
-  GST_LOG ("buffer out with size %d ts %" GST_TIME_FORMAT,
-      GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
-  return TRUE;
-}
-
-/*
- * camerabin_video_sink_have_event:
- * @pad: video bin sink pad
- * @event: received event
- * @u_data: video bin object
- *
- * Event probe for video bin eos handling.
- * Copies the eos event to audio branch of video bin.
- *
- * Returns: FALSE to drop the event, TRUE otherwise
- */
-static gboolean
-camerabin_video_sink_have_event (GstPad * pad, GstEvent * event,
-    gpointer u_data)
-{
-  GstCameraBinVideo *vid = (GstCameraBinVideo *) u_data;
-  gboolean ret = TRUE;
-
-  GST_DEBUG_OBJECT (vid, "got videobin sink event: %s",
-      GST_EVENT_TYPE_NAME (event));
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_EOS:
-      if (vid->aud_src) {
-        GST_DEBUG_OBJECT (vid, "copying %s to audio branch",
-            GST_EVENT_TYPE_NAME (event));
-        gst_element_send_event (vid->aud_src, gst_event_copy (event));
-      }
-
-      /* If we're paused, we can't pass eos to video now to avoid blocking.
-         Instead send eos when changing to playing next time. */
-      if (GST_STATE (GST_ELEMENT (vid)) == GST_STATE_PAUSED) {
-        GST_DEBUG_OBJECT (vid, "paused, delay eos sending");
-        vid->pending_eos = gst_event_ref (event);
-        ret = FALSE;            /* Drop the event */
-      }
-      break;
-    default:
-      break;
-  }
-  return ret;
-}
-
-/*
- * gst_camerabin_video_create_elements:
- * @vid: a pointer to #GstCameraBinVideo
- *
- * This function creates the needed #GstElements and resources to record videos.
- * Use gst_camerabin_video_destroy_elements() to free these resources.
- *
- * Returns: %TRUE if succeeded or FALSE if failed
- */
-static gboolean
-gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
-{
-  GstPad *vid_sinkpad = NULL, *vid_srcpad = NULL;
-  GstBin *vidbin = GST_BIN (vid);
-  GstElement *queue = NULL;
-
-  vid->adjust_ts_video = 0;
-  vid->last_ts_video = 0;
-  vid->calculate_adjust_ts_video = FALSE;
-
-  /* Add video post processing element if any */
-  if (vid->app_post) {
-    if (!gst_camerabin_add_element (vidbin, vid->app_post)) {
-      goto error;
-    }
-    vid_sinkpad = gst_element_get_static_pad (vid->app_post, "sink");
-  }
-
-  /* Add tee element */
-  if (!(vid->tee =
-          gst_camerabin_create_and_add_element (vidbin, "tee", "video-tee"))) {
-    goto error;
-  }
-
-  /* Set up sink ghost pad for video bin */
-  if (!vid_sinkpad) {
-    vid_sinkpad = gst_element_get_static_pad (vid->tee, "sink");
-  }
-  gst_ghost_pad_set_target (GST_GHOST_PAD (vid->sinkpad), vid_sinkpad);
-  gst_object_unref (vid_sinkpad);
-
-  /* Add queue element for video */
-  vid->tee_video_srcpad = gst_element_get_request_pad (vid->tee, "src_%u");
-
-  vid->video_queue = gst_element_factory_make ("queue", "video-queue");
-  if (!gst_camerabin_add_element (vidbin, vid->video_queue)) {
-    goto error;
-  }
-  g_object_set (vid->video_queue, "silent", TRUE, NULL);
-
-  /* Add probe for rewriting video timestamps */
-  vid->vid_tee_probe_id = gst_pad_add_buffer_probe (vid->tee_video_srcpad,
-      G_CALLBACK (camerabin_video_pad_tee_src0_have_buffer), vid);
-
-  if (vid->flags & GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION) {
-    /* Add colorspace converter */
-    if (gst_camerabin_create_and_add_element (vidbin,
-            "ffmpegcolorspace", "video-ffmpegcolorspace") == NULL) {
-      goto error;
-    }
-  }
-
-  /* Add user set or default video encoder element */
-  if (vid->app_vid_enc) {
-    vid->vid_enc = vid->app_vid_enc;
-    if (!gst_camerabin_add_element (vidbin, vid->vid_enc)) {
-      goto error;
-    }
-  } else if (!(vid->vid_enc =
-          gst_camerabin_create_and_add_element (vidbin, DEFAULT_VID_ENC,
-              "video-encoder"))) {
-    goto error;
-  }
-
-  /* Add application set or default muxer element */
-  if (vid->app_mux) {
-    vid->muxer = vid->app_mux;
-    if (!gst_camerabin_add_element (vidbin, vid->muxer)) {
-      goto error;
-    }
-  } else if (!(vid->muxer =
-          gst_camerabin_create_and_add_element (vidbin, DEFAULT_MUX,
-              "video-muxer"))) {
-    goto error;
-  }
-
-  /* Add sink element for storing the video */
-  if (!(vid->sink =
-          gst_camerabin_create_and_add_element (vidbin, DEFAULT_SINK,
-              "video-sink"))) {
-    goto error;
-  }
-  g_object_set (G_OBJECT (vid->sink), "location", vid->filename->str, "buffer-mode", 2, /* non buffered io */
-      NULL);
-
-  if (!(vid->flags & GST_CAMERABIN_FLAG_DISABLE_AUDIO)) {
-    /* Add application set or default audio source element */
-    if (!(vid->aud_src = gst_camerabin_setup_default_element (vidbin,
-                vid->app_aud_src, "autoaudiosrc", DEFAULT_AUDIOSRC))) {
-      vid->aud_src = NULL;
-      goto error;
-    } else {
-      if (!gst_camerabin_add_element (vidbin, vid->aud_src))
-        goto error;
-    }
-
-    /* Add queue element for audio */
-    queue = gst_element_factory_make ("queue", "audio-queue");
-    if (!gst_camerabin_add_element (vidbin, queue)) {
-      goto error;
-    }
-    g_object_set (queue, "silent", TRUE, NULL);
-
-    /* Add optional audio conversion and volume elements and
-       raise no errors if adding them fails */
-    if (vid->flags & GST_CAMERABIN_FLAG_AUDIO_CONVERSION) {
-      if (!gst_camerabin_try_add_element (vidbin,
-              gst_element_factory_make ("audioconvert", NULL))) {
-        GST_WARNING_OBJECT (vid, "unable to add audio conversion element");
-        /* gst_camerabin_try_add_element() destroyed the element */
-      }
-    }
-
-    vid->volume = gst_element_factory_make ("volume", NULL);
-    if (!gst_camerabin_try_add_element (vidbin, vid->volume)) {
-      GST_WARNING_OBJECT (vid, "unable to add volume element");
-      /* gst_camerabin_try_add_element() destroyed the element */
-      vid->volume = NULL;
-    } else {
-      g_object_set (vid->volume, "mute", vid->mute, NULL);
-    }
-
-    /* Add application set or default audio encoder element */
-    if (vid->app_aud_enc) {
-      vid->aud_enc = vid->app_aud_enc;
-      if (!gst_camerabin_add_element (vidbin, vid->aud_enc)) {
-        goto error;
-      }
-    } else if (!(vid->aud_enc =
-            gst_camerabin_create_and_add_element (vidbin, DEFAULT_AUD_ENC,
-                "audio-encoder"))) {
-      goto error;
-    }
-
-    /* Link audio part to the muxer */
-    if (!gst_element_link_pads_full (vid->aud_enc, NULL, vid->muxer, NULL,
-            GST_PAD_LINK_CHECK_CAPS)) {
-      GST_ELEMENT_ERROR (vid, CORE, NEGOTIATION, (NULL),
-          ("linking audio encoder and muxer failed"));
-      goto error;
-    }
-  }
-  /* Add queue leading out of the video bin and to view finder */
-  vid->tee_vf_srcpad = gst_element_get_request_pad (vid->tee, "src_%u");
-  queue = gst_element_factory_make ("queue", "viewfinder-queue");
-  if (!gst_camerabin_add_element (vidbin, queue)) {
-    goto error;
-  }
-  /* Set queue leaky, we don't want to block video encoder feed, but
-     prefer leaking view finder buffers instead. */
-  g_object_set (G_OBJECT (queue), "leaky", 2, "max-size-buffers", 1, "silent",
-      TRUE, NULL);
-
-  /* Set up src ghost pad for video bin */
-  vid_srcpad = gst_element_get_static_pad (queue, "src");
-  gst_ghost_pad_set_target (GST_GHOST_PAD (vid->srcpad), vid_srcpad);
-  /* Never let video bin eos events reach view finder */
-  vid->vid_src_probe_id = gst_pad_add_event_probe (vid_srcpad,
-      G_CALLBACK (gst_camerabin_drop_eos_probe), vid);
-  gst_object_unref (vid_srcpad);
-
-  /* audio source is not always present and might be set to NULL during operation */
-  if (vid->aud_src
-      && g_object_class_find_property (G_OBJECT_GET_CLASS (vid->aud_src),
-          "provide-clock")) {
-    g_object_set (vid->aud_src, "provide-clock", FALSE, NULL);
-  }
-
-  GST_DEBUG ("created video elements");
-
-  return TRUE;
-
-error:
-
-  gst_camerabin_video_destroy_elements (vid);
-
-  return FALSE;
-
-}
-
-/*
- * gst_camerabin_video_destroy_elements:
- * @vid: a pointer to #GstCameraBinVideo
- *
- * This function destroys all the elements created by
- * gst_camerabin_video_create_elements().
- *
- */
-static void
-gst_camerabin_video_destroy_elements (GstCameraBinVideo * vid)
-{
-  GST_DEBUG ("destroying video elements");
-
-  /* Remove EOS event probe from videobin srcpad (queue's srcpad) */
-  if (vid->vid_src_probe_id) {
-    GstPad *pad = gst_ghost_pad_get_target (GST_GHOST_PAD (vid->srcpad));
-    if (pad) {
-      gst_pad_remove_event_probe (pad, vid->vid_src_probe_id);
-      gst_object_unref (pad);
-    }
-    vid->vid_src_probe_id = 0;
-  }
-
-  /* Remove buffer probe from video tee srcpad */
-  if (vid->vid_tee_probe_id) {
-    gst_pad_remove_buffer_probe (vid->tee_video_srcpad, vid->vid_tee_probe_id);
-    vid->vid_tee_probe_id = 0;
-  }
-
-  /* Release tee request pads */
-  if (vid->tee_video_srcpad) {
-    gst_element_release_request_pad (vid->tee, vid->tee_video_srcpad);
-    gst_object_unref (vid->tee_video_srcpad);
-    vid->tee_video_srcpad = NULL;
-  }
-  if (vid->tee_vf_srcpad) {
-    gst_element_release_request_pad (vid->tee, vid->tee_vf_srcpad);
-    gst_object_unref (vid->tee_vf_srcpad);
-    vid->tee_vf_srcpad = NULL;
-  }
-
-  gst_ghost_pad_set_target (GST_GHOST_PAD (vid->sinkpad), NULL);
-  gst_ghost_pad_set_target (GST_GHOST_PAD (vid->srcpad), NULL);
-
-  gst_camerabin_remove_elements_from_bin (GST_BIN (vid));
-
-  vid->aud_src = NULL;
-  vid->sink = NULL;
-  vid->tee = NULL;
-  vid->volume = NULL;
-  vid->video_queue = NULL;
-  vid->vid_enc = NULL;
-  vid->aud_enc = NULL;
-  vid->muxer = NULL;
-
-  if (vid->pending_eos) {
-    gst_event_unref (vid->pending_eos);
-    vid->pending_eos = NULL;
-  }
-}
-
-/*
- * Set & get mute and video capture elements
- */
-
-void
-gst_camerabin_video_set_mute (GstCameraBinVideo * vid, gboolean mute)
-{
-  g_return_if_fail (vid != NULL);
-
-  GST_DEBUG_OBJECT (vid, "setting mute %s", mute ? "on" : "off");
-  vid->mute = mute;
-  if (vid->volume) {
-    g_object_set (vid->volume, "mute", mute, NULL);
-  }
-}
-
-void
-gst_camerabin_video_set_post (GstCameraBinVideo * vid, GstElement * post)
-{
-  GstElement **app_post;
-  GST_DEBUG_OBJECT (vid, "setting video post processing: %" GST_PTR_FORMAT,
-      post);
-  GST_OBJECT_LOCK (vid);
-  app_post = &vid->app_post;
-  gst_object_replace ((GstObject **) app_post, GST_OBJECT (post));
-  GST_OBJECT_UNLOCK (vid);
-}
-
-void
-gst_camerabin_video_set_video_enc (GstCameraBinVideo * vid,
-    GstElement * video_enc)
-{
-  GstElement **app_vid_enc;
-  GST_DEBUG_OBJECT (vid, "setting video encoder: %" GST_PTR_FORMAT, video_enc);
-  GST_OBJECT_LOCK (vid);
-  app_vid_enc = &vid->app_vid_enc;
-  gst_object_replace ((GstObject **) app_vid_enc, GST_OBJECT (video_enc));
-  GST_OBJECT_UNLOCK (vid);
-}
-
-void
-gst_camerabin_video_set_audio_enc (GstCameraBinVideo * vid,
-    GstElement * audio_enc)
-{
-  GstElement **app_aud_enc;
-  GST_DEBUG_OBJECT (vid, "setting audio encoder: %" GST_PTR_FORMAT, audio_enc);
-  GST_OBJECT_LOCK (vid);
-  app_aud_enc = &vid->app_aud_enc;
-  gst_object_replace ((GstObject **) app_aud_enc, GST_OBJECT (audio_enc));
-  GST_OBJECT_UNLOCK (vid);
-}
-
-void
-gst_camerabin_video_set_muxer (GstCameraBinVideo * vid, GstElement * muxer)
-{
-  GstElement **app_mux;
-  GST_DEBUG_OBJECT (vid, "setting muxer: %" GST_PTR_FORMAT, muxer);
-  GST_OBJECT_LOCK (vid);
-  app_mux = &vid->app_mux;
-  gst_object_replace ((GstObject **) app_mux, GST_OBJECT (muxer));
-  GST_OBJECT_UNLOCK (vid);
-}
-
-void
-gst_camerabin_video_set_audio_src (GstCameraBinVideo * vid,
-    GstElement * audio_src)
-{
-  GstElement **app_aud_src;
-  GST_DEBUG_OBJECT (vid, "setting audio source: %" GST_PTR_FORMAT, audio_src);
-  GST_OBJECT_LOCK (vid);
-  app_aud_src = &vid->app_aud_src;
-  gst_object_replace ((GstObject **) app_aud_src, GST_OBJECT (audio_src));
-  GST_OBJECT_UNLOCK (vid);
-}
-
-void
-gst_camerabin_video_set_flags (GstCameraBinVideo * vid, GstCameraBinFlags flags)
-{
-  GST_DEBUG_OBJECT (vid, "setting video flags: %d", flags);
-  GST_OBJECT_LOCK (vid);
-  vid->flags = flags;
-  GST_OBJECT_UNLOCK (vid);
-}
-
-
-gboolean
-gst_camerabin_video_get_mute (GstCameraBinVideo * vid)
-{
-  g_return_val_if_fail (vid != NULL, FALSE);
-
-  if (vid->volume) {
-    g_object_get (vid->volume, "mute", &vid->mute, NULL);
-  }
-
-  return vid->mute;
-}
-
-GstElement *
-gst_camerabin_video_get_post (GstCameraBinVideo * vid)
-{
-  return vid->app_post;
-}
-
-GstElement *
-gst_camerabin_video_get_video_enc (GstCameraBinVideo * vid)
-{
-  return vid->vid_enc ? vid->vid_enc : vid->app_vid_enc;
-}
-
-GstElement *
-gst_camerabin_video_get_audio_enc (GstCameraBinVideo * vid)
-{
-  return vid->aud_enc ? vid->aud_enc : vid->app_aud_enc;
-}
-
-GstElement *
-gst_camerabin_video_get_muxer (GstCameraBinVideo * vid)
-{
-  return vid->muxer ? vid->muxer : vid->app_mux;
-}
-
-GstElement *
-gst_camerabin_video_get_audio_src (GstCameraBinVideo * vid)
-{
-  return vid->aud_src ? vid->aud_src : vid->app_aud_src;
-}
diff --git a/gst/camerabin/camerabinvideo.h b/gst/camerabin/camerabinvideo.h
deleted file mode 100644 (file)
index 8f9a0f0..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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_VIDEO_H__
-#define __CAMERABIN_VIDEO_H__
-
-#include <gst/gstbin.h>
-
-#include "gstcamerabin-enum.h"
-
-G_BEGIN_DECLS
-#define ARG_DEFAULT_MUTE FALSE
-#define GST_TYPE_CAMERABIN_VIDEO             (gst_camerabin_video_get_type())
-#define GST_CAMERABIN_VIDEO_CAST(obj)        ((GstCameraBinVideo*)(obj))
-#define GST_CAMERABIN_VIDEO(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERABIN_VIDEO,GstCameraBinVideo))
-#define GST_CAMERABIN_VIDEO_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERABIN_VIDEO,GstCameraBinVideoClass))
-#define GST_IS_CAMERABIN_VIDEO(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERABIN_VIDEO))
-#define GST_IS_CAMERABIN_VIDEO_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERABIN_VIDEO))
-/**
- * GstCameraBinVideo:
- *
- * The opaque #GstCameraBinVideo structure.
- */
-typedef struct _GstCameraBinVideo GstCameraBinVideo;
-typedef struct _GstCameraBinVideoClass GstCameraBinVideoClass;
-
-struct _GstCameraBinVideo
-{
-  GstBin parent;
-
-  GString *filename;
-
-  /* A/V timestamp rewriting */
-  guint64 adjust_ts_video;
-  guint64 last_ts_video;
-  gboolean calculate_adjust_ts_video;
-
-  /* Sink and src pads of video bin */
-  GstPad *sinkpad;
-  GstPad *srcpad;
-
-  /* Tee src pads leading to video encoder and view finder */
-  GstPad *tee_video_srcpad;
-  GstPad *tee_vf_srcpad;
-
-  /* Application set elements */
-  GstElement *app_post;         /* Video post processing */
-  GstElement *app_vid_enc;
-  GstElement *app_aud_enc;
-  GstElement *app_aud_src;
-  GstElement *app_mux;
-
-  /* Other elements */
-  GstElement *aud_src;          /* Audio source */
-  GstElement *sink;             /* Sink for recorded video */
-  GstElement *tee;              /* Split output to view finder and recording sink */
-  GstElement *volume;           /* Volume for muting */
-  GstElement *video_queue;      /* Buffer for raw video frames */
-  GstElement *vid_enc;          /* Video encoder */
-  GstElement *aud_enc;          /* Audio encoder */
-  GstElement *muxer;            /* Muxer */
-
-  GstEvent *pending_eos;
-
-  /* Probe IDs */
-  gulong vid_src_probe_id;
-  gulong vid_tee_probe_id;
-  gulong vid_sink_probe_id;
-
-  gboolean mute;
-  GstCameraBinFlags flags;
-};
-
-struct _GstCameraBinVideoClass
-{
-  GstBinClass parent_class;
-};
-
-GType gst_camerabin_video_get_type (void);
-
-/*
- * external function prototypes
- */
-
-void gst_camerabin_video_set_mute (GstCameraBinVideo * vid, gboolean mute);
-
-void gst_camerabin_video_set_post (GstCameraBinVideo * vid, GstElement * post);
-
-void
-gst_camerabin_video_set_video_enc (GstCameraBinVideo * vid,
-    GstElement * video_enc);
-
-void
-gst_camerabin_video_set_audio_enc (GstCameraBinVideo * vid,
-    GstElement * audio_enc);
-
-void
-gst_camerabin_video_set_muxer (GstCameraBinVideo * vid, GstElement * muxer);
-
-void
-gst_camerabin_video_set_audio_src (GstCameraBinVideo * vid,
-    GstElement * audio_src);
-
-void
-gst_camerabin_video_set_flags (GstCameraBinVideo * vid,
-    GstCameraBinFlags flags);
-
-
-gboolean gst_camerabin_video_get_mute (GstCameraBinVideo * vid);
-
-GstElement *gst_camerabin_video_get_post (GstCameraBinVideo * vid);
-
-GstElement *gst_camerabin_video_get_video_enc (GstCameraBinVideo * vid);
-
-GstElement *gst_camerabin_video_get_audio_enc (GstCameraBinVideo * vid);
-
-GstElement *gst_camerabin_video_get_muxer (GstCameraBinVideo * vid);
-
-GstElement *gst_camerabin_video_get_audio_src (GstCameraBinVideo * vid);
-
-G_END_DECLS
-#endif /* #ifndef __CAMERABIN_VIDEO_H__ */
diff --git a/gst/camerabin/gstcamerabin-enum.c b/gst/camerabin/gstcamerabin-enum.c
deleted file mode 100644 (file)
index 7367949..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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"},
-    {C_FLAGS (GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION),
-          "Enable colorspace conversion for video capture",
-        "video-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;
-}
diff --git a/gst/camerabin/gstcamerabin-enum.h b/gst/camerabin/gstcamerabin-enum.h
deleted file mode 100644 (file)
index b848047..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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
-
-enum
-{
-  ARG_0,
-  ARG_FILENAME,
-  ARG_MODE,
-  ARG_FLAGS,
-  ARG_MUTE,
-  ARG_ZOOM,
-  ARG_IMAGE_POST,
-  ARG_IMAGE_ENC,
-  ARG_IMAGE_FORMATTER,
-  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,
-  ARG_PREVIEW_SOURCE_FILTER,
-  ARG_READY_FOR_CAPTURE,
-  ARG_IDLE
-};
-
-/**
- * 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
- * @GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION:  enable color
- *   conversion for video encoder 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),
-  GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION      = (1 << 7)
-} GstCameraBinFlags;
-
-#define GST_TYPE_CAMERABIN_FLAGS (gst_camerabin_flags_get_type())
-GType gst_camerabin_flags_get_type (void);
-
-G_END_DECLS
-
-#endif                          /* #ifndef __GST_CAMERABIN_ENUM_H__ */
diff --git a/gst/camerabin/gstcamerabin-marshal.list b/gst/camerabin/gstcamerabin-marshal.list
deleted file mode 100644 (file)
index 6bc959a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# glib-genmarshal --header --prefix=gst_camerabin camerabin_marshal.marshal > camerabin_marshal.h
-# glib-genmarshal --body --prefix=gst_camerabin camerabin_marshal.marshal > camerabin_marshal.c
-
-VOID:INT,INT,INT,INT
-VOID:INT,INT
-BOOLEAN:STRING
-INT64:VOID
-VOID:OBJECT,INT64,INT64
diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c
deleted file mode 100644 (file)
index 7fc9da9..0000000
+++ /dev/null
@@ -1,4350 +0,0 @@
-/*
- * 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:element-camerabin
- *
- * GstCameraBin is a high-level camera object that encapsulates the gstreamer
- * internals and provides a task based API for the application. It consists of
- * three main data paths: view-finder, image capture and video capture.
- *
- * <informalfigure>
- *   <mediaobject>
- *     <imageobject><imagedata fileref="camerabin.png"/></imageobject>
- *     <textobject><phrase>CameraBin structure</phrase></textobject>
- *     <caption><para>Structural decomposition of CameraBin object.</para></caption>
- *   </mediaobject>
- * </informalfigure>
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m camerabin
- * ]|
- * </refsect2>
- * <refsect2>
- * <title>Image capture</title>
- * <para>
- * Image capture is selected by switching #GstCameraBin:mode to %MODE_IMAGE.
- * Taking still images is initiated with the #GstCameraBin::capture-start action
- * signal. Once the image has been captured, "image-captured" gst message is
- * posted to the bus and capturing another image is possible. If application 
- * has set #GstCameraBin:preview-caps property, then a "preview-image" gst
- * message is posted to bus containing preview image formatted according to
- * specified caps. Eventually when image has been saved
- * #GstCameraBin::image-done signal is emitted.
- * 
- * Available resolutions can be taken from the #GstCameraBin:video-source-caps
- * property. Image capture resolution can be set with 
- * #GstCameraBin::set-image-resolution action signal.
- *
- * Some video source elements implement the #GstPhotography interface, which contains
- * functions and properties for setting photography parameters. One can use
- * gst_bin_iterate_all_by_interface() to get a reference to it.
- *
- * </para>
- * </refsect2>
- * <refsect2>
- * <title>Video capture</title>
- * <para>
- * Video capture is selected by switching #GstCameraBin:mode to %MODE_VIDEO.
- * The capture is started with the #GstCameraBin::capture-start action signal
- * too. In addition to image capture one can use #GstCameraBin::capture-pause to
- * pause recording and #GstCameraBin::capture-stop to end recording.
- * 
- * Available resolutions and fps can be taken from the 
- * #GstCameraBin:video-source-caps property. 
- * #GstCameraBin::set-video-resolution-fps action signal can be used to set
- * frame rate and resolution for the video recording and view finder as well.
- * </para>
- * </refsect2>
- * <refsect2>
- * <title>States</title>
- * <para>
- * Elements within GstCameraBin are created and destroyed when switching
- * between NULL and READY states. Therefore element properties should be set
- * in NULL state. User set elements are not unreffed until GstCameraBin is
- * unreffed or replaced by a new user set element. Initially only elements
- * needed for view finder mode are created to speed up startup. Image bin and
- * video bin elements are created when setting the mode or starting capture.
- * GstCameraBin must be in the PLAYING state before #GstCameraBin::capture-start
- * is called.
- * </para>
- * </refsect2>
- * <refsect2>
- * <title>Video and image previews</title>
- * <para>
- * GstCameraBin contains #GstCameraBin:preview-caps property, which is used to
- * determine whether the application wants a preview image of the captured
- * picture or video. When set, a GstMessage named "preview-image" will be sent.
- * This message will contain a GstBuffer holding the preview image, converted
- * to a format defined by those preview caps. The ownership of the preview
- * image is kept in GstCameraBin, so application should ref the preview buffer
- * object if it needs to use it elsewhere than in message handler.
- * 
- * Defining preview caps is done by selecting the capturing #GstCameraBin:mode
- * first and then setting the property. Camerabin remembers caps separately for
- * both modes, so it is not necessary to set the caps again after changing the
- * mode.
- * </para>
- * </refsect2>
- * <refsect2>
- * <note>
- * <para>
- * Since the muxers tested so far have problems with discontinous buffers, QoS
- * has been disabled, and then in order to record video, you MUST ensure that
- * there is enough CPU to encode the video. Thus choose smart resolution and
- * frames per second values. It is also highly recommended to avoid color
- * conversions; make sure all the elements involved work with the same
- * colorspace (i.e. rgb or yuv i420 or whatelse).
- * </para>
- * </note>
- * </refsect2>
- */
-
-/*
- * The pipeline in the camerabin is
- *
- * videosrc [ ! ffmpegcsp ] ! capsfilter ! crop ! scale ! capsfilter ! \
- *     [ video_filter ! ] out-sel name=osel ! queue name=img_q
- *
- * View finder:
- * osel. ! in-sel name=isel ! scale ! capsfilter [ ! ffmpegcsp ] ! vfsink
- *
- * Image bin:
- * img_q. [ ! ipp ] ! ffmpegcsp ! imageenc ! metadatamux ! filesink
- *
- * Video bin:
- * osel. ! tee name=t ! queue ! videoenc ! videomux name=mux ! filesink
- * t. ! queue ! isel.
- * audiosrc ! queue ! audioconvert ! volume ! audioenc ! mux.
- *
- * The properties of elements are:
- *
- *   vfsink - "sync", FALSE, "qos", FALSE, "async", FALSE
- *   output-selector - "resend-latest", FALSE
- *   input-selector - "select-all", TRUE
- */
-
-/*
- * includes
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
- * with newer GLib versions (>= 2.31.0) */
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <gst/gst.h>
-#include <gst/tag/tag.h>
-#include <gst/glib-compat-private.h>
-/* FIXME: include #include <gst/gst-i18n-plugin.h> and use _(" ") */
-
-#include "gstcamerabin.h"
-#include "gstcamerabincolorbalance.h"
-
-#include "camerabindebug.h"
-#include "camerabingeneral.h"
-#include "camerabinpreview.h"
-
-#include "gstcamerabin-marshal.h"
-
-/*
- * enum and types
- */
-
-enum
-{
-  /* action signals */
-  CAPTURE_START_SIGNAL,
-  CAPTURE_STOP_SIGNAL,
-  CAPTURE_PAUSE_SIGNAL,
-  SET_VIDEO_RESOLUTION_FPS_SIGNAL,
-  SET_IMAGE_RESOLUTION_SIGNAL,
-  /* emit signals */
-  IMG_DONE_SIGNAL,
-  LAST_SIGNAL
-};
-
-
-/*
- * defines and static global vars
- */
-
-static guint camerabin_signals[LAST_SIGNAL];
-
-#define GST_TYPE_CAMERABIN_MODE (gst_camerabin_mode_get_type ())
-
-/* default and range values for args */
-
-#define DEFAULT_MODE MODE_IMAGE
-#define DEFAULT_ZOOM 1.0
-#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 CAMERABIN_DEFAULT_VF_CAPS "video/x-raw-yuv,format=(fourcc)I420"
-#define CAMERABIN_MAX_VF_WIDTH 848
-#define CAMERABIN_MAX_VF_HEIGHT 848
-
-#define DEFAULT_FLAGS GST_CAMERABIN_FLAG_SOURCE_RESIZE | \
-  GST_CAMERABIN_FLAG_VIEWFINDER_SCALE | \
-  GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION | \
-  GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION | \
-  GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION | \
-  GST_CAMERABIN_FLAG_AUDIO_CONVERSION
-
-/* Using "bilinear" as default zoom method */
-#define CAMERABIN_DEFAULT_ZOOM_METHOD 1
-
-#define MIN_ZOOM 1.0
-#define MAX_ZOOM 10.0
-#define ZOOM_1X MIN_ZOOM
-
-/* FIXME: this is v4l2camsrc specific */
-#define DEFAULT_V4L2CAMSRC_DRIVER_NAME "omap3cam"
-
-#define DEFAULT_BLOCK_VIEWFINDER FALSE
-#define DEFAULT_READY_FOR_CAPTURE TRUE
-
-/* message names */
-#define PREVIEW_MESSAGE_NAME "preview-image"
-#define IMG_CAPTURED_MESSAGE_NAME "image-captured"
-
-#define CAMERABIN_PROCESSING_INC_UNLOCKED(c)  \
-  (c)->processing_counter += 1;               \
-  GST_DEBUG_OBJECT ((c), "Processing counter incremented to: %d", \
-      (c)->processing_counter);               \
-  if ((c)->processing_counter == 1)           \
-    g_object_notify (G_OBJECT (c), "idle");
-
-#define CAMERABIN_PROCESSING_DEC_UNLOCKED(c)  \
-  (c)->processing_counter -= 1;               \
-  GST_DEBUG_OBJECT ((c), "Processing counter decremented to: %d", \
-      (c)->processing_counter);               \
-  g_assert ((c)->processing_counter >= 0);    \
-  if ((c)->processing_counter == 0) {         \
-    g_cond_signal ((c)->idle_cond);           \
-    g_object_notify (G_OBJECT (c), "idle");   \
-  }
-
-#define CAMERABIN_PROCESSING_INC(c)           \
-  g_mutex_lock ((c)->capture_mutex);          \
-  CAMERABIN_PROCESSING_INC_UNLOCKED ((c));    \
-  g_mutex_unlock ((c)->capture_mutex);
-
-#define CAMERABIN_PROCESSING_DEC(c)           \
-  g_mutex_lock ((c)->capture_mutex);          \
-  CAMERABIN_PROCESSING_DEC_UNLOCKED ((c));    \
-  g_mutex_unlock ((c)->capture_mutex);
-
-#define CAMERABIN_PROCESSING_WAIT_IDLE(c)             \
-  g_mutex_lock ((c)->capture_mutex);                  \
-  if ((c)->processing_counter > 0) {                  \
-    GST_DEBUG_OBJECT ((c), "Waiting for processing operations to finish %d", \
-        (c)->processing_counter);                     \
-    g_cond_wait ((c)->idle_cond, (c)->capture_mutex); \
-    GST_DEBUG_OBJECT ((c), "Processing operations finished"); \
-  }                                                   \
-  g_mutex_unlock ((c)->capture_mutex);
-
-/*
- * static helper functions declaration
- */
-
-static void camerabin_setup_src_elements (GstCameraBin * camera);
-
-static gboolean camerabin_create_src_elements (GstCameraBin * camera);
-
-static void camerabin_setup_view_elements (GstCameraBin * camera);
-
-static gboolean camerabin_create_view_elements (GstCameraBin * camera);
-
-static gboolean camerabin_create_elements (GstCameraBin * camera);
-
-static void camerabin_destroy_elements (GstCameraBin * camera);
-
-static void camerabin_dispose_elements (GstCameraBin * camera);
-
-static void gst_camerabin_change_mode (GstCameraBin * camera, gint mode);
-
-static void
-gst_camerabin_set_flags (GstCameraBin * camera, GstCameraBinFlags flags);
-
-static void
-gst_camerabin_change_filename (GstCameraBin * camera, const gchar * name);
-
-static void gst_camerabin_setup_zoom (GstCameraBin * camera);
-
-static GstCaps *gst_camerabin_get_allowed_input_caps (GstCameraBin * camera);
-
-static void gst_camerabin_rewrite_tags (GstCameraBin * camera);
-
-static void
-gst_camerabin_set_capsfilter_caps (GstCameraBin * camera, GstCaps * new_caps);
-
-static void gst_camerabin_start_image_capture (GstCameraBin * camera);
-
-static void gst_camerabin_start_video_recording (GstCameraBin * camera);
-
-static void
-camerabin_pad_blocked (GstPad * pad, gboolean blocked, gpointer user_data);
-
-static gboolean
-gst_camerabin_have_img_buffer (GstPad * pad, GstMiniObject * obj,
-    gpointer u_data);
-static gboolean
-gst_camerabin_have_vid_buffer (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data);
-static gboolean
-gst_camerabin_have_queue_data (GstPad * pad, GstMiniObject * mini_obj,
-    gpointer u_data);
-static gboolean
-gst_camerabin_have_src_buffer (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data);
-
-static void gst_camerabin_reset_to_view_finder (GstCameraBin * camera);
-
-static void gst_camerabin_do_stop (GstCameraBin * camera);
-
-static void
-gst_camerabin_set_allowed_framerate (GstCameraBin * camera,
-    GstCaps * filter_caps);
-
-static guint32 get_srcpad_current_format (GstElement * element);
-
-static const GValue *gst_camerabin_find_better_framerate (GstCameraBin * camera,
-    GstStructure * st, const GValue * orig_framerate);
-
-static void
-gst_camerabin_update_aspect_filter (GstCameraBin * camera, GstCaps * new_caps);
-
-static void gst_camerabin_finish_image_capture (GstCameraBin * camera);
-static void gst_camerabin_adapt_image_capture (GstCameraBin * camera,
-    GstCaps * new_caps);
-static void gst_camerabin_scene_mode_notify_cb (GObject * video_source,
-    GParamSpec * pspec, gpointer user_data);
-static void gst_camerabin_zoom_notify_cb (GObject * video_source,
-    GParamSpec * pspec, gpointer user_data);
-static void gst_camerabin_monitor_video_source_properties (GstCameraBin *
-    camera);
-static void gst_camerabin_configure_format (GstCameraBin * camera,
-    GstCaps * caps);
-static gboolean
-copy_missing_fields (GQuark field_id, const GValue * value, gpointer user_data);
-
-/*
- * GObject callback functions declaration
- */
-
-static void gst_camerabin_dispose (GObject * object);
-
-static void gst_camerabin_finalize (GObject * object);
-
-static void gst_camerabin_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-
-static void gst_camerabin_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-/*
- * GstElement function declarations
- */
-
-static GstStateChangeReturn
-gst_camerabin_change_state (GstElement * element, GstStateChange transition);
-
-static GstClock *gst_camerabin_provide_clock (GstElement * element);
-
-/*
- * GstBin function declarations
- */
-static void
-gst_camerabin_handle_message_func (GstBin * bin, GstMessage * message);
-
-
-/*
- * Action signal function declarations
- */
-
-static void gst_camerabin_capture_start (GstCameraBin * camera);
-
-static void gst_camerabin_capture_stop (GstCameraBin * camera);
-
-static void gst_camerabin_capture_pause (GstCameraBin * camera);
-
-static void
-gst_camerabin_set_image_capture_caps (GstCameraBin * camera, gint width,
-    gint height);
-
-static void
-gst_camerabin_set_video_resolution_fps (GstCameraBin * camera, gint width,
-    gint height, gint fps_n, gint fps_d);
-static void
-do_set_video_resolution_fps (GstCameraBin * camera, gint width,
-    gint height, gint fps_n, gint fps_d);
-
-static void
-gst_camerabin_set_image_resolution (GstCameraBin * camera, gint width,
-    gint height);
-
-
-/*
- * GST BOILERPLATE and GObject types
- */
-
-static GType
-gst_camerabin_mode_get_type (void)
-{
-  static GType gtype = 0;
-
-  if (gtype == 0) {
-    static const GEnumValue values[] = {
-      {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;
-}
-
-
-static gboolean
-gst_camerabin_iface_supported (GstImplementsInterface * iface, GType iface_type)
-{
-  GstCameraBin *camera = GST_CAMERABIN (iface);
-
-  if (iface_type == GST_TYPE_COLOR_BALANCE) {
-    if (camera->src_vid_src) {
-      return GST_IS_COLOR_BALANCE (camera->src_vid_src);
-    }
-  } else if (iface_type == GST_TYPE_TAG_SETTER) {
-    /* Note: Tag setter elements aren't
-       present when image and video bin in NULL */
-    GstElement *setter;
-    setter = gst_bin_get_by_interface (GST_BIN (camera), iface_type);
-    if (setter) {
-      gst_object_unref (setter);
-      return TRUE;
-    } else {
-      return FALSE;
-    }
-  }
-  return FALSE;
-}
-
-static void
-gst_camerabin_interface_init (GstImplementsInterfaceClass * klass)
-{
-  /*
-   * default virtual functions
-   */
-  klass->supported = gst_camerabin_iface_supported;
-}
-
-static void
-camerabin_init_interfaces (GType type)
-{
-
-  static const GInterfaceInfo camerabin_info = {
-    (GInterfaceInitFunc) gst_camerabin_interface_init,
-    NULL,
-    NULL,
-  };
-
-  static const GInterfaceInfo camerabin_color_balance_info = {
-    (GInterfaceInitFunc) gst_camerabin_color_balance_init,
-    NULL,
-    NULL,
-  };
-
-  static const GInterfaceInfo camerabin_tagsetter_info = {
-    NULL,
-    NULL,
-    NULL,
-  };
-
-  g_type_add_interface_static (type,
-      GST_TYPE_IMPLEMENTS_INTERFACE, &camerabin_info);
-
-  g_type_add_interface_static (type, GST_TYPE_COLOR_BALANCE,
-      &camerabin_color_balance_info);
-
-  g_type_add_interface_static (type, GST_TYPE_TAG_SETTER,
-      &camerabin_tagsetter_info);
-}
-
-GST_BOILERPLATE_FULL (GstCameraBin, gst_camerabin, GstPipeline,
-    GST_TYPE_PIPELINE, camerabin_init_interfaces);
-
-/*
- * static helper functions implementation
- */
-
-/*
- * camerabin_setup_src_elements:
- * @camera: camerabin object
- *
- * This function updates camerabin capsfilters according
- * to fps, resolution and zoom that have been configured
- * to camerabin.
- */
-static void
-camerabin_setup_src_elements (GstCameraBin * camera)
-{
-  GstStructure *st;
-  GstCaps *new_caps;
-  gboolean detect_framerate = FALSE;
-
-  /* clear video update status */
-  camera->video_capture_caps_update = FALSE;
-
-  if (!camera->view_finder_caps) {
-    st = gst_structure_from_string (CAMERABIN_DEFAULT_VF_CAPS, NULL);
-  } else {
-    st = gst_structure_copy (gst_caps_get_structure (camera->view_finder_caps,
-            0));
-  }
-
-  gst_camerabin_monitor_video_source_properties (camera);
-
-  if (camera->app_width > 0 && camera->app_height > 0) {
-    gst_structure_set (st,
-        "width", G_TYPE_INT, camera->app_width,
-        "height", G_TYPE_INT, camera->app_height, NULL);
-  }
-
-  if (camera->app_fps_n > 0 && camera->app_fps_d > 0) {
-    if (camera->night_mode) {
-      GST_INFO_OBJECT (camera, "night mode, lowest allowed fps will be forced");
-      camera->pre_night_fps_n = camera->app_fps_n;
-      camera->pre_night_fps_d = camera->app_fps_d;
-      detect_framerate = TRUE;
-    } else {
-      gst_structure_set (st,
-          "framerate", GST_TYPE_FRACTION, camera->app_fps_n,
-          camera->app_fps_d, NULL);
-      new_caps = gst_caps_new_full (st, NULL);
-    }
-  } else {
-    GST_DEBUG_OBJECT (camera, "no framerate specified");
-    detect_framerate = TRUE;
-  }
-
-  if (detect_framerate) {
-    GST_DEBUG_OBJECT (camera, "detecting allowed framerate");
-    /* Remove old framerate if any */
-    if (gst_structure_has_field (st, "framerate")) {
-      gst_structure_remove_field (st, "framerate");
-    }
-    new_caps = gst_caps_new_full (st, NULL);
-
-    /* Set allowed framerate for the resolution */
-    gst_camerabin_set_allowed_framerate (camera, new_caps);
-  }
-
-  /* Set default zoom method */
-  if (camera->src_zoom_scale) {
-    g_object_set (camera->src_zoom_scale, "method",
-        CAMERABIN_DEFAULT_ZOOM_METHOD, NULL);
-  }
-  /* we create new caps in any way and they take ownership of the structure st */
-  gst_caps_replace (&camera->view_finder_caps, new_caps);
-  gst_caps_unref (new_caps);
-
-  /* Set caps for view finder mode */
-  /* This also sets zoom */
-  gst_camerabin_set_capsfilter_caps (camera, camera->view_finder_caps);
-}
-
-/*
- * camerabin_create_src_elements:
- * @camera: camerabin object
- *
- * This function creates and links upstream side elements for camerabin.
- * videosrc ! cspconv ! capsfilter ! crop ! scale ! capsfilter ! out-sel !
- *
- * Returns: TRUE, if elements were successfully created, FALSE otherwise
- */
-static gboolean
-camerabin_create_src_elements (GstCameraBin * camera)
-{
-  gboolean ret = FALSE;
-  GstBin *cbin = GST_BIN (camera);
-  gchar *driver_name = NULL;
-
-  /* Add application set or default video src element */
-  if (!(camera->src_vid_src = gst_camerabin_setup_default_element (cbin,
-              camera->app_vid_src, "autovideosrc", DEFAULT_VIDEOSRC))) {
-    camera->src_vid_src = NULL;
-    goto done;
-  } else {
-    if (!gst_camerabin_add_element (cbin, camera->src_vid_src))
-      goto done;
-  }
-  if (camera->flags & GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION) {
-    if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
-            "src-ffmpegcolorspace"))
-      goto done;
-  }
-  if (!(camera->src_filter =
-          gst_camerabin_create_and_add_element (cbin, "capsfilter",
-              "src-capsfilter")))
-    goto done;
-  if (camera->flags & GST_CAMERABIN_FLAG_SOURCE_RESIZE) {
-    if (!(camera->src_zoom_crop =
-            gst_camerabin_create_and_add_element (cbin, "videocrop",
-                "src-videocrop")))
-      goto done;
-    if (!(camera->src_zoom_scale =
-            gst_camerabin_create_and_add_element (cbin, "videoscale",
-                "src-videoscale")))
-      goto done;
-    if (!(camera->src_zoom_filter =
-            gst_camerabin_create_and_add_element (cbin, "capsfilter",
-                "src-resize-capsfilter")))
-      goto done;
-  }
-  if (camera->app_video_filter) {
-    if (!gst_camerabin_add_element (cbin, camera->app_video_filter)) {
-      goto done;
-    }
-  }
-  if (!(camera->src_out_sel =
-          gst_camerabin_create_and_add_element (cbin, "output-selector", NULL)))
-    goto done;
-
-  /* Set pad-negotiation-mode to active */
-  g_object_set (camera->src_out_sel, "pad-negotiation-mode", 2, NULL);
-
-  /* Set default "driver-name" for v4l2camsrc if not set */
-  /* FIXME: v4l2camsrc specific */
-  if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
-          "driver-name")) {
-    g_object_get (G_OBJECT (camera->src_vid_src), "driver-name",
-        &driver_name, NULL);
-    if (!driver_name) {
-      g_object_set (G_OBJECT (camera->src_vid_src), "driver-name",
-          DEFAULT_V4L2CAMSRC_DRIVER_NAME, NULL);
-    }
-  }
-
-  ret = TRUE;
-done:
-  return ret;
-}
-
-/*
- * camerabin_setup_view_elements:
- * @camera: camerabin object
- *
- * This function configures properties for view finder sink element.
- */
-static void
-camerabin_setup_view_elements (GstCameraBin * camera)
-{
-  GST_DEBUG_OBJECT (camera, "setting view finder properties");
-  g_object_set (G_OBJECT (camera->view_in_sel), "select-all", TRUE, NULL);
-  /* Set properties for view finder sink */
-  /* Find the actual sink if using bin like autovideosink */
-  if (GST_IS_BIN (camera->view_sink)) {
-    GList *child = NULL, *children = GST_BIN_CHILDREN (camera->view_sink);
-    for (child = children; child != NULL; child = g_list_next (child)) {
-      GObject *ch = G_OBJECT (child->data);
-      if (g_object_class_find_property (G_OBJECT_GET_CLASS (ch), "sync")) {
-        g_object_set (G_OBJECT (ch), "sync", FALSE, "qos", FALSE, "async",
-            FALSE, NULL);
-      }
-    }
-  } else {
-    g_object_set (G_OBJECT (camera->view_sink), "sync", FALSE, "qos", FALSE,
-        "async", FALSE, NULL);
-  }
-}
-
-/*
- * camerabin_create_view_elements:
- * @camera: camerabin object
- *
- * This function creates and links downstream side elements for camerabin.
- * ! scale ! cspconv ! view finder sink
- *
- * Returns: TRUE, if elements were successfully created, FALSE otherwise
- */
-static gboolean
-camerabin_create_view_elements (GstCameraBin * camera)
-{
-  const GList *pads;
-  GstBin *cbin = GST_BIN (camera);
-
-  if (!(camera->view_in_sel =
-          gst_camerabin_create_and_add_element (cbin, "input-selector",
-              NULL))) {
-    goto error;
-  }
-
-  /* Look for recently added input selector sink pad, we need to release it later */
-  pads = GST_ELEMENT_PADS (camera->view_in_sel);
-  while (pads != NULL
-      && (GST_PAD_DIRECTION (GST_PAD (pads->data)) != GST_PAD_SINK)) {
-    pads = g_list_next (pads);
-  }
-  camera->pad_view_src = GST_PAD (pads->data);
-
-  /* Add videoscale in case we need to downscale frame for view finder */
-  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
-    if (!(camera->view_scale =
-            gst_camerabin_create_and_add_element (cbin, "videoscale",
-                "vf-videoscale"))) {
-      goto error;
-    }
-
-    /* Add capsfilter to maintain aspect ratio while scaling */
-    if (!(camera->aspect_filter =
-            gst_camerabin_create_and_add_element (cbin, "capsfilter",
-                "vf-scale-capsfilter"))) {
-      goto error;
-    }
-  }
-  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION) {
-    if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
-            "vf-ffmpegcolorspace")) {
-      goto error;
-    }
-  }
-
-  if (camera->app_viewfinder_filter) {
-    if (!gst_camerabin_add_element (GST_BIN (camera),
-            camera->app_viewfinder_filter)) {
-      goto error;
-    }
-  }
-
-  /* Add application set or default video sink element */
-  if (!(camera->view_sink = gst_camerabin_setup_default_element (cbin,
-              camera->app_vf_sink, "autovideosink", DEFAULT_VIDEOSINK))) {
-    camera->view_sink = NULL;
-    goto error;
-  } else {
-    if (!gst_camerabin_add_element (cbin, camera->view_sink))
-      goto error;
-  }
-
-  return TRUE;
-error:
-  return FALSE;
-}
-
-/*
- * camerabin_create_elements:
- * @camera: camerabin object
- *
- * This function creates and links all elements for camerabin,
- *
- * Returns: TRUE, if elements were successfully created, FALSE otherwise
- */
-static gboolean
-camerabin_create_elements (GstCameraBin * camera)
-{
-  gboolean ret = FALSE;
-  GstPadLinkReturn link_ret = GST_PAD_LINK_REFUSED;
-  GstPad *unconnected_pad;
-
-  GST_LOG_OBJECT (camera, "creating elements");
-
-  /* Create "src" elements */
-  if (!camerabin_create_src_elements (camera)) {
-    goto done;
-  }
-
-  camera->pad_src_img =
-      gst_element_get_request_pad (camera->src_out_sel, "src_%u");
-
-  gst_pad_add_data_probe (camera->pad_src_img,
-      G_CALLBACK (gst_camerabin_have_img_buffer), camera);
-
-  /* Add queue leading to image bin */
-  camera->img_queue = gst_element_factory_make ("queue", "image-queue");
-  if (!gst_camerabin_add_element (GST_BIN (camera), camera->img_queue)) {
-    goto done;
-  }
-
-  /* To avoid deadlock, we won't restrict the image queue size */
-  /* FIXME: actually we would like to have some kind of restriction here (size),
-     but deadlocks must be handled somehow... */
-  g_object_set (G_OBJECT (camera->img_queue), "max-size-buffers", 0,
-      "max-size-bytes", 0, "max-size-time", G_GUINT64_CONSTANT (0), NULL);
-  g_object_set (camera->img_queue, "silent", TRUE, NULL);
-
-  camera->pad_src_queue = gst_element_get_static_pad (camera->img_queue, "src");
-
-  gst_pad_add_data_probe (camera->pad_src_queue,
-      G_CALLBACK (gst_camerabin_have_queue_data), camera);
-
-  /* Add image bin */
-  if (!gst_camerabin_add_element (GST_BIN (camera), camera->imgbin)) {
-    goto done;
-  }
-
-  camera->pad_src_view =
-      gst_element_get_request_pad (camera->src_out_sel, "src_%u");
-
-  /* Create view finder elements */
-  if (!camerabin_create_view_elements (camera)) {
-    GST_WARNING_OBJECT (camera, "creating view finder elements failed");
-    goto done;
-  }
-
-  /* Set view finder active as default */
-  g_object_set (G_OBJECT (camera->src_out_sel), "active-pad",
-      camera->pad_src_view, NULL);
-
-  /* Add video bin */
-  camera->pad_src_vid =
-      gst_element_get_request_pad (camera->src_out_sel, "src_%u");
-  if (!gst_camerabin_add_element (GST_BIN (camera), camera->vidbin)) {
-    goto done;
-  }
-  gst_pad_add_buffer_probe (camera->pad_src_vid,
-      G_CALLBACK (gst_camerabin_have_vid_buffer), camera);
-
-  /* Link video bin ! view finder */
-  unconnected_pad = gst_bin_find_unlinked_pad (GST_BIN (camera), GST_PAD_SRC);
-  camera->pad_view_vid =
-      gst_element_get_request_pad (camera->view_in_sel, "sink_%u");
-  link_ret =
-      gst_pad_link_full (unconnected_pad, camera->pad_view_vid,
-      GST_PAD_LINK_CHECK_CAPS);
-  gst_object_unref (unconnected_pad);
-  if (GST_PAD_LINK_FAILED (link_ret)) {
-    GST_ELEMENT_ERROR (camera, CORE, NEGOTIATION, (NULL),
-        ("linking video bin and view finder failed"));
-    goto done;
-  }
-
-  ret = TRUE;
-
-done:
-
-  if (FALSE == ret)
-    camerabin_destroy_elements (camera);
-
-  return ret;
-}
-
-/*
- * camerabin_destroy_elements:
- * @camera: camerabin object
- *
- * This function removes all elements from camerabin.
- */
-static void
-camerabin_destroy_elements (GstCameraBin * camera)
-{
-  GST_DEBUG_OBJECT (camera, "destroying elements");
-
-  /* Release request pads */
-  if (camera->pad_view_vid) {
-    gst_element_release_request_pad (camera->view_in_sel, camera->pad_view_vid);
-    gst_object_unref (camera->pad_view_vid);
-    camera->pad_view_vid = NULL;
-  }
-  if (camera->pad_src_vid) {
-    gst_element_release_request_pad (camera->src_out_sel, camera->pad_src_vid);
-    gst_object_unref (camera->pad_src_vid);
-    camera->pad_src_vid = NULL;
-  }
-  if (camera->pad_src_img) {
-    gst_element_release_request_pad (camera->src_out_sel, camera->pad_src_img);
-    gst_object_unref (camera->pad_src_img);
-    camera->pad_src_img = NULL;
-  }
-  if (camera->pad_view_src) {
-    gst_element_release_request_pad (camera->view_in_sel, camera->pad_view_src);
-    /* don't unref, we have not requested it */
-    camera->pad_view_src = NULL;
-  }
-  if (camera->pad_src_view) {
-    gst_element_release_request_pad (camera->src_out_sel, camera->pad_src_view);
-    gst_object_unref (camera->pad_src_view);
-    camera->pad_src_view = NULL;
-  }
-
-  if (camera->pad_src_queue) {
-    gst_object_unref (camera->pad_src_queue);
-    camera->pad_src_queue = NULL;
-  }
-
-  /* view finder elements */
-  camera->view_in_sel = NULL;
-  camera->view_scale = NULL;
-  camera->aspect_filter = NULL;
-  camera->view_sink = NULL;
-
-  /* source elements */
-  camera->src_vid_src = NULL;
-  camera->src_filter = NULL;
-  camera->src_zoom_crop = NULL;
-  camera->src_zoom_scale = NULL;
-  camera->src_zoom_filter = NULL;
-  camera->src_out_sel = NULL;
-
-  camera->active_bin = NULL;
-
-  /* Reset caps data as the elements might be completely different next
-   * time we 'start' */
-  if (camera->view_finder_caps) {
-    gst_caps_replace (&camera->view_finder_caps, NULL);
-  }
-  gst_caps_replace (&camera->allowed_caps, NULL);
-  camera->fps_n = camera->fps_d = 0;
-  camera->width = camera->height = 0;
-
-  /* Remove elements */
-  gst_camerabin_remove_elements_from_bin (GST_BIN (camera));
-}
-
-/*
- * camerabin_dispose_elements:
- * @camera: camerabin object
- *
- * This function releases all allocated camerabin resources.
- */
-static void
-camerabin_dispose_elements (GstCameraBin * camera)
-{
-  GST_INFO ("cleaning");
-
-  if (camera->capture_mutex) {
-    g_mutex_free (camera->capture_mutex);
-    camera->capture_mutex = NULL;
-  }
-  if (camera->cond) {
-    g_cond_free (camera->cond);
-    camera->cond = NULL;
-  }
-  if (camera->idle_cond) {
-    g_cond_free (camera->idle_cond);
-    camera->idle_cond = NULL;
-  }
-  if (camera->filename) {
-    g_string_free (camera->filename, TRUE);
-    camera->filename = NULL;
-  }
-  /* Unref application set elements */
-  if (camera->app_vf_sink) {
-    gst_object_unref (camera->app_vf_sink);
-    camera->app_vf_sink = NULL;
-  }
-  if (camera->app_vid_src) {
-    gst_object_unref (camera->app_vid_src);
-    camera->app_vid_src = NULL;
-  }
-
-  if (camera->app_video_filter) {
-    gst_object_unref (camera->app_video_filter);
-    camera->app_video_filter = NULL;
-  }
-
-  if (camera->app_viewfinder_filter) {
-    gst_object_unref (camera->app_viewfinder_filter);
-    camera->app_viewfinder_filter = NULL;
-  }
-
-  if (camera->app_preview_source_filter) {
-    gst_object_unref (camera->app_preview_source_filter);
-    camera->app_preview_source_filter = NULL;
-  }
-
-  if (camera->app_video_preview_source_filter) {
-    gst_object_unref (camera->app_video_preview_source_filter);
-    camera->app_video_preview_source_filter = NULL;
-  }
-
-  /* Free caps */
-  gst_caps_replace (&camera->image_capture_caps, NULL);
-  gst_caps_replace (&camera->view_finder_caps, NULL);
-  gst_caps_replace (&camera->allowed_caps, NULL);
-  gst_caps_replace (&camera->preview_caps, NULL);
-  gst_caps_replace (&camera->video_preview_caps, NULL);
-  gst_buffer_replace (&camera->video_preview_buffer, NULL);
-
-  if (camera->event_tags) {
-    gst_tag_list_free (camera->event_tags);
-    camera->event_tags = NULL;
-  }
-}
-
-/*
- * gst_camerabin_image_capture_continue:
- * @camera: camerabin object
- * @filename: filename of the finished image
- *
- * Notify application that image has been saved with a signal.
- *
- * Returns TRUE if another image should be captured, FALSE otherwise.
- */
-static gboolean
-gst_camerabin_image_capture_continue (GstCameraBin * camera,
-    const gchar * filename)
-{
-  gboolean cont = FALSE;
-
-  GST_DEBUG_OBJECT (camera, "emitting img_done signal, filename: %s", filename);
-  g_signal_emit (G_OBJECT (camera), camerabin_signals[IMG_DONE_SIGNAL], 0,
-      filename, &cont);
-
-  /* If the app wants to continue make sure new filename has been set */
-  if (cont && g_str_equal (camera->filename->str, "")) {
-    GST_ELEMENT_ERROR (camera, RESOURCE, NOT_FOUND,
-        ("cannot continue capture, no filename has been set"), (NULL));
-    cont = FALSE;
-  }
-
-  return cont;
-}
-
-/*
- * gst_camerabin_change_mode:
- * @camera: camerabin object
- * @mode: image or video mode
- *
- * Change camerabin mode between image and video capture.
- * Changing mode will stop ongoing capture.
- */
-static void
-gst_camerabin_change_mode (GstCameraBin * camera, gint mode)
-{
-  if (camera->mode != mode || !camera->active_bin) {
-    GstState state, pending_state;
-
-    GST_DEBUG_OBJECT (camera, "setting mode: %d (old_mode=%d)",
-        mode, camera->mode);
-    /* Interrupt ongoing capture */
-    gst_camerabin_do_stop (camera);
-
-    /* reset night-mode stored values */
-    camera->pre_night_fps_n = 0;
-    camera->pre_night_fps_d = 1;
-
-    camera->mode = mode;
-    gst_element_get_state (GST_ELEMENT (camera), &state, &pending_state, 0);
-    if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING ||
-        pending_state == GST_STATE_PAUSED
-        || pending_state == GST_STATE_PLAYING) {
-      if (camera->active_bin) {
-        GST_DEBUG_OBJECT (camera, "stopping active bin");
-        gst_element_set_state (camera->active_bin, GST_STATE_READY);
-      }
-      if (camera->mode == MODE_IMAGE) {
-        GstStateChangeReturn state_ret;
-
-        camera->active_bin = camera->imgbin;
-        state_ret =
-            gst_element_set_state (camera->active_bin, GST_STATE_PAUSED);
-
-        if (state_ret == GST_STATE_CHANGE_FAILURE) {
-          GST_WARNING_OBJECT (camera, "state change failed");
-          gst_element_set_state (camera->active_bin, GST_STATE_NULL);
-          camera->active_bin = NULL;
-        }
-      } else if (camera->mode == MODE_VIDEO) {
-        camera->active_bin = camera->vidbin;
-      }
-      gst_camerabin_reset_to_view_finder (camera);
-    } else if (camera->mode == MODE_IMAGE) {
-      /* Prepare needed elements for image processing */
-      gst_camerabin_image_prepare_elements (GST_CAMERABIN_IMAGE
-          (camera->imgbin));
-    }
-  }
-}
-
-/*
- * gst_camerabin_set_flags:
- * @camera: camerabin object
- * @flags: flags for camerabin, videobin and imagebin
- *
- * Change camerabin capture flags.
- */
-static void
-gst_camerabin_set_flags (GstCameraBin * camera, GstCameraBinFlags flags)
-{
-  g_return_if_fail (camera != NULL);
-
-  GST_DEBUG_OBJECT (camera, "setting flags: %d", flags);
-
-  GST_OBJECT_LOCK (camera);
-  camera->flags = flags;
-  GST_OBJECT_UNLOCK (camera);
-
-  gst_camerabin_video_set_flags (GST_CAMERABIN_VIDEO (camera->vidbin), flags);
-  gst_camerabin_image_set_flags (GST_CAMERABIN_IMAGE (camera->imgbin), flags);
-}
-
-/*
- * gst_camerabin_change_filename:
- * @camera: camerabin object
- * @name: new filename for capture
- *
- * Change filename for image or video capture.
- */
-static void
-gst_camerabin_change_filename (GstCameraBin * camera, const gchar * name)
-{
-  if (name == NULL)
-    name = "";
-
-  if (0 != strcmp (camera->filename->str, name)) {
-    GST_DEBUG_OBJECT (camera, "changing filename from '%s' to '%s'",
-        camera->filename->str, name);
-    g_string_assign (camera->filename, name);
-  }
-}
-
-static gboolean
-gst_camerabin_set_videosrc_zoom (GstCameraBin * camera, gfloat zoom)
-{
-  gboolean ret = FALSE;
-
-  /* Try with photography interface zooming */
-  if (GST_IS_ELEMENT (camera->src_vid_src) &&
-      gst_element_implements_interface (camera->src_vid_src,
-          GST_TYPE_PHOTOGRAPHY)) {
-    gst_photography_set_zoom (GST_PHOTOGRAPHY (camera->src_vid_src), zoom);
-    ret = TRUE;
-  }
-  return ret;
-}
-
-
-static gboolean
-gst_camerabin_set_element_zoom (GstCameraBin * camera, gfloat zoom)
-{
-  gint w2_crop = 0, h2_crop = 0;
-  GstPad *pad_zoom_sink = NULL;
-  gboolean ret = FALSE;
-  gint left = camera->base_crop_left;
-  gint right = camera->base_crop_right;
-  gint top = camera->base_crop_top;
-  gint bottom = camera->base_crop_bottom;
-
-  if (camera->src_zoom_crop) {
-    /* Update capsfilters to apply the zoom */
-    GST_INFO_OBJECT (camera, "zoom: %f, orig size: %dx%d", zoom,
-        camera->width, camera->height);
-
-    if (zoom != ZOOM_1X) {
-      w2_crop = (camera->width - (camera->width * ZOOM_1X / zoom)) / 2;
-      h2_crop = (camera->height - (camera->height * ZOOM_1X / zoom)) / 2;
-
-      left += w2_crop;
-      right += w2_crop;
-      top += h2_crop;
-      bottom += h2_crop;
-
-      /* force number of pixels cropped from left to be even, to avoid slow code
-       * path on videoscale */
-      left &= 0xFFFE;
-    }
-
-    pad_zoom_sink = gst_element_get_static_pad (camera->src_zoom_crop, "sink");
-
-    GST_INFO_OBJECT (camera,
-        "sw cropping: left:%d, right:%d, top:%d, bottom:%d", left, right, top,
-        bottom);
-
-    GST_PAD_STREAM_LOCK (pad_zoom_sink);
-    g_object_set (camera->src_zoom_crop, "left", left, "right", right, "top",
-        top, "bottom", bottom, NULL);
-    GST_PAD_STREAM_UNLOCK (pad_zoom_sink);
-    gst_object_unref (pad_zoom_sink);
-    ret = TRUE;
-  }
-  return ret;
-}
-
-/*
- * gst_camerabin_setup_zoom:
- * @camera: camerabin object
- *
- * Apply zoom configured to camerabin to capture.
- */
-static void
-gst_camerabin_setup_zoom (GstCameraBin * camera)
-{
-  gfloat zoom;
-
-  g_return_if_fail (camera != NULL);
-
-  zoom = camera->zoom;
-
-  g_return_if_fail (zoom);
-
-  GST_INFO_OBJECT (camera, "setting zoom %f", zoom);
-
-  if (gst_camerabin_set_videosrc_zoom (camera, zoom)) {
-    gst_camerabin_set_element_zoom (camera, ZOOM_1X);
-    GST_INFO_OBJECT (camera, "zoom set using videosrc");
-  } else if (gst_camerabin_set_element_zoom (camera, zoom)) {
-    GST_INFO_OBJECT (camera, "zoom set using gst elements");
-  } else {
-    GST_INFO_OBJECT (camera, "setting zoom failed");
-  }
-}
-
-/*
- * gst_camerabin_get_allowed_input_caps:
- * @camera: camerabin object
- *
- * Retrieve caps from videosrc describing formats it supports
- *
- * Returns: caps object from videosrc
- */
-static GstCaps *
-gst_camerabin_get_allowed_input_caps (GstCameraBin * camera)
-{
-  GstCaps *caps = NULL;
-  GstPad *pad = NULL, *peer_pad = NULL;
-  GstState state;
-  GstElement *videosrc;
-
-  g_return_val_if_fail (camera != NULL, NULL);
-
-  videosrc = camera->src_vid_src ? camera->src_vid_src : camera->app_vid_src;
-
-  if (!videosrc) {
-    GST_WARNING_OBJECT (camera, "no videosrc, can't get allowed caps");
-    goto failed;
-  }
-
-  if (camera->allowed_caps) {
-    GST_DEBUG_OBJECT (camera, "returning cached caps");
-    goto done;
-  }
-
-  pad = gst_element_get_static_pad (videosrc, "src");
-
-  if (!pad) {
-    GST_WARNING_OBJECT (camera, "no srcpad in videosrc");
-    goto failed;
-  }
-
-  state = GST_STATE (videosrc);
-
-  /* Make this function work also in NULL state */
-  if (state == GST_STATE_NULL) {
-    GST_DEBUG_OBJECT (camera, "setting videosrc to ready temporarily");
-    peer_pad = gst_pad_get_peer (pad);
-    if (peer_pad) {
-      gst_pad_unlink (pad, peer_pad);
-    }
-    /* Set videosrc to READY to open video device */
-    gst_element_set_locked_state (videosrc, TRUE);
-    gst_element_set_state (videosrc, GST_STATE_READY);
-  }
-
-  camera->allowed_caps = gst_pad_get_caps (pad);
-
-  /* Restore state and re-link if necessary */
-  if (state == GST_STATE_NULL) {
-    GST_DEBUG_OBJECT (camera, "restoring videosrc state %d", state);
-    /* Reset videosrc to NULL state, some drivers seem to need this */
-    gst_element_set_state (videosrc, GST_STATE_NULL);
-    if (peer_pad) {
-      gst_pad_link_full (pad, peer_pad, GST_PAD_LINK_CHECK_CAPS);
-      gst_object_unref (peer_pad);
-    }
-    gst_element_set_locked_state (videosrc, FALSE);
-  }
-
-  gst_object_unref (pad);
-
-done:
-  if (camera->allowed_caps) {
-    caps = gst_caps_copy (camera->allowed_caps);
-  }
-  GST_DEBUG_OBJECT (camera, "allowed caps:%" GST_PTR_FORMAT, caps);
-failed:
-  return caps;
-}
-
-/*
- * gst_camerabin_send_img_queue_event:
- * @camera: camerabin object
- * @event: event to be sent
- *
- * Send the given event to image queue.
- */
-static void
-gst_camerabin_send_img_queue_event (GstCameraBin * camera, GstEvent * event)
-{
-  GstPad *queue_sink;
-
-  g_return_if_fail (camera != NULL);
-  g_return_if_fail (event != NULL);
-
-  queue_sink = gst_element_get_static_pad (camera->img_queue, "sink");
-  gst_pad_send_event (queue_sink, event);
-  gst_object_unref (queue_sink);
-}
-
-/*
- * gst_camerabin_send_img_queue_custom_event:
- * @camera: camerabin object
- * @ev_struct: event structure to be sent
- *
- * Generate and send a custom event to image queue.
- */
-static void
-gst_camerabin_send_img_queue_custom_event (GstCameraBin * camera,
-    GstStructure * ev_struct)
-{
-  GstEvent *event;
-
-  g_return_if_fail (camera != NULL);
-  g_return_if_fail (ev_struct != NULL);
-
-  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, ev_struct);
-  gst_camerabin_send_img_queue_event (camera, event);
-}
-
-/*
- * gst_camerabin_rewrite_tags_to_bin:
- * @bin: bin holding tag setter elements
- * @list: tag list to be written
- *
- * This function looks for certain tag setters from given bin
- * and REPLACES ALL setter tags with given tag list
- *
- */
-static void
-gst_camerabin_rewrite_tags_to_bin (GstBin * bin, const GstTagList * list)
-{
-  GstElement *setter;
-  GstIterator *iter;
-  GstIteratorResult res = GST_ITERATOR_OK;
-  gpointer data;
-
-  iter = gst_bin_iterate_all_by_interface (bin, GST_TYPE_TAG_SETTER);
-
-  while (res == GST_ITERATOR_OK || res == GST_ITERATOR_RESYNC) {
-    res = gst_iterator_next (iter, &data);
-    switch (res) {
-      case GST_ITERATOR_DONE:
-        break;
-      case GST_ITERATOR_RESYNC:
-        gst_iterator_resync (iter);
-        break;
-      case GST_ITERATOR_ERROR:
-        GST_WARNING ("error iterating tag setters");
-        break;
-      case GST_ITERATOR_OK:
-        setter = GST_ELEMENT (data);
-        GST_LOG ("iterating tag setters: %" GST_PTR_FORMAT, setter);
-        GST_DEBUG ("replacement tags %" GST_PTR_FORMAT, list);
-        gst_tag_setter_merge_tags (GST_TAG_SETTER (setter), list,
-            GST_TAG_MERGE_REPLACE_ALL);
-        gst_object_unref (setter);
-        break;
-      default:
-        break;
-    }
-  }
-
-  gst_iterator_free (iter);
-}
-
-/*
- * gst_camerabin_get_internal_tags:
- * @camera: the camera bin element
- *
- * Returns tag list containing metadata from camerabin
- * and it's elements
- */
-static GstTagList *
-gst_camerabin_get_internal_tags (GstCameraBin * camera)
-{
-  GstTagList *list = gst_tag_list_new ();
-  GstColorBalance *balance = NULL;
-  const GList *controls = NULL, *item;
-  GstColorBalanceChannel *channel;
-  gint min_value, max_value, mid_value, cur_value;
-
-  if (camera->active_bin == camera->vidbin) {
-    /* FIXME: check if internal video tag setting is needed */
-    goto done;
-  }
-
-  gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-      GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, (gdouble) camera->zoom, NULL);
-
-  if (gst_element_implements_interface (GST_ELEMENT (camera),
-          GST_TYPE_COLOR_BALANCE)) {
-    balance = GST_COLOR_BALANCE (camera);
-  }
-
-  if (balance) {
-    controls = gst_color_balance_list_channels (balance);
-  }
-  for (item = controls; item; item = g_list_next (item)) {
-    channel = item->data;
-    min_value = channel->min_value;
-    max_value = channel->max_value;
-    /* the default value would probably better */
-    mid_value = min_value + ((max_value - min_value) / 2);
-    cur_value = gst_color_balance_get_value (balance, channel);
-
-    if (!g_ascii_strcasecmp (channel->label, "brightness")) {
-      /* The value of brightness. The unit is the APEX value (Additive System of Photographic Exposure).
-       * Ordinarily it is given in the range of -99.99 to 99.99. Note that
-       * if the numerator of the recorded value is 0xFFFFFFFF, Unknown shall be indicated.
-       *
-       * BrightnessValue (Bv) = log2 ( B/NK )
-       * Note that: B:cd/cm² (candela per square centimeter), N,K: constant
-       *
-       * http://johnlind.tripod.com/science/scienceexposure.html
-       *
-       */
-/*
-      gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-          "capture-brightness", cur_value, 1, NULL);
-*/
-    } else if (!g_ascii_strcasecmp (channel->label, "contrast")) {
-      /* 0 = Normal, 1 = Soft, 2 = Hard */
-
-      gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-          GST_TAG_CAPTURING_CONTRAST,
-          (cur_value == mid_value) ? "normal" : ((cur_value < mid_value)
-              ? "soft" : "hard"), NULL);
-    } else if (!g_ascii_strcasecmp (channel->label, "gain")) {
-      /* 0 = Normal, 1 = Low Up, 2 = High Up, 3 = Low Down, 4 = Hight Down */
-      gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-          GST_TAG_CAPTURING_GAIN_ADJUSTMENT,
-          (cur_value == mid_value) ? "normal" : ((cur_value <
-                  mid_value) ? "low-gain-up" : "low-gain-down"), NULL);
-    } else if (!g_ascii_strcasecmp (channel->label, "saturation")) {
-      /* 0 = Normal, 1 = Low, 2 = High */
-      gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-          GST_TAG_CAPTURING_SATURATION,
-          (cur_value == mid_value) ? "normal" : ((cur_value < mid_value)
-              ? "low-saturation" : "high-saturation"), NULL);
-    }
-  }
-
-done:
-
-  return list;
-}
-
-/*
- * gst_camerabin_rewrite_tags:
- * @camera: the camera bin element
- *
- * Merges application set tags to camerabin internal tags,
- * and writes them using image or video bin tag setters.
- */
-static void
-gst_camerabin_rewrite_tags (GstCameraBin * camera)
-{
-  const GstTagList *app_tag_list = NULL;
-  GstTagList *list = NULL;
-
-  /* Get application set tags */
-  app_tag_list = gst_tag_setter_get_tag_list (GST_TAG_SETTER (camera));
-
-  /* Get tags from camerabin and it's elements */
-  list = gst_camerabin_get_internal_tags (camera);
-
-  if (app_tag_list) {
-    gst_tag_list_insert (list, app_tag_list, GST_TAG_MERGE_REPLACE);
-  }
-
-  /* Write tags */
-  if (camera->active_bin == camera->vidbin) {
-    gst_camerabin_rewrite_tags_to_bin (GST_BIN (camera->active_bin), list);
-  } else {
-    /* Image tags need to be sent as a serialized event into image queue */
-    GstEvent *tagevent = gst_event_new_tag (gst_tag_list_copy (list));
-    gst_camerabin_send_img_queue_event (camera, tagevent);
-  }
-
-  gst_tag_list_free (list);
-}
-
-/*
- * gst_camerabin_set_capsfilter_caps:
- * @camera: camerabin object
- * @new_caps: pointer to caps object to set
- *
- * Set given caps to camerabin capsfilters.
- */
-static void
-gst_camerabin_set_capsfilter_caps (GstCameraBin * camera, GstCaps * new_caps)
-{
-  GST_INFO_OBJECT (camera, "new_caps:%" GST_PTR_FORMAT, new_caps);
-
-  gst_camerabin_configure_format (camera, new_caps);
-
-  /* Update zoom */
-  gst_camerabin_setup_zoom (camera);
-
-  /* Update capsfilters */
-  g_object_set (G_OBJECT (camera->src_filter), "caps", new_caps, NULL);
-  if (camera->src_zoom_filter)
-    g_object_set (G_OBJECT (camera->src_zoom_filter), "caps", new_caps, NULL);
-  gst_camerabin_update_aspect_filter (camera, new_caps);
-  GST_INFO_OBJECT (camera, "udpated");
-}
-
-/*
- * img_capture_prepared:
- * @data: camerabin object
- * @caps: caps describing the prepared image format
- *
- * Callback which is called after image capture has been prepared.
- */
-static void
-img_capture_prepared (gpointer data, GstCaps * caps)
-{
-  GstCameraBin *camera = GST_CAMERABIN (data);
-
-  GST_INFO_OBJECT (camera, "image capture prepared");
-
-  /* It is possible we are about to get something else that we requested */
-  if (!gst_caps_is_equal (camera->image_capture_caps, caps)) {
-    gst_camerabin_adapt_image_capture (camera, caps);
-  } else {
-    gst_camerabin_set_capsfilter_caps (camera, camera->image_capture_caps);
-  }
-
-  g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
-      "active-pad", camera->pad_src_img, NULL);
-}
-
-/*
- * gst_camerabin_start_image_capture:
- * @camera: camerabin object
- *
- * Initiates image capture.
- */
-static void
-gst_camerabin_start_image_capture (GstCameraBin * camera)
-{
-  gboolean wait_for_prepare = FALSE, ret = FALSE;
-
-  GST_INFO_OBJECT (camera, "starting image capture");
-
-  if (GST_IS_ELEMENT (camera->src_vid_src) &&
-      gst_element_implements_interface (camera->src_vid_src,
-          GST_TYPE_PHOTOGRAPHY)) {
-    /* Start image capture preparations using photography iface */
-    wait_for_prepare = TRUE;
-    g_mutex_lock (camera->capture_mutex);
-
-    /* Enable still image capture mode in v4l2camsrc */
-    if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
-            "capture-mode")) {
-      g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 1, NULL);
-    }
-
-    if (!camera->image_capture_caps || camera->image_capture_caps_update) {
-      if (camera->image_capture_width && camera->image_capture_height) {
-        /* Resolution is set, but it isn't in use yet */
-        gst_camerabin_set_image_capture_caps (camera,
-            camera->image_capture_width, camera->image_capture_height);
-      } else {
-        /* Capture resolution not set. Use viewfinder resolution */
-        camera->image_capture_caps = gst_caps_copy (camera->view_finder_caps);
-        camera->image_capture_caps_update = FALSE;
-      }
-    }
-
-    /* Start preparations for image capture */
-    GST_DEBUG_OBJECT (camera, "prepare image capture caps %" GST_PTR_FORMAT,
-        camera->image_capture_caps);
-    ret =
-        gst_photography_prepare_for_capture (GST_PHOTOGRAPHY
-        (camera->src_vid_src), (GstPhotoCapturePrepared) img_capture_prepared,
-        camera->image_capture_caps, camera);
-    camera->capturing = TRUE;
-    g_mutex_unlock (camera->capture_mutex);
-  }
-
-  if (!wait_for_prepare) {
-    g_mutex_lock (camera->capture_mutex);
-    g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", TRUE,
-        "active-pad", camera->pad_src_img, NULL);
-    camera->capturing = TRUE;
-    ret = TRUE;
-    g_mutex_unlock (camera->capture_mutex);
-  }
-
-  if (!ret) {
-    CAMERABIN_PROCESSING_DEC_UNLOCKED (camera);
-    GST_WARNING_OBJECT (camera, "starting image capture failed");
-  }
-}
-
- /*
-  * FIXME ideally a caps renegotiation is better here
-  */
-static void
-reset_video_capture_caps (GstCameraBin * camera)
-{
-  GstState state, pending;
-  GstPad *activepad = NULL;
-
-  GST_INFO_OBJECT (camera, "switching resolution to %dx%d and fps to %d/%d",
-      camera->width, camera->height, camera->fps_n, camera->fps_d);
-
-  /* Interrupt ongoing capture */
-  gst_camerabin_do_stop (camera);
-
-  /* prevent image captures from being lost */
-  CAMERABIN_PROCESSING_WAIT_IDLE (camera);
-
-  gst_element_get_state (GST_ELEMENT (camera), &state, &pending, 0);
-  if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) {
-    GST_INFO_OBJECT (camera,
-        "changing to READY to initialize videosrc with new format");
-    g_object_get (G_OBJECT (camera->src_out_sel), "active-pad", &activepad,
-        NULL);
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_READY);
-  }
-  if (pending != GST_STATE_VOID_PENDING) {
-    GST_LOG_OBJECT (camera, "restoring pending state: %s",
-        gst_element_state_get_name (pending));
-    state = pending;
-  }
-
-  /* Re-set the active pad since switching camerabin to READY state clears this
-   * setting in output-selector */
-  if (activepad) {
-    GST_INFO_OBJECT (camera, "re-setting active pad in output-selector");
-
-    g_object_set (G_OBJECT (camera->src_out_sel), "active-pad", activepad,
-        NULL);
-  }
-
-  gst_element_set_state (GST_ELEMENT (camera), state);
-}
-
-/*
- * gst_camerabin_start_video_recording:
- * @camera: camerabin object
- *
- * Initiates video recording.
- */
-static void
-gst_camerabin_start_video_recording (GstCameraBin * camera)
-{
-  GstStateChangeReturn state_ret;
-  GstCameraBinVideo *vidbin = (GstCameraBinVideo *) camera->vidbin;
-  /* FIXME: how to ensure resolution and fps is supported by CPU?
-   * use a queue overrun signal?
-   */
-  GST_INFO_OBJECT (camera, "starting video capture");
-
-  /* check if need to update video capture caps */
-  if (camera->video_capture_caps_update) {
-    reset_video_capture_caps (camera);
-  }
-
-  gst_camerabin_rewrite_tags (camera);
-
-  /* Pause the pipeline in order to distribute new clock in paused_to_playing */
-  /* Audio source needs to go to null to reset the ringbuffer */
-  if (vidbin->aud_src)
-    gst_element_set_state (vidbin->aud_src, GST_STATE_NULL);
-  state_ret = gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
-
-  if (state_ret != GST_STATE_CHANGE_FAILURE) {
-    GstClock *clock = gst_element_get_clock (GST_ELEMENT (camera));
-
-    g_mutex_lock (camera->capture_mutex);
-    camera->capturing = TRUE;
-    g_mutex_unlock (camera->capture_mutex);
-    gst_element_set_locked_state (camera->vidbin, FALSE);
-    /* ensure elements activated before feeding data into it */
-    state_ret = gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
-    g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
-        "active-pad", camera->pad_src_vid, NULL);
-
-    /* Enable video mode in v4l2camsrc */
-    if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
-            "capture-mode")) {
-      g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 2, NULL);
-    }
-
-    /* Clock might be distributed as NULL to audiosrc, messing timestamping */
-    if (vidbin->aud_src)
-      gst_element_set_clock (vidbin->aud_src, clock);
-    gst_object_unref (clock);
-
-    /* videobin will not go to playing if file is not writable */
-    if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-        GST_STATE_CHANGE_FAILURE) {
-      GST_ELEMENT_ERROR (camera, CORE, STATE_CHANGE,
-          ("Setting videobin to PLAYING failed"), (NULL));
-      gst_element_set_state (camera->vidbin, GST_STATE_NULL);
-      gst_element_set_locked_state (camera->vidbin, TRUE);
-      g_mutex_lock (camera->capture_mutex);
-      camera->capturing = FALSE;
-      g_mutex_unlock (camera->capture_mutex);
-      gst_camerabin_reset_to_view_finder (camera);
-    } else {
-      gst_element_set_locked_state (camera->vidbin, TRUE);
-    }
-  } else {
-    GST_WARNING_OBJECT (camera, "videobin state change failed");
-    gst_element_set_state (camera->vidbin, GST_STATE_NULL);
-    gst_camerabin_reset_to_view_finder (camera);
-
-    CAMERABIN_PROCESSING_DEC (camera);
-  }
-}
-
-/*
- * gst_camerabin_send_video_eos:
- * @camera: camerabin object
- *
- * Generate and send eos event to video bin in order to
- * finish recording properly.
- */
-static void
-gst_camerabin_send_video_eos (GstCameraBin * camera)
-{
-  GstPad *videopad;
-
-  g_return_if_fail (camera != NULL);
-
-  if (!camera->eos_handled) {
-    /* Send eos event to video bin */
-    GST_INFO_OBJECT (camera, "sending eos to videobin");
-    videopad = gst_element_get_static_pad (camera->vidbin, "sink");
-    gst_pad_send_event (videopad, gst_event_new_eos ());
-    gst_object_unref (videopad);
-    /* Block viewfinder after capturing if requested by application */
-    GST_OBJECT_LOCK (camera);
-    if (camera->block_viewfinder_trigger) {
-      gst_pad_set_blocked_async (camera->pad_src_view, TRUE,
-          (GstPadBlockCallback) camerabin_pad_blocked, camera);
-    }
-    GST_OBJECT_UNLOCK (camera);
-    camera->eos_handled = TRUE;
-  } else {
-    GST_INFO_OBJECT (camera, "dropping duplicate EOS");
-  }
-}
-
-/*
- * camerabin_pad_blocked:
- * @pad: pad to block/unblock
- * @blocked: TRUE to block, FALSE to unblock
- * @u_data: camera bin object
- *
- * Callback function for blocking a pad.
- */
-static void
-camerabin_pad_blocked (GstPad * pad, gboolean blocked, gpointer user_data)
-{
-  GstCameraBin *camera;
-
-  camera = (GstCameraBin *) user_data;
-
-  GST_DEBUG_OBJECT (camera, "%s %s:%s",
-      blocked ? "blocking" : "unblocking", GST_DEBUG_PAD_NAME (pad));
-}
-
-/*
- * gst_camerabin_send_preview:
- * @camera: camerabin object
- * @buffer: received buffer
- *
- * Convert given buffer to desired preview format and send is as a #GstMessage
- * to application.
- *
- * Returns: TRUE always
- */
-static gboolean
-gst_camerabin_send_preview (GstCameraBin * camera, GstBuffer * buffer)
-{
-  GstCameraBinPreviewPipelineData *data;
-  GstBuffer *prev = NULL;
-  GstStructure *s;
-  GstMessage *msg;
-  gboolean ret = FALSE;
-
-  GST_DEBUG_OBJECT (camera, "creating preview");
-
-  data = (camera->mode == MODE_IMAGE) ?
-      camera->preview_pipeline : camera->video_preview_pipeline;
-  prev = gst_camerabin_preview_convert (data, buffer);
-
-  GST_DEBUG_OBJECT (camera, "preview created: %p", prev);
-
-  if (prev) {
-    s = gst_structure_new (PREVIEW_MESSAGE_NAME,
-        "buffer", GST_TYPE_BUFFER, prev, NULL);
-    gst_buffer_unref (prev);
-
-    msg = gst_message_new_element (GST_OBJECT (camera), s);
-
-    GST_DEBUG_OBJECT (camera, "sending message with preview image");
-
-    if (gst_element_post_message (GST_ELEMENT (camera), msg) == FALSE) {
-      GST_WARNING_OBJECT (camera,
-          "This element has no bus, therefore no message sent!");
-    }
-    ret = TRUE;
-  }
-
-  return ret;
-}
-
-/*
- * gst_camerabin_have_img_buffer:
- * @pad: output-selector src pad leading to image bin
- * @buffer: still image frame
- * @u_data: camera bin object
- *
- * Buffer probe called before sending each buffer to image queue.
- * Generates and sends preview image as gst message if requested.
- */
-static gboolean
-gst_camerabin_have_img_buffer (GstPad * pad, GstMiniObject * obj,
-    gpointer u_data)
-{
-  GstCameraBin *camera = (GstCameraBin *) u_data;
-
-  if (GST_IS_BUFFER (obj)) {
-    GstBuffer *buffer = GST_BUFFER_CAST (obj);
-    GstStructure *fn_ev_struct = NULL;
-    GstPad *os_sink = NULL;
-
-    GST_LOG ("got buffer %p with size %d", buffer, GST_BUFFER_SIZE (buffer));
-
-    if (camera->preview_caps) {
-      gst_camerabin_send_preview (camera, buffer);
-    }
-
-    /* Image filename should be set by now */
-    if (g_str_equal (camera->filename->str, "")) {
-      GST_DEBUG_OBJECT (camera, "filename not set, dropping buffer");
-      CAMERABIN_PROCESSING_DEC_UNLOCKED (camera);
-      goto done;
-    }
-
-    gst_camerabin_rewrite_tags (camera);
-
-    /* Send a custom event which tells the filename to image queue */
-    /* NOTE: This needs to be THE FIRST event to be sent to queue for
-       every image. It triggers imgbin state change to PLAYING. */
-    fn_ev_struct = gst_structure_new ("img-filename",
-        "filename", G_TYPE_STRING, camera->filename->str, NULL);
-    GST_DEBUG_OBJECT (camera, "sending filename event to image queue");
-    gst_camerabin_send_img_queue_custom_event (camera, fn_ev_struct);
-
-    /* Add buffer probe to outputselector's sink pad. It sends
-       EOS event to image queue. */
-    os_sink = gst_element_get_static_pad (camera->src_out_sel, "sink");
-    camera->image_captured_id = gst_pad_add_buffer_probe (os_sink,
-        G_CALLBACK (gst_camerabin_have_src_buffer), camera);
-    gst_object_unref (os_sink);
-
-  done:
-
-    /* HACK: v4l2camsrc changes to view finder resolution automatically
-       after one captured still image */
-    gst_camerabin_finish_image_capture (camera);
-
-    GST_DEBUG_OBJECT (camera, "image captured, switching to viewfinder");
-
-    gst_camerabin_reset_to_view_finder (camera);
-
-    GST_DEBUG_OBJECT (camera, "switched back to viewfinder");
-
-    return TRUE;
-  } else if (GST_IS_EVENT (obj)) {
-    GstEvent *event = GST_EVENT_CAST (obj);
-
-    GST_DEBUG_OBJECT (camera, "Received event in image pipeline");
-
-    /* forward tag events to preview pipeline */
-    if (camera->preview_caps && GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
-      GstCameraBinPreviewPipelineData *data;
-
-      data = (camera->mode == MODE_IMAGE) ?
-          camera->preview_pipeline : camera->video_preview_pipeline;
-      gst_camerabin_preview_send_event (data, gst_event_ref (event));
-    }
-  }
-
-  return TRUE;
-}
-
-/*
- * gst_camerabin_have_vid_buffer:
- * @pad: output-selector src pad leading to video bin
- * @buffer: buffer pushed to the pad
- * @u_data: camerabin object
- *
- * Buffer probe for src pad leading to video bin.
- * Sends eos event to video bin if stop requested and drops
- * all buffers after this.
- */
-static gboolean
-gst_camerabin_have_vid_buffer (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data)
-{
-  GstCameraBin *camera = (GstCameraBin *) u_data;
-  gboolean ret = TRUE;
-  GST_LOG ("got video buffer %p with size %d",
-      buffer, GST_BUFFER_SIZE (buffer));
-
-  if (!camera->video_preview_buffer && camera->video_preview_caps) {
-    GST_DEBUG ("storing video preview %p", buffer);
-    camera->video_preview_buffer = gst_buffer_copy (buffer);
-  }
-
-  if (G_UNLIKELY (camera->stop_requested)) {
-    gst_camerabin_send_video_eos (camera);
-    ret = FALSE;                /* Drop buffer */
-  }
-
-  return ret;
-}
-
-/*
- * gst_camerabin_have_src_buffer:
- * @pad: output-selector sink pad which receives frames from video source
- * @buffer: buffer pushed to the pad
- * @u_data: camerabin object
- *
- * Buffer probe for sink pad. It sends custom eos event to image queue and
- * notifies application by sending a "image-captured" message to GstBus.
- * This probe is installed after image has been captured and it disconnects
- * itself after EOS has been sent.
- */
-static gboolean
-gst_camerabin_have_src_buffer (GstPad * pad, GstBuffer * buffer,
-    gpointer u_data)
-{
-  GstCameraBin *camera = (GstCameraBin *) u_data;
-  GstMessage *msg;
-
-  GST_LOG_OBJECT (camera, "got image buffer %p with size %d",
-      buffer, GST_BUFFER_SIZE (buffer));
-
-  g_mutex_lock (camera->capture_mutex);
-  camera->capturing = FALSE;
-  g_cond_signal (camera->cond);
-  g_mutex_unlock (camera->capture_mutex);
-
-  msg = gst_message_new_element (GST_OBJECT (camera),
-      gst_structure_new (IMG_CAPTURED_MESSAGE_NAME, NULL));
-
-  GST_DEBUG_OBJECT (camera, "sending 'image captured' message");
-
-  if (gst_element_post_message (GST_ELEMENT (camera), msg) == FALSE) {
-    GST_WARNING_OBJECT (camera,
-        "This element has no bus, therefore no message sent!");
-  }
-
-  /* We can't send real EOS event, since it would switch the image queue
-     into "draining mode". Therefore we send our own custom eos and
-     catch & drop it later in queue's srcpad data probe */
-  GST_DEBUG_OBJECT (camera, "sending img-eos to image queue");
-  gst_camerabin_send_img_queue_custom_event (camera,
-      gst_structure_new ("img-eos", NULL));
-
-  /* Prevent video source from pushing frames until we want them */
-  GST_OBJECT_LOCK (camera);
-  if (camera->block_viewfinder_trigger) {
-    gst_pad_set_blocked_async (camera->pad_src_view, TRUE,
-        (GstPadBlockCallback) camerabin_pad_blocked, camera);
-  }
-  GST_OBJECT_UNLOCK (camera);
-
-  /* our work is done, disconnect */
-  gst_pad_remove_buffer_probe (pad, camera->image_captured_id);
-
-  /* Image captured, notify that preparing a new capture is possible */
-  g_object_notify (G_OBJECT (camera), "ready-for-capture");
-
-  return TRUE;
-}
-
-/*
- * gst_camerabin_have_queue_data:
- * @pad: image queue src pad leading to image bin
- * @mini_obj: buffer or event pushed to the pad
- * @u_data: camerabin object
- *
- * Buffer probe for image queue src pad leading to image bin. It sets imgbin
- * into PLAYING mode when image buffer is passed to it. This probe also
- * monitors our internal custom events and handles them accordingly.
- */
-static gboolean
-gst_camerabin_have_queue_data (GstPad * pad, GstMiniObject * mini_obj,
-    gpointer u_data)
-{
-  GstCameraBin *camera = (GstCameraBin *) u_data;
-  gboolean ret = TRUE;
-
-  if (GST_IS_BUFFER (mini_obj)) {
-    GstEvent *tagevent;
-
-    GST_LOG_OBJECT (camera, "queue sending image buffer to imagebin");
-
-    tagevent = gst_event_new_tag (gst_tag_list_copy (camera->event_tags));
-    gst_element_send_event (camera->imgbin, tagevent);
-    gst_tag_list_free (camera->event_tags);
-    camera->event_tags = gst_tag_list_new ();
-  } else if (GST_IS_EVENT (mini_obj)) {
-    const GstStructure *evs;
-    GstEvent *event;
-
-    event = GST_EVENT_CAST (mini_obj);
-    evs = gst_event_get_structure (event);
-
-    GST_LOG_OBJECT (camera, "got event %s", GST_EVENT_TYPE_NAME (event));
-
-    if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
-      GstTagList *tlist;
-
-      GST_DEBUG_OBJECT (camera, "queue sending taglist to image pipeline");
-      gst_event_parse_tag (event, &tlist);
-      gst_tag_list_insert (camera->event_tags, tlist, GST_TAG_MERGE_REPLACE);
-      ret = FALSE;
-    } else if (evs && gst_structure_has_name (evs, "img-filename")) {
-      const gchar *fname;
-
-      GST_DEBUG_OBJECT (camera, "queue setting image filename to imagebin");
-      fname = gst_structure_get_string (evs, "filename");
-      g_object_set (G_OBJECT (camera->imgbin), "filename", fname, NULL);
-
-      /* imgbin fails to start unless the filename is set or file
-         cannot be written */
-      if (gst_element_set_state (camera->imgbin, GST_STATE_PLAYING) ==
-          GST_STATE_CHANGE_FAILURE) {
-        GST_ELEMENT_ERROR (camera, CORE, STATE_CHANGE,
-            ("Setting imagebin to PLAYING failed"), (NULL));
-        gst_element_set_state (camera->imgbin, GST_STATE_NULL);
-      } else {
-        GST_LOG_OBJECT (camera, "Set imagebin to PLAYING");
-      }
-
-      ret = FALSE;
-    } else if (evs && gst_structure_has_name (evs, "img-eos")) {
-      GST_DEBUG_OBJECT (camera, "queue sending EOS to image pipeline");
-      gst_pad_set_blocked_async (camera->pad_src_queue, TRUE,
-          (GstPadBlockCallback) camerabin_pad_blocked, camera);
-      gst_element_send_event (camera->imgbin, gst_event_new_eos ());
-      ret = FALSE;
-    }
-  }
-
-  return ret;
-}
-
-/*
- * gst_camerabin_reset_to_view_finder:
- * @camera: camerabin object
- *
- * Stop capturing and set camerabin to view finder mode.
- * Reset capture counters and flags.
- */
-static void
-gst_camerabin_reset_to_view_finder (GstCameraBin * camera)
-{
-  GstStateChangeReturn state_ret;
-  GST_DEBUG_OBJECT (camera, "resetting");
-
-  if (camera->src_out_sel) {
-    /* Set selector to forward data to view finder */
-    g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
-        "active-pad", camera->pad_src_view, NULL);
-  }
-
-  /* Set video bin to READY state */
-  if (camera->active_bin == camera->vidbin) {
-    state_ret = gst_element_set_state (camera->active_bin, GST_STATE_READY);
-    if (state_ret == GST_STATE_CHANGE_FAILURE) {
-      GST_WARNING_OBJECT (camera, "state change failed");
-      gst_element_set_state (camera->active_bin, GST_STATE_NULL);
-      camera->active_bin = NULL;
-    }
-  }
-
-  /* Reset counters and flags */
-  camera->stop_requested = FALSE;
-  camera->paused = FALSE;
-  camera->eos_handled = FALSE;
-  if (camera->video_preview_buffer) {
-    gst_buffer_unref (camera->video_preview_buffer);
-    camera->video_preview_buffer = NULL;
-  }
-
-  /* Enable view finder mode in v4l2camsrc */
-  if (camera->src_vid_src &&
-      g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
-          "capture-mode")) {
-    g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 0, NULL);
-  }
-
-  GST_DEBUG_OBJECT (camera, "reset done");
-}
-
-/*
- * gst_camerabin_do_stop:
- * @camera: camerabin object
- *
- * Raise flag to indicate to image and video bin capture stop.
- * Stopping paused video recording handled as a special case.
- * Wait for ongoing capturing to finish.
- */
-static void
-gst_camerabin_do_stop (GstCameraBin * camera)
-{
-  gboolean video_preview_sent = FALSE;
-  g_mutex_lock (camera->capture_mutex);
-  if (camera->capturing) {
-    GST_DEBUG_OBJECT (camera, "mark stop");
-    camera->stop_requested = TRUE;
-
-    /* Post preview image ASAP and don't wait that video recording
-       finishes as it may take time. */
-    if (camera->video_preview_buffer) {
-      gst_camerabin_send_preview (camera, camera->video_preview_buffer);
-      video_preview_sent = TRUE;
-    }
-
-    /* Take special care when stopping paused video capture */
-    if ((camera->active_bin == camera->vidbin) && camera->paused) {
-      /* Send eos event to video bin before setting it to playing */
-      gst_camerabin_send_video_eos (camera);
-      /* We must change to playing now in order to get video bin eos events
-         and buffered data through and finish recording properly */
-      gst_element_set_state (GST_ELEMENT (camera->vidbin), GST_STATE_PLAYING);
-      camera->paused = FALSE;
-    }
-
-    GST_DEBUG_OBJECT (camera, "waiting for capturing to finish");
-    g_cond_wait (camera->cond, camera->capture_mutex);
-    GST_DEBUG_OBJECT (camera, "capturing finished");
-
-    if (camera->video_preview_buffer) {
-      /* Double check that preview image has been sent. This is useful
-         in a corner case where capture-stop is issued immediately after
-         start before a single video buffer is actually recorded */
-      if (video_preview_sent == FALSE) {
-        gst_camerabin_send_preview (camera, camera->video_preview_buffer);
-      }
-    }
-  }
-  g_mutex_unlock (camera->capture_mutex);
-}
-
-/*
- * gst_camerabin_default_signal_img_done:
- * @camera: camerabin object
- * @fname: filename of the recently saved image
- *
- * Default handler for #GstCameraBin::image-done signal,
- * stops always capture.
- *
- * Returns: FALSE always
- */
-static gboolean
-gst_camerabin_default_signal_img_done (GstCameraBin * camera,
-    const gchar * fname)
-{
-  return FALSE;
-}
-
-/*
- * gst_camerabin_set_allowed_framerate:
- * @camera: camerabin object
- * @filter_caps: update allowed framerate to these caps
- *
- * Find allowed frame rate from video source that matches with
- * resolution in @filter_caps. Set found frame rate to @filter_caps.
- */
-static void
-gst_camerabin_set_allowed_framerate (GstCameraBin * camera,
-    GstCaps * filter_caps)
-{
-  GstStructure *structure;
-  GstCaps *allowed_caps = NULL, *intersect = NULL, *tmp_caps = NULL;
-  const GValue *framerate = NULL;
-  guint caps_size, i;
-  guint32 format = 0;
-
-  GST_INFO_OBJECT (camera, "filter caps:%" GST_PTR_FORMAT, filter_caps);
-
-  structure = gst_structure_copy (gst_caps_get_structure (filter_caps, 0));
-
-  /* Set fourcc format according to current videosrc format */
-  format = get_srcpad_current_format (camera->src_vid_src);
-  if (format) {
-    GST_DEBUG_OBJECT (camera,
-        "using format %" GST_FOURCC_FORMAT " for matching",
-        GST_FOURCC_ARGS (format));
-    gst_structure_set (structure, "format", GST_TYPE_FOURCC, format, NULL);
-  } else {
-    GST_DEBUG_OBJECT (camera, "not matching against fourcc format");
-    gst_structure_remove_field (structure, "format");
-  }
-
-  tmp_caps = gst_caps_new_full (structure, NULL);
-
-  /* Get supported caps from video src that matches with new filter caps */
-  allowed_caps = gst_camerabin_get_allowed_input_caps (camera);
-  intersect = gst_caps_intersect (allowed_caps, tmp_caps);
-  GST_INFO_OBJECT (camera, "intersect caps:%" GST_PTR_FORMAT, intersect);
-
-  /* Find the best framerate from the caps */
-  caps_size = gst_caps_get_size (intersect);
-  for (i = 0; i < caps_size; i++) {
-    structure = gst_caps_get_structure (intersect, i);
-    framerate =
-        gst_camerabin_find_better_framerate (camera, structure, framerate);
-  }
-
-  /* Set found frame rate to original caps */
-  if (GST_VALUE_HOLDS_FRACTION (framerate)) {
-    gst_caps_set_simple (filter_caps,
-        "framerate", GST_TYPE_FRACTION,
-        gst_value_get_fraction_numerator (framerate),
-        gst_value_get_fraction_denominator (framerate), NULL);
-  }
-
-  /* Unref helper caps */
-  if (allowed_caps) {
-    gst_caps_unref (allowed_caps);
-  }
-  if (intersect) {
-    gst_caps_unref (intersect);
-  }
-  if (tmp_caps) {
-    gst_caps_unref (tmp_caps);
-  }
-}
-
-
-/**
- * get_srcpad_current_format:
- * @element: element to get the format from
- *
- * Helper function to get the negotiated fourcc
- * format from @element src pad.
- *
- * Returns: negotiated format (fourcc), 0 if not found
- */
-static guint32
-get_srcpad_current_format (GstElement * element)
-{
-  GstPad *srcpad = NULL;
-  GstCaps *srccaps = NULL;
-  GstStructure *structure;
-  guint32 format = 0;
-
-  g_return_val_if_fail (element != NULL, 0);
-
-  if ((srcpad = gst_element_get_static_pad (element, "src")) == NULL) {
-    goto no_pad;
-  }
-
-  if ((srccaps = gst_pad_get_negotiated_caps (srcpad)) == NULL) {
-    goto no_caps;
-  }
-
-  GST_LOG ("negotiated caps %" GST_PTR_FORMAT, srccaps);
-
-  structure = gst_caps_get_structure (srccaps, 0);
-  if (gst_structure_has_field (structure, "format")) {
-    gst_structure_get_fourcc (structure, "format", &format);
-  }
-
-  gst_caps_unref (srccaps);
-no_caps:
-  gst_object_unref (srcpad);
-no_pad:
-  GST_DEBUG ("current format for %" GST_PTR_FORMAT ": %" GST_FOURCC_FORMAT,
-      element, GST_FOURCC_ARGS (format));
-  return format;
-}
-
-/*
- * gst_camerabin_find_better_framerate:
- * @camera: camerabin 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
- */
-static const GValue *
-gst_camerabin_find_better_framerate (GstCameraBin * camera, GstStructure * st,
-    const GValue * orig_framerate)
-{
-  const GValue *framerate = NULL;
-  guint i, i_best, list_size;
-  gint res, comparison;
-
-  if (camera->night_mode) {
-    GST_LOG_OBJECT (camera, "finding min framerate in %" GST_PTR_FORMAT, st);
-    comparison = GST_VALUE_LESS_THAN;
-  } else {
-    GST_LOG_OBJECT (camera, "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 (camera, "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 (camera, "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 (camera->night_mode) {
-        GST_LOG_OBJECT (camera, "getting min framerate from range");
-        framerate = gst_value_get_fraction_range_min (framerate);
-      } else {
-        GST_LOG_OBJECT (camera, "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 (camera, "original framerate was the best");
-      framerate = orig_framerate;
-    }
-  }
-
-  return framerate;
-}
-
-/*
- * gst_camerabin_update_aspect_filter:
- * @camera: camerabin object
- * @new_caps: new caps of next buffers arriving to view finder sink element
- *
- * Updates aspect ratio capsfilter to maintain aspect ratio, if we need to
- * scale frames for showing them in view finder.
- */
-static void
-gst_camerabin_update_aspect_filter (GstCameraBin * camera, GstCaps * new_caps)
-{
-  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
-    GstCaps *sink_caps, *ar_caps;
-    GstStructure *st;
-    gint in_w = 0, in_h = 0, sink_w = 0, sink_h = 0, target_w = 0, target_h = 0;
-    gdouble ratio_w, ratio_h;
-    GstPad *sink_pad;
-    const GValue *range;
-
-    sink_pad = gst_element_get_static_pad (camera->view_sink, "sink");
-
-    if (sink_pad) {
-      sink_caps = gst_pad_get_caps (sink_pad);
-      gst_object_unref (sink_pad);
-      if (sink_caps) {
-        if (!gst_caps_is_any (sink_caps)) {
-          GST_DEBUG_OBJECT (camera, "sink element caps %" GST_PTR_FORMAT,
-              sink_caps);
-          /* Get maximum resolution that view finder sink accepts */
-          st = gst_caps_get_structure (sink_caps, 0);
-          if (gst_structure_has_field_typed (st, "width", GST_TYPE_INT_RANGE)) {
-            range = gst_structure_get_value (st, "width");
-            sink_w = gst_value_get_int_range_max (range);
-          }
-          if (gst_structure_has_field_typed (st, "height", GST_TYPE_INT_RANGE)) {
-            range = gst_structure_get_value (st, "height");
-            sink_h = gst_value_get_int_range_max (range);
-          }
-          GST_DEBUG_OBJECT (camera, "sink element accepts max %dx%d", sink_w,
-              sink_h);
-
-          /* Get incoming frames' resolution */
-          if (sink_h && sink_w) {
-            st = gst_caps_get_structure (new_caps, 0);
-            gst_structure_get_int (st, "width", &in_w);
-            gst_structure_get_int (st, "height", &in_h);
-            GST_DEBUG_OBJECT (camera, "new caps with %dx%d", in_w, in_h);
-          }
-        }
-        gst_caps_unref (sink_caps);
-      }
-    }
-
-    /* If we get bigger frames than view finder sink accepts, then we scale.
-       If we scale we need to adjust aspect ratio capsfilter caps in order
-       to maintain aspect ratio while scaling. */
-    if (in_w && in_h && (in_w > sink_w || in_h > sink_h)) {
-      ratio_w = (gdouble) sink_w / in_w;
-      ratio_h = (gdouble) sink_h / in_h;
-
-      if (ratio_w < ratio_h) {
-        target_w = sink_w;
-        target_h = (gint) (ratio_w * in_h);
-      } else {
-        target_w = (gint) (ratio_h * in_w);
-        target_h = sink_h;
-      }
-
-      GST_DEBUG_OBJECT (camera, "setting %dx%d filter to maintain aspect ratio",
-          target_w, target_h);
-      ar_caps = gst_caps_copy (new_caps);
-      gst_caps_set_simple (ar_caps, "width", G_TYPE_INT, target_w, "height",
-          G_TYPE_INT, target_h, NULL);
-    } else {
-      GST_DEBUG_OBJECT (camera, "no scaling");
-      ar_caps = new_caps;
-    }
-
-    GST_DEBUG_OBJECT (camera, "aspect ratio filter caps %" GST_PTR_FORMAT,
-        ar_caps);
-    g_object_set (G_OBJECT (camera->aspect_filter), "caps", ar_caps, NULL);
-    if (ar_caps != new_caps)
-      gst_caps_unref (ar_caps);
-  }
-}
-
-/*
- * gst_camerabin_finish_image_capture:
- * @camera: camerabin object
- *
- * Perform finishing operations after image capture is done and
- * returning back to view finder mode.
- */
-static void
-gst_camerabin_finish_image_capture (GstCameraBin * camera)
-{
-  if (camera->image_capture_caps) {
-    /* If we used specific caps for image capture we need to 
-       restore the caps and zoom/crop for view finder mode */
-    if (camera->src_zoom_crop) {
-      GST_DEBUG_OBJECT (camera, "resetting crop in camerabin");
-      g_object_set (camera->src_zoom_crop, "left", 0, "right", 0,
-          "top", 0, "bottom", 0, NULL);
-    }
-    camera->base_crop_left = 0;
-    camera->base_crop_right = 0;
-    camera->base_crop_top = 0;
-    camera->base_crop_bottom = 0;
-    gst_camerabin_set_capsfilter_caps (camera, camera->view_finder_caps);
-  }
-}
-
-/*
- * gst_camerabin_adapt_image_capture:
- * @camera: camerabin object
- * @in_caps: caps object that describes incoming image format
- *
- * Adjust capsfilters and crop according image capture caps if necessary.
- * The captured image format from video source might be different from
- * what application requested, so we can try to fix that in camerabin.
- *
- */
-static void
-gst_camerabin_adapt_image_capture (GstCameraBin * camera, GstCaps * in_caps)
-{
-  GstStructure *in_st, *new_st, *req_st;
-  gint in_width = 0, in_height = 0, req_width = 0, req_height = 0, crop = 0;
-  gdouble ratio_w, ratio_h;
-  GstCaps *filter_caps = NULL;
-
-  GST_LOG_OBJECT (camera, "in caps: %" GST_PTR_FORMAT, in_caps);
-  GST_LOG_OBJECT (camera, "requested caps: %" GST_PTR_FORMAT,
-      camera->image_capture_caps);
-
-  in_st = gst_caps_get_structure (in_caps, 0);
-  gst_structure_get_int (in_st, "width", &in_width);
-  gst_structure_get_int (in_st, "height", &in_height);
-
-  req_st = gst_caps_get_structure (camera->image_capture_caps, 0);
-  gst_structure_get_int (req_st, "width", &req_width);
-  gst_structure_get_int (req_st, "height", &req_height);
-
-  GST_INFO_OBJECT (camera, "we requested %dx%d, and got %dx%d", req_width,
-      req_height, in_width, in_height);
-
-  new_st = gst_structure_copy (req_st);
-  /* If new fields have been added, we need to copy them */
-  gst_structure_foreach (in_st, copy_missing_fields, new_st);
-
-  if (!(camera->flags & GST_CAMERABIN_FLAG_SOURCE_RESIZE)) {
-    GST_DEBUG_OBJECT (camera,
-        "source-resize flag disabled, unable to adapt resolution");
-    gst_structure_set (new_st, "width", G_TYPE_INT, in_width, "height",
-        G_TYPE_INT, in_height, NULL);
-  }
-
-  GST_LOG_OBJECT (camera, "new image capture caps: %" GST_PTR_FORMAT, new_st);
-
-  /* Crop if requested aspect ratio differs from incoming frame aspect ratio */
-  if (camera->src_zoom_crop) {
-
-    ratio_w = (gdouble) in_width / req_width;
-    ratio_h = (gdouble) in_height / req_height;
-
-    if (ratio_w < ratio_h) {
-      crop = in_height - (req_height * ratio_w);
-      camera->base_crop_top = crop / 2;
-      camera->base_crop_bottom = crop / 2;
-    } else {
-      crop = in_width - (req_width * ratio_h);
-      camera->base_crop_left = crop / 2;
-      camera->base_crop_right += crop / 2;
-    }
-
-    GST_INFO_OBJECT (camera,
-        "setting base crop: left:%d, right:%d, top:%d, bottom:%d",
-        camera->base_crop_left, camera->base_crop_right, camera->base_crop_top,
-        camera->base_crop_bottom);
-    g_object_set (G_OBJECT (camera->src_zoom_crop), "top",
-        camera->base_crop_top, "bottom", camera->base_crop_bottom, "left",
-        camera->base_crop_left, "right", camera->base_crop_right, NULL);
-  }
-
-  /* Update capsfilters */
-  gst_caps_replace (&camera->image_capture_caps,
-      gst_caps_new_full (new_st, NULL));
-  gst_camerabin_set_capsfilter_caps (camera, camera->image_capture_caps);
-
-  /* Adjust the capsfilter before crop and videoscale elements if necessary */
-  if (in_width == camera->width && in_height == camera->height) {
-    GST_DEBUG_OBJECT (camera, "no adaptation with resolution needed");
-  } else {
-    GST_DEBUG_OBJECT (camera,
-        "changing %" GST_PTR_FORMAT " from %dx%d to %dx%d", camera->src_filter,
-        camera->width, camera->height, in_width, in_height);
-    /* Apply the width and height to filter caps */
-    g_object_get (G_OBJECT (camera->src_filter), "caps", &filter_caps, NULL);
-    filter_caps = gst_caps_make_writable (filter_caps);
-    gst_caps_set_simple (filter_caps, "width", G_TYPE_INT, in_width, "height",
-        G_TYPE_INT, in_height, NULL);
-    g_object_set (G_OBJECT (camera->src_filter), "caps", filter_caps, NULL);
-    gst_caps_unref (filter_caps);
-  }
-}
-
-/*
- * gst_camerabin_handle_scene_mode:
- * @camera:       camerabin object
- * scene_mode:    scene mode
- *
- * Handle scene mode if night mode was selected/deselected in video-source
- *
- */
-static void
-gst_camerabin_handle_scene_mode (GstCameraBin * camera, GstSceneMode scene_mode)
-{
-  if (scene_mode == GST_PHOTOGRAPHY_SCENE_MODE_NIGHT) {
-    if (!camera->night_mode) {
-      GST_DEBUG ("enabling night mode, lowering fps");
-      /* Make camerabin select the lowest allowed frame rate */
-      camera->night_mode = TRUE;
-      /* Remember frame rate before setting night mode */
-      camera->pre_night_fps_n = camera->fps_n;
-      camera->pre_night_fps_d = camera->fps_d;
-      do_set_video_resolution_fps (camera, camera->width, camera->height, 0, 1);
-    } else {
-      GST_DEBUG ("night mode already enabled");
-    }
-  } else {
-    if (camera->night_mode) {
-      GST_DEBUG ("disabling night mode, restoring fps to %d/%d",
-          camera->pre_night_fps_n, camera->pre_night_fps_d);
-      camera->night_mode = FALSE;
-      do_set_video_resolution_fps (camera, camera->width, camera->height,
-          camera->pre_night_fps_n, camera->pre_night_fps_d);
-    }
-  }
-}
-
-/*
- * gst_camerabin_scene_mode_notify_cb:
- * @video_source: videosrc object
- * @pspec:        GParamSpec for property
- * @user_data:    camerabin object
- *
- * Update framerate if scene mode was updated in video-source
- *
- */
-static void
-gst_camerabin_scene_mode_notify_cb (GObject * video_source, GParamSpec * pspec,
-    gpointer user_data)
-{
-  GstSceneMode scene_mode;
-  const gchar *name = g_param_spec_get_name (pspec);
-  GstCameraBin *camera = GST_CAMERABIN (user_data);
-
-  g_object_get (video_source, name, &scene_mode, NULL);
-  gst_camerabin_handle_scene_mode (camera, scene_mode);
-}
-
- /*
-  * gst_camerabin_zoom_notify_cb:
-  * @video_source: videosrc object
-  * @pspec:        GParamSpec for property
-  * @user_data:    camerabin object
-  *
-  * Update zoom value if video-source updated its zoom
-  *
-  */
-static void
-gst_camerabin_zoom_notify_cb (GObject * video_source, GParamSpec * pspec,
-    gpointer user_data)
-{
-  gfloat zoom;
-  const gchar *name = g_param_spec_get_name (pspec);
-  GstCameraBin *camera = GST_CAMERABIN (user_data);
-
-  g_object_get (video_source, name, &zoom, NULL);
-
-  camera->zoom = zoom;
-  g_object_notify (G_OBJECT (camera), "zoom");
-}
-
-/*
- * gst_camerabin_monitor_video_source_properties:
- * @camera: camerabin object
- *
- * Monitor notify signals from video source photography interface
- * property scene mode.
- *
- */
-static void
-gst_camerabin_monitor_video_source_properties (GstCameraBin * camera)
-{
-  GST_DEBUG_OBJECT (camera, "checking for photography interface support");
-  if (GST_IS_ELEMENT (camera->src_vid_src) &&
-      gst_element_implements_interface (camera->src_vid_src,
-          GST_TYPE_PHOTOGRAPHY)) {
-    gint scene_mode;
-    GST_DEBUG_OBJECT (camera,
-        "connecting to %" GST_PTR_FORMAT " - notify::scene-mode",
-        camera->src_vid_src);
-    g_signal_connect (G_OBJECT (camera->src_vid_src), "notify::scene-mode",
-        (GCallback) gst_camerabin_scene_mode_notify_cb, camera);
-    g_object_get (G_OBJECT (camera->src_vid_src), "scene-mode", &scene_mode,
-        NULL);
-    camera->night_mode = scene_mode == GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
-
-    GST_DEBUG_OBJECT (camera,
-        "connecting to %" GST_PTR_FORMAT " - notify::zoom",
-        camera->src_vid_src);
-    g_signal_connect (G_OBJECT (camera->src_vid_src), "notify::zoom",
-        (GCallback) gst_camerabin_zoom_notify_cb, camera);
-  }
-}
-
-/*
- * gst_camerabin_configure_format:
- * @camera: camerabin object
- * @caps: caps describing new format
- *
- * Configure internal video format for camerabin.
- *
- */
-static void
-gst_camerabin_configure_format (GstCameraBin * camera, GstCaps * caps)
-{
-  GstStructure *st;
-
-  st = gst_caps_get_structure (caps, 0);
-
-  gst_structure_get_int (st, "width", &camera->width);
-  gst_structure_get_int (st, "height", &camera->height);
-
-  if (gst_structure_has_field_typed (st, "framerate", GST_TYPE_FRACTION)) {
-    gst_structure_get_fraction (st, "framerate", &camera->fps_n,
-        &camera->fps_d);
-  }
-}
-
-static gboolean
-copy_missing_fields (GQuark field_id, const GValue * value, gpointer user_data)
-{
-  GstStructure *st = (GstStructure *) user_data;
-  const GValue *val = gst_structure_id_get_value (st, field_id);
-
-  if (G_UNLIKELY (val == NULL)) {
-    gst_structure_id_set_value (st, field_id, value);
-  }
-
-  return TRUE;
-}
-
-/*
-* gst_camerabin_change_viewfinder_blocking:
-* @camera: camerabin object
-* @blocked: new viewfinder blocking state
-*
-* Handle viewfinder blocking parameter change.
-*/
-static void
-gst_camerabin_change_viewfinder_blocking (GstCameraBin * camera,
-    gboolean blocked)
-{
-  gboolean old_value;
-
-  GST_OBJECT_LOCK (camera);
-  old_value = camera->block_viewfinder_prop;
-  camera->block_viewfinder_prop = blocked;
-  if (blocked == FALSE) {
-    camera->block_viewfinder_trigger = FALSE;
-  }
-  GST_OBJECT_UNLOCK (camera);
-
-  /* "block_viewfinder_prop" is now set and will be checked after capture */
-  GST_DEBUG_OBJECT (camera, "viewfinder blocking set to %d, was %d",
-      camera->block_viewfinder_prop, old_value);
-
-  if (old_value == blocked)
-    return;
-
-  if (!blocked && camera->pad_src_view
-      && gst_pad_is_blocked (camera->pad_src_view)) {
-    /* Unblock viewfinder: the pad is blocked and we need to unblock it */
-    gst_pad_set_blocked_async (camera->pad_src_view, FALSE,
-        (GstPadBlockCallback) camerabin_pad_blocked, camera);
-  }
-}
-
-/*
- * GObject callback functions implementation
- */
-
-static void
-gst_camerabin_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  gst_tag_register_musicbrainz_tags ();
-
-  gst_element_class_set_details_simple (element_class, "Camera Bin",
-      "Generic/Bin/Camera",
-      "Handle lot of features present in DSC",
-      "Nokia Corporation <multimedia@maemo.org>, "
-      "Edgard Lima <edgard.lima@indt.org.br>");
-}
-
-static void
-gst_camerabin_class_init (GstCameraBinClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
-  GstBinClass *gstbin_class;
-
-  gobject_class = G_OBJECT_CLASS (klass);
-  gstelement_class = GST_ELEMENT_CLASS (klass);
-  gstbin_class = GST_BIN_CLASS (klass);
-
-  /* gobject */
-
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_camerabin_dispose);
-  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_camerabin_finalize);
-
-  gobject_class->set_property = gst_camerabin_set_property;
-  gobject_class->get_property = gst_camerabin_get_property;
-
-  /**
-   * GstCameraBin:filename:
-   *
-   * Set filename for the still image capturing or video capturing.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_FILENAME,
-      g_param_spec_string ("filename", "Filename",
-          "Filename of the image or video to save", "",
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:mode:
-   *
-   * Set the mode of operation: still image capturing or video recording.
-   * Setting the mode will create and destroy image bin or video bin elements
-   * according to the mode. You can set this property at any time, changing
-   * the mode will stop ongoing capture.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_MODE,
-      g_param_spec_enum ("mode", "Mode",
-          "The capture mode (still image capture or video recording)",
-          GST_TYPE_CAMERABIN_MODE, DEFAULT_MODE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:flags
-   *
-   * Control the behaviour of camerabin.
-   */
-  g_object_class_install_property (gobject_class, ARG_FLAGS,
-      g_param_spec_flags ("flags", "Flags", "Flags to control behaviour",
-          GST_TYPE_CAMERABIN_FLAGS, DEFAULT_FLAGS,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
-   * GstCameraBin:mute:
-   *
-   * Mute audio in video recording mode.
-   * Set this property only when #GstCameraBin is in READY, PAUSED or PLAYING.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_MUTE,
-      g_param_spec_boolean ("mute", "Mute",
-          "True to mute the recording. False to record with audio",
-          ARG_DEFAULT_MUTE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:zoom:
-   *
-   * Set up the zoom applied to the frames.
-   * Set this property only when #GstCameraBin is in READY, PAUSED or PLAYING.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_ZOOM,
-      g_param_spec_float ("zoom", "Zoom",
-          "The zoom. 1.0 for 1x, 2.0 for 2x and so on",
-          MIN_ZOOM, MAX_ZOOM, DEFAULT_ZOOM,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:image-post-processing:
-   *
-   * Set up an element to do image post processing.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-  g_object_class_install_property (gobject_class, ARG_IMAGE_POST,
-      g_param_spec_object ("image-post-processing",
-          "Image post processing element",
-          "Image Post-Processing GStreamer element (default is NULL)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:image-encoder:
-   *
-   * Set up an image encoder (for example, jpegenc or pngenc) element.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_IMAGE_ENC,
-      g_param_spec_object ("image-encoder", "Image encoder",
-          "Image encoder GStreamer element (default is jpegenc)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:image-formatter:
-   *
-   * Set up an image formatter (for example, jifmux) element.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_IMAGE_FORMATTER,
-      g_param_spec_object ("image-formatter", "Image formatter",
-          "Image formatter GStreamer element (default is jifmux)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:video-post-processing:
-   *
-   * Set up an element to do video post processing.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIDEO_POST,
-      g_param_spec_object ("video-post-processing",
-          "Video post processing element",
-          "Video post processing GStreamer element (default is NULL)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:video-encoder:
-   *
-   * Set up a video encoder element.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIDEO_ENC,
-      g_param_spec_object ("video-encoder", "Video encoder",
-          "Video encoder GStreamer element (default is theoraenc)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:audio-encoder:
-   *
-   * Set up an audio encoder element.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_AUDIO_ENC,
-      g_param_spec_object ("audio-encoder", "Audio encoder",
-          "Audio encoder GStreamer element (default is vorbisenc)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:video-muxer:
-   *
-   * Set up a video muxer element.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIDEO_MUX,
-      g_param_spec_object ("video-muxer", "Video muxer",
-          "Video muxer GStreamer element (default is oggmux)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:viewfinder-sink:
-   *
-   * Set up a sink element to render frames in view finder.
-   * By default "autovideosink" or DEFAULT_VIDEOSINK will be used.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VF_SINK,
-      g_param_spec_object ("viewfinder-sink", "Viewfinder sink",
-          "Viewfinder sink GStreamer element (NULL = default video sink)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:video-source:
-   *
-   * Set up a video source element.
-   * By default "autovideosrc" or DEFAULT_VIDEOSRC will be used.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIDEO_SRC,
-      g_param_spec_object ("video-source", "Video source element",
-          "Video source GStreamer element (NULL = default video src)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  /**
-   *  GstCameraBin:audio-source:
-   *
-   * Set up an audio source element.
-   * By default "autoaudiosrc" or DEFAULT_AUDIOSRC will be used.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_AUDIO_SRC,
-      g_param_spec_object ("audio-source", "Audio source element",
-          "Audio source GStreamer element (NULL = default audio src)",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   *  GstCameraBin:video-source-filter:
-   *
-   * Set up optional video filter element, all frames from video source
-   * will be processed by this element. e.g. An application might add
-   * image enhancers/parameter adjustment filters here to improve captured
-   * image/video results, or add analyzers to give feedback on capture
-   * the application.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIDEO_SOURCE_FILTER,
-      g_param_spec_object ("video-source-filter", "video source filter element",
-          "Optional video filter GStreamer element, filters all frames from"
-          "the video source", GST_TYPE_ELEMENT,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:video-source-caps:
-   *
-   * The allowed modes of operation of the video source. Have in mind that it
-   * doesn't mean #GstCameraBin can operate in all those modes,
-   * it depends also on the other elements in the pipeline. Remember to
-   * gst_caps_unref after using it.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_INPUT_CAPS,
-      g_param_spec_boxed ("video-source-caps", "Video source caps",
-          "The allowed modes of the video source operation",
-          GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:filter-caps:
-   *
-   * Caps applied to capsfilter element after videosrc [ ! ffmpegcsp ].
-   * You can use this e.g. to make sure video color format matches with
-   * encoders and other elements configured to camerabin and/or change
-   * resolution and frame rate.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_FILTER_CAPS,
-      g_param_spec_boxed ("filter-caps", "Filter caps",
-          "Filter video data coming from videosrc element",
-          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:preview-caps:
-   *
-   * If application wants to receive a preview image, it needs to 
-   * set this property to depict the desired image format caps. When
-   * this property is not set (NULL), message containing the preview
-   * image is not sent.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_PREVIEW_CAPS,
-      g_param_spec_boxed ("preview-caps", "Preview caps",
-          "Caps defining the preview image format",
-          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:preview-source-filter:
-   * Set up preview filter element, all frames coming from appsrc
-   * element will be processed by this element.
-   * Applications can use this to overlay text/images for preview frame, 
-   * for example.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_PREVIEW_SOURCE_FILTER,
-      g_param_spec_object ("preview-source-filter",
-          "preview source filter element",
-          "Optional preview source filter GStreamer element",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:viewfinder-filter:
-   * Set up viewfinder filter element, all frames going to viewfinder sink
-   * element will be processed by this element.
-   * Applications can use this to overlay text/images in the screen, or
-   * plug facetracking algorithms, for example.
-   * This property can only be set while #GstCameraBin is in NULL state.
-   * The ownership of the element will be taken by #GstCameraBin.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_VIEWFINDER_FILTER,
-      g_param_spec_object ("viewfinder-filter", "viewfinder filter element",
-          "viewfinder filter GStreamer element",
-          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:block-after-capture:
-   *
-   * Block viewfinder after capture.
-   * If it is TRUE when 'capture-start' is issued, camerabin will prepare to
-   * block and freeze the viewfinder after capturing. Setting it to FALSE will
-   * abort the blocking if it hasn't happened yet, or will enable again the
-   * viewfinder if it is already blocked. Note that setting this property
-   * to TRUE after 'capture-start' will only work for the next capture. This
-   * makes possible for applications to set the property to FALSE to abort
-   * the current blocking and already set it back to TRUE again to block at
-   * the next capture.
-   *
-   * This is useful if application wants to display the preview image
-   * and running the viewfinder at the same time would be just a waste of
-   * CPU cycles.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_BLOCK_VIEWFINDER,
-      g_param_spec_boolean ("block-after-capture",
-          "Block viewfinder after capture",
-          "Block viewfinder after capturing an image or video",
-          DEFAULT_BLOCK_VIEWFINDER,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-   /**
-    * GstCameraBin:image-capture-width:
-    *
-    * The width to be used when capturing still images. If 0, the
-    * viewfinder's width will be used.
-    */
-  g_object_class_install_property (gobject_class, ARG_IMAGE_CAPTURE_WIDTH,
-      g_param_spec_int ("image-capture-width",
-          "The width used for image capture",
-          "The width used for image capture", 0, G_MAXINT16,
-          DEFAULT_CAPTURE_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-   /**
-    * GstCameraBin:image-capture-height:
-    *
-    * The height to be used when capturing still images. If 0, the
-    * viewfinder's height will be used.
-    */
-  g_object_class_install_property (gobject_class, ARG_IMAGE_CAPTURE_HEIGHT,
-      g_param_spec_int ("image-capture-height",
-          "The height used for image capture",
-          "The height used for image capture", 0, G_MAXINT16,
-          DEFAULT_CAPTURE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-   /**
-    * GstCameraBin:video-capture-width:
-    *
-    * The width to be used when capturing video.
-    */
-  g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_WIDTH,
-      g_param_spec_int ("video-capture-width",
-          "The width used for video capture",
-          "The width used for video capture", 0, G_MAXINT16,
-          DEFAULT_CAPTURE_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:video-capture-height:
-   *
-   * The height to be used when capturing video.
-   */
-  g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_HEIGHT,
-      g_param_spec_int ("video-capture-height",
-          "The height used for video capture",
-          "The height used for video capture", 0, G_MAXINT16,
-          DEFAULT_CAPTURE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:video-capture-framerate:
-   *
-   * The framerate to be used when capturing video.
-   */
-  g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_FRAMERATE,
-      gst_param_spec_fraction ("video-capture-framerate",
-          "The framerate used for video capture",
-          "The framerate used for video capture", 0, 1, G_MAXINT32, 1,
-          DEFAULT_FPS_N, DEFAULT_FPS_D,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:ready-for-capture:
-   *
-   * When TRUE new capture can be prepared. If FALSE capturing is ongoing
-   * and starting a new capture immediately is not possible.
-   */
-
-  g_object_class_install_property (gobject_class, ARG_READY_FOR_CAPTURE,
-      g_param_spec_boolean ("ready-for-capture",
-          "Indicates if preparing a new capture is possible",
-          "Indicates if preparing a new capture is possible",
-          DEFAULT_READY_FOR_CAPTURE,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin:idle:
-   *
-   * When TRUE no capturing/encoding/saving is running and it is safe to set
-   * camerabin to NULL to release resources without losing data.
-   *
-   * In case of errors, this property is made unreliable. Set the pipeline
-   * back to READY or NULL to make it reliable again.
-   */
-  g_object_class_install_property (gobject_class, ARG_IDLE,
-      g_param_spec_boolean ("idle",
-          "Indicates if data is being processed (recording/capturing/saving)",
-          "Indicates if data is being processed (recording/capturing/saving)",
-          TRUE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstCameraBin::capture-start:
-   * @camera: the camera bin element
-   *
-   * Starts image capture or video recording depending on the Mode.
-   * If there is a capture already going on, does nothing.
-   * Resumes video recording if it has been paused.
-   */
-
-  camerabin_signals[CAPTURE_START_SIGNAL] =
-      g_signal_new ("capture-start",
-      G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstCameraBinClass, capture_start),
-      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-  /**
-   * GstCameraBin::capture-stop:
-   * @camera: the camera bin element
-   *
-   * Stops still image preview, continuous image capture and video
-   * recording and returns to the view finder mode.
-   */
-
-  camerabin_signals[CAPTURE_STOP_SIGNAL] =
-      g_signal_new ("capture-stop",
-      G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstCameraBinClass, capture_stop),
-      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-  /**
-   * GstCameraBin::capture-pause:
-   * @camera: the camera bin element
-   *
-   * Pauses video recording or resumes paused video recording.
-   * If in image mode or not recording, does nothing.
-   */
-
-  camerabin_signals[CAPTURE_PAUSE_SIGNAL] =
-      g_signal_new ("capture-pause",
-      G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstCameraBinClass, capture_pause),
-      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-  /**
-   * GstCameraBin::set-video-resolution-fps:
-   * @camera: the camera bin element
-   * @width: number of horizontal pixels
-   * @height: number of vertical pixels
-   * @fps_n: frames per second numerator
-   * @fps_d: frames per second denominator
-   *
-   * Changes the frame resolution and frames per second of the video source.
-   * The application must be aware of the resolutions supported by the camera.
-   * Supported resolutions and frame rates can be get using input-caps property.
-   *
-   * Setting @fps_n or @fps_d to 0 configures maximum framerate for the
-   * given resolution, unless in night mode when minimum is configured.
-   *
-   * This is the same as setting the 'video-capture-width',
-   * 'video-capture-height' and 'video-capture-framerate' properties, but it
-   * already updates the caps to force use this resolution and framerate.
-   */
-
-  camerabin_signals[SET_VIDEO_RESOLUTION_FPS_SIGNAL] =
-      g_signal_new ("set-video-resolution-fps",
-      G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstCameraBinClass, set_video_resolution_fps),
-      NULL, NULL, __gst_camerabin_marshal_VOID__INT_INT_INT_INT, G_TYPE_NONE, 4,
-      G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
-
-  /**
-   * GstCameraBin::set-image-resolution:
-   * @camera: the camera bin element
-   * @width: number of horizontal pixels
-   * @height: number of vertical pixels
-   *
-   * Changes the resolution used for still image capture.
-   * Does not affect view finder mode and video recording.
-   *
-   * This actually sets the 'image-capture-width' and 'image-capture-height'
-   * properties.
-   */
-
-  camerabin_signals[SET_IMAGE_RESOLUTION_SIGNAL] =
-      g_signal_new ("set-image-resolution",
-      G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstCameraBinClass, set_image_resolution),
-      NULL, NULL, __gst_camerabin_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
-      G_TYPE_INT, G_TYPE_INT);
-
-  /**
-   * GstCameraBin::image-done:
-   * @camera: the camera bin element
-   * @filename: the name of the file just saved
-   *
-   * Signal emitted when the file has just been saved.
-   *
-   * Don't call any #GstCameraBin method from this signal, if you do so there
-   * will be a deadlock.
-   */
-
-  camerabin_signals[IMG_DONE_SIGNAL] =
-      g_signal_new ("image-done", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstCameraBinClass, img_done),
-      g_signal_accumulator_true_handled, NULL,
-      __gst_camerabin_marshal_BOOLEAN__STRING, G_TYPE_BOOLEAN, 1,
-      G_TYPE_STRING);
-
-  klass->capture_start = gst_camerabin_capture_start;
-  klass->capture_stop = gst_camerabin_capture_stop;
-  klass->capture_pause = gst_camerabin_capture_pause;
-  klass->set_video_resolution_fps = gst_camerabin_set_video_resolution_fps;
-  klass->set_image_resolution = gst_camerabin_set_image_resolution;
-
-  klass->img_done = gst_camerabin_default_signal_img_done;
-
-  /* gstelement */
-
-  gstelement_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_camerabin_change_state);
-
-  gstelement_class->provide_clock =
-      GST_DEBUG_FUNCPTR (gst_camerabin_provide_clock);
-
-  /* gstbin */
-  /* override handle_message to peek when video or image bin reaches eos */
-  gstbin_class->handle_message =
-      GST_DEBUG_FUNCPTR (gst_camerabin_handle_message_func);
-
-}
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set functions
- * initialize structure
- */
-static void
-gst_camerabin_init (GstCameraBin * camera, GstCameraBinClass * gclass)
-{
-  /* GstElementClass *klass = GST_ELEMENT_GET_CLASS (camera); */
-
-  camera->filename = g_string_new ("");
-  camera->mode = DEFAULT_MODE;
-  camera->flags = DEFAULT_FLAGS;
-  camera->stop_requested = FALSE;
-  camera->paused = FALSE;
-  camera->capturing = FALSE;
-  camera->night_mode = FALSE;
-  camera->eos_handled = FALSE;
-
-  camera->app_width = camera->width = DEFAULT_WIDTH;
-  camera->app_height = camera->height = DEFAULT_HEIGHT;
-  camera->app_fps_n = camera->fps_n = DEFAULT_FPS_N;
-  camera->app_fps_d = camera->fps_d = DEFAULT_FPS_D;
-  camera->image_capture_width = 0;
-  camera->image_capture_height = 0;
-  camera->base_crop_left = 0;
-  camera->base_crop_right = 0;
-  camera->base_crop_top = 0;
-  camera->base_crop_bottom = 0;
-
-  camera->event_tags = gst_tag_list_new ();
-
-  camera->image_capture_caps = NULL;
-  camera->view_finder_caps = NULL;
-  camera->allowed_caps = NULL;
-
-  camera->zoom = DEFAULT_ZOOM;
-
-  /* concurrency control */
-  camera->capture_mutex = g_mutex_new ();
-  camera->cond = g_cond_new ();
-  camera->idle_cond = g_cond_new ();
-  camera->processing_counter = 0;
-
-  /* pad names for output and input selectors */
-  camera->pad_src_view = NULL;
-  camera->pad_view_src = NULL;
-  camera->pad_src_img = NULL;
-  camera->pad_src_vid = NULL;
-  camera->pad_view_vid = NULL;
-
-  camera->video_preview_buffer = NULL;
-  camera->preview_caps = NULL;
-  camera->video_preview_caps = NULL;
-
-  /* image capture bin */
-  camera->imgbin = g_object_new (GST_TYPE_CAMERABIN_IMAGE, NULL);
-  gst_object_ref (camera->imgbin);
-
-  /* video capture bin */
-  camera->vidbin = g_object_new (GST_TYPE_CAMERABIN_VIDEO, NULL);
-  gst_object_ref (camera->vidbin);
-
-  /* view finder elements */
-  camera->view_in_sel = NULL;
-  camera->view_scale = NULL;
-  camera->aspect_filter = NULL;
-  camera->view_sink = NULL;
-
-  camera->app_vf_sink = NULL;
-  camera->app_viewfinder_filter = NULL;
-
-  /* preview elements */
-  camera->app_preview_source_filter = NULL;
-  camera->app_video_preview_source_filter = NULL;
-
-  /* source elements */
-  camera->src_vid_src = NULL;
-  camera->src_filter = NULL;
-  camera->src_zoom_crop = NULL;
-  camera->src_zoom_scale = NULL;
-  camera->src_zoom_filter = NULL;
-  camera->src_out_sel = NULL;
-
-  camera->app_video_filter = NULL;
-  camera->app_vid_src = NULL;
-
-  camera->active_bin = NULL;
-}
-
-static void
-gst_camerabin_dispose (GObject * object)
-{
-  GstCameraBin *camera;
-
-  camera = GST_CAMERABIN (object);
-
-  GST_DEBUG_OBJECT (camera, "disposing");
-
-  gst_element_set_state (camera->imgbin, GST_STATE_NULL);
-  gst_object_unref (camera->imgbin);
-
-  gst_element_set_state (camera->vidbin, GST_STATE_NULL);
-  gst_object_unref (camera->vidbin);
-
-  if (camera->preview_pipeline) {
-    gst_camerabin_preview_destroy_pipeline (camera->preview_pipeline);
-    camera->preview_pipeline = NULL;
-  }
-  if (camera->video_preview_pipeline) {
-    gst_camerabin_preview_destroy_pipeline (camera->video_preview_pipeline);
-    camera->video_preview_pipeline = NULL;
-  }
-
-  camerabin_destroy_elements (camera);
-  camerabin_dispose_elements (camera);
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_camerabin_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_camerabin_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstCameraBin *camera = GST_CAMERABIN (object);
-
-  switch (prop_id) {
-    case ARG_MUTE:
-      gst_camerabin_video_set_mute (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_boolean (value));
-      break;
-    case ARG_ZOOM:
-      camera->zoom = g_value_get_float (value);
-      /* does not set it if in NULL, the src is not created yet */
-      if (GST_STATE (camera) != GST_STATE_NULL)
-        gst_camerabin_setup_zoom (camera);
-      break;
-    case ARG_MODE:
-      gst_camerabin_change_mode (camera, g_value_get_enum (value));
-      break;
-    case ARG_FLAGS:
-      gst_camerabin_set_flags (camera, g_value_get_flags (value));
-      break;
-    case ARG_FILENAME:
-      gst_camerabin_change_filename (camera, g_value_get_string (value));
-      break;
-    case ARG_VIDEO_POST:
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next video bin NULL to READY state change");
-      }
-      gst_camerabin_video_set_post (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_object (value));
-      break;
-    case ARG_VIDEO_ENC:
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next video bin NULL to READY state change");
-      }
-      gst_camerabin_video_set_video_enc (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_object (value));
-      break;
-    case ARG_AUDIO_ENC:
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next video bin NULL to READY state change");
-      }
-      gst_camerabin_video_set_audio_enc (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_object (value));
-      break;
-    case ARG_VIDEO_MUX:
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next video bin NULL to READY state change");
-      }
-      gst_camerabin_video_set_muxer (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_object (value));
-      break;
-    case ARG_IMAGE_POST:
-      if (GST_STATE (camera->imgbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next image bin NULL to READY state change");
-      }
-      gst_camerabin_image_set_postproc (GST_CAMERABIN_IMAGE (camera->imgbin),
-          g_value_get_object (value));
-      break;
-    case ARG_IMAGE_ENC:
-      if (GST_STATE (camera->imgbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next image bin NULL to READY state change");
-      }
-      gst_camerabin_image_set_encoder (GST_CAMERABIN_IMAGE (camera->imgbin),
-          g_value_get_object (value));
-      break;
-    case ARG_IMAGE_FORMATTER:
-      if (GST_STATE (camera->imgbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next image bin NULL to READY state change");
-      }
-      gst_camerabin_image_set_formatter (GST_CAMERABIN_IMAGE (camera->imgbin),
-          g_value_get_object (value));
-      break;
-    case ARG_VF_SINK:
-      if (GST_STATE (camera) != GST_STATE_NULL) {
-        GST_ELEMENT_ERROR (camera, CORE, FAILED,
-            ("camerabin must be in NULL state when setting the view finder element"),
-            (NULL));
-      } else {
-        if (camera->app_vf_sink)
-          gst_object_unref (camera->app_vf_sink);
-        camera->app_vf_sink = g_value_get_object (value);
-        if (camera->app_vf_sink)
-          gst_object_ref (camera->app_vf_sink);
-      }
-      break;
-    case ARG_VIDEO_SRC:
-      if (GST_STATE (camera) != GST_STATE_NULL) {
-        GST_ELEMENT_ERROR (camera, CORE, FAILED,
-            ("camerabin must be in NULL state when setting the video source element"),
-            (NULL));
-      } else {
-        if (camera->app_vid_src)
-          gst_object_unref (camera->app_vid_src);
-        camera->app_vid_src = g_value_get_object (value);
-        if (camera->app_vid_src)
-          gst_object_ref (camera->app_vid_src);
-      }
-      break;
-    case ARG_AUDIO_SRC:
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        GST_WARNING_OBJECT (camera,
-            "can't use set element until next video bin NULL to READY state change");
-      }
-      gst_camerabin_video_set_audio_src (GST_CAMERABIN_VIDEO (camera->vidbin),
-          g_value_get_object (value));
-      break;
-    case ARG_VIDEO_SOURCE_FILTER:
-      if (GST_STATE (camera) != GST_STATE_NULL) {
-        GST_ELEMENT_ERROR (camera, CORE, FAILED,
-            ("camerabin must be in NULL state when setting the video filter element"),
-            (NULL));
-      } else {
-        if (camera->app_video_filter)
-          gst_object_unref (camera->app_video_filter);
-        camera->app_video_filter = g_value_dup_object (value);
-      }
-      break;
-    case ARG_FILTER_CAPS:
-      GST_OBJECT_LOCK (camera);
-      gst_caps_replace (&camera->view_finder_caps,
-          (GstCaps *) gst_value_get_caps (value));
-      GST_OBJECT_UNLOCK (camera);
-      if (!camera->view_finder_caps)
-        camera->view_finder_caps =
-            gst_caps_from_string (CAMERABIN_DEFAULT_VF_CAPS);
-      gst_camerabin_configure_format (camera, camera->view_finder_caps);
-      break;
-    case ARG_PREVIEW_CAPS:
-    {
-      GstCameraBinPreviewPipelineData **prev_pipe = NULL;
-      GstElement **preview_source_filter = NULL;
-      GstCaps **prev_caps = NULL;
-      GstCaps *new_caps = NULL;
-
-      if (camera->mode == MODE_IMAGE) {
-        prev_pipe = &camera->preview_pipeline;
-        preview_source_filter = &camera->app_preview_source_filter;
-        prev_caps = &camera->preview_caps;
-      } else {                  /* MODE VIDEO */
-        prev_pipe = &camera->video_preview_pipeline;
-        preview_source_filter = &camera->app_video_preview_source_filter;
-        prev_caps = &camera->video_preview_caps;
-      }
-
-      new_caps = (GstCaps *) gst_value_get_caps (value);
-
-      if (prev_caps && !gst_caps_is_equal (*prev_caps, new_caps)) {
-        GST_DEBUG_OBJECT (camera,
-            "setting preview caps: %" GST_PTR_FORMAT, new_caps);
-
-        GST_OBJECT_LOCK (camera);
-        gst_caps_replace (prev_caps, new_caps);
-        GST_OBJECT_UNLOCK (camera);
-
-        if (new_caps && !gst_caps_is_any (new_caps) &&
-            !gst_caps_is_empty (new_caps)) {
-          if (!*prev_pipe) {
-            *prev_pipe =
-                gst_camerabin_preview_create_pipeline (GST_ELEMENT (camera),
-                new_caps, *preview_source_filter);
-          } else {
-            gst_camerabin_preview_set_caps (*prev_pipe, new_caps);
-          }
-        }
-      }
-      break;
-    }
-    case ARG_PREVIEW_SOURCE_FILTER:
-      if (GST_STATE (camera) != GST_STATE_NULL) {
-        GST_ELEMENT_ERROR (camera, CORE, FAILED,
-            ("camerabin must be in NULL state when setting the preview source filter element"),
-            (NULL));
-      } else {
-        GstCameraBinPreviewPipelineData **preview_pipe = NULL;
-        GstElement **preview_source_filter = NULL;
-        GstCaps *preview_caps = NULL;
-
-        if (camera->mode == MODE_IMAGE) {
-          preview_pipe = &camera->preview_pipeline;
-          preview_source_filter = &camera->app_preview_source_filter;
-          preview_caps = camera->preview_caps;
-        } else {                /* MODE VIDEO */
-          preview_pipe = &camera->video_preview_pipeline;
-          preview_source_filter = &camera->app_video_preview_source_filter;
-          preview_caps = camera->video_preview_caps;
-        }
-
-        if (*preview_source_filter)
-          gst_object_unref (*preview_source_filter);
-        *preview_source_filter = g_value_dup_object (value);
-
-        if (*preview_pipe) {
-          gst_camerabin_preview_destroy_pipeline (*preview_pipe);
-          *preview_pipe =
-              gst_camerabin_preview_create_pipeline (GST_ELEMENT (camera),
-              preview_caps, *preview_source_filter);
-        }
-      }
-      break;
-    case ARG_VIEWFINDER_FILTER:
-      if (GST_STATE (camera) != GST_STATE_NULL) {
-        GST_ELEMENT_ERROR (camera, CORE, FAILED,
-            ("camerabin must be in NULL state when setting the viewfinder filter element"),
-            (NULL));
-      } else {
-        if (camera->app_viewfinder_filter)
-          gst_object_unref (camera->app_viewfinder_filter);
-        camera->app_viewfinder_filter = g_value_dup_object (value);
-      }
-      break;
-    case ARG_BLOCK_VIEWFINDER:
-      gst_camerabin_change_viewfinder_blocking (camera,
-          g_value_get_boolean (value));
-      break;
-    case ARG_IMAGE_CAPTURE_WIDTH:
-    {
-      gint width = g_value_get_int (value);
-
-      if (width != camera->image_capture_width) {
-        camera->image_capture_width = width;
-        camera->image_capture_caps_update = TRUE;
-      }
-    }
-      break;
-    case ARG_IMAGE_CAPTURE_HEIGHT:
-    {
-      gint height = g_value_get_int (value);
-
-      if (height != camera->image_capture_height) {
-        camera->image_capture_height = height;
-        camera->image_capture_caps_update = TRUE;
-      }
-    }
-      break;
-    case ARG_VIDEO_CAPTURE_WIDTH:
-    {
-      gint width = g_value_get_int (value);
-
-      camera->app_width = width;
-
-      if (width != camera->width) {
-        camera->width = width;
-        camera->video_capture_caps_update = TRUE;
-      }
-    }
-      break;
-    case ARG_VIDEO_CAPTURE_HEIGHT:
-    {
-      gint height = g_value_get_int (value);
-
-      camera->app_height = height;
-
-      if (height != camera->height) {
-        camera->height = height;
-        camera->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);
-
-      camera->app_fps_n = fps_n;
-      camera->app_fps_d = fps_d;
-
-      if (fps_n != camera->fps_n || fps_d != camera->fps_d) {
-        camera->fps_n = fps_n;
-        camera->fps_d = fps_d;
-        camera->video_capture_caps_update = TRUE;
-      }
-    }
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_camerabin_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstCameraBin *camera = GST_CAMERABIN (object);
-
-  switch (prop_id) {
-    case ARG_FILENAME:
-      g_value_set_string (value, camera->filename->str);
-      break;
-    case ARG_MODE:
-      g_value_set_enum (value, camera->mode);
-      break;
-    case ARG_FLAGS:
-      g_value_set_flags (value, camera->flags);
-      break;
-    case ARG_MUTE:
-      g_value_set_boolean (value,
-          gst_camerabin_video_get_mute (GST_CAMERABIN_VIDEO (camera->vidbin)));
-      break;
-    case ARG_ZOOM:
-      g_value_set_float (value, camera->zoom);
-      break;
-    case ARG_IMAGE_POST:
-      g_value_set_object (value,
-          gst_camerabin_image_get_postproc (GST_CAMERABIN_IMAGE
-              (camera->imgbin)));
-      break;
-    case ARG_IMAGE_ENC:
-      g_value_set_object (value,
-          gst_camerabin_image_get_encoder (GST_CAMERABIN_IMAGE
-              (camera->imgbin)));
-      break;
-    case ARG_IMAGE_FORMATTER:
-      g_value_set_object (value,
-          gst_camerabin_image_get_formatter (GST_CAMERABIN_IMAGE
-              (camera->imgbin)));
-      break;
-    case ARG_VIDEO_POST:
-      g_value_set_object (value,
-          gst_camerabin_video_get_post (GST_CAMERABIN_VIDEO (camera->vidbin)));
-      break;
-    case ARG_VIDEO_ENC:
-      g_value_set_object (value,
-          gst_camerabin_video_get_video_enc (GST_CAMERABIN_VIDEO
-              (camera->vidbin)));
-      break;
-    case ARG_AUDIO_ENC:
-      g_value_set_object (value,
-          gst_camerabin_video_get_audio_enc (GST_CAMERABIN_VIDEO
-              (camera->vidbin)));
-      break;
-    case ARG_VIDEO_MUX:
-      g_value_set_object (value,
-          gst_camerabin_video_get_muxer (GST_CAMERABIN_VIDEO (camera->vidbin)));
-      break;
-    case ARG_VF_SINK:
-      if (camera->view_sink)
-        g_value_set_object (value, camera->view_sink);
-      else
-        g_value_set_object (value, camera->app_vf_sink);
-      break;
-    case ARG_VIDEO_SRC:
-      if (camera->src_vid_src)
-        g_value_set_object (value, camera->src_vid_src);
-      else
-        g_value_set_object (value, camera->app_vid_src);
-      break;
-    case ARG_AUDIO_SRC:
-      g_value_set_object (value,
-          gst_camerabin_video_get_audio_src (GST_CAMERABIN_VIDEO
-              (camera->vidbin)));
-      break;
-    case ARG_VIDEO_SOURCE_FILTER:
-      g_value_set_object (value, camera->app_video_filter);
-      break;
-    case ARG_INPUT_CAPS:
-      gst_value_set_caps (value, gst_camerabin_get_allowed_input_caps (camera));
-      break;
-    case ARG_FILTER_CAPS:
-      gst_value_set_caps (value, camera->view_finder_caps);
-      break;
-    case ARG_PREVIEW_CAPS:
-      if (camera->mode == MODE_IMAGE)
-        gst_value_set_caps (value, camera->preview_caps);
-      else if (camera->mode == MODE_VIDEO)
-        gst_value_set_caps (value, camera->video_preview_caps);
-      break;
-    case ARG_PREVIEW_SOURCE_FILTER:
-      if (camera->mode == MODE_IMAGE)
-        g_value_set_object (value, camera->app_preview_source_filter);
-      else if (camera->mode == MODE_VIDEO)
-        g_value_set_object (value, camera->app_video_preview_source_filter);
-      break;
-    case ARG_VIEWFINDER_FILTER:
-      g_value_set_object (value, camera->app_viewfinder_filter);
-      break;
-    case ARG_BLOCK_VIEWFINDER:
-      g_value_set_boolean (value, camera->block_viewfinder_prop);
-      break;
-    case ARG_READY_FOR_CAPTURE:
-      g_mutex_lock (camera->capture_mutex);
-      g_value_set_boolean (value, !camera->capturing);
-      g_mutex_unlock (camera->capture_mutex);
-      break;
-    case ARG_IMAGE_CAPTURE_WIDTH:
-      g_value_set_int (value, camera->image_capture_width);
-      break;
-    case ARG_IMAGE_CAPTURE_HEIGHT:
-      g_value_set_int (value, camera->image_capture_height);
-      break;
-    case ARG_VIDEO_CAPTURE_WIDTH:
-      g_value_set_int (value, camera->app_width);
-      break;
-    case ARG_VIDEO_CAPTURE_HEIGHT:
-      g_value_set_int (value, camera->app_height);
-      break;
-    case ARG_VIDEO_CAPTURE_FRAMERATE:
-      gst_value_set_fraction (value, camera->app_fps_n, camera->app_fps_d);
-      break;
-    case ARG_IDLE:
-      g_value_set_boolean (value, camera->processing_counter == 0);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/*
- * GstElement functions implementation
- */
-
-static GstStateChangeReturn
-gst_camerabin_change_state (GstElement * element, GstStateChange transition)
-{
-  GstCameraBin *camera = GST_CAMERABIN (element);
-  GstStateChangeReturn ret;
-
-  GST_DEBUG_OBJECT (element, "changing state: %s -> %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
-
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!camerabin_create_elements (camera)) {
-        ret = GST_STATE_CHANGE_FAILURE;
-        goto done;
-      }
-      /* Lock to control image and video bin state separately
-         from view finder */
-      gst_element_set_locked_state (camera->imgbin, TRUE);
-      gst_element_set_locked_state (camera->vidbin, TRUE);
-      break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      camerabin_setup_src_elements (camera);
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      /* If using autovideosink, set view finder sink properties
-         now that actual sink has been created. */
-      camerabin_setup_view_elements (camera);
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* all processing should stop and those elements could have their state
-       * locked, so set them explicitly here */
-      if (GST_STATE (camera->imgbin) != GST_STATE_NULL) {
-        gst_element_set_state (camera->imgbin, GST_STATE_READY);
-      }
-      if (GST_STATE (camera->vidbin) != GST_STATE_NULL) {
-        gst_element_set_state (camera->vidbin, GST_STATE_READY);
-      }
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      gst_element_set_locked_state (camera->imgbin, FALSE);
-      gst_element_set_locked_state (camera->vidbin, FALSE);
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  GST_DEBUG_OBJECT (element, "after chaining up: %s -> %s = %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)),
-      gst_element_state_change_return_get_name (ret));
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      g_mutex_lock (camera->capture_mutex);
-      if (camera->capturing) {
-        GST_WARNING_OBJECT (camera, "was capturing when changing to READY");
-        camera->capturing = FALSE;
-        /* Reset capture and don't wait for capturing to finish properly.
-           Proper capturing should have been finished before going to READY. */
-        gst_camerabin_reset_to_view_finder (camera);
-        g_cond_signal (camera->cond);
-      }
-
-      /* reset processing counter */
-      GST_DEBUG_OBJECT (camera, "Reset processing counter from %d to 0",
-          camera->processing_counter);
-      camera->processing_counter = 0;
-      g_cond_signal (camera->idle_cond);
-      g_object_notify (G_OBJECT (camera), "idle");
-      g_mutex_unlock (camera->capture_mutex);
-
-      /* unblock the viewfinder, but keep the property as is */
-      gst_pad_set_blocked_async (camera->pad_src_view, FALSE,
-          (GstPadBlockCallback) camerabin_pad_blocked, camera);
-
-      g_signal_handlers_disconnect_by_func (camera->src_vid_src,
-          gst_camerabin_scene_mode_notify_cb, camera);
-      g_signal_handlers_disconnect_by_func (camera->src_vid_src,
-          gst_camerabin_zoom_notify_cb, camera);
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      camerabin_destroy_elements (camera);
-      break;
-      /* In some error situation camerabin may end up being still in NULL
-         state so we must take care of destroying elements. */
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (ret == GST_STATE_CHANGE_FAILURE)
-        camerabin_destroy_elements (camera);
-      break;
-    default:
-      break;
-  }
-
-done:
-  GST_DEBUG_OBJECT (element, "changed state: %s -> %s = %s",
-      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
-      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)),
-      gst_element_state_change_return_get_name (ret));
-
-  return ret;
-}
-
-static GstClock *
-gst_camerabin_provide_clock (GstElement * element)
-{
-  GstClock *clock = NULL;
-  GstClock *vidbin_clock = NULL;
-  GstCameraBin *camera = GST_CAMERABIN (element);
-  GstElement *aud_src = GST_CAMERABIN_VIDEO (camera->vidbin)->aud_src;
-
-  if (aud_src)
-    vidbin_clock = gst_element_provide_clock (aud_src);
-
-  if (camera->capturing && camera->mode == MODE_VIDEO && vidbin_clock)
-    clock = vidbin_clock;
-  else {
-    clock = GST_ELEMENT_CLASS (parent_class)->provide_clock (element);
-    if (clock == vidbin_clock) {
-      /* Do not reuse vidbin_clock if it was current clock */
-      clock = gst_system_clock_obtain ();
-    }
-  }
-
-  GST_INFO_OBJECT (camera, "Reset pipeline clock to %p(%s)",
-      clock, GST_ELEMENT_NAME (clock));
-
-  return clock;
-}
-
-static gpointer
-gst_camerabin_imgbin_finished (gpointer u_data)
-{
-  GstCameraBin *camera = GST_CAMERABIN (u_data);
-  gchar *filename = NULL;
-
-  /* FIXME: should set a flag (and take a lock) when going to NULL, so we
-   * short-circuit this bit if we got shut down between thread create and now */
-
-  GST_DEBUG_OBJECT (camera, "Image encoding finished");
-
-  /* Get the filename of the finished image */
-  g_object_get (G_OBJECT (camera->imgbin), "filename", &filename, NULL);
-
-  /* Close the file of saved image */
-  gst_element_set_state (camera->imgbin, GST_STATE_READY);
-  GST_DEBUG_OBJECT (camera, "Image pipeline set to READY");
-
-  g_mutex_lock (camera->capture_mutex);
-  if (camera->processing_counter) {
-    CAMERABIN_PROCESSING_DEC_UNLOCKED (camera);
-  } else {
-    /* Camerabin state change to READY may have reset processing counter to
-     * zero. This is possible as this functions is scheduled from another
-     * thread.
-     */
-    GST_WARNING_OBJECT (camera, "camerabin has been forced to idle");
-  }
-  g_mutex_unlock (camera->capture_mutex);
-
-  /* Set image bin back to PAUSED so that buffer-allocs don't fail */
-  gst_element_set_state (camera->imgbin, GST_STATE_PAUSED);
-
-  /* Unblock image queue pad to process next buffer */
-  GST_STATE_LOCK (camera);
-  if (camera->pad_src_queue) {
-    gst_pad_set_blocked_async (camera->pad_src_queue, FALSE,
-        (GstPadBlockCallback) camerabin_pad_blocked, camera);
-    GST_DEBUG_OBJECT (camera, "Queue srcpad unblocked");
-  } else {
-    GST_DEBUG_OBJECT (camera, "Queue srcpad unreffed already, doesn't need "
-        "to unblock");
-  }
-  GST_STATE_UNLOCK (camera);
-
-  /* Send image-done signal */
-  gst_camerabin_image_capture_continue (camera, filename);
-  g_free (filename);
-
-  GST_INFO_OBJECT (camera, "leaving helper thread");
-  gst_object_unref (camera);
-  return NULL;
-}
-
-/*
- * GstBin functions implementation
- */
-
-/* Peek eos messages but don't interfere with bin msg handling */
-static void
-gst_camerabin_handle_message_func (GstBin * bin, GstMessage * msg)
-{
-  GstCameraBin *camera = GST_CAMERABIN (bin);
-
-  switch (GST_MESSAGE_TYPE (msg)) {
-    case GST_MESSAGE_EOS:
-      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (camera->vidbin)) {
-        /* Video eos */
-        GST_DEBUG_OBJECT (camera,
-            "got video eos message, stopping video capture");
-        g_mutex_lock (camera->capture_mutex);
-        camera->capturing = FALSE;
-        g_cond_signal (camera->cond);
-
-        CAMERABIN_PROCESSING_DEC_UNLOCKED (camera);
-        g_mutex_unlock (camera->capture_mutex);
-      } else if (GST_MESSAGE_SRC (msg) == GST_OBJECT (camera->imgbin)) {
-        /* Image eos */
-        GST_DEBUG_OBJECT (camera, "got image eos message");
-        /* Can't change state here, since we're in the streaming thread */
-        if (!g_thread_create (gst_camerabin_imgbin_finished,
-                gst_object_ref (camera), FALSE, NULL)) {
-          /* FIXME: what do do if this fails? */
-          gst_object_unref (camera);
-        }
-      }
-      break;
-    case GST_MESSAGE_ERROR:
-      GST_DEBUG_OBJECT (camera, "error from child %" GST_PTR_FORMAT,
-          GST_MESSAGE_SRC (msg));
-      g_mutex_lock (camera->capture_mutex);
-      if (camera->capturing) {
-        camera->capturing = FALSE;
-        g_cond_signal (camera->cond);
-      }
-
-      /* Ideally we should check what error was and only decrement the
-       * counter if the error means that a 'processing' operation failed,
-       * instead of a setting up error. But this can be quite tricky to do
-       * and we expect the app to set the whole pipeline to READY/NULL
-       * when an error happens. For now we just mention that the
-       * processing counter and the 'idle' property are unreliable */
-      GST_DEBUG_OBJECT (camera, "An error makes the processing counter "
-          "unreliable");
-
-      g_mutex_unlock (camera->capture_mutex);
-      break;
-    default:
-      break;
-  }
-  GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
-}
-
-/*
- * Action signal function implementation
- */
-
-static void
-gst_camerabin_capture_start (GstCameraBin * camera)
-{
-
-  GST_INFO_OBJECT (camera, "starting capture");
-  if (camera->paused) {
-    gst_camerabin_capture_pause (camera);
-    return;
-  }
-
-  if (!camera->active_bin) {
-    GST_INFO_OBJECT (camera, "mode not explicitly set by application");
-    gst_camerabin_change_mode (camera, camera->mode);
-    if (!camera->active_bin) {
-      GST_ELEMENT_ERROR (camera, CORE, FAILED,
-          ("starting capture failed"), (NULL));
-    }
-  }
-
-  /* We need a filename unless it's a photo and preview_caps is set */
-
-  if (g_str_equal (camera->filename->str, ""))
-    if (camera->active_bin == camera->vidbin || !camera->preview_caps) {
-      GST_ELEMENT_ERROR (camera, CORE, FAILED,
-          ("set filename before starting capture"), (NULL));
-      return;
-    }
-
-  g_mutex_lock (camera->capture_mutex);
-  if (camera->capturing) {
-    GST_WARNING_OBJECT (camera, "capturing \"%s\" ongoing, set new filename",
-        camera->filename->str);
-    /* FIXME: we need to send something more to the app, so that it does not for
-     * for image-done */
-    g_mutex_unlock (camera->capture_mutex);
-    return;
-  }
-  CAMERABIN_PROCESSING_INC_UNLOCKED (camera);
-  g_mutex_unlock (camera->capture_mutex);
-
-  GST_OBJECT_LOCK (camera);
-  camera->block_viewfinder_trigger = camera->block_viewfinder_prop;
-  GST_OBJECT_UNLOCK (camera);
-
-  if (camera->active_bin) {
-    if (camera->active_bin == camera->imgbin) {
-      GST_INFO_OBJECT (camera, "starting image capture");
-      gst_camerabin_start_image_capture (camera);
-    } else if (camera->active_bin == camera->vidbin) {
-      GST_INFO_OBJECT (camera,
-          "setting video filename and starting video capture");
-      g_object_set (G_OBJECT (camera->active_bin), "filename",
-          camera->filename->str, NULL);
-      gst_camerabin_start_video_recording (camera);
-    }
-  }
-  /* Capturing is now ongoing, notify that new capture isn't possible */
-  g_object_notify (G_OBJECT (camera), "ready-for-capture");
-}
-
-static void
-gst_camerabin_capture_stop (GstCameraBin * camera)
-{
-  if (camera->active_bin == camera->vidbin) {
-    GST_INFO_OBJECT (camera, "stopping video capture");
-    gst_camerabin_do_stop (camera);
-    gst_camerabin_reset_to_view_finder (camera);
-    /* Video capture stopped, notify that preparing a new capture is possible */
-    g_object_notify (G_OBJECT (camera), "ready-for-capture");
-  } else {
-    GST_INFO_OBJECT (camera, "stopping image capture isn't needed");
-  }
-}
-
-static void
-gst_camerabin_capture_pause (GstCameraBin * camera)
-{
-  if (camera->active_bin == camera->vidbin) {
-    if (!camera->paused) {
-      GST_INFO_OBJECT (camera, "pausing capture");
-
-      /* Bring all camerabin elements to PAUSED */
-      gst_element_set_locked_state (camera->vidbin, FALSE);
-      gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
-
-      /* Switch to view finder mode */
-      g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
-          "active-pad", camera->pad_src_view, NULL);
-
-      /* Set view finder to PLAYING and leave videobin PAUSED */
-      gst_element_set_locked_state (camera->vidbin, TRUE);
-      gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING);
-
-      camera->paused = TRUE;
-    } else {
-      GST_INFO_OBJECT (camera, "unpausing capture");
-
-      /* Bring all camerabin elements to PAUSED */
-      gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
-
-      /* Switch to video recording mode */
-      g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", TRUE,
-          "active-pad", camera->pad_src_vid, NULL);
-
-      /* Bring all camerabin elements to PLAYING */
-      gst_element_set_locked_state (camera->vidbin, FALSE);
-      gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING);
-      gst_element_set_locked_state (camera->vidbin, TRUE);
-
-      camera->paused = FALSE;
-    }
-    GST_DEBUG_OBJECT (camera, "pause done");
-  } else {
-    GST_WARNING ("pausing in image capture mode disabled");
-  }
-}
-
-/*
- * Updates the properties (excluding the user preferred width/height/fps) and
- * tells camerabin to update the video capture caps.
- */
-static void
-do_set_video_resolution_fps (GstCameraBin * camera, gint width,
-    gint height, gint fps_n, gint fps_d)
-{
-  if (height != camera->height) {
-    camera->height = height;
-    camera->video_capture_caps_update = TRUE;
-  }
-  if (width != camera->width) {
-    camera->width = width;
-    camera->video_capture_caps_update = TRUE;
-  }
-  if (fps_n != camera->fps_n) {
-    camera->fps_n = fps_n;
-    camera->video_capture_caps_update = TRUE;
-  }
-  if (fps_d != camera->fps_d) {
-    camera->fps_d = fps_d;
-    camera->video_capture_caps_update = TRUE;
-  }
-
-  reset_video_capture_caps (camera);
-}
-
-/*
- * Updates the properties (including the user preferred width/height/fps) and
- * tells camerabin to update the video capture caps.
- */
-static void
-gst_camerabin_set_video_resolution_fps (GstCameraBin * camera, gint width,
-    gint height, gint fps_n, gint fps_d)
-{
-  g_object_set (camera, "video-capture-width", width, "video-capture-height",
-      height, "video-capture-framerate", fps_n, fps_d, NULL);
-
-  reset_video_capture_caps (camera);
-}
-
-static void
-gst_camerabin_set_image_capture_caps (GstCameraBin * camera, gint width,
-    gint height)
-{
-  GstStructure *structure;
-  GstCaps *new_caps = NULL;
-
-  g_return_if_fail (camera != NULL);
-
-  if (width && height && camera->view_finder_caps) {
-    /* Use view finder mode caps as a basis */
-    structure = gst_caps_get_structure (camera->view_finder_caps, 0);
-
-    /* Set new resolution for image capture */
-    new_caps = gst_caps_new_simple (gst_structure_get_name (structure),
-        "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
-
-    /* Set allowed framerate for the resolution. */
-    gst_camerabin_set_allowed_framerate (camera, new_caps);
-  }
-
-  GST_INFO_OBJECT (camera,
-      "init filter caps for image capture %" GST_PTR_FORMAT, new_caps);
-  gst_caps_replace (&camera->image_capture_caps, new_caps);
-  camera->image_capture_caps_update = FALSE;
-  if (new_caps)
-    gst_caps_unref (new_caps);
-}
-
-static void
-gst_camerabin_set_image_resolution (GstCameraBin * camera, gint width,
-    gint height)
-{
-  g_object_set (camera, "image-capture-width", (guint16) width,
-      "image-capture-height", (guint16) height, NULL);
-}
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and pad templates
- * register the features
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  GST_DEBUG_CATEGORY_INIT (gst_camerabin_debug, "camerabin", 0, "CameraBin");
-
-  return gst_element_register (plugin, "camerabin",
-      GST_RANK_NONE, GST_TYPE_CAMERABIN);
-}
-
-/* this is the structure that gstreamer looks for to register plugins
- */
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    camerabin,
-    "High level api for DC (Digital Camera) application",
-    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/gst/camerabin/gstcamerabin.h b/gst/camerabin/gstcamerabin.h
deleted file mode 100644 (file)
index 1c0a075..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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 __GST_CAMERABIN_H__
-#define __GST_CAMERABIN_H__
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <gst/gstbin.h>
-#include <gst/interfaces/photography.h>
-
-#include "gstcamerabin-enum.h"
-#include "camerabinimage.h"
-#include "camerabinvideo.h"
-#include "camerabinpreview.h"
-
-G_BEGIN_DECLS
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_CAMERABIN \
-  (gst_camerabin_get_type())
-#define GST_CAMERABIN(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERABIN,GstCameraBin))
-#define GST_CAMERABIN_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERABIN,GstCameraBinClass))
-#define GST_IS_CAMERABIN(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERABIN))
-#define GST_IS_CAMERABIN_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERABIN))
-typedef struct _GstCameraBin GstCameraBin;
-typedef struct _GstCameraBinClass GstCameraBinClass;
-
-/**
- * GstCameraBin:
- *
- * The opaque #GstCameraBin structure.
- */
-
-struct _GstCameraBin
-{
-  GstPipeline parent;
-
-  /* private */
-  GString *filename;
-  gint mode;                      /* MODE_IMAGE or MODE_VIDEO */
-  GstCameraBinFlags flags;
-  gboolean stop_requested;        /* TRUE if capturing stop needed */
-  gboolean paused;                /* TRUE if capturing paused */
-
-  /*
-   * Those 2 booleans work together.
-   *
-   * 'block_viewfinder_prop' is the property, 'block_viewfinder_trigger'
-   * is the flag that actually makes the viewfinder block after capture.
-   * We need both to avoid blocking the viewfinder if the application resets
-   * the flag after issuing the 'capture-start', but before the actual
-   * blocking happens. This causes the viewfinder to block even though
-   * the application resetted the flag to keep it running already.
-   *
-   * Here's how this should work:
-   * When a capture is started, the property is checked, if it is TRUE, the
-   * trigger is set to TRUE. The blocking will only happen if
-   * the trigger is TRUE after image capture finishes, ff the property
-   * is reset before the blocking happens, the trigger goes to
-   * FALSE and no blocking happens.
-   */
-  gboolean block_viewfinder_prop; /* TRUE if viewfinder blocks after capture */
-  gboolean block_viewfinder_trigger;
-
-  /* Resolution of the buffers configured to camerabin */
-  gint width;
-  gint height;
-  /* Frames per second configured to camerabin */
-  gint fps_n;
-  gint fps_d;
-
-  /* app configured resolution/framerate */
-  gint app_width;
-  gint app_height;
-  gint app_fps_n;
-  gint app_fps_d;
-
-  gboolean video_capture_caps_update;
-
-  /* Image capture resolution */
-  gint image_capture_width;
-  gint image_capture_height;
-
-  /* Image tags are collected here first before sending to imgbin */
-  GstTagList *event_tags;
-
-  /* Caps applied to capsfilters when taking still image */
-  GstCaps *image_capture_caps;
-  gboolean image_capture_caps_update;
-
-  /* Caps applied to capsfilters when in view finder mode */
-  GstCaps *view_finder_caps;
-
-  /* Caps that videosrc supports */
-  GstCaps *allowed_caps;
-
-  /* Caps used to create preview image */
-  GstCaps *preview_caps;
-
-  /* Caps used to create video preview image */
-  GstCaps *video_preview_caps;
-
-  /* The digital zoom (from 1.0 to 10.0) */
-  gfloat zoom;
-
-  /* concurrency control */
-  GMutex *capture_mutex;
-  GCond *cond;
-  GCond *idle_cond;
-  gboolean capturing;
-  gboolean eos_handled;
-  /* everytime a new capture is started this is incremented, when it is
-   * finished/fails it is decremented. Used to know if camerabin is idle */
-  gint processing_counter;
-
-  /* pad names for output and input selectors */
-  GstPad *pad_src_view;
-  GstPad *pad_view_src;
-  GstPad *pad_src_img;
-  GstPad *pad_src_vid;
-  GstPad *pad_view_vid;
-  GstPad *pad_src_queue;
-
-  GstElement *img_queue;        /* queue for decoupling capture from
-                                   image-postprocessing and saving */
-  GstElement *imgbin;           /* bin that holds image capturing elements */
-  GstElement *vidbin;           /*  bin that holds video capturing elements */
-  GstElement *active_bin;       /* image or video bin that is currently in use */
-  /* pipeline for creating preview images */
-  GstCameraBinPreviewPipelineData *preview_pipeline;
-  /* pipeline for creating video preview image */
-  GstCameraBinPreviewPipelineData *video_preview_pipeline;
-
-  GstBuffer *video_preview_buffer;      /* buffer for storing video preview */
-
-  /* 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;
-
-  /* view finder elements */
-  GstElement *view_in_sel;
-  GstElement *aspect_filter;
-  GstElement *view_scale;
-  GstElement *view_sink;
-
-  /* Application configurable elements */
-  GstElement *app_vid_src;
-  GstElement *app_vf_sink;
-  GstElement *app_video_filter;
-  GstElement *app_viewfinder_filter;
-  GstElement *app_preview_source_filter;
-  GstElement *app_video_preview_source_filter;
-
-  /* Night mode handling */
-  gboolean night_mode;
-  gint pre_night_fps_n;
-  gint pre_night_fps_d;
-
-  /* Buffer probe id for captured image handling */
-  gulong image_captured_id;
-
-  /* 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;
-};
-
-/**
- * GstCameraBinClass:
- *
- * The #GstCameraBin class structure.
- */
-struct _GstCameraBinClass
-{
-  GstPipelineClass parent_class;
-
-  /* action signals */
-
-  void (*capture_start) (GstCameraBin * camera);
-  void (*capture_stop) (GstCameraBin * camera);
-  void (*capture_pause) (GstCameraBin * camera);
-  void (*set_video_resolution_fps) (GstCameraBin * camera, gint width,
-      gint height, gint fps_n, gint fps_d);
-  void (*set_image_resolution) (GstCameraBin * camera, gint width, gint height);
-
-  /* signals (callback) */
-
-    gboolean (*img_done) (GstCameraBin * camera, const gchar * filename);
-};
-
-/**
- * GstCameraBinMode:
- * @MODE_IMAGE: image capture
- * @MODE_VIDEO: video capture
- *
- * Capture mode to use.
- */
-typedef enum
-{
-  MODE_IMAGE = 0,
-  MODE_VIDEO
-} GstCameraBinMode;
-
-GType gst_camerabin_get_type (void);
-
-G_END_DECLS
-#endif /* #ifndef __GST_CAMERABIN_H__ */
diff --git a/gst/camerabin/gstcamerabincolorbalance.c b/gst/camerabin/gstcamerabincolorbalance.c
deleted file mode 100644 (file)
index 54899fa..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * Includes
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gstcamerabincolorbalance.h"
-#include "gstcamerabin.h"
-
-/*
- * static functions implementation
- */
-
-static const GList *
-gst_camerabin_color_balance_list_channels (GstColorBalance * cb)
-{
-  if (cb && GST_CAMERABIN (cb)->src_vid_src) {
-    GstColorBalance *cbl = GST_COLOR_BALANCE (GST_CAMERABIN (cb)->src_vid_src);
-    return gst_color_balance_list_channels (cbl);
-  } else {
-    return NULL;
-  }
-}
-
-static void
-gst_camerabin_color_balance_set_value (GstColorBalance * cb,
-    GstColorBalanceChannel * channel, gint value)
-{
-  if (cb && GST_CAMERABIN (cb)->src_vid_src) {
-    GstColorBalance *cbl = GST_COLOR_BALANCE (GST_CAMERABIN (cb)->src_vid_src);
-    gst_color_balance_set_value (cbl, channel, value);
-  }
-}
-
-static gint
-gst_camerabin_color_balance_get_value (GstColorBalance * cb,
-    GstColorBalanceChannel * channel)
-{
-  if (cb && GST_CAMERABIN (cb)->src_vid_src) {
-    GstColorBalance *cbl = GST_COLOR_BALANCE (GST_CAMERABIN (cb)->src_vid_src);
-    return gst_color_balance_get_value (cbl, channel);
-  } else {
-    return 0;
-  }
-}
-
-/*
- * extern functions implementation
- */
-
-void
-gst_camerabin_color_balance_init (GstColorBalanceInterface * iface)
-{
-  /* FIXME: to get the same type as v4l2src */
-  GST_COLOR_BALANCE_TYPE (iface) = GST_COLOR_BALANCE_HARDWARE;
-  iface->list_channels = gst_camerabin_color_balance_list_channels;
-  iface->set_value = gst_camerabin_color_balance_set_value;
-  iface->get_value = gst_camerabin_color_balance_get_value;
-}
diff --git a/gst/camerabin/gstcamerabincolorbalance.h b/gst/camerabin/gstcamerabincolorbalance.h
deleted file mode 100644 (file)
index 81984e7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 __GST_CAMERA_COLOR_BALANCE_H__
-#define __GST_CAMERA_COLOR_BALANCE_H__
-
-#include <gst/interfaces/colorbalance.h>
-
-extern void gst_camerabin_color_balance_init (GstColorBalanceInterface * iface);
-
-#endif /* #ifndef __GST_CAMERA_COLOR_BALANCE_H__ */
diff --git a/gst/camerabin/gstinputselector.c b/gst/camerabin/gstinputselector.c
deleted file mode 100644 (file)
index 6af1918..0000000
+++ /dev/null
@@ -1,1499 +0,0 @@
-/* GStreamer
- * Copyright (C) 2003 Julien Moutte <julien@moutte.net>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
- * Copyright (C) 2007 Wim Taymans <wim.taymans@gmail.com>
- * Copyright (C) 2007 Andy Wingo <wingo@pobox.com>
- * Copyright (C) 2008 Nokia Corporation. (contact <stefan.kost@nokia.com>)
- *
- * 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-input-selector
- * @see_also: #GstOutputSelector
- *
- * Direct one out of N input streams to the output pad.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <gst/glib-compat-private.h>
-#include "gstinputselector.h"
-#include "gstcamerabin-marshal.h"
-
-GST_DEBUG_CATEGORY_STATIC (input_selector_debug);
-#define GST_CAT_DEFAULT input_selector_debug
-
-static GstStaticPadTemplate gst_input_selector_sink_factory =
-GST_STATIC_PAD_TEMPLATE ("sink_%u",
-    GST_PAD_SINK,
-    GST_PAD_REQUEST,
-    GST_STATIC_CAPS_ANY);
-
-static GstStaticPadTemplate gst_input_selector_src_factory =
-GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
-
-enum
-{
-  PROP_0,
-  PROP_N_PADS,
-  PROP_ACTIVE_PAD,
-  PROP_SELECT_ALL,
-  PROP_LAST
-};
-
-#define DEFAULT_PAD_ALWAYS_OK  TRUE
-
-enum
-{
-  PROP_PAD_0,
-  PROP_PAD_RUNNING_TIME,
-  PROP_PAD_TAGS,
-  PROP_PAD_ACTIVE,
-  PROP_PAD_ALWAYS_OK,
-  PROP_PAD_LAST
-};
-
-enum
-{
-  /* methods */
-  SIGNAL_BLOCK,
-  SIGNAL_SWITCH,
-  LAST_SIGNAL
-};
-static guint gst_input_selector_signals[LAST_SIGNAL] = { 0 };
-
-static inline gboolean gst_input_selector_is_active_sinkpad (GstInputSelector *
-    sel, GstPad * pad);
-static GstPad *gst_input_selector_activate_sinkpad (GstInputSelector * sel,
-    GstPad * pad);
-static GstPad *gst_input_selector_get_linked_pad (GstPad * pad,
-    gboolean strict);
-static gboolean gst_input_selector_check_eos (GstElement * selector);
-
-#define GST_TYPE_SELECTOR_PAD \
-  (gst_selector_pad_get_type())
-#define GST_SELECTOR_PAD(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SELECTOR_PAD, GstSelectorPad))
-#define GST_SELECTOR_PAD_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SELECTOR_PAD, GstSelectorPadClass))
-#define GST_IS_SELECTOR_PAD(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SELECTOR_PAD))
-#define GST_IS_SELECTOR_PAD_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SELECTOR_PAD))
-#define GST_SELECTOR_PAD_CAST(obj) \
-  ((GstSelectorPad *)(obj))
-
-typedef struct _GstSelectorPad GstSelectorPad;
-typedef struct _GstSelectorPadClass GstSelectorPadClass;
-
-struct _GstSelectorPad
-{
-  GstPad parent;
-
-  gboolean active;              /* when buffer have passed the pad */
-  gboolean eos;                 /* when EOS has been received */
-  gboolean discont;             /* after switching we create a discont */
-  gboolean always_ok;
-  GstSegment segment;           /* the current segment on the pad */
-  GstTagList *tags;             /* last tags received on the pad */
-
-  gboolean segment_pending;
-};
-
-struct _GstSelectorPadClass
-{
-  GstPadClass parent;
-};
-
-static void gst_selector_pad_class_init (GstSelectorPadClass * klass);
-static void gst_selector_pad_init (GstSelectorPad * pad);
-static void gst_selector_pad_finalize (GObject * object);
-static void gst_selector_pad_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_selector_pad_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-
-static GstPadClass *selector_pad_parent_class = NULL;
-
-static gint64 gst_selector_pad_get_running_time (GstSelectorPad * pad);
-static void gst_selector_pad_reset (GstSelectorPad * pad);
-static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_selector_pad_getcaps (GstPad * pad);
-static gboolean gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps);
-static GstIterator *gst_selector_pad_iterate_linked_pads (GstPad * pad);
-static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
-static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-
-static GType
-gst_selector_pad_get_type (void)
-{
-  static GType selector_pad_type = 0;
-
-  if (!selector_pad_type) {
-    static const GTypeInfo selector_pad_info = {
-      sizeof (GstSelectorPadClass),
-      NULL,
-      NULL,
-      (GClassInitFunc) gst_selector_pad_class_init,
-      NULL,
-      NULL,
-      sizeof (GstSelectorPad),
-      0,
-      (GInstanceInitFunc) gst_selector_pad_init,
-    };
-
-    selector_pad_type =
-        g_type_register_static (GST_TYPE_PAD, "GstCamerabinSelectorPad",
-        &selector_pad_info, 0);
-  }
-  return selector_pad_type;
-}
-
-static void
-gst_selector_pad_class_init (GstSelectorPadClass * klass)
-{
-  GObjectClass *gobject_class;
-
-  gobject_class = (GObjectClass *) klass;
-
-  selector_pad_parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->finalize = gst_selector_pad_finalize;
-
-  gobject_class->get_property = gst_selector_pad_get_property;
-  gobject_class->set_property = gst_selector_pad_set_property;
-
-  g_object_class_install_property (gobject_class, PROP_PAD_RUNNING_TIME,
-      g_param_spec_int64 ("running-time", "Running time",
-          "Running time of stream on pad", 0, G_MAXINT64, 0,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_PAD_TAGS,
-      g_param_spec_boxed ("tags", "Tags",
-          "The currently active tags on the pad", GST_TYPE_TAG_LIST,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_PAD_ACTIVE,
-      g_param_spec_boolean ("active", "Active",
-          "If the pad is currently active", FALSE,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_PAD_ALWAYS_OK,
-      g_param_spec_boolean ("always-ok", "Always OK",
-          "Make an inactive pad return OK instead of NOT_LINKED",
-          DEFAULT_PAD_ALWAYS_OK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_selector_pad_init (GstSelectorPad * pad)
-{
-  pad->always_ok = DEFAULT_PAD_ALWAYS_OK;
-  gst_selector_pad_reset (pad);
-}
-
-static void
-gst_selector_pad_finalize (GObject * object)
-{
-  GstSelectorPad *pad;
-
-  pad = GST_SELECTOR_PAD_CAST (object);
-
-  if (pad->tags)
-    gst_tag_list_free (pad->tags);
-
-  G_OBJECT_CLASS (selector_pad_parent_class)->finalize (object);
-}
-
-static void
-gst_selector_pad_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstSelectorPad *spad = GST_SELECTOR_PAD_CAST (object);
-
-  switch (prop_id) {
-    case PROP_PAD_ALWAYS_OK:
-      GST_OBJECT_LOCK (object);
-      spad->always_ok = g_value_get_boolean (value);
-      GST_OBJECT_UNLOCK (object);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_selector_pad_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstSelectorPad *spad = GST_SELECTOR_PAD_CAST (object);
-
-  switch (prop_id) {
-    case PROP_PAD_RUNNING_TIME:
-      g_value_set_int64 (value, gst_selector_pad_get_running_time (spad));
-      break;
-    case PROP_PAD_TAGS:
-      GST_OBJECT_LOCK (object);
-      g_value_set_boxed (value, spad->tags);
-      GST_OBJECT_UNLOCK (object);
-      break;
-    case PROP_PAD_ACTIVE:
-    {
-      GstInputSelector *sel;
-
-      sel = GST_INPUT_SELECTOR (gst_pad_get_parent (spad));
-      g_value_set_boolean (value, gst_input_selector_is_active_sinkpad (sel,
-              GST_PAD_CAST (spad)));
-      gst_object_unref (sel);
-      break;
-    }
-    case PROP_PAD_ALWAYS_OK:
-      GST_OBJECT_LOCK (object);
-      g_value_set_boolean (value, spad->always_ok);
-      GST_OBJECT_UNLOCK (object);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gint64
-gst_selector_pad_get_running_time (GstSelectorPad * pad)
-{
-  gint64 ret = 0;
-
-  GST_OBJECT_LOCK (pad);
-  if (pad->active) {
-    gint64 last_stop = pad->segment.last_stop;
-
-    if (last_stop >= 0)
-      ret = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME,
-          last_stop);
-  }
-  GST_OBJECT_UNLOCK (pad);
-
-  GST_DEBUG_OBJECT (pad, "running time: %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (ret));
-
-  return ret;
-}
-
-static void
-gst_selector_pad_reset (GstSelectorPad * pad)
-{
-  GST_OBJECT_LOCK (pad);
-  pad->active = FALSE;
-  pad->eos = FALSE;
-  pad->segment_pending = FALSE;
-  pad->discont = FALSE;
-  gst_segment_init (&pad->segment, GST_FORMAT_UNDEFINED);
-  GST_OBJECT_UNLOCK (pad);
-}
-
-/* strictly get the linked pad from the sinkpad. If the pad is active we return
- * the srcpad else we return NULL */
-static GstIterator *
-gst_selector_pad_iterate_linked_pads (GstPad * pad)
-{
-  GstInputSelector *sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  GstPad *otherpad;
-  GstIterator *it;
-
-  otherpad = gst_input_selector_get_linked_pad (pad, TRUE);
-  it = gst_iterator_new_single (GST_TYPE_PAD, otherpad,
-      (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
-
-  if (otherpad)
-    gst_object_unref (otherpad);
-  gst_object_unref (sel);
-
-  return it;
-}
-
-static gboolean
-gst_selector_pad_event (GstPad * pad, GstEvent * event)
-{
-  gboolean res = TRUE;
-  gboolean forward = TRUE;
-  GstInputSelector *sel;
-  GstSelectorPad *selpad;
-  GstPad *prev_active_sinkpad;
-  GstPad *active_sinkpad;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  selpad = GST_SELECTOR_PAD_CAST (pad);
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  prev_active_sinkpad = sel->active_sinkpad;
-  active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
-
-  /* only forward if we are dealing with the active sinkpad or if select_all
-   * is enabled */
-  if (pad != active_sinkpad && !sel->select_all)
-    forward = FALSE;
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad)
-    g_object_notify (G_OBJECT (sel), "active-pad");
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH_START:
-      /* FIXME, flush out the waiter */
-      break;
-    case GST_EVENT_FLUSH_STOP:
-      GST_INPUT_SELECTOR_LOCK (sel);
-      gst_selector_pad_reset (selpad);
-      sel->pending_close = FALSE;
-      GST_INPUT_SELECTOR_UNLOCK (sel);
-      break;
-    case GST_EVENT_NEWSEGMENT:
-    {
-      gboolean update;
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      GST_DEBUG_OBJECT (pad,
-          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-          "format %d, "
-          "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
-
-      GST_INPUT_SELECTOR_LOCK (sel);
-      GST_OBJECT_LOCK (selpad);
-      gst_segment_set_newsegment_full (&selpad->segment, update,
-          rate, arate, format, start, stop, time);
-      GST_OBJECT_UNLOCK (selpad);
-
-      /* If we aren't forwarding the event (because the pad is not the
-       * active_sinkpad, and select_all is not set, then set the flag on the
-       * that says a segment needs sending if/when that pad is activated.
-       * For all other cases, we send the event immediately, which makes
-       * sparse streams and other segment updates work correctly downstream.
-       */
-      if (!forward)
-        selpad->segment_pending = TRUE;
-
-      GST_INPUT_SELECTOR_UNLOCK (sel);
-      break;
-    }
-    case GST_EVENT_TAG:
-    {
-      GstTagList *tags, *oldtags, *newtags;
-
-      gst_event_parse_tag (event, &tags);
-
-      GST_OBJECT_LOCK (selpad);
-      oldtags = selpad->tags;
-
-      newtags = gst_tag_list_merge (oldtags, tags, GST_TAG_MERGE_REPLACE);
-      selpad->tags = newtags;
-      if (oldtags)
-        gst_tag_list_free (oldtags);
-      GST_DEBUG_OBJECT (pad, "received tags %" GST_PTR_FORMAT, newtags);
-      GST_OBJECT_UNLOCK (selpad);
-
-      g_object_notify (G_OBJECT (selpad), "tags");
-      break;
-    }
-    case GST_EVENT_EOS:
-      selpad->eos = TRUE;
-      GST_DEBUG_OBJECT (pad, "received EOS");
-      /* don't forward eos in select_all mode until all sink pads have eos */
-      if (sel->select_all && !gst_input_selector_check_eos (GST_ELEMENT (sel))) {
-        forward = FALSE;
-      }
-      break;
-    default:
-      break;
-  }
-  if (forward) {
-    GST_DEBUG_OBJECT (pad, "forwarding event");
-    res = gst_pad_push_event (sel->srcpad, event);
-  } else
-    gst_event_unref (event);
-
-  gst_object_unref (sel);
-
-  return res;
-}
-
-static GstCaps *
-gst_selector_pad_getcaps (GstPad * pad)
-{
-  GstInputSelector *sel;
-  GstCaps *caps;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-
-  GST_DEBUG_OBJECT (sel, "Getting caps of srcpad peer");
-  caps = gst_pad_peer_get_caps_reffed (sel->srcpad);
-  if (caps == NULL)
-    caps = gst_caps_new_any ();
-
-  gst_object_unref (sel);
-
-  return caps;
-}
-
-static gboolean
-gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps)
-{
-  GstInputSelector *sel;
-  gboolean res;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-
-  GST_DEBUG_OBJECT (sel, "Checking acceptcaps of srcpad peer");
-  res = gst_pad_peer_accept_caps (sel->srcpad, caps);
-  gst_object_unref (sel);
-
-  return res;
-}
-
-static GstFlowReturn
-gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf)
-{
-  GstInputSelector *sel;
-  GstFlowReturn result;
-  GstPad *active_sinkpad;
-  GstPad *prev_active_sinkpad;
-  GstSelectorPad *selpad;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  selpad = GST_SELECTOR_PAD_CAST (pad);
-
-  GST_LOG_OBJECT (pad, "received alloc");
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  prev_active_sinkpad = sel->active_sinkpad;
-  active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
-
-  if (pad != active_sinkpad)
-    goto not_active;
-
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad)
-    g_object_notify (G_OBJECT (sel), "active-pad");
-
-  result = gst_pad_alloc_buffer (sel->srcpad, offset, size, caps, buf);
-
-done:
-  gst_object_unref (sel);
-
-  return result;
-
-  /* ERRORS */
-not_active:
-  {
-    GST_INPUT_SELECTOR_UNLOCK (sel);
-
-    /* unselected pad, perform fallback alloc or return unlinked when
-     * asked */
-    GST_OBJECT_LOCK (selpad);
-    if (selpad->always_ok) {
-      GST_DEBUG_OBJECT (pad, "Not selected, performing fallback allocation");
-      *buf = NULL;
-      result = GST_FLOW_OK;
-    } else {
-      GST_DEBUG_OBJECT (pad, "Not selected, return NOT_LINKED");
-      result = GST_FLOW_NOT_LINKED;
-    }
-    GST_OBJECT_UNLOCK (selpad);
-
-    goto done;
-  }
-}
-
-/* must be called with the SELECTOR_LOCK, will block while the pad is blocked 
- * or return TRUE when flushing */
-static gboolean
-gst_input_selector_wait (GstInputSelector * self, GstPad * pad)
-{
-  while (self->blocked && !self->flushing) {
-    /* we can be unlocked here when we are shutting down (flushing) or when we
-     * get unblocked */
-    GST_INPUT_SELECTOR_WAIT (self);
-  }
-  return self->flushing;
-}
-
-static GstFlowReturn
-gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
-{
-  GstInputSelector *sel;
-  GstFlowReturn res;
-  GstPad *active_sinkpad;
-  GstPad *prev_active_sinkpad;
-  GstSelectorPad *selpad;
-  GstClockTime start_time;
-  GstSegment *seg;
-  GstEvent *close_event = NULL, *start_event = NULL;
-  GstCaps *caps;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  selpad = GST_SELECTOR_PAD_CAST (pad);
-  seg = &selpad->segment;
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  /* wait or check for flushing */
-  if (gst_input_selector_wait (sel, pad))
-    goto flushing;
-
-  GST_LOG_OBJECT (pad, "getting active pad");
-
-  prev_active_sinkpad = sel->active_sinkpad;
-  active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
-
-  /* update the segment on the srcpad */
-  start_time = GST_BUFFER_TIMESTAMP (buf);
-  if (GST_CLOCK_TIME_IS_VALID (start_time)) {
-    GST_LOG_OBJECT (pad, "received start time %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (start_time));
-    if (GST_BUFFER_DURATION_IS_VALID (buf))
-      GST_LOG_OBJECT (pad, "received end time %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
-
-    GST_OBJECT_LOCK (pad);
-    gst_segment_set_last_stop (seg, seg->format, start_time);
-    GST_OBJECT_UNLOCK (pad);
-  }
-
-  /* Ignore buffers from pads except the selected one */
-  if (pad != active_sinkpad)
-    goto ignore;
-
-  if (G_UNLIKELY (sel->pending_close)) {
-    GstSegment *cseg = &sel->segment;
-
-    GST_DEBUG_OBJECT (sel,
-        "pushing close NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-        "format %d, "
-        "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-        G_GINT64_FORMAT, TRUE, cseg->rate, cseg->applied_rate, cseg->format,
-        cseg->start, cseg->stop, cseg->time);
-
-    /* create update segment */
-    close_event = gst_event_new_new_segment_full (TRUE, cseg->rate,
-        cseg->applied_rate, cseg->format, cseg->start, cseg->stop, cseg->time);
-
-    sel->pending_close = FALSE;
-  }
-  /* if we have a pending segment, push it out now */
-  if (G_UNLIKELY (selpad->segment_pending)) {
-    GST_DEBUG_OBJECT (pad,
-        "pushing pending NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-        "format %d, "
-        "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-        G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format,
-        seg->start, seg->stop, seg->time);
-
-    start_event = gst_event_new_new_segment_full (FALSE, seg->rate,
-        seg->applied_rate, seg->format, seg->start, seg->stop, seg->time);
-
-    selpad->segment_pending = FALSE;
-  }
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad)
-    g_object_notify (G_OBJECT (sel), "active-pad");
-
-  if (close_event)
-    gst_pad_push_event (sel->srcpad, close_event);
-
-  if (start_event)
-    gst_pad_push_event (sel->srcpad, start_event);
-
-  if (selpad->discont) {
-    buf = gst_buffer_make_metadata_writable (buf);
-
-    GST_DEBUG_OBJECT (pad, "Marking discont buffer %p", buf);
-    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
-    selpad->discont = FALSE;
-  }
-
-  /* forward */
-  GST_LOG_OBJECT (pad, "Forwarding buffer %p", buf);
-
-  if ((caps = GST_BUFFER_CAPS (buf))) {
-    if (GST_PAD_CAPS (sel->srcpad) != caps)
-      gst_pad_set_caps (sel->srcpad, caps);
-  }
-
-  res = gst_pad_push (sel->srcpad, buf);
-
-done:
-  gst_object_unref (sel);
-  return res;
-
-  /* dropped buffers */
-ignore:
-  {
-    GST_DEBUG_OBJECT (pad, "Pad not active, discard buffer %p", buf);
-    /* when we drop a buffer, we're creating a discont on this pad */
-    selpad->discont = TRUE;
-    GST_INPUT_SELECTOR_UNLOCK (sel);
-    gst_buffer_unref (buf);
-
-    /* figure out what to return upstream */
-    GST_OBJECT_LOCK (selpad);
-    if (selpad->always_ok)
-      res = GST_FLOW_OK;
-    else
-      res = GST_FLOW_NOT_LINKED;
-    GST_OBJECT_UNLOCK (selpad);
-
-    goto done;
-  }
-flushing:
-  {
-    GST_DEBUG_OBJECT (pad, "We are flushing, discard buffer %p", buf);
-    GST_INPUT_SELECTOR_UNLOCK (sel);
-    gst_buffer_unref (buf);
-    res = GST_FLOW_FLUSHING;
-    goto done;
-  }
-}
-
-static void gst_input_selector_init (GstInputSelector * sel);
-static void gst_input_selector_base_init (GstInputSelectorClass * klass);
-static void gst_input_selector_class_init (GstInputSelectorClass * klass);
-
-static void gst_input_selector_dispose (GObject * object);
-
-static void gst_input_selector_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_input_selector_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-
-static GstPad *gst_input_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused);
-static void gst_input_selector_release_pad (GstElement * element, GstPad * pad);
-
-static GstStateChangeReturn gst_input_selector_change_state (GstElement *
-    element, GstStateChange transition);
-
-static GstCaps *gst_input_selector_getcaps (GstPad * pad);
-static gboolean gst_input_selector_event (GstPad * pad, GstEvent * event);
-static gboolean gst_input_selector_query (GstPad * pad, GstQuery * query);
-static gint64 gst_input_selector_block (GstInputSelector * self);
-static void gst_input_selector_switch (GstInputSelector * self,
-    GstPad * pad, gint64 stop_time, gint64 start_time);
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_input_selector_get_type (void)
-{
-  static GType input_selector_type = 0;
-
-  if (!input_selector_type) {
-    static const GTypeInfo input_selector_info = {
-      sizeof (GstInputSelectorClass),
-      (GBaseInitFunc) gst_input_selector_base_init,
-      NULL,
-      (GClassInitFunc) gst_input_selector_class_init,
-      NULL,
-      NULL,
-      sizeof (GstInputSelector),
-      0,
-      (GInstanceInitFunc) gst_input_selector_init,
-    };
-    input_selector_type =
-        g_type_register_static (GST_TYPE_ELEMENT,
-        "GstCamerabinInputSelector", &input_selector_info, 0);
-    GST_DEBUG_CATEGORY_INIT (input_selector_debug,
-        "camerabin-input-selector", 0, "Camerabin input selector element");
-  }
-
-  return input_selector_type;
-}
-
-static void
-gst_input_selector_base_init (GstInputSelectorClass * klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_set_details_simple (element_class,
-      "Input selector", "Generic",
-      "N-to-1 input stream selectoring",
-      "Julien Moutte <julien@moutte.net>, "
-      "Jan Schmidt <thaytan@mad.scientist.com>, "
-      "Wim Taymans <wim.taymans@gmail.com>");
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_input_selector_sink_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_input_selector_src_factory));
-}
-
-static void
-gst_input_selector_class_init (GstInputSelectorClass * klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  /* FIXME: remove after confirming it is safe now */
-  g_type_class_ref (gst_selector_pad_get_type ());
-
-  gobject_class->dispose = gst_input_selector_dispose;
-
-  gobject_class->set_property = gst_input_selector_set_property;
-  gobject_class->get_property = gst_input_selector_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_N_PADS,
-      g_param_spec_uint ("n-pads", "Number of Pads",
-          "The number of sink pads", 0, G_MAXUINT, 0,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_ACTIVE_PAD,
-      g_param_spec_object ("active-pad", "Active pad",
-          "The currently active sink pad", GST_TYPE_PAD,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_SELECT_ALL,
-      g_param_spec_boolean ("select-all", "Select all mode",
-          "Forwards data from all input pads", FALSE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstInputSelector::block:
-   * @inputselector: the #GstInputSelector
-   *
-   * Block all sink pads in preparation for a switch. Returns the stop time of
-   * the current switch segment, as a running time, or 0 if there is no current
-   * active pad or the current active pad never received data.
-   */
-  gst_input_selector_signals[SIGNAL_BLOCK] =
-      g_signal_new ("block", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-      G_STRUCT_OFFSET (GstInputSelectorClass, block), NULL, NULL,
-      __gst_camerabin_marshal_INT64__VOID, G_TYPE_INT64, 0);
-  /**
-   * GstInputSelector::switch:
-   * @inputselector: the #GstInputSelector
-   * @pad:            the pad to switch to
-   * @stop_time:      running time at which to close the previous segment, or -1
-   *                  to use the running time of the previously active sink pad
-   * @start_time:     running time at which to start the new segment, or -1 to
-   *                  use the running time of the newly active sink pad
-   *
-   * Switch to a new feed. The segment opened by the previously active pad, if
-   * any, will be closed, and a new segment opened before data flows again.
-   *
-   * This signal must be emitted when the element has been blocked via the <link
-   * linkend="GstInputSelector-block">block</link> signal.
-   *
-   * If you have a stream with only one switch element, such as an audio-only
-   * stream, a stream switch should be performed by first emitting the block
-   * signal, and then emitting the switch signal with -1 for the stop and start
-   * time values.
-   *
-   * The intention of the @stop_time and @start_time arguments is to allow
-   * multiple switch elements to switch and maintain stream synchronization.
-   * When switching a stream with multiple feeds, you will need as many switch
-   * elements as you have feeds. For example, a feed with audio and video will
-   * have one switch element between the audio feeds and one for video.
-   *
-   * A switch over multiple switch elements should be performed as follows:
-   * First, emit the <link linkend="GstInputSelector-block">block</link>
-   * signal, collecting the returned values. The maximum running time returned
-   * by block should then be used as the time at which to close the previous
-   * segment.
-   *
-   * Then, query the running times of the new audio and video pads that you will
-   * switch to. Naturally, these pads are on separate switch elements. Take the
-   * minimum running time for those streams and use it for the time at which to
-   * open the new segment.
-   *
-   * If @pad is the same as the current active pad, the element will cancel any
-   * previous block without adjusting segments.
-   *
-   * <note><simpara>
-   * the signal changed from accepting the pad name to the pad object.
-   * </simpara></note>
-   *
-   * Since: 0.10.7
-   */
-  gst_input_selector_signals[SIGNAL_SWITCH] =
-      g_signal_new ("switch", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstInputSelectorClass, switch_),
-      NULL, NULL, __gst_camerabin_marshal_VOID__OBJECT_INT64_INT64,
-      G_TYPE_NONE, 3, GST_TYPE_PAD, G_TYPE_INT64, G_TYPE_INT64);
-
-  gstelement_class->request_new_pad = gst_input_selector_request_new_pad;
-  gstelement_class->release_pad = gst_input_selector_release_pad;
-  gstelement_class->change_state = gst_input_selector_change_state;
-
-  klass->block = GST_DEBUG_FUNCPTR (gst_input_selector_block);
-  /* note the underscore because switch is a keyword otherwise */
-  klass->switch_ = GST_DEBUG_FUNCPTR (gst_input_selector_switch);
-}
-
-static void
-gst_input_selector_init (GstInputSelector * sel)
-{
-  sel->srcpad = gst_pad_new ("src", GST_PAD_SRC);
-  gst_pad_set_iterate_internal_links_function (sel->srcpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
-  gst_pad_set_getcaps_function (sel->srcpad,
-      GST_DEBUG_FUNCPTR (gst_input_selector_getcaps));
-  gst_pad_set_query_function (sel->srcpad,
-      GST_DEBUG_FUNCPTR (gst_input_selector_query));
-  gst_pad_set_event_function (sel->srcpad,
-      GST_DEBUG_FUNCPTR (gst_input_selector_event));
-  gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad);
-  /* sinkpad management */
-  sel->active_sinkpad = NULL;
-  sel->padcount = 0;
-  gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
-
-  sel->lock = g_mutex_new ();
-  sel->cond = g_cond_new ();
-  sel->blocked = FALSE;
-
-  sel->select_all = FALSE;
-}
-
-static void
-gst_input_selector_dispose (GObject * object)
-{
-  GstInputSelector *sel = GST_INPUT_SELECTOR (object);
-
-  if (sel->active_sinkpad) {
-    gst_object_unref (sel->active_sinkpad);
-    sel->active_sinkpad = NULL;
-  }
-  if (sel->lock) {
-    g_mutex_free (sel->lock);
-    sel->lock = NULL;
-  }
-  if (sel->cond) {
-    g_cond_free (sel->cond);
-    sel->cond = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/* Solve the following equation for B.timestamp, and set that as the segment
- * stop:
- * B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum
- */
-static gint64
-gst_segment_get_timestamp (GstSegment * segment, gint64 running_time)
-{
-  if (running_time <= segment->accum)
-    return segment->start;
-  else
-    return (running_time - segment->accum) * segment->abs_rate + segment->start;
-}
-
-static void
-gst_segment_set_stop (GstSegment * segment, gint64 running_time)
-{
-  segment->stop = gst_segment_get_timestamp (segment, running_time);
-  segment->last_stop = -1;
-}
-
-static void
-gst_segment_set_start (GstSegment * segment, gint64 running_time)
-{
-  gint64 new_start, duration;
-
-  new_start = gst_segment_get_timestamp (segment, running_time);
-
-  /* this is the duration we skipped */
-  duration = new_start - segment->start;
-  /* add the duration to the accumulated segment time */
-  segment->accum += duration;
-  /* move position in the segment */
-  segment->time += duration;
-  segment->start += duration;
-}
-
-/* this function must be called with the SELECTOR_LOCK. It returns TRUE when the
- * active pad changed. */
-static gboolean
-gst_input_selector_set_active_pad (GstInputSelector * self,
-    GstPad * pad, gint64 stop_time, gint64 start_time)
-{
-  GstSelectorPad *old, *new;
-  GstPad **active_pad_p;
-
-  if (pad == self->active_sinkpad)
-    return FALSE;
-
-  old = GST_SELECTOR_PAD_CAST (self->active_sinkpad);
-  new = GST_SELECTOR_PAD_CAST (pad);
-
-  GST_DEBUG_OBJECT (self, "setting active pad to %s:%s",
-      GST_DEBUG_PAD_NAME (new));
-
-  if (!GST_CLOCK_TIME_IS_VALID (stop_time) && old) {
-    /* no stop time given, get the latest running_time on the active pad to 
-     * close and open the new segment */
-    stop_time = start_time = gst_selector_pad_get_running_time (old);
-    GST_DEBUG_OBJECT (self, "using start/stop of %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (start_time));
-  }
-
-  if (old && old->active && !self->pending_close && stop_time >= 0) {
-    /* schedule a last_stop update if one isn't already scheduled, and a
-       segment has been pushed before. */
-    memcpy (&self->segment, &old->segment, sizeof (self->segment));
-
-    GST_DEBUG_OBJECT (self, "setting stop_time to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (stop_time));
-    gst_segment_set_stop (&self->segment, stop_time);
-    self->pending_close = TRUE;
-  }
-
-  if (new && new->active && start_time >= 0) {
-    GST_DEBUG_OBJECT (self, "setting start_time to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (start_time));
-    /* schedule a new segment push */
-    gst_segment_set_start (&new->segment, start_time);
-    new->segment_pending = TRUE;
-  }
-
-  active_pad_p = &self->active_sinkpad;
-  gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad));
-  GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT,
-      self->active_sinkpad);
-
-  return TRUE;
-}
-
-static void
-gst_input_selector_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstInputSelector *sel = GST_INPUT_SELECTOR (object);
-
-  switch (prop_id) {
-    case PROP_ACTIVE_PAD:
-    {
-      GstPad *pad;
-
-      pad = g_value_get_object (value);
-
-      GST_INPUT_SELECTOR_LOCK (sel);
-      gst_input_selector_set_active_pad (sel, pad,
-          GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE);
-      GST_INPUT_SELECTOR_UNLOCK (sel);
-      break;
-    }
-    case PROP_SELECT_ALL:
-      GST_INPUT_SELECTOR_LOCK (object);
-      sel->select_all = g_value_get_boolean (value);
-      GST_INPUT_SELECTOR_UNLOCK (object);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_input_selector_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstInputSelector *sel = GST_INPUT_SELECTOR (object);
-
-  switch (prop_id) {
-    case PROP_N_PADS:
-      GST_INPUT_SELECTOR_LOCK (object);
-      g_value_set_uint (value, sel->n_pads);
-      GST_INPUT_SELECTOR_UNLOCK (object);
-      break;
-    case PROP_ACTIVE_PAD:
-      GST_INPUT_SELECTOR_LOCK (object);
-      g_value_set_object (value, sel->active_sinkpad);
-      GST_INPUT_SELECTOR_UNLOCK (object);
-      break;
-    case PROP_SELECT_ALL:
-      GST_INPUT_SELECTOR_LOCK (object);
-      g_value_set_boolean (value, sel->select_all);
-      GST_INPUT_SELECTOR_UNLOCK (object);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static GstPad *
-gst_input_selector_get_linked_pad (GstPad * pad, gboolean strict)
-{
-  GstInputSelector *sel;
-  GstPad *otherpad = NULL;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  if (pad == sel->srcpad)
-    otherpad = sel->active_sinkpad;
-  else if (pad == sel->active_sinkpad || !strict)
-    otherpad = sel->srcpad;
-  if (otherpad)
-    gst_object_ref (otherpad);
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  gst_object_unref (sel);
-
-  return otherpad;
-}
-
-static gboolean
-gst_input_selector_event (GstPad * pad, GstEvent * event)
-{
-  gboolean res = FALSE;
-  GstPad *otherpad;
-  GstInputSelector *sel;
-  GstIterator *iter;
-  gboolean done;
-  gpointer nextpad;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  otherpad = gst_input_selector_get_linked_pad (pad, TRUE);
-
-  if (otherpad) {
-    res = gst_pad_push_event (otherpad, event);
-
-    gst_object_unref (otherpad);
-  } else if (sel->select_all) {
-
-    /* If select-all is set, we should push the event to all pads.
-     * The result will be TRUE if the push works for any of the pads, even if a
-     * push fails. This is coherent with the way camerabin uses input-selector,
-     * but might not be for other uses of it. */
-
-    iter = gst_element_iterate_sink_pads (GST_ELEMENT (sel));
-
-    done = FALSE;
-    while (!done) {
-      switch (gst_iterator_next (iter, &nextpad)) {
-        case GST_ITERATOR_OK:
-          res |= gst_pad_push_event (nextpad, gst_event_ref (event));
-          gst_object_unref (nextpad);
-          break;
-        case GST_ITERATOR_RESYNC:
-          gst_iterator_resync (iter);
-          break;
-        case GST_ITERATOR_ERROR:
-          GST_WARNING_OBJECT (sel,
-              "Wrong parameters when retrieving sink pads");
-          done = TRUE;
-          break;
-        case GST_ITERATOR_DONE:
-          done = TRUE;
-          break;
-      }
-    }
-    gst_event_unref (event);
-    gst_iterator_free (iter);
-  } else
-    gst_event_unref (event);
-
-  gst_object_unref (sel);
-
-  return res;
-}
-
-/* query on the srcpad. We override this function because by default it will
- * only forward the query to one random sinkpad */
-static gboolean
-gst_input_selector_query (GstPad * pad, GstQuery * query)
-{
-  gboolean res = TRUE;
-  GstInputSelector *sel;
-  GstPad *otherpad;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-
-  otherpad = gst_input_selector_get_linked_pad (pad, TRUE);
-
-  switch (GST_QUERY_TYPE (query)) {
-    case GST_QUERY_LATENCY:
-    {
-      GList *walk;
-      GstClockTime resmin, resmax;
-      gboolean reslive;
-
-      resmin = 0;
-      resmax = -1;
-      reslive = FALSE;
-
-      /* assume FALSE, we become TRUE if one query succeeds */
-      res = FALSE;
-
-      /* perform the query on all sinkpads and combine the results. We take the
-       * max of min and the min of max for the result latency. */
-      GST_INPUT_SELECTOR_LOCK (sel);
-      for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk;
-          walk = g_list_next (walk)) {
-        GstPad *sinkpad = GST_PAD_CAST (walk->data);
-
-        if (gst_pad_peer_query (sinkpad, query)) {
-          GstClockTime min, max;
-          gboolean live;
-
-          /* one query succeeded, we succeed too */
-          res = TRUE;
-
-          gst_query_parse_latency (query, &live, &min, &max);
-
-          GST_DEBUG_OBJECT (sinkpad,
-              "peer latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
-              ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live);
-
-          if (live) {
-            if (min > resmin)
-              resmin = min;
-            if (resmax == -1)
-              resmax = max;
-            else if (max < resmax)
-              resmax = max;
-            if (reslive == FALSE)
-              reslive = live;
-          }
-        }
-      }
-      GST_INPUT_SELECTOR_UNLOCK (sel);
-      if (res) {
-        gst_query_set_latency (query, reslive, resmin, resmax);
-
-        GST_DEBUG_OBJECT (sel,
-            "total latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
-            ", live %d", GST_TIME_ARGS (resmin), GST_TIME_ARGS (resmax),
-            reslive);
-      }
-
-      break;
-    }
-    default:
-      if (otherpad)
-        res = gst_pad_peer_query (otherpad, query);
-      break;
-  }
-  if (otherpad)
-    gst_object_unref (otherpad);
-  gst_object_unref (sel);
-
-  return res;
-}
-
-static GstCaps *
-gst_input_selector_getcaps (GstPad * pad)
-{
-  GstPad *otherpad;
-  GstObject *parent;
-  GstCaps *caps;
-
-  parent = gst_object_get_parent (GST_OBJECT (pad));
-
-  otherpad = gst_input_selector_get_linked_pad (pad, FALSE);
-
-  if (!otherpad) {
-    if (GST_INPUT_SELECTOR (parent)->select_all) {
-      GST_DEBUG_OBJECT (parent,
-          "Pad %s:%s not linked, returning merge of caps",
-          GST_DEBUG_PAD_NAME (pad));
-      caps = gst_pad_proxy_getcaps (pad);
-    } else {
-      GST_DEBUG_OBJECT (parent,
-          "Pad %s:%s not linked, returning ANY", GST_DEBUG_PAD_NAME (pad));
-      caps = gst_caps_new_any ();
-    }
-  } else {
-    GST_DEBUG_OBJECT (parent,
-        "Pad %s:%s is linked (to %s:%s), returning peer caps",
-        GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (otherpad));
-    /* if the peer has caps, use those. If the pad is not linked, this function
-     * returns NULL and we return ANY */
-    if (!(caps = gst_pad_peer_get_caps_reffed (otherpad)))
-      caps = gst_caps_new_any ();
-    gst_object_unref (otherpad);
-  }
-
-  gst_object_unref (parent);
-  return caps;
-}
-
-/* check if the pad is the active sinkpad */
-static gboolean
-gst_input_selector_is_active_sinkpad (GstInputSelector * sel, GstPad * pad)
-{
-  gboolean res;
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  res = (pad == sel->active_sinkpad);
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  return res;
-}
-
-/* Get or create the active sinkpad, must be called with SELECTOR_LOCK */
-static GstPad *
-gst_input_selector_activate_sinkpad (GstInputSelector * sel, GstPad * pad)
-{
-  GstPad *active_sinkpad;
-  GstSelectorPad *selpad;
-
-  selpad = GST_SELECTOR_PAD_CAST (pad);
-
-  selpad->active = TRUE;
-  active_sinkpad = sel->active_sinkpad;
-  if (active_sinkpad == NULL || sel->select_all) {
-    /* first pad we get activity on becomes the activated pad by default, if we
-     * select all, we also remember the last used pad. */
-    if (sel->active_sinkpad)
-      gst_object_unref (sel->active_sinkpad);
-    active_sinkpad = sel->active_sinkpad = gst_object_ref (pad);
-    GST_DEBUG_OBJECT (sel, "Activating pad %s:%s", GST_DEBUG_PAD_NAME (pad));
-  }
-
-  return active_sinkpad;
-}
-
-static GstPad *
-gst_input_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused)
-{
-  GstInputSelector *sel;
-  gchar *name = NULL;
-  GstPad *sinkpad = NULL;
-
-  g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL);
-
-  sel = GST_INPUT_SELECTOR (element);
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-
-  GST_LOG_OBJECT (sel, "Creating new pad %d", sel->padcount);
-  name = g_strdup_printf ("sink_%u", sel->padcount++);
-  sinkpad = g_object_new (GST_TYPE_SELECTOR_PAD,
-      "name", name, "direction", templ->direction, "template", templ, NULL);
-  g_free (name);
-
-  sel->n_pads++;
-
-  gst_pad_set_event_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_event));
-  gst_pad_set_getcaps_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_getcaps));
-  gst_pad_set_acceptcaps_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_acceptcaps));
-  gst_pad_set_chain_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_chain));
-  gst_pad_set_iterate_internal_links_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
-  gst_pad_set_bufferalloc_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc));
-
-  gst_pad_set_active (sinkpad, TRUE);
-  gst_element_add_pad (GST_ELEMENT (sel), sinkpad);
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  return sinkpad;
-}
-
-static void
-gst_input_selector_release_pad (GstElement * element, GstPad * pad)
-{
-  GstInputSelector *sel;
-
-  sel = GST_INPUT_SELECTOR (element);
-  GST_LOG_OBJECT (sel, "Releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  /* if the pad was the active pad, makes us select a new one */
-  if (sel->active_sinkpad == pad) {
-    GST_DEBUG_OBJECT (sel, "Deactivating pad %s:%s", GST_DEBUG_PAD_NAME (pad));
-    gst_object_unref (sel->active_sinkpad);
-    sel->active_sinkpad = NULL;
-  }
-  sel->n_pads--;
-
-  gst_pad_set_active (pad, FALSE);
-  gst_element_remove_pad (GST_ELEMENT (sel), pad);
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-}
-
-static void
-gst_input_selector_reset (GstInputSelector * sel)
-{
-  GList *walk;
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  /* clear active pad */
-  if (sel->active_sinkpad) {
-    gst_object_unref (sel->active_sinkpad);
-    sel->active_sinkpad = NULL;
-  }
-  /* reset segment */
-  gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
-  sel->pending_close = FALSE;
-  /* reset each of our sinkpads state */
-  for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk; walk = g_list_next (walk)) {
-    GstSelectorPad *selpad = GST_SELECTOR_PAD_CAST (walk->data);
-
-    gst_selector_pad_reset (selpad);
-
-    if (selpad->tags) {
-      gst_tag_list_free (selpad->tags);
-      selpad->tags = NULL;
-    }
-  }
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-}
-
-static GstStateChangeReturn
-gst_input_selector_change_state (GstElement * element,
-    GstStateChange transition)
-{
-  GstInputSelector *self = GST_INPUT_SELECTOR (element);
-  GstStateChangeReturn result;
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      GST_INPUT_SELECTOR_LOCK (self);
-      self->blocked = FALSE;
-      self->flushing = FALSE;
-      GST_INPUT_SELECTOR_UNLOCK (self);
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* first unlock before we call the parent state change function, which
-       * tries to acquire the stream lock when going to ready. */
-      GST_INPUT_SELECTOR_LOCK (self);
-      self->blocked = FALSE;
-      self->flushing = TRUE;
-      GST_INPUT_SELECTOR_BROADCAST (self);
-      GST_INPUT_SELECTOR_UNLOCK (self);
-      break;
-    default:
-      break;
-  }
-
-  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      gst_input_selector_reset (self);
-      break;
-    default:
-      break;
-  }
-
-  return result;
-}
-
-static gint64
-gst_input_selector_block (GstInputSelector * self)
-{
-  gint64 ret = 0;
-  GstSelectorPad *spad;
-
-  GST_INPUT_SELECTOR_LOCK (self);
-
-  if (self->blocked)
-    GST_WARNING_OBJECT (self, "switch already blocked");
-
-  self->blocked = TRUE;
-  spad = GST_SELECTOR_PAD_CAST (self->active_sinkpad);
-
-  if (spad)
-    ret = gst_selector_pad_get_running_time (spad);
-  else
-    GST_DEBUG_OBJECT (self, "no active pad while blocking");
-
-  GST_INPUT_SELECTOR_UNLOCK (self);
-
-  return ret;
-}
-
-/* stop_time and start_time are running times */
-static void
-gst_input_selector_switch (GstInputSelector * self, GstPad * pad,
-    gint64 stop_time, gint64 start_time)
-{
-  gboolean changed;
-
-  g_return_if_fail (self->blocked == TRUE);
-
-  GST_INPUT_SELECTOR_LOCK (self);
-  changed =
-      gst_input_selector_set_active_pad (self, pad, stop_time, start_time);
-
-  self->blocked = FALSE;
-  GST_INPUT_SELECTOR_BROADCAST (self);
-  GST_INPUT_SELECTOR_UNLOCK (self);
-
-  if (changed)
-    g_object_notify (G_OBJECT (self), "active-pad");
-}
-
-static gboolean
-gst_input_selector_check_eos (GstElement * selector)
-{
-  GstIterator *it = gst_element_iterate_sink_pads (selector);
-  GstIteratorResult ires;
-  gpointer item;
-  gboolean done = FALSE, is_eos = FALSE;
-  GstSelectorPad *pad;
-
-  while (!done) {
-    ires = gst_iterator_next (it, &item);
-    switch (ires) {
-      case GST_ITERATOR_DONE:
-        GST_INFO_OBJECT (selector, "all sink pads have eos");
-        done = TRUE;
-        is_eos = TRUE;
-        break;
-      case GST_ITERATOR_OK:
-        pad = GST_SELECTOR_PAD_CAST (item);
-        if (!pad->eos) {
-          done = TRUE;
-        }
-        gst_object_unref (pad);
-        break;
-      case GST_ITERATOR_RESYNC:
-        gst_iterator_resync (it);
-        break;
-      default:
-        done = TRUE;
-        break;
-    }
-  }
-  gst_iterator_free (it);
-
-  return is_eos;
-}
diff --git a/gst/camerabin/gstinputselector.h b/gst/camerabin/gstinputselector.h
deleted file mode 100644 (file)
index 58a671d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* GStreamer
- * Copyright (C) 2003 Julien Moutte <julien@moutte.net>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2008 Nokia Corporation. (contact <stefan.kost@nokia.com>)
- *
- * 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_INPUT_SELECTOR_H__
-#define __GST_INPUT_SELECTOR_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_INPUT_SELECTOR \
-  (gst_input_selector_get_type())
-#define GST_INPUT_SELECTOR(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_INPUT_SELECTOR, GstInputSelector))
-#define GST_INPUT_SELECTOR_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_INPUT_SELECTOR, GstInputSelectorClass))
-#define GST_IS_INPUT_SELECTOR(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INPUT_SELECTOR))
-#define GST_IS_INPUT_SELECTOR_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_INPUT_SELECTOR))
-
-typedef struct _GstInputSelector GstInputSelector;
-typedef struct _GstInputSelectorClass GstInputSelectorClass;
-
-#define GST_INPUT_SELECTOR_GET_LOCK(sel) (((GstInputSelector*)(sel))->lock)
-#define GST_INPUT_SELECTOR_GET_COND(sel) (((GstInputSelector*)(sel))->cond)
-#define GST_INPUT_SELECTOR_LOCK(sel) (g_mutex_lock (GST_INPUT_SELECTOR_GET_LOCK(sel)))
-#define GST_INPUT_SELECTOR_UNLOCK(sel) (g_mutex_unlock (GST_INPUT_SELECTOR_GET_LOCK(sel)))
-#define GST_INPUT_SELECTOR_WAIT(sel) (g_cond_wait (GST_INPUT_SELECTOR_GET_COND(sel), \
-                       GST_INPUT_SELECTOR_GET_LOCK(sel)))
-#define GST_INPUT_SELECTOR_BROADCAST(sel) (g_cond_broadcast (GST_INPUT_SELECTOR_GET_COND(sel)))
-
-struct _GstInputSelector {
-  GstElement element;
-
-  GstPad *srcpad;
-
-  GstPad *active_sinkpad;
-  guint n_pads;
-  guint padcount;
-
-  GstSegment segment;      /* the output segment */
-  gboolean pending_close;  /* if we should push a close first */
-
-  GMutex *lock;
-  GCond *cond;
-  gboolean blocked;
-  gboolean flushing;
-
-  /* select all mode, send data from all input pads forward */
-  gboolean select_all;
-};
-
-struct _GstInputSelectorClass {
-  GstElementClass parent_class;
-
-  gint64 (*block)      (GstInputSelector *self);
-  void (*switch_)      (GstInputSelector *self, GstPad *pad,
-                         gint64 stop_time, gint64 start_time);
-};
-
-GType gst_input_selector_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_INPUT_SELECTOR_H__ */
index 6d4f297..0ef573d 100644 (file)
@@ -14,7 +14,7 @@ TESTS_ENVIRONMENT = \
        GST_PLUGIN_SYSTEM_PATH=                                 \
        GST_PLUGIN_PATH=$(top_builddir)/gst:$(top_builddir)/sys:$(top_builddir)/ext:$(GST_PLUGINS_FFMPEG_DIR):$(GST_PLUGINS_UGLY_DIR):$(GST_PLUGINS_GOOD_DIR):$(GST_PLUGINS_BASE_DIR):$(GST_PLUGINS_DIR) \
        GST_PLUGIN_LOADING_WHITELIST="gstreamer@$(GST_PLUGINS_DIR):gst-plugins-base@$(GSTPB_PLUGINS_DIR):gst-plugins-good:gst-plugins-ugly:gst-ffmpeg:gst-plugins-bad@$(top_builddir)" \
-       GST_STATE_IGNORE_ELEMENTS="apexsink camerabin camerabin2 cdaudio dc1394src \
+       GST_STATE_IGNORE_ELEMENTS="apexsink camerabin cdaudio dc1394src \
            dccpclientsrc dccpclientsink dccpserversrc dccpserversink decklinksrc \
            decklinksink dvbsrc dvbbasebin dfbvideosink festival gsettingsvideosrc \
            gsettingsvideosink gsettingsaudiosrc gsettingsaudiosink linsyssdisrc linsyssdisink nassink \
@@ -182,7 +182,6 @@ check_PROGRAMS = \
        elements/asfmux \
        elements/baseaudiovisualizer \
        elements/camerabin \
-        elements/camerabin2 \
        elements/dataurisrc \
        elements/legacyresample \
         $(check_jifmux) \
@@ -306,21 +305,11 @@ elements_camerabin_CFLAGS = \
        $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
        $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS) -DGST_USE_UNSTABLE_API
 elements_camerabin_LDADD = \
-       $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
-       $(GST_PLUGINS_BASE_LIBS) \
-       $(GST_BASE_LIBS) $(GST_LIBS) $(LDADD)
-
-elements_camerabin_SOURCES = elements/camerabin.c
-
-elements_camerabin2_CFLAGS = \
-       $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
-       $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS) -DGST_USE_UNSTABLE_API
-elements_camerabin2_LDADD = \
         $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
         $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la \
         -lgstpbutils-$(GST_API_VERSION) \
         $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) $(LDADD)
-elements_camerabin2_SOURCES = elements/camerabin2.c
+elements_camerabin_SOURCES = elements/camerabin.c
 
 elements_jifmux_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(EXIF_CFLAGS) $(AM_CFLAGS)
 elements_jifmux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) $(GST_CHECK_LIBS) $(EXIF_LIBS) $(LDADD)
index 6d353d9..d8bea46 100644 (file)
@@ -1,7 +1,8 @@
 /* GStreamer
  *
- * unit test for camerabin basic operations
- * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
+ * unit test for camerabin2 basic operations
+ * Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
  *
  *
  * This library is free software; you can redistribute it and/or
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <gst/gst.h>
+#include <gst/video/video.h>
 #include <gst/check/gstcheck.h>
-#include <gst/interfaces/photography.h>
+#include <gst/basecamerabinsrc/gstbasecamerasrc.h>
+#include <gst/pbutils/encoding-profile.h>
 
-#define SINGLE_IMAGE_FILENAME "image"
-#define SINGLE_IMAGE_WITH_FLAGS_FILENAME "image_with_flags"
-#define SEQUENTIAL_IMAGES_FILENAME "sequential_image"
-#define BURST_IMAGE_FILENAME "burst_image"
+#define IMAGE_FILENAME "image"
 #define VIDEO_FILENAME "video"
-#define VIDEO_WITH_FLAGS_FILENAME "video_with_flags"
-#define VIDEO_PAUSE_FILENAME "video_pause"
-#define VIDEO_NOAUDIO_FILENAME "video_noaudio"
-#define CYCLE_IMAGE_FILENAME "cycle_image"
-#define CYCLE_VIDEO_FILENAME "cycle_video"
-#define TAGLISTS_COUNT 3
-#define CYCLE_COUNT_MAX 2
-#define SEQUENTIAL_IMAGES_COUNT 3
-#define MAX_BURST_IMAGES 10
-#define PHOTO_SETTING_DELAY_US 0
+#define CAPTURE_COUNT 3
+#define VIDEO_DURATION 5
+
+#define VIDEO_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=600, height=480"
+#define IMAGE_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=800, height=600"
+
+/* custom test camera src element */
+#define GST_TYPE_TEST_CAMERA_SRC \
+  (gst_test_camera_src_get_type())
+#define GST_TEST_CAMERA_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrc))
+#define GST_TEST_CAMERA_SRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrcClass))
+#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEST_CAMERA_SRC))
+#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEST_CAMERA_SRC))
+#define GST_TEST_CAMERA_SRC_CAST(obj) ((GstTestCameraSrc *)obj)
+
+typedef struct _GstTestCameraSrc GstTestCameraSrc;
+typedef struct _GstTestCameraSrcClass GstTestCameraSrcClass;
+struct _GstTestCameraSrc
+{
+  GstBaseCameraSrc element;
 
-static GstElement *camera;
-static guint bus_source;
-static GMainLoop *main_loop;
-static guint cycle_count = 0;
-static gboolean received_preview_msg = FALSE;
-static GstTagList *taglists[TAGLISTS_COUNT];
-static GstTagList *validation_taglist;
+  GstPad *vfpad;
+  GstPad *vidpad;
+  GstPad *imgpad;
 
-/* helper function for filenames */
-static const gchar *
-make_test_file_name (const gchar * base_name, gint num)
+  GstCameraBinMode mode;
+};
+
+struct _GstTestCameraSrcClass
 {
-  static gchar file_name[1000];
+  GstBaseCameraSrcClass parent_class;
+};
 
-  g_snprintf (file_name, 999, "%s" G_DIR_SEPARATOR_S
-      "gstcamerabintest_%s_%03d.cap", g_get_tmp_dir (), base_name, num);
+GType gst_test_camera_src_get_type (void);
 
-  GST_INFO ("capturing to: %s (cycle: %d)", file_name, cycle_count);
-  return file_name;
-}
+#define gst_test_camera_src_parent_class parent_class
+G_DEFINE_TYPE (GstTestCameraSrc, gst_test_camera_src, GST_TYPE_BASE_CAMERA_SRC);
 
-/* burst capture is not supported in camerabin for the moment */
-#ifdef ENABLE_BURST_CAPTURE
-static const gchar *
-make_test_seq_file_name (const gchar * base_name)
+static gboolean
+gst_test_camera_src_set_mode (GstBaseCameraSrc * src, GstCameraBinMode mode)
 {
-  static gchar file_name[1000];
+  GstTestCameraSrc *self = GST_TEST_CAMERA_SRC (src);
 
-  g_snprintf (file_name, 999, "%s" G_DIR_SEPARATOR_S "%02u_%s",
-      g_get_tmp_dir (), captured_images, base_name);
-
-  GST_INFO ("capturing to: %s", file_name);
-  return file_name;
+  self->mode = mode;
+  return TRUE;
 }
-#endif
-/* signal handlers */
 
 static gboolean
-handle_image_captured_cb (gpointer data)
+gst_test_camera_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
-  GMainLoop *loop = (GMainLoop *) data;
+  GstTestCameraSrc *self = (GstTestCameraSrc *) GST_PAD_PARENT (pad);
+  GstCaps *result = NULL;
+  gboolean ret = FALSE;
 
-  /* unblock viewfinder */
-  g_object_set (camera, "block-after-capture", FALSE, NULL);
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:
+      if (pad == self->vfpad) {
+        result = gst_caps_new_any ();
+      } else if (pad == self->vidpad) {
+        result = gst_caps_from_string (VIDEO_PAD_SUPPORTED_CAPS);
+      } else if (pad == self->imgpad) {
+        result = gst_caps_from_string (IMAGE_PAD_SUPPORTED_CAPS);
+      } else {
+        g_assert_not_reached ();
+      }
+      if (result) {
+        GstCaps *filter;
+
+        gst_query_parse_caps (query, &filter);
+        if (filter) {
+          GstCaps *tmp;
+          tmp = gst_caps_intersect (result, filter);
+          gst_caps_replace (&result, tmp);
+          gst_caps_unref (tmp);
+        }
+        gst_query_set_caps_result (query, result);
+        ret = TRUE;
+      }
+      break;
+    default:
+      break;
+  }
 
-  GST_DEBUG ("handle_image_captured_cb, cycle: %d", cycle_count);
-  if (cycle_count == 0) {
-    GST_DEBUG ("all cycles done");
-    g_main_loop_quit (loop);
-  } else {
-    /* Set video recording mode */
-    g_object_set (camera, "mode", 1,
-        "filename", make_test_file_name (CYCLE_VIDEO_FILENAME, cycle_count),
-        NULL);
-    /* Record video */
-    g_signal_emit_by_name (camera, "capture-start", NULL);
-    g_usleep (G_USEC_PER_SEC);
-    g_signal_emit_by_name (camera, "capture-stop", NULL);
-    GST_DEBUG ("video captured");
-
-    /* Set still image mode */
-    g_object_set (camera, "mode", 0,
-        "filename", make_test_file_name (CYCLE_IMAGE_FILENAME, cycle_count),
-        NULL);
-
-    cycle_count--;
-    GST_DEBUG ("next cycle: %d", cycle_count);
-
-    /* Take a picture */
-    g_signal_emit_by_name (camera, "capture-start", NULL);
-  }
-  GST_DEBUG ("handle_image_captured_cb done");
-  return FALSE;
+  return ret;
 }
 
-static gboolean
-capture_done (GstElement * elem, const gchar * filename, gpointer user_data)
+static void
+gst_test_camera_src_class_init (GstTestCameraSrcClass * klass)
 {
-  GMainLoop *loop = (GMainLoop *) user_data;
+  GstBaseCameraSrcClass *gstbasecamera_class;
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
 
-  g_idle_add ((GSourceFunc) handle_image_captured_cb, loop);
+  gstbasecamera_class = GST_BASE_CAMERA_SRC_CLASS (klass);
+  gstbasecamera_class->set_mode = gst_test_camera_src_set_mode;
 
-  GST_INFO ("image saved");
+  gst_element_class_set_details_simple (gstelement_class,
+      "Test Camera Src",
+      "Camera/Src",
+      "Some test camera src",
+      "Thiago Santos <thiago.sousa.santos@collabora.com>");
+}
 
-  return FALSE;
+static void
+gst_test_camera_src_init (GstTestCameraSrc * self)
+{
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (parent_class);
+  GstPadTemplate *template;
+
+  /* create pads */
+  template = gst_element_class_get_pad_template (gstelement_class,
+      GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME);
+  self->vfpad = gst_pad_new_from_template (template,
+      GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME);
+  gst_element_add_pad (GST_ELEMENT_CAST (self), self->vfpad);
+
+  template = gst_element_class_get_pad_template (gstelement_class,
+      GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);
+  self->imgpad = gst_pad_new_from_template (template,
+      GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);
+  gst_element_add_pad (GST_ELEMENT_CAST (self), self->imgpad);
+
+  template = gst_element_class_get_pad_template (gstelement_class,
+      GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
+  self->vidpad = gst_pad_new_from_template (template,
+      GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
+  gst_element_add_pad (GST_ELEMENT_CAST (self), self->vidpad);
+
+  /* add get caps functions */
+  gst_pad_set_query_function (self->vfpad, gst_test_camera_src_query);
+  gst_pad_set_query_function (self->vidpad, gst_test_camera_src_query);
+  gst_pad_set_query_function (self->imgpad, gst_test_camera_src_query);
 }
 
-/* configuration */
+/* end of custom test camera src element */
+
+
+static GstElement *camera;
+static guint bus_source;
+static GMainLoop *main_loop;
+static gint capture_count = 0;
+guint32 test_id = 0;
+static gchar *image_filename;
+static gchar *video_filename;
+
+static GstBuffer *preview_buffer;
+static gchar *preview_filename;
+static GstCaps *preview_caps;
+static GstTagList *tags_found;
 
 static gboolean
-set_and_check_camerabin_element (GstElement * camera, const char *property,
-    GstElement * element)
-{
-  GstElement *element_check;
-  gboolean ret = FALSE;
+validity_bus_cb (GstBus * bus, GstMessage * message, gpointer data);
 
-  if (element) {
-    g_object_set (camera, property, element, NULL);
-    g_object_get (camera, property, &element_check, NULL);
-    if (element_check == element)
-      ret = TRUE;
-    if (element_check)
-      g_object_unref (element_check);
-  }
-  return ret;
-}
+static GstMessage *wait_for_element_message (GstElement * camera,
+    const gchar * name, GstClockTime timeout);
 
 static void
-setup_camerabin_elements (GstElement * camera)
+validate_taglist_foreach (const GstTagList * list, const gchar * tag,
+    gpointer user_data)
 {
-  GstElement *vfsink, *audiosrc, *videosrc, *audioenc, *videoenc, *imageenc,
-      *videomux, *viewfinder_filter, *imagepp, *videopp, *formatter;
-  GstCaps *audiocaps, *videocaps;
+  GstTagList *other = GST_TAG_LIST (user_data);
 
-  /* Use fakesink for view finder */
-  vfsink = gst_element_factory_make ("fakesink", NULL);
-  g_object_set (vfsink, "sync", TRUE, NULL);
-  audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
-  g_object_set (audiosrc, "is-live", TRUE, NULL);
-  videosrc = gst_element_factory_make ("videotestsrc", NULL);
-  /* Set pattern to white (3) to avoid timeouts */
-  g_object_set (videosrc, "is-live", TRUE, "pattern", 3, NULL);
-  audioenc = gst_element_factory_make ("capsfilter", NULL);
-  audiocaps = gst_caps_from_string ("audio/x-raw-int");
-  g_object_set (audioenc, "caps", audiocaps, NULL);
-  gst_caps_unref (audiocaps);
-  videoenc = gst_element_factory_make ("capsfilter", NULL);
-  videocaps = gst_caps_from_string ("video/x-raw-yuv");
-  g_object_set (videoenc, "caps", videocaps, NULL);
-  gst_caps_unref (videocaps);
-  videomux = gst_element_factory_make ("avimux", NULL);
-  imageenc = gst_element_factory_make ("jpegenc", NULL);
-  viewfinder_filter = gst_element_factory_make ("identity", NULL);
-  imagepp = gst_element_factory_make ("identity", NULL);
-  videopp = gst_element_factory_make ("identity", NULL);
-  formatter = gst_element_factory_make ("jifmux", NULL);
-
-  if (set_and_check_camerabin_element (camera, "viewfinder-sink", vfsink)
-      && set_and_check_camerabin_element (camera, "audio-source", audiosrc)
-      && set_and_check_camerabin_element (camera, "video-source", videosrc)
-      && set_and_check_camerabin_element (camera, "audio-encoder", audioenc)
-      && set_and_check_camerabin_element (camera, "video-encoder", videoenc)
-      && set_and_check_camerabin_element (camera, "image-encoder", imageenc)
-      && set_and_check_camerabin_element (camera, "video-muxer", videomux)
-      && set_and_check_camerabin_element (camera, "viewfinder-filter",
-          viewfinder_filter)
-      && set_and_check_camerabin_element (camera, "image-post-processing",
-          imagepp)
-      && set_and_check_camerabin_element (camera, "video-post-processing",
-          videopp)
-      && set_and_check_camerabin_element (camera, "image-formatter", formatter)) {
-    GST_INFO ("element properties set and checked");
+  const GValue *val1 = gst_tag_list_get_value_index (list, tag, 0);
+  const GValue *val2 = gst_tag_list_get_value_index (other, tag, 0);
+
+  GST_DEBUG ("checking tag '%s'", tag);
+
+  fail_if (val1 == NULL);
+  fail_if (val2 == NULL);
+
+  fail_unless (gst_value_compare (val1, val2) == GST_VALUE_EQUAL);
+}
+
+
+/* helper function for filenames */
+static gchar *
+make_test_file_name (const gchar * base_name, gint num)
+{
+  /* num == -1 means to keep the %d in the resulting string to be used on
+   * multifilesink like location */
+  if (num == -1) {
+    return g_strdup_printf ("%s" G_DIR_SEPARATOR_S
+        "gstcamerabin2test_%s_%u_%%03d.cap", g_get_tmp_dir (), base_name,
+        test_id);
   } else {
-    GST_WARNING ("error setting up test plugins");
+    return g_strdup_printf ("%s" G_DIR_SEPARATOR_S
+        "gstcamerabin2test_%s_%u_%03d.cap", g_get_tmp_dir (), base_name,
+        test_id, num);
   }
 }
 
+static const gchar *
+make_const_file_name (const gchar * filename, gint num)
+{
+  static gchar file_name[1000];
+
+  /* num == -1 means to keep the %d in the resulting string to be used on
+   * multifilesink like location */
+  g_snprintf (file_name, 999, filename, num);
+
+  return file_name;
+}
+
+/* configuration */
+
 static gboolean
 capture_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
 {
@@ -246,90 +286,135 @@ capture_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
       break;
     default:
       st = gst_message_get_structure (message);
-      if (st && gst_structure_has_name (st, "image-captured")) {
-        gboolean ready = FALSE;
+      if (st && gst_structure_has_name (st, "image-done")) {
         GST_INFO ("image captured");
-        g_object_get (camera, "ready-for-capture", &ready, NULL);
-        fail_if (!ready, "not ready for capture");
+      } else if (st && gst_structure_has_name (st,
+              GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME)) {
+        GstBuffer *buf;
+        const GValue *value;
+
+        value = gst_structure_get_value (st, "buffer");
+        fail_unless (value != NULL);
+        buf = gst_value_get_buffer (value);
+
+        if (preview_buffer)
+          gst_buffer_unref (preview_buffer);
+        preview_buffer = gst_buffer_ref (buf);
+        g_free (preview_filename);
+        preview_filename = g_strdup (gst_structure_get_string (st, "location"));
       }
       break;
   }
   return TRUE;
 }
 
-static GstBusSyncReply
-bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
+static void
+check_preview_image (GstElement * camera, const gchar * filename, gint index)
 {
-  const GstStructure *st;
-  st = gst_message_get_structure (message);
-  if (st) {
-    if (gst_structure_has_name (st, "preview-image")) {
-      GST_DEBUG ("get preview-image message");
-      received_preview_msg = TRUE;
+  gchar *prev_filename = NULL;
+
+  if (!preview_buffer && camera) {
+    GstMessage *msg = wait_for_element_message (camera,
+        GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME, GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+  }
+  fail_unless (preview_buffer != NULL);
+  if (filename) {
+    if (index >= 0) {
+      prev_filename = g_strdup_printf (filename, index);
+    } else {
+      prev_filename = g_strdup (filename);
     }
+    fail_unless (preview_filename != NULL);
+    fail_unless (strcmp (preview_filename, prev_filename) == 0);
   }
+  if (preview_caps) {
+    /* TODO porting
+       fail_unless (GST_BUFFER_CAPS (preview_buffer) != NULL);
+       fail_unless (gst_caps_can_intersect (GST_BUFFER_CAPS (preview_buffer),
+       preview_caps));
+     */
+  }
+  g_free (prev_filename);
+}
 
+static void
+extract_jpeg_tags (const gchar * filename, gint num)
+{
+  GstBus *bus;
+  GMainLoop *loop = g_main_loop_new (NULL, FALSE);
+  const gchar *filepath = make_const_file_name (filename, num);
+  gchar *pipeline_str = g_strdup_printf ("filesrc location=%s ! "
+      "jpegparse ! fakesink", filepath);
+  GstElement *pipeline;
+  guint source;
+
+  pipeline = gst_parse_launch (pipeline_str, NULL);
+  fail_unless (pipeline != NULL);
+  g_free (pipeline_str);
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+  source = gst_bus_add_watch (bus, (GstBusFunc) validity_bus_cb, loop);
 
-  return GST_BUS_PASS;
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  g_main_loop_run (loop);
+  gst_element_set_state (pipeline, GST_STATE_NULL);
 
+  gst_object_unref (bus);
+  g_source_remove (source);
+  gst_object_unref (pipeline);
+  g_main_loop_unref (loop);
 }
 
 static void
-setup (void)
+setup_wrappercamerabinsrc_videotestsrc (void)
 {
-  GstTagSetter *setter;
-  gchar *desc_str;
-  GstCaps *filter_caps;
   GstBus *bus;
-  gint i;
+  GstElement *vfbin;
+  GstElement *fakevideosink;
+  GstElement *src;
+  GstElement *testsrc;
+  GstElement *audiosrc;
 
   GST_INFO ("init");
 
+  test_id = g_random_int ();
+  bus_source = 0;
+
   main_loop = g_main_loop_new (NULL, TRUE);
 
-  camera = gst_check_setup_element ("camerabin");
+  camera = gst_check_setup_element ("camerabin2");
+  fakevideosink = gst_element_factory_make ("fakesink", NULL);
+  src = gst_element_factory_make ("wrappercamerabinsrc", NULL);
+  testsrc = gst_element_factory_make ("videotestsrc", NULL);
+  audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
+
+  preview_caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+      320, "height", G_TYPE_INT, 240, NULL);
 
-  setup_camerabin_elements (camera);
+  g_object_set (G_OBJECT (testsrc), "is-live", TRUE, NULL);
+  g_object_set (G_OBJECT (audiosrc), "is-live", TRUE, NULL);
+  g_object_set (G_OBJECT (src), "video-source", testsrc, NULL);
+  g_object_set (G_OBJECT (camera), "camera-source", src, "preview-caps",
+      preview_caps, "post-previews", TRUE, "audio-source", audiosrc, NULL);
+  gst_object_unref (src);
+  gst_object_unref (testsrc);
+  gst_object_unref (audiosrc);
 
-  g_signal_connect (camera, "image-done", G_CALLBACK (capture_done), main_loop);
+  vfbin = gst_bin_get_by_name (GST_BIN (camera), "vf-bin");
+  g_object_set (G_OBJECT (vfbin), "video-sink", fakevideosink, NULL);
+  gst_object_unref (vfbin);
+  gst_object_unref (fakevideosink);
 
   bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
   bus_source = gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop);
-  gst_bus_set_sync_handler (bus, bus_sync_callback, main_loop);
   gst_object_unref (bus);
 
-  filter_caps = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420");
-  g_object_set (G_OBJECT (camera), "filter-caps", filter_caps, NULL);
-  gst_caps_unref (filter_caps);
-
-  /* force a low framerate here to not timeout the tests because of the
-   * encoders */
-  g_signal_emit_by_name (camera, "set-video-resolution-fps", 320, 240, 5, 1,
-      NULL);
-
-  /* Set some default tags */
-  setter = GST_TAG_SETTER (camera);
-  desc_str = g_strdup_printf ("Created by %s", g_get_real_name ());
-
-  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
-      GST_TAG_DESCRIPTION, desc_str, NULL);
-  g_free (desc_str);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-
-  /* create the taglists */
-  for (i = 0; i < TAGLISTS_COUNT; i++) {
-    taglists[i] = gst_tag_list_new (GST_TAG_ARTIST, "test-artist",
-        GST_TAG_GEO_LOCATION_LONGITUDE, g_random_double_range (-180, 180),
-        GST_TAG_GEO_LOCATION_LATITUDE, g_random_double_range (-90, 90),
-        GST_TAG_GEO_LOCATION_ELEVATION, g_random_double_range (0, 3000), NULL);
-  }
+  tags_found = NULL;
+  capture_count = 0;
+  image_filename = make_test_file_name (IMAGE_FILENAME, -1);
+  video_filename = make_test_file_name (VIDEO_FILENAME, -1);
 
   GST_INFO ("init finished");
 }
@@ -337,43 +422,41 @@ setup (void)
 static void
 teardown (void)
 {
-  gint i;
-
-  g_source_remove (bus_source);
+  gst_element_set_state (camera, GST_STATE_NULL);
 
   if (camera)
     gst_check_teardown_element (camera);
+  camera = NULL;
 
-  for (i = 0; i < TAGLISTS_COUNT; i++) {
-    gst_tag_list_free (taglists[i]);
-  }
+  if (bus_source)
+    g_source_remove (bus_source);
 
-  GST_INFO ("done");
-}
+  if (main_loop)
+    g_main_loop_unref (main_loop);
+  main_loop = NULL;
 
-static void
-test_camerabin_properties (GstElement * cam)
-{
-  guint flags;
-  gfloat zoom;
-  gboolean mute;
+  if (preview_caps)
+    gst_caps_unref (preview_caps);
+  preview_caps = NULL;
+
+  if (preview_buffer)
+    gst_buffer_unref (preview_buffer);
+  preview_buffer = NULL;
+
+  g_free (preview_filename);
+  preview_filename = NULL;
+
+  if (tags_found)
+    gst_tag_list_free (tags_found);
+  tags_found = NULL;
 
-  flags = 0x1f;
-  g_object_set (G_OBJECT (cam), "flags", flags, NULL);
-  g_object_get (G_OBJECT (cam), "flags", &flags, NULL);
-  fail_if (flags != 0x1f, "setting camerabin flags failed");
+  g_free (video_filename);
+  video_filename = NULL;
 
-  zoom = 2.0;
-  g_object_set (G_OBJECT (cam), "zoom", zoom, NULL);
-  g_object_get (G_OBJECT (cam), "zoom", &zoom, NULL);
-  fail_if (zoom != 2.0, "setting camerabin zoom failed");
-  g_object_set (G_OBJECT (cam), "zoom", 1.0f, NULL);
+  g_free (image_filename);
+  image_filename = NULL;
 
-  mute = TRUE;
-  g_object_set (G_OBJECT (cam), "mute", mute, NULL);
-  g_object_get (G_OBJECT (cam), "mute", &mute, NULL);
-  fail_if (mute != TRUE, "setting camerabin mute failed");
-  g_object_set (G_OBJECT (cam), "mute", FALSE, NULL);
+  GST_INFO ("done");
 }
 
 static gboolean
@@ -381,95 +464,105 @@ validity_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
 {
   GMainLoop *loop = (GMainLoop *) data;
   switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ERROR:
+    case GST_MESSAGE_ERROR:{
+      GError *err = NULL;
+      gchar *debug = NULL;
+
+      gst_message_parse_error (message, &err, &debug);
+
+      GST_ERROR ("Error: %s : %s", err->message, debug);
+      g_error_free (err);
+      g_free (debug);
+
       fail_if (TRUE, "validating captured data failed");
       g_main_loop_quit (loop);
+    }
       break;
     case GST_MESSAGE_EOS:
       g_main_loop_quit (loop);
       GST_DEBUG ("eos");
       break;
     case GST_MESSAGE_TAG:{
-      GstTagList *tags = NULL;
-      gst_message_parse_tag (message, &tags);
-      if (validation_taglist) {
-        gst_tag_list_insert (validation_taglist, tags, GST_TAG_MERGE_REPLACE);
-        gst_tag_list_free (tags);
-      } else
-        validation_taglist = tags;
-      break;
+      GstTagList *taglist = NULL;
+
+      gst_message_parse_tag (message, &taglist);
+      if (tags_found) {
+        gst_tag_list_insert (tags_found, taglist, GST_TAG_MERGE_REPLACE);
+        gst_tag_list_free (taglist);
+      } else {
+        tags_found = taglist;
+      }
+      GST_DEBUG ("tags: %" GST_PTR_FORMAT, tags_found);
     }
+      break;
     default:
       break;
   }
   return TRUE;
 }
 
-static void
-validate_taglist_foreach (const GstTagList * list, const gchar * tag,
-    gpointer user_data)
-{
-  GstTagList *other = GST_TAG_LIST (user_data);
-
-  const GValue *val1 = gst_tag_list_get_value_index (list, tag, 0);
-  const GValue *val2 = gst_tag_list_get_value_index (other, tag, 0);
-
-  fail_if (val1 == NULL);
-  fail_if (val2 == NULL);
-
-  fail_unless (gst_value_can_intersect (val1, val2));
-}
-
-static void
-extract_jpeg_tags (const gchar * filename, gint num)
+/* checks that tags in @tags_a are in @tags_b */
+static gboolean
+taglist_is_subset (GstTagList * tags_a, GstTagList * tags_b)
 {
-  guint source;
-  GstBus *bus;
-  GMainLoop *loop = g_main_loop_new (NULL, FALSE);
-  const gchar *filepath = make_test_file_name (filename, num);
-  gchar *pipeline_str = g_strdup_printf ("filesrc location=%s ! "
-      "jpegparse ! fakesink", filepath);
-  GstElement *pipeline;
-
-  pipeline = gst_parse_launch (pipeline_str, NULL);
-  fail_unless (pipeline != NULL);
-  g_free (pipeline_str);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
-  source = gst_bus_add_watch (bus, (GstBusFunc) validity_bus_cb, loop);
-
-  gst_element_set_state (pipeline, GST_STATE_PLAYING);
-  g_main_loop_run (loop);
-  gst_element_set_state (pipeline, GST_STATE_NULL);
-
-  g_main_loop_unref (loop);
-  g_source_remove (source);
-  gst_object_unref (bus);
-  gst_object_unref (pipeline);
+  gst_tag_list_foreach (tags_a, validate_taglist_foreach, tags_b);
+  return TRUE;
 }
 
 /* Validate captured files by playing them with playbin
  * and checking that no errors occur. */
+#define WITH_AUDIO TRUE
+#define NO_AUDIO FALSE
 static gboolean
-check_file_validity (const gchar * filename, gint num, GstTagList * taglist)
+check_file_validity (const gchar * filename, gint num, GstTagList * taglist,
+    gint width, gint height, gboolean has_audio)
 {
-  guint source;
   GstBus *bus;
+  GstPad *pad;
+  GstCaps *caps;
+  gint caps_width, caps_height;
+  GstState state;
+  guint source;
+
   GMainLoop *loop = g_main_loop_new (NULL, FALSE);
   GstElement *playbin = gst_element_factory_make ("playbin2", NULL);
   GstElement *fakevideo = gst_element_factory_make ("fakesink", NULL);
   GstElement *fakeaudio = gst_element_factory_make ("fakesink", NULL);
-  gchar *uri = g_strconcat ("file://", make_test_file_name (filename, num),
+  gchar *uri = g_strconcat ("file://", make_const_file_name (filename, num),
       NULL);
 
   GST_DEBUG ("checking uri: %s", uri);
   g_object_set (G_OBJECT (playbin), "uri", uri, "video-sink", fakevideo,
       "audio-sink", fakeaudio, NULL);
 
-  validation_taglist = NULL;
   bus = gst_pipeline_get_bus (GST_PIPELINE (playbin));
   source = gst_bus_add_watch (bus, (GstBusFunc) validity_bus_cb, loop);
 
+  gst_element_set_state (playbin, GST_STATE_PAUSED);
+  gst_element_get_state (playbin, &state, NULL, GST_SECOND * 3);
+
+  if (width != 0 && height != 0) {
+    g_signal_emit_by_name (playbin, "get-video-pad", 0, &pad, NULL);
+    g_assert (pad != NULL);
+    caps = gst_pad_get_current_caps (pad);
+
+    g_assert (gst_structure_get_int (gst_caps_get_structure (caps, 0),
+            "width", &caps_width));
+    g_assert (gst_structure_get_int (gst_caps_get_structure (caps, 0),
+            "height", &caps_height));
+
+    g_assert (width == caps_width);
+    g_assert (height == caps_height);
+
+    gst_caps_unref (caps);
+    gst_object_unref (pad);
+  }
+  if (has_audio) {
+    g_signal_emit_by_name (playbin, "get-audio-pad", 0, &pad, NULL);
+    g_assert (pad != NULL);
+    gst_object_unref (pad);
+  }
+
   gst_element_set_state (playbin, GST_STATE_PLAYING);
   g_main_loop_run (loop);
   gst_element_set_state (playbin, GST_STATE_NULL);
@@ -480,18 +573,10 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist)
     extract_jpeg_tags (filename, num);
   }
 
-  /* check taglist */
   if (taglist) {
-    fail_if (validation_taglist == NULL);
-
-    GST_DEBUG ("Comparing taglists %" GST_PTR_FORMAT "; with %" GST_PTR_FORMAT,
-        taglist, validation_taglist);
-
-    gst_tag_list_foreach (taglist, validate_taglist_foreach,
-        validation_taglist);
+    fail_unless (tags_found != NULL);
+    fail_unless (taglist_is_subset (taglist, tags_found));
   }
-  if (validation_taglist)
-    gst_tag_list_free (validation_taglist);
 
   g_free (uri);
   g_source_remove (source);
@@ -507,340 +592,993 @@ remove_file (const gchar * fn_template, guint num)
 {
   const gchar *fn;
 
-  fn = make_test_file_name (fn_template, num);
+  fn = make_const_file_name (fn_template, num);
   GST_INFO ("removing %s", fn);
   g_unlink (fn);
 }
 
-GST_START_TEST (test_single_image_capture)
+static GstPadProbeReturn
+filter_buffer_count (GstPad * pad, GstPadProbeInfo * info, gpointer data)
 {
-  gboolean ready = FALSE;
-  gboolean idle = FALSE;
-  if (!camera)
-    return;
+  gint *counter = data;
 
-  /* Test photography iface settings */
-  gst_element_get_state (GST_ELEMENT (camera), NULL, NULL, (2 * GST_SECOND));
-  test_camerabin_properties (camera);
+  (*counter)++;
 
-  /* set flags to disable additional elements */
-  g_object_set (camera, "flags", 0, NULL);
+  return GST_PAD_PROBE_OK;
+}
 
-  /* set still image mode */
-  g_object_set (camera, "mode", 0,
-      "filename", make_test_file_name (SINGLE_IMAGE_FILENAME, 0), NULL);
+static GstMessage *
+wait_for_element_message (GstElement * camera, const gchar * name,
+    GstClockTime timeout)
+{
+  GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
+  GstMessage *msg;
+
+  while (1) {
+    msg = gst_bus_timed_pop_filtered (bus, timeout, GST_MESSAGE_ERROR |
+        GST_MESSAGE_EOS | GST_MESSAGE_ELEMENT);
+
+    if (msg) {
+      if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT) {
+        const GstStructure *st = gst_message_get_structure (msg);
+        if (gst_structure_has_name (st,
+                GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME)) {
+          GstBuffer *buf;
+          const GValue *value;
+
+          value = gst_structure_get_value (st, "buffer");
+          fail_unless (value != NULL);
+          buf = gst_value_get_buffer (value);
+
+          if (preview_buffer)
+            gst_buffer_unref (preview_buffer);
+          preview_buffer = gst_buffer_ref (buf);
+          g_free (preview_filename);
+          preview_filename =
+              g_strdup (gst_structure_get_string (st, "location"));
+        }
+
+        if (gst_structure_has_name (st, name))
+          break;
+        else
+          gst_message_unref (msg);
+      } else {
+        gst_message_unref (msg);
+        msg = NULL;
+        break;
+      }
+    }
+  }
 
-  /* don't run viewfinder after capture */
-  g_object_set (camera, "block-after-capture", TRUE, NULL);
+  gst_object_unref (bus);
+  return msg;
+}
 
-  /* check that capturing is possible */
-  g_object_get (camera, "ready-for-capture", &ready, NULL);
-  fail_if (!ready, "not ready for capture");
+static void
+wait_for_idle_state (void)
+{
+  gboolean idle = FALSE;
 
-  /* check that the camera is idle */
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (!idle, "camera should be idle");
+  /* not the ideal way, but should be enough for testing */
+  while (idle == FALSE) {
+    g_object_get (camera, "idle", &idle, NULL);
+    if (idle)
+      break;
 
-  GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
+    GST_LOG ("waiting for idle state..");
+    g_usleep (G_USEC_PER_SEC / 5);
+  }
+  fail_unless (idle);
+}
 
-  g_object_get (camera, "ready-for-capture", &ready, NULL);
-  fail_if (ready, "ready for capture during capture");
+GST_START_TEST (test_single_image_capture)
+{
+  gboolean idle;
+  GstMessage *msg;
+  if (!camera)
+    return;
 
-  g_main_loop_run (main_loop);
+  /* set still image mode */
+  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
 
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  GST_INFO ("starting capture");
+  fail_unless (camera != NULL);
   g_object_get (camera, "idle", &idle, NULL);
-  fail_if (!idle, "camera should be idle");
+  fail_unless (idle);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
 
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+  fail_unless (msg != NULL);
+  gst_message_unref (msg);
+
+  /* check that we got a preview image */
+  check_preview_image (camera, image_filename, 0);
 
-  check_file_validity (SINGLE_IMAGE_FILENAME, 0, NULL);
-  remove_file (SINGLE_IMAGE_FILENAME, 0);
+  wait_for_idle_state ();
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
+  remove_file (image_filename, 0);
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_single_image_capture_with_flags)
+
+GST_START_TEST (test_multiple_image_captures)
 {
+  gboolean idle;
+  gint i;
+  gint widths[] = { 800, 640, 1280 };
+  gint heights[] = { 600, 480, 1024 };
+
   if (!camera)
     return;
 
-  /* set flags to enable modifier elements */
-  g_object_set (camera, "flags", 79, NULL);
-
   /* set still image mode */
-  g_object_set (camera, "mode", 0,
-      "filename", make_test_file_name (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0),
-      NULL);
+  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
 
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  fail_unless (camera != NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (idle);
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
 
-  g_main_loop_run (main_loop);
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  for (i = 0; i < 3; i++) {
+    GstMessage *msg;
+    GstCaps *caps;
 
-  check_file_validity (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0, NULL);
-  remove_file (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0);
-}
+    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+        widths[i], "height", G_TYPE_INT, heights[i], NULL);
 
-GST_END_TEST;
+    g_object_set (camera, "image-capture-caps", caps, NULL);
+    gst_caps_unref (caps);
 
-GST_START_TEST (test_video_recording)
-{
-  GstCaps *preview_caps;
-  gboolean idle = FALSE;
-  preview_caps = gst_caps_from_string ("video/x-raw-rgb,width=320,height=240");
+    g_signal_emit_by_name (camera, "start-capture", NULL);
 
-  if (!camera)
-    return;
+    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
 
-  /* set flags to disable additional elements */
-  g_object_set (camera, "flags", 0, NULL);
+    check_preview_image (camera, image_filename, i);
+  }
 
-  /* Set video recording mode */
-  g_object_set (camera, "mode", 1,
-      "filename", make_test_file_name (VIDEO_WITH_FLAGS_FILENAME, 0), NULL);
+  wait_for_idle_state ();
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  for (i = 0; i < 3; i++) {
+    check_file_validity (image_filename, i, NULL, widths[i], heights[i],
+        NO_AUDIO);
+    remove_file (image_filename, i);
+  }
+}
 
-  /* Set preview-caps */
-  g_object_set (camera, "preview-caps", preview_caps, NULL);
-  gst_caps_unref (preview_caps);
+GST_END_TEST;
 
-  /* check that the camera is idle */
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (!idle, "camera should be idle");
+GST_START_TEST (test_single_video_recording)
+{
+  GstMessage *msg;
+  gboolean idle;
+  if (!camera)
+    return;
+
+  /* Set video recording mode */
+  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
 
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
+  fail_unless (camera != NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (idle);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
 
   g_object_get (camera, "idle", &idle, NULL);
-  fail_if (idle, "camera should not be idle");
+  fail_unless (!idle);
 
   /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
+  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
+      main_loop);
+  g_main_loop_run (main_loop);
 
-  g_signal_emit_by_name (camera, "capture-stop", NULL);
+  g_signal_emit_by_name (camera, "stop-capture", NULL);
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (!idle, "camera should be idle");
+  check_preview_image (camera, video_filename, 0);
 
-  /* check if receiving the preview-image message */
-  fail_if (!received_preview_msg,
-      "creating video recording preview image failed");
+  msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
+  fail_unless (msg != NULL);
+  gst_message_unref (msg);
 
+  wait_for_idle_state ();
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
 
-  check_file_validity (VIDEO_WITH_FLAGS_FILENAME, 0, NULL);
-  remove_file (VIDEO_WITH_FLAGS_FILENAME, 0);
+  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
+  remove_file (video_filename, 0);
+
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_video_recording_with_flags)
+GST_START_TEST (test_multiple_video_recordings)
 {
-  GstCaps *preview_caps;
-  preview_caps = gst_caps_from_string ("video/x-raw-rgb,width=320,height=240");
+  gboolean idle;
+  gint i;
+  gint widths[] = { 800, 640, 1280 };
+  gint heights[] = { 600, 480, 1024 };
+  gint fr[] = { 20, 30, 5 };
 
   if (!camera)
     return;
 
-  /* set flags to enable modifier elements */
-  g_object_set (camera, "flags", 95, NULL);
-
   /* Set video recording mode */
-  g_object_set (camera, "mode", 1,
-      "filename", make_test_file_name (VIDEO_FILENAME, 0), NULL);
+  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
 
-  /* Set preview-caps */
-  g_object_set (camera, "preview-caps", preview_caps, NULL);
-  gst_caps_unref (preview_caps);
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
 
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
-  /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
-  g_signal_emit_by_name (camera, "capture-stop", NULL);
+  fail_unless (camera != NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (idle);
+  for (i = 0; i < 3; i++) {
+    GstMessage *msg;
+    GstCaps *caps;
+
+    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+        widths[i], "height", G_TYPE_INT, heights[i], "framerate",
+        GST_TYPE_FRACTION, fr[i], 1, NULL);
+
+    g_object_set (camera, "video-capture-caps", caps, NULL);
 
-  /*check if receiving the preview-image message */
-  fail_if (!received_preview_msg,
-      "creating video recording preview image failed");
+    gst_caps_unref (caps);
 
+    GST_LOG ("starting #%d with caps %" GST_PTR_FORMAT, i, caps);
+    g_signal_emit_by_name (camera, "start-capture", NULL);
+
+    g_object_get (camera, "idle", &idle, NULL);
+    fail_unless (!idle);
+
+    g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
+        main_loop);
+    g_main_loop_run (main_loop);
+
+    GST_LOG ("stopping run %d", i);
+    g_signal_emit_by_name (camera, "stop-capture", NULL);
+
+    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+
+    GST_LOG ("video done, checking preview image");
+    check_preview_image (camera, video_filename, i);
+
+    GST_LOG ("waiting for idle state");
+    wait_for_idle_state ();
+    GST_LOG ("finished run %d", i);
+  }
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
 
-  check_file_validity (VIDEO_FILENAME, 0, NULL);
-  remove_file (VIDEO_FILENAME, 0);
+  for (i = 0; i < 3; i++) {
+    check_file_validity (video_filename, i, NULL, widths[i], heights[i],
+        WITH_AUDIO);
+    remove_file (video_filename, i);
+  }
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_video_recording_pause)
+GST_START_TEST (test_image_video_cycle)
 {
-  gboolean idle = FALSE;
+  gint i;
+
   if (!camera)
     return;
 
-  /* Set video recording mode */
-  g_object_set (camera, "mode", 1,
-      "filename", make_test_file_name (VIDEO_PAUSE_FILENAME, 0), NULL);
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle, "camera should be idle");
+  GST_INFO ("starting capture");
+  for (i = 0; i < 2; i++) {
+    GstMessage *msg;
+    const gchar *img_filename;
+    const gchar *vid_filename;
+
+    wait_for_idle_state ();
+
+    /* take a picture */
+    img_filename = make_const_file_name (image_filename, i);
+    g_object_set (camera, "mode", 1, NULL);
+    g_object_set (camera, "location", img_filename, NULL);
+    g_signal_emit_by_name (camera, "start-capture", NULL);
+
+    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+
+    check_preview_image (camera, img_filename, i);
+
+    /* now go to video */
+    vid_filename = make_const_file_name (video_filename, i);
+    g_object_set (camera, "mode", 2, NULL);
+    g_object_set (camera, "location", vid_filename, NULL);
 
+    g_signal_emit_by_name (camera, "start-capture", NULL);
+    g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
+        main_loop);
+    g_main_loop_run (main_loop);
+    g_signal_emit_by_name (camera, "stop-capture", NULL);
+
+    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+
+    check_preview_image (camera, vid_filename, i);
+  }
+
+  wait_for_idle_state ();
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+
+  /* validate all the files */
+  for (i = 0; i < 2; i++) {
+    check_file_validity (image_filename, i, NULL, 0, 0, NO_AUDIO);
+    remove_file (image_filename, i);
+    check_file_validity (video_filename, i, NULL, 0, 0, WITH_AUDIO);
+    remove_file (video_filename, i);
+  }
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_image_capture_previews)
+{
+  gint i;
+  gint widths[] = { 800, 640, 1280 };
+  gint heights[] = { 600, 480, 1024 };
+
+  if (!camera)
+    return;
+
+  /* set still image mode */
+  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  fail_unless (camera != NULL);
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (idle, "camera shouldn't be idle when recording");
+  for (i = 0; i < 3; i++) {
+    GstMessage *msg;
+    GstCaps *caps;
 
-  /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
+    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+        widths[i], "height", G_TYPE_INT, heights[i], NULL);
 
-  GST_INFO ("pause capture");
-  g_signal_emit_by_name (camera, "capture-pause", NULL);
+    g_object_set (camera, "preview-caps", caps, NULL);
+    gst_caps_replace (&preview_caps, caps);
+    gst_caps_unref (caps);
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (idle, "camera shouldn't be idle when recording and paused");
+    g_signal_emit_by_name (camera, "start-capture", NULL);
 
-  /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
+    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
 
-  GST_INFO ("continue capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
+    check_preview_image (camera, image_filename, i);
+    remove_file (image_filename, i);
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_if (idle, "camera shouldn't be idle when recording");
+    if (preview_buffer)
+      gst_buffer_unref (preview_buffer);
+    preview_buffer = NULL;
+    gst_caps_replace (&preview_caps, NULL);
+  }
 
-  /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
-  g_signal_emit_by_name (camera, "capture-stop", NULL);
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+}
 
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle, "camera should be idle after capture-stop");
+GST_END_TEST;
+
+
+GST_START_TEST (test_image_capture_with_tags)
+{
+  gint i;
+  GstTagList *taglists[3];
+
+  if (!camera)
+    return;
+
+  taglists[0] = gst_tag_list_new (GST_TAG_COMMENT, "test1",
+      GST_TAG_GEO_LOCATION_LATITUDE, 36.6, GST_TAG_GEO_LOCATION_LONGITUDE,
+      -12.5,
+      GST_TAG_COPYRIGHT, "My copyright notice",
+      GST_TAG_DEVICE_MANUFACTURER, "MyFavoriteBrand",
+      GST_TAG_DEVICE_MODEL, "123v42.1",
+      GST_TAG_DESCRIPTION, "some description",
+      GST_TAG_APPLICATION_NAME, "camerabin2 test",
+      GST_TAG_GEO_LOCATION_ELEVATION, 300.85, NULL);
+  taglists[1] = gst_tag_list_new (GST_TAG_COMMENT, "test2",
+      GST_TAG_GEO_LOCATION_LATITUDE, 1.6, GST_TAG_GEO_LOCATION_LONGITUDE,
+      0.0,
+      GST_TAG_COPYRIGHT, "some cp",
+      GST_TAG_DEVICE_MANUFACTURER, "ABRAND",
+      GST_TAG_DEVICE_MODEL, "abcd",
+      GST_TAG_DESCRIPTION, "desc",
+      GST_TAG_APPLICATION_NAME, "another cam test",
+      GST_TAG_GEO_LOCATION_ELEVATION, 10.0, NULL);
+  taglists[2] = gst_tag_list_new (GST_TAG_COMMENT, "test3",
+      GST_TAG_GEO_LOCATION_LATITUDE, 1.3, GST_TAG_GEO_LOCATION_LONGITUDE,
+      -5.0,
+      GST_TAG_COPYRIGHT, "CC",
+      GST_TAG_DEVICE_MANUFACTURER, "Homemade",
+      GST_TAG_DEVICE_MODEL, "xpto",
+      GST_TAG_DESCRIPTION, "another  description",
+      GST_TAG_APPLICATION_NAME, "cam2 test",
+      GST_TAG_GEO_LOCATION_ELEVATION, 0.0, NULL);
+
+  /* set still image mode */
+  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  fail_unless (camera != NULL);
+  GST_INFO ("starting capture");
+
+  for (i = 0; i < 3; i++) {
+    GstMessage *msg;
+    gst_tag_setter_merge_tags (GST_TAG_SETTER (camera), taglists[i],
+        GST_TAG_MERGE_REPLACE);
+
+    g_signal_emit_by_name (camera, "start-capture", NULL);
+
+    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+  }
 
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
 
-  check_file_validity (VIDEO_PAUSE_FILENAME, 0, NULL);
-  remove_file (VIDEO_PAUSE_FILENAME, 0);
+  for (i = 0; i < 3; i++) {
+    check_file_validity (image_filename, i, taglists[i], 0, 0, NO_AUDIO);
+    gst_tag_list_free (taglists[i]);
+    remove_file (image_filename, i);
+  }
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_video_recording_no_audio)
+
+GST_START_TEST (test_video_capture_with_tags)
 {
-  GstCaps *preview_caps;
-  preview_caps = gst_caps_from_string ("video/x-raw-rgb,width=320,height=240");
+  gint i;
+  GstTagList *taglists[3];
 
   if (!camera)
     return;
 
-  /* set flags to disable audio elements */
-  g_object_set (camera, "flags", 32, NULL);
+  taglists[0] = gst_tag_list_new (GST_TAG_COMMENT, "test1", NULL);
+  taglists[1] = gst_tag_list_new (GST_TAG_COMMENT, "test2", NULL);
+  taglists[2] = gst_tag_list_new (GST_TAG_COMMENT, "test3", NULL);
+
+  /* set video mode */
+  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
+
+  /* set a profile that has xmp support for more tags being saved */
+  {
+    GstEncodingContainerProfile *profile;
+    GstCaps *caps;
+
+    caps =
+        gst_caps_new_simple ("video/quicktime", "variant", G_TYPE_STRING,
+        "apple", NULL);
+    profile = gst_encoding_container_profile_new ("qt", "jpeg+qt", caps, NULL);
+    gst_caps_unref (caps);
+
+    caps = gst_caps_new_simple ("image/jpeg", NULL, NULL);
+    if (!gst_encoding_container_profile_add_profile (profile,
+            (GstEncodingProfile *) gst_encoding_video_profile_new (caps,
+                NULL, NULL, 1))) {
+      GST_WARNING_OBJECT (camera, "Failed to create encoding profiles");
+    }
+    gst_caps_unref (caps);
+
+    g_object_set (camera, "video-profile", profile, NULL);
+    gst_encoding_profile_unref (profile);
+  }
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  fail_unless (camera != NULL);
+  GST_INFO ("starting capture");
+
+  for (i = 0; i < 3; i++) {
+    GstMessage *msg;
+
+    gst_tag_setter_merge_tags (GST_TAG_SETTER (camera), taglists[i],
+        GST_TAG_MERGE_REPLACE);
+
+    g_signal_emit_by_name (camera, "start-capture", NULL);
+
+    g_timeout_add_seconds (3, (GSourceFunc) g_main_loop_quit, main_loop);
+    g_main_loop_run (main_loop);
+
+    g_signal_emit_by_name (camera, "stop-capture", NULL);
+
+    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
+    fail_unless (msg != NULL);
+    gst_message_unref (msg);
+  }
+
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+
+  for (i = 0; i < 3; i++) {
+    check_file_validity (video_filename, i, taglists[i], 0, 0, NO_AUDIO);
+    gst_tag_list_free (taglists[i]);
+    remove_file (video_filename, i);
+  }
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_supported_caps)
+{
+  GstCaps *padcaps = NULL;
+  GstCaps *expectedcaps;
+  GstElement *src;
+
+  if (!camera)
+    return;
+
+  src = g_object_new (GST_TYPE_TEST_CAMERA_SRC, NULL);
+  g_object_set (camera, "camera-source", src, NULL);
+  gst_object_unref (src);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  g_assert (camera != NULL);
+
+  expectedcaps = gst_caps_from_string (VIDEO_PAD_SUPPORTED_CAPS);
+  g_object_get (G_OBJECT (camera), "video-capture-supported-caps", &padcaps,
+      NULL);
+  g_assert (expectedcaps != NULL);
+  g_assert (padcaps != NULL);
+  g_assert (gst_caps_is_equal (padcaps, expectedcaps));
+  gst_caps_unref (expectedcaps);
+  gst_caps_unref (padcaps);
+
+  expectedcaps = gst_caps_from_string (IMAGE_PAD_SUPPORTED_CAPS);
+  g_object_get (G_OBJECT (camera), "image-capture-supported-caps", &padcaps,
+      NULL);
+  g_assert (expectedcaps != NULL);
+  g_assert (padcaps != NULL);
+  g_assert (gst_caps_is_equal (padcaps, expectedcaps));
+  gst_caps_unref (expectedcaps);
+  gst_caps_unref (padcaps);
+
+  gst_element_set_state (camera, GST_STATE_NULL);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_idle_property)
+{
+  GstMessage *msg;
+  gboolean idle;
+  if (!camera)
+    return;
 
   /* Set video recording mode */
-  g_object_set (camera, "mode", 1,
-      "filename", make_test_file_name (VIDEO_NOAUDIO_FILENAME, 0), NULL);
+  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
 
-  /* Set preview-caps */
-  g_object_set (camera, "preview-caps", preview_caps, NULL);
-  gst_caps_unref (preview_caps);
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
 
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
+  fail_unless (camera != NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (idle);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (!idle);
+
+  /* emit a second start-capture that should be ignored */
+  g_signal_emit_by_name (camera, "start-capture", NULL);
+  g_object_get (camera, "idle", &idle, NULL);
+  fail_unless (!idle);
+
   /* Record for one seconds  */
-  g_usleep (G_USEC_PER_SEC);
-  g_signal_emit_by_name (camera, "capture-stop", NULL);
+  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
+      main_loop);
+  g_main_loop_run (main_loop);
+
+  g_signal_emit_by_name (camera, "stop-capture", NULL);
+
+  msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
+  fail_unless (msg != NULL);
+  gst_message_unref (msg);
 
-  /* check if receiving the preview-image message */
-  fail_if (!received_preview_msg,
-      "creating video recording preview image failed");
+  check_preview_image (camera, video_filename, 0);
+
+  wait_for_idle_state ();
 
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
 
-  check_file_validity (VIDEO_NOAUDIO_FILENAME, 0, NULL);
-  remove_file (VIDEO_NOAUDIO_FILENAME, 0);
+  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
+  remove_file (video_filename, 0);
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_image_video_cycle)
+
+GST_START_TEST (test_image_custom_filter)
 {
-  gint i;
+  GstElement *vf_filter;
+  GstElement *image_filter;
+  GstElement *preview_filter;
+  GstPad *pad;
+  gint vf_probe_counter = 0;
+  gint image_probe_counter = 0;
+  gint preview_probe_counter = 0;
 
   if (!camera)
     return;
 
-  cycle_count = CYCLE_COUNT_MAX;
+  vf_filter = gst_element_factory_make ("identity", "vf-filter");
+  image_filter = gst_element_factory_make ("identity", "img-filter");
+  preview_filter = gst_element_factory_make ("identity", "preview-filter");
 
-  /* set still image mode */
-  g_object_set (camera, "mode", 0,
-      "filename", make_test_file_name (CYCLE_IMAGE_FILENAME, cycle_count),
-      NULL);
+  pad = gst_element_get_static_pad (vf_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &vf_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (image_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &image_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (preview_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &preview_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  /* set still image mode and filters */
+  g_object_set (camera, "mode", 1,
+      "location", image_filename,
+      "viewfinder-filter", vf_filter, "image-filter", image_filter,
+      "preview-filter", preview_filter, NULL);
+
+  gst_object_unref (vf_filter);
+  gst_object_unref (preview_filter);
+  gst_object_unref (image_filter);
 
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
   GST_INFO ("starting capture");
-  g_signal_emit_by_name (camera, "capture-start", NULL);
+  fail_unless (camera != NULL);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
 
+  g_timeout_add_seconds (3, (GSourceFunc) g_main_loop_quit, main_loop);
   g_main_loop_run (main_loop);
+
+  /* check that we got a preview image */
+  check_preview_image (camera, image_filename, 0);
+
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
+  remove_file (image_filename, 0);
 
-  /* validate all the files */
-  for (i = 2; i > 0; i--) {
-    check_file_validity (CYCLE_IMAGE_FILENAME, i, NULL);
-    remove_file (CYCLE_IMAGE_FILENAME, i);
-    check_file_validity (CYCLE_VIDEO_FILENAME, i, NULL);
-    remove_file (CYCLE_VIDEO_FILENAME, i);
+  fail_unless (vf_probe_counter > 0);
+  fail_unless (image_probe_counter == 1);
+  fail_unless (preview_probe_counter == 1);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_video_custom_filter)
+{
+  GstElement *vf_filter;
+  GstElement *video_filter;
+  GstElement *preview_filter;
+  GstElement *audio_filter;
+  GstPad *pad;
+  gint vf_probe_counter = 0;
+  gint video_probe_counter = 0;
+  gint preview_probe_counter = 0;
+  gint audio_probe_counter = 0;
+
+  if (!camera)
+    return;
+
+  vf_filter = gst_element_factory_make ("identity", "vf-filter");
+  video_filter = gst_element_factory_make ("identity", "video-filter");
+  preview_filter = gst_element_factory_make ("identity", "preview-filter");
+  audio_filter = gst_element_factory_make ("identity", "audio-filter");
+
+  pad = gst_element_get_static_pad (vf_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &vf_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (video_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &video_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (audio_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &audio_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (preview_filter, "src");
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
+      &preview_probe_counter, NULL);
+  gst_object_unref (pad);
+
+  /* set still image mode and filters */
+  g_object_set (camera, "mode", 2,
+      "location", video_filename,
+      "viewfinder-filter", vf_filter, "video-filter", video_filter,
+      "preview-filter", preview_filter, "audio-filter", audio_filter, NULL);
+
+  gst_object_unref (vf_filter);
+  gst_object_unref (preview_filter);
+  gst_object_unref (video_filter);
+  gst_object_unref (audio_filter);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
   }
+  GST_INFO ("starting capture");
+  fail_unless (camera != NULL);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
+
+  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
+      main_loop);
+  g_main_loop_run (main_loop);
+  g_signal_emit_by_name (camera, "stop-capture", NULL);
+
+  /* check that we got a preview image */
+  check_preview_image (camera, video_filename, 0);
+
+  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
+  remove_file (video_filename, 0);
+
+  fail_unless (vf_probe_counter > 0);
+  fail_unless (video_probe_counter > 0);
+  fail_unless (audio_probe_counter > 0);
+  fail_unless (preview_probe_counter == 1);
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_image_tags_setting)
+#define LOCATION_SWITCHING_FILENAMES_COUNT 5
+
+static gboolean
+image_location_switch_do_capture (gpointer data)
+{
+  gchar **filenames = data;
+  if (capture_count >= LOCATION_SWITCHING_FILENAMES_COUNT) {
+    g_main_loop_quit (main_loop);
+  }
+
+  g_object_set (camera, "location", filenames[capture_count], NULL);
+  g_signal_emit_by_name (camera, "start-capture", NULL);
+  capture_count++;
+  return FALSE;
+}
+
+static void
+image_location_switch_readyforcapture (GObject * obj, GParamSpec * pspec,
+    gpointer user_data)
+{
+  gboolean ready;
+
+  g_object_get (obj, "ready-for-capture", &ready, NULL);
+  if (ready) {
+    g_idle_add (image_location_switch_do_capture, user_data);
+  }
+};
+
+/*
+ * Tests that setting the location and then doing an image
+ * capture will set this capture resulting filename to the
+ * correct location.
+ *
+ * There was a bug in which setting the location, issuing a capture 
+ * and then setting a new location would cause this capture to have
+ * the location set after this capture. This test should prevent it
+ * from happening again.
+ */
+GST_START_TEST (test_image_location_switching)
 {
+  gchar *filenames[LOCATION_SWITCHING_FILENAMES_COUNT + 1];
   gint i;
+  glong notify_id;
+  GstCaps *caps;
+  GstElement *src;
+  GstMessage *msg;
 
-  g_object_set (camera, "flags", 0, NULL);
-  g_object_set (camera, "block-after-capture", TRUE, NULL);
+  if (!camera)
+    return;
 
-  GST_INFO ("starting capture series");
+  g_object_get (camera, "camera-source", &src, NULL);
 
-  for (i = 0; i < SEQUENTIAL_IMAGES_COUNT; i++) {
-    g_object_set (camera, "filename",
-        make_test_file_name (SEQUENTIAL_IMAGES_FILENAME, i), NULL);
-    gst_tag_setter_merge_tags (GST_TAG_SETTER (camera),
-        taglists[i % TAGLISTS_COUNT],
-        gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (camera)));
-    g_signal_emit_by_name (camera, "capture-start", NULL);
-    g_main_loop_run (main_loop);
+  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
+    filenames[i] = make_test_file_name ("image-switching-filename-test", i);
   }
+  filenames[LOCATION_SWITCHING_FILENAMES_COUNT] = NULL;
+
+  /* set still image mode */
+  g_object_set (camera, "mode", 1, NULL);
+  caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+      800, "height", G_TYPE_INT, 600, NULL);
+  g_object_set (camera, "image-capture-caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
+      GST_STATE_CHANGE_FAILURE) {
+    GST_WARNING ("setting camerabin to PLAYING failed");
+    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
+    gst_object_unref (camera);
+    camera = NULL;
+  }
+  fail_unless (camera != NULL);
+  GST_INFO ("starting capture");
+
+  notify_id = g_signal_connect (G_OBJECT (src),
+      "notify::ready-for-capture",
+      G_CALLBACK (image_location_switch_readyforcapture), filenames);
+
+  g_idle_add (image_location_switch_do_capture, filenames);
+  g_main_loop_run (main_loop);
+
+  msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
+  fail_unless (msg != NULL);
+  gst_message_unref (msg);
+
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
 
-  for (i = 0; i < SEQUENTIAL_IMAGES_COUNT; i++) {
-    check_file_validity (SEQUENTIAL_IMAGES_FILENAME, i,
-        taglists[i % TAGLISTS_COUNT]);
-    remove_file (SEQUENTIAL_IMAGES_FILENAME, i);
+  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
+    GST_INFO ("Checking for file: %s", filenames[i]);
+    fail_unless (g_file_test (filenames[i], G_FILE_TEST_IS_REGULAR));
   }
+
+  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
+    g_unlink (filenames[i]);
+    g_free (filenames[i]);
+  }
+  g_signal_handler_disconnect (src, notify_id);
 }
 
 GST_END_TEST;
 
+
+typedef struct _TestCaseDef
+{
+  const gchar *name;
+  gpointer setup_func;
+} TestCaseDef;
+
+TestCaseDef tests[] = {
+  {"wrappercamerabinsrc", setup_wrappercamerabinsrc_videotestsrc}
+};
+
 static Suite *
 camerabin_suite (void)
 {
-  Suite *s = suite_create ("camerabin");
-  TCase *tc_basic = tcase_create ("general");
-
-  /* Test that basic operations run without errors */
-  suite_add_tcase (s, tc_basic);
-  /* Increase timeout due to video recording */
-  tcase_set_timeout (tc_basic, 20);
-  tcase_add_checked_fixture (tc_basic, setup, teardown);
-  tcase_add_test (tc_basic, test_single_image_capture);
-  tcase_add_test (tc_basic, test_single_image_capture_with_flags);
-  tcase_add_test (tc_basic, test_video_recording);
-  tcase_add_test (tc_basic, test_video_recording_with_flags);
-  tcase_add_test (tc_basic, test_video_recording_pause);
-  tcase_add_test (tc_basic, test_video_recording_no_audio);
-  tcase_add_test (tc_basic, test_image_video_cycle);
-  tcase_add_test (tc_basic, test_image_tags_setting);
+  GstElementFactory *jpegenc_factory;
+  Suite *s = suite_create ("camerabin2");
+  gint i;
+  TCase *tc_generic = tcase_create ("generic");
+
+  jpegenc_factory = gst_element_factory_find ("jpegenc");
+  if (jpegenc_factory == NULL) {
+    GST_WARNING ("Skipping camerabin2 tests because jpegenc is missing");
+    goto end;
+  }
+
+  suite_add_tcase (s, tc_generic);
+  tcase_add_checked_fixture (tc_generic, setup_wrappercamerabinsrc_videotestsrc,
+      teardown);
+  tcase_add_test (tc_generic, test_supported_caps);
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++) {
+    TCase *tc_basic = tcase_create (tests[i].name);
+    suite_add_tcase (s, tc_basic);
+
+    /* Increase timeout due to video recording */
+    tcase_set_timeout (tc_basic, 60);
+    tcase_add_checked_fixture (tc_basic, tests[i].setup_func, teardown);
+
+    tcase_add_test (tc_basic, test_single_image_capture);
+    tcase_add_test (tc_basic, test_single_video_recording);
+    tcase_add_test (tc_basic, test_image_video_cycle);
+    if (gst_plugin_feature_check_version ((GstPluginFeature *) jpegenc_factory,
+            0, 10, 27))
+      tcase_add_test (tc_basic, test_multiple_image_captures);
+    else
+      GST_WARNING ("Skipping image capture test because -good 0.10.27 is "
+          "needed");
+    tcase_add_test (tc_basic, test_multiple_video_recordings);
+
+    tcase_add_test (tc_basic, test_image_capture_previews);
+    tcase_add_test (tc_basic, test_image_capture_with_tags);
+
+    tcase_add_test (tc_basic, test_video_capture_with_tags);
+
+    tcase_add_test (tc_basic, test_idle_property);
+
+    tcase_add_test (tc_basic, test_image_custom_filter);
+    tcase_add_test (tc_basic, test_video_custom_filter);
+
+    tcase_add_test (tc_basic, test_image_location_switching);
+  }
 
+end:
   return s;
 }
 
diff --git a/tests/check/elements/camerabin2.c b/tests/check/elements/camerabin2.c
deleted file mode 100644 (file)
index d8bea46..0000000
+++ /dev/null
@@ -1,1585 +0,0 @@
-/* GStreamer
- *
- * unit test for camerabin2 basic operations
- * Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
- * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
- *
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <unistd.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <gst/check/gstcheck.h>
-#include <gst/basecamerabinsrc/gstbasecamerasrc.h>
-#include <gst/pbutils/encoding-profile.h>
-
-#define IMAGE_FILENAME "image"
-#define VIDEO_FILENAME "video"
-#define CAPTURE_COUNT 3
-#define VIDEO_DURATION 5
-
-#define VIDEO_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=600, height=480"
-#define IMAGE_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=800, height=600"
-
-/* custom test camera src element */
-#define GST_TYPE_TEST_CAMERA_SRC \
-  (gst_test_camera_src_get_type())
-#define GST_TEST_CAMERA_SRC(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrc))
-#define GST_TEST_CAMERA_SRC_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrcClass))
-#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEST_CAMERA_SRC))
-#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEST_CAMERA_SRC))
-#define GST_TEST_CAMERA_SRC_CAST(obj) ((GstTestCameraSrc *)obj)
-
-typedef struct _GstTestCameraSrc GstTestCameraSrc;
-typedef struct _GstTestCameraSrcClass GstTestCameraSrcClass;
-struct _GstTestCameraSrc
-{
-  GstBaseCameraSrc element;
-
-  GstPad *vfpad;
-  GstPad *vidpad;
-  GstPad *imgpad;
-
-  GstCameraBinMode mode;
-};
-
-struct _GstTestCameraSrcClass
-{
-  GstBaseCameraSrcClass parent_class;
-};
-
-GType gst_test_camera_src_get_type (void);
-
-#define gst_test_camera_src_parent_class parent_class
-G_DEFINE_TYPE (GstTestCameraSrc, gst_test_camera_src, GST_TYPE_BASE_CAMERA_SRC);
-
-static gboolean
-gst_test_camera_src_set_mode (GstBaseCameraSrc * src, GstCameraBinMode mode)
-{
-  GstTestCameraSrc *self = GST_TEST_CAMERA_SRC (src);
-
-  self->mode = mode;
-  return TRUE;
-}
-
-static gboolean
-gst_test_camera_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
-{
-  GstTestCameraSrc *self = (GstTestCameraSrc *) GST_PAD_PARENT (pad);
-  GstCaps *result = NULL;
-  gboolean ret = FALSE;
-
-  switch (GST_QUERY_TYPE (query)) {
-    case GST_QUERY_CAPS:
-      if (pad == self->vfpad) {
-        result = gst_caps_new_any ();
-      } else if (pad == self->vidpad) {
-        result = gst_caps_from_string (VIDEO_PAD_SUPPORTED_CAPS);
-      } else if (pad == self->imgpad) {
-        result = gst_caps_from_string (IMAGE_PAD_SUPPORTED_CAPS);
-      } else {
-        g_assert_not_reached ();
-      }
-      if (result) {
-        GstCaps *filter;
-
-        gst_query_parse_caps (query, &filter);
-        if (filter) {
-          GstCaps *tmp;
-          tmp = gst_caps_intersect (result, filter);
-          gst_caps_replace (&result, tmp);
-          gst_caps_unref (tmp);
-        }
-        gst_query_set_caps_result (query, result);
-        ret = TRUE;
-      }
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-}
-
-static void
-gst_test_camera_src_class_init (GstTestCameraSrcClass * klass)
-{
-  GstBaseCameraSrcClass *gstbasecamera_class;
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
-  gstbasecamera_class = GST_BASE_CAMERA_SRC_CLASS (klass);
-  gstbasecamera_class->set_mode = gst_test_camera_src_set_mode;
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Test Camera Src",
-      "Camera/Src",
-      "Some test camera src",
-      "Thiago Santos <thiago.sousa.santos@collabora.com>");
-}
-
-static void
-gst_test_camera_src_init (GstTestCameraSrc * self)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (parent_class);
-  GstPadTemplate *template;
-
-  /* create pads */
-  template = gst_element_class_get_pad_template (gstelement_class,
-      GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME);
-  self->vfpad = gst_pad_new_from_template (template,
-      GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME);
-  gst_element_add_pad (GST_ELEMENT_CAST (self), self->vfpad);
-
-  template = gst_element_class_get_pad_template (gstelement_class,
-      GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);
-  self->imgpad = gst_pad_new_from_template (template,
-      GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);
-  gst_element_add_pad (GST_ELEMENT_CAST (self), self->imgpad);
-
-  template = gst_element_class_get_pad_template (gstelement_class,
-      GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
-  self->vidpad = gst_pad_new_from_template (template,
-      GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
-  gst_element_add_pad (GST_ELEMENT_CAST (self), self->vidpad);
-
-  /* add get caps functions */
-  gst_pad_set_query_function (self->vfpad, gst_test_camera_src_query);
-  gst_pad_set_query_function (self->vidpad, gst_test_camera_src_query);
-  gst_pad_set_query_function (self->imgpad, gst_test_camera_src_query);
-}
-
-/* end of custom test camera src element */
-
-
-static GstElement *camera;
-static guint bus_source;
-static GMainLoop *main_loop;
-static gint capture_count = 0;
-guint32 test_id = 0;
-static gchar *image_filename;
-static gchar *video_filename;
-
-static GstBuffer *preview_buffer;
-static gchar *preview_filename;
-static GstCaps *preview_caps;
-static GstTagList *tags_found;
-
-static gboolean
-validity_bus_cb (GstBus * bus, GstMessage * message, gpointer data);
-
-static GstMessage *wait_for_element_message (GstElement * camera,
-    const gchar * name, GstClockTime timeout);
-
-static void
-validate_taglist_foreach (const GstTagList * list, const gchar * tag,
-    gpointer user_data)
-{
-  GstTagList *other = GST_TAG_LIST (user_data);
-
-  const GValue *val1 = gst_tag_list_get_value_index (list, tag, 0);
-  const GValue *val2 = gst_tag_list_get_value_index (other, tag, 0);
-
-  GST_DEBUG ("checking tag '%s'", tag);
-
-  fail_if (val1 == NULL);
-  fail_if (val2 == NULL);
-
-  fail_unless (gst_value_compare (val1, val2) == GST_VALUE_EQUAL);
-}
-
-
-/* helper function for filenames */
-static gchar *
-make_test_file_name (const gchar * base_name, gint num)
-{
-  /* num == -1 means to keep the %d in the resulting string to be used on
-   * multifilesink like location */
-  if (num == -1) {
-    return g_strdup_printf ("%s" G_DIR_SEPARATOR_S
-        "gstcamerabin2test_%s_%u_%%03d.cap", g_get_tmp_dir (), base_name,
-        test_id);
-  } else {
-    return g_strdup_printf ("%s" G_DIR_SEPARATOR_S
-        "gstcamerabin2test_%s_%u_%03d.cap", g_get_tmp_dir (), base_name,
-        test_id, num);
-  }
-}
-
-static const gchar *
-make_const_file_name (const gchar * filename, gint num)
-{
-  static gchar file_name[1000];
-
-  /* num == -1 means to keep the %d in the resulting string to be used on
-   * multifilesink like location */
-  g_snprintf (file_name, 999, filename, num);
-
-  return file_name;
-}
-
-/* configuration */
-
-static gboolean
-capture_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
-{
-  GMainLoop *loop = (GMainLoop *) data;
-  const GstStructure *st;
-
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ERROR:{
-      GError *err = NULL;
-      gchar *debug = NULL;
-
-      gst_message_parse_error (message, &err, &debug);
-      GST_WARNING ("ERROR: %s [%s]", err->message, debug);
-      g_error_free (err);
-      g_free (debug);
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera),
-          GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error");
-
-      fail_if (TRUE, "error while capturing");
-      g_main_loop_quit (loop);
-      break;
-    }
-    case GST_MESSAGE_WARNING:{
-      GError *err = NULL;
-      gchar *debug = NULL;
-
-      gst_message_parse_warning (message, &err, &debug);
-      GST_WARNING ("WARNING: %s [%s]", err->message, debug);
-      g_error_free (err);
-      g_free (debug);
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera),
-          GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.warning");
-      break;
-    }
-    case GST_MESSAGE_EOS:
-      GST_DEBUG ("eos");
-      g_main_loop_quit (loop);
-      break;
-    default:
-      st = gst_message_get_structure (message);
-      if (st && gst_structure_has_name (st, "image-done")) {
-        GST_INFO ("image captured");
-      } else if (st && gst_structure_has_name (st,
-              GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME)) {
-        GstBuffer *buf;
-        const GValue *value;
-
-        value = gst_structure_get_value (st, "buffer");
-        fail_unless (value != NULL);
-        buf = gst_value_get_buffer (value);
-
-        if (preview_buffer)
-          gst_buffer_unref (preview_buffer);
-        preview_buffer = gst_buffer_ref (buf);
-        g_free (preview_filename);
-        preview_filename = g_strdup (gst_structure_get_string (st, "location"));
-      }
-      break;
-  }
-  return TRUE;
-}
-
-static void
-check_preview_image (GstElement * camera, const gchar * filename, gint index)
-{
-  gchar *prev_filename = NULL;
-
-  if (!preview_buffer && camera) {
-    GstMessage *msg = wait_for_element_message (camera,
-        GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME, GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-  }
-  fail_unless (preview_buffer != NULL);
-  if (filename) {
-    if (index >= 0) {
-      prev_filename = g_strdup_printf (filename, index);
-    } else {
-      prev_filename = g_strdup (filename);
-    }
-    fail_unless (preview_filename != NULL);
-    fail_unless (strcmp (preview_filename, prev_filename) == 0);
-  }
-  if (preview_caps) {
-    /* TODO porting
-       fail_unless (GST_BUFFER_CAPS (preview_buffer) != NULL);
-       fail_unless (gst_caps_can_intersect (GST_BUFFER_CAPS (preview_buffer),
-       preview_caps));
-     */
-  }
-  g_free (prev_filename);
-}
-
-static void
-extract_jpeg_tags (const gchar * filename, gint num)
-{
-  GstBus *bus;
-  GMainLoop *loop = g_main_loop_new (NULL, FALSE);
-  const gchar *filepath = make_const_file_name (filename, num);
-  gchar *pipeline_str = g_strdup_printf ("filesrc location=%s ! "
-      "jpegparse ! fakesink", filepath);
-  GstElement *pipeline;
-  guint source;
-
-  pipeline = gst_parse_launch (pipeline_str, NULL);
-  fail_unless (pipeline != NULL);
-  g_free (pipeline_str);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
-  source = gst_bus_add_watch (bus, (GstBusFunc) validity_bus_cb, loop);
-
-  gst_element_set_state (pipeline, GST_STATE_PLAYING);
-  g_main_loop_run (loop);
-  gst_element_set_state (pipeline, GST_STATE_NULL);
-
-  gst_object_unref (bus);
-  g_source_remove (source);
-  gst_object_unref (pipeline);
-  g_main_loop_unref (loop);
-}
-
-static void
-setup_wrappercamerabinsrc_videotestsrc (void)
-{
-  GstBus *bus;
-  GstElement *vfbin;
-  GstElement *fakevideosink;
-  GstElement *src;
-  GstElement *testsrc;
-  GstElement *audiosrc;
-
-  GST_INFO ("init");
-
-  test_id = g_random_int ();
-  bus_source = 0;
-
-  main_loop = g_main_loop_new (NULL, TRUE);
-
-  camera = gst_check_setup_element ("camerabin2");
-  fakevideosink = gst_element_factory_make ("fakesink", NULL);
-  src = gst_element_factory_make ("wrappercamerabinsrc", NULL);
-  testsrc = gst_element_factory_make ("videotestsrc", NULL);
-  audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
-
-  preview_caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
-      320, "height", G_TYPE_INT, 240, NULL);
-
-  g_object_set (G_OBJECT (testsrc), "is-live", TRUE, NULL);
-  g_object_set (G_OBJECT (audiosrc), "is-live", TRUE, NULL);
-  g_object_set (G_OBJECT (src), "video-source", testsrc, NULL);
-  g_object_set (G_OBJECT (camera), "camera-source", src, "preview-caps",
-      preview_caps, "post-previews", TRUE, "audio-source", audiosrc, NULL);
-  gst_object_unref (src);
-  gst_object_unref (testsrc);
-  gst_object_unref (audiosrc);
-
-  vfbin = gst_bin_get_by_name (GST_BIN (camera), "vf-bin");
-  g_object_set (G_OBJECT (vfbin), "video-sink", fakevideosink, NULL);
-  gst_object_unref (vfbin);
-  gst_object_unref (fakevideosink);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
-  bus_source = gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop);
-  gst_object_unref (bus);
-
-  tags_found = NULL;
-  capture_count = 0;
-  image_filename = make_test_file_name (IMAGE_FILENAME, -1);
-  video_filename = make_test_file_name (VIDEO_FILENAME, -1);
-
-  GST_INFO ("init finished");
-}
-
-static void
-teardown (void)
-{
-  gst_element_set_state (camera, GST_STATE_NULL);
-
-  if (camera)
-    gst_check_teardown_element (camera);
-  camera = NULL;
-
-  if (bus_source)
-    g_source_remove (bus_source);
-
-  if (main_loop)
-    g_main_loop_unref (main_loop);
-  main_loop = NULL;
-
-  if (preview_caps)
-    gst_caps_unref (preview_caps);
-  preview_caps = NULL;
-
-  if (preview_buffer)
-    gst_buffer_unref (preview_buffer);
-  preview_buffer = NULL;
-
-  g_free (preview_filename);
-  preview_filename = NULL;
-
-  if (tags_found)
-    gst_tag_list_free (tags_found);
-  tags_found = NULL;
-
-  g_free (video_filename);
-  video_filename = NULL;
-
-  g_free (image_filename);
-  image_filename = NULL;
-
-  GST_INFO ("done");
-}
-
-static gboolean
-validity_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
-{
-  GMainLoop *loop = (GMainLoop *) data;
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ERROR:{
-      GError *err = NULL;
-      gchar *debug = NULL;
-
-      gst_message_parse_error (message, &err, &debug);
-
-      GST_ERROR ("Error: %s : %s", err->message, debug);
-      g_error_free (err);
-      g_free (debug);
-
-      fail_if (TRUE, "validating captured data failed");
-      g_main_loop_quit (loop);
-    }
-      break;
-    case GST_MESSAGE_EOS:
-      g_main_loop_quit (loop);
-      GST_DEBUG ("eos");
-      break;
-    case GST_MESSAGE_TAG:{
-      GstTagList *taglist = NULL;
-
-      gst_message_parse_tag (message, &taglist);
-      if (tags_found) {
-        gst_tag_list_insert (tags_found, taglist, GST_TAG_MERGE_REPLACE);
-        gst_tag_list_free (taglist);
-      } else {
-        tags_found = taglist;
-      }
-      GST_DEBUG ("tags: %" GST_PTR_FORMAT, tags_found);
-    }
-      break;
-    default:
-      break;
-  }
-  return TRUE;
-}
-
-/* checks that tags in @tags_a are in @tags_b */
-static gboolean
-taglist_is_subset (GstTagList * tags_a, GstTagList * tags_b)
-{
-  gst_tag_list_foreach (tags_a, validate_taglist_foreach, tags_b);
-  return TRUE;
-}
-
-/* Validate captured files by playing them with playbin
- * and checking that no errors occur. */
-#define WITH_AUDIO TRUE
-#define NO_AUDIO FALSE
-static gboolean
-check_file_validity (const gchar * filename, gint num, GstTagList * taglist,
-    gint width, gint height, gboolean has_audio)
-{
-  GstBus *bus;
-  GstPad *pad;
-  GstCaps *caps;
-  gint caps_width, caps_height;
-  GstState state;
-  guint source;
-
-  GMainLoop *loop = g_main_loop_new (NULL, FALSE);
-  GstElement *playbin = gst_element_factory_make ("playbin2", NULL);
-  GstElement *fakevideo = gst_element_factory_make ("fakesink", NULL);
-  GstElement *fakeaudio = gst_element_factory_make ("fakesink", NULL);
-  gchar *uri = g_strconcat ("file://", make_const_file_name (filename, num),
-      NULL);
-
-  GST_DEBUG ("checking uri: %s", uri);
-  g_object_set (G_OBJECT (playbin), "uri", uri, "video-sink", fakevideo,
-      "audio-sink", fakeaudio, NULL);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (playbin));
-  source = gst_bus_add_watch (bus, (GstBusFunc) validity_bus_cb, loop);
-
-  gst_element_set_state (playbin, GST_STATE_PAUSED);
-  gst_element_get_state (playbin, &state, NULL, GST_SECOND * 3);
-
-  if (width != 0 && height != 0) {
-    g_signal_emit_by_name (playbin, "get-video-pad", 0, &pad, NULL);
-    g_assert (pad != NULL);
-    caps = gst_pad_get_current_caps (pad);
-
-    g_assert (gst_structure_get_int (gst_caps_get_structure (caps, 0),
-            "width", &caps_width));
-    g_assert (gst_structure_get_int (gst_caps_get_structure (caps, 0),
-            "height", &caps_height));
-
-    g_assert (width == caps_width);
-    g_assert (height == caps_height);
-
-    gst_caps_unref (caps);
-    gst_object_unref (pad);
-  }
-  if (has_audio) {
-    g_signal_emit_by_name (playbin, "get-audio-pad", 0, &pad, NULL);
-    g_assert (pad != NULL);
-    gst_object_unref (pad);
-  }
-
-  gst_element_set_state (playbin, GST_STATE_PLAYING);
-  g_main_loop_run (loop);
-  gst_element_set_state (playbin, GST_STATE_NULL);
-
-  /* special handling for images (jpg) as jpegparse isn't plugged by
-   * default due to its current low rank */
-  if (taglist && strstr (filename, "image")) {
-    extract_jpeg_tags (filename, num);
-  }
-
-  if (taglist) {
-    fail_unless (tags_found != NULL);
-    fail_unless (taglist_is_subset (taglist, tags_found));
-  }
-
-  g_free (uri);
-  g_source_remove (source);
-  gst_object_unref (bus);
-  gst_object_unref (playbin);
-  g_main_loop_unref (loop);
-
-  return TRUE;
-}
-
-static void
-remove_file (const gchar * fn_template, guint num)
-{
-  const gchar *fn;
-
-  fn = make_const_file_name (fn_template, num);
-  GST_INFO ("removing %s", fn);
-  g_unlink (fn);
-}
-
-static GstPadProbeReturn
-filter_buffer_count (GstPad * pad, GstPadProbeInfo * info, gpointer data)
-{
-  gint *counter = data;
-
-  (*counter)++;
-
-  return GST_PAD_PROBE_OK;
-}
-
-static GstMessage *
-wait_for_element_message (GstElement * camera, const gchar * name,
-    GstClockTime timeout)
-{
-  GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
-  GstMessage *msg;
-
-  while (1) {
-    msg = gst_bus_timed_pop_filtered (bus, timeout, GST_MESSAGE_ERROR |
-        GST_MESSAGE_EOS | GST_MESSAGE_ELEMENT);
-
-    if (msg) {
-      if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT) {
-        const GstStructure *st = gst_message_get_structure (msg);
-        if (gst_structure_has_name (st,
-                GST_BASE_CAMERA_SRC_PREVIEW_MESSAGE_NAME)) {
-          GstBuffer *buf;
-          const GValue *value;
-
-          value = gst_structure_get_value (st, "buffer");
-          fail_unless (value != NULL);
-          buf = gst_value_get_buffer (value);
-
-          if (preview_buffer)
-            gst_buffer_unref (preview_buffer);
-          preview_buffer = gst_buffer_ref (buf);
-          g_free (preview_filename);
-          preview_filename =
-              g_strdup (gst_structure_get_string (st, "location"));
-        }
-
-        if (gst_structure_has_name (st, name))
-          break;
-        else
-          gst_message_unref (msg);
-      } else {
-        gst_message_unref (msg);
-        msg = NULL;
-        break;
-      }
-    }
-  }
-
-  gst_object_unref (bus);
-  return msg;
-}
-
-static void
-wait_for_idle_state (void)
-{
-  gboolean idle = FALSE;
-
-  /* not the ideal way, but should be enough for testing */
-  while (idle == FALSE) {
-    g_object_get (camera, "idle", &idle, NULL);
-    if (idle)
-      break;
-
-    GST_LOG ("waiting for idle state..");
-    g_usleep (G_USEC_PER_SEC / 5);
-  }
-  fail_unless (idle);
-}
-
-GST_START_TEST (test_single_image_capture)
-{
-  gboolean idle;
-  GstMessage *msg;
-  if (!camera)
-    return;
-
-  /* set still image mode */
-  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-
-  msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-  fail_unless (msg != NULL);
-  gst_message_unref (msg);
-
-  /* check that we got a preview image */
-  check_preview_image (camera, image_filename, 0);
-
-  wait_for_idle_state ();
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-  check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
-  remove_file (image_filename, 0);
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_multiple_image_captures)
-{
-  gboolean idle;
-  gint i;
-  gint widths[] = { 800, 640, 1280 };
-  gint heights[] = { 600, 480, 1024 };
-
-  if (!camera)
-    return;
-
-  /* set still image mode */
-  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  fail_unless (camera != NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle);
-  GST_INFO ("starting capture");
-
-  for (i = 0; i < 3; i++) {
-    GstMessage *msg;
-    GstCaps *caps;
-
-    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
-        widths[i], "height", G_TYPE_INT, heights[i], NULL);
-
-    g_object_set (camera, "image-capture-caps", caps, NULL);
-    gst_caps_unref (caps);
-
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-
-    check_preview_image (camera, image_filename, i);
-  }
-
-  wait_for_idle_state ();
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-  for (i = 0; i < 3; i++) {
-    check_file_validity (image_filename, i, NULL, widths[i], heights[i],
-        NO_AUDIO);
-    remove_file (image_filename, i);
-  }
-}
-
-GST_END_TEST;
-
-GST_START_TEST (test_single_video_recording)
-{
-  GstMessage *msg;
-  gboolean idle;
-  if (!camera)
-    return;
-
-  /* Set video recording mode */
-  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (!idle);
-
-  /* Record for one seconds  */
-  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
-      main_loop);
-  g_main_loop_run (main_loop);
-
-  g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-  check_preview_image (camera, video_filename, 0);
-
-  msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
-  fail_unless (msg != NULL);
-  gst_message_unref (msg);
-
-  wait_for_idle_state ();
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
-  remove_file (video_filename, 0);
-
-}
-
-GST_END_TEST;
-
-GST_START_TEST (test_multiple_video_recordings)
-{
-  gboolean idle;
-  gint i;
-  gint widths[] = { 800, 640, 1280 };
-  gint heights[] = { 600, 480, 1024 };
-  gint fr[] = { 20, 30, 5 };
-
-  if (!camera)
-    return;
-
-  /* Set video recording mode */
-  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle);
-  for (i = 0; i < 3; i++) {
-    GstMessage *msg;
-    GstCaps *caps;
-
-    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
-        widths[i], "height", G_TYPE_INT, heights[i], "framerate",
-        GST_TYPE_FRACTION, fr[i], 1, NULL);
-
-    g_object_set (camera, "video-capture-caps", caps, NULL);
-
-    gst_caps_unref (caps);
-
-    GST_LOG ("starting #%d with caps %" GST_PTR_FORMAT, i, caps);
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    g_object_get (camera, "idle", &idle, NULL);
-    fail_unless (!idle);
-
-    g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
-        main_loop);
-    g_main_loop_run (main_loop);
-
-    GST_LOG ("stopping run %d", i);
-    g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-
-    GST_LOG ("video done, checking preview image");
-    check_preview_image (camera, video_filename, i);
-
-    GST_LOG ("waiting for idle state");
-    wait_for_idle_state ();
-    GST_LOG ("finished run %d", i);
-  }
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  for (i = 0; i < 3; i++) {
-    check_file_validity (video_filename, i, NULL, widths[i], heights[i],
-        WITH_AUDIO);
-    remove_file (video_filename, i);
-  }
-}
-
-GST_END_TEST;
-
-GST_START_TEST (test_image_video_cycle)
-{
-  gint i;
-
-  if (!camera)
-    return;
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-
-  GST_INFO ("starting capture");
-  for (i = 0; i < 2; i++) {
-    GstMessage *msg;
-    const gchar *img_filename;
-    const gchar *vid_filename;
-
-    wait_for_idle_state ();
-
-    /* take a picture */
-    img_filename = make_const_file_name (image_filename, i);
-    g_object_set (camera, "mode", 1, NULL);
-    g_object_set (camera, "location", img_filename, NULL);
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-
-    check_preview_image (camera, img_filename, i);
-
-    /* now go to video */
-    vid_filename = make_const_file_name (video_filename, i);
-    g_object_set (camera, "mode", 2, NULL);
-    g_object_set (camera, "location", vid_filename, NULL);
-
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-    g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
-        main_loop);
-    g_main_loop_run (main_loop);
-    g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-
-    check_preview_image (camera, vid_filename, i);
-  }
-
-  wait_for_idle_state ();
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  /* validate all the files */
-  for (i = 0; i < 2; i++) {
-    check_file_validity (image_filename, i, NULL, 0, 0, NO_AUDIO);
-    remove_file (image_filename, i);
-    check_file_validity (video_filename, i, NULL, 0, 0, WITH_AUDIO);
-    remove_file (video_filename, i);
-  }
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_image_capture_previews)
-{
-  gint i;
-  gint widths[] = { 800, 640, 1280 };
-  gint heights[] = { 600, 480, 1024 };
-
-  if (!camera)
-    return;
-
-  /* set still image mode */
-  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  fail_unless (camera != NULL);
-  GST_INFO ("starting capture");
-
-  for (i = 0; i < 3; i++) {
-    GstMessage *msg;
-    GstCaps *caps;
-
-    caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
-        widths[i], "height", G_TYPE_INT, heights[i], NULL);
-
-    g_object_set (camera, "preview-caps", caps, NULL);
-    gst_caps_replace (&preview_caps, caps);
-    gst_caps_unref (caps);
-
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-
-    check_preview_image (camera, image_filename, i);
-    remove_file (image_filename, i);
-
-    if (preview_buffer)
-      gst_buffer_unref (preview_buffer);
-    preview_buffer = NULL;
-    gst_caps_replace (&preview_caps, NULL);
-  }
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_image_capture_with_tags)
-{
-  gint i;
-  GstTagList *taglists[3];
-
-  if (!camera)
-    return;
-
-  taglists[0] = gst_tag_list_new (GST_TAG_COMMENT, "test1",
-      GST_TAG_GEO_LOCATION_LATITUDE, 36.6, GST_TAG_GEO_LOCATION_LONGITUDE,
-      -12.5,
-      GST_TAG_COPYRIGHT, "My copyright notice",
-      GST_TAG_DEVICE_MANUFACTURER, "MyFavoriteBrand",
-      GST_TAG_DEVICE_MODEL, "123v42.1",
-      GST_TAG_DESCRIPTION, "some description",
-      GST_TAG_APPLICATION_NAME, "camerabin2 test",
-      GST_TAG_GEO_LOCATION_ELEVATION, 300.85, NULL);
-  taglists[1] = gst_tag_list_new (GST_TAG_COMMENT, "test2",
-      GST_TAG_GEO_LOCATION_LATITUDE, 1.6, GST_TAG_GEO_LOCATION_LONGITUDE,
-      0.0,
-      GST_TAG_COPYRIGHT, "some cp",
-      GST_TAG_DEVICE_MANUFACTURER, "ABRAND",
-      GST_TAG_DEVICE_MODEL, "abcd",
-      GST_TAG_DESCRIPTION, "desc",
-      GST_TAG_APPLICATION_NAME, "another cam test",
-      GST_TAG_GEO_LOCATION_ELEVATION, 10.0, NULL);
-  taglists[2] = gst_tag_list_new (GST_TAG_COMMENT, "test3",
-      GST_TAG_GEO_LOCATION_LATITUDE, 1.3, GST_TAG_GEO_LOCATION_LONGITUDE,
-      -5.0,
-      GST_TAG_COPYRIGHT, "CC",
-      GST_TAG_DEVICE_MANUFACTURER, "Homemade",
-      GST_TAG_DEVICE_MODEL, "xpto",
-      GST_TAG_DESCRIPTION, "another  description",
-      GST_TAG_APPLICATION_NAME, "cam2 test",
-      GST_TAG_GEO_LOCATION_ELEVATION, 0.0, NULL);
-
-  /* set still image mode */
-  g_object_set (camera, "mode", 1, "location", image_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  fail_unless (camera != NULL);
-  GST_INFO ("starting capture");
-
-  for (i = 0; i < 3; i++) {
-    GstMessage *msg;
-    gst_tag_setter_merge_tags (GST_TAG_SETTER (camera), taglists[i],
-        GST_TAG_MERGE_REPLACE);
-
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-  }
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  for (i = 0; i < 3; i++) {
-    check_file_validity (image_filename, i, taglists[i], 0, 0, NO_AUDIO);
-    gst_tag_list_free (taglists[i]);
-    remove_file (image_filename, i);
-  }
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_video_capture_with_tags)
-{
-  gint i;
-  GstTagList *taglists[3];
-
-  if (!camera)
-    return;
-
-  taglists[0] = gst_tag_list_new (GST_TAG_COMMENT, "test1", NULL);
-  taglists[1] = gst_tag_list_new (GST_TAG_COMMENT, "test2", NULL);
-  taglists[2] = gst_tag_list_new (GST_TAG_COMMENT, "test3", NULL);
-
-  /* set video mode */
-  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
-
-  /* set a profile that has xmp support for more tags being saved */
-  {
-    GstEncodingContainerProfile *profile;
-    GstCaps *caps;
-
-    caps =
-        gst_caps_new_simple ("video/quicktime", "variant", G_TYPE_STRING,
-        "apple", NULL);
-    profile = gst_encoding_container_profile_new ("qt", "jpeg+qt", caps, NULL);
-    gst_caps_unref (caps);
-
-    caps = gst_caps_new_simple ("image/jpeg", NULL, NULL);
-    if (!gst_encoding_container_profile_add_profile (profile,
-            (GstEncodingProfile *) gst_encoding_video_profile_new (caps,
-                NULL, NULL, 1))) {
-      GST_WARNING_OBJECT (camera, "Failed to create encoding profiles");
-    }
-    gst_caps_unref (caps);
-
-    g_object_set (camera, "video-profile", profile, NULL);
-    gst_encoding_profile_unref (profile);
-  }
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  fail_unless (camera != NULL);
-  GST_INFO ("starting capture");
-
-  for (i = 0; i < 3; i++) {
-    GstMessage *msg;
-
-    gst_tag_setter_merge_tags (GST_TAG_SETTER (camera), taglists[i],
-        GST_TAG_MERGE_REPLACE);
-
-    g_signal_emit_by_name (camera, "start-capture", NULL);
-
-    g_timeout_add_seconds (3, (GSourceFunc) g_main_loop_quit, main_loop);
-    g_main_loop_run (main_loop);
-
-    g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-    msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
-    fail_unless (msg != NULL);
-    gst_message_unref (msg);
-  }
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  for (i = 0; i < 3; i++) {
-    check_file_validity (video_filename, i, taglists[i], 0, 0, NO_AUDIO);
-    gst_tag_list_free (taglists[i]);
-    remove_file (video_filename, i);
-  }
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_supported_caps)
-{
-  GstCaps *padcaps = NULL;
-  GstCaps *expectedcaps;
-  GstElement *src;
-
-  if (!camera)
-    return;
-
-  src = g_object_new (GST_TYPE_TEST_CAMERA_SRC, NULL);
-  g_object_set (camera, "camera-source", src, NULL);
-  gst_object_unref (src);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  g_assert (camera != NULL);
-
-  expectedcaps = gst_caps_from_string (VIDEO_PAD_SUPPORTED_CAPS);
-  g_object_get (G_OBJECT (camera), "video-capture-supported-caps", &padcaps,
-      NULL);
-  g_assert (expectedcaps != NULL);
-  g_assert (padcaps != NULL);
-  g_assert (gst_caps_is_equal (padcaps, expectedcaps));
-  gst_caps_unref (expectedcaps);
-  gst_caps_unref (padcaps);
-
-  expectedcaps = gst_caps_from_string (IMAGE_PAD_SUPPORTED_CAPS);
-  g_object_get (G_OBJECT (camera), "image-capture-supported-caps", &padcaps,
-      NULL);
-  g_assert (expectedcaps != NULL);
-  g_assert (padcaps != NULL);
-  g_assert (gst_caps_is_equal (padcaps, expectedcaps));
-  gst_caps_unref (expectedcaps);
-  gst_caps_unref (padcaps);
-
-  gst_element_set_state (camera, GST_STATE_NULL);
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_idle_property)
-{
-  GstMessage *msg;
-  gboolean idle;
-  if (!camera)
-    return;
-
-  /* Set video recording mode */
-  g_object_set (camera, "mode", 2, "location", video_filename, NULL);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (idle);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (!idle);
-
-  /* emit a second start-capture that should be ignored */
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-  g_object_get (camera, "idle", &idle, NULL);
-  fail_unless (!idle);
-
-  /* Record for one seconds  */
-  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
-      main_loop);
-  g_main_loop_run (main_loop);
-
-  g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-  msg = wait_for_element_message (camera, "video-done", GST_CLOCK_TIME_NONE);
-  fail_unless (msg != NULL);
-  gst_message_unref (msg);
-
-  check_preview_image (camera, video_filename, 0);
-
-  wait_for_idle_state ();
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
-  remove_file (video_filename, 0);
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_image_custom_filter)
-{
-  GstElement *vf_filter;
-  GstElement *image_filter;
-  GstElement *preview_filter;
-  GstPad *pad;
-  gint vf_probe_counter = 0;
-  gint image_probe_counter = 0;
-  gint preview_probe_counter = 0;
-
-  if (!camera)
-    return;
-
-  vf_filter = gst_element_factory_make ("identity", "vf-filter");
-  image_filter = gst_element_factory_make ("identity", "img-filter");
-  preview_filter = gst_element_factory_make ("identity", "preview-filter");
-
-  pad = gst_element_get_static_pad (vf_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &vf_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  pad = gst_element_get_static_pad (image_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &image_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  pad = gst_element_get_static_pad (preview_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &preview_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  /* set still image mode and filters */
-  g_object_set (camera, "mode", 1,
-      "location", image_filename,
-      "viewfinder-filter", vf_filter, "image-filter", image_filter,
-      "preview-filter", preview_filter, NULL);
-
-  gst_object_unref (vf_filter);
-  gst_object_unref (preview_filter);
-  gst_object_unref (image_filter);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-
-  g_timeout_add_seconds (3, (GSourceFunc) g_main_loop_quit, main_loop);
-  g_main_loop_run (main_loop);
-
-  /* check that we got a preview image */
-  check_preview_image (camera, image_filename, 0);
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-  check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO);
-  remove_file (image_filename, 0);
-
-  fail_unless (vf_probe_counter > 0);
-  fail_unless (image_probe_counter == 1);
-  fail_unless (preview_probe_counter == 1);
-}
-
-GST_END_TEST;
-
-
-GST_START_TEST (test_video_custom_filter)
-{
-  GstElement *vf_filter;
-  GstElement *video_filter;
-  GstElement *preview_filter;
-  GstElement *audio_filter;
-  GstPad *pad;
-  gint vf_probe_counter = 0;
-  gint video_probe_counter = 0;
-  gint preview_probe_counter = 0;
-  gint audio_probe_counter = 0;
-
-  if (!camera)
-    return;
-
-  vf_filter = gst_element_factory_make ("identity", "vf-filter");
-  video_filter = gst_element_factory_make ("identity", "video-filter");
-  preview_filter = gst_element_factory_make ("identity", "preview-filter");
-  audio_filter = gst_element_factory_make ("identity", "audio-filter");
-
-  pad = gst_element_get_static_pad (vf_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &vf_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  pad = gst_element_get_static_pad (video_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &video_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  pad = gst_element_get_static_pad (audio_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &audio_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  pad = gst_element_get_static_pad (preview_filter, "src");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, filter_buffer_count,
-      &preview_probe_counter, NULL);
-  gst_object_unref (pad);
-
-  /* set still image mode and filters */
-  g_object_set (camera, "mode", 2,
-      "location", video_filename,
-      "viewfinder-filter", vf_filter, "video-filter", video_filter,
-      "preview-filter", preview_filter, "audio-filter", audio_filter, NULL);
-
-  gst_object_unref (vf_filter);
-  gst_object_unref (preview_filter);
-  gst_object_unref (video_filter);
-  gst_object_unref (audio_filter);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  GST_INFO ("starting capture");
-  fail_unless (camera != NULL);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-
-  g_timeout_add_seconds (VIDEO_DURATION, (GSourceFunc) g_main_loop_quit,
-      main_loop);
-  g_main_loop_run (main_loop);
-  g_signal_emit_by_name (camera, "stop-capture", NULL);
-
-  /* check that we got a preview image */
-  check_preview_image (camera, video_filename, 0);
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-  check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO);
-  remove_file (video_filename, 0);
-
-  fail_unless (vf_probe_counter > 0);
-  fail_unless (video_probe_counter > 0);
-  fail_unless (audio_probe_counter > 0);
-  fail_unless (preview_probe_counter == 1);
-}
-
-GST_END_TEST;
-
-#define LOCATION_SWITCHING_FILENAMES_COUNT 5
-
-static gboolean
-image_location_switch_do_capture (gpointer data)
-{
-  gchar **filenames = data;
-  if (capture_count >= LOCATION_SWITCHING_FILENAMES_COUNT) {
-    g_main_loop_quit (main_loop);
-  }
-
-  g_object_set (camera, "location", filenames[capture_count], NULL);
-  g_signal_emit_by_name (camera, "start-capture", NULL);
-  capture_count++;
-  return FALSE;
-}
-
-static void
-image_location_switch_readyforcapture (GObject * obj, GParamSpec * pspec,
-    gpointer user_data)
-{
-  gboolean ready;
-
-  g_object_get (obj, "ready-for-capture", &ready, NULL);
-  if (ready) {
-    g_idle_add (image_location_switch_do_capture, user_data);
-  }
-};
-
-/*
- * Tests that setting the location and then doing an image
- * capture will set this capture resulting filename to the
- * correct location.
- *
- * There was a bug in which setting the location, issuing a capture 
- * and then setting a new location would cause this capture to have
- * the location set after this capture. This test should prevent it
- * from happening again.
- */
-GST_START_TEST (test_image_location_switching)
-{
-  gchar *filenames[LOCATION_SWITCHING_FILENAMES_COUNT + 1];
-  gint i;
-  glong notify_id;
-  GstCaps *caps;
-  GstElement *src;
-  GstMessage *msg;
-
-  if (!camera)
-    return;
-
-  g_object_get (camera, "camera-source", &src, NULL);
-
-  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
-    filenames[i] = make_test_file_name ("image-switching-filename-test", i);
-  }
-  filenames[LOCATION_SWITCHING_FILENAMES_COUNT] = NULL;
-
-  /* set still image mode */
-  g_object_set (camera, "mode", 1, NULL);
-  caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
-      800, "height", G_TYPE_INT, 600, NULL);
-  g_object_set (camera, "image-capture-caps", caps, NULL);
-  gst_caps_unref (caps);
-
-  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
-      GST_STATE_CHANGE_FAILURE) {
-    GST_WARNING ("setting camerabin to PLAYING failed");
-    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-    gst_object_unref (camera);
-    camera = NULL;
-  }
-  fail_unless (camera != NULL);
-  GST_INFO ("starting capture");
-
-  notify_id = g_signal_connect (G_OBJECT (src),
-      "notify::ready-for-capture",
-      G_CALLBACK (image_location_switch_readyforcapture), filenames);
-
-  g_idle_add (image_location_switch_do_capture, filenames);
-  g_main_loop_run (main_loop);
-
-  msg = wait_for_element_message (camera, "image-done", GST_CLOCK_TIME_NONE);
-  fail_unless (msg != NULL);
-  gst_message_unref (msg);
-
-  gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
-
-  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
-    GST_INFO ("Checking for file: %s", filenames[i]);
-    fail_unless (g_file_test (filenames[i], G_FILE_TEST_IS_REGULAR));
-  }
-
-  for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) {
-    g_unlink (filenames[i]);
-    g_free (filenames[i]);
-  }
-  g_signal_handler_disconnect (src, notify_id);
-}
-
-GST_END_TEST;
-
-
-typedef struct _TestCaseDef
-{
-  const gchar *name;
-  gpointer setup_func;
-} TestCaseDef;
-
-TestCaseDef tests[] = {
-  {"wrappercamerabinsrc", setup_wrappercamerabinsrc_videotestsrc}
-};
-
-static Suite *
-camerabin_suite (void)
-{
-  GstElementFactory *jpegenc_factory;
-  Suite *s = suite_create ("camerabin2");
-  gint i;
-  TCase *tc_generic = tcase_create ("generic");
-
-  jpegenc_factory = gst_element_factory_find ("jpegenc");
-  if (jpegenc_factory == NULL) {
-    GST_WARNING ("Skipping camerabin2 tests because jpegenc is missing");
-    goto end;
-  }
-
-  suite_add_tcase (s, tc_generic);
-  tcase_add_checked_fixture (tc_generic, setup_wrappercamerabinsrc_videotestsrc,
-      teardown);
-  tcase_add_test (tc_generic, test_supported_caps);
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++) {
-    TCase *tc_basic = tcase_create (tests[i].name);
-    suite_add_tcase (s, tc_basic);
-
-    /* Increase timeout due to video recording */
-    tcase_set_timeout (tc_basic, 60);
-    tcase_add_checked_fixture (tc_basic, tests[i].setup_func, teardown);
-
-    tcase_add_test (tc_basic, test_single_image_capture);
-    tcase_add_test (tc_basic, test_single_video_recording);
-    tcase_add_test (tc_basic, test_image_video_cycle);
-    if (gst_plugin_feature_check_version ((GstPluginFeature *) jpegenc_factory,
-            0, 10, 27))
-      tcase_add_test (tc_basic, test_multiple_image_captures);
-    else
-      GST_WARNING ("Skipping image capture test because -good 0.10.27 is "
-          "needed");
-    tcase_add_test (tc_basic, test_multiple_video_recordings);
-
-    tcase_add_test (tc_basic, test_image_capture_previews);
-    tcase_add_test (tc_basic, test_image_capture_with_tags);
-
-    tcase_add_test (tc_basic, test_video_capture_with_tags);
-
-    tcase_add_test (tc_basic, test_idle_property);
-
-    tcase_add_test (tc_basic, test_image_custom_filter);
-    tcase_add_test (tc_basic, test_video_custom_filter);
-
-    tcase_add_test (tc_basic, test_image_location_switching);
-  }
-
-end:
-  return s;
-}
-
-GST_CHECK_MAIN (camerabin);
index 5183dfe..eef73e6 100644 (file)
@@ -1,5 +1,5 @@
 if HAVE_GTK
-GTK_EXAMPLES=camerabin mxf scaletempo camerabin2
+GTK_EXAMPLES=mxf scaletempo camerabin2
 else
 GTK_EXAMPLES=
 endif
@@ -13,6 +13,6 @@ endif
 OPENCV_EXAMPLES=opencv
 
 SUBDIRS= $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES)
-DIST_SUBDIRS= camerabin camerabin2 directfb mxf scaletempo opencv
+DIST_SUBDIRS= camerabin2 directfb mxf scaletempo opencv
 
 include $(top_srcdir)/common/parallel-subdirs.mak
diff --git a/tests/examples/camerabin/.gitignore b/tests/examples/camerabin/.gitignore
deleted file mode 100644 (file)
index 075d2a5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-gst-camera
-gst-camera-perf
-gst-camerabin-test
-test_*.jpg
diff --git a/tests/examples/camerabin/Makefile.am b/tests/examples/camerabin/Makefile.am
deleted file mode 100644 (file)
index 5e1d09e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-GST_CAMERABIN_UI_FILES = gst-camera.ui
-
-if HAVE_GTK
-
-GST_CAMERABIN_GTK_EXAMPLES = gst-camera
-
-gst_camera_SOURCES = gst-camera.h gst-camera.c
-gst_camera_CFLAGS  = \
-        $(GST_PLUGINS_BAD_CFLAGS) \
-        $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
-       $(GTK_CFLAGS) \
-       $(GMODULE_EXPORT_CFLAGS) \
-        -DGST_USE_UNSTABLE_API
-gst_camera_LDADD   = \
-        $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
-        $(GST_PLUGINS_BASE_LIBS) \
-        -lgstvideo-@GST_API_VERSION@ \
-        $(GST_LIBS) \
-       $(GTK_LIBS) \
-       $(GMODULE_EXPORT_LIBS)
-
-noinst_DATA = $(GST_CAMERABIN_UI_FILES)
-
-INCLUDES = -DCAMERA_APPS_UIDIR=\""$(srcdir)"\"
-
-else
-GST_CAMERABIN_GTK_EXAMPLES =
-endif
-
-gst_camera_perf_SOURCES = gst-camera-perf.c
-gst_camera_perf_CFLAGS  = $(GST_CFLAGS)
-gst_camera_perf_LDADD = $(GST_LIBS)
-
-if HAVE_X11
-
-GST_CAMERABIN_X11_EXAMPLES = gst-camerabin-test
-
-gst_camerabin_test_SOURCES = gst-camerabin-test.c
-gst_camerabin_test_CFLAGS  = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS)
-gst_camerabin_test_LDADD   = \
-       $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
-        -lgstvideo-@GST_API_VERSION@ \
-       $(GST_LIBS) \
-       $(GST_PLUGINS_BASE_LIBS) \
-       $(X11_LIBS)
-
-else
-GST_CAMERABIN_X11_EXAMPLES =
-endif
-
-noinst_PROGRAMS = gst-camera-perf $(GST_CAMERABIN_X11_EXAMPLES) $(GST_CAMERABIN_GTK_EXAMPLES)
-
-EXTRA_DIST = $(GST_CAMERABIN_UI_FILES)
-
diff --git a/tests/examples/camerabin/gst-camera-perf.c b/tests/examples/camerabin/gst-camera-perf.c
deleted file mode 100644 (file)
index e865fdf..0000000
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * 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.
- */
-/*
- * This application runs various tests and messures how long it takes.
- * FIXME: It needs to figure sane defaults for different hardware or support
- * we could use GOption for specifying the parameters
- * The config should have:
- * - target times
- * - filter-caps
- * - preview-caps
- * - user-res-fps
- * - element-names: videoenc, audioenc, videomux, imageenc, videosrc, audiosrc
- * Most of it is interpreted in setup_pipeline()
- *
- * gcc `pkg-config --cflags --libs gstreamer-0.10` gst-camera-perf.c -ogst-camera-perf
- *
- * plain linux:
- * ./gst-camera-perf --src-colorspace=YUY2 --image-width=640 --image-height=480 --video-width=640 --video-height=480 --view-framerate-num=15 --view-framerate-den=1
- *
- * maemo:
- * ./gst-camera-perf --src-colorspace=UYVY --image-width=640 --image-height=480 --video-width=640 --video-height=480 --view-framerate-num=1491 --view-framerate-den=100 --video-src=v4l2camsrc --audio-enc=nokiaaacenc --video-enc=dspmpeg4enc --video-mux=hantromp4mux --image-enc=dspjpegenc --target-times=1000,1500,1500,2000,500,2000,3500,1000,1000
- * ./gst-camera-perf --src-colorspace=UYVY --image-width=2576 --image-height=1936 --video-width=640 --video-height=480 --view-framerate-num=2999 --view-framerate-den=100 --video-src=v4l2camsrc --audio-enc=nokiaaacenc --video-enc=dspmpeg4enc --video-mux=hantromp4mux
- * ./gst-camera-perf --src-colorspace=UYVY --image-width=2576 --image-height=1936 --video-width=640 --video-height=480 --view-framerate-num=126 --view-framerate-den=5 --video-src=v4l2camsrc --audio-enc=nokiaaacenc --video-enc=dspmpeg4enc --video-mux=hantromp4mux --image-enc=dspjpegenc
- */
-
-/*
- * Includes
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* save the snapshot images
- * gcc `pkg-config --cflags --libs gstreamer-0.10 gdk-pixbuf-2.0` gst-camera-perf.c -ogst-camera-perf
- *
-#define SAVE_SNAPSHOT 1
- **/
-#include <gst/gst.h>
-#ifdef SAVE_SNAPSHOT
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-/*
- * debug logging
- */
-GST_DEBUG_CATEGORY_STATIC (camera_perf);
-#define GST_CAT_DEFAULT camera_perf
-
-
-/*
- * enums, typedefs and defines
- */
-
-#define GET_TIME(t)                                     \
-do {                                                    \
-  t = gst_util_get_timestamp ();                        \
-  GST_DEBUG("%2d ----------------------------------------", test_ix); \
-} while(0)
-
-#define DIFF_TIME(e,s,d) d=GST_CLOCK_DIFF(s,e)
-
-#define CONT_SHOTS 10
-#define TEST_CASES 9
-
-typedef struct _ResultType
-{
-  GstClockTime avg;
-  GstClockTime min;
-  GstClockTime max;
-  guint32 times;
-} ResultType;
-
-/*
- * Global vars
- */
-static GstElement *camera_bin = NULL;
-static GMainLoop *loop = NULL;
-
-/* commandline options */
-static gchar *audiosrc_name = NULL;
-static gchar *videosrc_name = NULL;
-static gchar *audioenc_name = NULL;
-static gchar *videoenc_name = NULL;
-static gchar *imageenc_name = NULL;
-static gchar *videomux_name = NULL;
-static gchar *src_csp = NULL;
-static gint image_width = 0;
-static gint image_height = 0;
-static gint video_width = 0;
-static gint video_height = 0;
-static gint view_framerate_num = 0;
-static gint view_framerate_den = 0;
-
-/* test configuration for common callbacks */
-static GString *filename = NULL;
-static guint32 num_pics = 0;
-static guint32 num_pics_cont = 0;
-//static guint32 num_vids = 0;
-static guint test_ix = 0;
-static gboolean signal_vf_sink = FALSE;
-static gboolean signal_vid_sink = FALSE;
-static gboolean signal_img_enc = FALSE;
-static gboolean signal_shot = FALSE;
-static gboolean signal_cont = FALSE;
-
-static gboolean need_pad_probe = FALSE;
-static gboolean need_ienc_pad_probe = FALSE;
-static gboolean need_vmux_pad_probe = FALSE;
-
-static gboolean have_img_captured = FALSE;
-static gboolean have_img_done = FALSE;
-
-/* time samples and test results */
-static GstClockTime t_initial = G_GUINT64_CONSTANT (0);
-static GstClockTime t_final[CONT_SHOTS] = { G_GUINT64_CONSTANT (0), };
-
-static GstClockTime test_06_taget, test_09_taget;
-static GstClockTimeDiff diff;
-static ResultType result;
-
-/* these can be overridden with commandline args --target-times */
-static GstClockTime target[TEST_CASES] = {
-  1000 * GST_MSECOND,
-  1500 * GST_MSECOND,
-  1500 * GST_MSECOND,
-  2000 * GST_MSECOND,           /* this should be shorter, as we can take next picture before preview is ready */
-  500 * GST_MSECOND,
-  2000 * GST_MSECOND,
-  3500 * GST_MSECOND,
-  1000 * GST_MSECOND,
-  1000 * GST_MSECOND
-};
-
-static const gchar *test_names[TEST_CASES] = {
-  "Camera OFF to VF on",
-  "(3A latency)",               /* time to get AF? */
-  "Shot to snapshot",
-  "Shot to shot",
-  "Serial shooting",
-  "Shutter lag",
-  "Image saved",
-  "Mode change",
-  "Video recording"
-};
-
-/*
- * Prototypes
- */
-
-static void print_result (void);
-static gboolean run_test (gpointer user_data);
-static gboolean setup_add_pad_probe (GstElement * elem, const gchar * pad_name,
-    GstPadProbeCallback handler, gpointer data);
-
-
-/*
- * Callbacks
- */
-
-static GstPadProbeReturn
-pad_has_buffer (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
-{
-  gboolean *signal_sink = (gboolean *) user_data;
-  gboolean print_and_restart = FALSE;
-
-  if (*signal_sink) {
-    *signal_sink = FALSE;
-    GET_TIME (t_final[0]);
-    GST_DEBUG_OBJECT (pad, "%2d pad has buffer", test_ix);
-    switch (test_ix) {
-      case 5:                  // shutter lag
-        DIFF_TIME (t_final[num_pics_cont], t_initial, diff);
-        result.avg = result.min = result.max = diff;
-        print_and_restart = TRUE;
-        break;
-      case 8:                  // video recording start
-        DIFF_TIME (t_final[num_pics_cont], t_initial, diff);
-        result.avg = result.min = result.max = diff;
-        //g_signal_emit_by_name (camera_bin, "capture-stop", 0);
-        print_and_restart = TRUE;
-        break;
-      default:
-        GST_WARNING_OBJECT (pad, "%2d pad has buffer, not handled", test_ix);
-        break;
-    }
-  }
-  if (print_and_restart) {
-    print_result ();
-    g_idle_add ((GSourceFunc) run_test, NULL);
-  }
-  return GST_PAD_PROBE_OK;
-}
-
-static void
-element_added (GstBin * bin, GstElement * element, gpointer user_data)
-{
-  GstElement *elem;
-
-  if (GST_IS_BIN (element)) {
-    g_signal_connect (element, "element-added", (GCallback) element_added,
-        NULL);
-  }
-
-  if (need_vmux_pad_probe) {
-    g_object_get (camera_bin, "video-muxer", &elem, NULL);
-    if (elem) {
-      need_vmux_pad_probe = FALSE;
-      GST_INFO_OBJECT (elem, "got default video muxer");
-      if (setup_add_pad_probe (elem, "src", pad_has_buffer, &signal_vid_sink)) {
-        /* enable test */
-        target[8] = test_09_taget;
-      }
-    }
-  }
-  if (need_ienc_pad_probe) {
-    g_object_get (camera_bin, "image-encoder", &elem, NULL);
-    if (elem) {
-      need_ienc_pad_probe = FALSE;
-      GST_INFO_OBJECT (elem, "got default image encoder");
-      if (setup_add_pad_probe (elem, "src", pad_has_buffer, &signal_img_enc)) {
-        /* enable test */
-        target[5] = test_06_taget;
-      }
-    }
-  }
-}
-
-static gboolean
-img_capture_done (GstElement * camera, GString * fname, gpointer user_data)
-{
-  gboolean ret = FALSE;
-  gboolean print_and_restart = FALSE;
-
-  GST_DEBUG ("shot %d, cont %d, num %d", signal_shot, signal_cont,
-      num_pics_cont);
-
-  if (signal_shot) {
-    GET_TIME (t_final[num_pics_cont]);
-    signal_shot = FALSE;
-    switch (test_ix) {
-      case 6:
-        DIFF_TIME (t_final[num_pics_cont], t_initial, diff);
-        result.avg = result.min = result.max = diff;
-        print_and_restart = TRUE;
-        break;
-    }
-    GST_DEBUG ("%2d shot done", test_ix);
-  }
-
-  if (signal_cont) {
-    gint i;
-
-    if (num_pics_cont < CONT_SHOTS) {
-      gchar tmp[6];
-
-      GET_TIME (t_final[num_pics_cont]);
-      num_pics_cont++;
-      for (i = filename->len - 1; i > 0; --i) {
-        if (filename->str[i] == '_')
-          break;
-      }
-      snprintf (tmp, 6, "_%04d", num_pics_cont);
-      memcpy (filename->str + i, tmp, 5);
-      GST_DEBUG ("%2d cont new filename '%s'", test_ix, filename->str);
-      g_object_set (camera_bin, "filename", filename->str, NULL);
-      // FIXME: is burst capture broken? new filename and return TRUE should be enough
-      // as a workaround we will kick next image from here
-      // but this needs sync so that we have received "image-captured" message already
-      if (have_img_captured) {
-        have_img_captured = FALSE;
-        g_signal_emit_by_name (camera_bin, "capture-start", NULL);
-      } else {
-        have_img_done = TRUE;
-      }
-      ret = TRUE;
-    } else {
-      GstClockTime max = 0;
-      GstClockTime min = -1;
-      GstClockTime total = 0;
-
-      num_pics_cont = 0;
-      signal_cont = FALSE;
-
-      DIFF_TIME (t_final[0], t_initial, diff);
-      max < diff ? max = diff : max;
-      min > diff ? min = diff : min;
-      total += diff;
-
-      DIFF_TIME (t_final[1], t_final[0], diff);
-      max < diff ? max = diff : max;
-      min > diff ? min = diff : min;
-      total += diff;
-
-      for (i = 2; i < CONT_SHOTS; ++i) {
-        DIFF_TIME (t_final[i], t_final[i - 1], diff);
-
-        max < diff ? max = diff : max;
-        min > diff ? min = diff : min;
-        total += diff;
-      }
-
-      result.avg = total / CONT_SHOTS;
-      result.min = min;
-      result.max = max;
-      print_and_restart = TRUE;
-      GST_DEBUG ("%2d cont done", test_ix);
-    }
-  }
-
-  switch (test_ix) {
-    case 2:
-    case 3:
-      print_and_restart = TRUE;
-      break;
-  }
-
-  if (print_and_restart) {
-    print_result ();
-    g_idle_add ((GSourceFunc) run_test, NULL);
-    return FALSE;
-  }
-  return ret;
-}
-
-static gboolean
-bus_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-  const GstStructure *st;
-
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ERROR:{
-      GError *err;
-      gchar *debug;
-
-      gst_message_parse_error (message, &err, &debug);
-      g_print ("Error: %s\n", err->message);
-      g_error_free (err);
-      g_free (debug);
-
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera_bin),
-          GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error");
-
-      g_main_loop_quit (loop);
-      break;
-    }
-    case GST_MESSAGE_STATE_CHANGED:
-      if (GST_IS_BIN (GST_MESSAGE_SRC (message))) {
-        GstState oldstate, newstate;
-
-        gst_message_parse_state_changed (message, &oldstate, &newstate, NULL);
-        GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s",
-            gst_element_state_get_name (oldstate),
-            gst_element_state_get_name (newstate));
-        if (GST_MESSAGE_SRC (message) == GST_OBJECT (camera_bin)) {
-          if (GST_STATE_TRANSITION (oldstate,
-                  newstate) == GST_STATE_CHANGE_PAUSED_TO_PLAYING) {
-            switch (test_ix) {
-              case 0:          // camera on
-                GET_TIME (t_final[0]);
-                DIFF_TIME (t_final[0], t_initial, diff);
-
-                result.avg = result.min = result.max = diff;
-                print_result ();
-                g_idle_add ((GSourceFunc) run_test, NULL);
-                break;
-            }
-          }
-        }
-      }
-      break;
-    case GST_MESSAGE_EOS:
-      /* end-of-stream */
-      GST_INFO ("got eos() - should not happen");
-      g_main_loop_quit (loop);
-      break;
-    default:
-      st = gst_message_get_structure (message);
-      if (st) {
-        if (gst_structure_has_name (st, "image-captured")) {
-          GST_DEBUG ("%2d image-captured", test_ix);
-          switch (test_ix) {
-            case 3:
-              GET_TIME (t_final[num_pics_cont]);
-              DIFF_TIME (t_final[num_pics_cont], t_initial, diff);
-              result.avg = result.min = result.max = diff;
-              break;
-            case 4:
-              // we need to have this received before we can take next one
-              if (have_img_done) {
-                have_img_done = FALSE;
-                g_signal_emit_by_name (camera_bin, "capture-start", NULL);
-              } else {
-                have_img_captured = TRUE;
-              }
-              break;
-          }
-        } else if (gst_structure_has_name (st, "preview-image")) {
-          GST_DEBUG ("%2d preview-image", test_ix);
-          switch (test_ix) {
-            case 2:
-              GET_TIME (t_final[num_pics_cont]);
-              DIFF_TIME (t_final[num_pics_cont], t_initial, diff);
-              result.avg = result.min = result.max = diff;
-              /* turn off preview image generation again */
-              g_object_set (camera_bin, "preview-caps", NULL, NULL);
-              break;
-          }
-#ifdef SAVE_SNAPSHOT
-          {
-            const GValue *value = gst_structure_get_value (st, "buffer");
-            GstBuffer *buf = gst_value_get_buffer (value);
-            GstCaps *caps = GST_BUFFER_CAPS (buf);
-            GstStructure *buf_st = gst_caps_get_structure (caps, 0);
-            gint width, height, rowstride;
-            GdkPixbuf *pixbuf;
-            guchar *data;
-
-            GST_INFO ("preview : buf=%p, size=%d, format=%" GST_PTR_FORMAT,
-                buf, GST_BUFFER_SIZE (buf), caps);
-
-            data = GST_BUFFER_DATA (buff);
-            gst_structure_get_int (buf_st, "width", &width);
-            gst_structure_get_int (buf_st, "height", &height);
-            rowstride = GST_ROUND_UP_4 (width * 3);
-
-            pixbuf = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, FALSE,
-                8, width, height, rowstride, NULL, NULL);
-            gdk_pixbuf_save (pixbuf, "/tmp/gst-camerabin-preview.png", "png",
-                NULL, NULL);
-            gdk_pixbuf_unref (pixbuf);
-          }
-#endif
-        }
-      }
-      /* unhandled message */
-      break;
-  }
-  return TRUE;
-}
-
-
-/*
- * Helpers
- */
-
-static void
-cleanup_pipeline (void)
-{
-  if (camera_bin) {
-    GST_INFO_OBJECT (camera_bin, "stopping and destroying");
-    gst_element_set_state (camera_bin, GST_STATE_NULL);
-    gst_object_unref (camera_bin);
-    camera_bin = NULL;
-  }
-}
-
-static gboolean
-setup_add_pad_probe (GstElement * elem, const gchar * pad_name,
-    GstPadProbeCallback handler, gpointer data)
-{
-  GstPad *pad = NULL;
-
-  if (!(pad = gst_element_get_static_pad (elem, pad_name))) {
-    GST_WARNING ("sink has no pad named '%s'", pad_name);
-    return FALSE;
-  }
-
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
-      handler, data, NULL);
-  gst_object_unref (pad);
-
-  return TRUE;
-}
-
-static gboolean
-setup_pipeline_element (const gchar * property_name, const gchar * element_name,
-    GstElement ** res_elem)
-{
-  gboolean res = TRUE;
-  GstElement *elem = NULL;
-
-  if (element_name) {
-    elem = gst_element_factory_make (element_name, NULL);
-    if (elem) {
-      g_object_set (camera_bin, property_name, elem, NULL);
-    } else {
-      GST_WARNING ("can't create element '%s' for property '%s'", element_name,
-          property_name);
-      res = FALSE;
-    }
-  } else {
-    GST_DEBUG ("no element for property '%s' given", property_name);
-  }
-  if (res_elem)
-    *res_elem = elem;
-  return res;
-}
-
-static gboolean
-setup_pipeline (void)
-{
-  GstBus *bus;
-  gboolean res = TRUE;
-  GstElement *vmux, *ienc, *sink;
-
-  g_string_printf (filename, "test_%04u.jpg", num_pics);
-
-  camera_bin = gst_element_factory_make ("camerabin", NULL);
-  if (NULL == camera_bin) {
-    g_warning ("can't create camerabin element\n");
-    goto error;
-  }
-
-  g_signal_connect (camera_bin, "image-done", (GCallback) img_capture_done,
-      NULL);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (camera_bin));
-  gst_bus_add_watch (bus, bus_callback, NULL);
-  gst_object_unref (bus);
-
-  GST_INFO_OBJECT (camera_bin, "camerabin created");
-
-  /* configure used elements */
-  res &= setup_pipeline_element ("viewfinder-sink", "fakesink", &sink);
-  res &= setup_pipeline_element ("audio-source", audiosrc_name, NULL);
-  res &= setup_pipeline_element ("video-source", videosrc_name, NULL);
-  res &= setup_pipeline_element ("audio-encoder", audioenc_name, NULL);
-  res &= setup_pipeline_element ("video-encoder", videoenc_name, NULL);
-  res &= setup_pipeline_element ("image-encoder", imageenc_name, &ienc);
-  res &= setup_pipeline_element ("video-muxer", videomux_name, &vmux);
-  if (!res) {
-    goto error;
-  }
-
-  GST_INFO_OBJECT (camera_bin, "elements created");
-
-  if (GST_STATE_CHANGE_FAILURE ==
-      gst_element_set_state (camera_bin, GST_STATE_READY)) {
-    g_warning ("can't set camerabin to ready\n");
-    goto error;
-  }
-  GST_INFO_OBJECT (camera_bin, "camera ready");
-
-  /* set properties */
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-
-  if (src_csp) {
-    GstCaps *filter_caps;
-
-    /* FIXME: why do we need to set this? */
-    filter_caps = gst_caps_new_simple ("video/x-raw",
-        "format", G_TYPE_STRING, src_csp, NULL);
-    if (filter_caps) {
-      g_object_set (camera_bin, "filter-caps", filter_caps, NULL);
-      gst_caps_unref (filter_caps);
-    } else {
-      g_warning ("can't make filter-caps with format=%s\n", src_csp);
-      goto error;
-    }
-  }
-
-  g_object_set (sink, "sync", TRUE, NULL);
-
-  GST_INFO_OBJECT (camera_bin, "elements configured");
-
-  /* connect signal handlers */
-  g_assert (sink);
-  if (!setup_add_pad_probe (sink, "sink", pad_has_buffer, &signal_vf_sink)) {
-    goto error;
-  }
-  if (!vmux) {
-    g_object_get (camera_bin, "video-muxer", &vmux, NULL);
-    if (!vmux) {
-      need_pad_probe = need_vmux_pad_probe = TRUE;
-      /* only run the test if we later get the element */
-      test_09_taget = target[8];
-      target[8] = G_GUINT64_CONSTANT (0);
-    }
-  }
-  if (vmux) {
-    if (!setup_add_pad_probe (vmux, "src", pad_has_buffer, &signal_vid_sink)) {
-      goto error;
-    }
-  }
-  if (!ienc) {
-    g_object_get (camera_bin, "image-encoder", &ienc, NULL);
-    if (!ienc) {
-      need_pad_probe = need_ienc_pad_probe = TRUE;
-      /* only run the test if we later get the element */
-      test_06_taget = target[5];
-      target[5] = G_GUINT64_CONSTANT (0);
-    }
-  }
-  if (ienc) {
-    if (!setup_add_pad_probe (ienc, "src", pad_has_buffer, &signal_img_enc)) {
-      goto error;
-    }
-  }
-  if (need_pad_probe) {
-    g_signal_connect (camera_bin, "element-added", (GCallback) element_added,
-        NULL);
-  }
-  GST_INFO_OBJECT (camera_bin, "probe signals connected");
-
-  /* configure a resolution and framerate for video and viewfinder */
-  if (image_width && image_height) {
-    g_signal_emit_by_name (camera_bin, "set-image-resolution", image_width,
-        image_height, NULL);
-  }
-  /* configure a resolution and framerate for video and viewfinder */
-  if (video_width && video_height && view_framerate_num && view_framerate_den) {
-    g_signal_emit_by_name (camera_bin, "set-video-resolution-fps", video_width,
-        video_height, view_framerate_num, view_framerate_den, NULL);
-  }
-
-  if (GST_STATE_CHANGE_FAILURE ==
-      gst_element_set_state (camera_bin, GST_STATE_PLAYING)) {
-    g_warning ("can't set camerabin to playing\n");
-    goto error;
-  }
-  GST_INFO_OBJECT (camera_bin, "camera started");
-  return TRUE;
-error:
-  cleanup_pipeline ();
-  return FALSE;
-}
-
-/*
- * Tests
- */
-
-/* 01) Camera OFF to VF On
- *
- * This only tests the time it takes to create the pipeline and CameraBin
- * element and have the first video frame available in ViewFinder.
- * It is not testing the real init time. To do it, the timer must start before
- * the app.
- */
-static gboolean
-test_01 (void)
-{
-  gboolean res;
-
-  GET_TIME (t_initial);
-  if (setup_pipeline ()) {
-    /* the actual results are fetched in bus_callback::state-changed */
-    res = FALSE;
-  } else {
-    GET_TIME (t_final[0]);
-    DIFF_TIME (t_final[0], t_initial, diff);
-
-    result.avg = result.min = result.max = diff;
-    res = TRUE;
-  }
-  result.times = 1;
-  return res;
-}
-
-
-/* 03) Shot to snapshot
- *
- * It tests the time between pressing the Shot button and having the photo shown
- * in ViewFinder
- */
-static gboolean
-test_03 (void)
-{
-  GstCaps *snap_caps;
-
-  /* FIXME: add options */
-  snap_caps = gst_caps_from_string ("video/x-raw-rgb,width=320,height=240");
-  g_object_set (camera_bin, "preview-caps", snap_caps, NULL);
-  gst_caps_unref (snap_caps);
-
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-  /* the actual results are fetched in bus_callback::preview-image */
-  result.times = 1;
-  return FALSE;
-}
-
-
-/* 04) Shot to shot
- * It tests the time for being able to take a second shot after the first one.
- */
-static gboolean
-test_04 (void)
-{
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-  /* the actual results are fetched in bus_callback::image-captured */
-  result.times = 1;
-  return FALSE;
-}
-
-
-/* 05) Serial shooting
- *
- * It tests the time between shots in continuous mode.
- */
-static gboolean
-test_05 (void)
-{
-  signal_cont = TRUE;
-  have_img_captured = have_img_done = FALSE;
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-  /* the actual results are fetched in img_capture_done */
-  result.times = CONT_SHOTS;
-  return FALSE;
-}
-
-
-/* 06) Shutter lag
- * 
- * It tests the time from user-start signal to buffer reaching img-enc
- */
-static gboolean
-test_06 (void)
-{
-  signal_img_enc = TRUE;
-
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-  /* the actual results are fetched in pad_has_buffer */
-  result.times = 1;
-  return FALSE;
-}
-
-
-/* 07) Image saved
- * 
- * It tests the time between pressing the Shot and the final image is saved to
- * file system.
- */
-static gboolean
-test_07 (void)
-{
-  signal_shot = TRUE;
-
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-  /* the actual results are fetched in img_capture_done */
-  result.times = 1;
-  return FALSE;
-}
-
-
-/* 08) Mode change
- * 
- * It tests the time it takes to change between still image and video recording
- * mode (In this test we change the mode few times).
- */
-static gboolean
-test_08 (void)
-{
-  GstClockTime total = 0;
-  GstClockTime max = 0;
-  GstClockTime min = -1;
-  const gint count = 6;
-  gint i;
-
-  /* switch to image mode */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-
-  for (i = 0; i < count; ++i) {
-    GET_TIME (t_final[i]);
-    g_object_set (camera_bin, "mode", (i + 1) & 1, NULL);
-    GET_TIME (t_final[i + 1]);
-  }
-
-  for (i = 0; i < count; ++i) {
-    DIFF_TIME (t_final[i + 1], t_final[i], diff);
-    total += diff;
-    if (diff > max)
-      max = diff;
-    if (diff < min)
-      min = diff;
-  }
-
-  result.avg = total / count;
-  result.min = min;
-  result.max = max;
-  result.times = count;
-
-  /* just make sure we are back to still image mode again */
-  g_object_set (camera_bin, "mode", 0, NULL);
-  return TRUE;
-}
-
-
-/* 09) Video recording
- * 
- * It tests the time it takes to start video recording.
- * FIXME: shouldn't we wait for the buffer arriving on the venc instead of sink?
- */
-static gboolean
-test_09 (void)
-{
-  signal_vid_sink = TRUE;
-
-  /* switch to video mode */
-  g_object_set (camera_bin, "mode", 1, NULL);
-  g_object_set (camera_bin, "filename", filename->str, NULL);
-  GET_TIME (t_initial);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-  /* the actual results are fetched in pad_has_buffer */
-  result.times = 1;
-  return FALSE;
-}
-
-
-typedef gboolean (*test_case) (void);
-static test_case test_cases[TEST_CASES] = {
-  test_01,
-  NULL,
-  test_03,
-  test_04,
-  test_05,
-  test_06,
-  test_07,
-  test_08,
-  test_09
-};
-
-static void
-print_result (void)
-{
-  if (test_ix >= TEST_CASES) {
-    GST_WARNING ("text case index overrun");
-    return;
-  }
-  printf ("| %6.02f%% ", 100.0f * (float) result.avg / (float) target[test_ix]);
-  printf ("|%5u ms ", (guint) GST_TIME_AS_MSECONDS (target[test_ix]));
-  printf ("|%5u ms ", (guint) GST_TIME_AS_MSECONDS (result.avg));
-  printf ("|%5u ms ", (guint) GST_TIME_AS_MSECONDS (result.min));
-  printf ("|%5u ms ", (guint) GST_TIME_AS_MSECONDS (result.max));
-  printf ("|  %3d   ", result.times);
-  printf ("| %-19s |\n", test_names[test_ix]);
-  test_ix++;
-}
-
-static gboolean
-run_test (gpointer user_data)
-{
-  gboolean ret = TRUE;
-  guint old_test_ix = test_ix;
-
-  if (test_ix >= TEST_CASES) {
-    GST_INFO ("done");
-    g_main_loop_quit (loop);
-    return FALSE;
-  }
-
-  printf ("|  %02d  ", test_ix + 1);
-  fflush (stdout);
-  if (test_cases[test_ix]) {
-    if (target[test_ix]) {
-      memset (&result, 0, sizeof (ResultType));
-      ret = test_cases[test_ix] ();
-
-      //while (g_main_context_pending (NULL)) g_main_context_iteration (NULL,FALSE);
-      if (ret) {
-        print_result ();
-      }
-    } else {
-      printf ("|                      test skipped                        ");
-      printf ("| %-19s |\n", test_names[test_ix]);
-      test_ix++;
-    }
-  } else {
-    printf ("|                  test not implemented                    ");
-    printf ("| %-19s |\n", test_names[test_ix]);
-    test_ix++;
-  }
-  fflush (stdout);
-
-  if (old_test_ix == 0 && ret == TRUE && !camera_bin) {
-    GST_INFO ("done (camerabin creation failed)");
-    g_main_loop_quit (loop);
-    return FALSE;
-  }
-  if (old_test_ix > 0 && !camera_bin) {
-    GST_INFO ("done (camerabin was destroyed)");
-    g_main_loop_quit (loop);
-    return FALSE;
-  }
-  if (test_ix >= TEST_CASES) {
-    GST_INFO ("done");
-    g_main_loop_quit (loop);
-    return FALSE;
-  }
-  GST_INFO ("%2d result: %d", test_ix, ret);
-  return ret;
-}
-
-int
-main (int argc, char *argv[])
-{
-  gchar *target_times = NULL;
-  GOptionEntry options[] = {
-    {"audio-src", '\0', 0, G_OPTION_ARG_STRING, &audiosrc_name,
-        "audio source used in video recording", NULL},
-    {"video-src", '\0', 0, G_OPTION_ARG_STRING, &videosrc_name,
-        "video source used in still capture and video recording", NULL},
-    {"audio-enc", '\0', 0, G_OPTION_ARG_STRING, &audioenc_name,
-        "audio encoder used in video recording", NULL},
-    {"video-enc", '\0', 0, G_OPTION_ARG_STRING, &videoenc_name,
-        "video encoder used in video recording", NULL},
-    {"image-enc", '\0', 0, G_OPTION_ARG_STRING, &imageenc_name,
-        "image encoder used in still capture", NULL},
-    {"video-mux", '\0', 0, G_OPTION_ARG_STRING, &videomux_name,
-        "muxer used in video recording", NULL},
-    {"image-width", '\0', 0, G_OPTION_ARG_INT, &image_width,
-        "width for image capture", NULL},
-    {"image-height", '\0', 0, G_OPTION_ARG_INT, &image_height,
-        "height for image capture", NULL},
-    {"video-width", '\0', 0, G_OPTION_ARG_INT, &video_width,
-        "width for image capture", NULL},
-    {"video-height", '\0', 0, G_OPTION_ARG_INT, &video_height,
-        "height for image capture", NULL},
-    {"view-framerate-num", '\0', 0, G_OPTION_ARG_INT, &view_framerate_num,
-        "framerate numerator for viewfinder", NULL},
-    {"view-framerate-den", '\0', 0, G_OPTION_ARG_INT, &view_framerate_den,
-        "framerate denominator for viewfinder", NULL},
-    {"src-colorspace", '\0', 0, G_OPTION_ARG_STRING, &src_csp,
-        "colorspace format for videosource (e.g. YUY2, UYVY)", NULL},
-    {"target-times", '\0', 0, G_OPTION_ARG_STRING, &target_times,
-          "target test times in ms as comma separated values (0 to skip test)",
-        NULL},
-    {NULL}
-  };
-  GOptionContext *ctx;
-  GError *err = NULL;
-
-  ctx = g_option_context_new (NULL);
-  g_option_context_add_main_entries (ctx, options, NULL);
-  g_option_context_add_group (ctx, gst_init_get_option_group ());
-  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
-    g_print ("Error initializing: %s\n", err->message);
-    exit (1);
-  }
-  g_option_context_free (ctx);
-
-  GST_DEBUG_CATEGORY_INIT (camera_perf, "camera-perf", 0,
-      "camera performcance test");
-
-  /* init */
-  filename = g_string_new_len ("", 16);
-  loop = g_main_loop_new (NULL, FALSE);
-
-  if (target_times) {
-    gchar **numbers;
-    gint i;
-
-    numbers = g_strsplit (target_times, ",", TEST_CASES);
-    for (i = 0; (numbers[i] && i < TEST_CASES); i++) {
-      target[i] = GST_MSECOND * atoi (numbers[i]);
-    }
-    g_strfreev (numbers);
-  }
-
-  /* run */
-  puts ("");
-  puts ("+---------------------------------------------------------------------------------------+");
-  puts ("| test |  rate   | target  |   avg   |   min   |   max   | trials |     description     |");
-  puts ("+---------------------------------------------------------------------------------------+");
-  g_idle_add ((GSourceFunc) run_test, NULL);
-  g_main_loop_run (loop);
-  puts ("+---------------------------------------------------------------------------------------+");
-  puts ("");
-
-  fflush (stdout);
-
-  /* free */
-  cleanup_pipeline ();
-  g_main_loop_unref (loop);
-  g_string_free (filename, TRUE);
-  g_free (audiosrc_name);
-  g_free (videosrc_name);
-  g_free (audioenc_name);
-  g_free (videoenc_name);
-  g_free (imageenc_name);
-  g_free (videomux_name);
-  g_free (src_csp);
-  g_free (target_times);
-
-  return 0;
-}
diff --git a/tests/examples/camerabin/gst-camera-perf.ui b/tests/examples/camerabin/gst-camera-perf.ui
deleted file mode 100644 (file)
index 9a3885a..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <!-- interface-requires gtk+ 2.8 -->
-  <!-- interface-naming-policy project-wide -->
-  <object class="GtkWindow" id="wndMain">
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-    <property name="default_width">400</property>
-    <property name="default_height">600</property>
-    <signal name="delete_event" handler="on_wndMain_delete_event"/>
-    <child>
-      <object class="GtkVPaned" id="vpnMain">
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="position">200</property>
-        <child>
-          <object class="GtkDrawingArea" id="daMain">
-            <property name="height_request">100</property>
-            <property name="visible">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-          </object>
-          <packing>
-            <property name="resize">False</property>
-            <property name="shrink">True</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkVBox" id="vboxMain">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtkButton" id="btnStart">
-                <property name="label" translatable="yes">start</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <signal name="clicked" handler="on_btnStart_clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="scrwndMain">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <object class="GtkViewport" id="vpMain">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <child>
-                      <object class="GtkLabel" id="lbMain">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="yalign">0</property>
-                        <property name="label" translatable="yes">== Please wait few seconds after press start ==</property>
-                        <property name="use_markup">True</property>
-                        <property name="wrap">True</property>
-                        <property name="selectable">True</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="resize">True</property>
-            <property name="shrink">True</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
diff --git a/tests/examples/camerabin/gst-camera.c b/tests/examples/camerabin/gst-camera.c
deleted file mode 100644 (file)
index 610b32f..0000000
+++ /dev/null
@@ -1,1705 +0,0 @@
-/*
- * 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.
- */
-/*
- * This is a demo application to test the camerabin element.
- * If you have question don't hesitate in contact me edgard.lima@indt.org.br
- */
-
-/*
- * Includes
- */
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include "gst-camera.h"
-
-#include <gst/gst.h>
-#include <gst/video/videooverlay.h>
-#include <gst/video/colorbalance.h>
-#include <gst/interfaces/photography.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <string.h>
-
-#include <sys/time.h>
-#include <time.h>
-#include <glib/gstdio.h>        // g_fopen()
-
-#if !GTK_CHECK_VERSION (2, 17, 7)
-static void
-gtk_widget_get_allocation (GtkWidget * w, GtkAllocation * a)
-{
-  *a = w->allocation;
-}
-#endif
-
-/*
- * enums, typedefs and defines
- */
-
-#ifdef USE_MP4
-#define VID_FILE_EXT "mp4"
-#else
-#define VID_FILE_EXT "ogg"
-#endif
-
-#define PREVIEW_TIME_MS (2 * 1000)
-#define N_BURST_IMAGES 10
-#define UI_FILE CAMERA_APPS_UIDIR G_DIR_SEPARATOR_S "gst-camera.ui"
-
-/* Names of default elements */
-#define CAMERA_APP_VIDEOSRC "v4l2src"
-#define CAMERA_APP_IMAGE_POSTPROC "dummy"
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-#define EV_COMP_MAX 3.0
-#define EV_COMP_MIN -3.0
-#define EV_COMP_STEP 0.5
-#endif
-
-#define DEFAULT_VF_CAPS \
-  "video/x-raw-yuv, width = (int) 320, height = (int) 240, framerate = (fraction) 1496/100;" \
-  "video/x-raw-yuv, width = (int) 640, height = (int) 480, framerate = (fraction) 1494/100;" \
-  "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 2503/100;" \
-  "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 2988/100;" \
-  "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 1494/100;" \
-  "video/x-raw-yuv, width = (int) 720, height = (int) 480, framerate = (fraction) 1494/100"
-
-#define PREVIEW_CAPS \
-  "video/x-raw-rgb, width = (int) 640, height = (int) 480"
-
-/* states:
- (image) <---> (video_stopped) <---> (video_recording)
-*/
-typedef enum _tag_CaptureState
-{
-  CAP_STATE_IMAGE,
-  CAP_STATE_VIDEO_STOPED,
-  CAP_STATE_VIDEO_PAUSED,
-  CAP_STATE_VIDEO_RECORDING,
-} CaptureState;
-
-/*
- * Global Vars
- */
-
-static GtkBuilder *builder = NULL;
-static GtkWidget *ui_main_window = NULL;
-static GtkWidget *ui_drawing = NULL;
-static GtkWidget *ui_drawing_frame = NULL;
-static GtkWidget *ui_chk_continous = NULL;
-static GtkButton *ui_bnt_shot = NULL;
-static GtkButton *ui_bnt_pause = NULL;
-static GtkWidget *ui_chk_mute = NULL;
-static GtkWidget *ui_vbox_color_controls = NULL;
-static GtkWidget *ui_chk_rawmsg = NULL;
-
-static GtkWidget *ui_rdbntImageCapture = NULL;
-static GtkWidget *ui_rdbntVideoCapture = NULL;
-static GtkWidget *ui_menuitem_photography = NULL;
-static GtkWidget *ui_menuitem_capture = NULL;
-
-static GtkComboBox *ui_cbbox_resolution = NULL;
-static guint ui_cbbox_resolution_count = 0;
-
-static CaptureState capture_state = CAP_STATE_IMAGE;
-
-static GstElement *gst_camera_bin = NULL;
-static GstElement *gst_videosrc = NULL;
-
-static GString *filename = NULL;
-static guint32 num_pics = 0;
-static guint32 num_pics_cont = 0;
-static guint32 num_vids = 0;
-
-static gint max_fr_n = 0;
-static gint max_fr_d = 0;
-static const gchar *video_post;
-static const gchar *image_post;
-
-static GList *video_caps_list = NULL;
-
-static guint bus_handler_id = 0;
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-static gchar *iso_speed_labels[] = { "auto", "100", "200", "400" };
-
-static struct
-{
-  const gchar *label;
-  gint width;
-  gint height;
-} image_resolution_label_map[] = {
-  {
-  "View finder resolution", 0, 0}, {
-  "VGA", 640, 480}, {
-  "1,3Mpix (1280x960)", 1280, 960}, {
-  "3Mpix (2048x1536)", 2048, 1536}, {
-  "3,7Mpix 16:9 (2592x1456)", 2592, 1456}, {
-  "5Mpix (2592x1968)", 2592, 1968}
-};
-#endif
-
-/*
- * functions prototypes
- */
-static gboolean me_gst_setup_pipeline (const gchar * imagepost,
-    const gchar * videopost);
-static void me_gst_cleanup_element (void);
-
-static gboolean capture_mode_set_state (CaptureState state);
-static void capture_mode_config_gui (void);
-static gboolean capture_mode_stop (void);
-
-static void ui_connect_signals (void);
-static gboolean ui_create (void);
-static void destroy_color_controls (void);
-static void create_color_controls (void);
-static void init_view_finder_resolution_combobox (void);
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-static void menuitem_toggle_active (GtkWidget * widget, gpointer data);
-static void sub_menu_initialize (GtkWidget * widget, gpointer data);
-static void fill_photography_menu (GtkMenuItem * parent_item);
-#endif
-
-/*
- * functions implementation
- */
-
-static void
-set_filename (GString * name)
-{
-  const gchar *datadir;
-
-  if (capture_state == CAP_STATE_IMAGE) {
-    g_string_printf (name, G_DIR_SEPARATOR_S "test_%04u.jpg", num_pics);
-    datadir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
-  } else {
-    g_string_printf (name, G_DIR_SEPARATOR_S "test_%04u.%s", num_vids,
-        VID_FILE_EXT);
-    datadir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
-  }
-
-  if (datadir == NULL) {
-    gchar *curdir = g_get_current_dir ();
-    g_string_prepend (name, curdir);
-    g_free (curdir);
-  } else {
-    g_string_prepend (name, datadir);
-  }
-  GST_INFO ("capture to %s", name->str);
-}
-
-/* Write raw image buffer to file if found from message */
-static void
-handle_element_message (GstMessage * msg)
-{
-  const GstStructure *st;
-  const GValue *image;
-  GstBuffer *buf = NULL;
-  gchar *filename = NULL;
-  FILE *f = NULL;
-  size_t written;
-
-  st = gst_message_get_structure (msg);
-  if (g_str_equal (gst_structure_get_name (st), "autofocus-done")) {
-    gtk_button_set_label (ui_bnt_pause, "Focus");
-  } else if (gst_structure_has_field_typed (st, "buffer", GST_TYPE_BUFFER)) {
-    image = gst_structure_get_value (st, "buffer");
-    if (image) {
-      buf = gst_value_get_buffer (image);
-      if (g_str_equal (gst_structure_get_name (st), "raw-image")) {
-        filename = g_strdup_printf ("test_%04u.raw", num_pics);
-      } else if (g_str_equal (gst_structure_get_name (st), "preview-image")) {
-        filename = g_strdup_printf ("test_%04u_vga.rgb", num_pics);
-      } else {
-        /* for future purposes */
-        g_print ("unknown buffer received\n");
-        return;
-      }
-      g_print ("writing buffer to %s\n", filename);
-      f = g_fopen (filename, "w");
-      if (f) {
-        GstMapInfo map;
-
-        gst_buffer_map (buf, &map, GST_MAP_READ);
-        written = fwrite (map.data, map.size, 1, f);
-        gst_buffer_unmap (buf, &map);
-        if (!written) {
-          g_print ("errro writing file\n");
-        }
-        fclose (f);
-      } else {
-        g_print ("error opening file for raw image writing\n");
-      }
-      g_free (filename);
-    }
-  } else if (g_str_equal (gst_structure_get_name (st), "photo-capture-start")) {
-    g_print ("=== CLICK ===\n");
-  }
-}
-
-static GstBusSyncReply
-my_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
-    return GST_BUS_PASS;
-
-  if (!gst_message_has_name (message, "prepare-xwindow-id"))
-    return GST_BUS_PASS;
-
-  /* FIXME: make sure to get XID in main thread */
-  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (message->src),
-#if GTK_CHECK_VERSION (2, 91, 6)
-      GDK_WINDOW_XID (gtk_widget_get_window (ui_drawing)));
-#else
-      GDK_WINDOW_XWINDOW (gtk_widget_get_window (ui_drawing)));
-#endif
-
-  gst_message_unref (message);
-  return GST_BUS_DROP;
-}
-
-static void
-print_error_message (GstMessage * msg)
-{
-  GError *err = NULL;
-  gchar *dbg = NULL;
-
-  gst_message_parse_error (msg, &err, &dbg);
-
-  g_printerr ("Camerabin won't start up!\nError: %s\nDebug Info: %s\n",
-      err->message, (dbg) ? dbg : "None");
-
-  g_error_free (err);
-  g_free (dbg);
-}
-
-static gboolean
-my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_WARNING:{
-      GError *err;
-      gchar *debug;
-
-      gst_message_parse_warning (message, &err, &debug);
-      g_print ("Warning: %s\n", err->message);
-      g_error_free (err);
-      g_free (debug);
-      break;
-    }
-    case GST_MESSAGE_ERROR:{
-      print_error_message (message);
-      me_gst_cleanup_element ();
-      gtk_main_quit ();
-      break;
-    }
-    case GST_MESSAGE_EOS:
-      /* end-of-stream */
-      gtk_main_quit ();
-      break;
-    case GST_MESSAGE_STATE_CHANGED:{
-      GstState old, new, pending;
-
-      gst_message_parse_state_changed (message, &old, &new, &pending);
-
-      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-change %s -> %s",
-          gst_element_state_get_name (old), gst_element_state_get_name (new));
-
-      /* Create/destroy color controls according videosrc state */
-      if (GST_MESSAGE_SRC (message) == GST_OBJECT (gst_videosrc)) {
-        GST_INFO_OBJECT (GST_MESSAGE_SRC (message), "state-change %s -> %s",
-            gst_element_state_get_name (old), gst_element_state_get_name (new));
-
-        if (old == GST_STATE_READY && new == GST_STATE_NULL) {
-          destroy_color_controls ();
-        } else if (old == GST_STATE_NULL && new == GST_STATE_READY) {
-          create_color_controls ();
-        }
-      }
-
-      /* we only care about pipeline state change messages */
-      if (GST_IS_PIPELINE (GST_MESSAGE_SRC (message))) {
-        /* dump graph for pipeline state changes */
-        gchar *dump_name = g_strdup_printf ("camerabin.%s_%s",
-            gst_element_state_get_name (old),
-            gst_element_state_get_name (new));
-        GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (GST_MESSAGE_SRC (message)),
-            GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE |
-            GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS, dump_name);
-        g_free (dump_name);
-      }
-      break;
-    }
-    case GST_MESSAGE_ELEMENT:
-    {
-      handle_element_message (message);
-      break;
-    }
-    default:
-      /* unhandled message */
-      break;
-  }
-  return TRUE;
-}
-
-static void
-me_set_next_cont_file_name (GString * filename)
-{
-  /* FIXME: better file naming (possible with signal) */
-  if (G_UNLIKELY (num_pics_cont == 1)) {
-    gint i;
-    for (i = filename->len - 1; i > 0; --i) {
-      if (filename->str[i] == '.')
-        break;
-    }
-    g_string_insert (filename, i, "_0001");
-  } else {
-    gchar tmp[6];
-    gint i;
-    for (i = filename->len - 1; i > 0; --i) {
-      if (filename->str[i] == '_')
-        break;
-    }
-    snprintf (tmp, 6, "_%04d", num_pics_cont);
-    memcpy (filename->str + i, tmp, 5);
-  }
-}
-
-static gboolean
-stop_image_preview (gpointer data)
-{
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  g_signal_emit_by_name (data, "capture-stop", 0);
-
-  return FALSE;
-}
-
-static gboolean
-me_image_capture_done (GstElement * camera, const gchar * fname,
-    gpointer user_data)
-{
-  gboolean cont =
-      gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ui_chk_continous));
-  GString *filename = g_string_new (fname);
-
-  if (num_pics_cont < N_BURST_IMAGES && cont) {
-    num_pics_cont++;
-    me_set_next_cont_file_name (filename);
-    g_object_set (G_OBJECT (camera), "filename", filename->str, NULL);
-    g_string_free (filename, TRUE);
-  } else {
-    gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_shot), TRUE);
-    printf ("%u image(s) saved\n", num_pics_cont + 1);
-    fflush (stdout);
-    num_pics_cont = 0;
-
-    g_timeout_add (PREVIEW_TIME_MS, (GSourceFunc) stop_image_preview, camera);
-
-    cont = FALSE;
-  }
-  return cont;
-}
-
-static gboolean
-me_gst_setup_pipeline_create_post_bin (const gchar * post, gboolean video)
-{
-  GstElement *vpp = NULL;
-  GstElement *bin, *c1, *c2, *filter;
-  GstPad *pad;
-  GstCaps *caps;
-
-  /* this function uses a bin just because it needs ffmpegcolorspace. For
-   * performance reason one should provide an element without need for color
-   * convertion */
-
-  vpp = gst_element_factory_make (post, NULL);
-  if (NULL == vpp) {
-    fprintf (stderr, "cannot create \'%s\' element\n", post);
-    fflush (stderr);
-    goto done;
-  }
-  c1 = gst_element_factory_make ("ffmpegcolorspace", NULL);
-  c2 = gst_element_factory_make ("ffmpegcolorspace", NULL);
-  if (NULL == c1 || NULL == c2) {
-    fprintf (stderr, "cannot create \'ffmpegcolorspace\' element\n");
-    fflush (stderr);
-    goto done;
-  }
-  filter = gst_element_factory_make ("capsfilter", NULL);
-  if (NULL == filter) {
-    fprintf (stderr, "cannot create \'capsfilter\' element\n");
-    fflush (stderr);
-    goto done;
-  }
-  bin = gst_bin_new (video ? "vid_postproc_bin" : "img_postproc_bin");
-  if (NULL == bin) {
-    goto done;
-  }
-
-  caps = gst_caps_new_simple ("video/x-raw-yuv",
-      "format", G_TYPE_STRING, "I420", NULL);
-  g_object_set (G_OBJECT (filter), "caps", caps, NULL);
-  gst_caps_unref (caps);
-
-  gst_bin_add_many (GST_BIN (bin), c1, vpp, c2, filter, NULL);
-  if (!gst_element_link_many (c1, vpp, c2, filter, NULL)) {
-    fprintf (stderr, "cannot link video post proc elements\n");
-    fflush (stderr);
-    goto done;
-  }
-
-  pad = gst_element_get_static_pad (c1, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  pad = gst_element_get_static_pad (filter, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  g_object_set (gst_camera_bin,
-      (video ? "video-post-processing" : "image-post-processing"), bin, NULL);
-  return TRUE;
-done:
-  return FALSE;
-}
-
-static void
-me_gst_setup_pipeline_create_codecs (void)
-{
-#ifdef USE_MP4
-  g_object_set (gst_camera_bin, "video-encoder",
-      gst_element_factory_make ("omx_mpeg4enc", NULL), NULL);
-
-  g_object_set (gst_camera_bin, "audio-encoder",
-      gst_element_factory_make ("omx_aacenc", NULL), NULL);
-
-  g_object_set (gst_camera_bin, "video-muxer",
-      gst_element_factory_make ("hantromp4mux", NULL), NULL);
-#else
-  /* using defaults theora, vorbis, ogg */
-#endif
-}
-
-static gboolean
-me_gst_setup_pipeline_create_img_post_bin (const gchar * imagepost)
-{
-  return me_gst_setup_pipeline_create_post_bin (imagepost, FALSE);
-}
-
-static gboolean
-me_gst_setup_pipeline_create_vid_post_bin (const gchar * videopost)
-{
-  return me_gst_setup_pipeline_create_post_bin (videopost, TRUE);
-}
-
-static gboolean
-me_gst_setup_pipeline (const gchar * imagepost, const gchar * videopost)
-{
-  GstBus *bus;
-  GstCaps *preview_caps;
-
-  set_filename (filename);
-
-  me_gst_cleanup_element ();
-
-  gst_camera_bin = gst_element_factory_make ("camerabin", NULL);
-  if (NULL == gst_camera_bin) {
-    goto done;
-  }
-
-  g_signal_connect (gst_camera_bin, "image-done",
-      (GCallback) me_image_capture_done, NULL);
-
-  preview_caps = gst_caps_from_string (PREVIEW_CAPS);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (gst_camera_bin));
-  bus_handler_id = gst_bus_add_watch (bus, my_bus_callback, NULL);
-  gst_bus_set_sync_handler (bus, my_bus_sync_callback, NULL);
-  gst_object_unref (bus);
-
-  /* set properties */
-  g_object_set (gst_camera_bin, "filename", filename->str, NULL);
-  g_object_set (gst_camera_bin, "preview-caps", preview_caps, NULL);
-  g_object_set (gst_camera_bin, "flags", 0xdf, NULL);
-  gst_caps_unref (preview_caps);
-
-  gst_videosrc = gst_element_factory_make (CAMERA_APP_VIDEOSRC, NULL);
-  if (gst_videosrc) {
-    g_object_set (G_OBJECT (gst_camera_bin), "video-source", gst_videosrc,
-        NULL);
-  }
-
-  if (imagepost) {
-    if (!me_gst_setup_pipeline_create_img_post_bin (imagepost))
-      goto done;
-  } else {
-    /* Use default image postprocessing element */
-    GstElement *ipp =
-        gst_element_factory_make (CAMERA_APP_IMAGE_POSTPROC, NULL);
-    if (ipp) {
-      g_object_set (G_OBJECT (gst_camera_bin), "image-post-processing", ipp,
-          NULL);
-    }
-  }
-
-  if (videopost) {
-    if (!me_gst_setup_pipeline_create_vid_post_bin (videopost))
-      goto done;
-  }
-
-  me_gst_setup_pipeline_create_codecs ();
-
-  if (GST_STATE_CHANGE_FAILURE ==
-      gst_element_set_state (gst_camera_bin, GST_STATE_READY)) {
-    goto done;
-  }
-
-  if (!gst_videosrc) {
-    g_object_get (G_OBJECT (gst_camera_bin), "video-source", &gst_videosrc,
-        NULL);
-  }
-
-  init_view_finder_resolution_combobox ();
-
-  gst_element_set_state (gst_camera_bin, GST_STATE_PLAYING);
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-  /* Initialize menus to default settings */
-  GtkWidget *sub_menu =
-      gtk_menu_item_get_submenu (GTK_MENU_ITEM (ui_menuitem_capture));
-  gtk_container_foreach (GTK_CONTAINER (sub_menu), sub_menu_initialize, NULL);
-  sub_menu =
-      gtk_menu_item_get_submenu (GTK_MENU_ITEM (ui_menuitem_photography));
-  gtk_container_foreach (GTK_CONTAINER (sub_menu), sub_menu_initialize, NULL);
-#endif
-
-  capture_state = CAP_STATE_IMAGE;
-  return TRUE;
-done:
-  fprintf (stderr, "error to create pipeline\n");
-  fflush (stderr);
-  me_gst_cleanup_element ();
-  return FALSE;
-}
-
-static gboolean
-me_gst_setup_default_pipeline (gpointer data)
-{
-  if (!me_gst_setup_pipeline (NULL, NULL)) {
-    gtk_main_quit ();
-  }
-  return FALSE;
-}
-
-static void
-me_gst_cleanup_element (void)
-{
-  if (gst_camera_bin) {
-    GstBus *bus;
-
-    gst_element_set_state (gst_camera_bin, GST_STATE_NULL);
-    gst_element_get_state (gst_camera_bin, NULL, NULL, GST_CLOCK_TIME_NONE);
-
-    bus = gst_pipeline_get_bus (GST_PIPELINE (gst_camera_bin));
-    gst_bus_set_sync_handler (bus, NULL, NULL);
-    g_source_remove (bus_handler_id);
-
-    gst_object_unref (gst_camera_bin);
-    gst_camera_bin = NULL;
-
-    g_list_foreach (video_caps_list, (GFunc) gst_caps_unref, NULL);
-    g_list_free (video_caps_list);
-    video_caps_list = NULL;
-  }
-}
-
-static gboolean
-capture_mode_stop (void)
-{
-  if (capture_state == CAP_STATE_VIDEO_PAUSED
-      || capture_state == CAP_STATE_VIDEO_RECORDING) {
-    return capture_mode_set_state (CAP_STATE_VIDEO_STOPED);
-  } else {
-    return TRUE;
-  }
-}
-
-static void
-capture_mode_config_gui (void)
-{
-  switch (capture_state) {
-    case CAP_STATE_IMAGE:
-      gtk_button_set_label (ui_bnt_shot, "Shot");
-      gtk_button_set_label (ui_bnt_pause, "Focus");
-      gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), TRUE);
-      gtk_widget_show (ui_chk_continous);
-      gtk_widget_show (ui_chk_rawmsg);
-      gtk_widget_hide (ui_chk_mute);
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui_rdbntImageCapture),
-          TRUE);
-      break;
-    case CAP_STATE_VIDEO_STOPED:
-      gtk_button_set_label (ui_bnt_shot, "Rec");
-      gtk_button_set_label (ui_bnt_pause, "Pause");
-      gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), FALSE);
-      gtk_widget_show (GTK_WIDGET (ui_bnt_pause));
-      gtk_widget_show (ui_chk_mute);
-      gtk_widget_hide (ui_chk_continous);
-      gtk_widget_hide (ui_chk_rawmsg);
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui_rdbntVideoCapture),
-          TRUE);
-      break;
-    case CAP_STATE_VIDEO_PAUSED:
-      gtk_button_set_label (ui_bnt_pause, "Cont");
-      break;
-    case CAP_STATE_VIDEO_RECORDING:
-      gtk_button_set_label (ui_bnt_shot, "Stop");
-      gtk_button_set_label (ui_bnt_pause, "Pause");
-      gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), TRUE);
-      break;
-    default:
-      break;
-  }
-}
-
-static gboolean
-capture_mode_set_state (CaptureState state)
-{
-  if (capture_state == state)
-    return TRUE;
-
-  switch (capture_state) {
-    case CAP_STATE_IMAGE:
-      if (state == CAP_STATE_VIDEO_PAUSED) {
-        goto done;
-      }
-      g_object_set (gst_camera_bin, "mode", 1, NULL);
-      capture_state = CAP_STATE_VIDEO_STOPED;
-      if (state == CAP_STATE_VIDEO_RECORDING)
-        capture_mode_set_state (state);
-      break;
-    case CAP_STATE_VIDEO_STOPED:
-      if (state == CAP_STATE_VIDEO_PAUSED) {
-        goto done;
-      }
-      capture_state = state;
-      if (state == CAP_STATE_IMAGE)
-        g_object_set (gst_camera_bin, "mode", 0, NULL);
-      else {                    /* state == CAP_STATE_VIDEO_RECORDING */
-        g_object_set (gst_camera_bin, "mode", 1, NULL);
-        g_signal_emit_by_name (gst_camera_bin, "capture-start", 0);
-      }
-      break;
-    case CAP_STATE_VIDEO_PAUSED:
-      if (state == CAP_STATE_VIDEO_RECORDING) {
-        g_signal_emit_by_name (gst_camera_bin, "capture-start", 0);
-        capture_state = CAP_STATE_VIDEO_RECORDING;
-      } else {
-        g_signal_emit_by_name (gst_camera_bin, "capture-stop", 0);
-        capture_state = CAP_STATE_VIDEO_STOPED;
-        if (state == CAP_STATE_IMAGE)
-          capture_mode_set_state (state);
-      }
-      break;
-    case CAP_STATE_VIDEO_RECORDING:
-      if (state == CAP_STATE_VIDEO_PAUSED) {
-        g_signal_emit_by_name (gst_camera_bin, "capture-pause", 0);
-        capture_state = CAP_STATE_VIDEO_PAUSED;
-      } else {
-        g_signal_emit_by_name (gst_camera_bin, "capture-stop", 0);
-        capture_state = CAP_STATE_VIDEO_STOPED;
-        if (state == CAP_STATE_IMAGE)
-          capture_mode_set_state (state);
-      }
-      break;
-  }
-  return TRUE;
-done:
-  return FALSE;
-}
-
-void
-on_windowMain_delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
-{
-  capture_mode_set_state (CAP_STATE_IMAGE);
-  capture_mode_config_gui ();
-  me_gst_cleanup_element ();
-  gtk_main_quit ();
-}
-
-static void
-set_metadata (void)
-{
-  /* for more information about image metadata tags, see:
-   * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/tests/icles/metadata_editor.c
-   * and for the mapping:
-   * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/ext/metadata/metadata_mapping.htm?view=co
-   */
-
-  GstTagSetter *setter = GST_TAG_SETTER (gst_camera_bin);
-  GTimeVal time = { 0, 0 };
-  gchar *date_str, *desc_str;
-
-  g_get_current_time (&time);
-  date_str = g_time_val_to_iso8601 (&time);     /* this is UTC */
-  desc_str = g_strdup_printf ("picture taken by %s", g_get_real_name ());
-
-  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
-      "date-time-original", date_str,
-      "date-time-modified", date_str,
-      "creator-tool", "camerabin-demo",
-      GST_TAG_DESCRIPTION, desc_str,
-      GST_TAG_TITLE, "My picture", GST_TAG_COPYRIGHT, "LGPL", NULL);
-
-  g_free (date_str);
-  g_free (desc_str);
-}
-
-void
-on_buttonShot_clicked (GtkButton * button, gpointer user_data)
-{
-  switch (capture_state) {
-    case CAP_STATE_IMAGE:
-    {
-      gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_shot), FALSE);
-      set_filename (filename);
-      num_pics++;
-      g_object_set (gst_camera_bin, "filename", filename->str, NULL);
-
-      set_metadata ();
-      g_signal_emit_by_name (gst_camera_bin, "capture-start", 0);
-    }
-      break;
-    case CAP_STATE_VIDEO_STOPED:
-      set_filename (filename);
-      num_vids++;
-      g_object_set (gst_camera_bin, "filename", filename->str, NULL);
-      capture_mode_set_state (CAP_STATE_VIDEO_RECORDING);
-      capture_mode_config_gui ();
-      break;
-    case CAP_STATE_VIDEO_PAUSED:
-      /* fall trough */
-    case CAP_STATE_VIDEO_RECORDING:
-      capture_mode_set_state (CAP_STATE_VIDEO_STOPED);
-      capture_mode_config_gui ();
-      break;
-    default:
-      break;
-  }
-}
-
-void
-on_buttonPause_clicked (GtkButton * button, gpointer user_data)
-{
-  switch (capture_state) {
-    case CAP_STATE_IMAGE:
-      if (g_str_equal (gtk_button_get_label (ui_bnt_pause), "Focus")) {
-        /* Start autofocus */
-        gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), TRUE);
-        gtk_button_set_label (ui_bnt_pause, "Cancel Focus");
-      } else {
-        /* Cancel autofocus */
-        gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), FALSE);
-        gtk_button_set_label (ui_bnt_pause, "Focus");
-      }
-      break;
-    case CAP_STATE_VIDEO_STOPED:
-      break;
-    case CAP_STATE_VIDEO_PAUSED:
-      capture_mode_set_state (CAP_STATE_VIDEO_RECORDING);
-      capture_mode_config_gui ();
-      break;
-    case CAP_STATE_VIDEO_RECORDING:
-      capture_mode_set_state (CAP_STATE_VIDEO_PAUSED);
-      capture_mode_config_gui ();
-      break;
-    default:
-      break;
-  }
-}
-
-void
-on_drawingareaView_realize (GtkWidget * widget, gpointer data)
-{
-#if GTK_CHECK_VERSION (2, 18, 0)
-  gdk_window_ensure_native (gtk_widget_get_window (widget));
-#endif
-}
-
-gboolean
-on_drawingareaView_configure_event (GtkWidget * widget,
-    GdkEventConfigure * event, gpointer data)
-{
-  GtkAllocation a;
-
-  gtk_widget_get_allocation (widget, &a);
-  gdk_window_move_resize (gtk_widget_get_window (widget),
-      a.x, a.y, a.width, a.height);
-  gdk_display_sync (gtk_widget_get_display (widget));
-
-  return TRUE;
-}
-
-void
-on_comboboxResolution_changed (GtkComboBox * widget, gpointer user_data)
-{
-  GstStructure *st;
-  gint w = 0, h = 0;
-  GstCaps *video_caps =
-      g_list_nth_data (video_caps_list, gtk_combo_box_get_active (widget));
-
-  if (video_caps) {
-    GstState old;
-
-    gst_element_get_state (gst_camera_bin, &old, NULL, GST_CLOCK_TIME_NONE);
-    GST_DEBUG ("change resolution in %s", gst_element_state_get_name (old));
-
-    if (old != GST_STATE_NULL) {
-      gst_element_set_state (gst_camera_bin, GST_STATE_READY);
-      /* source need to be NULL, otherwise changing the mode fails with device
-       * busy:
-       * - if src goes from NULL->PLAYING it sets new mode anyway
-       * - if src goes form READY->PLAYIN new mode is activated via reverse caps
-       *   negotiation, but then the device is already streaming
-       */
-      gst_element_set_state (gst_videosrc, GST_STATE_NULL);
-    }
-
-    st = gst_caps_get_structure (video_caps, 0);
-
-    gst_structure_get_int (st, "width", &w);
-    gst_structure_get_int (st, "height", &h);
-
-    if (w && h) {
-      g_object_set (ui_drawing_frame, "ratio", (gfloat) w / (gfloat) h, NULL);
-    }
-
-    g_object_set (G_OBJECT (gst_camera_bin), "filter-caps", video_caps, NULL);
-
-    if (old != GST_STATE_NULL) {
-      gst_element_set_state (gst_camera_bin, old);
-    }
-  }
-}
-
-void
-on_radiobuttonImageCapture_toggled (GtkToggleButton * togglebutton,
-    gpointer user_data)
-{
-  if (gtk_toggle_button_get_active (togglebutton)) {
-    if (capture_state != CAP_STATE_IMAGE) {
-      capture_mode_set_state (CAP_STATE_IMAGE);
-      capture_mode_config_gui ();
-    }
-  }
-}
-
-void
-on_radiobuttonVideoCapture_toggled (GtkToggleButton * togglebutton,
-    gpointer user_data)
-{
-  if (gtk_toggle_button_get_active (togglebutton)) {
-    if (capture_state == CAP_STATE_IMAGE) {
-      capture_mode_set_state (CAP_STATE_VIDEO_STOPED);
-      capture_mode_config_gui ();
-    }
-  }
-}
-
-static void
-on_rbBntVidEff_toggled (GtkToggleButton * togglebutton, const gchar * effect)
-{
-  if (gtk_toggle_button_get_active (togglebutton)) {
-    /* lets also use those effects to image */
-    video_post = effect;
-    image_post = effect;
-    capture_mode_stop ();
-
-    me_gst_cleanup_element ();
-    if (!me_gst_setup_pipeline (image_post, video_post))
-      gtk_main_quit ();
-    capture_mode_config_gui ();
-  }
-}
-
-void
-on_rbBntVidEffNone_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, NULL);
-}
-
-void
-on_rbBntVidEffEdge_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "edgetv");
-}
-
-void
-on_rbBntVidEffAging_toggled (GtkToggleButton * togglebutton, gpointer user_data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "agingtv");
-}
-
-void
-on_rbBntVidEffDice_toggled (GtkToggleButton * togglebutton, gpointer user_data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "dicetv");
-}
-
-void
-on_rbBntVidEffWarp_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "warptv");
-}
-
-void
-on_rbBntVidEffShagadelic_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "shagadelictv");
-}
-
-void
-on_rbBntVidEffVertigo_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "vertigotv");
-}
-
-void
-on_rbBntVidEffRev_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "revtv");
-}
-
-void
-on_rbBntVidEffQuark_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  on_rbBntVidEff_toggled (togglebutton, "quarktv");
-}
-
-void
-on_chkbntMute_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  g_object_set (gst_camera_bin, "mute",
-      gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton)), NULL);
-}
-
-void
-on_chkbtnRawMsg_toggled (GtkToggleButton * togglebutton, gpointer data)
-{
-  const gchar *env_var = "CAMSRC_PUBLISH_RAW";
-  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton))) {
-    g_setenv (env_var, "1", TRUE);
-  } else {
-    g_unsetenv (env_var);
-  }
-}
-
-void
-on_hscaleZoom_value_changed (GtkRange * range, gpointer user_data)
-{
-  gint zoom = gtk_range_get_value (range);
-  g_object_set (gst_camera_bin, "zoom", zoom, NULL);
-}
-
-void
-on_color_control_value_changed (GtkRange * range, gpointer user_data)
-{
-  GstColorBalance *balance = GST_COLOR_BALANCE (gst_camera_bin);
-  gint val = gtk_range_get_value (range);
-  GstColorBalanceChannel *channel = (GstColorBalanceChannel *) user_data;
-  gst_color_balance_set_value (balance, channel, val);
-}
-
-#ifndef GDK_KEY_F11
-#define GDK_KEY_F11 GDK_F11
-#endif
-
-gboolean
-on_key_released (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
-{
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  switch (event->keyval) {
-    case GDK_KEY_F11:
-#ifdef HAVE_GST_PHOTO_IFACE_H
-      gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), FALSE);
-#endif
-      break;
-    default:
-      break;
-  }
-
-  return FALSE;
-}
-
-gboolean
-on_key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
-{
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  switch (event->keyval) {
-    case GDK_KEY_F11:
-#ifdef HAVE_GST_PHOTO_IFACE_H
-      gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), TRUE);
-#endif
-      break;
-    case 0x0:
-      on_buttonShot_clicked (NULL, NULL);
-      break;
-    default:
-      break;
-  }
-
-  return FALSE;
-}
-
-static void
-ui_connect_signals (void)
-{
-  gtk_builder_connect_signals (builder, NULL);
-
-  g_signal_connect (ui_main_window, "key-press-event",
-      (GCallback) on_key_pressed, NULL);
-
-  g_signal_connect (ui_main_window, "key-release-event",
-      (GCallback) on_key_released, NULL);
-}
-
-static gchar *
-format_value_callback (GtkScale * scale, gdouble value, gpointer user_data)
-{
-  GstColorBalanceChannel *channel = (GstColorBalanceChannel *) user_data;
-
-  return g_strdup_printf ("%s: %d", channel->label, (gint) value);
-}
-
-static gint
-create_menu_items_from_structure (GstStructure * structure)
-{
-  GtkListStore *store;
-  const GValue *framerate_list = NULL;
-  const gchar *structure_name;
-  GString *item_str = NULL;
-  guint j, num_items_created = 0, num_framerates = 1;
-  gint w = 0, h = 0, n = 0, d = 1;
-  const gchar *format = NULL;
-
-  g_return_val_if_fail (structure != NULL, 0);
-
-  structure_name = gst_structure_get_name (structure);
-
-  /* lets filter yuv only */
-  if (0 == strcmp (structure_name, "video/x-raw-yuv")) {
-    item_str = g_string_new_len ("", 128);
-
-    if (gst_structure_has_field_typed (structure, "format", G_TYPE_STRING)) {
-      format = gst_structure_get_string (structure, "format");
-    }
-
-    if (gst_structure_has_field_typed (structure, "width", GST_TYPE_INT_RANGE)) {
-      const GValue *wrange = gst_structure_get_value (structure, "width");
-      /* If range found, use the maximum */
-      w = gst_value_get_int_range_max (wrange);
-    } else if (gst_structure_has_field_typed (structure, "width", G_TYPE_INT)) {
-      gst_structure_get_int (structure, "width", &w);
-    }
-
-    if (gst_structure_has_field_typed (structure, "height", GST_TYPE_INT_RANGE)) {
-      const GValue *hrange = gst_structure_get_value (structure, "height");
-      /* If range found, use the maximum */
-      h = gst_value_get_int_range_max (hrange);
-    } else if (gst_structure_has_field_typed (structure, "height", G_TYPE_INT)) {
-      gst_structure_get_int (structure, "height", &h);
-    }
-
-    if (gst_structure_has_field_typed (structure, "framerate",
-            GST_TYPE_FRACTION)) {
-      gst_structure_get_fraction (structure, "framerate", &n, &d);
-    } else if (gst_structure_has_field_typed (structure, "framerate",
-            GST_TYPE_LIST)) {
-      framerate_list = gst_structure_get_value (structure, "framerate");
-      num_framerates = gst_value_list_get_size (framerate_list);
-    } else if (gst_structure_has_field_typed (structure, "framerate",
-            GST_TYPE_FRACTION_RANGE)) {
-      const GValue *fr = gst_structure_get_value (structure, "framerate");
-      const GValue *frmax = gst_value_get_fraction_range_max (fr);
-      max_fr_n = gst_value_get_fraction_numerator (frmax);
-      max_fr_d = gst_value_get_fraction_denominator (frmax);
-    }
-
-    if (max_fr_n || max_fr_d) {
-      goto range_found;
-    }
-
-    store = GTK_LIST_STORE (gtk_combo_box_get_model (ui_cbbox_resolution));
-    for (j = 0; j < num_framerates; j++) {
-      GstCaps *video_caps;
-      GtkTreeIter iter;
-
-      if (framerate_list) {
-        const GValue *item = gst_value_list_get_value (framerate_list, j);
-        n = gst_value_get_fraction_numerator (item);
-        d = gst_value_get_fraction_denominator (item);
-      }
-      g_string_assign (item_str, structure_name);
-      g_string_append_printf (item_str, " (%s)", format);
-      g_string_append_printf (item_str, ", %dx%d at %d/%d", w, h, n, d);
-      gtk_list_store_append (store, &iter);
-      gtk_list_store_set (store, &iter, 0, item_str->str, -1);
-
-      video_caps =
-          gst_caps_new_simple (structure_name, "format", G_TYPE_STRING,
-          format,
-          "width", G_TYPE_INT, w, "height", G_TYPE_INT, h,
-          "framerate", GST_TYPE_FRACTION, n, d, NULL);
-      video_caps_list = g_list_append (video_caps_list, video_caps);
-      num_items_created++;
-    }
-  }
-
-range_found:
-
-  if (item_str) {
-    g_string_free (item_str, TRUE);
-  }
-
-  return num_items_created;
-}
-
-static void
-fill_resolution_combo (GstCaps * caps)
-{
-  guint size, num_items, i;
-  GstStructure *st;
-
-  max_fr_n = max_fr_d = 0;
-
-  /* Create new items */
-  size = gst_caps_get_size (caps);
-
-  for (i = 0; i < size; i++) {
-    st = gst_caps_get_structure (caps, i);
-    num_items = create_menu_items_from_structure (st);
-    ui_cbbox_resolution_count += num_items;
-  }
-}
-
-static GstCaps *
-create_default_caps (void)
-{
-  GstCaps *default_caps;
-
-  default_caps = gst_caps_from_string (DEFAULT_VF_CAPS);
-
-  return default_caps;
-}
-
-static void
-init_view_finder_resolution_combobox (void)
-{
-  GstCaps *input_caps = NULL, *default_caps = NULL, *intersect = NULL;
-
-  g_object_get (gst_camera_bin, "video-source-caps", &input_caps, NULL);
-  if (input_caps) {
-    fill_resolution_combo (input_caps);
-  }
-
-  /* Fill in default items if supported */
-  default_caps = create_default_caps ();
-  intersect = gst_caps_intersect (default_caps, input_caps);
-  if (intersect) {
-    fill_resolution_combo (intersect);
-    gst_caps_unref (intersect);
-  }
-  gst_caps_unref (default_caps);
-
-  if (input_caps) {
-    gst_caps_unref (input_caps);
-  }
-
-  /* Set some item active */
-  gtk_combo_box_set_active (ui_cbbox_resolution, ui_cbbox_resolution_count - 1);
-}
-
-static void
-destroy_color_controls (void)
-{
-  GList *widgets, *item;
-  GtkWidget *widget = NULL;
-  gpointer user_data = NULL;
-
-  widgets = gtk_container_get_children (GTK_CONTAINER (ui_vbox_color_controls));
-  for (item = widgets; item; item = g_list_next (item)) {
-    widget = GTK_WIDGET (item->data);
-    user_data = g_object_get_data (G_OBJECT (widget), "channel");
-    g_signal_handlers_disconnect_by_func (widget, (GFunc) format_value_callback,
-        user_data);
-    g_signal_handlers_disconnect_by_func (widget,
-        (GFunc) on_color_control_value_changed, user_data);
-    gtk_container_remove (GTK_CONTAINER (ui_vbox_color_controls), widget);
-  }
-  g_list_free (widgets);
-}
-
-static void
-create_color_controls (void)
-{
-  GstColorBalance *balance = NULL;
-  const GList *controls, *item;
-  GstColorBalanceChannel *channel;
-  GtkWidget *hscale;
-
-  if (GST_IS_COLOR_BALANCE (gst_camera_bin)) {
-    balance = GST_COLOR_BALANCE (gst_camera_bin);
-  }
-
-  if (NULL == balance) {
-    goto done;
-  }
-
-  controls = gst_color_balance_list_channels (balance);
-  for (item = controls; item; item = g_list_next (item)) {
-    channel = item->data;
-
-    hscale = gtk_hscale_new ((GtkAdjustment *)
-        gtk_adjustment_new (gst_color_balance_get_value (balance, channel),
-            channel->min_value, channel->max_value, 1, 10, 10));
-
-    g_signal_connect (GTK_RANGE (hscale), "value-changed",
-        (GCallback) on_color_control_value_changed, (gpointer) channel);
-    g_signal_connect (GTK_SCALE (hscale), "format-value",
-        (GCallback) format_value_callback, (gpointer) channel);
-    g_object_set_data (G_OBJECT (hscale), "channel", (gpointer) channel);
-
-    gtk_box_pack_start (GTK_BOX (ui_vbox_color_controls), GTK_WIDGET (hscale),
-        FALSE, TRUE, 0);
-  }
-
-  gtk_widget_show_all (ui_vbox_color_controls);
-done:
-  return;
-}
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-static void
-menuitem_toggle_active (GtkWidget * widget, gpointer data)
-{
-  gboolean active;
-  g_object_get (G_OBJECT (widget), "active", &active, NULL);
-  if (active) {
-    gtk_check_menu_item_toggled (GTK_CHECK_MENU_ITEM (widget));
-  }
-}
-
-static void
-sub_menu_initialize (GtkWidget * widget, gpointer data)
-{
-  GtkWidget *submenu;
-  submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
-  gtk_container_foreach (GTK_CONTAINER (submenu), menuitem_toggle_active, NULL);
-}
-
-void
-photo_menuitem_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data)
-{
-  gboolean active = FALSE, ret = FALSE;
-  GEnumClass *eclass = (GEnumClass *) user_data;
-  GType etype = G_ENUM_CLASS_TYPE (eclass);
-  GEnumValue *val;
-  gint set_value = -1;
-
-  /* Get value using menu item name */
-  val =
-      g_enum_get_value_by_nick (eclass,
-      gtk_widget_get_name (GTK_WIDGET (menuitem)));
-
-  g_object_get (G_OBJECT (menuitem), "active", &active, NULL);
-  if (active) {
-    if (etype == GST_TYPE_WHITE_BALANCE_MODE) {
-      GstWhiteBalanceMode mode;
-      ret =
-          gst_photography_set_white_balance_mode (GST_PHOTOGRAPHY
-          (gst_videosrc), val->value);
-      gst_photography_get_white_balance_mode (GST_PHOTOGRAPHY (gst_videosrc),
-          &mode);
-      set_value = (gint) mode;
-    } else if (etype == GST_TYPE_SCENE_MODE) {
-      GstSceneMode mode;
-      ret =
-          gst_photography_set_scene_mode (GST_PHOTOGRAPHY (gst_videosrc),
-          val->value);
-      gst_photography_get_scene_mode (GST_PHOTOGRAPHY (gst_videosrc), &mode);
-      set_value = (gint) mode;
-    } else if (etype == GST_TYPE_COLOUR_TONE_MODE) {
-      GstColourToneMode mode;
-      ret =
-          gst_photography_set_colour_tone_mode (GST_PHOTOGRAPHY
-          (gst_videosrc), val->value);
-      gst_photography_get_colour_tone_mode (GST_PHOTOGRAPHY (gst_videosrc),
-          &mode);
-      set_value = (gint) mode;
-    } else if (etype == GST_TYPE_FLASH_MODE) {
-      GstFlashMode mode;
-      ret =
-          gst_photography_set_flash_mode (GST_PHOTOGRAPHY (gst_videosrc),
-          val->value);
-      gst_photography_get_flash_mode (GST_PHOTOGRAPHY (gst_videosrc), &mode);
-      set_value = (gint) mode;
-    }
-
-    if (!ret) {
-      g_print ("%s setting failed\n", val->value_name);
-    } else if (val->value != set_value) {
-      g_print ("%s setting failed, got %d\n", val->value_nick, set_value);
-    }
-  }
-}
-
-void
-photo_iso_speed_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data)
-{
-  gboolean active;
-  const gchar *name;
-  guint val = 0, set_val = G_MAXUINT;
-
-  g_object_get (G_OBJECT (menuitem), "active", &active, NULL);
-  if (active) {
-    name = gtk_widget_get_name (GTK_WIDGET (menuitem));
-    /* iso auto setting = 0 */
-    /* FIXME: check what values other than 0 can be set */
-    if (!g_str_equal (name, "auto")) {
-      sscanf (name, "%d", &val);
-    }
-    if (!gst_photography_set_iso_speed (GST_PHOTOGRAPHY (gst_videosrc), val)) {
-      g_print ("ISO speed (%d) setting failed\n", val);
-    } else {
-      gst_photography_get_iso_speed (GST_PHOTOGRAPHY (gst_videosrc), &set_val);
-      if (val != set_val) {
-        g_print ("ISO speed (%d) setting failed, got %d\n", val, set_val);
-      }
-    }
-  }
-}
-
-void
-photo_ev_comp_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data)
-{
-  gboolean active;
-  const gchar *name;
-  gfloat val = 0.0, set_val = G_MAXFLOAT;
-
-  g_object_get (G_OBJECT (menuitem), "active", &active, NULL);
-  if (active) {
-    name = gtk_widget_get_name (GTK_WIDGET (menuitem));
-    sscanf (name, "%f", &val);
-    if (!gst_photography_set_ev_compensation (GST_PHOTOGRAPHY (gst_videosrc),
-            val)) {
-      g_print ("EV compensation (%.1f) setting failed\n", val);
-    } else {
-      gst_photography_get_ev_compensation (GST_PHOTOGRAPHY (gst_videosrc),
-          &set_val);
-      if (val != set_val) {
-        g_print ("EV compensation (%.1f) setting failed, got %.1f\n", val,
-            set_val);
-      }
-    }
-  }
-}
-
-static void
-photo_add_submenu_from_enum (GtkMenuItem * parent_item, GType enum_type)
-{
-  GTypeClass *tclass;
-  GEnumClass *eclass;
-  GtkWidget *new_item = NULL, *new_submenu = NULL;
-  guint i;
-  GEnumValue *val;
-  GSList *group = NULL;
-
-  g_return_if_fail (parent_item && enum_type && G_TYPE_IS_CLASSED (enum_type));
-
-  tclass = g_type_class_ref (enum_type);
-  eclass = G_ENUM_CLASS (tclass);
-  new_submenu = gtk_menu_new ();
-
-  for (i = 0; i < eclass->n_values; i++) {
-    val = g_enum_get_value (eclass, i);
-    new_item = gtk_radio_menu_item_new_with_label (group, val->value_nick);
-    /* Store enum nick as the menu item name */
-    gtk_widget_set_name (new_item, val->value_nick);
-    group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (new_item));
-    g_signal_connect (new_item, "toggled",
-        (GCallback) photo_menuitem_toggled_cb, eclass);
-    gtk_menu_shell_append (GTK_MENU_SHELL (new_submenu), new_item);
-    gtk_widget_show (new_item);
-  }
-
-  gtk_menu_item_set_submenu (parent_item, new_submenu);
-  g_type_class_unref (tclass);
-}
-
-static void
-add_submenu_from_list (GtkMenuItem * parent_item, GList * labels,
-    GCallback toggled_cb)
-{
-  GtkWidget *new_item = NULL, *new_submenu = NULL;
-  GSList *group = NULL;
-  GList *l;
-
-  new_submenu = gtk_menu_new ();
-
-  for (l = labels; l != NULL; l = g_list_next (l)) {
-    const gchar *label = l->data;
-    new_item = gtk_radio_menu_item_new_with_label (group, label);
-    if (g_str_equal (label, "0")) {
-      /* Let's set zero as default */
-      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_item), TRUE);
-    }
-    gtk_widget_set_name (new_item, label);
-    group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (new_item));
-    g_signal_connect (new_item, "toggled", toggled_cb, NULL);
-    gtk_menu_shell_append (GTK_MENU_SHELL (new_submenu), new_item);
-    gtk_widget_show (new_item);
-  }
-
-  gtk_menu_item_set_submenu (parent_item, new_submenu);
-}
-
-static GtkMenuItem *
-add_menuitem (GtkMenu * parent_menu, const gchar * item_name)
-{
-  GtkWidget *new_item;
-
-  new_item = gtk_menu_item_new_with_label (item_name);
-  gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), new_item);
-  gtk_widget_show (new_item);
-
-  return GTK_MENU_ITEM (new_item);
-}
-
-GList *
-create_iso_speed_labels (void)
-{
-  GList *labels = NULL;
-  gint i;
-  for (i = 0; i < G_N_ELEMENTS (iso_speed_labels); i++) {
-    labels = g_list_append (labels, iso_speed_labels[i]);
-  }
-  return labels;
-}
-
-GList *
-create_ev_comp_labels (void)
-{
-  GList *labels = NULL;
-  gdouble comp;
-  char buf[G_ASCII_DTOSTR_BUF_SIZE];
-
-  for (comp = EV_COMP_MIN; comp <= EV_COMP_MAX; comp += EV_COMP_STEP) {
-    g_ascii_dtostr (buf, sizeof (buf), comp);
-    labels = g_list_append (labels, g_strdup (buf));
-  }
-  return labels;
-}
-
-static void
-fill_photography_menu (GtkMenuItem * parent_item)
-{
-  GtkWidget *photo_menu = gtk_menu_new ();
-  GtkMenuItem *item = NULL;
-  GList *labels = NULL;
-
-  /* Add menu items and create and associate submenus to each item */
-  item = add_menuitem (GTK_MENU (photo_menu), "AWB");
-  photo_add_submenu_from_enum (item, GST_TYPE_WHITE_BALANCE_MODE);
-
-  item = add_menuitem (GTK_MENU (photo_menu), "Colour Tone");
-  photo_add_submenu_from_enum (item, GST_TYPE_COLOUR_TONE_MODE);
-
-  item = add_menuitem (GTK_MENU (photo_menu), "Scene");
-  photo_add_submenu_from_enum (item, GST_TYPE_SCENE_MODE);
-
-  item = add_menuitem (GTK_MENU (photo_menu), "Flash");
-  photo_add_submenu_from_enum (item, GST_TYPE_FLASH_MODE);
-
-  item = add_menuitem (GTK_MENU (photo_menu), "ISO");
-  labels = create_iso_speed_labels ();
-  add_submenu_from_list (item, labels, (GCallback) photo_iso_speed_toggled_cb);
-  g_list_free (labels);
-
-  item = add_menuitem (GTK_MENU (photo_menu), "EV comp");
-  labels = create_ev_comp_labels ();
-  add_submenu_from_list (item, labels, (GCallback) photo_ev_comp_toggled_cb);
-  g_list_free (labels);
-
-  gtk_menu_item_set_submenu (parent_item, photo_menu);
-}
-
-void
-capture_image_res_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data)
-{
-  gboolean active;
-  const gchar *label;
-  gint i;
-
-  g_object_get (G_OBJECT (menuitem), "active", &active, NULL);
-  if (active) {
-    label = gtk_widget_get_name (GTK_WIDGET (menuitem));
-    /* Look for width and height corresponding to the label */
-    for (i = 0; i < G_N_ELEMENTS (image_resolution_label_map); i++) {
-      if (g_str_equal (label, image_resolution_label_map[i].label)) {
-        /* set found values */
-        g_signal_emit_by_name (gst_camera_bin, "set-image-resolution",
-            image_resolution_label_map[i].width,
-            image_resolution_label_map[i].height, 0);
-        break;
-      }
-    }
-  }
-}
-
-GList *
-create_image_resolution_labels (void)
-{
-  GList *labels = NULL;
-  int i;
-  for (i = 0; i < G_N_ELEMENTS (image_resolution_label_map); i++) {
-    labels = g_list_append (labels, image_resolution_label_map[i].label);
-  }
-  return labels;
-}
-
-static void
-fill_capture_menu (GtkMenuItem * parent_item)
-{
-  GtkWidget *capture_menu = gtk_menu_new ();
-  GtkMenuItem *item = NULL;
-  GList *labels = NULL;
-
-  /* Add menu items and create and associate submenus to each item */
-  item = add_menuitem (GTK_MENU (capture_menu), "Image resolution");
-
-  labels = create_image_resolution_labels ();
-  add_submenu_from_list (item, labels,
-      (GCallback) capture_image_res_toggled_cb);
-  g_list_free (labels);
-
-  gtk_menu_item_set_submenu (parent_item, capture_menu);
-}
-#endif /* HAVE_GST_PHOTO_IFACE_H */
-
-static gboolean
-ui_create (void)
-{
-  GError *error = NULL;
-
-  builder = gtk_builder_new ();
-  if (!gtk_builder_add_from_file (builder, UI_FILE, &error)) {
-    g_warning ("Couldn't load builder file: %s", error->message);
-    g_error_free (error);
-    goto done;
-  }
-
-  ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "windowMain"));
-  ui_drawing = GTK_WIDGET (gtk_builder_get_object (builder, "drawingareaView"));
-  ui_drawing_frame =
-      GTK_WIDGET (gtk_builder_get_object (builder, "drawingareaFrame"));
-  ui_chk_continous =
-      GTK_WIDGET (gtk_builder_get_object (builder, "chkbntContinous"));
-  ui_chk_rawmsg = GTK_WIDGET (gtk_builder_get_object (builder, "chkbtnRawMsg"));
-  ui_bnt_shot = GTK_BUTTON (gtk_builder_get_object (builder, "buttonShot"));
-  ui_bnt_pause = GTK_BUTTON (gtk_builder_get_object (builder, "buttonPause"));
-  ui_cbbox_resolution =
-      GTK_COMBO_BOX (gtk_builder_get_object (builder, "comboboxResolution"));
-  ui_chk_mute = GTK_WIDGET (gtk_builder_get_object (builder, "chkbntMute"));
-  ui_vbox_color_controls =
-      GTK_WIDGET (gtk_builder_get_object (builder, "vboxColorControls"));
-  ui_rdbntImageCapture =
-      GTK_WIDGET (gtk_builder_get_object (builder, "radiobuttonImageCapture"));
-  ui_rdbntVideoCapture =
-      GTK_WIDGET (gtk_builder_get_object (builder, "radiobuttonVideoCapture"));
-  ui_menuitem_photography =
-      GTK_WIDGET (gtk_builder_get_object (builder, "menuitemPhotography"));
-  ui_menuitem_capture =
-      GTK_WIDGET (gtk_builder_get_object (builder, "menuitemCapture"));
-
-#ifdef HAVE_GST_PHOTO_IFACE_H
-  if (ui_menuitem_photography) {
-    fill_photography_menu (GTK_MENU_ITEM (ui_menuitem_photography));
-  }
-
-  if (ui_menuitem_capture) {
-    fill_capture_menu (GTK_MENU_ITEM (ui_menuitem_capture));
-  }
-#endif
-  if (!(ui_main_window && ui_drawing && ui_chk_continous && ui_bnt_shot &&
-          ui_bnt_pause && ui_cbbox_resolution && ui_chk_mute &&
-          ui_vbox_color_controls && ui_rdbntImageCapture &&
-          ui_rdbntVideoCapture && ui_chk_rawmsg && ui_menuitem_photography &&
-          ui_menuitem_capture)) {
-    fprintf (stderr, "Some widgets couldn't be created\n");
-    fflush (stderr);
-    goto done;
-  }
-
-  gtk_widget_set_double_buffered (ui_drawing, FALSE);
-  ui_connect_signals ();
-  gtk_widget_show_all (ui_main_window);
-  capture_mode_config_gui ();
-  return TRUE;
-done:
-  return FALSE;
-}
-
-/*
- * main
- */
-
-int
-main (int argc, char *argv[])
-{
-  int ret = 0;
-
-  gst_init (&argc, &argv);
-  gtk_init (&argc, &argv);
-
-  filename = g_string_new_len ("", 16);
-
-  /* create UI */
-  if (!ui_create ()) {
-    ret = -1;
-    goto done;
-  }
-  /* create pipeline and run */
-  g_idle_add (me_gst_setup_default_pipeline, NULL);
-  gtk_main ();
-
-done:
-  me_gst_cleanup_element ();
-  g_string_free (filename, TRUE);
-  return ret;
-}
diff --git a/tests/examples/camerabin/gst-camera.h b/tests/examples/camerabin/gst-camera.h
deleted file mode 100644 (file)
index f1d8844..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.
- */
-/*
- * This is a demo application to test the camerabin element.
- * If you have question don't hesitate in contact me edgard.lima@indt.org.br
- */
-
-#ifndef __GST_CAMERA_BIN_H__
-#define __GST_CAMERA_BIN_H__
-
-#include <gtk/gtk.h>
-
-void
-on_windowMain_delete_event (GtkWidget * widget, GdkEvent * event, gpointer data);
-
-void
-on_buttonShot_clicked (GtkButton * button, gpointer user_data);
-
-void
-on_buttonPause_clicked (GtkButton * button, gpointer user_data);
-
-void
-on_drawingareaView_realize (GtkWidget * widget, gpointer data);
-
-gboolean
-on_drawingareaView_configure_event (GtkWidget * widget,
-    GdkEventConfigure * event, gpointer data);
-
-void
-on_comboboxResolution_changed (GtkComboBox * widget, gpointer user_data);
-
-void
-on_radiobuttonImageCapture_toggled (GtkToggleButton * togglebutton,
-    gpointer user_data);
-
-void
-on_radiobuttonVideoCapture_toggled (GtkToggleButton * togglebutton,
-    gpointer user_data);
-
-void
-on_rbBntVidEffNone_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffEdge_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffAging_toggled (GtkToggleButton * togglebutton, gpointer user_data);
-
-void
-on_rbBntVidEffDice_toggled (GtkToggleButton * togglebutton, gpointer user_data);
-
-void
-on_rbBntVidEffWarp_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffShagadelic_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffVertigo_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffRev_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_rbBntVidEffQuark_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_chkbntMute_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_chkbtnRawMsg_toggled (GtkToggleButton * togglebutton, gpointer data);
-
-void
-on_hscaleZoom_value_changed (GtkRange * range, gpointer user_data);
-
-void
-on_color_control_value_changed (GtkRange * range, gpointer user_data);
-
-gboolean
-on_key_released (GtkWidget * widget, GdkEventKey * event, gpointer user_data);
-
-gboolean
-on_key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data);
-
-#endif /* __GST_CAMERA_BIN_H__ */
diff --git a/tests/examples/camerabin/gst-camera.ui b/tests/examples/camerabin/gst-camera.ui
deleted file mode 100644 (file)
index 1dcf33c..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-<?xml version="1.0"?>
-<interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy project-wide -->
-  <object class="GtkWindow" id="windowMain">
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-    <property name="title" translatable="yes">gst-camera</property>
-    <signal name="delete_event" handler="on_windowMain_delete_event"/>
-    <child>
-      <object class="GtkVBox" id="vboxMain">
-        <property name="visible">True</property>
-        <child>
-          <object class="GtkHBox" id="hbox2">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtkMenuBar" id="menubar1">
-                <property name="visible">True</property>
-                <child>
-                  <object class="GtkMenuItem" id="menuitemPhotography">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">Photography</property>
-                    <property name="use_underline">True</property>
-                    <child type="submenu">
-                      <object class="GtkMenu" id="menu1">
-                        <property name="visible">True</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkMenuItem" id="menuitemCapture">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">Capture</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkComboBox" id="comboboxResolution">
-                <property name="visible">True</property>
-                <property name="model">liststore1</property>
-                <signal name="changed" handler="on_comboboxResolution_changed"/>
-                <child>
-                  <object class="GtkCellRendererText" id="cellrenderertext1"/>
-                  <attributes>
-                    <attribute name="text">0</attribute>
-                  </attributes>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHBox" id="hboxMode">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtkRadioButton" id="radiobuttonImageCapture">
-                <property name="label" translatable="yes">Image capture</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="active">True</property>
-                <property name="draw_indicator">True</property>
-                <signal name="toggled" handler="on_radiobuttonImageCapture_toggled"/>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkRadioButton" id="radiobuttonVideoCapture">
-                <property name="label" translatable="yes">Video rec</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="active">True</property>
-                <property name="draw_indicator">True</property>
-                <property name="group">radiobuttonImageCapture</property>
-                <signal name="toggled" handler="on_radiobuttonVideoCapture_toggled"/>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="buttonShot">
-                <property name="label" translatable="yes">Shot</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <signal name="clicked" handler="on_buttonShot_clicked"/>
-              </object>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="buttonPause">
-                <property name="label" translatable="yes">Pause</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <signal name="clicked" handler="on_buttonPause_clicked"/>
-              </object>
-              <packing>
-                <property name="position">3</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="chkbntMute">
-                <property name="label" translatable="yes">mute</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="draw_indicator">True</property>
-                <signal name="toggled" handler="on_chkbntMute_toggled"/>
-              </object>
-              <packing>
-                <property name="position">4</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="chkbntContinous">
-                <property name="label" translatable="yes">continous</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="draw_indicator">True</property>
-              </object>
-              <packing>
-                <property name="position">5</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="chkbtnRawMsg">
-                <property name="label" translatable="yes">raw msg</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Send raw image after still image capture as gstreamer message</property>
-                <property name="use_underline">True</property>
-                <property name="draw_indicator">True</property>
-                <signal name="toggled" handler="on_chkbtnRawMsg_toggled"/>
-              </object>
-              <packing>
-                <property name="position">6</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkTable" id="tableOptions">
-            <property name="visible">True</property>
-            <property name="n_columns">3</property>
-            <child>
-              <object class="GtkVBox" id="vboxVidEffect">
-                <property name="visible">True</property>
-                <child>
-                  <object class="GtkLabel" id="labelVidEff">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">video effects:</property>
-                  </object>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffNone">
-                    <property name="label" translatable="yes">none</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <signal name="toggled" handler="on_rbBntVidEffNone_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffEdge">
-                    <property name="label" translatable="yes">edged</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffEdge_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffAging">
-                    <property name="label" translatable="yes">aging</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffAging_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffDice">
-                    <property name="label" translatable="yes">dice</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffDice_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffWarp">
-                    <property name="label" translatable="yes">warp</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffWarp_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">5</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffShaga">
-                    <property name="label" translatable="yes">shagadelic</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffShagadelic_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">6</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffVertigo">
-                    <property name="label" translatable="yes">vertigo</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffVertigo_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">7</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffRev">
-                    <property name="label" translatable="yes">rev</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffRev_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">8</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="rbBntVidEffQuark">
-                    <property name="label" translatable="yes">quark</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">rbBntVidEffNone</property>
-                    <signal name="toggled" handler="on_rbBntVidEffQuark_toggled"/>
-                  </object>
-                  <packing>
-                    <property name="position">9</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="x_options"></property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="scrlWndColorControls">
-                <property name="width_request">200</property>
-                <property name="height_request">200</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">automatic</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <object class="GtkViewport" id="viewportColorControls">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <child>
-                      <object class="GtkVBox" id="vboxColorControls">
-                        <property name="visible">True</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="right_attach">3</property>
-                <property name="x_options"></property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkAspectFrame" id="drawingareaFrame">
-                <property name="visible">True</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <property name="obey_child">False</property>
-                <child>
-                  <object class="GtkAlignment" id="alignment1">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkDrawingArea" id="drawingareaView">
-                        <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <signal name="configure_event" handler="on_drawingareaView_configure_event"/>
-                        <signal name="realize" handler="on_drawingareaView_realize"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHScale" id="hscaleZoom">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="adjustment">adjustment1</property>
-            <property name="digits">0</property>
-            <property name="value_pos">left</property>
-            <signal name="value_changed" handler="on_hscaleZoom_value_changed"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-  <object class="GtkAdjustment" id="adjustment1">
-    <property name="lower">100</property>
-    <property name="upper">1100</property>
-    <property name="value">100</property>
-    <property name="step_increment">10</property>
-    <property name="page_increment">100</property>
-    <property name="page_size">100</property>
-  </object>
-  <object class="GtkListStore" id="liststore1">
-    <columns>
-      <!-- column-name item text -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
-</interface>
diff --git a/tests/examples/camerabin/gst-camerabin-test.c b/tests/examples/camerabin/gst-camerabin-test.c
deleted file mode 100644 (file)
index 023542d..0000000
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2010 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.
- */
-
- /*
-    Examples:
-    ./gst-camerabin-test --image-width=2048 --image-height=1536 --image-enc=dspjpegenc
-    ./gst-camerabin-test --mode=1 --capture-time=10 --image-width=848 --image-height=480 --view-framerate-num=2825 \
-    --view-framerate-den=100 --audio-src=pulsesrc --audio-enc=nokiaaacenc --video-enc=dspmp4venc \
-    --video-mux=mp4mux --src-colorspace=UYVY
-
-    gst-camerabin-test --help
-    Usage:
-    gst-camerabin-test [OPTION...]
-
-    camerabin command line test application.
-
-    Help Options:
-    -h, --help                        Show help options
-    --help-all                        Show all help options
-    --help-gst                        Show GStreamer Options
-
-    Application Options:
-    --ev-compensation                 EV compensation (-2.5..2.5, default = 0)
-    --aperture                        Aperture (size of lens opening, default = 0 (auto))
-    --flash-mode                      Flash mode (default = 0 (auto))
-    --scene-mode                      Scene mode (default = 6 (auto))
-    --exposure                        Exposure (default = 0 (auto))
-    --iso-speed                       ISO speed (default = 0 (auto))
-    --white-balance-mode              White balance mode (default = 0 (auto))
-    --colour-tone-mode                Colour tone mode (default = 0 (auto))
-    --directory                       Directory for capture file(s) (default is current directory)
-    --mode                            Capture mode (default = 0 (image), 1 = video)
-    --capture-time                    Time to capture video in seconds (default = 10)
-    --capture-total                   Total number of captures to be done (default = 1)
-    --flags                           Flags for camerabin, (default = 0x9)
-    --mute                            Mute audio
-    --zoom                            Zoom (100 = 1x (default), 200 = 2x etc.)
-    --audio-src                       Audio source used in video recording
-    --audio-bitrate                   Audio bitrate (default 128000)
-    --audio-samplerate                Audio samplerate (default 48000)
-    --audio-channels                  Audio channels (default 1)
-    --video-src                       Video source used in still capture and video recording
-    --audio-enc                       Audio encoder used in video recording
-    --video-enc                       Video encoder used in video recording
-    --image-enc                       Image encoder used in still capture
-    --image-pp                        Image post-processing element
-    --image-formatter                 Image metadata formatter element
-    --video-mux                       Muxer used in video recording
-    --viewfinder-sink                 Viewfinder sink (default = fakesink)
-    --image-width                     Width for image capture
-    --image-height                    Height for image capture
-    --view-framerate-num              Framerate numerator for viewfinder
-    --view-framerate-den              Framerate denominator for viewfinder
-    --src-colorspace                  Colorspace format for video source (e.g. YUY2, UYVY)
-    --src-format                      Video format for video source
-    --preview-caps                    Preview caps (e.g. video/x-raw-rgb,width=320,height=240)
-    --video-source-filter             Video filter to process all frames from video source
-    --viewfinder-filter               Filter to process all frames going to viewfinder sink
-    --x-width                         X window width (default = 320)
-    --x-height                        X window height (default = 240)
-    --no-xwindow                      Do not create XWindow
-
-  */
-
-/*
- * Includes
- */
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#define GST_USE_UNSTABLE_API 1
-
-#include <gst/gst.h>
-#include <gst/video/videooverlay.h>
-#include <gst/interfaces/photography.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-/*
- * debug logging
- */
-GST_DEBUG_CATEGORY_STATIC (camerabin_test);
-#define GST_CAT_DEFAULT camerabin_test
-typedef struct _ResultType
-{
-  GstClockTime avg;
-  GstClockTime min;
-  GstClockTime max;
-  guint32 times;
-} ResultType;
-
-/*
- * Global vars
- */
-static GstElement *camera_bin = NULL;
-static GMainLoop *loop = NULL;
-
-/* commandline options */
-static gchar *audiosrc_name = NULL;
-static gchar *videosrc_name = NULL;
-static gchar *audioenc_name = NULL;
-static gchar *videoenc_name = NULL;
-static gchar *imageenc_name = NULL;
-static gchar *imagepp_name = NULL;
-static gchar *imageformatter_name = NULL;
-static gchar *videomux_name = NULL;
-static gchar *vfsink_name = NULL;
-static gchar *src_csp = NULL;
-static gchar *src_format = NULL;
-static gint image_width = 1280;
-static gint image_height = 720;
-static gint view_framerate_num = 2825;
-static gint view_framerate_den = 100;
-static gboolean no_xwindow = FALSE;
-
-static gint mode = 1;
-static gint flags = 0x4f;
-static gboolean mute = FALSE;
-static gint zoom = 100;
-
-static gint capture_time = 10;
-static gint capture_count = 0;
-static gint capture_total = 1;
-
-/* photography interface command line options */
-#define EV_COMPENSATION_NONE -G_MAXFLOAT
-#define APERTURE_NONE -G_MAXINT
-#define FLASH_MODE_NONE -G_MAXINT
-#define SCENE_MODE_NONE -G_MAXINT
-#define EXPOSURE_NONE -G_MAXINT64
-#define ISO_SPEED_NONE -G_MAXINT
-#define WHITE_BALANCE_MODE_NONE -G_MAXINT
-#define COLOR_TONE_MODE_NONE -G_MAXINT
-static gfloat ev_compensation = EV_COMPENSATION_NONE;
-static gint aperture = APERTURE_NONE;
-static gint flash_mode = FLASH_MODE_NONE;
-static gint scene_mode = SCENE_MODE_NONE;
-static gint64 exposure = EXPOSURE_NONE;
-static gint iso_speed = ISO_SPEED_NONE;
-static gint wb_mode = WHITE_BALANCE_MODE_NONE;
-static gint color_mode = COLOR_TONE_MODE_NONE;
-
-/* audio capsfilter options */
-static gint audio_bitrate = 128000;
-static gint audio_samplerate = 48000;
-static gint audio_channels = 1;
-
-static gchar *video_src_filter = NULL;
-static gchar *viewfinder_filter = NULL;
-
-static int x_width = 320;
-static int x_height = 240;
-
-/* test configuration for common callbacks */
-static GString *filename = NULL;
-
-static gchar *preview_caps_name = NULL;
-
-/* X window variables */
-static Display *display = NULL;
-static Window window = 0;
-
-GTimer *timer = NULL;
-
-/*
- * Prototypes
- */
-static gboolean run_pipeline (gpointer user_data);
-static void set_metadata (GstElement * camera);
-
-static void
-create_host_window (void)
-{
-  unsigned long valuemask;
-  XSetWindowAttributes attributes;
-
-  display = XOpenDisplay (NULL);
-  if (display) {
-    window =
-        XCreateSimpleWindow (display, DefaultRootWindow (display), 0, 0,
-        x_width, x_height, 0, 0, 0);
-    if (window) {
-      valuemask = CWOverrideRedirect;
-      attributes.override_redirect = True;
-      XChangeWindowAttributes (display, window, valuemask, &attributes);
-      XSetWindowBackgroundPixmap (display, window, None);
-      XMapRaised (display, window);
-      XSync (display, FALSE);
-    } else {
-      GST_DEBUG ("could not create X window!");
-    }
-  } else {
-    GST_DEBUG ("could not open display!");
-  }
-}
-
-static gboolean
-img_capture_done (GstElement * camera, const gchar * fname, gpointer user_data)
-{
-  gboolean ret = FALSE;
-
-  GST_DEBUG ("image done: %s", fname);
-  if (capture_count < capture_total) {
-    g_idle_add ((GSourceFunc) run_pipeline, NULL);
-  } else {
-    g_main_loop_quit (loop);
-  }
-  return ret;
-}
-
-static GstBusSyncReply
-sync_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-  const GstStructure *st;
-  const GValue *image;
-  GstBuffer *buf = NULL;
-  gchar *preview_filename = NULL;
-  FILE *f = NULL;
-  size_t written;
-
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ELEMENT:{
-      st = gst_message_get_structure (message);
-      if (st) {
-        if (gst_structure_has_name (st, "prepare-xwindow-id")) {
-          if (!no_xwindow && window) {
-            gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY
-                (GST_MESSAGE_SRC (message)), window);
-            gst_message_unref (message);
-            message = NULL;
-            return GST_BUS_DROP;
-          }
-        } else if (gst_structure_has_name (st, "image-captured")) {
-          GST_DEBUG ("image-captured");
-        } else if (gst_structure_has_name (st, "preview-image")) {
-          GST_DEBUG ("preview-image");
-          //extract preview-image from msg
-          image = gst_structure_get_value (st, "buffer");
-          if (image) {
-            GstMapInfo map;
-
-            buf = gst_value_get_buffer (image);
-            gst_buffer_map (buf, &map, GST_MAP_READ);
-            preview_filename = g_strdup_printf ("test_vga.rgb");
-            g_print ("writing buffer to %s, elapsed: %.2fs\n",
-                preview_filename, g_timer_elapsed (timer, NULL));
-            f = g_fopen (preview_filename, "w");
-            if (f) {
-              written = fwrite (map.data, map.size, 1, f);
-              if (!written) {
-                g_print ("error writing file\n");
-              }
-              fclose (f);
-            } else {
-              g_print ("error opening file for raw image writing\n");
-            }
-            g_free (preview_filename);
-            gst_buffer_unmap (buf, &map);
-          }
-        }
-      }
-      break;
-    }
-    default:
-      /* unhandled message */
-      break;
-  }
-  return GST_BUS_PASS;
-}
-
-static gboolean
-bus_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ERROR:{
-      GError *err;
-      gchar *debug;
-
-      gst_message_parse_error (message, &err, &debug);
-      g_print ("Error: %s\n", err->message);
-      g_error_free (err);
-      g_free (debug);
-
-      /* Write debug graph to file */
-      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera_bin),
-          GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error");
-
-      g_main_loop_quit (loop);
-      break;
-    }
-    case GST_MESSAGE_STATE_CHANGED:
-      if (GST_IS_BIN (GST_MESSAGE_SRC (message))) {
-        GstState oldstate, newstate;
-
-        gst_message_parse_state_changed (message, &oldstate, &newstate, NULL);
-        GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s",
-            gst_element_state_get_name (oldstate),
-            gst_element_state_get_name (newstate));
-      }
-      break;
-    case GST_MESSAGE_EOS:
-      /* end-of-stream */
-      GST_INFO ("got eos() - should not happen");
-      g_main_loop_quit (loop);
-      break;
-    default:
-      /* unhandled message */
-      break;
-  }
-  return TRUE;
-}
-
-/*
- * Helpers
- */
-
-static void
-cleanup_pipeline (void)
-{
-  if (camera_bin) {
-    GST_INFO_OBJECT (camera_bin, "stopping and destroying");
-    gst_element_set_state (camera_bin, GST_STATE_NULL);
-    gst_object_unref (camera_bin);
-    camera_bin = NULL;
-  }
-}
-
-static gboolean
-setup_pipeline_element (const gchar * property_name, const gchar * element_name,
-    GstElement ** res_elem)
-{
-  gboolean res = TRUE;
-  GstElement *elem = NULL;
-
-  if (element_name) {
-    elem = gst_element_factory_make (element_name, NULL);
-    if (elem) {
-      g_object_set (camera_bin, property_name, elem, NULL);
-    } else {
-      GST_WARNING ("can't create element '%s' for property '%s'", element_name,
-          property_name);
-      res = FALSE;
-    }
-  } else {
-    GST_DEBUG ("no element for property '%s' given", property_name);
-  }
-  if (res_elem)
-    *res_elem = elem;
-  return res;
-}
-
-static GstElement *
-create_audioencoder_bin (void)
-{
-  GstElement *bin, *aenc, *filter;
-  GstPad *pad;
-  GstCaps *audio_caps;
-
-  bin = gst_bin_new ("aebin");
-  filter = gst_element_factory_make ("capsfilter", "aefilter");
-  aenc = gst_element_factory_make (audioenc_name, "aenc");
-
-  if (!g_ascii_strcasecmp (audioenc_name, "pulsesrc")) {
-    g_object_set (G_OBJECT (aenc),
-        "bitrate", audio_bitrate, "profile", 2, NULL);
-  }
-
-  audio_caps = gst_caps_new_simple ("audio/x-raw-int",
-      "channels", G_TYPE_INT, audio_channels,
-      "rate", G_TYPE_INT, audio_samplerate, NULL);
-
-  if (!audio_caps) {
-    g_warning ("error generating caps");
-  }
-
-  g_object_set (G_OBJECT (filter), "caps", audio_caps, NULL);
-
-  gst_caps_unref (audio_caps);
-
-  gst_bin_add_many (GST_BIN (bin), filter, aenc, NULL);
-  gst_element_link (filter, aenc);
-
-  pad = gst_element_get_static_pad (filter, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  pad = gst_element_get_static_pad (aenc, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  return bin;
-}
-
-static GstElement *
-create_ipp_bin (void)
-{
-  GstElement *bin = NULL, *element = NULL;
-  GstPad *pad = NULL;
-  gchar **elements;
-  GList *element_list = NULL, *current = NULL, *next = NULL;
-  int i;
-
-  bin = gst_bin_new ("ippbin");
-
-  elements = g_strsplit (imagepp_name, ",", 0);
-
-  for (i = 0; elements[i] != NULL; i++) {
-    element = gst_element_factory_make (elements[i], NULL);
-    if (element) {
-      element_list = g_list_append (element_list, element);
-      gst_bin_add (GST_BIN (bin), element);
-    } else
-      GST_WARNING ("Could create element %s for ippbin", elements[i]);
-  }
-
-  for (i = 1; i < g_list_length (element_list); i++) {
-    current = g_list_nth (element_list, i - 1);
-    next = g_list_nth (element_list, i);
-    gst_element_link (current->data, next->data);
-  }
-
-  current = g_list_first (element_list);
-  pad = gst_element_get_static_pad (current->data, "sink");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  current = g_list_last (element_list);
-  pad = gst_element_get_static_pad (current->data, "src");
-  gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad));
-  gst_object_unref (GST_OBJECT (pad));
-
-  g_list_free (element_list);
-  g_strfreev (elements);
-
-  return bin;
-}
-
-static gboolean
-setup_pipeline (void)
-{
-  GstBus *bus;
-  gboolean res = TRUE;
-  GstElement *vmux = NULL, *ienc = NULL, *sink = NULL, *aenc = NULL, *ipp =
-      NULL;
-  GstCaps *filter_caps = NULL;
-
-  camera_bin = gst_element_factory_make ("camerabin", NULL);
-  if (NULL == camera_bin) {
-    g_warning ("can't create camerabin element\n");
-    goto error;
-  }
-  g_object_set (camera_bin, "flags", flags, NULL);
-
-  g_signal_connect (camera_bin, "image-done", (GCallback) img_capture_done,
-      NULL);
-
-  bus = gst_pipeline_get_bus (GST_PIPELINE (camera_bin));
-  /* Add sync handler for time critical messages that need to be handled fast */
-  gst_bus_set_sync_handler (bus, sync_bus_callback, NULL);
-  /* Handle normal messages asynchronously */
-  gst_bus_add_watch (bus, bus_callback, NULL);
-  gst_object_unref (bus);
-
-  GST_INFO_OBJECT (camera_bin, "camerabin created");
-
-  /* configure used elements */
-  res &= setup_pipeline_element ("viewfinder-sink", vfsink_name, &sink);
-  res &= setup_pipeline_element ("audio-source", audiosrc_name, NULL);
-  res &= setup_pipeline_element ("video-source", videosrc_name, NULL);
-  res &= setup_pipeline_element ("video-source-filter", video_src_filter, NULL);
-  res &= setup_pipeline_element ("viewfinder-filter", viewfinder_filter, NULL);
-
-  if (audioenc_name) {
-    aenc = create_audioencoder_bin ();
-    if (aenc)
-      g_object_set (camera_bin, "audio-encoder", aenc, NULL);
-    else
-      GST_WARNING ("Could not make audio encoder element");
-  }
-
-  if (imagepp_name) {
-    ipp = create_ipp_bin ();
-    if (ipp)
-      g_object_set (camera_bin, "image-post-processing", ipp, NULL);
-    else
-      GST_WARNING ("Could not create ipp elements");
-  }
-
-  res &= setup_pipeline_element ("video-encoder", videoenc_name, NULL);
-  res &= setup_pipeline_element ("image-encoder", imageenc_name, &ienc);
-  res &= setup_pipeline_element ("image-formatter", imageformatter_name, NULL);
-  res &= setup_pipeline_element ("video-muxer", videomux_name, &vmux);
-  if (!res) {
-    goto error;
-  }
-  GST_INFO_OBJECT (camera_bin, "elements created");
-
-  /* set properties */
-  if (src_format) {
-    filter_caps = gst_caps_from_string (src_format);
-  } else if (src_csp) {
-    /* Set requested colorspace format, this is needed if the default 
-       colorspace negotiated for viewfinder doesn't match with e.g. encoders. */
-    filter_caps = gst_caps_new_simple ("video/x-raw",
-        "format", G_TYPE_STRING, src_csp, NULL);
-  }
-
-  if (filter_caps) {
-    g_object_set (camera_bin, "filter-caps", filter_caps, NULL);
-    gst_caps_unref (filter_caps);
-  }
-
-  g_object_set (sink, "sync", TRUE, NULL);
-
-  GST_INFO_OBJECT (camera_bin, "elements configured");
-
-  /* configure a resolution and framerate */
-  if (mode == 1) {
-    g_signal_emit_by_name (camera_bin, "set-video-resolution-fps", image_width,
-        image_height, view_framerate_num, view_framerate_den, NULL);
-  } else {
-    g_signal_emit_by_name (camera_bin, "set-image-resolution", image_width,
-        image_height, NULL);
-  }
-
-  if (GST_STATE_CHANGE_FAILURE ==
-      gst_element_set_state (camera_bin, GST_STATE_READY)) {
-    g_warning ("can't set camerabin to ready\n");
-    goto error;
-  }
-  GST_INFO_OBJECT (camera_bin, "camera ready");
-
-  if (GST_STATE_CHANGE_FAILURE ==
-      gst_element_set_state (camera_bin, GST_STATE_PLAYING)) {
-    g_warning ("can't set camerabin to playing\n");
-    goto error;
-  }
-
-  GST_INFO_OBJECT (camera_bin, "camera started");
-  return TRUE;
-error:
-  cleanup_pipeline ();
-  return FALSE;
-}
-
-static gboolean
-stop_capture (gpointer user_data)
-{
-  g_signal_emit_by_name (camera_bin, "capture-stop", 0);
-  if (capture_count < capture_total) {
-    g_idle_add ((GSourceFunc) run_pipeline, NULL);
-  } else {
-    g_main_loop_quit (loop);
-  }
-  return FALSE;
-}
-
-static void
-set_metadata (GstElement * camera)
-{
-  GstTagSetter *setter = GST_TAG_SETTER (camera);
-  GTimeVal time = { 0, 0 };
-  gchar *desc_str;
-  GDate *date = g_date_new ();
-
-  g_get_current_time (&time);
-  g_date_set_time_val (date, &time);
-
-  desc_str = g_strdup_printf ("captured by %s", g_get_real_name ());
-
-  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
-      GST_TAG_DATE, date,
-      GST_TAG_DESCRIPTION, desc_str,
-      GST_TAG_TITLE, "gst-camerabin-test capture",
-      GST_TAG_GEO_LOCATION_LONGITUDE, 1.0,
-      GST_TAG_GEO_LOCATION_LATITUDE, 2.0,
-      GST_TAG_GEO_LOCATION_ELEVATION, 3.0,
-      GST_TAG_DEVICE_MANUFACTURER, "gst-camerabin-test manufacturer",
-      GST_TAG_DEVICE_MODEL, "gst-camerabin-test model", NULL);
-
-  g_free (desc_str);
-  g_date_free (date);
-}
-
-static gboolean
-run_pipeline (gpointer user_data)
-{
-  GstCaps *preview_caps = NULL;
-  gchar *filename_str = NULL;
-  GstElement *video_source = NULL;
-  const gchar *filename_suffix;
-
-  g_object_set (camera_bin, "mode", mode, NULL);
-
-  if (preview_caps_name != NULL) {
-    preview_caps = gst_caps_from_string (preview_caps_name);
-    if (preview_caps) {
-      g_object_set (camera_bin, "preview-caps", preview_caps, NULL);
-      GST_DEBUG ("Preview caps set");
-    } else
-      GST_DEBUG ("Preview caps set but could not create caps from string");
-  }
-
-  set_metadata (camera_bin);
-
-  /* Construct filename */
-  if (mode == 1)
-    filename_suffix = ".mp4";
-  else
-    filename_suffix = ".jpg";
-  filename_str =
-      g_strdup_printf ("%s/test_%04u%s", filename->str, capture_count,
-      filename_suffix);
-  GST_DEBUG ("Setting filename: %s", filename_str);
-  g_object_set (camera_bin, "filename", filename_str, NULL);
-  g_free (filename_str);
-
-  g_object_get (camera_bin, "video-source", &video_source, NULL);
-  if (video_source) {
-    if (GST_IS_ELEMENT (video_source) && GST_IS_PHOTOGRAPHY (video_source)) {
-      /* Set GstPhotography interface options. If option not given as
-         command-line parameter use default of the source element. */
-      if (scene_mode != SCENE_MODE_NONE)
-        g_object_set (video_source, "scene-mode", scene_mode, NULL);
-      if (ev_compensation != EV_COMPENSATION_NONE)
-        g_object_set (video_source, "ev-compensation", ev_compensation, NULL);
-      if (aperture != APERTURE_NONE)
-        g_object_set (video_source, "aperture", aperture, NULL);
-      if (flash_mode != FLASH_MODE_NONE)
-        g_object_set (video_source, "flash-mode", flash_mode, NULL);
-      if (exposure != EXPOSURE_NONE)
-        g_object_set (video_source, "exposure", exposure, NULL);
-      if (iso_speed != ISO_SPEED_NONE)
-        g_object_set (video_source, "iso-speed", iso_speed, NULL);
-      if (wb_mode != WHITE_BALANCE_MODE_NONE)
-        g_object_set (video_source, "white-balance-mode", wb_mode, NULL);
-      if (color_mode != COLOR_TONE_MODE_NONE)
-        g_object_set (video_source, "colour-tone-mode", color_mode, NULL);
-    }
-    g_object_unref (video_source);
-  }
-  g_object_set (camera_bin, "mute", mute, NULL);
-  g_object_set (camera_bin, "zoom", zoom / 100.0f, NULL);
-
-  capture_count++;
-  g_timer_start (timer);
-  g_signal_emit_by_name (camera_bin, "capture-start", 0);
-
-
-  if (mode == 1) {
-    g_timeout_add ((capture_time * 1000), (GSourceFunc) stop_capture, NULL);
-  }
-
-  return FALSE;
-}
-
-int
-main (int argc, char *argv[])
-{
-  gchar *target_times = NULL;
-  gchar *ev_option = NULL;
-  gchar *fn_option = NULL;
-
-  GOptionEntry options[] = {
-    {"ev-compensation", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
-          &ev_option,
-        "EV compensation for source element GstPhotography interface", NULL},
-    {"aperture", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &aperture,
-          "Aperture (size of lens opening) for source element GstPhotography interface",
-        NULL},
-    {"flash-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &flash_mode,
-        "Flash mode for source element GstPhotography interface", NULL},
-    {"scene-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &scene_mode,
-        "Scene mode for source element GstPhotography interface", NULL},
-    {"exposure", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT64,
-          &exposure,
-          "Exposure time (in ms) for source element GstPhotography interface",
-        NULL},
-    {"iso-speed", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &iso_speed,
-        "ISO speed for source element GstPhotography interface", NULL},
-    {"white-balance-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &wb_mode,
-        "White balance mode for source element GstPhotography interface", NULL},
-    {"colour-tone-mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &color_mode,
-        "Colour tone mode for source element GstPhotography interface", NULL},
-    {"directory", '\0', 0, G_OPTION_ARG_STRING, &fn_option,
-        "Directory for capture file(s) (default is current directory)", NULL},
-    {"mode", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &mode,
-        "Capture mode (default = 0 (image), 1 = video)", NULL},
-    {"capture-time", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT,
-          &capture_time,
-        "Time to capture video in seconds (default = 10)", NULL},
-    {"capture-total", '\0', 0, G_OPTION_ARG_INT, &capture_total,
-        "Total number of captures to be done (default = 1)", NULL},
-    {"flags", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &flags,
-        "Flags for camerabin, (default = 0x9)", NULL},
-    {"mute", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &mute,
-        "Mute audio", NULL},
-    {"zoom", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &zoom,
-        "Zoom (100 = 1x (default), 200 = 2x etc.)", NULL},
-    {"audio-src", '\0', 0, G_OPTION_ARG_STRING, &audiosrc_name,
-        "Audio source used in video recording", NULL},
-    {"audio-bitrate", '\0', 0, G_OPTION_ARG_INT, &audio_bitrate,
-        "Audio bitrate (default 128000)", NULL},
-    {"audio-samplerate", '\0', 0, G_OPTION_ARG_INT, &audio_samplerate,
-        "Audio samplerate (default 48000)", NULL},
-    {"audio-channels", '\0', 0, G_OPTION_ARG_INT, &audio_channels,
-        "Audio channels (default 1)", NULL},
-    {"video-src", '\0', 0, G_OPTION_ARG_STRING, &videosrc_name,
-        "Video source used in still capture and video recording", NULL},
-    {"audio-enc", '\0', 0, G_OPTION_ARG_STRING, &audioenc_name,
-        "Audio encoder used in video recording", NULL},
-    {"video-enc", '\0', 0, G_OPTION_ARG_STRING, &videoenc_name,
-        "Video encoder used in video recording", NULL},
-    {"image-enc", '\0', 0, G_OPTION_ARG_STRING, &imageenc_name,
-        "Image encoder used in still capture", NULL},
-    {"image-pp", '\0', 0, G_OPTION_ARG_STRING, &imagepp_name,
-        "List of image post-processing elements separated with comma", NULL},
-    {"image-formatter", '\0', 0, G_OPTION_ARG_STRING, &imageformatter_name,
-        "Image metadata formatter used in still image capture", NULL},
-    {"video-mux", '\0', 0, G_OPTION_ARG_STRING, &videomux_name,
-        "Muxer used in video recording", NULL},
-    {"viewfinder-sink", '\0', 0, G_OPTION_ARG_STRING, &vfsink_name,
-        "Viewfinder sink (default = fakesink)", NULL},
-    {"image-width", '\0', 0, G_OPTION_ARG_INT, &image_width,
-        "Width for image capture", NULL},
-    {"image-height", '\0', 0, G_OPTION_ARG_INT, &image_height,
-        "Height for image capture", NULL},
-    {"view-framerate-num", '\0', 0, G_OPTION_ARG_INT, &view_framerate_num,
-        "Framerate numerator for viewfinder", NULL},
-    {"view-framerate-den", '\0', 0, G_OPTION_ARG_INT, &view_framerate_den,
-        "Framerate denominator for viewfinder", NULL},
-    {"src-colorspace", '\0', 0, G_OPTION_ARG_STRING, &src_csp,
-        "Colorspace format for video source (e.g. YUY2, UYVY)", NULL},
-    {"src-format", '\0', 0, G_OPTION_ARG_STRING, &src_format,
-        "Video format for video source", NULL},
-    {"preview-caps", '\0', 0, G_OPTION_ARG_STRING, &preview_caps_name,
-        "Preview caps (e.g. video/x-raw-rgb,width=320,height=240)", NULL},
-    {"video-source-filter", '\0', 0, G_OPTION_ARG_STRING, &video_src_filter,
-        "Video filter to process all frames from video source", NULL},
-    {"viewfinder-filter", '\0', 0, G_OPTION_ARG_STRING, &viewfinder_filter,
-        "Filter to process all frames going to viewfinder sink", NULL},
-    {"x-width", '\0', 0, G_OPTION_ARG_INT, &x_width,
-        "X window width (default = 320)", NULL},
-    {"x-height", '\0', 0, G_OPTION_ARG_INT, &x_height,
-        "X window height (default = 240)", NULL},
-    {"no-xwindow", '\0', 0, G_OPTION_ARG_NONE, &no_xwindow,
-        "Do not create XWindow", NULL},
-    {NULL}
-  };
-
-  GOptionContext *ctx;
-  GError *err = NULL;
-
-  ctx = g_option_context_new ("\n\ncamerabin command line test application.");
-  g_option_context_add_main_entries (ctx, options, NULL);
-  g_option_context_add_group (ctx, gst_init_get_option_group ());
-  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
-    g_print ("Error initializing: %s\n", err->message);
-    exit (1);
-  }
-  g_option_context_free (ctx);
-
-  /* if we fail to create xwindow should we care? */
-  if (!no_xwindow)
-    create_host_window ();
-
-  GST_DEBUG_CATEGORY_INIT (camerabin_test, "camerabin-test", 0,
-      "camerabin test");
-
-  /* FIXME: error handling */
-  if (ev_option != NULL)
-    ev_compensation = strtod (ev_option, (char **) NULL);
-
-  if (vfsink_name == NULL)
-    vfsink_name = g_strdup ("fakesink");
-
-  filename = g_string_new (fn_option);
-  if (filename->len == 0)
-    filename = g_string_append (filename, ".");
-
-  timer = g_timer_new ();
-
-  /* init */
-  if (setup_pipeline ()) {
-    loop = g_main_loop_new (NULL, FALSE);
-    g_idle_add ((GSourceFunc) run_pipeline, NULL);
-    g_main_loop_run (loop);
-    cleanup_pipeline ();
-    g_main_loop_unref (loop);
-  }
-  /* free */
-  g_string_free (filename, TRUE);
-  g_free (ev_option);
-  g_free (audiosrc_name);
-  g_free (videosrc_name);
-  g_free (audioenc_name);
-  g_free (videoenc_name);
-  g_free (imageenc_name);
-  g_free (imageformatter_name);
-  g_free (imagepp_name);
-  g_free (videomux_name);
-  g_free (vfsink_name);
-  g_free (src_csp);
-  g_free (src_format);
-  g_free (target_times);
-  g_timer_destroy (timer);
-
-  if (window)
-    XDestroyWindow (display, window);
-
-  if (display)
-    XCloseDisplay (display);
-
-  return 0;
-}