~ubuntu-branches/ubuntu/raring/gst-plugins-good0.10/raring-proposed

« back to all changes in this revision

Viewing changes to debian/patches/07_move-camerabin.patch

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-02-09 16:44:53 UTC
  • mfrom: (40.2.38 experimental)
  • Revision ID: package-import@ubuntu.com-20120209164453-6hjokwrvdn42zopb
Tags: 0.10.30.3-1ubuntu1
* Merge from Debian experimental, remaining changes:
  - 04_move_farsight_plugins_to_good.patch
    Import autoconvert, dtmf, liveadder, rptmux from -plugins-bad
  - 05_move_shm_to_good.patch
    Import shm from -plugins-bad.
  - 07_move-camerabin.patch
    Import camerabin, camerabin2, jpegformat and basecamerabinsrc
    from -plugins-bad.
  - control*:
    * Drop dependency from gstreamer0.10-plugins-good on
      gstreamer0.10-gconf. It pulls gconf and gtk3 onto the Kubuntu cd.
    * Use Breaks instead of Conflicts.
    * Add a 'Pre-Depends: ${misc:Pre-Depends}' to the plugin package,
      since we're shipping shared libraries in the package that Debian
      isn't.
* Update the patches by pulling new version of the code from
  -plugins-bad 0.10.22.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Index: trunk/Makefile.am
 
1
Index: gst-plugins-good0.10/Makefile.am
2
2
===================================================================
3
 
--- trunk.orig/Makefile.am
4
 
+++ trunk/Makefile.am
5
 
@@ -7,7 +7,7 @@
 
3
--- gst-plugins-good0.10.orig/Makefile.am       2012-02-09 14:44:25.708660265 +0200
 
4
+++ gst-plugins-good0.10/Makefile.am    2012-02-09 14:44:42.765169676 +0200
 
5
@@ -7,7 +7,8 @@
6
6
 endif
7
7
 
8
8
 ALWAYS_SUBDIRS =               \
9
9
-       gst sys ext             \
10
 
+       gst-libs gst sys ext    \
 
10
+       gst-libs                \
 
11
+       gst sys ext             \
11
12
        farsight                \
12
13
        tests                   \
13
14
        docs                    \
14
 
@@ -36,10 +36,6 @@
 
15
@@ -36,11 +37,6 @@
15
16
 
16
17
 DISTCLEANFILES = _stdint.h
17
18
 
18
19
-noinst_HEADERS = \
19
20
-       gst-libs/gst/gettext.h \
20
 
-       gst-libs/gst/gst-i18n-plugin.h
 
21
-       gst-libs/gst/gst-i18n-plugin.h \
 
22
-       gst-libs/gst/glib-compat-private.h
21
23
-
22
24
 ACLOCAL_AMFLAGS = -I m4 -I common/m4
23
25
 
24
26
 include $(top_srcdir)/common/release.mak
25
 
Index: trunk/configure.ac
 
27
Index: gst-plugins-good0.10/configure.ac
26
28
===================================================================
27
 
--- trunk.orig/configure.ac
28
 
+++ trunk/configure.ac
 
29
--- gst-plugins-good0.10.orig/configure.ac      2012-02-09 14:44:26.616687386 +0200
 
30
+++ gst-plugins-good0.10/configure.ac   2012-02-09 14:44:27.396710680 +0200
29
31
@@ -150,6 +150,9 @@
30
32
 dnl check if we have ANSI C header files
31
33
 AC_HEADER_STDC
92
94
 ext/Makefile
93
95
 ext/aalib/Makefile
94
96
 ext/annodex/Makefile
95
 
Index: trunk/gst-libs/Makefile.am
 
97
Index: gst-plugins-good0.10/gst-libs/Makefile.am
96
98
===================================================================
97
 
--- /dev/null
98
 
+++ trunk/gst-libs/Makefile.am
 
99
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
100
+++ gst-plugins-good0.10/gst-libs/Makefile.am   2012-02-09 14:44:27.396710680 +0200
99
101
@@ -0,0 +1 @@
100
102
+SUBDIRS = gst
101
 
Index: trunk/gst-libs/gst/Makefile.am
 
103
Index: gst-plugins-good0.10/gst-libs/gst/Makefile.am
102
104
===================================================================
103
 
--- /dev/null
104
 
+++ trunk/gst-libs/gst/Makefile.am
 
105
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
106
+++ gst-plugins-good0.10/gst-libs/gst/Makefile.am       2012-02-09 14:44:27.400710798 +0200
105
107
@@ -0,0 +1,9 @@
106
108
+if BUILD_EXPERIMENTAL
107
109
+EXPERIMENTAL_LIBS=basecamerabinsrc
112
114
+noinst_HEADERS = gst-i18n-plugin.h gettext.h
113
115
+DIST_SUBDIRS = interfaces basecamerabinsrc
114
116
+
115
 
Index: trunk/gst-libs/gst/basecamerabinsrc/Makefile.am
 
117
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/Makefile.am
116
118
===================================================================
117
 
--- /dev/null
118
 
+++ trunk/gst-libs/gst/basecamerabinsrc/Makefile.am
119
 
@@ -0,0 +1,42 @@
 
119
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
120
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/Makefile.am      2012-02-09 14:44:27.400710798 +0200
 
121
@@ -0,0 +1,39 @@
120
122
+
121
123
+lib_LTLIBRARIES = libgstbasecamerabinsrc-@GST_MAJORMINOR@.la
122
124
+
134
136
+       gstbasecamerasrc.h
135
137
+
136
138
+libgstbasecamerabinsrc_@GST_MAJORMINOR@_la_CFLAGS = \
137
 
+       $(GST_PLUGINS_GOOD_CFLAGS) \
 
139
+       $(GST_PLUGINS_BAD_CFLAGS) \
138
140
+       $(GST_PLUGINS_BASE_CFLAGS) \
139
141
+       -DGST_USE_UNSTABLE_API \
140
142
+       $(GST_CFLAGS)
141
143
+libgstbasecamerabinsrc_@GST_MAJORMINOR@_la_LIBADD = \
142
 
+        $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_MAJORMINOR@.la \
143
 
+       $(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_MAJORMINOR) \
144
144
+       -lgstapp-$(GST_MAJORMINOR) $(GST_BASE_LIBS) $(GST_LIBS)
145
145
+
146
146
+libgstbasecamerabinsrc_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
154
154
+        -:LDFLAGS $(libgstbasecamerabinsrc_@GST_MAJORMINOR@_la_LDFLAGS) \
155
155
+                  $(libgstbasecamerabinsrc_@GST_MAJORMINOR@_la_LIBADD) \
156
156
+                  -ldl \
157
 
+        -:LIBFILTER_STATIC gstphotography-@GST_MAJORMINOR@ \
158
157
+        -:HEADER_TARGET gstreamer-@GST_MAJORMINOR@/gst/basecamerabinsrc \
159
158
+        -:HEADERS $(libgstbasecamerabinsrcinclude_HEADERS) \
160
159
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
161
160
+       > $@
162
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c
 
161
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c
163
162
===================================================================
164
 
--- /dev/null
165
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c
166
 
@@ -0,0 +1,639 @@
 
163
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
164
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c       2012-02-09 14:44:27.400710798 +0200
 
165
@@ -0,0 +1,566 @@
167
166
+/*
168
167
+ * GStreamer
169
168
+ * Copyright (C) 2010 Texas Instruments, Inc
277
276
+ */
278
277
+
279
278
+/**
280
 
+ * gst_base_camera_src_get_photography:
281
 
+ * @self: the camerasrc bin
282
 
+ *
283
 
+ * Get object implementing photography interface, if there is one.  Otherwise
284
 
+ * returns NULL.
285
 
+ */
286
 
+GstPhotography *
287
 
+gst_base_camera_src_get_photography (GstBaseCameraSrc * self)
288
 
+{
289
 
+  GstElement *elem;
290
 
+
291
 
+  if (GST_IS_PHOTOGRAPHY (self)) {
292
 
+    elem = GST_ELEMENT (self);
293
 
+  } else {
294
 
+    elem = gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_PHOTOGRAPHY);
295
 
+  }
296
 
+
297
 
+  if (elem) {
298
 
+    return GST_PHOTOGRAPHY (elem);
299
 
+  }
300
 
+
301
 
+  return NULL;
302
 
+}
303
 
+
304
 
+
305
 
+/**
306
 
+ * gst_base_camera_src_get_colorbalance:
307
 
+ * @self: the camerasrc bin
308
 
+ *
309
 
+ * Get object implementing colorbalance interface, if there is one.  Otherwise
310
 
+ * returns NULL.
311
 
+ */
312
 
+GstColorBalance *
313
 
+gst_base_camera_src_get_color_balance (GstBaseCameraSrc * self)
314
 
+{
315
 
+  GstElement *elem;
316
 
+
317
 
+  if (GST_IS_COLOR_BALANCE (self)) {
318
 
+    elem = GST_ELEMENT (self);
319
 
+  } else {
320
 
+    elem = gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_COLOR_BALANCE);
321
 
+  }
322
 
+
323
 
+  if (elem) {
324
 
+    return GST_COLOR_BALANCE (self);
325
 
+  }
326
 
+
327
 
+  return NULL;
328
 
+}
329
 
+
330
 
+/**
331
279
+ * gst_base_camera_src_set_mode:
332
280
+ * @self: the camerasrc bin
333
281
+ * @mode: the mode
388
336
+    bclass->set_preview (self, preview_caps);
389
337
+}
390
338
+
391
 
+/**
392
 
+ * gst_base_camera_src_get_allowed_input_caps:
393
 
+ * @self: the camerasrc bin
394
 
+ *
395
 
+ * Retrieve caps from videosrc describing formats it supports
396
 
+ *
397
 
+ * Returns: caps object from videosrc
398
 
+ */
399
 
+GstCaps *
400
 
+gst_base_camera_src_get_allowed_input_caps (GstBaseCameraSrc * self)
401
 
+{
402
 
+  GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
403
 
+
404
 
+  g_return_val_if_fail (bclass->get_allowed_input_caps, NULL);
405
 
+
406
 
+  return bclass->get_allowed_input_caps (self);
407
 
+}
408
 
+
409
339
+static void
410
340
+gst_base_camera_src_start_capture (GstBaseCameraSrc * src)
411
341
+{
534
464
+      if (self->preview_filter)
535
465
+        gst_object_unref (self->preview_filter);
536
466
+      self->preview_filter = g_value_dup_object (value);
537
 
+      self->preview_filter_changed = TRUE;
 
467
+      if (!gst_camerabin_preview_set_filter (self->preview_pipeline,
 
468
+              self->preview_filter)) {
 
469
+        GST_WARNING_OBJECT (self,
 
470
+            "Cannot change preview filter, is element in NULL state?");
 
471
+      }
538
472
+      break;
539
473
+    default:
540
474
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
618
552
+      if (!construct_pipeline (self))
619
553
+        return GST_STATE_CHANGE_FAILURE;
620
554
+
621
 
+      /* recreate the preview pipeline */
622
 
+      if (self->preview_pipeline && self->preview_filter_changed) {
623
 
+        gst_camerabin_destroy_preview_pipeline (self->preview_pipeline);
624
 
+        self->preview_pipeline = NULL;
 
555
+      if (self->preview_pipeline == NULL) {
 
556
+        /* failed to create preview pipeline, fail state change */
 
557
+        return GST_STATE_CHANGE_FAILURE;
625
558
+      }
626
559
+
627
 
+      if (self->preview_pipeline == NULL)
628
 
+        self->preview_pipeline =
629
 
+            gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self),
630
 
+            self->preview_filter);
631
 
+
632
 
+      g_assert (self->preview_pipeline != NULL);
633
 
+      self->preview_filter_changed = FALSE;
634
560
+      if (self->preview_caps) {
635
561
+        GST_DEBUG_OBJECT (self,
636
562
+            "Setting preview pipeline caps %" GST_PTR_FORMAT,
642
568
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
643
569
+      if (!setup_pipeline (self))
644
570
+        return GST_STATE_CHANGE_FAILURE;
 
571
+      /* without this the preview pipeline will not post buffer
 
572
+       * messages on the pipeline */
645
573
+      gst_element_set_state (self->preview_pipeline->pipeline,
646
574
+          GST_STATE_PLAYING);
647
575
+      break;
652
580
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
653
581
+
654
582
+  switch (transition) {
 
583
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
 
584
+      gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_READY);
 
585
+      break;
655
586
+    case GST_STATE_CHANGE_READY_TO_NULL:
656
587
+      gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL);
657
588
+      break;
674
605
+      "Base class for camerabin src bin", "Source/Video",
675
606
+      "Abstracts capture device for camerabin2", "Rob Clark <rob@ti.com>");
676
607
+
677
 
+  gst_element_class_add_pad_template (gstelement_class,
678
 
+      gst_static_pad_template_get (&vfsrc_template));
679
 
+
680
 
+  gst_element_class_add_pad_template (gstelement_class,
681
 
+      gst_static_pad_template_get (&imgsrc_template));
682
 
+
683
 
+  gst_element_class_add_pad_template (gstelement_class,
684
 
+      gst_static_pad_template_get (&vidsrc_template));
 
608
+  gst_element_class_add_static_pad_template (gstelement_class, &vfsrc_template);
 
609
+
 
610
+  gst_element_class_add_static_pad_template (gstelement_class,
 
611
+      &imgsrc_template);
 
612
+
 
613
+  gst_element_class_add_static_pad_template (gstelement_class,
 
614
+      &vidsrc_template);
685
615
+}
686
616
+
687
617
+static void
755
685
+
756
686
+  /* Signals */
757
687
+  basecamerasrc_signals[START_CAPTURE_SIGNAL] =
758
 
+      g_signal_new ("start-capture",
 
688
+      g_signal_new_class_handler ("start-capture",
759
689
+      G_TYPE_FROM_CLASS (klass),
760
690
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
761
 
+      G_STRUCT_OFFSET (GstBaseCameraSrcClass, private_start_capture),
 
691
+      G_CALLBACK (gst_base_camera_src_start_capture),
762
692
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
763
693
+
764
694
+  basecamerasrc_signals[STOP_CAPTURE_SIGNAL] =
765
 
+      g_signal_new ("stop-capture",
 
695
+      g_signal_new_class_handler ("stop-capture",
766
696
+      G_TYPE_FROM_CLASS (klass),
767
697
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
768
 
+      G_STRUCT_OFFSET (GstBaseCameraSrcClass, private_stop_capture),
 
698
+      G_CALLBACK (gst_base_camera_src_stop_capture),
769
699
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
770
700
+
771
 
+  /* TODO these should be moved to a private struct
772
 
+   * that is allocated sequentially to the main struct as said at:
773
 
+   * http://library.gnome.org/devel/gobject/unstable/gobject-Type-Information.html#g-type-add-class-private
774
 
+   */
775
 
+  klass->private_start_capture = gst_base_camera_src_start_capture;
776
 
+  klass->private_stop_capture = gst_base_camera_src_stop_capture;
777
 
+
778
701
+  gstelement_class->change_state = gst_base_camera_src_change_state;
779
702
+}
780
703
+
792
715
+  self->capturing_mutex = g_mutex_new ();
793
716
+
794
717
+  self->post_preview = DEFAULT_POST_PREVIEW;
 
718
+
 
719
+  self->preview_pipeline =
 
720
+      gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self), NULL);
795
721
+}
796
722
+
797
723
+void
803
729
+    GST_DEBUG_OBJECT (self, "Previews not enabled, not posting");
804
730
+  }
805
731
+}
806
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h
 
732
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h
807
733
===================================================================
808
 
--- /dev/null
809
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h
810
 
@@ -0,0 +1,150 @@
 
734
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
735
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h       2012-02-09 14:44:27.400710798 +0200
 
736
@@ -0,0 +1,142 @@
811
737
+/*
812
738
+ * GStreamer
813
739
+ * Copyright (C) 2010 Texas Instruments, Inc
 
740
+ * Copyright (C) 2011 Thiago Santos <thiago.sousa.santos@collabora.com>
814
741
+ *
815
742
+ * This library is free software; you can redistribute it and/or
816
743
+ * modify it under the terms of the GNU Library General Public
839
766
+
840
767
+#include <gst/gst.h>
841
768
+#include <gst/gstbin.h>
842
 
+#include <gst/interfaces/photography.h>
843
 
+#include <gst/interfaces/colorbalance.h>
844
769
+#include "gstcamerabin-enum.h"
845
770
+#include "gstcamerabinpreview.h"
846
771
+
887
812
+  gboolean post_preview;
888
813
+  GstElement *preview_filter;
889
814
+  GstCameraBinPreviewPipelineData *preview_pipeline;
890
 
+  gboolean preview_filter_changed;
891
815
+
892
816
+  /* Resolution of the buffers configured to camerabin */
893
817
+  gint width;
902
826
+
903
827
+/**
904
828
+ * GstBaseCameraSrcClass:
905
 
+ * @construct_pipeline: construct pipeline must be implemented by derived class
 
829
+ * @construct_pipeline: construct pipeline
906
830
+ * @setup_pipeline: configure pipeline for the chosen settings
907
831
+ * @set_zoom: set the zoom
908
832
+ * @set_mode: set the mode
911
835
+{
912
836
+  GstBinClass parent;
913
837
+
914
 
+  /* construct pipeline must be implemented by derived class */
 
838
+  /* Construct pipeline. (called in GST_STATE_CHANGE_NULL_TO_READY) Optional. */
915
839
+  gboolean    (*construct_pipeline)  (GstBaseCameraSrc *self);
916
840
+
917
 
+  /* optional */
 
841
+  /* (called in GST_STATE_CHANGE_READY_TO_PAUSED). Optional. */
918
842
+  gboolean    (*setup_pipeline)      (GstBaseCameraSrc *self);
919
843
+
920
 
+  /* set the zoom */
 
844
+  /* Set the zoom. If set, called when changing 'zoom' property. Optional. */
921
845
+  void        (*set_zoom)            (GstBaseCameraSrc *self, gfloat zoom);
922
846
+
923
 
+  /* set the mode */
 
847
+  /* Set the mode. If set, called when changing 'mode' property. Optional. */
924
848
+  gboolean    (*set_mode)            (GstBaseCameraSrc *self,
925
849
+                                      GstCameraBinMode mode);
926
850
+
927
 
+  /* set preview caps */
 
851
+  /* Set preview caps. If set, called called when setting new 'preview-caps'. Optional. */
928
852
+  gboolean    (*set_preview)         (GstBaseCameraSrc *self,
929
853
+                                      GstCaps *preview_caps);
930
854
+
931
 
+  /* */
932
 
+  GstCaps *   (*get_allowed_input_caps) (GstBaseCameraSrc * self);
933
 
+
934
 
+  void (*private_start_capture) (GstBaseCameraSrc * src);
935
 
+  void (*private_stop_capture) (GstBaseCameraSrc * src);
 
855
+  /* Called by the handler for 'start-capture'. Mandatory. */
936
856
+  gboolean (*start_capture) (GstBaseCameraSrc * src);
 
857
+
 
858
+  /* Called by the handler for 'stop-capture'. Mandatory. */
937
859
+  void (*stop_capture) (GstBaseCameraSrc * src);
938
860
+
939
861
+  gpointer _gst_reserved[GST_PADDING_LARGE];
944
866
+#define MAX_ZOOM 10.0f
945
867
+#define ZOOM_1X MIN_ZOOM
946
868
+
947
 
+GstPhotography * gst_base_camera_src_get_photography (GstBaseCameraSrc *self);
948
 
+GstColorBalance * gst_base_camera_src_get_color_balance (GstBaseCameraSrc *self);
949
 
+
950
869
+gboolean gst_base_camera_src_set_mode (GstBaseCameraSrc *self, GstCameraBinMode mode);
951
870
+void gst_base_camera_src_setup_zoom (GstBaseCameraSrc * self);
952
871
+void gst_base_camera_src_setup_preview (GstBaseCameraSrc * self, GstCaps * preview_caps);
953
 
+GstCaps * gst_base_camera_src_get_allowed_input_caps (GstBaseCameraSrc * self);
954
872
+void gst_base_camera_src_finish_capture (GstBaseCameraSrc *self);
955
873
+
956
874
+
958
876
+// XXX add methods to get/set img capture and vid capture caps..
959
877
+
960
878
+#endif /* __GST_BASE_CAMERA_SRC_H__ */
961
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.c
 
879
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.c
962
880
===================================================================
963
 
--- /dev/null
964
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.c
 
881
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
882
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.c      2012-02-09 14:44:27.400710798 +0200
965
883
@@ -0,0 +1,39 @@
966
884
+/*
967
885
+ * GStreamer
1002
920
+  }
1003
921
+  return gtype;
1004
922
+}
1005
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.h
 
923
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.h
1006
924
===================================================================
1007
 
--- /dev/null
1008
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.h
 
925
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
926
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.h      2012-02-09 14:44:27.400710798 +0200
1009
927
@@ -0,0 +1,62 @@
1010
928
+/*
1011
929
+ * GStreamer
1069
987
+G_END_DECLS
1070
988
+
1071
989
+#endif                          /* #ifndef __GST_CAMERABIN_ENUM_H__ */
1072
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
 
990
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
1073
991
===================================================================
1074
 
--- /dev/null
1075
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
1076
 
@@ -0,0 +1,226 @@
 
992
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
993
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c    2012-02-09 14:44:27.400710798 +0200
 
994
@@ -0,0 +1,404 @@
1077
995
+/*
1078
996
+ * GStreamer
1079
997
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
1107
1025
+#include "gstcamerabinpreview.h"
1108
1026
+#include "gstbasecamerasrc.h"
1109
1027
+
1110
 
+static GstFlowReturn
1111
 
+gst_camerabin_preview_pipeline_new_preroll (GstAppSink * appsink,
1112
 
+    gpointer user_data)
 
1028
+GST_DEBUG_CATEGORY_EXTERN (base_camera_src_debug);
 
1029
+#define GST_CAT_DEFAULT base_camera_src_debug
 
1030
+
 
1031
+static void _gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData *
 
1032
+    preview, GstCaps * caps);
 
1033
+
 
1034
+static gboolean
 
1035
+bus_callback (GstBus * bus, GstMessage * message, gpointer user_data)
1113
1036
+{
1114
 
+  GstBuffer *buffer;
1115
 
+
1116
 
+  buffer = gst_app_sink_pull_preroll (appsink);
1117
 
+  gst_buffer_unref (buffer);
1118
 
+
1119
 
+  return GST_FLOW_OK;
 
1037
+  switch (GST_MESSAGE_TYPE (message)) {
 
1038
+    case GST_MESSAGE_ERROR:{
 
1039
+      GError *err;
 
1040
+      GstCameraBinPreviewPipelineData *data;
 
1041
+
 
1042
+      data = user_data;
 
1043
+
 
1044
+      gst_message_parse_error (message, &err, NULL);
 
1045
+      GST_WARNING ("Error from preview pipeline: %s", err->message);
 
1046
+      g_error_free (err);
 
1047
+
 
1048
+      /* TODO Not sure if we should post an Error or Warning here */
 
1049
+      GST_ELEMENT_ERROR (data, CORE, FAILED,
 
1050
+          ("fatal error in preview pipeline, disposing the pipeline"), (NULL));
 
1051
+
 
1052
+      /* Possible error situations:
 
1053
+       * 1) cond_wait pending. prevent deadlock by signalling the cond
 
1054
+       * 2) preview_pipeline_post called with new buffer to handle. returns
 
1055
+       *    because data->pipeline is set to null
 
1056
+       * 3) new preview caps incoming. returns because data->pipeline is null
 
1057
+       */
 
1058
+
 
1059
+      if (data->pipeline) {
 
1060
+        gst_element_set_state (data->pipeline, GST_STATE_NULL);
 
1061
+        gst_object_unref (data->pipeline);
 
1062
+        data->pipeline = NULL;
 
1063
+      }
 
1064
+
 
1065
+      g_cond_signal (data->processing_cond);
 
1066
+
 
1067
+      break;
 
1068
+    }
 
1069
+    default:
 
1070
+      break;
 
1071
+  }
 
1072
+  return TRUE;
1120
1073
+}
1121
1074
+
1122
1075
+static GstFlowReturn
1142
1095
+        "This element has no bus, therefore no message sent!");
1143
1096
+  }
1144
1097
+
 
1098
+  g_mutex_lock (data->processing_lock);
 
1099
+
 
1100
+  data->processing--;
 
1101
+  if (data->processing == 0)
 
1102
+    g_cond_signal (data->processing_cond);
 
1103
+
 
1104
+  g_mutex_unlock (data->processing_lock);
 
1105
+
1145
1106
+  return GST_FLOW_OK;
1146
1107
+}
1147
1108
+
1161
1122
+{
1162
1123
+  GstCameraBinPreviewPipelineData *data;
1163
1124
+  GstElement *csp;
1164
 
+  GstElement *csp2;
1165
1125
+  GstElement *vscale;
1166
1126
+  gboolean added = FALSE;
 
1127
+  gboolean linkfail = FALSE;
 
1128
+  GstBus *bus;
1167
1129
+  GstAppSinkCallbacks callbacks = { 0, };
1168
1130
+
1169
 
+  data = g_new (GstCameraBinPreviewPipelineData, 1);
 
1131
+  data = g_new0 (GstCameraBinPreviewPipelineData, 1);
1170
1132
+
1171
1133
+  data->pipeline = gst_pipeline_new ("preview-pipeline");
1172
1134
+  data->appsrc = gst_element_factory_make ("appsrc", "preview-appsrc");
1173
 
+  data->capsfilter = gst_element_factory_make ("capsfilter",
1174
 
+      "preview-capsfilter");
1175
1135
+  data->appsink = gst_element_factory_make ("appsink", "preview-appsink");
1176
 
+  csp = gst_element_factory_make ("ffmpegcolorspace", "preview-csp0");
1177
 
+  csp2 = gst_element_factory_make ("ffmpegcolorspace", "preview-csp1");
 
1136
+  csp = gst_element_factory_make ("ffmpegcolorspace", "preview-csp");
1178
1137
+  vscale = gst_element_factory_make ("videoscale", "preview-vscale");
1179
1138
+
1180
 
+  if (!data->appsrc || !data->capsfilter || !data->appsink || !csp ||
1181
 
+      !csp2 || !vscale) {
 
1139
+  if (!data->appsrc || !data->appsink || !csp || !vscale) {
1182
1140
+    goto error;
1183
1141
+  }
1184
1142
+
1185
 
+  gst_bin_add_many (GST_BIN (data->pipeline), data->appsrc, data->capsfilter,
1186
 
+      data->appsink, csp, csp2, vscale, NULL);
 
1143
+  g_object_set (data->appsrc, "emit-signals", FALSE, NULL);
 
1144
+  g_object_set (data->appsink, "sync", FALSE, "enable-last-buffer",
 
1145
+      FALSE, NULL);
 
1146
+
 
1147
+  gst_bin_add_many (GST_BIN (data->pipeline), data->appsrc,
 
1148
+      data->appsink, csp, vscale, NULL);
1187
1149
+  if (filter)
1188
1150
+    gst_bin_add (GST_BIN (data->pipeline), gst_object_ref (filter));
1189
1151
+  added = TRUE;
1190
1152
+
1191
1153
+  if (filter) {
1192
 
+    if (!gst_element_link_many (data->appsrc, filter, csp, vscale, csp2,
1193
 
+            data->capsfilter, data->appsink, NULL))
1194
 
+      goto error;
 
1154
+    linkfail |=
 
1155
+        GST_PAD_LINK_FAILED (gst_element_link_pads_full (data->appsrc, "src",
 
1156
+            filter, NULL, GST_PAD_LINK_CHECK_NOTHING));
 
1157
+    linkfail |=
 
1158
+        GST_PAD_LINK_FAILED (gst_element_link_pads_full (filter, NULL,
 
1159
+            vscale, "sink", GST_PAD_LINK_CHECK_CAPS));
1195
1160
+  } else {
1196
 
+    if (!gst_element_link_many (data->appsrc, csp, vscale, csp2,
1197
 
+            data->capsfilter, data->appsink, NULL))
1198
 
+      goto error;
1199
 
+  }
1200
 
+
1201
 
+  callbacks.new_preroll = gst_camerabin_preview_pipeline_new_preroll;
 
1161
+    linkfail |=
 
1162
+        GST_PAD_LINK_FAILED (gst_element_link_pads_full (data->appsrc, "src",
 
1163
+            vscale, "sink", GST_PAD_LINK_CHECK_NOTHING));
 
1164
+  }
 
1165
+
 
1166
+  linkfail |=
 
1167
+      GST_PAD_LINK_FAILED (gst_element_link_pads_full (vscale, "src", csp,
 
1168
+          "sink", GST_PAD_LINK_CHECK_NOTHING));
 
1169
+  linkfail |=
 
1170
+      GST_PAD_LINK_FAILED (gst_element_link_pads_full (csp, "src",
 
1171
+          data->appsink, "sink", GST_PAD_LINK_CHECK_NOTHING));
 
1172
+
 
1173
+  if (linkfail) {
 
1174
+    GST_WARNING ("Failed to link preview pipeline elements");
 
1175
+    goto error;
 
1176
+  }
 
1177
+
1202
1178
+  callbacks.new_buffer = gst_camerabin_preview_pipeline_new_buffer;
1203
1179
+  gst_app_sink_set_callbacks ((GstAppSink *) data->appsink, &callbacks, data,
1204
1180
+      NULL);
1205
1181
+
 
1182
+  bus = gst_pipeline_get_bus (GST_PIPELINE (data->pipeline));
 
1183
+  gst_bus_add_watch (bus, bus_callback, data);
 
1184
+  gst_object_unref (bus);
 
1185
+
1206
1186
+  g_object_set (data->appsink, "sync", FALSE, NULL);
1207
1187
+
1208
1188
+  data->element = element;
1209
1189
+  data->filter = filter;
 
1190
+  data->vscale = vscale;
 
1191
+
 
1192
+  data->processing_lock = g_mutex_new ();
 
1193
+  data->processing_cond = g_cond_new ();
 
1194
+
 
1195
+  data->pending_preview_caps = NULL;
 
1196
+  data->processing = 0;
1210
1197
+
1211
1198
+  return data;
1212
1199
+error:
1214
1201
+  if (!added) {
1215
1202
+    if (csp)
1216
1203
+      gst_object_unref (csp);
1217
 
+    if (csp2)
1218
 
+      gst_object_unref (csp2);
1219
1204
+    if (vscale)
1220
1205
+      gst_object_unref (vscale);
1221
1206
+    if (data->appsrc)
1222
1207
+      gst_object_unref (data->appsrc);
1223
 
+    if (data->capsfilter)
1224
 
+      gst_object_unref (data->capsfilter);
1225
1208
+    if (data->appsink)
1226
1209
+      gst_object_unref (data->appsink);
1227
1210
+  }
1239
1222
+gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData *
1240
1223
+    preview)
1241
1224
+{
 
1225
+  g_return_if_fail (preview != NULL);
 
1226
+
 
1227
+  if (preview->processing_lock) {
 
1228
+    g_mutex_free (preview->processing_lock);
 
1229
+    preview->processing_lock = NULL;
 
1230
+  }
 
1231
+  if (preview->processing_cond) {
 
1232
+    g_cond_free (preview->processing_cond);
 
1233
+    preview->processing_cond = NULL;
 
1234
+  }
1242
1235
+  if (preview->pipeline) {
1243
1236
+    gst_element_set_state (preview->pipeline, GST_STATE_NULL);
1244
1237
+    gst_object_unref (preview->pipeline);
1264
1257
+  g_return_val_if_fail (preview->pipeline != NULL, FALSE);
1265
1258
+  g_return_val_if_fail (buffer, FALSE);
1266
1259
+
 
1260
+  g_mutex_lock (preview->processing_lock);
 
1261
+  g_return_val_if_fail (preview->pipeline != NULL, FALSE);
 
1262
+
 
1263
+  if (preview->pending_preview_caps) {
 
1264
+    if (preview->processing > 0) {
 
1265
+      g_cond_wait (preview->processing_cond, preview->processing_lock);
 
1266
+    }
 
1267
+    _gst_camerabin_preview_set_caps (preview, preview->pending_preview_caps);
 
1268
+    gst_caps_replace (&preview->pending_preview_caps, NULL);
 
1269
+  }
 
1270
+
 
1271
+  preview->processing++;
 
1272
+
1267
1273
+  gst_app_src_push_buffer ((GstAppSrc *) preview->appsrc,
1268
1274
+      gst_buffer_ref (buffer));
1269
1275
+
 
1276
+  g_mutex_unlock (preview->processing_lock);
 
1277
+
1270
1278
+  return TRUE;
1271
1279
+}
1272
1280
+
1273
 
+/**
1274
 
+ * gst_camerabin_preview_set_caps:
1275
 
+ * @preview: the #GstCameraBinPreviewPipelineData
1276
 
+ * @caps: the #GstCaps to be set
1277
 
+ *
1278
 
+ * The caps that preview buffers should have when posted
1279
 
+ * on the bus 
1280
 
+ */
1281
 
+void
1282
 
+gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
 
1281
+static void
 
1282
+_gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
1283
1283
+    GstCaps * caps)
1284
1284
+{
1285
1285
+  GstState state, pending;
1286
1286
+  GstStateChangeReturn ret;
1287
1287
+
1288
1288
+  g_return_if_fail (preview != NULL);
 
1289
+  g_return_if_fail (preview->pipeline != NULL);
1289
1290
+
1290
1291
+  ret = gst_element_get_state (preview->pipeline, &state, &pending, 0);
1291
1292
+  if (ret == GST_STATE_CHANGE_FAILURE) {
1293
1294
+    state = GST_STATE_PLAYING;
1294
1295
+    pending = GST_STATE_VOID_PENDING;
1295
1296
+  }
1296
 
+
1297
1297
+  gst_element_set_state (preview->pipeline, GST_STATE_NULL);
1298
 
+  g_object_set (preview->capsfilter, "caps", caps, NULL);
 
1298
+  g_object_set (preview->appsink, "caps", caps, NULL);
1299
1299
+  if (pending != GST_STATE_VOID_PENDING)
1300
1300
+    state = pending;
1301
1301
+  gst_element_set_state (preview->pipeline, state);
1302
1302
+}
1303
 
