ef81a2c588dd4db7aaaba2fa1b86c02a12dcface
[harmattan/cameraplus] / lib / qtcamanalysisbin.cpp
1 /*!
2  * This file is part of CameraPlus.
3  *
4  * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "qtcamanalysisbin.h"
22 #include <QDebug>
23
24 #define FACTORY_NAME(x) gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(x)))
25
26 GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char *name) {
27   GstElement *bin = 0;
28
29   QList<GstElement *> added;
30
31   if (children.isEmpty()) {
32     return 0;
33   }
34
35   if (children.size() == 1) {
36     return qt_cam_analysis_bin_create(children.takeFirst(), name);
37   }
38
39   bin = gst_bin_new("analysis_bin_bin");
40
41   while (!children.isEmpty()) {
42     GstElement *elem = children.takeFirst();
43
44     if (!gst_bin_add(GST_BIN(bin), elem)) {
45       qWarning() << "Failed to add element" << FACTORY_NAME(elem) << "to bin";
46       gst_object_unref(elem);
47     }
48     else {
49       added << elem;
50     }
51   }
52
53   for (int x = 1; x < added.count(); x++) {
54     GstElement *elem = added[x];
55     GstElement *prev = added[x - 1];
56
57     if (!gst_element_link(prev, elem)) {
58       qWarning() << "Failed to link" << FACTORY_NAME(prev) << "and" << FACTORY_NAME(elem);
59     }
60   }
61
62   GstPad *pad = gst_element_get_static_pad(added.first(), "sink");
63   gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad));
64   gst_object_unref(GST_OBJECT(pad));
65
66   pad = gst_element_get_static_pad(added.last(), "src");
67   gst_element_add_pad(bin, gst_ghost_pad_new("src", pad));
68   gst_object_unref(GST_OBJECT(pad));
69
70   return qt_cam_analysis_bin_create(bin, name);
71 }
72
73 /*
74  *       -- identity -- ghost pad
75  * tee -
76  *       -- queue -- copy -- filters -- fakesink
77  */
78 GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name) {
79   GstPad *pad = 0;
80
81   GstElement *bin = gst_bin_new(name);
82
83   GstElement *tee = gst_element_factory_make("tee", "analysis-bin-tee");
84   GstElement *queue = gst_element_factory_make("queue", "analysis-bin-queue");
85   GstElement *fakesink = gst_element_factory_make("fakesink", "analysis-bin-fakesink");
86   GstElement *copy = gst_element_factory_make("copy", "analysis-bin-copy");
87   GstElement *identity = gst_element_factory_make("identity", "analysis-bin-identity");
88
89   if (!bin || !tee || !queue || !fakesink || !copy || !identity) {
90     qWarning() << "Failed to create some elements";
91     goto free_and_out;
92   }
93
94   gst_bin_add_many(GST_BIN(bin), tee, queue, copy, fakesink, child, identity, NULL);
95
96   g_object_set(tee, "silent", TRUE, NULL);
97   g_object_set(queue, "silent", TRUE, "leaky", 2, "max-size-buffers", 1, NULL);
98   g_object_set(fakesink, "silent", TRUE, "sync", FALSE, "async", FALSE, NULL);
99   g_object_set(identity, "silent", TRUE, "signal-handoffs", FALSE, NULL);
100
101   gst_element_link(tee, identity);
102   gst_element_link(tee, queue);
103   gst_element_link(queue, copy);
104   gst_element_link(copy, child);
105   gst_element_link(child, fakesink);
106
107   pad = gst_element_get_static_pad(tee, "sink");
108   gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad));
109   gst_object_unref(GST_OBJECT(pad));
110
111   pad = gst_element_get_static_pad(identity, "src");
112   gst_element_add_pad(bin, gst_ghost_pad_new("src", pad));
113   gst_object_unref(GST_OBJECT(pad));
114
115   pad = gst_element_get_static_pad(tee, "src0");
116   g_object_set(tee, "alloc-pad", pad, NULL);
117   gst_object_unref(GST_OBJECT(pad));
118
119   return bin;
120
121  free_and_out:
122   if (bin) {
123     gst_object_unref(bin);
124   }
125   else {
126     gst_object_unref(child);
127   }
128
129   if (tee) {
130     gst_object_unref(tee);
131   }
132
133   if (queue) {
134     gst_object_unref(queue);
135   }
136
137   if (copy) {
138     gst_object_unref(copy);
139   }
140
141   if (identity) {
142     gst_object_unref(identity);
143   }
144
145   if (fakesink) {
146     gst_object_unref(fakesink);
147   }
148
149   return 0;
150 }