Index: trunk/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
 
1303
+
 
1304
+/**
 
1305
+ * gst_camerabin_preview_set_caps:
 
1306
+ * @preview: the #GstCameraBinPreviewPipelineData
 
1307
+ * @caps: the #GstCaps to be set (a new ref will be taken)
 
1308
+ *
 
1309
+ * The caps that preview buffers should have when posted
 
1310
+ * on the bus
 
1311
+ */
 
1312
+void
 
1313
+gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
 
1314
+    GstCaps * caps)
 
1315
+{
 
1316
+  g_return_if_fail (preview != NULL);
 
1317
+
 
1318
+  g_mutex_lock (preview->processing_lock);
 
1319
+
 
1320
+  if (preview->processing == 0) {
 
1321
+    _gst_camerabin_preview_set_caps (preview, caps);
 
1322
+  } else {
 
1323
+    GST_DEBUG ("Preview pipeline busy, storing new caps as pending");
 
1324
+    gst_caps_replace (&preview->pending_preview_caps, caps);
 
1325
+  }
 
1326
+  g_mutex_unlock (preview->processing_lock);
 
1327
+}
 
1328
+
 
1329
+/**
 
1330
+ * gst_camerabin_preview_set_filter:
 
1331
+ * @preview: the #GstCameraBinPreviewPipelineData
 
1332
+ * @filter: Custom filter to process preview data (an extra ref is taken)
 
1333
+ *
 
1334
+ * Set the filter element into preview pipeline.
 
1335
+ *
 
1336
+ * Returns: %TRUE on success
 
1337
+ */
 
1338
+gboolean
 
1339
+gst_camerabin_preview_set_filter (GstCameraBinPreviewPipelineData * preview,
 
1340
+    GstElement * filter)
 
1341
+{
 
1342
+  gboolean ret = TRUE;
 
1343
+  GstState current;
 
1344
+
 
1345
+  g_return_val_if_fail (preview != NULL, FALSE);
 
1346
+
 
1347
+  GST_DEBUG ("Preview pipeline setting new filter %p", filter);
 
1348
+
 
1349
+  g_mutex_lock (preview->processing_lock);
 
1350
+
 
1351
+  gst_element_get_state (preview->pipeline, &current, NULL, 0);
 
1352
+
 
1353
+  if (preview->processing == 0 && current == GST_STATE_NULL) {
 
1354
+    gboolean linkfail = FALSE;
 
1355
+
 
1356
+    if (preview->filter) {
 
1357
+      /* Unlink and remove old filter */
 
1358
+      gst_element_unlink (preview->appsrc, preview->filter);
 
1359
+      gst_element_unlink (preview->filter, preview->vscale);
 
1360
+      gst_bin_remove (GST_BIN (preview->pipeline), preview->filter);
 
1361
+    } else {
 
1362
+      /* Make room for filter by breaking the link between appsrc and vcale */
 
1363
+      gst_element_unlink (preview->appsrc, preview->vscale);
 
1364
+    }
 
1365
+
 
1366
+    if (filter) {
 
1367
+      /* Add and link the new filter between appsrc and vscale */
 
1368
+      gst_bin_add (GST_BIN (preview->pipeline), gst_object_ref (filter));
 
1369
+
 
1370
+      linkfail |=
 
1371
+          GST_PAD_LINK_FAILED (gst_element_link_pads_full (preview->appsrc,
 
1372
+              "src", filter, NULL, GST_PAD_LINK_CHECK_NOTHING));
 
1373
+
 
1374
+      linkfail |=
 
1375
+          GST_PAD_LINK_FAILED (gst_element_link_pads_full (filter, NULL,
 
1376
+              preview->vscale, "sink", GST_PAD_LINK_CHECK_CAPS));
 
1377
+    } else {
 
1378
+      /* No filter was given. Just link the appsrc to vscale directly */
 
1379
+      linkfail |=
 
1380
+          GST_PAD_LINK_FAILED (gst_element_link_pads_full (preview->appsrc,
 
1381
+              "src", preview->vscale, "sink", GST_PAD_LINK_CHECK_NOTHING));
 
1382
+    }
 
1383
+
 
1384
+    if (linkfail) {
 
1385
+      GST_WARNING ("Linking the filter to pipeline failed");
 
1386
+      ret = FALSE;
 
1387
+    } else {
 
1388
+      GST_DEBUG ("Linking the filter to pipeline successful");
 
1389
+      preview->filter = filter;
 
1390
+    }
 
1391
+  } else {
 
1392
+    GST_WARNING ("Cannot change filter when pipeline is running");
 
1393
+    ret = FALSE;
 
1394
+  }
 
1395
+  g_mutex_unlock (preview->processing_lock);
 
1396
+
 
1397
+  return ret;
 
1398
+}
 
1399
Index: gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
1304
1400
===================================================================
1305
 
--- /dev/null
1306
 
+++ trunk/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
1307
 
@@ -0,0 +1,49 @@
 
1401
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
1402
+++ gst-plugins-good0.10/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h    2012-02-09 14:44:27.400710798 +0200
 
1403
@@ -0,0 +1,56 @@
1308
1404
+/*
1309
1405
+ * GStreamer
1310
1406
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
1342
1438
+
1343
1439
+  GstElement *appsrc;
1344
1440
+  GstElement *filter;
1345
 
+  GstElement *capsfilter;
1346
1441
+  GstElement *appsink;
 
1442
+  GstElement *vscale;
1347
1443
+
1348
1444
+  GstElement *element;
 
1445
+
 
1446
+  GstCaps *pending_preview_caps;
 
1447
+  guint processing;
 
1448
+  GMutex *processing_lock;
 
1449
+  GCond *processing_cond;
 
1450
+
1349
1451
+} GstCameraBinPreviewPipelineData;
1350
1452
+
1351
1453
+GstCameraBinPreviewPipelineData *gst_camerabin_create_preview_pipeline (GstElement * element, GstElement * filter);
1352
1454
+void gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData * preview);
1353
1455
+gboolean gst_camerabin_preview_pipeline_post (GstCameraBinPreviewPipelineData * preview, GstBuffer * buffer);
1354
1456
+void gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview, GstCaps * caps);
 
1457
+gboolean gst_camerabin_preview_set_filter (GstCameraBinPreviewPipelineData * preview, GstElement * filter);
1355
1458
+
1356
1459
+#endif /* #ifndef __CAMERABIN_PREVIEW_H_ */
1357
 
Index: trunk/gst-libs/gst/interfaces/Makefile.am
 
1460
Index: gst-plugins-good0.10/gst-libs/gst/interfaces/Makefile.am
1358
1461
===================================================================
1359
 
--- /dev/null
1360
 
+++ trunk/gst-libs/gst/interfaces/Makefile.am
 
1462
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
1463
+++ gst-plugins-good0.10/gst-libs/gst/interfaces/Makefile.am    2012-02-09 14:44:27.400710798 +0200
1361
1464
@@ -0,0 +1,61 @@
1362
1465
+lib_LTLIBRARIES = libgstphotography-@GST_MAJORMINOR@.la
1363
1466
+libgstphotographyincludedir = \
1392
1495
+
1393
1496
+libgstphotography_@GST_MAJORMINOR@_la_CFLAGS = \
1394
1497
+       -DGST_USE_UNSTABLE_API \
1395
 
+       $(GST_PLUGINS_GOOD_CFLAGS) \
 
1498
+       $(GST_PLUGINS_BAD_CFLAGS) \
1396
1499
+       $(GST_CFLAGS)
1397
1500
+libgstphotography_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS) 
1398
1501
+libgstphotography_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
1420
1523
+         $(built_headers) \
1421
1524
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
1422
1525
+       > $@
1423
 
Index: trunk/gst-libs/gst/interfaces/photography.c
 
1526
Index: gst-plugins-good0.10/gst-libs/gst/interfaces/photography.c
1424
1527
===================================================================
1425
 
--- /dev/null
1426
 
+++ trunk/gst-libs/gst/interfaces/photography.c
 
1528
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
1529
+++ gst-plugins-good0.10/gst-libs/gst/interfaces/photography.c  2012-02-09 14:44:27.400710798 +0200
1427
1530
@@ -0,0 +1,624 @@
1428
1531
+/* GStreamer
1429
1532
+ *
2049
2152
+          GST_TYPE_PHOTOGRAPHY_NOISE_REDUCTION,
2050
2153
+          0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2051
2154
+}
2052
 
Index: trunk/gst-libs/gst/interfaces/photography.h
 
2155
Index: gst-plugins-good0.10/gst-libs/gst/interfaces/photography.h
2053
2156
===================================================================
2054
 
--- /dev/null
2055
 
+++ trunk/gst-libs/gst/interfaces/photography.h
2056
 
@@ -0,0 +1,387 @@
 
2157
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2158
+++ gst-plugins-good0.10/gst-libs/gst/interfaces/photography.h  2012-02-09 14:44:27.400710798 +0200
 
2159
@@ -0,0 +1,389 @@
2057
2160
+/* GStreamer
2058
2161
+ *
2059
2162
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
2231
2334
+  GST_PHOTOGRAPHY_CAPS_APERTURE = (1 << 8),
2232
2335
+  GST_PHOTOGRAPHY_CAPS_EXPOSURE = (1 << 9),
2233
2336
+  GST_PHOTOGRAPHY_CAPS_SHAKE = (1 << 10),
2234
 
+  GST_PHOTOGRAPHY_CAPS_NOISE_REDUCTION = (1 << 11)
 
2337
+  GST_PHOTOGRAPHY_CAPS_NOISE_REDUCTION = (1 << 11),
 
2338
+  GST_PHOTOGRAPHY_CAPS_FLICKER_REDUCTION = (1 << 12),
 
2339
+  GST_PHOTOGRAPHY_CAPS_ALL = (~0)
2235
2340
+} GstPhotoCaps;
2236
2341
+
2237
2342
+typedef enum
2441
2546
+G_END_DECLS
2442
2547
+
2443
2548
+#endif /* __GST_PHOTOGRAPHY_H__ */
2444
 
Index: trunk/gst/camerabin/Makefile.am
 
2549
Index: gst-plugins-good0.10/gst/camerabin/Makefile.am
2445
2550
===================================================================
2446
 
--- /dev/null
2447
 
+++ trunk/gst/camerabin/Makefile.am
 
2551
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2552
+++ gst-plugins-good0.10/gst/camerabin/Makefile.am      2012-02-09 14:44:27.400710798 +0200
2448
2553
@@ -0,0 +1,63 @@
2449
2554
+glib_gen_prefix = __gst_camerabin
2450
2555
+glib_gen_basename = gstcamerabin
2473
2578
+
2474
2579
+nodist_libgstcamerabin_la_SOURCES = $(built_sources)
2475
2580
+libgstcamerabin_la_CFLAGS = \
2476
 
+       $(GST_PLUGINS_GOOD_CFLAGS) \
 
2581
+       $(GST_PLUGINS_BAD_CFLAGS) \
2477
2582
+       $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
2478
2583
+       -DGST_USE_UNSTABLE_API
2479
2584
+libgstcamerabin_la_LIBADD = \
2509
2614
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
2510
2615
+                      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
2511
2616
+       > $@
2512
 
Index: trunk/gst/camerabin/TODO
 
2617
Index: gst-plugins-good0.10/gst/camerabin/TODO
2513
2618
===================================================================
2514
 
--- /dev/null
2515
 
+++ trunk/gst/camerabin/TODO
 
2619
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2620
+++ gst-plugins-good0.10/gst/camerabin/TODO     2012-02-09 14:44:27.400710798 +0200
2516
2621
@@ -0,0 +1,31 @@
2517
2622
+= Cleanups =
2518
2623
+* often two g_object_set for same object one after the other
2545
2650
+    - on eos, put it back to the pool
2546
2651
+    - for this we need to check that we can have multiple instances of e.g.
2547
2652
+      dsp jpeg encoders
2548
 
Index: trunk/gst/camerabin/camerabindebug.h
 
2653
Index: gst-plugins-good0.10/gst/camerabin/camerabindebug.h
2549
2654
===================================================================
2550
 
--- /dev/null
2551
 
+++ trunk/gst/camerabin/camerabindebug.h
 
2655
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2656
+++ gst-plugins-good0.10/gst/camerabin/camerabindebug.h 2012-02-09 14:44:27.400710798 +0200
2552
2657
@@ -0,0 +1,30 @@
2553
2658
+/*
2554
2659
+ * GStreamer
2580
2685
+#define GST_CAT_DEFAULT gst_camerabin_debug
2581
2686
+
2582
2687
+#endif /* #ifndef __CAMERABIN_DEBUG_H_ */
2583
 
Index: trunk/gst/camerabin/camerabingeneral.c
 
2688
Index: gst-plugins-good0.10/gst/camerabin/camerabingeneral.c
2584
2689
===================================================================
2585
 
--- /dev/null
2586
 
+++ trunk/gst/camerabin/camerabingeneral.c
 
2690
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2691
+++ gst-plugins-good0.10/gst/camerabin/camerabingeneral.c       2012-02-09 14:44:27.400710798 +0200
2587
2692
@@ -0,0 +1,263 @@
2588
2693
+/*
2589
2694
+ * GStreamer
2848
2953
+  }
2849
2954
+  return ret;
2850
2955
+}
2851
 
Index: trunk/gst/camerabin/camerabingeneral.h
 
2956
Index: gst-plugins-good0.10/gst/camerabin/camerabingeneral.h
2852
2957
===================================================================
2853
 
--- /dev/null
2854
 
+++ trunk/gst/camerabin/camerabingeneral.h
 
2958
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
2959
+++ gst-plugins-good0.10/gst/camerabin/camerabingeneral.h       2012-02-09 14:44:27.400710798 +0200
2855
2960
@@ -0,0 +1,36 @@
2856
2961
+/*
2857
2962
+ * GStreamer
2889
2994
+gboolean gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data);
2890
2995
+
2891
2996
+#endif /* #ifndef __CAMERABIN_GENERAL_H_ */
2892
 
Index: trunk/gst/camerabin/camerabinimage.c
 
2997
Index: gst-plugins-good0.10/gst/camerabin/camerabinimage.c
2893
2998
===================================================================
2894
 
--- /dev/null
2895
 
+++ trunk/gst/camerabin/camerabinimage.c
2896
 
@@ -0,0 +1,744 @@
 
2999
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
3000
+++ gst-plugins-good0.10/gst/camerabin/camerabinimage.c 2012-02-09 14:44:27.400710798 +0200
 
3001
@@ -0,0 +1,775 @@
2897
3002
+/*
2898
3003
+ * GStreamer
2899
3004
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
2957
3062
+
2958
3063
+#define DEFAULT_SINK "filesink"
2959
3064
+#define DEFAULT_ENC "jpegenc"
2960
 
+#define DEFAULT_META_MUX "jifmux"
 
3065
+#define DEFAULT_FORMATTER "jifmux"
2961
3066
+#define DEFAULT_FLAGS GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION
2962
3067
+
2963
3068
+enum
2998
3103
+{
2999
3104
+  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
3000
3105
+
3001
 
+  gst_element_class_add_pad_template (eklass,
3002
 
+      gst_static_pad_template_get (&sink_template));
 
3106
+  gst_element_class_add_static_pad_template (eklass, &sink_template);
3003
3107
+  gst_element_class_set_details_simple (eklass,
3004
3108
+      "Image capture bin for camerabin", "Bin/Image",
3005
3109
+      "Process and store image data",
3046
3150
+  img->csp = NULL;
3047
3151
+  img->enc = NULL;
3048
3152
+  img->app_enc = NULL;
3049
 
+  img->meta_mux = NULL;
 
3153
+  img->formatter = NULL;
 
3154
+  img->app_formatter = NULL;
3050
3155
+  img->sink = NULL;
3051
3156
+
3052
3157
+  /* Create src and sink ghost pads */
3076
3181
+    img->sink = NULL;
3077
3182
+  }
3078
3183
+
3079
 
+  if (img->meta_mux) {
3080
 
+    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
3081
 
+        GST_ELEMENT_NAME (img->meta_mux),
3082
 
+        GST_OBJECT_REFCOUNT_VALUE (img->meta_mux));
3083
 
+    gst_object_unref (img->meta_mux);
3084
 
+    img->meta_mux = NULL;
 
3184
+  if (img->formatter) {
 
3185
+    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
 
3186
+        GST_ELEMENT_NAME (img->formatter),
 
3187
+        GST_OBJECT_REFCOUNT_VALUE (img->formatter));
 
3188
+    gst_object_unref (img->formatter);
 
3189
+    img->formatter = NULL;
 
3190
+  }
 
3191
+
 
3192
+  if (img->app_formatter) {
 
3193
+    gst_object_sink (img->app_formatter);
 
3194
+    GST_LOG_OBJECT (img, "disposing %s with refcount %d",
 
3195
+        GST_ELEMENT_NAME (img->app_formatter),
 
3196
+        GST_OBJECT_REFCOUNT_VALUE (img->app_formatter));
 
3197
+    gst_object_unref (img->app_formatter);
 
3198
+    img->app_formatter = NULL;
3085
3199
+  }
3086
3200
+
3087
3201
+  if (img->enc) {
3295
3409
+  }
3296
3410
+
3297
3411
+  /* Create metadata muxer element */
3298
 
+  if (!prepare_element (&imagebin->elements, DEFAULT_META_MUX, NULL,
3299
 
+          &imagebin->meta_mux)) {
 
3412
+  if (!prepare_element (&imagebin->elements, DEFAULT_FORMATTER,
 
3413
+          imagebin->app_formatter, &imagebin->formatter)) {
3300
3414
+    goto done;
3301
3415
+  } else if (!imagebin->metadata_probe_id) {
3302
3416
+    /* Add probe for default XMP metadata writing */
3303
 
+    sinkpad = gst_element_get_static_pad (imagebin->meta_mux, "sink");
 
3417
+    sinkpad = gst_element_get_static_pad (imagebin->formatter, "sink");
3304
3418
+    imagebin->metadata_probe_id =
3305
3419
+        gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (metadata_write_probe),
3306
3420
+        imagebin);
3364
3478
+
3365
3479
+  g_return_val_if_fail (img != NULL, TRUE);
3366
3480
+
3367
 
+  setter = GST_TAG_SETTER (img->meta_mux);
 
3481
+  if (GST_IS_TAG_SETTER (img->formatter)) {
 
3482
+    setter = GST_TAG_SETTER (img->formatter);
 
3483
+  }
3368
3484
+
3369
3485
+  if (!setter) {
3370
3486
+    GST_WARNING_OBJECT (img, "setting tags failed");
3613
3729
+}
3614
3730
+
3615
3731
+void
 
3732
+gst_camerabin_image_set_formatter (GstCameraBinImage * img,
 
3733
+    GstElement * formatter)
 
3734
+{
 
3735
+  GstElement **app_formatter;
 
3736
+  GST_DEBUG ("setting image formatter %" GST_PTR_FORMAT, formatter);
 
3737
+
 
3738
+  app_formatter = &img->app_formatter;
 
3739
+  GST_OBJECT_LOCK (img);
 
3740
+  gst_object_replace ((GstObject **) app_formatter, GST_OBJECT (formatter));
 
3741
+  GST_OBJECT_UNLOCK (img);
 
3742
+}
 
3743
+
 
3744
+void
3616
3745
+gst_camerabin_image_set_flags (GstCameraBinImage * img, GstCameraBinFlags flags)
3617
3746
+{
3618
3747
+  GST_DEBUG_OBJECT (img, "setting image flags: %d", flags);
3634
3763
+}
3635
3764
+
3636
3765
+GstElement *
 
3766
+gst_camerabin_image_get_formatter (GstCameraBinImage * img)
 
3767
+{
 
3768
+  /* Prefer formatter that is currently in use */
 
3769
+  return img->formatter ? img->formatter : img->app_formatter;
 
3770
+}
 
3771
+
 
3772
+GstElement *
3637
3773
+gst_camerabin_image_get_postproc (GstCameraBinImage * img)
3638
3774
+{
3639
3775
+  return img->post;
3640
3776
+}
3641
 
Index: trunk/gst/camerabin/camerabinimage.h
 
3777
Index: gst-plugins-good0.10/gst/camerabin/camerabinimage.h
3642
3778
===================================================================
3643
 
--- /dev/null
3644
 
+++ trunk/gst/camerabin/camerabinimage.h
3645
 
@@ -0,0 +1,90 @@
 
3779
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
3780
+++ gst-plugins-good0.10/gst/camerabin/camerabinimage.h 2012-02-09 14:44:27.400710798 +0200
 
3781
@@ -0,0 +1,96 @@
3646
3782
+/*
3647
3783
+ * GStreamer
3648
3784
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
3700
3836
+  GstElement *csp;
3701
3837
+  GstElement *enc;
3702
3838
+  GstElement *app_enc;
3703
 
+  GstElement *meta_mux;
 
3839
+  GstElement *formatter;
 
3840
+  GstElement *app_formatter;
3704
3841
+  GstElement *sink;
3705
3842
+
3706
3843
+  GstCameraBinFlags flags;
3722
3859
+    GstElement * postproc);
3723
3860
+
3724
3861
+void
 
3862
+gst_camerabin_image_set_formatter (GstCameraBinImage * img, GstElement * formatter);
 
3863
+
 
3864
+void
3725
3865
+gst_camerabin_image_set_flags (GstCameraBinImage * img,
3726
3866
+    GstCameraBinFlags flags);
3727
3867
+
3729
3869
+
3730
3870
+GstElement *gst_camerabin_image_get_postproc (GstCameraBinImage * img);
3731
3871
+
 
3872
+GstElement *gst_camerabin_image_get_formatter (GstCameraBinImage * img);
 
3873
+
3732
3874
+gboolean gst_camerabin_image_prepare_elements (GstCameraBinImage * imagebin);
3733
3875
+
3734
3876
+G_END_DECLS
3735
3877
+#endif /* #ifndef __CAMERABIN_IMAGE_H__ */
3736
 
Index: trunk/gst/camerabin/camerabinpreview.c
 
3878
Index: gst-plugins-good0.10/gst/camerabin/camerabinpreview.c
3737
3879
===================================================================
3738
 
--- /dev/null
3739
 
+++ trunk/gst/camerabin/camerabinpreview.c
 
3880
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
3881
+++ gst-plugins-good0.10/gst/camerabin/camerabinpreview.c       2012-02-09 14:44:27.400710798 +0200
3740
3882
@@ -0,0 +1,364 @@
3741
3883
+/*
3742
3884
+* GStreamer
4102
4244
+    state = pending;
4103
4245
+  gst_element_set_state (data->pipeline, state);
4104
4246
+}
4105
 
Index: trunk/gst/camerabin/camerabinpreview.h
 
4247
Index: gst-plugins-good0.10/gst/camerabin/camerabinpreview.h
4106
4248
===================================================================
4107
 
--- /dev/null
4108
 
+++ trunk/gst/camerabin/camerabinpreview.h
 
4249
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
4250
+++ gst-plugins-good0.10/gst/camerabin/camerabinpreview.h       2012-02-09 14:44:27.400710798 +0200
4109
4251
@@ -0,0 +1,57 @@
4110
4252
+/*
4111
4253
+* GStreamer
4164
4306
+G_END_DECLS
4165
4307
+
4166
4308
+#endif                          /* __CAMERABINPREVIEW_H__ */
4167
 
Index: trunk/gst/camerabin/camerabinvideo.c
 
4309
Index: gst-plugins-good0.10/gst/camerabin/camerabinvideo.c
4168
4310
===================================================================
4169
 
--- /dev/null
4170
 
+++ trunk/gst/camerabin/camerabinvideo.c
4171
 
@@ -0,0 +1,838 @@
 
4311
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
4312
+++ gst-plugins-good0.10/gst/camerabin/camerabinvideo.c 2012-02-09 14:44:27.400710798 +0200
 
4313
@@ -0,0 +1,843 @@
4172
4314
+/*
4173
4315
+ * GStreamer
4174
4316
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
4289
4431
+{
4290
4432
+  GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
4291
4433
+
4292
 
+  gst_element_class_add_pad_template (eklass,
4293
 
+      gst_static_pad_template_get (&sink_template));
4294
 
+  gst_element_class_add_pad_template (eklass,
4295
 
+      gst_static_pad_template_get (&src_template));
 
4434
+  gst_element_class_add_static_pad_template (eklass, &sink_template);
 
4435
+  gst_element_class_add_static_pad_template (eklass, &src_template);
4296
4436
+  gst_element_class_set_details_simple (eklass,
4297
4437
+      "Video capture bin for camerabin", "Bin/Video",
4298
4438
+      "Process and store video data",
4808
4948
+      G_CALLBACK (gst_camerabin_drop_eos_probe), vid);
4809
4949
+  gst_object_unref (vid_srcpad);
4810
4950
+
 
4951
+  /* audio source is not always present and might be set to NULL during operation */
 
4952
+  if (vid->aud_src
 
4953
+      && g_object_class_find_property (G_OBJECT_GET_CLASS (vid->aud_src),
 
4954
+          "provide-clock")) {
 
4955
+    g_object_set (vid->aud_src, "provide-clock", FALSE, NULL);
 
4956
+  }
 
4957
+
4811
4958
+  GST_DEBUG ("created video elements");
4812
4959
+
4813
4960
+  return TRUE;
5007
5154
+{
5008
5155
+  return vid->aud_src ? vid->aud_src : vid->app_aud_src;
5009
5156
+}
5010
 
Index: trunk/gst/camerabin/camerabinvideo.h
 
5157
Index: gst-plugins-good0.10/gst/camerabin/camerabinvideo.h
5011
5158
===================================================================
5012
 
--- /dev/null
5013
 
+++ trunk/gst/camerabin/camerabinvideo.h
 
5159
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
5160
+++ gst-plugins-good0.10/gst/camerabin/camerabinvideo.h 2012-02-09 14:44:27.400710798 +0200
5014
5161
@@ -0,0 +1,139 @@
5015
5162
+/*
5016
5163
+ * GStreamer
5151
5298
+
5152
5299
+G_END_DECLS
5153
5300
+#endif /* #ifndef __CAMERABIN_VIDEO_H__ */
5154
 
Index: trunk/gst/camerabin/gstcamerabin-enum.c
 
5301
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabin-enum.c
5155
5302
===================================================================
5156
 
--- /dev/null
5157
 
+++ trunk/gst/camerabin/gstcamerabin-enum.c
 
5303
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
5304
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabin-enum.c      2012-02-09 14:44:27.400710798 +0200
5158
5305
@@ -0,0 +1,62 @@
5159
5306
+/*
5160
5307
+ * GStreamer
5218
5365
+  g_once (&once, (GThreadFunc) register_gst_camerabin_flags, &id);
5219
5366
+  return id;
5220
5367
+}
5221
 
Index: trunk/gst/camerabin/gstcamerabin-enum.h
 
5368
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabin-enum.h
5222
5369
===================================================================
5223
 
--- /dev/null
5224
 
+++ trunk/gst/camerabin/gstcamerabin-enum.h
5225
 
@@ -0,0 +1,111 @@
 
5370
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
5371
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabin-enum.h      2012-02-09 14:44:27.404710917 +0200
 
5372
@@ -0,0 +1,112 @@
5226
5373
+/*
5227
5374
+ * GStreamer
5228
5375
+ * Copyright (C) 2009 Nokia Corporation <multimedia@maemo.org>
5260
5407
+  ARG_ZOOM,
5261
5408
+  ARG_IMAGE_POST,
5262
5409
+  ARG_IMAGE_ENC,
 
5410
+  ARG_IMAGE_FORMATTER,
5263
5411
+  ARG_VIDEO_POST,
5264
5412
+  ARG_VIDEO_ENC,
5265
5413
+  ARG_AUDIO_ENC,
5334
5482
+G_END_DECLS
5335
5483
+
5336
5484
+#endif                          /* #ifndef __GST_CAMERABIN_ENUM_H__ */
5337
 
Index: trunk/gst/camerabin/gstcamerabin-marshal.list
 
5485
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabin-marshal.list
5338
5486
===================================================================
5339
 
--- /dev/null
5340
 
+++ trunk/gst/camerabin/gstcamerabin-marshal.list
 
5487
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
5488
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabin-marshal.list        2012-02-09 14:44:27.404710917 +0200
5341
5489
@@ -0,0 +1,8 @@
5342
5490
+# glib-genmarshal --header --prefix=gst_camerabin camerabin_marshal.marshal > camerabin_marshal.h
5343
5491
+# glib-genmarshal --body --prefix=gst_camerabin camerabin_marshal.marshal > camerabin_marshal.c
5347
5495
+BOOLEAN:STRING
5348
5496
+INT64:VOID
5349
5497
+VOID:OBJECT,INT64,INT64
5350
 
Index: trunk/gst/camerabin/gstcamerabin.c
 
5498
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabin.c
5351
5499
===================================================================
5352
 
--- /dev/null
5353
 
+++ trunk/gst/camerabin/gstcamerabin.c
5354
 
@@ -0,0 +1,4285 @@
 
5500
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
5501
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabin.c   2012-02-09 14:44:27.404710917 +0200
 
5502
@@ -0,0 +1,4323 @@
5355
5503
+/*
5356
5504
+ * GStreamer
5357
5505
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
5438
5586
+ * unreffed or replaced by a new user set element. Initially only elements
5439
5587
+ * needed for view finder mode are created to speed up startup. Image bin and
5440
5588
+ * video bin elements are created when setting the mode or starting capture.
 
5589
+ * GstCameraBin must be in the PLAYING state before #GstCameraBin::capture-start
 
5590
+ * is called.
5441
5591
+ * </para>
5442
5592
+ * </refsect2>
5443
5593
+ * <refsect2>
5562
5712
+
5563
5713
+#define DEFAULT_FLAGS GST_CAMERABIN_FLAG_SOURCE_RESIZE | \
5564
5714
+  GST_CAMERABIN_FLAG_VIEWFINDER_SCALE | \
5565
 
+  GST_CAMERABIN_FLAG_AUDIO_CONVERSION | \
 
5715
+  GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION | \
5566
5716
+  GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION | \
5567
 
+  GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION
 
5717
+  GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION | \
 
5718
+  GST_CAMERABIN_FLAG_AUDIO_CONVERSION
5568
5719
+
5569
5720
+/* Using "bilinear" as default zoom method */
5570
5721
+#define CAMERABIN_DEFAULT_ZOOM_METHOD 1
6995
7146
+gst_camerabin_start_video_recording (GstCameraBin * camera)
6996
7147
+{
6997
7148
+  GstStateChangeReturn state_ret;
 
7149
+  GstCameraBinVideo *vidbin = (GstCameraBinVideo *) camera->vidbin;
6998
7150
+  /* FIXME: how to ensure resolution and fps is supported by CPU?
6999
7151
+   * use a queue overrun signal?
7000
7152
+   */
7008
7160
+  gst_camerabin_rewrite_tags (camera);
7009
7161
+
7010
7162
+  /* Pause the pipeline in order to distribute new clock in paused_to_playing */
 
7163
+  /* Audio source needs to go to null to reset the ringbuffer */
 
7164
+  if (vidbin->aud_src)
 
7165
+    gst_element_set_state (vidbin->aud_src, GST_STATE_NULL);
7011
7166
+  state_ret = gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
7012
7167
+
7013
7168
+  if (state_ret != GST_STATE_CHANGE_FAILURE) {
 
7169
+    GstClock *clock = gst_element_get_clock (GST_ELEMENT (camera));
 
7170
+
7014
7171
+    g_mutex_lock (camera->capture_mutex);
7015
7172
+    camera->capturing = TRUE;
7016
7173
+    g_mutex_unlock (camera->capture_mutex);
7026
7183
+      g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 2, NULL);
7027
7184
+    }
7028
7185
+
 
7186
+    /* Clock might be distributed as NULL to audiosrc, messing timestamping */
 
7187
+    if (vidbin->aud_src)
 
7188
+      gst_element_set_clock (vidbin->aud_src, clock);
 
7189
+    gst_object_unref (clock);
 
7190
+
7029
7191
+    /* videobin will not go to playing if file is not writable */
7030
7192
+    if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
7031
7193
+        GST_STATE_CHANGE_FAILURE) {
7165
7327
+  if (GST_IS_BUFFER (obj)) {
7166
7328
+    GstBuffer *buffer = GST_BUFFER_CAST (obj);
7167
7329
+    GstStructure *fn_ev_struct = NULL;
7168
 
+    gboolean ret = TRUE;
7169
7330
+    GstPad *os_sink = NULL;
7170
7331
+
7171
7332
+    GST_LOG ("got buffer %p with size %d", buffer, GST_BUFFER_SIZE (buffer));
7177
7338
+    /* Image filename should be set by now */
7178
7339
+    if (g_str_equal (camera->filename->str, "")) {
7179
7340
+      GST_DEBUG_OBJECT (camera, "filename not set, dropping buffer");
7180
 
+      ret = FALSE;
7181
7341
+      CAMERABIN_PROCESSING_DEC_UNLOCKED (camera);
7182
7342
+      goto done;
7183
7343
+    }
8205
8365
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
8206
8366
+
8207
8367
+  /**
 
8368
+   *  GstCameraBin:image-formatter:
 
8369
+   *
 
8370
+   * Set up an image formatter (for example, jifmux) element.
 
8371
+   * This property can only be set while #GstCameraBin is in NULL state.
 
8372
+   * The ownership of the element will be taken by #GstCameraBin.
 
8373
+   */
 
8374
+
 
8375
+  g_object_class_install_property (gobject_class, ARG_IMAGE_FORMATTER,
 
8376
+      g_param_spec_object ("image-formatter", "Image formatter",
 
8377
+          "Image formatter GStreamer element (default is jifmux)",
 
8378
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
8379
+
 
8380
+  /**
8208
8381
+   *  GstCameraBin:video-post-processing:
8209
8382
+   *
8210
8383
+   * Set up an element to do video post processing.
8836
9009
+      gst_camerabin_image_set_encoder (GST_CAMERABIN_IMAGE (camera->imgbin),
8837
9010
+          g_value_get_object (value));
8838
9011
+      break;
 
9012
+    case ARG_IMAGE_FORMATTER:
 
9013
+      if (GST_STATE (camera->imgbin) != GST_STATE_NULL) {
 
9014
+        GST_WARNING_OBJECT (camera,
 
9015
+            "can't use set element until next image bin NULL to READY state change");
 
9016
+      }
 
9017
+      gst_camerabin_image_set_formatter (GST_CAMERABIN_IMAGE (camera->imgbin),
 
9018
+          g_value_get_object (value));
 
9019
+      break;
8839
9020
+    case ARG_VF_SINK:
8840
9021
+      if (GST_STATE (camera) != GST_STATE_NULL) {
8841
9022
+        GST_ELEMENT_ERROR (camera, CORE, FAILED,
9078
9259
+          gst_camerabin_image_get_encoder (GST_CAMERABIN_IMAGE
9079
9260
+              (camera->imgbin)));
9080
9261
+      break;
 
9262
+    case ARG_IMAGE_FORMATTER:
 
9263
+      g_value_set_object (value,
 
9264
+          gst_camerabin_image_get_formatter (GST_CAMERABIN_IMAGE
 
9265
+              (camera->imgbin)));
 
9266
+      break;
9081
9267
+    case ARG_VIDEO_POST:
9082
9268
+      g_value_set_object (value,
9083
9269
+          gst_camerabin_video_get_post (GST_CAMERABIN_VIDEO (camera->vidbin)));
9637
9823
+    "camerabin",
9638
9824
+    "High level api for DC (Digital Camera) application",
9639
9825
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
9640
 
Index: trunk/gst/camerabin/gstcamerabin.h
 
9826
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabin.h
9641
9827
===================================================================
9642
 
--- /dev/null
9643
 
+++ trunk/gst/camerabin/gstcamerabin.h
 
9828
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
9829
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabin.h   2012-02-09 14:44:27.404710917 +0200
9644
9830
@@ -0,0 +1,235 @@
9645
9831
+/*
9646
9832
+ * GStreamer
9877
10063
+
9878
10064
+G_END_DECLS
9879
10065
+#endif /* #ifndef __GST_CAMERABIN_H__ */
9880
 
Index: trunk/gst/camerabin/gstcamerabincolorbalance.c
 
10066
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabincolorbalance.c
9881
10067
===================================================================
9882
 
--- /dev/null
9883
 
+++ trunk/gst/camerabin/gstcamerabincolorbalance.c
 
10068
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
10069
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabincolorbalance.c       2012-02-09 14:44:27.404710917 +0200
9884
10070
@@ -0,0 +1,81 @@
9885
10071
+/*
9886
10072
+ * GStreamer
9963
10149
+  iface->set_value = gst_camerabin_color_balance_set_value;
9964
10150
+  iface->get_value = gst_camerabin_color_balance_get_value;
9965
10151
+}
9966
 
Index: trunk/gst/camerabin/gstcamerabincolorbalance.h
 
10152
Index: gst-plugins-good0.10/gst/camerabin/gstcamerabincolorbalance.h
9967
10153
===================================================================
9968
 
--- /dev/null
9969
 
+++ trunk/gst/camerabin/gstcamerabincolorbalance.h
 
10154
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
10155
+++ gst-plugins-good0.10/gst/camerabin/gstcamerabincolorbalance.h       2012-02-09 14:44:27.404710917 +0200
9970
10156
@@ -0,0 +1,28 @@
9971
10157
+/*
9972
10158
+ * GStreamer
9996
10182
+extern void gst_camerabin_color_balance_init (GstColorBalanceClass * iface);
9997
10183
+
9998
10184
+#endif /* #ifndef __GST_CAMERA_COLOR_BALANCE_H__ */
9999
 
Index: trunk/gst/camerabin/gstinputselector.c
 
10185
Index: gst-plugins-good0.10/gst/camerabin/gstinputselector.c
10000
10186
===================================================================
10001
 
--- /dev/null
10002
 
+++ trunk/gst/camerabin/gstinputselector.c
 
10187
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
10188
+++ gst-plugins-good0.10/gst/camerabin/gstinputselector.c       2012-02-09 14:44:27.404710917 +0200
10003
10189
@@ -0,0 +1,1498 @@
10004
10190
+/* GStreamer
10005
10191
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.net>
10748
10934
+      "Julien Moutte <julien@moutte.net>, "
10749
10935
+      "Jan Schmidt <thaytan@mad.scientist.com>, "
10750
10936
+      "Wim Taymans <wim.taymans@gmail.com>");
10751
 
+  gst_element_class_add_pad_template (element_class,
10752
 
+      gst_static_pad_template_get (&gst_input_selector_sink_factory));
10753
 
+  gst_element_class_add_pad_template (element_class,
10754
 
+      gst_static_pad_template_get (&gst_input_selector_src_factory));
 
10937
+  gst_element_class_add_static_pad_template (element_class,
 
10938
+      &gst_input_selector_sink_factory);
 
10939
+  gst_element_class_add_static_pad_template (element_class,
 
10940
+      &gst_input_selector_src_factory);
10755
10941
+}
10756
10942
+
10757
10943
+static void
11499
11685
+
11500
11686
+  return is_eos;
11501
11687
+}
11502
 
Index: trunk/gst/camerabin/gstinputselector.h
 
11688
Index: gst-plugins-good0.10/gst/camerabin/gstinputselector.h
11503
11689
===================================================================
11504
 
--- /dev/null
11505
 
+++ trunk/gst/camerabin/gstinputselector.h
 
11690
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
11691
+++ gst-plugins-good0.10/gst/camerabin/gstinputselector.h       2012-02-09 14:44:27.404710917 +0200
11506
11692
@@ -0,0 +1,84 @@
11507
11693
+/* GStreamer
11508
11694
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.net>
11588
11774
+G_END_DECLS
11589
11775
+
11590
11776
+#endif /* __GST_INPUT_SELECTOR_H__ */
11591
 
Index: trunk/gst/camerabin2/Makefile.am
 
11777
Index: gst-plugins-good0.10/gst/camerabin2/Makefile.am
11592
11778
===================================================================
11593
 
--- /dev/null
11594
 
+++ trunk/gst/camerabin2/Makefile.am
11595
 
@@ -0,0 +1,45 @@
 
11779
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
11780
+++ gst-plugins-good0.10/gst/camerabin2/Makefile.am     2012-02-09 14:44:27.404710917 +0200
 
11781
@@ -0,0 +1,43 @@
11596
11782
+plugin_LTLIBRARIES = libgstcamerabin2.la
11597
11783
+
11598
11784
+libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \
11599
 
+                               gstimagecapturebin.c \
11600
11785
+                               camerabingeneral.c \
11601
11786
+                               gstwrappercamerabinsrc.c \
11602
11787
+                               gstcamerabin2.c \
11603
11788
+                               gstplugin.c
11604
11789
+
11605
11790
+libgstcamerabin2_la_CFLAGS = \
11606
 
+       $(GST_PLUGINS_GOOD_CFLAGS) \
 
11791
+       $(GST_PLUGINS_BAD_CFLAGS) \
11607
11792
+       $(GST_PLUGINS_BASE_CFLAGS) \
11608
11793
+       $(GST_BASE_CFLAGS) $(GST_CFLAGS) \
11609
11794
+       -DGST_USE_UNSTABLE_API
11618
11803
+libgstcamerabin2_la_LIBTOOLFLAGS = --tag=disable-static
11619
11804
+
11620
11805
+noinst_HEADERS = gstviewfinderbin.h \
11621
 
+               gstimagecapturebin.h \
11622
11806
+               camerabingeneral.h \
11623
11807
+               gstwrappercamerabinsrc.h \
11624
11808
+               gstcamerabin2.h
11638
11822
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
11639
11823
+                      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
11640
11824
+       > $@
11641
 
Index: trunk/gst/camerabin2/camerabingeneral.c
 
11825
Index: gst-plugins-good0.10/gst/camerabin2/camerabingeneral.c
11642
11826
===================================================================
11643
 
--- /dev/null
11644
 
+++ trunk/gst/camerabin2/camerabingeneral.c
11645
 
@@ -0,0 +1,278 @@
 
11827
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
11828
+++ gst-plugins-good0.10/gst/camerabin2/camerabingeneral.c      2012-02-09 14:44:27.404710917 +0200
 
11829
@@ -0,0 +1,260 @@
11646
11830
+/*
11647
11831
+ * GStreamer
11648
11832
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
11665
11849
+
11666
11850
+/**
11667
11851
+ * SECTION:camerabingeneral
11668
 
+ * @short_description: helper functions for #GstCameraBin and it's modules
 
11852
+ * @short_description: helper functions for #GstCameraBin2 and it's modules
11669
11853
+ *
11670
 
+ * Common helper functions for #GstCameraBin, #GstCameraBinImage and
11671
 
+ * #GstCameraBinVideo.
 
11854
+ * Common helper functions for #GstCameraBin2, #GstCameraBin2Image and
 
11855
+ * #GstCameraBin2Video.
11672
11856
+ *
11673
11857
+ */
 
11858
+#ifdef HAVE_CONFIG_H
 
11859
+#include "config.h"
 
11860
+#endif
 
11861
+
11674
11862
+#include <string.h>
11675
11863
+
11676
11864
+#include <glib.h>
11677
11865
+#include <gst/basecamerabinsrc/gstbasecamerasrc.h>
 
11866
+#include <gst/gst-i18n-plugin.h>
 
11867
+
11678
11868
+#include "camerabingeneral.h"
11679
11869
+
11680
11870
+/**
11764
11954
+        GST_DEBUG_PAD_NAME (bin_pad));
11765
11955
+    bin_elem = gst_pad_get_parent_element (bin_pad);
11766
11956
+    gst_object_unref (bin_pad);
11767
 
+    if (!gst_element_link_pads (bin_elem, srcpad, new_elem, dstpad)) {
 
11957
+    if (!gst_element_link_pads_full (bin_elem, srcpad, new_elem, dstpad,
 
11958
+            GST_PAD_LINK_CHECK_CAPS)) {
11768
11959
+      gst_object_ref (new_elem);
11769
11960
+      gst_bin_remove (bin, new_elem);
11770
11961
+      ret = FALSE;
11800
11991
+
11801
11992
+  new_elem = gst_element_factory_make (elem_name, instance_name);
11802
11993
+  if (!new_elem) {
11803
 
+    GST_ELEMENT_ERROR (bin, CORE, MISSING_PLUGIN, (NULL),
11804
 
+        ("could not create \"%s\" element.", elem_name));
 
11994
+    GST_ELEMENT_ERROR (bin, CORE, MISSING_PLUGIN,
 
11995
+        (_("Missing element '%s' - check your GStreamer installation."),
 
11996
+            elem_name), (NULL));
11805
11997
+  } else if (!gst_camerabin_add_element (bin, new_elem)) {
11806
11998
+    new_elem = NULL;
11807
11999
+  }
11895
12087
+  }
11896
12088
+  gst_iterator_free (iter);
11897
12089
+}
11898
 
+
11899
 
+/**
11900
 
+ * gst_camerabin_drop_eos_probe:
11901
 
+ * @pad: pad receiving the event
11902
 
+ * @event: received event
11903
 
+ * @u_data: not used
11904
 
+ *
11905
 
+ * Event probe that drop all eos events.
11906
 
+ *
11907
 
+ * Returns: FALSE to drop the event, TRUE otherwise
11908
 
+ */
11909
 
+gboolean
11910
 
+gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data)
11911
 
+{
11912
 
+  gboolean ret = TRUE;
11913
 
+
11914
 
+  switch (GST_EVENT_TYPE (event)) {
11915
 
+    case GST_EVENT_EOS:
11916
 
+      GST_DEBUG ("dropping eos in %s:%s", GST_DEBUG_PAD_NAME (pad));
11917
 
+      ret = FALSE;
11918
 
+      break;
11919
 
+    default:
11920
 
+      break;
11921
 
+  }
11922
 
+  return ret;
11923
 
+}
11924
 
Index: trunk/gst/camerabin2/camerabingeneral.h
 
12090
Index: gst-plugins-good0.10/gst/camerabin2/camerabingeneral.h
11925
12091
===================================================================
11926
 
--- /dev/null
11927
 
+++ trunk/gst/camerabin2/camerabingeneral.h
11928
 
@@ -0,0 +1,39 @@
 
12092
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
12093
+++ gst-plugins-good0.10/gst/camerabin2/camerabingeneral.h      2012-02-09 14:44:27.404710917 +0200
 
12094
@@ -0,0 +1,37 @@
11929
12095
+/*
11930
12096
+ * GStreamer
11931
12097
+ * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org>
11962
12128
+
11963
12129
+void gst_camerabin_remove_elements_from_bin (GstBin * bin);
11964
12130
+
11965
 
+gboolean gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data);
11966
 
+
11967
12131
+#endif /* #ifndef __CAMERABIN_GENERAL_H_ */
11968
 
Index: trunk/gst/camerabin2/gstcamerabin2.c
 
12132
Index: gst-plugins-good0.10/gst/camerabin2/gstcamerabin2.c
11969
12133
===================================================================
11970
 
--- /dev/null
11971
 
+++ trunk/gst/camerabin2/gstcamerabin2.c
11972
 
@@ -0,0 +1,1610 @@
 
12134
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
12135
+++ gst-plugins-good0.10/gst/camerabin2/gstcamerabin2.c 2012-02-09 14:44:27.408711038 +0200
 
12136
@@ -0,0 +1,2430 @@
11973
12137
+/* GStreamer
11974
12138
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
11975
12139
+ *
11989
12153
+ * Boston, MA 02111-1307, USA.
11990
12154
+ */
11991
12155
+/**
11992
 
+ * SECTION:element-gstcamerabin2
11993
 
+ *
11994
 
+ * The gstcamerabin2 element does FIXME stuff.
11995
 
+ *
11996
 
+ * Note that camerabin2 is still UNSTABLE, EXPERIMENTAL and under heavy
 
12156
+ * SECTION:element-camerabin2
 
12157
+ *
 
12158
+ * CameraBin2 is a high-level camera object that encapsulates gstreamer
 
12159
+ * elements, providing an API for controlling a digital camera.
 
12160
+ *
 
12161
+ * <note>
 
12162
+ * Note that camerabin2 is still UNSTABLE and under
11997
12163
+ * development.
 
12164
+ * </note>
 
12165
+ *
 
12166
+ * CameraBin2 has the following main features:
 
12167
+ * <itemizedlist>
 
12168
+ * <listitem>
 
12169
+ * Record videos
 
12170
+ * </listitem>
 
12171
+ * <listitem>
 
12172
+ * Capture pictures
 
12173
+ * </listitem>
 
12174
+ * <listitem>
 
12175
+ * Display a viewfinder
 
12176
+ * </listitem>
 
12177
+ * <listitem>
 
12178
+ * Post preview images for each capture (video and image)
 
12179
+ * </listitem>
 
12180
+ * </itemizedlist>
 
12181
+ *
 
12182
+ * <refsect2>
 
12183
+ * <title>Usage</title>
 
12184
+ * <para>
 
12185
+ * Camerabin2 can be created using gst_element_factory_make() just like
 
12186
+ * any other element. Video or image capture mode can be selected using
 
12187
+ * the #GstCameraBin2:mode property and the file to save the capture is
 
12188
+ * selected using #GstCameraBin2:location property.
 
12189
+ *
 
12190
+ * After creating camerabin2, applications might want to do some
 
12191
+ * customization (there's a section about this below), then select
 
12192
+ * the desired mode and start capturing.
 
12193
+ *
 
12194
+ * In image capture mode, just send a #GstCameraBin:start-capture and a
 
12195
+ * picture will be captured. When the picture is stored on the selected
 
12196
+ * location, a %GST_MESSAGE_ELEMENT named 'image-done' will be posted on
 
12197
+ * the #GstBus.
 
12198
+ *
 
12199
+ * In video capture mode, send a #GstCameraBin2:start-capture to start
 
12200
+ * recording, then send a #GstCameraBin2:stop-capture to stop recording.
 
12201
+ * Note that both signals are asynchronous, so, calling
 
12202
+ * #GstCameraBin2:stop-capture doesn't guarantee that the video has been
 
12203
+ * properly finished yet. Applications should wait for the 'video-done'
 
12204
+ * message to be posted on the bus.
 
12205
+ *
 
12206
+ * In both modes, if #GstCameraBin2:post-previews is %TRUE, a #GstBuffer
 
12207
+ * will be post to the #GstBus in a field named 'buffer', in a
 
12208
+ * 'preview-image' message of type %GST_MESSAGE_ELEMENT.
 
12209
+ * </para>
 
12210
+ * </refsect2>
 
12211
+
 
12212
+ * <refsect2>
 
12213
+ * <title>Customization</title>
 
12214
+ * <para>
 
12215
+ * Camerabin2 provides various customization properties, allowing the user
 
12216
+ * to set custom filters, selecting the viewfinder sink and formats to
 
12217
+ * use to encode the captured images/videos.
 
12218
+ *
 
12219
+ * #GstEncodingProfile<!-- -->s are used to tell camerabin2 which formats it
 
12220
+ * should encode the captures to, those should be set to
 
12221
+ * #GstCameraBin2:image-profile and #GstCameraBin2:video-profile. Default is
 
12222
+ * jpeg for images, and ogg (theora and vorbis) for video. If a profile without
 
12223
+ * an audio stream is set for video, audio will be disabled on recordings.
 
12224
+ *
 
12225
+ * #GstCameraBin2:preview-caps can be used to select which format preview
 
12226
+ * images should be posted on the #GstBus. It has to be a raw video format.
 
12227
+ *
 
12228
+ * Camerabin2 has a #GstCameraBin2:camera-source property so applications can
 
12229
+ * set their source that will provide buffers for the viewfinder and for
 
12230
+ * captures. This camera source is a special type of source that has 3 pads.
 
12231
+ * To use a 'regular' source with a single pad you should use
 
12232
+ * #GstWrapperCameraBinSource, it will adapt your source and provide 3 pads.
 
12233
+ *
 
12234
+ * Applications can also select the desired viewfinder sink using
 
12235
+ * #GstCameraBin2:viewfinder-sink, it is also possible to select the audio
 
12236
+ * source using #GstCameraBin2:audio-source.
 
12237
+ *
 
12238
+ * The viewfinder resolution can be configured using
 
12239
+ * #GstCameraBin2:viewfinder-caps, these #GstCaps should be a subset of
 
12240
+ * #GstCameraBin2:viewfinder-supported-caps.
 
12241
+ *
 
12242
+ * To select the desired resolution for captures, camerabin2 provides
 
12243
+ * #GstCameraBin2:image-capture-caps and #GstCameraBin2:video-capture-caps,
 
12244
+ * these caps must be a subset of what the source can produce. The allowed
 
12245
+ * caps can be probed using #GstCameraBin2:image-capture-supported-caps and
 
12246
+ * #GstCameraBin2:video-capture-supported-caps. In an analogous way, there
 
12247
+ * are #GstCameraBin2:audio-capture-caps and
 
12248
+ * #GstCameraBin2:audio-capture-supported-caps.
 
12249
+ *
 
12250
+ * Camerabin2 also allows applications to insert custom #GstElements on any
 
12251
+ * of its branches: video capture, image capture, viewfinder and preview.
 
12252
+ * Check #GstCameraBin2:video-filter, #GstCameraBin2:image-filter,
 
12253
+ * #GstCameraBin2:viewfinder-filter and #GstCameraBin2:preview-filter.
 
12254
+ * </para>
 
12255
+ * </refsect2>
 
12256
+ *
 
12257
+ * <refsect2>
 
12258
+ * <title>Example launch line</title>
 
12259
+ * <para>
 
12260
+ * Unfortunatelly, camerabin2 can't be really used from gst-launch, as you need
 
12261
+ * to send signals to control it. The following pipeline might be able
 
12262
+ * to show the viewfinder using all the default elements.
 
12263
+ * |[
 
12264
+ * gst-launch -v -m camerabin2
 
12265
+ * ]|
 
12266
+ * </para>
 
12267
+ * </refsect2>
 
12268
+
11998
12269
+ */
11999
12270
+
12000
12271
+/*
12028
12299
+
12029
12300
+#include <gst/basecamerabinsrc/gstbasecamerasrc.h>
12030
12301
+#include "gstcamerabin2.h"
12031
 
+
12032
 
+#define GST_CAMERA_BIN_PROCESSING_INC(c)                                \
 
12302
+#include <gst/gst-i18n-plugin.h>
 
12303
+#include <gst/pbutils/pbutils.h>
 
12304
+
 
12305
+#if GLIB_CHECK_VERSION(2,29,6)
 
12306
+#define gst_camerabin2_atomic_int_add g_atomic_int_add
 
12307
+#else
 
12308
+#define gst_camerabin2_atomic_int_add g_atomic_int_exchange_and_add
 
12309
+#endif
 
12310
+
 
12311
+#define GST_CAMERA_BIN2_PROCESSING_INC(c)                                \
12033
12312
+{                                                                       \
12034
 
+  gint bef = g_atomic_int_exchange_and_add (&c->processing_counter, 1); \
 
12313
+  gint bef = gst_camerabin2_atomic_int_add (&c->processing_counter, 1); \
12035
12314
+  if (bef == 0)                                                         \
12036
12315
+    g_object_notify (G_OBJECT (c), "idle");                             \
12037
12316
+  GST_DEBUG_OBJECT ((c), "Processing counter incremented to: %d",       \
12038
12317
+      bef + 1);                                                         \
12039
12318
+}
12040
12319
+
12041
 
+#define GST_CAMERA_BIN_PROCESSING_DEC(c)                                \
 
12320
+#define GST_CAMERA_BIN2_PROCESSING_DEC(c)                                \
12042
12321
+{                                                                       \
12043
 
+  if (g_atomic_int_dec_and_test (&c->processing_counter))               \
 
12322
+  if (g_atomic_int_dec_and_test (&c->processing_counter)) {             \
12044
12323
+    g_object_notify (G_OBJECT (c), "idle");                             \
 
12324
+    GST_DEBUG_OBJECT ((c), "Camerabin now idle");                      \
 
12325
+  }                                                                    \
12045
12326
+  GST_DEBUG_OBJECT ((c), "Processing counter decremented");             \
12046
12327
+}
12047
12328
+
12048
 
+#define GST_CAMERA_BIN_RESET_PROCESSING_COUNTER(c)                      \
 
12329
+#define GST_CAMERA_BIN2_RESET_PROCESSING_COUNTER(c)                      \
12049
12330
+{                                                                       \
12050
12331
+  g_atomic_int_set (&c->processing_counter, 0);                         \
12051
12332
+  GST_DEBUG_OBJECT ((c), "Processing counter reset");                   \
12082
12363
+  PROP_AUDIO_CAPTURE_CAPS,
12083
12364
+  PROP_ZOOM,
12084
12365
+  PROP_MAX_ZOOM,
12085
 
+  PROP_IMAGE_CAPTURE_ENCODER,
12086
 
+  PROP_IMAGE_CAPTURE_MUXER,
12087
 
+  PROP_IDLE
 
12366
+  PROP_IMAGE_ENCODING_PROFILE,
 
12367
+  PROP_IDLE,
 
12368
+  PROP_FLAGS,
 
12369
+  PROP_AUDIO_FILTER
12088
12370
+};
12089
12371
+
12090
12372
+enum
12098
12380
+static guint camerabin_signals[LAST_SIGNAL];
12099
12381
+
12100
12382
+#define DEFAULT_MODE MODE_IMAGE
12101
 
+#define DEFAULT_VID_LOCATION "vid_%d"
12102
 
+#define DEFAULT_IMG_LOCATION "img_%d"
12103
 
+#define DEFAULT_POST_PREVIEWS TRUE
 
12383
+#define DEFAULT_LOCATION "cap_%d"
 
12384
+#define DEFAULT_POST_PREVIEWS FALSE
12104
12385
+#define DEFAULT_MUTE_AUDIO FALSE
12105
12386
+#define DEFAULT_IDLE TRUE
 
12387
+#define DEFAULT_FLAGS 0
12106
12388
+
12107
12389
+#define DEFAULT_AUDIO_SRC "autoaudiosrc"
12108
12390
+
12112
12394
+ ********************************/
12113
12395
+
12114
12396
+static GstPipelineClass *parent_class;
12115
 
+static void gst_camera_bin_class_init (GstCameraBinClass * klass);
 
12397
+static void gst_camera_bin_class_init (GstCameraBin2Class * klass);
12116
12398
+static void gst_camera_bin_base_init (gpointer klass);
12117
 
+static void gst_camera_bin_init (GstCameraBin * camera);
 
12399
+static void gst_camera_bin_init (GstCameraBin2 * camera);
12118
12400
+static void gst_camera_bin_dispose (GObject * object);
12119
12401
+static void gst_camera_bin_finalize (GObject * object);
12120
12402
+
12121
12403
+static void gst_camera_bin_handle_message (GstBin * bin, GstMessage * message);
 
12404
+static gboolean gst_camera_bin_send_event (GstElement * element,
 
12405
+    GstEvent * event);
 
12406
+
 
12407
+#define C_FLAGS(v) ((guint) v)
 
12408
+#define GST_TYPE_CAM_FLAGS (gst_cam_flags_get_type())
 
12409
+static GType
 
12410
+gst_cam_flags_get_type (void)
 
12411
+{
 
12412
+  static const GFlagsValue values[] = {
 
12413
+    {C_FLAGS (GST_CAM_FLAG_NO_AUDIO_CONVERSION), "Do not use audio conversion "
 
12414
+          "elements", "no-audio-conversion"},
 
12415
+    {C_FLAGS (GST_CAM_FLAG_NO_VIDEO_CONVERSION), "Do not use video conversion "
 
12416
+          "elements", "no-video-conversion"},
 
12417
+    {C_FLAGS (GST_CAM_FLAG_NO_VIEWFINDER_CONVERSION),
 
12418
+          "Do not use viewfinder conversion " "elements",
 
12419
+        "no-viewfinder-conversion"},
 
12420
+    {C_FLAGS (GST_CAM_FLAG_NO_IMAGE_CONVERSION), "Do not use image conversion "
 
12421
+          "elements", "no-image-conversion"},
 
12422
+    {0, NULL, NULL}
 
12423
+  };
 
12424
+  static volatile GType id = 0;
 
12425
+
 
12426
+  if (g_once_init_enter ((gsize *) & id)) {
 
12427
+    GType _id;
 
12428
+
 
12429
+    _id = g_flags_register_static ("GstCamFlags", values);
 
12430
+
 
12431
+    g_once_init_leave ((gsize *) & id, _id);
 
12432
+  }
 
12433
+
 
12434
+  return id;
 
12435
+}
12122
12436
+
12123
12437
+GType
12124
 
+gst_camera_bin_get_type (void)
 
12438
+gst_camera_bin2_get_type (void)
12125
12439
+{
12126
12440
+  static GType gst_camera_bin_type = 0;
12127
12441
+  static const GInterfaceInfo camerabin_tagsetter_info = {
12132
12446
+
12133
12447
+  if (!gst_camera_bin_type) {
12134
12448
+    static const GTypeInfo gst_camera_bin_info = {
12135
 
+      sizeof (GstCameraBinClass),
 
12449
+      sizeof (GstCameraBin2Class),
12136
12450
+      (GBaseInitFunc) gst_camera_bin_base_init,
12137
12451
+      NULL,
12138
12452
+      (GClassInitFunc) gst_camera_bin_class_init,
12139
12453
+      NULL,
12140
12454
+      NULL,
12141
 
+      sizeof (GstCameraBin),
 
12455
+      sizeof (GstCameraBin2),
12142
12456
+      0,
12143
12457
+      (GInstanceInitFunc) gst_camera_bin_init,
12144
12458
+      NULL
12175
12489
+      gst_structure_new ("renegotiate", NULL));
12176
12490
+}
12177
12491
+
 
12492
+static GstEvent *
 
12493
+gst_camera_bin_new_event_file_location (const gchar * location)
 
12494
+{
 
12495
+  return gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
 
12496
+      gst_structure_new ("new-location", "location", G_TYPE_STRING, location,
 
12497
+          NULL));
 
12498
+}
 
12499
+
12178
12500
+static void
12179
 
+gst_camera_bin_start_capture (GstCameraBin * camerabin)
 
12501
+gst_camera_bin_start_capture (GstCameraBin2 * camerabin)
12180
12502
+{
12181
12503
+  const GstTagList *taglist;
12182
 
+
 
12504
+  gint capture_index = camerabin->capture_index;
 
12505
+  gchar *location = NULL;
12183
12506
+  GST_DEBUG_OBJECT (camerabin, "Received start-capture");
12184
 
+  GST_CAMERA_BIN_PROCESSING_INC (camerabin);
12185
 
+
 
12507
+
 
12508
+  /* check that we have a valid location */
 
12509
+  if (camerabin->mode == MODE_VIDEO) {
 
12510
+    if (camerabin->location == NULL) {
 
12511
+      GST_ELEMENT_ERROR (camerabin, RESOURCE, OPEN_WRITE,
 
12512
+          (_("File location is set to NULL, please set it to a valid filename")), (NULL));
 
12513
+      return;
 
12514
+    }
 
12515
+
 
12516
+    g_mutex_lock (camerabin->video_capture_mutex);
 
12517
+    while (camerabin->video_state == GST_CAMERA_BIN_VIDEO_FINISHING) {
 
12518
+      g_cond_wait (camerabin->video_state_cond, camerabin->video_capture_mutex);
 
12519
+    }
 
12520
+    if (camerabin->video_state != GST_CAMERA_BIN_VIDEO_IDLE) {
 
12521
+      GST_WARNING_OBJECT (camerabin, "Another video recording is ongoing"
 
12522
+          " (state %d), cannot start a new one", camerabin->video_state);
 
12523
+      g_mutex_unlock (camerabin->video_capture_mutex);
 
12524
+      return;
 
12525
+    }
 
12526
+    camerabin->video_state = GST_CAMERA_BIN_VIDEO_STARTING;
 
12527
+  }
 
12528
+
 
12529
+  GST_CAMERA_BIN2_PROCESSING_INC (camerabin);
 
12530
+
 
12531
+  if (camerabin->location)
 
12532
+    location = g_strdup_printf (camerabin->location, capture_index);
 
12533
+
 
12534
+  if (camerabin->mode == MODE_VIDEO) {
 
12535
+    if (camerabin->audio_src) {
 
12536
+      GstClock *clock = gst_pipeline_get_clock (GST_PIPELINE_CAST (camerabin));
 
12537
+
 
12538
+      gst_element_set_state (camerabin->audio_src, GST_STATE_PAUSED);
 
12539
+
 
12540
+      gst_element_set_base_time (camerabin->audio_src,
 
12541
+          gst_element_get_base_time (GST_ELEMENT_CAST (camerabin)));
 
12542
+      if (clock) {
 
12543
+        gst_element_set_clock (camerabin->audio_src, clock);
 
12544
+        gst_object_unref (clock);
 
12545
+      }
 
12546
+    }
 
12547
+  } else {
 
12548
+    /* store the next capture buffer filename */
 
12549
+    g_mutex_lock (camerabin->image_capture_mutex);
 
12550
+    camerabin->image_location_list =
 
12551
+        g_slist_append (camerabin->image_location_list, g_strdup (location));
 
12552
+    g_mutex_unlock (camerabin->image_capture_mutex);
 
12553
+  }
 
12554
+
 
12555
+  if (camerabin->post_previews) {
 
12556
+    /* Count processing of preview images too */
 
12557
+    GST_CAMERA_BIN2_PROCESSING_INC (camerabin);
 
12558
+    /* store the next preview filename */
 
12559
+    g_mutex_lock (camerabin->preview_list_mutex);
 
12560
+    camerabin->preview_location_list =
 
12561
+        g_slist_append (camerabin->preview_location_list, location);
 
12562
+    g_mutex_unlock (camerabin->preview_list_mutex);
 
12563
+  } else {
 
12564
+    g_free (location);
 
12565
+  }
 
12566
+
 
12567
+  g_signal_emit_by_name (camerabin->src, "start-capture", NULL);
 
12568
+  if (camerabin->mode == MODE_VIDEO) {
 
12569
+    camerabin->audio_send_newseg = TRUE;
 
12570
+    if (camerabin->audio_src)
 
12571
+      gst_element_set_state (camerabin->audio_src, GST_STATE_PLAYING);
 
12572
+
 
12573
+    camerabin->video_state = GST_CAMERA_BIN_VIDEO_RECORDING;
 
12574
+    g_mutex_unlock (camerabin->video_capture_mutex);
 
12575
+  }
 
12576
+
 
12577
+  /*
 
12578
+   * We have to push tags after start capture because the video elements
 
12579
+   * might be flushing from the previous capture and are reset only on the
 
12580
+   * notify from ready for capture going to FALSE
 
12581
+   */
12186
12582
+  taglist = gst_tag_setter_get_tag_list (GST_TAG_SETTER (camerabin));
12187
 
+  if (taglist) {
 
12583
+  GST_DEBUG_OBJECT (camerabin, "Have tags from application: %"
 
12584
+      GST_PTR_FORMAT, taglist);
 
12585
+
 
12586
+  if (camerabin->mode == MODE_IMAGE) {
 
12587
+    /* Store image tags in a list and push them later, this prevents
 
12588
+       start_capture() from blocking in pad_push_event call */
 
12589
+    g_mutex_lock (camerabin->image_capture_mutex);
 
12590
+    camerabin->image_tags_list =
 
12591
+        g_slist_append (camerabin->image_tags_list,
 
12592
+        taglist ? gst_tag_list_copy (taglist) : NULL);
 
12593
+    g_mutex_unlock (camerabin->image_capture_mutex);
 
12594
+  } else if (taglist) {
12188
12595
+    GstPad *active_pad;
12189
12596
+
12190
 
+    GST_DEBUG_OBJECT (camerabin, "Pushing tags from application: %"
12191
 
+        GST_PTR_FORMAT, taglist);
12192
 
+
12193
 
+    if (camerabin->mode == MODE_IMAGE) {
12194
 
+      active_pad = gst_element_get_static_pad (camerabin->src,
12195
 
+          GST_BASE_CAMERA_SRC_IMAGE_PAD_NAME);
12196
 
+    } else {
12197
 
+      active_pad = gst_element_get_static_pad (camerabin->src,
12198
 
+          GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
12199
 
+    }
12200
 
+
 
12597
+    active_pad = gst_element_get_static_pad (camerabin->src,
 
12598
+        GST_BASE_CAMERA_SRC_VIDEO_PAD_NAME);
12201
12599
+    gst_pad_push_event (active_pad,
12202
12600
+        gst_event_new_tag (gst_tag_list_copy (taglist)));
 
12601
+
12203
12602
+    gst_object_unref (active_pad);
12204
12603
+  }
12205
12604
+
12206
 
+  if (camerabin->mode == MODE_VIDEO && camerabin->audio_src) {
12207
 
+    gst_element_set_state (camerabin->audio_src, GST_STATE_READY);
12208
 
+    /* need to reset eos status (pads could be flushing) */
12209
 
+    gst_element_set_state (camerabin->audio_queue, GST_STATE_READY);
12210
 
+    gst_element_set_state (camerabin->audio_convert, GST_STATE_READY);
12211
 
+    gst_element_set_state (camerabin->audio_capsfilter, GST_STATE_READY);
12212
 
+    gst_element_set_state (camerabin->audio_volume, GST_STATE_READY);
12213
 
+
12214
 
+    gst_element_sync_state_with_parent (camerabin->audio_queue);
12215
 
+    gst_element_sync_state_with_parent (camerabin->audio_convert);
12216
 
+    gst_element_sync_state_with_parent (camerabin->audio_capsfilter);
12217
 
+    gst_element_sync_state_with_parent (camerabin->audio_volume);
12218
 
+  }
12219
 
+
12220
 
+  g_signal_emit_by_name (camerabin->src, "start-capture", NULL);
12221
 
+  if (camerabin->mode == MODE_VIDEO && camerabin->audio_src)
12222
 
+    gst_element_set_state (camerabin->audio_src, GST_STATE_PLAYING);
 
12605
+  GST_DEBUG_OBJECT (camerabin, "Start-capture end");
12223
12606
+}
12224
12607
+
12225
12608
+static void
12226
 
+gst_camera_bin_stop_capture (GstCameraBin * camerabin)
 
12609
+gst_camera_bin_stop_capture (GstCameraBin2 * camerabin)
12227
12610
+{
12228
12611
+  GST_DEBUG_OBJECT (camerabin, "Received stop-capture");
12229
 
+  if (camerabin->src)
12230
 
+    g_signal_emit_by_name (camerabin->src, "stop-capture", NULL);
 
12612
+  if (camerabin->mode == MODE_VIDEO) {
 
12613
+    g_mutex_lock (camerabin->video_capture_mutex);
 
12614
+    if (camerabin->video_state == GST_CAMERA_BIN_VIDEO_RECORDING) {
 
12615
+      if (camerabin->src)
 
12616
+        g_signal_emit_by_name (camerabin->src, "stop-capture", NULL);
12231
12617
+
12232
 
+  if (camerabin->mode == MODE_VIDEO && camerabin->audio_src) {
12233
 
+    gst_element_send_event (camerabin->audio_src, gst_event_new_eos ());
 
12618
+      camerabin->video_state = GST_CAMERA_BIN_VIDEO_FINISHING;
 
12619
+      if (camerabin->audio_src) {
 
12620
+        camerabin->audio_drop_eos = FALSE;
 
12621
+        gst_element_send_event (camerabin->audio_src, gst_event_new_eos ());
 
12622
+      }
 
12623
+    }
 
12624
+    g_mutex_unlock (camerabin->video_capture_mutex);
12234
12625
+  }
12235
12626
+}
12236
12627
+
12237
12628
+static void
12238
 
+gst_camera_bin_change_mode (GstCameraBin * camerabin, gint mode)
 
12629
+gst_camera_bin_change_mode (GstCameraBin2 * camerabin, gint mode)
12239
12630
+{
12240
12631
+  if (mode == camerabin->mode)
12241
12632
+    return;
12253
12644
+gst_camera_bin_src_notify_readyforcapture (GObject * obj, GParamSpec * pspec,
12254
12645
+    gpointer user_data)
12255
12646
+{
12256
 
+  GstCameraBin *camera = GST_CAMERA_BIN_CAST (user_data);
 
12647
+  GstCameraBin2 *camera = GST_CAMERA_BIN2_CAST (user_data);
12257
12648
+  gboolean ready;
12258
12649
+
12259
 
+  if (camera->mode == MODE_VIDEO) {
12260
 
+    g_object_get (camera->src, "ready-for-capture", &ready, NULL);
12261
 
+    if (!ready) {
12262
 
+      gchar *location;
 
12650
+  g_object_get (camera->src, "ready-for-capture", &ready, NULL);
 
12651
+  if (!ready) {
 
12652
+    gchar *location = NULL;
12263
12653
+
12264
 
+      /* a video recording is about to start, we reset the videobin to clear eos/flushing state
12265
 
+       * also need to clean the queue ! capsfilter before it */
12266
 
+      gst_element_set_state (camera->encodebin, GST_STATE_NULL);
 
12654
+    if (camera->mode == MODE_VIDEO) {
 
12655
+      /* a video recording is about to start, change the filesink location */
12267
12656
+      gst_element_set_state (camera->videosink, GST_STATE_NULL);
12268
 
+      gst_element_set_state (camera->videobin_queue, GST_STATE_NULL);
12269
 
+      gst_element_set_state (camera->videobin_capsfilter, GST_STATE_NULL);
12270
 
+      location =
12271
 
+          g_strdup_printf (camera->video_location, camera->video_index++);
 
12657
+      location = g_strdup_printf (camera->location, camera->capture_index);
12272
12658
+      GST_DEBUG_OBJECT (camera, "Switching videobin location to %s", location);
12273
12659
+      g_object_set (camera->videosink, "location", location, NULL);
12274
12660
+      g_free (location);
12275
 
+      gst_element_set_state (camera->encodebin, GST_STATE_PLAYING);
12276
 
+      gst_element_set_state (camera->videosink, GST_STATE_PLAYING);
12277
 
+      gst_element_set_state (camera->videobin_capsfilter, GST_STATE_PLAYING);
12278
 
+      gst_element_set_state (camera->videobin_queue, GST_STATE_PLAYING);
 
12661
+      if (gst_element_set_state (camera->videosink, GST_STATE_PLAYING) ==
 
12662
+          GST_STATE_CHANGE_FAILURE) {
 
12663
+        /* Resets the latest state change return, that would be a failure
 
12664
+         * and could cause problems in a camerabin2 state change */
 
12665
+        gst_element_set_state (camera->videosink, GST_STATE_NULL);
 
12666
+      }
12279
12667
+    }
 
12668
+
 
12669
+    camera->capture_index++;
12280
12670
+  }
12281
12671
+}
12282
12672
+
12283
12673
+static void
12284
12674
+gst_camera_bin_dispose (GObject * object)
12285
12675
+{
12286
 
+  GstCameraBin *camerabin = GST_CAMERA_BIN_CAST (object);
 
12676
+  GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (object);
12287
12677
+
12288
 
+  g_free (camerabin->image_location);
12289
 
+  g_free (camerabin->video_location);
 
12678
+  g_free (camerabin->location);
 
12679
+  g_mutex_free (camerabin->preview_list_mutex);
 
12680
+  g_mutex_free (camerabin->image_capture_mutex);
 
12681
+  g_mutex_free (camerabin->video_capture_mutex);
 
12682
+  g_cond_free (camerabin->video_state_cond);
12290
12683
+
12291
12684
+  if (camerabin->src_capture_notify_id)
12292
12685
+    g_signal_handler_disconnect (camerabin->src,
12303
12696
+
12304
12697
+  if (camerabin->audio_capsfilter)
12305
12698
+    gst_object_unref (camerabin->audio_capsfilter);
12306
 
+  if (camerabin->audio_queue)
12307
 
+    gst_object_unref (camerabin->audio_queue);
12308
 
+  if (camerabin->audio_convert)
12309
 
+    gst_object_unref (camerabin->audio_convert);
12310
12699
+  if (camerabin->audio_volume)
12311
12700
+    gst_object_unref (camerabin->audio_volume);
12312
12701
+
12317
12706
+  if (camerabin->viewfinderbin_capsfilter)
12318
12707
+    gst_object_unref (camerabin->viewfinderbin_capsfilter);
12319
12708
+
12320
 
+  if (camerabin->encodebin_signal_id)
12321
 
+    g_signal_handler_disconnect (camerabin->encodebin,
12322
 
+        camerabin->encodebin_signal_id);
12323
 
+
12324
 
+  if (camerabin->videosink_probe) {
12325
 
+    GstPad *pad = gst_element_get_static_pad (camerabin->videosink, "sink");
12326
 
+    gst_pad_remove_data_probe (pad, camerabin->videosink_probe);
12327
 
+    gst_object_unref (pad);
12328
 
+  }
 
12709
+  if (camerabin->video_encodebin_signal_id)
 
12710
+    g_signal_handler_disconnect (camerabin->video_encodebin,
 
12711
+        camerabin->video_encodebin_signal_id);
12329
12712
+
12330
12713
+  if (camerabin->videosink)
12331
12714
+    gst_object_unref (camerabin->videosink);
12332
 
+  if (camerabin->encodebin)
12333
 
+    gst_object_unref (camerabin->encodebin);
12334
 
+  if (camerabin->videobin_queue)
12335
 
+    gst_object_unref (camerabin->videobin_queue);
 
12715
+  if (camerabin->video_encodebin)
 
12716
+    gst_object_unref (camerabin->video_encodebin);
12336
12717
+  if (camerabin->videobin_capsfilter)
12337
12718
+    gst_object_unref (camerabin->videobin_capsfilter);
12338
12719
+
12339
 
+  if (camerabin->imagebin)
12340
 
+    gst_object_unref (camerabin->imagebin);
12341
 
+  if (camerabin->imagebin_queue)
12342
 
+    gst_object_unref (camerabin->imagebin_queue);
 
12720
+  if (camerabin->image_encodebin_signal_id)
 
12721
+    g_signal_handler_disconnect (camerabin->image_encodebin,
 
12722
+        camerabin->image_encodebin_signal_id);
 
12723
+  if (camerabin->imagesink)
 
12724
+    gst_object_unref (camerabin->imagesink);
 
12725
+  if (camerabin->image_encodebin)
 
12726
+    gst_object_unref (camerabin->image_encodebin);
12343
12727
+  if (camerabin->imagebin_capsfilter)
12344
12728
+    gst_object_unref (camerabin->imagebin_capsfilter);
12345
12729
+
12349
12733
+    gst_object_unref (camerabin->image_filter);
12350
12734
+  if (camerabin->viewfinder_filter)
12351
12735
+    gst_object_unref (camerabin->viewfinder_filter);
 
12736
+  if (camerabin->audio_filter)
 
12737
+    gst_object_unref (camerabin->audio_filter);
12352
12738
+
12353
12739
+  if (camerabin->user_video_filter)
12354
12740
+    gst_object_unref (camerabin->user_video_filter);
 
12741
+  if (camerabin->user_audio_filter)
 
12742
+    gst_object_unref (camerabin->user_audio_filter);
12355
12743
+  if (camerabin->user_image_filter)
12356
12744
+    gst_object_unref (camerabin->user_image_filter);
12357
12745
+  if (camerabin->user_viewfinder_filter)
12359
12747
+
12360
12748
+  if (camerabin->video_profile)
12361
12749
+    gst_encoding_profile_unref (camerabin->video_profile);
 
12750
+  if (camerabin->image_profile)
 
12751
+    gst_encoding_profile_unref (camerabin->image_profile);
12362
12752
+
12363
12753
+  if (camerabin->preview_caps)
12364
12754
+    gst_caps_replace (&camerabin->preview_caps, NULL);
12387
12777
+}
12388
12778
+
12389
12779
+static void
12390
 
+gst_camera_bin_class_init (GstCameraBinClass * klass)
 
12780
+gst_camera_bin_class_init (GstCameraBin2Class * klass)
12391
12781
+{
12392
12782
+  GObjectClass *object_class;
12393
12783
+  GstElementClass *element_class;
12404
12794
+  object_class->get_property = gst_camera_bin_get_property;
12405
12795
+
12406
12796
+  element_class->change_state = GST_DEBUG_FUNCPTR (gst_camera_bin_change_state);
 
12797
+  element_class->send_event = GST_DEBUG_FUNCPTR (gst_camera_bin_send_event);
12407
12798
+
12408
12799
+  bin_class->handle_message = gst_camera_bin_handle_message;
12409
12800
+
12411
12802
+  klass->stop_capture = gst_camera_bin_stop_capture;
12412
12803
+
12413
12804
+  /**
12414
 
+   * GstCameraBin:mode:
 
12805
+   * GstCameraBin2:mode:
12415
12806
+   *
12416
12807
+   * Set the mode of operation: still image capturing or video recording.
12417
12808
+   */
12425
12816
+      g_param_spec_string ("location", "Location",
12426
12817
+          "Location to save the captured files. A %d might be used on the"
12427
12818
+          "filename as a placeholder for a numeric index of the capture."
12428
 
+          "Default for images is img_%d and vid_%d for videos",
12429
 
+          DEFAULT_IMG_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
12819
+          "Default is cap_%d",
 
12820
+          DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12430
12821
+
12431
12822
+  g_object_class_install_property (object_class, PROP_CAMERA_SRC,
12432
 
+      g_param_spec_object ("camera-src", "Camera source",
12433
 
+          "The camera source element to be used",
 
12823
+      g_param_spec_object ("camera-source", "Camera source",
 
12824
+          "The camera source element to be used. It is only taken into use on"
 
12825
+          " the next null to ready transition",
12434
12826
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12435
12827
+
12436
12828
+  g_object_class_install_property (object_class, PROP_AUDIO_SRC,
12437
 
+      g_param_spec_object ("audio-src", "Audio source",
12438
 
+          "The audio source element to be used on video recordings",
 
12829
+      g_param_spec_object ("audio-source", "Audio source",
 
12830
+          "The audio source element to be used on video recordings. It is only"
 
12831
+          " taken into use on the next null to ready transition",
12439
12832
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12440
12833
+
12441
12834
+  g_object_class_install_property (object_class, PROP_MUTE_AUDIO,
12521
12914
+          " (Should be set on NULL state)",
12522
12915
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12523
12916
+
 
12917
+  g_object_class_install_property (object_class, PROP_AUDIO_FILTER,
 
12918
+      g_param_spec_object ("audio-filter", "Audio filter",
 
12919
+          "The element that will process captured audio buffers when recording"
 
12920
+          ". (Should be set on NULL state)",
 
12921
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
12922
+
12524
12923
+  g_object_class_install_property (object_class, PROP_PREVIEW_FILTER,
12525
12924
+      g_param_spec_object ("preview-filter", "Preview filter",
12526
12925
+          "The element that will process preview buffers."
12529
12928
+
12530
12929
+  g_object_class_install_property (object_class, PROP_VIEWFINDER_SINK,
12531
12930
+      g_param_spec_object ("viewfinder-sink", "Viewfinder sink",
12532
 
+          "The video sink of the viewfinder.",
 
12931
+          "The video sink of the viewfinder. It is only taken into use"
 
12932
+          " on the next null to ready transition",
12533
12933
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12534
12934
+
12535
12935
+  g_object_class_install_property (object_class,
12552
12952
+
12553
12953
+  /* TODO
12554
12954
+   * Review before stable
12555
 
+   * - We use a profile for video recording properties and here we have
12556
 
+   *   elements for image capture. This is slightly inconsistent.
12557
12955
+   * - One problem with using encodebin for images here is how jifmux
12558
12956
+   *   autoplugging works. We need to give it a higher rank and fix its
12559
12957
+   *   caps (it has image/jpeg on sink and src pads). Preliminary tests
12560
12958
+   *   show that jifmux is picked if image/jpeg is the caps of a container
12561
12959
+   *   profile. So this could work.
12562
12960
+   * - There seems to be a problem with encodebin for images currently as
12563
 
+   *   it autoplugs a videorate that ony starts outputing buffers after
 
12961
+   *   it autoplugs a videorate that only starts outputing buffers after
12564
12962
+   *   getting the 2nd buffer.
12565
12963
+   */
12566
 
+  g_object_class_install_property (object_class, PROP_IMAGE_CAPTURE_ENCODER,
12567
 
+      g_param_spec_object ("image-capture-encoder", "Image capture encoder",
12568
 
+          "The image encoder element to be used on image captures.",
12569
 
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
12964
+  g_object_class_install_property (object_class, PROP_IMAGE_ENCODING_PROFILE,
 
12965
+      gst_param_spec_mini_object ("image-profile", "Image Profile",
 
12966
+          "The GstEncodingProfile to use for image captures.",
 
12967
+          GST_TYPE_ENCODING_PROFILE,
 
12968
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12570
12969
+
12571
 
+  g_object_class_install_property (object_class, PROP_IMAGE_CAPTURE_MUXER,
12572
 
+      g_param_spec_object ("image-capture-muxer", "Image capture encoder",
12573
 
+          "The image encoder element to be used on image captures.",
12574
 
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
12575
12970
+
12576
12971
+  g_object_class_install_property (object_class, PROP_IDLE,
12577
12972
+      g_param_spec_boolean ("idle", "Idle",
12593
12988
+          "The caps that the camera source can produce on the viewfinder pad",
12594
12989
+          GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
12595
12990
+
 
12991
+   /**
 
12992
+    * GstCameraBin:flags
 
12993
+    *
 
12994
+    * Control the behaviour of encodebin.
 
12995
+    */
 
12996
+  g_object_class_install_property (object_class, PROP_FLAGS,
 
12997
+      g_param_spec_flags ("flags", "Flags", "Flags to control behaviour",
 
12998
+          GST_TYPE_CAM_FLAGS, DEFAULT_FLAGS,
 
12999
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
13000
+
12596
13001
+  /**
12597
 
+   * GstCameraBin::capture-start:
 
13002
+   * GstCameraBin2::capture-start:
12598
13003
+   * @camera: the camera bin element
12599
13004
+   *
12600
13005
+   * Starts image capture or video recording depending on the Mode.
12603
13008
+      g_signal_new ("start-capture",
12604
13009
+      G_TYPE_FROM_CLASS (klass),
12605
13010
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
12606
 
+      G_STRUCT_OFFSET (GstCameraBinClass, start_capture),
 
13011
+      G_STRUCT_OFFSET (GstCameraBin2Class, start_capture),
12607
13012
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
12608
13013
+
12609
13014
+  /**
12610
 
+   * GstCameraBin::capture-stop:
 
13015
+   * GstCameraBin2::capture-stop:
12611
13016
+   * @camera: the camera bin element
12612
13017
+   */
12613
13018
+  camerabin_signals[STOP_CAPTURE_SIGNAL] =
12614
13019
+      g_signal_new ("stop-capture",
12615
13020
+      G_TYPE_FROM_CLASS (klass),
12616
13021
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
12617
 
+      G_STRUCT_OFFSET (GstCameraBinClass, stop_capture),
 
13022
+      G_STRUCT_OFFSET (GstCameraBin2Class, stop_capture),
12618
13023
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
12619
13024
+}
12620
13025
+
12621
13026
+static void
12622
 
+gst_camera_bin_init (GstCameraBin * camera)
 
13027
+gst_camera_bin_init (GstCameraBin2 * camera)
12623
13028
+{
12624
13029
+  camera->post_previews = DEFAULT_POST_PREVIEWS;
12625
13030
+  camera->mode = DEFAULT_MODE;
12626
 
+  camera->video_location = g_strdup (DEFAULT_VID_LOCATION);
12627
 
+  camera->image_location = g_strdup (DEFAULT_IMG_LOCATION);
 
13031
+  camera->location = g_strdup (DEFAULT_LOCATION);
12628
13032
+  camera->viewfinderbin = gst_element_factory_make ("viewfinderbin", "vf-bin");
12629
 
+  camera->imagebin = gst_element_factory_make ("imagecapturebin", "imagebin");
12630
13033
+  camera->zoom = DEFAULT_ZOOM;
12631
13034
+  camera->max_zoom = MAX_ZOOM;
 
13035
+  camera->flags = DEFAULT_FLAGS;
 
13036
+  camera->preview_list_mutex = g_mutex_new ();
 
13037
+  camera->image_capture_mutex = g_mutex_new ();
 
13038
+  camera->video_capture_mutex = g_mutex_new ();
 
13039
+  camera->video_state_cond = g_cond_new ();
12632
13040
+
12633
13041
+  /* capsfilters are created here as we proxy their caps properties and
12634
13042
+   * this way we avoid having to store the caps while on NULL state to 
12653
13061
+}
12654
13062
+
12655
13063
+static void
12656
 
+gst_image_capture_bin_post_image_done (GstCameraBin * camera,
 
13064
+gst_image_capture_bin_post_image_done (GstCameraBin2 * camera,
12657
13065
+    const gchar * filename)
12658
13066
+{
12659
13067
+  GstMessage *msg;
12669
13077
+}
12670
13078
+
12671
13079
+static void
 
13080
+gst_video_capture_bin_post_video_done (GstCameraBin2 * camera)
 
13081
+{
 
13082
+  GstMessage *msg;
 
13083
+
 
13084
+  msg = gst_message_new_element (GST_OBJECT_CAST (camera),
 
13085
+      gst_structure_new ("video-done", NULL));
 
13086
+
 
13087
+  if (!gst_element_post_message (GST_ELEMENT_CAST (camera), msg))
 
13088
+    GST_WARNING_OBJECT (camera, "Failed to post video-done message");
 
13089
+}
 
13090
+
 
13091
+static void
 
13092
+gst_camera_bin_skip_next_preview (GstCameraBin2 * camerabin)
 
13093
+{
 
13094
+  gchar *location;
 
13095
+
 
13096
+  g_mutex_lock (camerabin->preview_list_mutex);
 
13097
+  if (camerabin->preview_location_list) {
 
13098
+    location = camerabin->preview_location_list->data;
 
13099
+    GST_DEBUG_OBJECT (camerabin, "Skipping preview for %s", location);
 
13100
+    g_free (location);
 
13101
+    camerabin->preview_location_list =
 
13102
+        g_slist_delete_link (camerabin->preview_location_list,
 
13103
+        camerabin->preview_location_list);
 
13104
+    GST_CAMERA_BIN2_PROCESSING_DEC (camerabin);
 
13105
+  } else {
 
13106
+    GST_WARNING_OBJECT (camerabin, "No previews to skip");
 
13107
+  }
 
13108
+  g_mutex_unlock (camerabin->preview_list_mutex);
 
13109
+}
 
13110
+
 
13111
+static gpointer
 
13112
+gst_camera_bin_video_reset_elements (gpointer u_data)
 
13113
+{
 
13114
+  GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (u_data);
 
13115
+
 
13116
+  GST_DEBUG_OBJECT (camerabin, "Resetting video elements state");
 
13117
+  g_mutex_lock (camerabin->video_capture_mutex);
 
13118
+
 
13119
+  /* reset element states to clear eos/flushing pads */
 
13120
+  gst_element_set_state (camerabin->video_encodebin, GST_STATE_READY);
 
13121
+  gst_element_set_state (camerabin->videobin_capsfilter, GST_STATE_READY);
 
13122
+  if (camerabin->video_filter) {
 
13123
+    gst_element_set_state (camerabin->video_filter, GST_STATE_READY);
 
13124
+    gst_element_sync_state_with_parent (camerabin->video_filter);
 
13125
+  }
 
13126
+  gst_element_sync_state_with_parent (camerabin->videobin_capsfilter);
 
13127
+  gst_element_sync_state_with_parent (camerabin->video_encodebin);
 
13128
+
 
13129
+  if (camerabin->audio_src) {
 
13130
+    gst_element_set_state (camerabin->audio_capsfilter, GST_STATE_READY);
 
13131
+    gst_element_set_state (camerabin->audio_volume, GST_STATE_READY);
 
13132
+
 
13133
+    /* FIXME We need to set audiosrc to null to make it resync the ringbuffer
 
13134
+     * while bug https://bugzilla.gnome.org/show_bug.cgi?id=648359 isn't
 
13135
+     * fixed.
 
13136
+     *
 
13137
+     * Also, we don't reinit the audiosrc to keep audio devices from being open
 
13138
+     * and running until we really need them */
 
13139
+    gst_element_set_state (camerabin->audio_src, GST_STATE_NULL);
 
13140
+
 
13141
+    if (camerabin->audio_filter) {
 
13142
+      gst_element_set_state (camerabin->audio_filter, GST_STATE_READY);
 
13143
+      gst_element_sync_state_with_parent (camerabin->audio_filter);
 
13144
+    }
 
13145
+
 
13146
+    gst_element_sync_state_with_parent (camerabin->audio_capsfilter);
 
13147
+    gst_element_sync_state_with_parent (camerabin->audio_volume);
 
13148
+
 
13149
+  }
 
13150
+
 
13151
+  GST_DEBUG_OBJECT (camerabin, "Setting video state to idle");
 
13152
+  camerabin->video_state = GST_CAMERA_BIN_VIDEO_IDLE;
 
13153
+  g_cond_signal (camerabin->video_state_cond);
 
13154
+  g_mutex_unlock (camerabin->video_capture_mutex);
 
13155
+
 
13156
+  gst_object_unref (camerabin);
 
13157
+  return NULL;
 
13158
+}
 
13159
+
 
13160
+static void
12672
13161
+gst_camera_bin_handle_message (GstBin * bin, GstMessage * message)
12673
13162
+{
 
13163
+  GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (bin);
 
13164
+  gboolean dec_counter = FALSE;
 
13165
+
12674
13166
+  switch (GST_MESSAGE_TYPE (message)) {
12675
13167
+    case GST_MESSAGE_ELEMENT:{
12676
13168
+      const GstStructure *structure = gst_message_get_structure (message);
12677
13169
+      const gchar *filename;
12678
13170
+
12679
13171
+      if (gst_structure_has_name (structure, "GstMultiFileSink")) {
12680
 
+        GST_CAMERA_BIN_PROCESSING_DEC (GST_CAMERA_BIN_CAST (bin));
12681
13172
+        filename = gst_structure_get_string (structure, "filename");
 
13173
+        GST_DEBUG_OBJECT (bin, "Got file save message from multifilesink, "
 
13174
+            "image %s has been saved", filename);
12682
13175
+        if (filename) {
12683
 
+          gst_image_capture_bin_post_image_done (GST_CAMERA_BIN_CAST (bin),
 
13176
+          gst_image_capture_bin_post_image_done (GST_CAMERA_BIN2_CAST (bin),
12684
13177
+              filename);
12685
13178
+        }
 
13179
+        dec_counter = TRUE;
 
13180
+      } else if (gst_structure_has_name (structure, "preview-image")) {
 
13181
+        gchar *location = NULL;
 
13182
+
 
13183
+        g_mutex_lock (camerabin->preview_list_mutex);
 
13184
+        if (camerabin->preview_location_list) {
 
13185
+          location = camerabin->preview_location_list->data;
 
13186
+          camerabin->preview_location_list =
 
13187
+              g_slist_delete_link (camerabin->preview_location_list,
 
13188
+              camerabin->preview_location_list);
 
13189
+          GST_DEBUG_OBJECT (camerabin, "Adding preview location to preview "
 
13190
+              "message '%s'", location);
 
13191
+        } else {
 
13192
+          GST_WARNING_OBJECT (camerabin, "Unexpected preview message received, "
 
13193
+              "won't be able to put location field into the message. This can "
 
13194
+              "happen if the source is posting previews while camerabin2 is "
 
13195
+              "shutting down");
 
13196
+        }
 
13197
+        g_mutex_unlock (camerabin->preview_list_mutex);
 
13198
+
 
13199
+        if (location) {
 
13200
+          GValue value = { 0 };
 
13201
+          g_value_init (&value, G_TYPE_STRING);
 
13202
+          g_value_take_string (&value, location);
 
13203
+          gst_structure_take_value ((GstStructure *) structure, "location",
 
13204
+              &value);
 
13205
+        }
 
13206
+
 
13207
+        GST_LOG_OBJECT (bin, "received preview-image message");
 
13208
+        dec_counter = TRUE;
12686
13209
+      }
12687
13210
+    }
12688
13211
+      break;
12693
13216
+      gst_message_parse_warning (message, &err, &debug);
12694
13217
+      if (err->domain == GST_RESOURCE_ERROR) {
12695
13218
+        /* some capturing failed */
12696
 
+        GST_CAMERA_BIN_PROCESSING_DEC (GST_CAMERA_BIN_CAST (bin));
 
13219
+        GST_WARNING_OBJECT (bin, "Capture failed, reason: %s - %s",
 
13220
+            err->message, debug);
 
13221
+        if (camerabin->post_previews) {
 
13222
+          gst_camera_bin_skip_next_preview (camerabin);
 
13223
+        }
 
13224
+        dec_counter = TRUE;
12697
13225
+      }
 
13226
+      g_error_free (err);
 
13227
+      g_free (debug);
12698
13228
+    }
12699
13229
+      break;
12700
13230
+    case GST_MESSAGE_EOS:{
12701
13231
+      GstElement *src = GST_ELEMENT (GST_MESSAGE_SRC (message));
12702
 
+      if (src == GST_CAMERA_BIN_CAST (bin)->videosink) {
 
13232
+      if (src == GST_CAMERA_BIN2_CAST (bin)->videosink) {
 
13233
+
 
13234
+        g_mutex_lock (camerabin->video_capture_mutex);
12703
13235
+        GST_DEBUG_OBJECT (bin, "EOS from video branch");
12704
 
+        GST_CAMERA_BIN_PROCESSING_DEC (GST_CAMERA_BIN_CAST (bin));
 
13236
+        g_assert (camerabin->video_state == GST_CAMERA_BIN_VIDEO_FINISHING);
 
13237
+
 
13238
+        gst_video_capture_bin_post_video_done (GST_CAMERA_BIN2_CAST (bin));
 
13239
+        dec_counter = TRUE;
 
13240
+
 
13241
+        if (!g_thread_create (gst_camera_bin_video_reset_elements,
 
13242
+                gst_object_ref (camerabin), FALSE, NULL)) {
 
13243
+          GST_WARNING_OBJECT (camerabin, "Failed to create thread to "
 
13244
+              "reset video elements' state, video recordings may not work "
 
13245
+              "anymore");
 
13246
+          gst_object_unref (camerabin);
 
13247
+          camerabin->video_state = GST_CAMERA_BIN_VIDEO_IDLE;
 
13248
+        }
 
13249
+
 
13250
+        g_mutex_unlock (camerabin->video_capture_mutex);
12705
13251
+      }
12706
13252
+    }
12707
13253
+      break;
12710
13256
+  }
12711
13257
+  if (message)
12712
13258
+    GST_BIN_CLASS (parent_class)->handle_message (bin, message);
 
13259
+
 
13260
+  if (dec_counter)
 
13261
+    GST_CAMERA_BIN2_PROCESSING_DEC (camerabin);
12713
13262
+}
12714
13263
+
12715
13264
+/*
12722
13271
+ * Where current_filter and new_filter might or might not be NULL
12723
13272
+ */
12724
13273
+static void
12725
 
+gst_camera_bin_check_and_replace_filter (GstCameraBin * camera,
 
13274
+gst_camera_bin_check_and_replace_filter (GstCameraBin2 * camera,
12726
13275
+    GstElement ** current_filter, GstElement * new_filter,
12727
 
+    GstElement * previous_element, GstElement * next_element)
 
13276
+    GstElement * previous_element, GstElement * next_element,
 
13277
+    const gchar * prev_elem_pad)
12728
13278
+{
12729
13279
+  if (*current_filter == new_filter) {
12730
13280
+    GST_DEBUG_OBJECT (camera, "Current filter is the same as the previous, "
12748
13298
+  if (new_filter) {
12749
13299
+    *current_filter = gst_object_ref (new_filter);
12750
13300
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (new_filter));
12751
 
+    gst_element_link_many (previous_element, new_filter, next_element, NULL);
 
13301
+  }
 
13302
+
 
13303
+  if (prev_elem_pad) {
 
13304
+    if (new_filter) {
 
13305
+      gst_element_link_pads (previous_element, prev_elem_pad, new_filter, NULL);
 
13306
+      gst_element_link (new_filter, next_element);
 
13307
+    } else {
 
13308
+      gst_element_link_pads (previous_element, prev_elem_pad, next_element,
 
13309
+          NULL);
 
13310
+    }
12752
13311
+  } else {
12753
 
+    gst_element_link (previous_element, next_element);
 
13312
+    if (new_filter)
 
13313
+      gst_element_link_many (previous_element, new_filter, next_element, NULL);
 
13314
+    else
 
13315
+      gst_element_link (previous_element, next_element);
12754
13316
+  }
12755
13317
+}
12756
13318
+
12757
13319
+static void
12758
13320
+encodebin_element_added (GstElement * encodebin, GstElement * new_element,
12759
 
+    GstCameraBin * camera)
 
13321
+    GstCameraBin2 * camera)
12760
13322
+{
12761
13323
+  GstElementFactory *factory = gst_element_get_factory (new_element);
12762
13324
+
12766
13328
+      g_object_set (new_element, "skip-to-first", TRUE, NULL);
12767
13329
+    }
12768
13330
+  }
 
13331
+
 
13332
+  if (gst_element_implements_interface (new_element, GST_TYPE_TAG_SETTER)) {
 
13333
+    GstTagSetter *tagsetter = GST_TAG_SETTER (new_element);
 
13334
+
 
13335
+    gst_tag_setter_set_tag_merge_mode (tagsetter, GST_TAG_MERGE_REPLACE);
 
13336
+  }
12769
13337
+}
12770
13338
+
12771
13339
+#define VIDEO_PAD 1
12772
13340
+#define AUDIO_PAD 2
12773
13341
+static GstPad *
12774
 
+encodebin_find_pad (GstCameraBin * camera, gint pad_type)
 
13342
+encodebin_find_pad (GstCameraBin2 * camera, GstElement * encodebin,
 
13343
+    gint pad_type)
12775
13344
+{
12776
13345
+  GstPad *pad = NULL;
12777
13346
+  GstIterator *iter;
12778
13347
+  gboolean done;
12779
 
+  GstElement *encodebin = camera->encodebin;
12780
13348
+
12781
13349
+  GST_DEBUG_OBJECT (camera, "Looking at encodebin pads, searching for %s pad",
12782
 
+      VIDEO_PAD ? "video" : "audio");
 
13350
+      pad_type == VIDEO_PAD ? "video" : "audio");
12783
13351
+
12784
13352
+  iter = gst_element_iterate_sink_pads (encodebin);
12785
13353
+  done = FALSE;
12830
13398
+
12831
13399
+    pad = gst_element_request_pad (encodebin, tmpl, NULL, NULL);
12832
13400
+    GST_DEBUG_OBJECT (camera, "Got pad: %s", pad ? GST_PAD_NAME (pad) : "null");
12833
 
+    gst_object_unref (tmpl);
12834
13401
+  }
12835
13402
+
12836
13403
+  return pad;
12837
13404
+}
12838
13405
+
12839
13406
+static gboolean
12840
 
+gst_camera_bin_video_profile_has_audio (GstCameraBin * camera)
 
13407
+gst_camera_bin_video_profile_has_audio (GstCameraBin2 * camera)
12841
13408
+{
12842
13409
+  const GList *list;
12843
13410
+
12859
13426
+}
12860
13427
+
12861
13428
+static GstPadLinkReturn
12862
 
+gst_camera_bin_link_encodebin (GstCameraBin * camera, GstElement * element,
12863
 
+    gint padtype)
 
13429
+gst_camera_bin_link_encodebin (GstCameraBin2 * camera, GstElement * encodebin,
 
13430
+    GstElement * element, gint padtype)
12864
13431
+{
12865
13432
+  GstPadLinkReturn ret;
12866
13433
+  GstPad *srcpad;
12867
13434
+  GstPad *sinkpad = NULL;
12868
13435
+
12869
13436
+  srcpad = gst_element_get_static_pad (element, "src");
12870
 
+  sinkpad = encodebin_find_pad (camera, padtype);
12871
 
+
12872
13437
+  g_assert (srcpad != NULL);
12873
 
+  g_assert (sinkpad != NULL);
12874
 
+
12875
 
+  ret = gst_pad_link (srcpad, sinkpad);
 
13438
+
 
13439
+  sinkpad = encodebin_find_pad (camera, encodebin, padtype);
 
13440
+
 
13441
+  /* there may be no available sink pad for encodebin in some situations:
 
13442
+   * e.g. missing elements or incompatible padtype */
 
13443
+  if (sinkpad == NULL) {
 
13444
+    gst_object_unref (srcpad);
 
13445
+    return GST_PAD_LINK_REFUSED;
 
13446
+  }
 
13447
+
 
13448
+  ret = gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_CAPS);
12876
13449
+  gst_object_unref (sinkpad);
12877
13450
+  gst_object_unref (srcpad);
12878
13451
+
12883
13456
+gst_camera_bin_src_notify_max_zoom_cb (GObject * self, GParamSpec * pspec,
12884
13457
+    gpointer user_data)
12885
13458
+{
12886
 
+  GstCameraBin *camera = (GstCameraBin *) user_data;
 
13459
+  GstCameraBin2 *camera = (GstCameraBin2 *) user_data;
12887
13460
+
12888
13461
+  g_object_get (self, "max-zoom", &camera->max_zoom, NULL);
12889
13462
+  GST_DEBUG_OBJECT (camera, "Max zoom updated to %f", camera->max_zoom);
12890
13463
+  g_object_notify (G_OBJECT (camera), "max-zoom");
12891
13464
+}
12892
13465
+
 
13466
+static void
 
13467
+gst_camera_bin_src_notify_zoom_cb (GObject * self, GParamSpec * pspec,
 
13468
+    gpointer user_data)
 
13469
+{
 
13470
+  GstCameraBin2 *camera = (GstCameraBin2 *) user_data;
 
13471
+
 
13472
+  g_object_get (self, "zoom", &camera->zoom, NULL);
 
13473
+  GST_DEBUG_OBJECT (camera, "Zoom updated to %f", camera->zoom);
 
13474
+  g_object_notify (G_OBJECT (camera), "zoom");
 
13475
+}
 
13476
+
 
13477
+static gboolean
 
13478
+gst_camera_bin_image_src_buffer_probe (GstPad * pad, GstBuffer * buf,
 
13479
+    gpointer data)
 
13480
+{
 
13481
+  gboolean ret = TRUE;
 
13482
+  GstCameraBin2 *camerabin = data;
 
13483
+  GstEvent *evt;
 
13484
+  gchar *location = NULL;
 
13485
+  GstPad *peer;
 
13486
+  GstTagList *tags;
 
13487
+
 
13488
+  g_mutex_lock (camerabin->image_capture_mutex);
 
13489
+
 
13490
+  /* Push pending image tags */
 
13491
+  if (camerabin->image_tags_list) {
 
13492
+    tags = camerabin->image_tags_list->data;
 
13493
+    camerabin->image_tags_list =
 
13494
+        g_slist_delete_link (camerabin->image_tags_list,
 
13495
+        camerabin->image_tags_list);
 
13496
+    GST_DEBUG_OBJECT (camerabin, "Pushing tags from application: %"
 
13497
+        GST_PTR_FORMAT, tags);
 
13498
+    if (tags) {
 
13499
+      peer = gst_pad_get_peer (pad);
 
13500
+      gst_pad_send_event (peer, gst_event_new_tag (tags));
 
13501
+      gst_object_unref (peer);
 
13502
+    }
 
13503
+  } else {
 
13504
+    GST_DEBUG_OBJECT (camerabin, "No tags from application to send");
 
13505
+  }
 
13506
+
 
13507
+  /* Push image location event */
 
13508
+  if (camerabin->image_location_list) {
 
13509
+    location = camerabin->image_location_list->data;
 
13510
+    camerabin->image_location_list =
 
13511
+        g_slist_delete_link (camerabin->image_location_list,
 
13512
+        camerabin->image_location_list);
 
13513
+    GST_DEBUG_OBJECT (camerabin, "Sending image location change to '%s'",
 
13514
+        location);
 
13515
+  } else {
 
13516
+    GST_DEBUG_OBJECT (camerabin, "No filename location change to send");
 
13517
+    g_mutex_unlock (camerabin->image_capture_mutex);
 
13518
+    return ret;
 
13519
+  }
 
13520
+  g_mutex_unlock (camerabin->image_capture_mutex);
 
13521
+
 
13522
+  if (location) {
 
13523
+    evt = gst_camera_bin_new_event_file_location (location);
 
13524
+    peer = gst_pad_get_peer (pad);
 
13525
+    gst_pad_send_event (peer, evt);
 
13526
+    gst_object_unref (peer);
 
13527
+    g_free (location);
 
13528
+  } else {
 
13529
+    /* This means we don't have to encode the capture, it is used for
 
13530
+     * signaling the application just wants the preview */
 
13531
+    ret = FALSE;
 
13532
+    GST_CAMERA_BIN2_PROCESSING_DEC (camerabin);
 
13533
+  }
 
13534
+
 
13535
+  return ret;
 
13536
+}
 
13537
+
 
13538
+
 
13539
+static gboolean
 
13540
+gst_camera_bin_image_sink_event_probe (GstPad * pad, GstEvent * event,
 
13541
+    gpointer data)
 
13542
+{
 
13543
+  GstCameraBin2 *camerabin = data;
 
13544
+
 
13545
+  switch (GST_EVENT_TYPE (event)) {
 
13546
+    case GST_EVENT_CUSTOM_DOWNSTREAM:{
 
13547
+      if (gst_event_has_name (event, "new-location")) {
 
13548
+        const GstStructure *structure = gst_event_get_structure (event);
 
13549
+        const gchar *filename = gst_structure_get_string (structure,
 
13550
+            "location");
 
13551
+
 
13552
+        gst_element_set_state (camerabin->imagesink, GST_STATE_NULL);
 
13553
+        GST_DEBUG_OBJECT (camerabin, "Setting filename to imagesink: %s",
 
13554
+            filename);
 
13555
+        g_object_set (camerabin->imagesink, "location", filename, NULL);
 
13556
+        if (gst_element_set_state (camerabin->imagesink, GST_STATE_PLAYING) ==
 
13557
+            GST_STATE_CHANGE_FAILURE) {
 
13558
+          /* Resets the latest state change return, that would be a failure
 
13559
+           * and could cause problems in a camerabin2 state change */
 
13560
+          gst_element_set_state (camerabin->imagesink, GST_STATE_NULL);
 
13561
+        }
 
13562
+      }
 
13563
+    }
 
13564
+      break;
 
13565
+    default:
 
13566
+      break;
 
13567
+  }
 
13568
+
 
13569
+  return TRUE;
 
13570
+}
 
13571
+
 
13572
+static gboolean
 
13573
+gst_camera_bin_audio_src_data_probe (GstPad * pad, GstMiniObject * obj,
 
13574
+    gpointer data)
 
13575
+{
 
13576
+  GstCameraBin2 *camera = data;
 
13577
+  gboolean ret = TRUE;
 
13578
+
 
13579
+  if (GST_IS_BUFFER (obj)) {
 
13580
+    if (G_UNLIKELY (camera->audio_send_newseg)) {
 
13581
+      GstBuffer *buf = GST_BUFFER_CAST (obj);
 
13582
+      GstClockTime ts = GST_BUFFER_TIMESTAMP (buf);
 
13583
+      GstPad *peer;
 
13584
+
 
13585
+      if (!GST_CLOCK_TIME_IS_VALID (ts)) {
 
13586
+        ts = 0;
 
13587
+      }
 
13588
+
 
13589
+      peer = gst_pad_get_peer (pad);
 
13590
+      g_return_val_if_fail (peer != NULL, TRUE);
 
13591
+
 
13592
+      gst_pad_send_event (peer, gst_event_new_new_segment (FALSE, 1.0,
 
13593
+              GST_FORMAT_TIME, ts, -1, 0));
 
13594
+
 
13595
+      gst_object_unref (peer);
 
13596
+
 
13597
+      camera->audio_send_newseg = FALSE;
 
13598
+    }
 
13599
+  } else {
 
13600
+    GstEvent *event = GST_EVENT_CAST (obj);
 
13601
+    if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
 
13602
+      /* we only let an EOS pass when the user is stopping a capture */
 
13603
+      if (camera->audio_drop_eos) {
 
13604
+        ret = FALSE;
 
13605
+      } else {
 
13606
+        camera->audio_drop_eos = TRUE;
 
13607
+        /* should already be false, but reinforce in case no buffers get
 
13608
+         * pushed */
 
13609
+        camera->audio_send_newseg = FALSE;
 
13610
+      }
 
13611
+    } else if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
 
13612
+      ret = FALSE;
 
13613
+    }
 
13614
+  }
 
13615
+
 
13616
+  return ret;
 
13617
+}
 
13618
+
12893
13619
+/**
12894
13620
+ * gst_camera_bin_create_elements:
12895
 
+ * @param camera: the #GstCameraBin
 
13621
+ * @param camera: the #GstCameraBin2
12896
13622
+ *
12897
 
+ * Creates all elements inside #GstCameraBin
 
13623
+ * Creates all elements inside #GstCameraBin2
12898
13624
+ *
12899
13625
+ * Each of the pads on the camera source is linked as follows:
12900
13626
+ * .pad ! queue ! capsfilter ! correspondingbin
12903
13629
+ * the camera source pad.
12904
13630
+ */
12905
13631
+static gboolean
12906
 
+gst_camera_bin_create_elements (GstCameraBin * camera)
 
13632
+gst_camera_bin_create_elements (GstCameraBin2 * camera)
12907
13633
+{
12908
13634
+  gboolean new_src = FALSE;
12909
13635
+  gboolean new_audio_src = FALSE;
12910
13636
+  gboolean has_audio;
12911
13637
+  gboolean profile_switched = FALSE;
 
13638
+  const gchar *missing_element_name;
 
13639
+  gint encbin_flags = 0;
12912
13640
+
12913
13641
+  if (!camera->elements_created) {
12914
 
+    /* TODO check that elements created in _init were really created */
12915
 
+    /* TODO add proper missing plugin error handling */
 
13642
+    /* Check that elements created in _init were really created */
 
13643
+    if (!(camera->audio_capsfilter && camera->videobin_capsfilter &&
 
13644
+            camera->imagebin_capsfilter && camera->viewfinderbin_capsfilter)) {
 
13645
+      missing_element_name = "capsfilter";
 
13646
+      goto missing_element;
 
13647
+    }
12916
13648
+
12917
 
+    camera->encodebin = gst_element_factory_make ("encodebin", NULL);
12918
 
+    camera->encodebin_signal_id = g_signal_connect (camera->encodebin,
12919
 
+        "element-added", (GCallback) encodebin_element_added, camera);
 
13649
+    camera->video_encodebin =
 
13650
+        gst_element_factory_make ("encodebin", "video-encodebin");
 
13651
+    if (!camera->video_encodebin) {
 
13652
+      missing_element_name = "encodebin";
 
13653
+      goto missing_element;
 
13654
+    }
 
13655
+    camera->video_encodebin_signal_id =
 
13656
+        g_signal_connect (camera->video_encodebin, "element-added",
 
13657
+        (GCallback) encodebin_element_added, camera);
12920
13658
+
12921
13659
+    camera->videosink =
12922
13660
+        gst_element_factory_make ("filesink", "videobin-filesink");
 
13661
+    if (!camera->videosink) {
 
13662
+      missing_element_name = "filesink";
 
13663
+      goto missing_element;
 
13664
+    }
12923
13665
+    g_object_set (camera->videosink, "async", FALSE, NULL);
12924
13666
+
12925
13667
+    /* audio elements */
12926
 
+    camera->audio_queue = gst_element_factory_make ("queue", "audio-queue");
12927
 
+    camera->audio_convert = gst_element_factory_make ("audioconvert",
12928
 
+        "audio-convert");
 
13668
+    if (!camera->audio_volume) {
 
13669
+      missing_element_name = "volume";
 
13670
+      goto missing_element;
 
13671
+    }
12929
13672
+
12930
13673
+    if (camera->video_profile == NULL) {
12931
13674
+      GstEncodingContainerProfile *prof;
12953
13696
+      gst_caps_unref (caps);
12954
13697
+
12955
13698
+      camera->video_profile = (GstEncodingProfile *) prof;
12956
 
+      camera->profile_switch = TRUE;
12957
 
+    }
12958
 
+
12959
 
+    camera->videobin_queue =
12960
 
+        gst_element_factory_make ("queue", "videobin-queue");
12961
 
+    camera->imagebin_queue =
12962
 
+        gst_element_factory_make ("queue", "imagebin-queue");
 
13699
+      camera->video_profile_switch = TRUE;
 
13700
+    }
 
13701
+
 
13702
+    camera->image_encodebin =
 
13703
+        gst_element_factory_make ("encodebin", "image-encodebin");
 
13704
+    if (!camera->image_encodebin) {
 
13705
+      missing_element_name = "encodebin";
 
13706
+      goto missing_element;
 
13707
+    }
 
13708
+    /* durations have no meaning for image captures */
 
13709
+    g_object_set (camera->image_encodebin, "queue-time-max", (guint64) 0, NULL);
 
13710
+
 
13711
+    camera->image_encodebin_signal_id =
 
13712
+        g_signal_connect (camera->image_encodebin, "element-added",
 
13713
+        (GCallback) encodebin_element_added, camera);
 
13714
+
 
13715
+    camera->imagesink =
 
13716
+        gst_element_factory_make ("multifilesink", "imagebin-filesink");
 
13717
+    if (!camera->imagesink) {
 
13718
+      missing_element_name = "multifilesink";
 
13719
+      goto missing_element;
 
13720
+    }
 
13721
+    g_object_set (camera->imagesink, "async", FALSE, "post-messages", TRUE,
 
13722
+        NULL);
 
13723
+
 
13724
+    if (camera->image_profile == NULL) {
 
13725
+      GstEncodingContainerProfile *prof;
 
13726
+      GstEncodingVideoProfile *vprof;
 
13727
+      GstCaps *caps;
 
13728
+
 
13729
+      caps = gst_caps_new_simple ("image/jpeg", NULL);
 
13730
+      vprof = gst_encoding_video_profile_new (caps, NULL, NULL, 1);
 
13731
+      gst_encoding_video_profile_set_variableframerate (vprof, TRUE);
 
13732
+
 
13733
+      prof = gst_encoding_container_profile_new ("jpeg", "jpeg container", caps,
 
13734
+          NULL);
 
13735
+      gst_encoding_container_profile_add_profile (prof,
 
13736
+          (GstEncodingProfile *) vprof);
 
13737
+
 
13738
+      gst_caps_unref (caps);
 
13739
+      camera->image_profile = (GstEncodingProfile *) prof;
 
13740
+      camera->image_profile_switch = TRUE;
 
13741
+    }
 
13742
+
12963
13743
+    camera->viewfinderbin_queue =
12964
13744
+        gst_element_factory_make ("queue", "viewfinderbin-queue");
 
13745
+    if (!camera->viewfinderbin_queue) {
 
13746
+      missing_element_name = "queue";
 
13747
+      goto missing_element;
 
13748
+    }
12965
13749
+
12966
13750
+    g_object_set (camera->viewfinderbin_queue, "leaky", 2, "silent", TRUE,
12967
 
+        NULL);
12968
 
+    g_object_set (camera->imagebin_queue, "max-size-time", (guint64) 0,
12969
 
+        "silent", TRUE, NULL);
12970
 
+    g_object_set (camera->videobin_queue, "silent", TRUE, NULL);
 
13751
+        "max-size-time", (guint64) 0, "max-size-bytes", (guint) 0,
 
13752
+        "max-size-buffers", (guint) 1, NULL);
12971
13753
+
12972
13754
+    gst_bin_add_many (GST_BIN_CAST (camera),
12973
 
+        gst_object_ref (camera->encodebin),
 
13755
+        gst_object_ref (camera->video_encodebin),
12974
13756
+        gst_object_ref (camera->videosink),
12975
 
+        gst_object_ref (camera->imagebin),
12976
 
+        gst_object_ref (camera->videobin_queue),
12977
 
+        gst_object_ref (camera->imagebin_queue),
 
13757
+        gst_object_ref (camera->image_encodebin),
 
13758
+        gst_object_ref (camera->imagesink),
12978
13759
+        gst_object_ref (camera->viewfinderbin_queue), NULL);
12979
13760
+
12980
 
+    /* Linking can be optimized TODO */
12981
 
+    gst_element_link_many (camera->videobin_queue, camera->videobin_capsfilter,
12982
 
+        NULL);
12983
 
+    gst_element_link (camera->encodebin, camera->videosink);
12984
 
+
12985
 
+    gst_element_link_many (camera->imagebin_queue, camera->imagebin_capsfilter,
12986
 
+        camera->imagebin, NULL);
12987
 
+    gst_element_link_many (camera->viewfinderbin_queue,
12988
 
+        camera->viewfinderbin_capsfilter, camera->viewfinderbin, NULL);
 
13761
+    gst_element_link_pads_full (camera->video_encodebin, "src",
 
13762
+        camera->videosink, "sink", GST_PAD_LINK_CHECK_NOTHING);
 
13763
+    gst_element_link_pads_full (camera->image_encodebin, "src",
 
13764
+        camera->imagesink, "sink", GST_PAD_LINK_CHECK_NOTHING);
 
13765
+    gst_element_link_pads_full (camera->viewfinderbin_queue, "src",
 
13766
+        camera->viewfinderbin_capsfilter, "sink", GST_PAD_LINK_CHECK_CAPS);
 
13767
+    gst_element_link_pads_full (camera->viewfinderbin_capsfilter, "src",
 
13768
+        camera->viewfinderbin, "sink", GST_PAD_LINK_CHECK_CAPS);
 
13769
+
 
13770
+    {
 
13771
+      /* set an event probe to watch for custom location changes */
 
13772
+      GstPad *srcpad;
 
13773
+
 
13774
+      srcpad = gst_element_get_static_pad (camera->image_encodebin, "src");
 
13775
+
 
13776
+      gst_pad_add_event_probe (srcpad,
 
13777
+          (GCallback) gst_camera_bin_image_sink_event_probe, camera);
 
13778
+
 
13779
+      gst_object_unref (srcpad);
 
13780
+    }
 
13781
+
12989
13782
+    /*
12990
13783
+     * Video can't get into playing as its internal filesink will open
12991
13784
+     * a file for writing and leave it empty if unused.
12996
13789
+     * starting recording, so we should prepare the video bin.
12997
13790
+     */
12998
13791
+    gst_element_set_locked_state (camera->videosink, TRUE);
 
13792
+    gst_element_set_locked_state (camera->imagesink, TRUE);
12999
13793
+
13000
 
+    g_object_set (camera->videosink, "location", camera->video_location, NULL);
13001
 
+    g_object_set (camera->imagebin, "location", camera->image_location, NULL);
 
13794
+    g_object_set (camera->videosink, "location", camera->location, NULL);
 
13795
+    g_object_set (camera->imagesink, "location", camera->location, NULL);
13002
13796
+  }
13003
 
+  if (camera->profile_switch) {
13004
 
+    GST_DEBUG_OBJECT (camera, "Switching encodebin's profile");
13005
 
+    g_object_set (camera->encodebin, "profile", camera->video_profile, NULL);
13006
 
+    gst_camera_bin_link_encodebin (camera, camera->videobin_capsfilter,
13007
 
+        VIDEO_PAD);
13008
 
+    camera->profile_switch = FALSE;
 
13797
+
 
13798
+  /* propagate the flags property by translating appropriate values
 
13799
+   * to GstEncFlags values */
 
13800
+  if (camera->flags & GST_CAM_FLAG_NO_AUDIO_CONVERSION)
 
13801
+    encbin_flags |= (1 << 0);
 
13802
+  if (camera->flags & GST_CAM_FLAG_NO_VIDEO_CONVERSION)
 
13803
+    encbin_flags |= (1 << 1);
 
13804
+  g_object_set (camera->video_encodebin, "flags", encbin_flags, NULL);
 
13805
+
 
13806
+  /* image encodebin has only video branch so disable its conversion elements
 
13807
+   * appropriately */
 
13808
+  if (camera->flags & GST_CAM_FLAG_NO_IMAGE_CONVERSION)
 
13809
+    g_object_set (camera->image_encodebin, "flags", (1 << 1), NULL);
 
13810
+
 
13811
+  g_object_set (camera->viewfinderbin, "disable-converters",
 
13812
+      camera->flags & GST_CAM_FLAG_NO_VIEWFINDER_CONVERSION ? TRUE : FALSE,
 
13813
+      NULL);
 
13814
+
 
13815
+  if (camera->video_profile_switch) {
 
13816
+    GST_DEBUG_OBJECT (camera, "Switching video-encodebin's profile");
 
13817
+    g_object_set (camera->video_encodebin, "profile", camera->video_profile,
 
13818
+        NULL);
 
13819
+    if (GST_PAD_LINK_FAILED (gst_camera_bin_link_encodebin (camera,
 
13820
+                camera->video_encodebin, camera->videobin_capsfilter,
 
13821
+                VIDEO_PAD))) {
 
13822
+      goto fail;
 
13823
+    }
 
13824
+    camera->video_profile_switch = FALSE;
13009
13825
+
13010
13826
+    /* used to trigger relinking further down */
13011
13827
+    profile_switched = TRUE;
13012
13828
+  }
13013
13829
+
 
13830
+  if (camera->image_profile_switch) {
 
13831
+    GST_DEBUG_OBJECT (camera, "Switching image-encodebin's profile");
 
13832
+    g_object_set (camera->image_encodebin, "profile", camera->image_profile,
 
13833
+        NULL);
 
13834
+    if (GST_PAD_LINK_FAILED (gst_camera_bin_link_encodebin (camera,
 
13835
+                camera->image_encodebin, camera->imagebin_capsfilter,
 
13836
+                VIDEO_PAD))) {
 
13837
+      goto fail;
 
13838
+    }
 
13839
+    camera->image_profile_switch = FALSE;
 
13840
+  }
 
13841
+
13014
13842
+  /* check if we need to replace the camera src */
13015
13843
+  if (camera->src) {
13016
13844
+    if (camera->user_src && camera->user_src != camera->src) {
13045
13873
+          "preview-caps", camera->preview_caps, "preview-filter",
13046
13874
+          camera->preview_filter, NULL);
13047
13875
+    }
 
13876
+    g_signal_connect (G_OBJECT (camera->src), "notify::zoom",
 
13877
+        (GCallback) gst_camera_bin_src_notify_zoom_cb, camera);
13048
13878
+    g_object_set (camera->src, "zoom", camera->zoom, NULL);
13049
13879
+    g_signal_connect (G_OBJECT (camera->src), "notify::max-zoom",
13050
13880
+        (GCallback) gst_camera_bin_src_notify_max_zoom_cb, camera);
13051
13881
+  }
13052
13882
+  if (new_src) {
 
13883
+    GstPad *imgsrc = gst_element_get_static_pad (camera->src, "imgsrc");
 
13884
+
13053
13885
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->src));
13054
13886
+    camera->src_capture_notify_id = g_signal_connect (G_OBJECT (camera->src),
13055
13887
+        "notify::ready-for-capture",
13056
13888
+        G_CALLBACK (gst_camera_bin_src_notify_readyforcapture), camera);
13057
13889
+    gst_element_link_pads (camera->src, "vfsrc", camera->viewfinderbin_queue,
13058
13890
+        "sink");
13059
 
+    gst_element_link_pads (camera->src, "imgsrc", camera->imagebin_queue,
13060
 
+        "sink");
13061
 
+    gst_element_link_pads (camera->src, "vidsrc", camera->videobin_queue,
13062
 
+        "sink");
 
13891
+
 
13892
+    if (!gst_element_link_pads (camera->src, "imgsrc",
 
13893
+            camera->imagebin_capsfilter, "sink")) {
 
13894
+      GST_ERROR_OBJECT (camera,
 
13895
+          "Failed to link camera source's imgsrc pad to image bin capsfilter");
 
13896
+      goto fail;
 
13897
+    }
 
13898
+    if (!gst_element_link_pads (camera->src, "vidsrc",
 
13899
+            camera->videobin_capsfilter, "sink")) {
 
13900
+      GST_ERROR_OBJECT (camera,
 
13901
+          "Failed to link camera source's vidsrc pad to video bin capsfilter");
 
13902
+      goto fail;
 
13903
+    }
 
13904
+
 
13905
+    gst_pad_add_buffer_probe (imgsrc,
 
13906
+        (GCallback) gst_camera_bin_image_src_buffer_probe, camera);
 
13907
+    gst_object_unref (imgsrc);
13063
13908
+  }
13064
13909
+
13065
13910
+  gst_camera_bin_check_and_replace_filter (camera, &camera->image_filter,
13066
 
+      camera->user_image_filter, camera->imagebin_queue,
13067
 
+      camera->imagebin_capsfilter);
 
13911
+      camera->user_image_filter, camera->src, camera->imagebin_capsfilter,
 
13912
+      "imgsrc");
13068
13913
+  gst_camera_bin_check_and_replace_filter (camera, &camera->video_filter,
13069
 
+      camera->user_video_filter, camera->videobin_queue,
13070
 
+      camera->videobin_capsfilter);
 
13914
+      camera->user_video_filter, camera->src, camera->videobin_capsfilter,
 
13915
+      "vidsrc");
13071
13916
+  gst_camera_bin_check_and_replace_filter (camera, &camera->viewfinder_filter,
13072
13917
+      camera->user_viewfinder_filter, camera->viewfinderbin_queue,
13073
 
+      camera->viewfinderbin_capsfilter);
 
13918
+      camera->viewfinderbin_capsfilter, NULL);
13074
13919
+
13075
13920
+  /* check if we need to replace the camera audio src */
13076
13921
+  has_audio = gst_camera_bin_video_profile_has_audio (camera);
13078
13923
+    if ((camera->user_audio_src && camera->user_audio_src != camera->audio_src)
13079
13924
+        || !has_audio) {
13080
13925
+      gst_bin_remove (GST_BIN_CAST (camera), camera->audio_src);
13081
 
+      gst_bin_remove (GST_BIN_CAST (camera), camera->audio_queue);
13082
13926
+      gst_bin_remove (GST_BIN_CAST (camera), camera->audio_volume);
13083
13927
+      gst_bin_remove (GST_BIN_CAST (camera), camera->audio_capsfilter);
13084
 
+      gst_bin_remove (GST_BIN_CAST (camera), camera->audio_convert);
13085
13928
+      gst_object_unref (camera->audio_src);
13086
13929
+      camera->audio_src = NULL;
13087
13930
+    }
13093
13936
+    } else {
13094
13937
+      camera->audio_src =
13095
13938
+          gst_element_factory_make (DEFAULT_AUDIO_SRC, "audiosrc");
 
13939
+      if (!camera->audio_src) {
 
13940
+        missing_element_name = DEFAULT_AUDIO_SRC;
 
13941
+        goto missing_element;
 
13942
+      }
13096
13943
+    }
13097
13944
+
13098
13945
+    gst_element_set_locked_state (camera->audio_src, TRUE);
13100
13947
+  }
13101
13948
+
13102
13949
+  if (new_audio_src) {
 
13950
+    GstPad *srcpad;
 
13951
+
 
13952
+    if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->audio_src),
 
13953
+            "provide-clock")) {
 
13954
+      g_object_set (camera->audio_src, "provide-clock", FALSE, NULL);
 
13955
+    }
13103
13956
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->audio_src));
13104
 
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->audio_queue));
13105
13957
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->audio_volume));
13106
13958
+    gst_bin_add (GST_BIN_CAST (camera),
13107
13959
+        gst_object_ref (camera->audio_capsfilter));
13108
 
+    gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->audio_convert));
13109
 
+
13110
 
+    gst_element_link_many (camera->audio_src, camera->audio_queue,
13111
 
+        camera->audio_volume,
13112
 
+        camera->audio_capsfilter, camera->audio_convert, NULL);
 
13960
+
 
13961
+    gst_element_link_pads_full (camera->audio_src, "src",
 
13962
+        camera->audio_volume, "sink", GST_PAD_LINK_CHECK_CAPS);
 
13963
+    gst_element_link_pads_full (camera->audio_volume, "src",
 
13964
+        camera->audio_capsfilter, "sink", GST_PAD_LINK_CHECK_CAPS);
 
13965
+
 
13966
+    srcpad = gst_element_get_static_pad (camera->audio_src, "src");
 
13967
+
 
13968
+    /* 1) drop EOS for audiosrc elements that push them on state_changes
 
13969
+     * (basesrc does this) 
 
13970
+     * 2) Fix newsegment events to have start time = first buffer ts */
 
13971
+    gst_pad_add_data_probe (srcpad,
 
13972
+        (GCallback) gst_camera_bin_audio_src_data_probe, camera);
 
13973
+
 
13974
+    gst_object_unref (srcpad);
 
13975
+  }
 
13976
+  if (has_audio) {
 
13977
+    gst_camera_bin_check_and_replace_filter (camera, &camera->audio_filter,
 
13978
+        camera->user_audio_filter, camera->audio_src, camera->audio_volume,
 
13979
+        "src");
13113
13980
+  }
13114
13981
+
13115
13982
+  if ((profile_switched && has_audio) || new_audio_src) {
13116
 
+    gst_camera_bin_link_encodebin (camera, camera->audio_convert, AUDIO_PAD);
 
13983
+    if (GST_PAD_LINK_FAILED (gst_camera_bin_link_encodebin (camera,
 
13984
+                camera->video_encodebin, camera->audio_capsfilter,
 
13985
+                AUDIO_PAD))) {
 
13986
+      goto fail;
 
13987
+    }
13117
13988
+  }
13118
13989
+
13119
13990
+  camera->elements_created = TRUE;
13120
13991
+  return TRUE;
 
13992
+
 
13993
+missing_element:
 
13994
+  gst_element_post_message (GST_ELEMENT_CAST (camera),
 
13995
+      gst_missing_element_message_new (GST_ELEMENT_CAST (camera),
 
13996
+          missing_element_name));
 
13997
+  GST_ELEMENT_ERROR (camera, CORE, MISSING_PLUGIN,
 
13998
+      (_("Missing element '%s' - check your GStreamer installation."),
 
13999
+          missing_element_name), (NULL));
 
14000
+  goto fail;
 
14001
+
 
14002
+fail:
 
14003
+  /* FIXME properly clean up */
 
14004
+  return FALSE;
 
14005
+}
 
14006
+
 
14007
+static void
 
14008
+_gst_tag_list_free_maybe (GstTagList * taglist)
 
14009
+{
 
14010
+  if (taglist)
 
14011
+    gst_tag_list_free (taglist);
13121
14012
+}
13122
14013
+
13123
14014
+static GstStateChangeReturn
13124
14015
+gst_camera_bin_change_state (GstElement * element, GstStateChange trans)
13125
14016
+{
13126
14017
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
13127
 
+  GstCameraBin *camera = GST_CAMERA_BIN_CAST (element);
 
14018
+  GstCameraBin2 *camera = GST_CAMERA_BIN2_CAST (element);
 
14019
+
13128
14020
+
13129
14021
+  switch (trans) {
13130
14022
+    case GST_STATE_CHANGE_NULL_TO_READY:
13133
14025
+      }
13134
14026
+      break;
13135
14027
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
13136
 
+      GST_CAMERA_BIN_RESET_PROCESSING_COUNTER (camera);
13137
 
+      break;
13138
 
+    default:
13139
 
+      break;
13140
 
+  }
13141
 
+
13142
 
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);
13143
 
+
13144
 
+  switch (trans) {
 
14028
+      GST_CAMERA_BIN2_RESET_PROCESSING_COUNTER (camera);
 
14029
+      camera->audio_drop_eos = TRUE;
 
14030
+      camera->audio_send_newseg = FALSE;
 
14031
+      break;
13145
14032
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
13146
14033
+      if (GST_STATE (camera->videosink) >= GST_STATE_PAUSED)
13147
14034
+        gst_element_set_state (camera->videosink, GST_STATE_READY);
 
14035
+      if (GST_STATE (camera->imagesink) >= GST_STATE_PAUSED)
 
14036
+        gst_element_set_state (camera->imagesink, GST_STATE_READY);
 
14037
+      break;
 
14038
+    case GST_STATE_CHANGE_READY_TO_NULL:
 
14039
+      gst_element_set_state (camera->videosink, GST_STATE_NULL);
 
14040
+      gst_element_set_state (camera->imagesink, GST_STATE_NULL);
 
14041
+      break;
 
14042
+    default:
 
14043
+      break;
 
14044
+  }
 
14045
+
 
14046
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);
 
14047
+
 
14048
+  switch (trans) {
 
14049
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
13148
14050
+      if (camera->audio_src && GST_STATE (camera->audio_src) >= GST_STATE_READY)
13149
14051
+        gst_element_set_state (camera->audio_src, GST_STATE_READY);
13150
14052
+
13151
14053
+      gst_tag_setter_reset_tags (GST_TAG_SETTER (camera));
13152
 
+      GST_CAMERA_BIN_RESET_PROCESSING_COUNTER (camera);
 
14054
+      GST_CAMERA_BIN2_RESET_PROCESSING_COUNTER (camera);
 
14055
+      camera->video_state = GST_CAMERA_BIN_VIDEO_IDLE;
 
14056
+
 
14057
+      g_mutex_lock (camera->image_capture_mutex);
 
14058
+      g_slist_foreach (camera->image_location_list, (GFunc) g_free, NULL);
 
14059
+      g_slist_free (camera->image_location_list);
 
14060
+      camera->image_location_list = NULL;
 
14061
+
 
14062
+      g_slist_foreach (camera->image_tags_list,
 
14063
+          (GFunc) _gst_tag_list_free_maybe, NULL);
 
14064
+      g_slist_free (camera->image_tags_list);
 
14065
+      camera->image_tags_list = NULL;
 
14066
+      g_mutex_unlock (camera->image_capture_mutex);
 
14067
+
 
14068
+      g_mutex_lock (camera->preview_list_mutex);
 
14069
+      g_slist_foreach (camera->preview_location_list, (GFunc) g_free, NULL);
 
14070
+      g_slist_free (camera->preview_location_list);
 
14071
+      camera->preview_location_list = NULL;
 
14072
+      g_mutex_unlock (camera->preview_list_mutex);
13153
14073
+
13154
14074
+      /* explicitly set to READY as they might be outside of the bin */
13155
 
+      gst_element_set_state (camera->audio_queue, GST_STATE_READY);
13156
14075
+      gst_element_set_state (camera->audio_volume, GST_STATE_READY);
13157
14076
+      gst_element_set_state (camera->audio_capsfilter, GST_STATE_READY);
13158
 
+      gst_element_set_state (camera->audio_convert, GST_STATE_READY);
13159
14077
+      break;
13160
14078
+    case GST_STATE_CHANGE_READY_TO_NULL:
13161
 
+      gst_element_set_state (camera->videosink, GST_STATE_NULL);
13162
14079
+      if (camera->audio_src)
13163
14080
+        gst_element_set_state (camera->audio_src, GST_STATE_NULL);
13164
14081
+
13165
14082
+      /* explicitly set to NULL as they might be outside of the bin */
13166
 
+      gst_element_set_state (camera->audio_queue, GST_STATE_NULL);
13167
14083
+      gst_element_set_state (camera->audio_volume, GST_STATE_NULL);
13168
14084
+      gst_element_set_state (camera->audio_capsfilter, GST_STATE_NULL);
13169
 
+      gst_element_set_state (camera->audio_convert, GST_STATE_NULL);
13170
14085
+
13171
14086
+      break;
13172
14087
+    default:
13176
14091
+  return ret;
13177
14092
+}
13178
14093
+
 
14094
+static gboolean
 
14095
+gst_camera_bin_send_event (GstElement * element, GstEvent * event)
 
14096
+{
 
14097
+  GstCameraBin2 *camera = GST_CAMERA_BIN2_CAST (element);
 
14098
+  gboolean res;
 
14099
+
 
14100
+  /* avoid losing our ref to send_event */
 
14101
+  gst_event_ref (event);
 
14102
+
 
14103
+  res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
 
14104
+  switch (GST_EVENT_TYPE (event)) {
 
14105
+    case GST_EVENT_EOS:
 
14106
+    {
 
14107
+      GstState current;
 
14108
+
 
14109
+      if (camera->videosink) {
 
14110
+        gst_element_get_state (camera->videosink, &current, NULL, 0);
 
14111
+        if (current <= GST_STATE_READY)
 
14112
+          gst_element_post_message (camera->videosink,
 
14113
+              gst_message_new_eos (GST_OBJECT (camera->videosink)));
 
14114
+      }
 
14115
+      if (camera->imagesink) {
 
14116
+        gst_element_get_state (camera->imagesink, &current, NULL, 0);
 
14117
+        if (current <= GST_STATE_READY)
 
14118
+          gst_element_post_message (camera->imagesink,
 
14119
+              gst_message_new_eos (GST_OBJECT (camera->imagesink)));
 
14120
+      }
 
14121
+      break;
 
14122
+    }
 
14123
+
 
14124
+    default:
 
14125
+      break;
 
14126
+  }
 
14127
+
 
14128
+  gst_event_unref (event);
 
14129
+  return res;
 
14130
+}
 
14131
+
13179
14132
+static void
13180
 
+gst_camera_bin_set_location (GstCameraBin * camera, const gchar * location)
 
14133
+gst_camera_bin_set_location (GstCameraBin2 * camera, const gchar * location)
13181
14134
+{
13182
14135
+  GST_DEBUG_OBJECT (camera, "Setting mode %d location to %s", camera->mode,
13183
14136
+      location);
13184
 
+  if (camera->mode == MODE_IMAGE) {
13185
 
+    if (camera->imagebin)
13186
 
+      g_object_set (camera->imagebin, "location", location, NULL);
13187
 
+    g_free (camera->image_location);
13188
 
+    camera->image_location = g_strdup (location);
13189
 
+  } else {
13190
 
+    g_free (camera->video_location);
13191
 
+    camera->video_location = g_strdup (location);
13192
 
+  }
 
14137
+  g_free (camera->location);
 
14138
+  camera->location = g_strdup (location);
13193
14139
+}
13194
14140
+
13195
14141
+static void
13196
 
+gst_camera_bin_set_audio_src (GstCameraBin * camera, GstElement * src)
 
14142
+gst_camera_bin_set_audio_src (GstCameraBin2 * camera, GstElement * src)
13197
14143
+{
13198
14144
+  GST_DEBUG_OBJECT (GST_OBJECT (camera),
13199
14145
+      "Setting audio source %" GST_PTR_FORMAT, src);
13207
14153
+}
13208
14154
+
13209
14155
+static void
13210
 
+gst_camera_bin_set_camera_src (GstCameraBin * camera, GstElement * src)
 
14156
+gst_camera_bin_set_camera_src (GstCameraBin2 * camera, GstElement * src)
13211
14157
+{
13212
14158
+  GST_DEBUG_OBJECT (GST_OBJECT (camera),
13213
14159
+      "Setting camera source %" GST_PTR_FORMAT, src);
13224
14170
+gst_camera_bin_set_property (GObject * object, guint prop_id,
13225
14171
+    const GValue * value, GParamSpec * pspec)
13226
14172
+{
13227
 
+  GstCameraBin *camera = GST_CAMERA_BIN_CAST (object);
 
14173
+  GstCameraBin2 *camera = GST_CAMERA_BIN2_CAST (object);
13228
14174
+
13229
14175
+  switch (prop_id) {
13230
14176
+    case PROP_MODE:
13248
14194
+          "Setting audio capture caps to %" GST_PTR_FORMAT,
13249
14195
+          gst_value_get_caps (value));
13250
14196
+
13251
 
+      g_object_set (camera->audio_capsfilter, "caps",
13252
 
+          gst_value_get_caps (value), NULL);
 
14197
+      if (G_LIKELY (camera->audio_capsfilter)) {
 
14198
+        g_object_set (camera->audio_capsfilter, "caps",
 
14199
+            gst_value_get_caps (value), NULL);
 
14200
+      } else {
 
14201
+        GST_WARNING_OBJECT (camera, "Audio capsfilter missing");
 
14202
+      }
13253
14203
+    }
13254
14204
+      break;
13255
14205
+    case PROP_IMAGE_CAPTURE_CAPS:{
13264
14214
+          "Setting image capture caps to %" GST_PTR_FORMAT,
13265
14215
+          gst_value_get_caps (value));
13266
14216
+
 
14217
+      if (G_LIKELY (camera->imagebin_capsfilter)) {
 
14218
+        g_object_set (camera->imagebin_capsfilter, "caps",
 
14219
+            gst_value_get_caps (value), NULL);
 
14220
+      } else {
 
14221
+        GST_WARNING_OBJECT (camera, "Image capsfilter missing");
 
14222
+      }
 
14223
+
13267
14224
+      /* set the capsfilter caps and notify the src to renegotiate */
13268
 
+      g_object_set (camera->imagebin_capsfilter, "caps",
13269
 
+          gst_value_get_caps (value), NULL);
13270
14225
+      if (pad) {
13271
14226
+        GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s",
13272
14227
+            GST_PAD_NAME (pad));
13273
 
+        GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ());
 
14228
+        gst_pad_send_event (pad, gst_camera_bin_new_event_renegotiate ());
13274
14229
+        gst_object_unref (pad);
13275
14230
+      }
13276
14231
+    }
13288
14243
+          gst_value_get_caps (value));
13289
14244
+
13290
14245
+      /* set the capsfilter caps and notify the src to renegotiate */
13291
 
+      g_object_set (camera->videobin_capsfilter, "caps",
13292
 
+          gst_value_get_caps (value), NULL);
 
14246
+      if (G_LIKELY (camera->videobin_capsfilter)) {
 
14247
+        g_object_set (camera->videobin_capsfilter, "caps",
 
14248
+            gst_value_get_caps (value), NULL);
 
14249
+      } else {
 
14250
+        GST_WARNING_OBJECT (camera, "Video capsfilter missing");
 
14251
+      }
 
14252
+
13293
14253
+      if (pad) {
13294
14254
+        GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s",
13295
14255
+            GST_PAD_NAME (pad));
13296
 
+        GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ());
 
14256
+        gst_pad_send_event (pad, gst_camera_bin_new_event_renegotiate ());
13297
14257
+        gst_object_unref (pad);
13298
14258
+      }
13299
14259
+    }
13311
14271
+          gst_value_get_caps (value));
13312
14272
+
13313
14273
+      /* set the capsfilter caps and notify the src to renegotiate */
13314
 
+      g_object_set (camera->viewfinderbin_capsfilter, "caps",
13315
 
+          gst_value_get_caps (value), NULL);
 
14274
+      if (G_LIKELY (camera->viewfinderbin_capsfilter)) {
 
14275
+        g_object_set (camera->viewfinderbin_capsfilter, "caps",
 
14276
+            gst_value_get_caps (value), NULL);
 
14277
+      } else {
 
14278
+        GST_WARNING_OBJECT (camera, "Viewfinder capsfilter missing");
 
14279
+      }
 
14280
+
13316
14281
+      if (pad) {
13317
14282
+        GST_DEBUG_OBJECT (camera, "Pushing renegotiate on %s",
13318
14283
+            GST_PAD_NAME (pad));
13319
 
+        GST_PAD_EVENTFUNC (pad) (pad, gst_camera_bin_new_event_renegotiate ());
 
14284
+        gst_pad_send_event (pad, gst_camera_bin_new_event_renegotiate ());
13320
14285
+        gst_object_unref (pad);
13321
14286
+      }
13322
14287
+    }
13342
14307
+        gst_encoding_profile_unref (camera->video_profile);
13343
14308
+      camera->video_profile =
13344
14309
+          (GstEncodingProfile *) gst_value_dup_mini_object (value);
13345
 
+      camera->profile_switch = TRUE;
 
14310
+      camera->video_profile_switch = TRUE;
13346
14311
+      break;
13347
14312
+    case PROP_IMAGE_FILTER:
13348
14313
+      if (camera->user_image_filter)
13373
14338
+        g_object_set (camera->src, "preview-filter", camera->preview_filter,
13374
14339
+            NULL);
13375
14340
+      break;
 
14341
+    case PROP_AUDIO_FILTER:
 
14342
+      if (camera->user_audio_filter)
 
14343
+        g_object_unref (camera->user_audio_filter);
 
14344
+
 
14345
+      camera->user_audio_filter = g_value_dup_object (value);
 
14346
+      break;
13376
14347
+    case PROP_VIEWFINDER_SINK:
13377
14348
+      g_object_set (camera->viewfinderbin, "video-sink",
13378
14349
+          g_value_get_object (value), NULL);
13388
14359
+      if (camera->src)
13389
14360
+        g_object_set (camera->src, "zoom", camera->zoom, NULL);
13390
14361
+      break;
13391
 
+    case PROP_IMAGE_CAPTURE_ENCODER:
13392
 
+      g_object_set (camera->imagebin, "image-encoder",
13393
 
+          g_value_get_object (value), NULL);
 
14362
+    case PROP_IMAGE_ENCODING_PROFILE:
 
14363
+      if (camera->image_profile)
 
14364
+        gst_encoding_profile_unref (camera->image_profile);
 
14365
+      camera->image_profile =
 
14366
+          (GstEncodingProfile *) gst_value_dup_mini_object (value);
 
14367
+      camera->image_profile_switch = TRUE;
13394
14368
+      break;
13395
 
+    case PROP_IMAGE_CAPTURE_MUXER:
13396
 
+      g_object_set (camera->imagebin, "image-muxer",
13397
 
+          g_value_get_object (value), NULL);
 
14369
+    case PROP_FLAGS:
 
14370
+      camera->flags = g_value_get_flags (value);
13398
14371
+      break;
13399
14372
+    default:
13400
14373
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
13406
14379
+gst_camera_bin_get_property (GObject * object, guint prop_id,
13407
14380
+    GValue * value, GParamSpec * pspec)
13408
14381
+{
13409
 
+  GstCameraBin *camera = GST_CAMERA_BIN_CAST (object);
 
14382
+  GstCameraBin2 *camera = GST_CAMERA_BIN2_CAST (object);
13410
14383
+
13411
14384
+  switch (prop_id) {
13412
14385
+    case PROP_MODE:
13413
14386
+      g_value_set_enum (value, camera->mode);
13414
14387
+      break;
13415
14388
+    case PROP_LOCATION:
13416
 
+      if (camera->mode == MODE_VIDEO) {
13417
 
+        g_value_set_string (value, camera->video_location);
13418
 
+      } else {
13419
 
+        g_value_set_string (value, camera->image_location);
13420
 
+      }
 
14389
+      g_value_set_string (value, camera->location);
13421
14390
+      break;
13422
14391
+    case PROP_CAMERA_SRC:
13423
 
+      g_value_set_object (value, camera->src);
 
14392
+      g_value_set_object (value, camera->user_src);
13424
14393
+      break;
13425
14394
+    case PROP_AUDIO_SRC:
13426
 
+      g_value_set_object (value, camera->audio_src);
 
14395
+      g_value_set_object (value, camera->user_audio_src);
13427
14396
+      break;
13428
14397
+    case PROP_MUTE_AUDIO:{
13429
14398
+      gboolean mute;
13480
14449
+      break;
13481
14450
+    case PROP_AUDIO_CAPTURE_CAPS:{
13482
14451
+      GstCaps *caps = NULL;
13483
 
+      g_object_get (camera->audio_capsfilter, "caps", &caps, NULL);
 
14452
+      if (G_LIKELY (camera->audio_capsfilter)) {
 
14453
+        g_object_get (camera->audio_capsfilter, "caps", &caps, NULL);
 
14454
+      } else {
 
14455
+        GST_WARNING ("Missing audio capsfilter");
 
14456
+      }
13484
14457
+      gst_value_set_caps (value, caps);
13485
14458
+      gst_caps_unref (caps);
13486
14459
+    }
13487
14460
+      break;
13488
14461
+    case PROP_IMAGE_CAPTURE_CAPS:{
13489
14462
+      GstCaps *caps = NULL;
13490
 
+      g_object_get (camera->imagebin_capsfilter, "caps", &caps, NULL);
 
14463
+      if (G_LIKELY (camera->imagebin_capsfilter)) {
 
14464
+        g_object_get (camera->imagebin_capsfilter, "caps", &caps, NULL);
 
14465
+      } else {
 
14466
+        GST_WARNING ("Missing imagebin capsfilter");
 
14467
+      }
13491
14468
+      gst_value_set_caps (value, caps);
13492
14469
+      gst_caps_unref (caps);
13493
14470
+    }
13494
14471
+      break;
13495
14472
+    case PROP_VIDEO_CAPTURE_CAPS:{
13496
14473
+      GstCaps *caps = NULL;
13497
 
+      g_object_get (camera->videobin_capsfilter, "caps", &caps, NULL);
 
14474
+      if (G_LIKELY (camera->videobin_capsfilter)) {
 
14475
+        g_object_get (camera->videobin_capsfilter, "caps", &caps, NULL);
 
14476
+      } else {
 
14477
+        GST_WARNING ("Missing imagebin capsfilter");
 
14478
+      }
13498
14479
+      gst_value_set_caps (value, caps);
13499
14480
+      gst_caps_unref (caps);
13500
14481
+    }
13501
14482
+      break;
13502
14483
+    case PROP_VIEWFINDER_CAPS:{
13503
14484
+      GstCaps *caps = NULL;
13504
 
+      g_object_get (camera->viewfinderbin_capsfilter, "caps", &caps, NULL);
 
14485
+      if (G_LIKELY (camera->viewfinderbin_capsfilter)) {
 
14486
+        g_object_get (camera->viewfinderbin_capsfilter, "caps", &caps, NULL);
 
14487
+      } else {
 
14488
+        GST_WARNING ("Missing imagebin capsfilter");
 
14489
+      }
13505
14490
+      gst_value_set_caps (value, caps);
13506
14491
+      gst_caps_unref (caps);
13507
14492
+    }
13520
14505
+      }
13521
14506
+      break;
13522
14507
+    case PROP_VIDEO_FILTER:
13523
 
+      if (camera->video_filter)
13524
 
+        g_value_set_object (value, camera->video_filter);
 
14508
+      if (camera->user_video_filter)
 
14509
+        g_value_set_object (value, camera->user_video_filter);
13525
14510
+      break;
13526
14511
+    case PROP_IMAGE_FILTER:
13527
 
+      if (camera->image_filter)
13528
 
+        g_value_set_object (value, camera->image_filter);
 
14512
+      if (camera->user_image_filter)
 
14513
+        g_value_set_object (value, camera->user_image_filter);
13529
14514
+      break;
13530
14515
+    case PROP_VIEWFINDER_FILTER:
13531
 
+      if (camera->viewfinder_filter)
13532
 
+        g_value_set_object (value, camera->viewfinder_filter);
 
14516
+      if (camera->user_viewfinder_filter)
 
14517
+        g_value_set_object (value, camera->user_viewfinder_filter);
 
14518
+      break;
 
14519
+    case PROP_AUDIO_FILTER:
 
14520
+      if (camera->user_audio_filter)
 
14521
+        g_value_set_object (value, camera->user_audio_filter);
13533
14522
+      break;
13534
14523
+    case PROP_PREVIEW_FILTER:
13535
14524
+      if (camera->preview_filter)
13548
14537
+    case PROP_MAX_ZOOM:
13549
14538
+      g_value_set_float (value, camera->max_zoom);
13550
14539
+      break;
13551
 
+    case PROP_IMAGE_CAPTURE_ENCODER:{
13552
 
+      GstElement *enc;
13553
 
+
13554
 
+      g_object_get (camera->imagebin, "image-encoder", &enc, NULL);
13555
 
+      g_value_take_object (value, enc);
13556
 
+      break;
13557
 
+    }
13558
 
+    case PROP_IMAGE_CAPTURE_MUXER:{
13559
 
+      GstElement *mux;
13560
 
+
13561
 
+      g_object_get (camera->imagebin, "image-muxer", &mux, NULL);
13562
 
+      g_value_take_object (value, mux);
13563
 
+      break;
13564
 
+    }
 
14540
+    case PROP_IMAGE_ENCODING_PROFILE:
 
14541
+      if (camera->image_profile) {
 
14542
+        gst_value_set_mini_object (value,
 
14543
+            (GstMiniObject *) camera->image_profile);
 
14544
+      }
 
14545
+      break;
13565
14546
+    case PROP_IDLE:
13566
14547
+      g_value_set_boolean (value,
13567
14548
+          g_atomic_int_get (&camera->processing_counter) == 0);
13568
14549
+      break;
 
14550
+    case PROP_FLAGS:
 
14551
+      g_value_set_flags (value, camera->flags);
 
14552
+      break;
13569
14553
+    default:
13570
14554
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
13571
14555
+      break;
13573
14557
+}
13574
14558
+
13575
14559
+gboolean
13576
 
+gst_camera_bin_plugin_init (GstPlugin * plugin)
 
14560
+gst_camera_bin2_plugin_init (GstPlugin * plugin)
13577
14561
+{
13578
14562
+  GST_DEBUG_CATEGORY_INIT (gst_camera_bin_debug, "camerabin2", 0, "CameraBin2");
13579
14563
+
13580
14564
+  return gst_element_register (plugin, "camerabin2", GST_RANK_NONE,
13581
 
+      gst_camera_bin_get_type ());
 
14565
+      gst_camera_bin2_get_type ());
13582
14566
+}
13583
 
Index: trunk/gst/camerabin2/gstcamerabin2.h
 
14567
Index: gst-plugins-good0.10/gst/camerabin2/gstcamerabin2.h
13584
14568
===================================================================
13585
 
--- /dev/null
13586
 
+++ trunk/gst/camerabin2/gstcamerabin2.h
13587
 
@@ -0,0 +1,109 @@
 
14569
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
14570
+++ gst-plugins-good0.10/gst/camerabin2/gstcamerabin2.h 2012-02-09 14:44:27.408711038 +0200
 
14571
@@ -0,0 +1,164 @@
13588
14572
+/* GStreamer
13589
14573
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
13590
14574
+ *
13603
14587
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
13604
14588
+ * Boston, MA 02111-1307, USA.
13605
14589
+ */
13606
 
+#ifndef _GST_CAMERA_BIN_H_
13607
 
+#define _GST_CAMERA_BIN_H_
 
14590
+#ifndef _GST_CAMERA_BIN2_H_
 
14591
+#define _GST_CAMERA_BIN2_H_
13608
14592
+
13609
14593
+#include <gst/gst.h>
13610
14594
+#include <gst/pbutils/encoding-profile.h>
13611
14595
+
13612
14596
+G_BEGIN_DECLS
13613
14597
+
13614
 
+#define GST_TYPE_CAMERA_BIN   (gst_camera_bin_get_type())
13615
 
+#define GST_CAMERA_BIN(obj)   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERA_BIN,GstCameraBin))
13616
 
+#define GST_CAMERA_BIN_CAST(obj)   ((GstCameraBin *) obj)
13617
 
+#define GST_CAMERA_BIN_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERA_BIN,GstCameraBinClass))
13618
 
+#define GST_IS_CAMERA_BIN(obj)   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERA_BIN))
13619
 
+#define GST_IS_CAMERA_BIN_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERA_BIN))
13620
 
+
13621
 
+typedef struct _GstCameraBin GstCameraBin;
13622
 
+typedef struct _GstCameraBinClass GstCameraBinClass;
13623
 
+
13624
 
+struct _GstCameraBin
 
14598
+#define GST_TYPE_CAMERA_BIN2   (gst_camera_bin2_get_type())
 
14599
+#define GST_CAMERA_BIN2(obj)   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CAMERA_BIN2,GstCameraBin2))
 
14600
+#define GST_CAMERA_BIN2_CAST(obj)   ((GstCameraBin2 *) obj)
 
14601
+#define GST_CAMERA_BIN2_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CAMERA_BIN2,GstCameraBin2Class))
 
14602
+#define GST_IS_CAMERA_BIN2(obj)   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERA_BIN2))
 
14603
+#define GST_IS_CAMERA_BIN2_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERA_BIN2))
 
14604
+
 
14605
+typedef enum
 
14606
+{
 
14607
+  /* matches GstEncFlags GST_ENC_FLAG_NO_AUDIO_CONVERSION in encodebin */
 
14608
+  GST_CAM_FLAG_NO_AUDIO_CONVERSION = (1 << 0),
 
14609
+  /* matches GstEncFlags GST_ENC_FLAG_NO_VIDEO_CONVERSION in encodebin */
 
14610
+  GST_CAM_FLAG_NO_VIDEO_CONVERSION = (1 << 1),
 
14611
+  /* maps to 'disable-converters' property in viewfinderbin */
 
14612
+  GST_CAM_FLAG_NO_VIEWFINDER_CONVERSION = (1 << 2),
 
14613
+  /* maps to GstEncFlags GST_ENC_FLAG_NO_VIDEO_CONVERSION in the image bin's
 
14614
+   * encodebin */
 
14615
+  GST_CAM_FLAG_NO_IMAGE_CONVERSION = (1 << 3)
 
14616
+} GstCamFlags;
 
14617
+
 
14618
+
 
14619
+typedef enum _GstCameraBinVideoState
 
14620
+{
 
14621
+  GST_CAMERA_BIN_VIDEO_IDLE=0,
 
14622
+  GST_CAMERA_BIN_VIDEO_STARTING=1,
 
14623
+  GST_CAMERA_BIN_VIDEO_RECORDING=2,
 
14624
+  GST_CAMERA_BIN_VIDEO_FINISHING=3
 
14625
+} GstCameraBinVideoState;
 
14626
+
 
14627
+typedef struct _GstCameraBin2 GstCameraBin2;
 
14628
+typedef struct _GstCameraBin2Class GstCameraBin2Class;
 
14629
+
 
14630
+struct _GstCameraBin2
13625
14631
+{
13626
14632
+  GstPipeline pipeline;
13627
14633
+
13629
14635
+  GstElement *user_src;
13630
14636
+  gulong src_capture_notify_id;
13631
14637
+
13632
 
+  GstElement *encodebin;
13633
 
+  gulong encodebin_signal_id;
 
14638
+  GstElement *video_encodebin;
 
14639
+  gulong video_encodebin_signal_id;
13634
14640
+  GstElement *videosink;
13635
 
+  gulong videosink_probe;
13636
 
+  GstElement *videobin_queue;
13637
14641
+  GstElement *videobin_capsfilter;
13638
14642
+
13639
14643
+  GstElement *viewfinderbin;
13640
14644
+  GstElement *viewfinderbin_queue;
13641
14645
+  GstElement *viewfinderbin_capsfilter;
13642
14646
+
13643
 
+  GstElement *imagebin;
13644
 
+  GstElement *imagebin_queue;
 
14647
+  GstElement *image_encodebin;
 
14648
+  gulong image_encodebin_signal_id;
 
14649
+  GstElement *imagesink;
13645
14650
+  GstElement *imagebin_capsfilter;
13646
14651
+
13647
14652
+  GstElement *video_filter;
13648
14653
+  GstElement *image_filter;
13649
14654
+  GstElement *viewfinder_filter;
 
14655
+  GstElement *audio_filter;
13650
14656
+  GstElement *user_video_filter;
13651
14657
+  GstElement *user_image_filter;
13652
14658
+  GstElement *user_viewfinder_filter;
 
14659
+  GstElement *user_audio_filter;
13653
14660
+
13654
14661
+  GstElement *audio_src;
13655
14662
+  GstElement *user_audio_src;
13656
 
+  GstElement *audio_queue;
13657
14663
+  GstElement *audio_volume;
13658
14664
+  GstElement *audio_capsfilter;
13659
 
+  GstElement *audio_convert;
13660
14665
+
13661
14666
+  gint processing_counter; /* atomic int */
13662
14667
+
13663
 
+  /* Index of the auto incrementing file index for video recordings */
13664
 
+  gint video_index;
13665
 
+
13666
 
+  gboolean profile_switch;
 
14668
+  /* Index of the auto incrementing file index for captures */
 
14669
+  gint capture_index;
 
14670
+
 
14671
+  GMutex *image_capture_mutex;
 
14672
+  /* stores list of image locations to be pushed to the image sink
 
14673
+   * as file location change notifications, they are pushed before
 
14674
+   * each buffer capture */
 
14675
+  GSList *image_location_list;
 
14676
+  /* Store also tags and push them before each captured image */
 
14677
+  GSList *image_tags_list;
 
14678
+
 
14679
+  /*
 
14680
+   * Similar to above, but used for giving names to previews
 
14681
+   *
 
14682
+   * Need to protect with a mutex as this list is used when the
 
14683
+   * camera-source posts a preview image. As we have no control
 
14684
+   * on how the camera-source will behave (we can only tell how
 
14685
+   * it should), the preview location list might be used in an
 
14686
+   * inconsistent way.
 
14687
+   * One example is the camera-source posting a preview image after
 
14688
+   * camerabin2 was put to ready, when this preview list will be
 
14689
+   * freed and set to NULL. Concurrent access might lead to crashes in
 
14690
+   * this situation. (Concurrency from the state-change freeing the
 
14691
+   * list and the message handling function looking at preview names)
 
14692
+   */
 
14693
+  GSList *preview_location_list;
 
14694
+  GMutex *preview_list_mutex;
 
14695
+
 
14696
+  gboolean video_profile_switch;
 
14697
+  gboolean image_profile_switch;
 
14698
+
 
14699
+  gboolean audio_drop_eos;
 
14700
+  gboolean audio_send_newseg;
 
14701
+
 
14702
+  GMutex *video_capture_mutex;
 
14703
+  GCond *video_state_cond;
 
14704
+  GstCameraBinVideoState video_state;
13667
14705
+
13668
14706
+  /* properties */
13669
14707
+  gint mode;
13670
 
+  gchar *video_location;
13671
 
+  gchar *image_location;
 
14708
+  gchar *location;
13672
14709
+  gboolean post_previews;
13673
14710
+  GstCaps *preview_caps;
13674
14711
+  GstElement *preview_filter;
13675
14712
+  GstEncodingProfile *video_profile;
 
14713
+  GstEncodingProfile *image_profile;
13676
14714
+  gfloat zoom;
13677
14715
+  gfloat max_zoom;
 
14716
+  GstCamFlags flags;
13678
14717
+
13679
14718
+  gboolean elements_created;
13680
14719
+};
13681
14720
+
13682
 
+struct _GstCameraBinClass
 
14721
+struct _GstCameraBin2Class
13683
14722
+{
13684
14723
+  GstPipelineClass pipeline_class;
13685
14724
+
13686
14725
+  /* Action signals */
13687
 
+  void (*start_capture) (GstCameraBin * camera);
13688
 
+  void (*stop_capture) (GstCameraBin * camera);
 
14726
+  void (*start_capture) (GstCameraBin2 * camera);
 
14727
+  void (*stop_capture) (GstCameraBin2 * camera);
13689
14728
+};
13690
14729
+
13691
 
+GType gst_camera_bin_get_type (void);
13692
 
+gboolean gst_camera_bin_plugin_init (GstPlugin * plugin);
 
14730
+GType gst_camera_bin2_get_type (void);
 
14731
+gboolean gst_camera_bin2_plugin_init (GstPlugin * plugin);
13693
14732
+
13694
14733
+G_END_DECLS
13695
14734
+
13696
14735
+#endif
13697
 
Index: trunk/gst/camerabin2/gstimagecapturebin.c
 
14736
Index: gst-plugins-good0.10/gst/camerabin2/gstimagecapturebin.c
13698
14737
===================================================================
13699
 
--- /dev/null
13700
 
+++ trunk/gst/camerabin2/gstimagecapturebin.c
 
14738
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
14739
+++ gst-plugins-good0.10/gst/camerabin2/gstimagecapturebin.c    2012-02-09 14:44:27.408711038 +0200
13701
14740
@@ -0,0 +1,352 @@
13702
14741
+/* GStreamer
13703
14742
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
14051
15090
+  return gst_element_register (plugin, "imagecapturebin", GST_RANK_NONE,
14052
15091
+      gst_image_capture_bin_get_type ());
14053
15092
+}
14054
 
Index: trunk/gst/camerabin2/gstimagecapturebin.h
 
15093
Index: gst-plugins-good0.10/gst/camerabin2/gstimagecapturebin.h
14055
15094
===================================================================
14056
 
--- /dev/null
14057
 
+++ trunk/gst/camerabin2/gstimagecapturebin.h
 
15095
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
15096
+++ gst-plugins-good0.10/gst/camerabin2/gstimagecapturebin.h    2012-02-09 14:44:27.408711038 +0200
14058
15097
@@ -0,0 +1,63 @@
14059
15098
+/* GStreamer
14060
15099
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
14119
15158
+G_END_DECLS
14120
15159
+
14121
15160
+#endif
14122
 
Index: trunk/gst/camerabin2/gstplugin.c
 
15161
Index: gst-plugins-good0.10/gst/camerabin2/gstplugin.c
14123
15162
===================================================================
14124
 
--- /dev/null
14125
 
+++ trunk/gst/camerabin2/gstplugin.c
14126
 
@@ -0,0 +1,49 @@
 
15163
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
15164
+++ gst-plugins-good0.10/gst/camerabin2/gstplugin.c     2012-02-09 14:44:27.408711038 +0200
 
15165
@@ -0,0 +1,46 @@
14127
15166
+/* GStreamer
14128
15167
+ * Copyright (C) <2010> Thiago Santos <thiago.sousa.santos@collabora.co.uk>
14129
15168
+ *
14150
15189
+#endif
14151
15190
+
14152
15191
+#include "gstviewfinderbin.h"
14153
 
+#include "gstimagecapturebin.h"
14154
15192
+#include "gstwrappercamerabinsrc.h"
14155
15193
+#include "gstcamerabin2.h"
14156
15194
+
14159
15197
+{
14160
15198
+  if (!gst_viewfinder_bin_plugin_init (plugin))
14161
15199
+    return FALSE;
14162
 
+  if (!gst_image_capture_bin_plugin_init (plugin))
14163
 
+    return FALSE;
14164
15200
+  if (!gst_wrapper_camera_bin_src_plugin_init (plugin))
14165
15201
+    return FALSE;
14166
 
+  if (!gst_camera_bin_plugin_init (plugin))
 
15202
+  if (!gst_camera_bin2_plugin_init (plugin))
14167
15203
+    return FALSE;
14168
15204
+
14169
15205
+  return TRUE;
14173
15209
+    GST_VERSION_MINOR,
14174
15210
+    "camerabin2", "camerabin2",
14175
15211
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
14176
 
Index: trunk/gst/camerabin2/gstviewfinderbin.c
 
15212
Index: gst-plugins-good0.10/gst/camerabin2/gstviewfinderbin.c
14177
15213
===================================================================
14178
 
--- /dev/null
14179
 
+++ trunk/gst/camerabin2/gstviewfinderbin.c
14180
 
@@ -0,0 +1,305 @@
 
15214
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
15215
+++ gst-plugins-good0.10/gst/camerabin2/gstviewfinderbin.c      2012-02-09 14:44:27.408711038 +0200
 
15216
@@ -0,0 +1,377 @@
14181
15217
+/* GStreamer
14182
15218
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
14183
15219
+ *
14215
15251
+#endif
14216
15252
+
14217
15253
+#include "gstviewfinderbin.h"
 
15254
+#include "camerabingeneral.h"
 
15255
+#include <gst/pbutils/pbutils.h>
 
15256
+
 
15257
+#include <gst/gst-i18n-plugin.h>
14218
15258
+
14219
15259
+GST_DEBUG_CATEGORY_STATIC (gst_viewfinder_bin_debug);
14220
15260
+#define GST_CAT_DEFAULT gst_viewfinder_bin_debug
14221
15261
+
14222
 
+/* prototypes */
14223
 
+
14224
 
+
14225
15262
+enum
14226
15263
+{
14227
15264
+  PROP_0,
14228
15265
+  PROP_VIDEO_SINK,
 
15266
+  PROP_DISABLE_CONVERTERS
14229
15267
+};
14230
15268
+
 
15269
+#define DEFAULT_DISABLE_CONVERTERS FALSE
 
15270
+
14231
15271
+/* pad templates */
14232
15272
+
14233
15273
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
14276
15316
+{
14277
15317
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
14278
15318
+
14279
 
+  gst_element_class_add_pad_template (element_class,
14280
 
+      gst_static_pad_template_get (&sink_template));
 
15319
+  gst_element_class_add_static_pad_template (element_class,
 
15320
+      &sink_template);
14281
15321
+
14282
15322
+  gst_element_class_set_details_simple (element_class, "Viewfinder Bin",
14283
15323
+      "Sink/Video", "Viewfinder Bin used in camerabin2",
14304
15344
+      g_param_spec_object ("video-sink", "Video Sink",
14305
15345
+          "the video output element to use (NULL = default)",
14306
15346
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
15347
+
 
15348
+  g_object_class_install_property (gobject_klass, PROP_DISABLE_CONVERTERS,
 
15349
+      g_param_spec_boolean ("disable-converters", "Disable conversion elements",
 
15350
+          "If video converters should be disabled (must be set on NULL)",
 
15351
+          DEFAULT_DISABLE_CONVERTERS,
 
15352
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
14307
15353
+}
14308
15354
+
14309
15355
+static void
14316
15362
+  gst_object_unref (templ);
14317
15363
+  gst_element_add_pad (GST_ELEMENT_CAST (viewfinderbin),
14318
15364
+      viewfinderbin->ghostpad);
 
15365
+
 
15366
+  viewfinderbin->disable_converters = DEFAULT_DISABLE_CONVERTERS;
14319
15367
+}
14320
15368
+
14321
15369
+static gboolean
14323
15371
+{
14324
15372
+  GstElement *csp = NULL;
14325
15373
+  GstElement *videoscale = NULL;
14326
 
+  GstPad *pad = NULL;
14327
 
+  gboolean added = FALSE;
 
15374
+  GstPad *firstpad = NULL;
 
15375
+  const gchar *missing_element_name;
 
15376
+  gboolean newsink = FALSE;
 
15377
+  gboolean updated_converters = FALSE;
14328
15378
+
14329
15379
+  GST_DEBUG_OBJECT (vfbin, "Creating internal elements");
14330
15380
+
14331
 
+  if (!vfbin->elements_created) {
14332
 
+    /* create elements */
14333
 
+    csp = gst_element_factory_make ("ffmpegcolorspace", "vfbin-csp");
14334
 
+    if (!csp)
14335
 
+      goto error;
14336
 
+
14337
 
+    videoscale = gst_element_factory_make ("videoscale", "vfbin-videoscale");
14338
 
+    if (!videoscale)
14339
 
+      goto error;
14340
 
+
14341
 
+    GST_DEBUG_OBJECT (vfbin, "Internal elements created, proceding to linking");
14342
 
+
14343
 
+    /* add and link */
14344
 
+    gst_bin_add_many (GST_BIN_CAST (vfbin), csp, videoscale, NULL);
14345
 
+    added = TRUE;
14346
 
+    if (!gst_element_link (csp, videoscale))
14347
 
+      goto error;
14348
 
+
14349
 
+    /* add ghostpad */
14350
 
+    pad = gst_element_get_static_pad (csp, "sink");
14351
 
+    if (!gst_ghost_pad_set_target (GST_GHOST_PAD (vfbin->ghostpad), pad))
14352
 
+      goto error;
14353
 
+    gst_object_unref (pad);
14354
 
+
14355
 
+    vfbin->elements_created = TRUE;
14356
 
+    GST_DEBUG_OBJECT (vfbin, "Elements succesfully created and linked");
14357
 
+  }
14358
 
+
 
15381
+  /* First check if we need to add/replace the internal sink */
14359
15382
+  if (vfbin->video_sink) {
14360
 
+    /* check if we need to replace the current one */
14361
15383
+    if (vfbin->user_video_sink && vfbin->video_sink != vfbin->user_video_sink) {
14362
15384
+      gst_bin_remove (GST_BIN_CAST (vfbin), vfbin->video_sink);
14363
15385
+      gst_object_unref (vfbin->video_sink);
14368
15390
+  if (!vfbin->video_sink) {
14369
15391
+    if (vfbin->user_video_sink)
14370
15392
+      vfbin->video_sink = gst_object_ref (vfbin->user_video_sink);
14371
 
+    else
 
15393
+    else {
14372
15394
+      vfbin->video_sink = gst_element_factory_make ("autovideosink",
14373
15395
+          "vfbin-sink");
 
15396
+      if (!vfbin->video_sink) {
 
15397
+        missing_element_name = "autovideosink";
 
15398
+        goto missing_element;
 
15399
+      }
 
15400
+    }
14374
15401
+
14375
15402
+    gst_bin_add (GST_BIN_CAST (vfbin), gst_object_ref (vfbin->video_sink));
14376
 
+
14377
 
+    if (!videoscale)
 
15403
+    newsink = TRUE;
 
15404
+  }
 
15405
+
 
15406
+  /* check if we want add/remove the conversion elements */
 
15407
+  if (vfbin->elements_created && vfbin->disable_converters) {
 
15408
+    /* remove the elements, user doesn't want them */
 
15409
+
 
15410
+    gst_ghost_pad_set_target (GST_GHOST_PAD (vfbin->ghostpad), NULL);
 
15411
+    csp = gst_bin_get_by_name (GST_BIN_CAST (vfbin), "vfbin-csp");
 
15412
+    videoscale = gst_bin_get_by_name (GST_BIN_CAST (vfbin), "vfbin-videoscale");
 
15413
+
 
15414
+    gst_bin_remove (GST_BIN_CAST (vfbin), csp);
 
15415
+    gst_bin_remove (GST_BIN_CAST (vfbin), videoscale);
 
15416
+
 
15417
+    gst_object_unref (csp);
 
15418
+    gst_object_unref (videoscale);
 
15419
+
 
15420
+    updated_converters = TRUE;
 
15421
+  } else if (!vfbin->elements_created && !vfbin->disable_converters) {
 
15422
+    gst_ghost_pad_set_target (GST_GHOST_PAD (vfbin->ghostpad), NULL);
 
15423
+
 
15424
+    /* add the elements, user wants them */
 
15425
+    csp = gst_element_factory_make ("ffmpegcolorspace", "vfbin-csp");
 
15426
+    if (!csp) {
 
15427
+      missing_element_name = "ffmpegcolorspace";
 
15428
+      goto missing_element;
 
15429
+    }
 
15430
+    gst_bin_add (GST_BIN_CAST (vfbin), csp);
 
15431
+
 
15432
+    videoscale = gst_element_factory_make ("videoscale", "vfbin->videoscale");
 
15433
+    if (!videoscale) {
 
15434
+      missing_element_name = "videoscale";
 
15435
+      goto missing_element;
 
15436
+    }
 
15437
+    gst_bin_add (GST_BIN_CAST (vfbin), videoscale);
 
15438
+
 
15439
+    gst_element_link_pads_full (csp, "src", videoscale, "sink",
 
15440
+        GST_PAD_LINK_CHECK_NOTHING);
 
15441
+
 
15442
+    vfbin->elements_created = TRUE;
 
15443
+    GST_DEBUG_OBJECT (vfbin, "Elements succesfully created and linked");
 
15444
+
 
15445
+    updated_converters = TRUE;
 
15446
+  }
 
15447
+  /* otherwise, just leave it as is */
 
15448
+
 
15449
+  /* if sink was replaced -> link it to the internal converters */
 
15450
+  if (newsink && !vfbin->disable_converters) {
 
15451
+    gboolean unref = FALSE;
 
15452
+    if (!videoscale) {
14378
15453
+      videoscale = gst_bin_get_by_name (GST_BIN_CAST (vfbin),
14379
 
+          "vfbin-videoscale");
14380
 
+
14381
 
+    if (!gst_element_link_pads (videoscale, "src", vfbin->video_sink, "sink")) {
14382
 
+      GST_WARNING_OBJECT (vfbin, "Failed to link the new sink");
14383
 
+    }
 
15454
+          "vfbin-videscale");
 
15455
+      unref = TRUE;
 
15456
+    }
 
15457
+
 
15458
+    if (!gst_element_link_pads_full (videoscale, "src", vfbin->video_sink,
 
15459
+            "sink", GST_PAD_LINK_CHECK_CAPS)) {
 
15460
+      GST_ELEMENT_ERROR (vfbin, CORE, NEGOTIATION, (NULL),
 
15461
+          ("linking videoscale and viewfindersink failed"));
 
15462
+    }
 
15463
+
 
15464
+    if (unref)
 
15465
+      gst_object_unref (videoscale);
 
15466
+    videoscale = NULL;
 
15467
+  }
 
15468
+
 
15469
+  /* Check if we need a new ghostpad target */
 
15470
+  if (updated_converters || (newsink && vfbin->disable_converters)) {
 
15471
+    if (vfbin->disable_converters) {
 
15472
+      firstpad = gst_element_get_static_pad (vfbin->video_sink, "sink");
 
15473
+    } else {
 
15474
+      /* csp should always exist at this point */
 
15475
+      firstpad = gst_element_get_static_pad (csp, "sink");
 
15476
+    }
 
15477
+  }
 
15478
+
 
15479
+  /* need to change the ghostpad target if firstpad is set */
 
15480
+  if (firstpad) {
 
15481
+    if (!gst_ghost_pad_set_target (GST_GHOST_PAD (vfbin->ghostpad), firstpad))
 
15482
+      goto error;
 
15483
+    gst_object_unref (firstpad);
 
15484
+    firstpad = NULL;
14384
15485
+  }
14385
15486
+
14386
15487
+  return TRUE;
14387
15488
+
 
15489
+missing_element:
 
15490
+  gst_element_post_message (GST_ELEMENT_CAST (vfbin),
 
15491
+      gst_missing_element_message_new (GST_ELEMENT_CAST (vfbin),
 
15492
+          missing_element_name));
 
15493
+  GST_ELEMENT_ERROR (vfbin, CORE, MISSING_PLUGIN,
 
15494
+      (_("Missing element '%s' - check your GStreamer installation."),
 
15495
+          missing_element_name), (NULL));
 
15496
+  goto error;
 
15497
+
14388
15498
+error:
14389
15499
+  GST_WARNING_OBJECT (vfbin, "Creating internal elements failed");
14390
 
+  if (pad)
14391
 
+    gst_object_unref (pad);
14392
 
+  if (!added) {
14393
 
+    if (csp)
14394
 
+      gst_object_unref (csp);
14395
 
+    if (videoscale)
14396
 
+      gst_object_unref (videoscale);
14397
 
+  } else {
14398
 
+    gst_bin_remove_many (GST_BIN_CAST (vfbin), csp, videoscale, NULL);
14399
 
+  }
 
15500
+  if (firstpad)
 
15501
+    gst_object_unref (firstpad);
14400
15502
+  return FALSE;
14401
15503
+}
14402
15504
+
14453
15555
+    case PROP_VIDEO_SINK:
14454
15556
+      gst_viewfinder_bin_set_video_sink (vfbin, g_value_get_object (value));
14455
15557
+      break;
 
15558
+    case PROP_DISABLE_CONVERTERS:
 
15559
+      vfbin->disable_converters = g_value_get_boolean (value);
 
15560
+      break;
14456
15561
+    default:
14457
15562
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
14458
15563
+      break;
14469
15574
+    case PROP_VIDEO_SINK:
14470
15575
+      g_value_set_object (value, vfbin->video_sink);
14471
15576
+      break;
 
15577
+    case PROP_DISABLE_CONVERTERS:
 
15578
+      g_value_set_boolean (value, vfbin->disable_converters);
 
15579
+      break;
14472
15580
+    default:
14473
15581
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
14474
15582
+      break;
14483
15591
+  return gst_element_register (plugin, "viewfinderbin", GST_RANK_NONE,
14484
15592
+      gst_viewfinder_bin_get_type ());
14485
15593
+}
14486
 
Index: trunk/gst/camerabin2/gstviewfinderbin.h
 
15594
Index: gst-plugins-good0.10/gst/camerabin2/gstviewfinderbin.h
14487
15595
===================================================================
14488
 
--- /dev/null
14489
 
+++ trunk/gst/camerabin2/gstviewfinderbin.h
14490
 
@@ -0,0 +1,58 @@
 
15596
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
15597
+++ gst-plugins-good0.10/gst/camerabin2/gstviewfinderbin.h      2012-02-09 14:44:27.408711038 +0200
 
15598
@@ -0,0 +1,60 @@
14491
15599
+/* GStreamer
14492
15600
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
14493
15601
+ *
14533
15641
+  GstElement *user_video_sink;
14534
15642
+
14535
15643
+  gboolean elements_created;
 
15644
+
 
15645
+  gboolean disable_converters;
14536
15646
+};
14537
15647
+
14538
15648
+struct _GstViewfinderBinClass
14546
15656
+G_END_DECLS
14547
15657
+
14548
15658
+#endif
14549
 
Index: trunk/gst/camerabin2/gstwrappercamerabinsrc.c
 
15659
Index: gst-plugins-good0.10/gst/camerabin2/gstwrappercamerabinsrc.c
14550
15660
===================================================================
14551
 
--- /dev/null
14552
 
+++ trunk/gst/camerabin2/gstwrappercamerabinsrc.c
14553
 
@@ -0,0 +1,1158 @@
 
15661
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
15662
+++ gst-plugins-good0.10/gst/camerabin2/gstwrappercamerabinsrc.c        2012-02-09 14:44:27.408711038 +0200
 
15663
@@ -0,0 +1,1155 @@
14554
15664
+/*
14555
15665
+ * GStreamer
14556
15666
+ * Copyright (C) 2010 Texas Instruments, Inc
14584
15694
+#  include <config.h>
14585
15695
+#endif
14586
15696
+
 
15697
+#include <gst/interfaces/photography.h>
 
15698
+
14587
15699
+#include "gstwrappercamerabinsrc.h"
14588
15700
+#include "camerabingeneral.h"
14589
15701
+
14590
15702
+enum
14591
15703
+{
14592
15704
+  PROP_0,
14593
 
+  PROP_VIDEO_SRC
 
15705
+  PROP_VIDEO_SRC,
 
15706
+  PROP_VIDEO_SRC_FILTER
14594
15707
+};
14595
15708
+
14596
15709
+GST_DEBUG_CATEGORY (wrapper_camera_bin_src_debug);
14611
15724
+    gst_object_unref (self->app_vid_src);
14612
15725
+    self->app_vid_src = NULL;
14613
15726
+  }
 
15727
+  if (self->app_vid_filter) {
 
15728
+    gst_object_unref (self->app_vid_filter);
 
15729
+    self->app_vid_filter = NULL;
 
15730
+  }
14614
15731
+  gst_caps_replace (&self->image_capture_caps, NULL);
14615
15732
+
14616
15733
+  G_OBJECT_CLASS (parent_class)->dispose (object);
14642
15759
+          gst_object_ref (self->app_vid_src);
14643
15760
+      }
14644
15761
+      break;
 
15762
+    case PROP_VIDEO_SRC_FILTER:
 
15763
+      if (GST_STATE (self) != GST_STATE_NULL) {
 
15764
+        GST_ELEMENT_ERROR (self, CORE, FAILED,
 
15765
+            ("camerasrc must be in NULL state when setting the video source filter element"),
 
15766
+            (NULL));
 
15767
+      } else {
 
15768
+        if (self->app_vid_filter)
 
15769
+          gst_object_unref (self->app_vid_filter);
 
15770
+        self->app_vid_filter = g_value_get_object (value);
 
15771
+        if (self->app_vid_filter)
 
15772
+          gst_object_ref (self->app_vid_filter);
 
15773
+      }
 
15774
+      break;
14645
15775
+    default:
14646
15776
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
14647
15777
+      break;
14661
15791
+      else
14662
15792
+        g_value_set_object (value, self->app_vid_src);
14663
15793
+      break;
 
15794
+    case PROP_VIDEO_SRC_FILTER:
 
15795
+      if (self->video_filter)
 
15796
+        g_value_set_object (value, self->video_filter);
 
15797
+      else
 
15798
+        g_value_set_object (value, self->app_vid_filter);
 
15799
+      break;
14664
15800
+    default:
14665
15801
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
14666
15802
+      break;
14782
15918
+  if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
14783
15919
+    /* NOP */
14784
15920
+  } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
 
15921
+    GstClockTime ts;
 
15922
+
14785
15923
+    GST_DEBUG_OBJECT (self, "Starting video recording");
14786
15924
+    self->video_rec_status = GST_VIDEO_RECORDING_STATUS_RUNNING;
14787
15925
+
 
15926
+    ts = GST_BUFFER_TIMESTAMP (buffer);
 
15927
+    if (!GST_CLOCK_TIME_IS_VALID (ts))
 
15928
+      ts = 0;
 
15929
+    gst_pad_push_event (self->vidsrc, gst_event_new_new_segment (FALSE, 1.0,
 
15930
+            GST_FORMAT_TIME, ts, -1, 0));
 
15931
+
14788
15932
+    /* post preview */
14789
15933
+    GST_DEBUG_OBJECT (self, "Posting preview for video");
14790
15934
+    gst_base_camera_src_post_preview (camerasrc, buffer);
14905
16049
+ * @bcamsrc: camerasrc object
14906
16050
+ *
14907
16051
+ * This function creates and links the elements of the camerasrc bin
14908
 
+ * videosrc ! cspconv ! capsfilter ! crop ! scale ! capsfilter ! tee name=t !
 
16052
+ * videosrc ! cspconv ! srcfilter ! cspconv ! capsfilter ! crop ! scale ! \
 
16053
+ * capsfilter ! tee name=t
14909
16054
+ *    t. ! ... (viewfinder pad)
14910
16055
+ *    t. ! output-selector name=outsel
14911
16056
+ *        outsel. ! (image pad)
14919
16064
+  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
14920
16065
+  GstBin *cbin = GST_BIN (bcamsrc);
14921
16066
+  GstElement *tee;
 
16067
+  GstElement *filter_csp;
 
16068
+  GstElement *src_csp;
 
16069
+  GstElement *capsfilter;
14922
16070
+  gboolean ret = FALSE;
14923
 
+  GstElement *videoscale;
14924
16071
+  GstPad *vf_pad;
14925
16072
+  GstPad *tee_capture_pad;
14926
16073
+  GstPad *src_caps_src_pad;
14998
16145
+    /* viewfinder pad */
14999
16146
+    vf_pad = gst_element_get_request_pad (tee, "src%d");
15000
16147
+    g_object_set (tee, "alloc-pad", vf_pad, NULL);
 
16148
+    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
15001
16149
+    gst_object_unref (vf_pad);
15002
16150
+
15003
 
+    /* the viewfinder should always work, so we add some converters to it */
15004
 
+    if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
15005
 
+            "viewfinder-colorspace"))
15006
 
+      goto done;
15007
 
+    if (!(videoscale =
15008
 
+            gst_camerabin_create_and_add_element (cbin, "videoscale",
15009
 
+                "viewfinder-scale")))
15010
 
+      goto done;
15011
 
+
15012
16151
+    /* image/video pad from tee */
15013
16152
+    tee_capture_pad = gst_element_get_request_pad (tee, "src%d");
15014
16153
+
15051
16190
+          NULL);
15052
16191
+    }
15053
16192
+
15054
 
+    /* hook-up the vf ghostpad */
15055
 
+    vf_pad = gst_element_get_static_pad (videoscale, "src");
15056
 
+    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
15057
 
+    gst_object_unref (vf_pad);
 
16193
+
15058
16194
+
15059
16195
+    gst_pad_set_active (self->vfsrc, TRUE);
15060
16196
+    gst_pad_set_active (self->imgsrc, TRUE);    /* XXX ??? */
15061
16197
+    gst_pad_set_active (self->vidsrc, TRUE);    /* XXX ??? */
15062
16198
+  }
 
16199
+
 
16200
+  /* Do this even if pipeline is constructed */
 
16201
+
 
16202
+  if (self->video_filter) {
 
16203
+    /* check if we need to replace the current one */
 
16204
+    if (self->video_filter != self->app_vid_filter) {
 
16205
+      gst_bin_remove (cbin, self->video_filter);
 
16206
+      gst_object_unref (self->video_filter);
 
16207
+      self->video_filter = NULL;
 
16208
+      filter_csp = gst_bin_get_by_name (cbin, "filter-colorspace");
 
16209
+      gst_bin_remove (cbin, filter_csp);
 
16210
+      gst_object_unref (filter_csp);
 
16211
+      filter_csp = NULL;
 
16212
+    }
 
16213
+  }
 
16214
+
 
16215
+  if (!self->video_filter) {
 
16216
+    if (self->app_vid_filter) {
 
16217
+      self->video_filter = gst_object_ref (self->app_vid_filter);
 
16218
+      filter_csp = gst_element_factory_make ("ffmpegcolorspace",
 
16219
+          "filter-colorspace");
 
16220
+      gst_bin_add_many (cbin, self->video_filter, filter_csp, NULL);
 
16221
+      src_csp = gst_bin_get_by_name (cbin, "src-colorspace");
 
16222
+      capsfilter = gst_bin_get_by_name (cbin, "src-capsfilter");
 
16223
+      if (gst_pad_is_linked (gst_element_get_static_pad (src_csp, "src")))
 
16224
+        gst_element_unlink (src_csp, capsfilter);
 
16225
+      if (!gst_element_link_many (src_csp, self->video_filter, filter_csp,
 
16226
+              capsfilter, NULL))
 
16227
+        goto done;
 
16228
+    }
 
16229
+  }
15063
16230
+  ret = TRUE;
15064
16231
+  self->elements_created = TRUE;
15065
16232
+done:
15201
16368
+start_image_capture (GstWrapperCameraBinSrc * self)
15202
16369
+{
15203
16370
+  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
15204
 
+  GstPhotography *photography = gst_base_camera_src_get_photography (bcamsrc);
 
16371
+  GstPhotography *photography =
 
16372
+      (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc),
 
16373
+      GST_TYPE_PHOTOGRAPHY);
15205
16374
+  gboolean ret = FALSE;
15206
16375
+  GstCaps *caps;
15207
16376
+
15242
16411
+gst_wrapper_camera_bin_src_set_mode (GstBaseCameraSrc * bcamsrc,
15243
16412
+    GstCameraBinMode mode)
15244
16413
+{
15245
 
+  GstPhotography *photography = gst_base_camera_src_get_photography (bcamsrc);
 
16414
+  GstPhotography *photography =
 
16415
+      (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc),
 
16416
+      GST_TYPE_PHOTOGRAPHY);
15246
16417
+  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
15247
16418
+
15248
16419
+  if (self->output_selector) {
15348
16519
+  }
15349
16520
+}
15350
16521
+
15351
 
+static GstCaps *
15352
 
+gst_wrapper_camera_bin_src_get_allowed_input_caps (GstBaseCameraSrc * bcamsrc)
15353
 
+{
15354
 
+  GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
15355
 
+  GstCaps *caps = NULL;
15356
 
+  GstPad *pad = NULL, *peer_pad = NULL;
15357
 
+  GstState state;
15358
 
+  GstElement *videosrc;
15359
 
+
15360
 
+  videosrc = self->src_vid_src ? self->src_vid_src : self->app_vid_src;
15361
 
+
15362
 
+  if (!videosrc) {
15363
 
+    GST_WARNING_OBJECT (self, "no videosrc, can't get allowed caps");
15364
 
+    goto failed;
15365
 
+  }
15366
 
+
15367
 
+  if (self->allowed_caps) {
15368
 
+    GST_DEBUG_OBJECT (self, "returning cached caps");
15369
 
+    goto done;
15370
 
+  }
15371
 
+
15372
 
+  pad = gst_element_get_static_pad (videosrc, "src");
15373
 
+
15374
 
+  if (!pad) {
15375
 
+    GST_WARNING_OBJECT (self, "no srcpad in videosrc");
15376
 
+    goto failed;
15377
 
+  }
15378
 
+
15379
 
+  state = GST_STATE (videosrc);
15380
 
+
15381
 
+  /* Make this function work also in NULL state */
15382
 
+  if (state == GST_STATE_NULL) {
15383
 
+    GST_DEBUG_OBJECT (self, "setting videosrc to ready temporarily");
15384
 
+    peer_pad = gst_pad_get_peer (pad);
15385
 
+    if (peer_pad) {
15386
 
+      gst_pad_unlink (pad, peer_pad);
15387
 
+    }
15388
 
+    /* Set videosrc to READY to open video device */
15389
 
+    gst_element_set_locked_state (videosrc, TRUE);
15390
 
+    gst_element_set_state (videosrc, GST_STATE_READY);
15391
 
+  }
15392
 
+
15393
 
+  self->allowed_caps = gst_pad_get_caps (pad);
15394
 
+
15395
 
+  /* Restore state and re-link if necessary */
15396
 
+  if (state == GST_STATE_NULL) {
15397
 
+    GST_DEBUG_OBJECT (self, "restoring videosrc state %d", state);
15398
 
+    /* Reset videosrc to NULL state, some drivers seem to need this */
15399
 
+    gst_element_set_state (videosrc, GST_STATE_NULL);
15400
 
+    if (peer_pad) {
15401
 
+      gst_pad_link (pad, peer_pad);
15402
 
+      gst_object_unref (peer_pad);
15403
 
+    }
15404
 
+    gst_element_set_locked_state (videosrc, FALSE);
15405
 
+  }
15406
 
+
15407
 
+  gst_object_unref (pad);
15408
 
+
15409
 
+done:
15410
 
+  if (self->allowed_caps) {
15411
 
+    caps = gst_caps_copy (self->allowed_caps);
15412
 
+  }
15413
 
+  GST_DEBUG_OBJECT (self, "allowed caps:%" GST_PTR_FORMAT, caps);
15414
 
+failed:
15415
 
+  return caps;
15416
 
+}
15417
 
+
15418
16522
+/**
15419
16523
+ * update_aspect_filter:
15420
16524
+ * @self: camerasrc object
15652
16756
+
15653
16757
+  /* g_object_class_install_property .... */
15654
16758
+  g_object_class_install_property (gobject_class, PROP_VIDEO_SRC,
15655
 
+      g_param_spec_object ("video-src", "Video source",
 
16759
+      g_param_spec_object ("video-source", "Video source",
15656
16760
+          "The video source element to be used",
15657
16761
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
16762
+  g_object_class_install_property (gobject_class, PROP_VIDEO_SRC_FILTER,
 
16763
+      g_param_spec_object ("video-source-filter", "Video source filter",
 
16764
+          "Optional video source filter element",
 
16765
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
15658
16766
+
15659
16767
+  gstelement_class->change_state = gst_wrapper_camera_bin_src_change_state;
15660
16768
+
15662
16770
+      gst_wrapper_camera_bin_src_construct_pipeline;
15663
16771
+  gstbasecamerasrc_class->set_zoom = gst_wrapper_camera_bin_src_set_zoom;
15664
16772
+  gstbasecamerasrc_class->set_mode = gst_wrapper_camera_bin_src_set_mode;
15665
 
+  gstbasecamerasrc_class->get_allowed_input_caps =
15666
 
+      gst_wrapper_camera_bin_src_get_allowed_input_caps;
15667
16773
+  gstbasecamerasrc_class->start_capture =
15668
16774
+      gst_wrapper_camera_bin_src_start_capture;
15669
16775
+  gstbasecamerasrc_class->stop_capture =
15701
16807
+  self->video_renegotiate = TRUE;
15702
16808
+  self->image_renegotiate = TRUE;
15703
16809
+  self->mode = GST_BASE_CAMERA_SRC_CAST (self)->mode;
 
16810
+  self->app_vid_filter = NULL;
15704
16811
+}
15705
16812
+
15706
16813
+gboolean
15709
16816
+  return gst_element_register (plugin, "wrappercamerabinsrc", GST_RANK_NONE,
15710
16817
+      gst_wrapper_camera_bin_src_get_type ());
15711
16818
+}
15712
 
Index: trunk/gst/camerabin2/gstwrappercamerabinsrc.h
 
16819
Index: gst-plugins-good0.10/gst/camerabin2/gstwrappercamerabinsrc.h
15713
16820
===================================================================
15714
 
--- /dev/null
15715
 
+++ trunk/gst/camerabin2/gstwrappercamerabinsrc.h
15716
 
@@ -0,0 +1,129 @@
 
16821
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
16822
+++ gst-plugins-good0.10/gst/camerabin2/gstwrappercamerabinsrc.h        2012-02-09 14:44:27.408711038 +0200
 
16823
@@ -0,0 +1,131 @@
15717
16824
+/*
15718
16825
+ * GStreamer
15719
16826
+ * Copyright (C) 2010 Texas Instruments, Inc
15790
16897
+
15791
16898
+  /* source elements */
15792
16899
+  GstElement *src_vid_src;
 
16900
+  GstElement *video_filter;
15793
16901
+  GstElement *src_filter;
15794
16902
+  GstElement *src_zoom_crop;
15795
16903
+  GstElement *src_zoom_scale;
15810
16918
+
15811
16919
+  /* Application configurable elements */
15812
16920
+  GstElement *app_vid_src;
 
16921
+  GstElement *app_vid_filter;
15813
16922
+
15814
16923
+  /* Caps that videosrc supports */
15815
16924
+  GstCaps *allowed_caps;
15843
16952
+gboolean gst_wrapper_camera_bin_src_plugin_init (GstPlugin * plugin);
15844
16953
+
15845
16954
+#endif /* __GST_WRAPPER_CAMERA_BIN_SRC_H__ */
15846
 
Index: trunk/gst/jpegformat/Makefile.am
 
16955
Index: gst-plugins-good0.10/gst/jpegformat/Makefile.am
15847
16956
===================================================================
15848
 
--- /dev/null
15849
 
+++ trunk/gst/jpegformat/Makefile.am
 
16957
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
16958
+++ gst-plugins-good0.10/gst/jpegformat/Makefile.am     2012-02-09 14:44:27.408711038 +0200
15850
16959
@@ -0,0 +1,27 @@
15851
16960
+plugin_LTLIBRARIES = libgstjpegformat.la
15852
16961
+
15875
16984
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
15876
16985
+                      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
15877
16986
+       > $@
15878
 
Index: trunk/gst/jpegformat/gstjifmux.c
 
16987
Index: gst-plugins-good0.10/gst/jpegformat/gstjifmux.c
15879
16988
===================================================================
15880
 
--- /dev/null
15881
 
+++ trunk/gst/jpegformat/gstjifmux.c
 
16989
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
16990
+++ gst-plugins-good0.10/gst/jpegformat/gstjifmux.c     2012-02-09 14:44:27.408711038 +0200
15882
16991
@@ -0,0 +1,783 @@
15883
16992
+/* GStreamer
15884
16993
+ *
16019
17128
+{
16020
17129
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
16021
17130
+
16022
 
+  gst_element_class_add_pad_template (element_class,
16023
 
+      gst_static_pad_template_get (&gst_jif_mux_src_pad_template));
16024
 
+  gst_element_class_add_pad_template (element_class,
16025
 
+      gst_static_pad_template_get (&gst_jif_mux_sink_pad_template));
 
17131
+  gst_element_class_add_static_pad_template (element_class,
 
17132
+      &gst_jif_mux_src_pad_template);
 
17133
+  gst_element_class_add_static_pad_template (element_class,
 
17134
+      &gst_jif_mux_sink_pad_template);
16026
17135
+  gst_element_class_set_details_simple (element_class,
16027
17136
+      "JPEG stream muxer",
16028
 
+      "Video/Muxer",
 
17137
+      "Video/Formatter",
16029
17138
+      "Remuxes JPEG images with markers and tags",
16030
17139
+      "Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>");
16031
17140
+}
16663
17772
+
16664
17773
+  return ret;
16665
17774
+}
16666
 
Index: trunk/gst/jpegformat/gstjifmux.h
 
17775
Index: gst-plugins-good0.10/gst/jpegformat/gstjifmux.h
16667
17776
===================================================================
16668
 
--- /dev/null
16669
 
+++ trunk/gst/jpegformat/gstjifmux.h
 
17777
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
17778
+++ gst-plugins-good0.10/gst/jpegformat/gstjifmux.h     2012-02-09 14:44:27.408711038 +0200
16670
17779
@@ -0,0 +1,61 @@
16671
17780
+/* GStreamer
16672
17781
+ *
16729
17838
+G_END_DECLS
16730
17839
+
16731
17840
+#endif /* __GST_JFIF_MUX_H__ */
16732
 
Index: trunk/gst/jpegformat/gstjpegformat.c
 
17841
Index: gst-plugins-good0.10/gst/jpegformat/gstjpegformat.c
16733
17842
===================================================================
16734
 
--- /dev/null
16735
 
+++ trunk/gst/jpegformat/gstjpegformat.c
16736
 
@@ -0,0 +1,46 @@
 
17843
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
17844
+++ gst-plugins-good0.10/gst/jpegformat/gstjpegformat.c 2012-02-09 14:44:27.408711038 +0200
 
17845
@@ -0,0 +1,47 @@
16737
17846
+/* GStreamer
16738
17847
+ *
16739
17848
+ * jpegformat: a plugin for JPEG Interchange Format
16769
17878
+  if (!gst_element_register (plugin, "jpegparse", GST_RANK_NONE,
16770
17879
+          GST_TYPE_JPEG_PARSE))
16771
17880
+    return FALSE;
16772
 
+  if (!gst_element_register (plugin, "jifmux", GST_RANK_NONE, GST_TYPE_JIF_MUX))
 
17881
+  if (!gst_element_register (plugin, "jifmux", GST_RANK_SECONDARY,
 
17882
+          GST_TYPE_JIF_MUX))
16773
17883
+    return FALSE;
16774
17884
+
16775
17885
+  return TRUE;
16780
17890
+    "jpegformat",
16781
17891
+    "JPEG interchange format plugin",
16782
17892
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
16783
 
Index: trunk/gst/jpegformat/gstjpegformat.h
 
17893
Index: gst-plugins-good0.10/gst/jpegformat/gstjpegformat.h
16784
17894
===================================================================
16785
 
--- /dev/null
16786
 
+++ trunk/gst/jpegformat/gstjpegformat.h
 
17895
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
17896
+++ gst-plugins-good0.10/gst/jpegformat/gstjpegformat.h 2012-02-09 14:44:27.408711038 +0200
16787
17897
@@ -0,0 +1,92 @@
16788
17898
+/* GStreamer
16789
17899
+ *
16877
17987
+G_END_DECLS
16878
17988
+
16879
17989
+#endif /* __GST_JPEG_FORMAT_H__ */
16880
 
Index: trunk/gst/jpegformat/gstjpegparse.c
 
17990
Index: gst-plugins-good0.10/gst/jpegformat/gstjpegparse.c
16881
17991
===================================================================
16882
 
--- /dev/null
16883
 
+++ trunk/gst/jpegformat/gstjpegparse.c
 
17992
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
17993
+++ gst-plugins-good0.10/gst/jpegformat/gstjpegparse.c  2012-02-09 14:44:27.408711038 +0200
16884
17994
@@ -0,0 +1,1057 @@
16885
17995
+/* GStreamer
16886
17996
+ *
17023
18133
+{
17024
18134
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
17025
18135
+
17026
 
+  gst_element_class_add_pad_template (element_class,
17027
 
+      gst_static_pad_template_get (&gst_jpeg_parse_src_pad_template));
17028
 
+  gst_element_class_add_pad_template (element_class,
17029
 
+      gst_static_pad_template_get (&gst_jpeg_parse_sink_pad_template));
 
18136
+  gst_element_class_add_static_pad_template (element_class,
 
18137
+      &gst_jpeg_parse_src_pad_template);
 
18138
+  gst_element_class_add_static_pad_template (element_class,
 
18139
+      &gst_jpeg_parse_sink_pad_template);
17030
18140
+  gst_element_class_set_details_simple (element_class,
17031
18141
+      "JPEG stream parser",
17032
18142
+      "Video/Parser",
17322
18432
+  guint8 numcomps = 0;          /* Number of components in image
17323
18433
+                                   (1 for gray, 3 for YUV, etc.) */
17324
18434
+  guint8 precision;             /* precision (in bits) for the samples */
17325
 
+  guint8 compId[3];             /* unique value identifying each component */
17326
 
+  guint8 qtId[3];               /* quantization table ID to use for this comp */
 
18435
+  guint8 compId[3] G_GNUC_UNUSED;       /* unique value identifying each component */
 
18436
+  guint8 qtId[3] G_GNUC_UNUSED; /* quantization table ID to use for this comp */
17327
18437
+  guint8 blockWidth[3];         /* Array[numComponents] giving the number of
17328
18438
+                                   blocks (horiz) in this component */
17329
18439
+  guint8 blockHeight[3];        /* Same for the vertical part of this component */
17348
18458
+  if (!gst_byte_reader_get_uint8 (reader, &numcomps))
17349
18459
+    return FALSE;
17350
18460
+
17351
 
+  if (numcomps > 3)
 
18461
+  if (numcomps > 3)             /* FIXME */
17352
18462
+    return FALSE;
17353
18463
+
17354
18464
+  /* Get decimation and quantization table id for each component */
17939
19049
+
17940
19050
+  return ret;
17941
19051
+}
17942
 
Index: trunk/gst/jpegformat/gstjpegparse.h
 
19052
Index: gst-plugins-good0.10/gst/jpegformat/gstjpegparse.h
17943
19053
===================================================================
17944
 
--- /dev/null
17945
 
+++ trunk/gst/jpegformat/gstjpegparse.h
 
19054
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
19055
+++ gst-plugins-good0.10/gst/jpegformat/gstjpegparse.h  2012-02-09 14:44:27.408711038 +0200
17946
19056
@@ -0,0 +1,61 @@
17947
19057
+/* GStreamer
17948
19058
+ *