tizen 2.3.1 release
[framework/multimedia/gst-plugins-ext0.10.git] / encodebin / src / gstencodebin.c
1 /*
2  * GStreamer encodebin
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation; either version 2.1 of the License, or (at your option)
11  * any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <string.h>
29 #include <gst/gst.h>
30 #include <gst/video/video.h>
31
32 #include "gstencodebin.h"
33
34 #ifdef GST_EXT_PAD_LINK_UNCHECKED
35 #define _GST_ELEMENT_LINK_MANY          gst_element_link_many_unchecked
36 #define _GST_ELEMENT_LINK                       gst_element_link_unchecked
37 #define _GST_PAD_LINK                           gst_pad_link_unchecked
38 #else
39 #define _GST_ELEMENT_LINK_MANY          gst_element_link_many
40 #define _GST_ELEMENT_LINK                       gst_element_link
41 #define _GST_PAD_LINK                           gst_pad_link
42 #endif
43
44 #ifndef VIDEO_ENC_QUE_TIME
45 #define VIDEO_ENC_QUE_TIME              1
46 #endif
47 #ifndef AUDIO_ENC_QUE_TIME
48 #define AUDIO_ENC_QUE_TIME      1
49 #endif
50
51 //define USE_ENCODER_QUEUE_SET
52 #ifdef USE_ENCODER_QUEUE_SET
53 #define ENCODER_QUEUE_SET(x_queue, x_byte, x_buffer, x_time /*sec*/) \
54 {\
55 g_object_set(G_OBJECT(x_queue), \
56                         "max-size-bytes", (guint)x_byte, \
57                         "max-size-buffers", (guint)x_buffer, \
58                         "max-size-time", (guint64)(x_time*GST_SECOND), \
59                         NULL); \
60                         GST_INFO("Set to [%s], max [%d] byte, max [%d] buffer, max [%d] time(sec) ", GST_OBJECT_NAME(x_queue), x_byte, x_buffer, x_time);\
61 }
62 #else
63 #define ENCODER_QUEUE_SET(x_queue, x_byte, x_buffer, x_time)
64 #endif
65
66 #define _GST_PAD_LINK_UNREF(srcpad, sinkpad, if_fail_goto)\
67 {\
68       GstPadLinkReturn ret = _GST_PAD_LINK(srcpad, sinkpad);\
69       if(ret != GST_PAD_LINK_OK) { \
70             GstObject *src_parent = gst_pad_get_parent(srcpad);\
71             GstObject *sink_parent = gst_pad_get_parent(sinkpad);\
72             char *src_name = NULL;\
73             char *sink_name = NULL;\
74             g_object_get((GObject *)src_parent, "name", &src_name, NULL);\
75             g_object_get((GObject *)sink_parent, "name", &sink_name, NULL);\
76             GST_ERROR("src[%s] - sink[%s] link failed", src_name, sink_name);\
77             gst_object_unref(src_parent); src_parent = NULL;\
78             gst_object_unref(sink_parent); sink_parent = NULL;\
79             if (src_name) {\
80                   free(src_name); src_name = NULL;\
81             }\
82             if (sink_name) {\
83                   free(sink_name); sink_name = NULL;\
84             }\
85             gst_object_unref(srcpad); srcpad = NULL;\
86             gst_object_unref(sinkpad); sinkpad = NULL;\
87             goto if_fail_goto;\
88       }\
89       gst_object_unref(srcpad); srcpad = NULL;\
90       gst_object_unref(sinkpad); sinkpad = NULL;\
91 }
92
93 #define _GST_PAD_UNLINK_UNREF(srcpad, sinkpad)\
94 {\
95       gst_pad_unlink(srcpad, sinkpad);\
96       gst_object_unref(srcpad); srcpad = NULL;\
97       gst_object_unref(sinkpad); sinkpad = NULL;\
98 }
99
100 #define DEFAULT_PROP_PROFILE            0
101 #define DEFAULT_PROP_HIGH_SPEED         0
102 #define DEFAULT_PROP_VENC_NAME          "ffenc_h263"
103 #define DEFAULT_PROP_AENC_NAME          "secenc_amr"
104 #define DEFAULT_PROP_IENC_NAME          "jpegenc"
105 #define DEFAULT_PROP_MUX_NAME           "ffmux_3gp"
106 #define DEFAULT_PROP_VCONV_NAME         "ffmpegcolorspace"
107
108 /* props */
109 enum
110 {
111         PROP_0,
112         // encodebin mode :  a/v, audio only, stillshot
113         PROP_PROFILE,
114         //support slow motion capture
115         PROP_HIGH_SPEED,
116         //elements name
117         PROP_VENC_NAME,
118         PROP_AENC_NAME,
119         PROP_IENC_NAME,
120         PROP_MUX_NAME,
121         PROP_VCONV_NAME,
122         //caps
123         PROP_VCAPS,
124         PROP_ACAPS,
125         PROP_ICAPS,
126         //functions
127         PROP_AUTO_AUDIO_CONVERT,
128         PROP_AUTO_AUDIO_RESAMPLE,
129         PROP_AUTO_COLORSPACE,
130         PROP_BLOCK,
131         PROP_PAUSE,
132         PROP_VENC_QUEUE,
133         PROP_AENC_QUEUE,
134         //elements pointer
135         PROP_VIDEO_ENC,
136         PROP_AUDIO_ENC,
137         PROP_IMAGE_ENC,
138         PROP_MUX,
139         PROP_VIDEO_CONV,
140         //options
141         PROP_USE_VIDEO_TOGGLE,
142 };
143
144 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
145 /* signals */
146 enum
147 {
148   SIGNAL_STREAM_BLOCK,
149   SIGNAL_STREAM_UNBLOCK,
150   SIGNAL_STREAM_PAUSE,
151   SIGNAL_STREAM_RESUME,
152   LAST_SIGNAL
153 };
154 #endif
155
156 typedef enum {
157         ENCODEBIN_ELEMENT_VENC,
158         ENCODEBIN_ELEMENT_AENC,
159         ENCODEBIN_ELEMENT_IENC,
160         ENCODEBIN_ELEMENT_MUX,
161         ENCODEBIN_ELEMENT_VIDEO_CONV
162 }GstEncodeBinElement;
163
164 typedef enum {
165         ENCODEBIN_MUX_AUDIO_SINK,
166         ENCODEBIN_MUX_VIDEO_SINK,
167 }GstEncodeBinMuxSinkPad;
168
169
170 /* FIX ME */
171
172 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
173 # define ENDIANNESS   "LITTLE_ENDIAN, BIG_ENDIAN"
174 #else
175 # define ENDIANNESS   "BIG_ENDIAN, LITTLE_ENDIAN"
176 #endif
177
178 /* generic templates */
179 #define STATIC_AUDIO_CAPS \
180 GST_STATIC_CAPS ( \
181   "audio/x-raw-float, " \
182     "rate = (int) [ 1, MAX ], " \
183     "channels = (int) [ 1, 8 ], " \
184     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
185     "width = (int) 64;" \
186   "audio/x-raw-float, " \
187     "rate = (int) [ 1, MAX ], " \
188     "channels = (int) [ 1, 8 ], " \
189     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
190     "width = (int) 32;" \
191   "audio/x-raw-int, " \
192     "rate = (int) [ 1, MAX ], " \
193     "channels = (int) [ 1, 8 ], " \
194     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
195     "width = (int) 32, " \
196     "depth = (int) [ 1, 32 ], " \
197     "signed = (boolean) { true, false }; " \
198   "audio/x-raw-int, "   \
199     "rate = (int) [ 1, MAX ], " \
200     "channels = (int) [ 1, 8 ], "       \
201     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "        \
202     "width = (int) 24, "        \
203     "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; "  \
204   "audio/x-raw-int, " \
205     "rate = (int) [ 1, MAX ], " \
206     "channels = (int) [ 1, 8 ], " \
207     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
208     "width = (int) 16, " \
209     "depth = (int) [ 1, 16 ], " \
210     "signed = (boolean) { true, false }; " \
211   "audio/x-raw-int, " \
212     "rate = (int) [ 1, MAX ], " \
213     "channels = (int) [ 1, 8 ], " \
214     "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
215     "width = (int) 8, " \
216     "depth = (int) [ 1, 8 ], " \
217     "signed = (boolean) { true, false } " \
218 )
219
220 #define STATIC_VIDEO_CAPS \
221 GST_STATIC_CAPS ( \
222   "video/x-raw-yuv," \
223     "width = (int) [ 1, 2147483647 ]," \
224     "height = (int) [ 1, 2147483647 ]," \
225     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
226     "format = (fourcc) I420;" \
227   "video/x-raw-yuv," \
228     "width = (int) [ 1, 2147483647 ]," \
229     "height = (int) [ 1, 2147483647 ]," \
230     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
231     "format = (fourcc) YV12;" \
232   "video/x-raw-yuv," \
233     "width = (int) [ 1, 2147483647 ]," \
234     "height = (int) [ 1, 2147483647 ]," \
235     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
236     "format = (fourcc) YUY2;" \
237   "video/x-raw-rgb," \
238     "width = (int) [ 1, 2147483647 ]," \
239     "height = (int) [ 1, 2147483647 ]," \
240     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
241     "bpp = (int) 24," \
242     "depth = (int) 24," \
243     "red_mask = (int) 16711680," \
244     "green_mask = (int) 65280," \
245     "blue_mask = (int) 255," \
246     "endianness = (int) 4321;" \
247   "video/x-raw-rgb," \
248     "width = (int) [ 1, 2147483647 ]," \
249     "height = (int) [ 1, 2147483647 ]," \
250     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
251     "bpp = (int) 24," \
252     "depth = (int) 24," \
253     "red_mask = (int) 255," \
254     "green_mask = (int) 65280," \
255     "blue_mask = (int) 16711680," \
256     "endianness = (int) 4321;" \
257   "video/x-raw-yuv," \
258     "width = (int) [ 1, 2147483647 ]," \
259     "height = (int) [ 1, 2147483647 ]," \
260     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
261     "format = (fourcc) Y42B;" \
262     "video/x-raw-yuv," \
263     "width = (int) [ 1, 2147483647 ]," \
264     "height = (int) [ 1, 2147483647 ]," \
265     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
266     "format = (fourcc) Y444;" \
267   "video/x-raw-rgb," \
268     "width = (int) [ 1, 2147483647 ]," \
269     "height = (int) [ 1, 2147483647 ]," \
270     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
271     "bpp = (int) 32," \
272     "depth = (int) 32," \
273     "red_mask = (int) 65280," \
274     "green_mask = (int) 16711680," \
275     "blue_mask = (int) -16777216," \
276     "alpha_mask = (int) 255," \
277     "endianness = (int) 4321;" \
278   "video/x-raw-rgb," \
279     "width = (int) [ 1, 2147483647 ]," \
280     "height = (int) [ 1, 2147483647 ]," \
281     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
282     "bpp = (int) 32," \
283     "depth = (int) 32," \
284     "red_mask = (int) 16711680," \
285     "green_mask = (int) 65280," \
286     "blue_mask = (int) 255," \
287     "alpha_mask = (int) -16777216," \
288     "endianness = (int) 4321;" \
289   "video/x-raw-rgb," \
290     "width = (int) [ 1, 2147483647 ]," \
291     "height = (int) [ 1, 2147483647 ]," \
292     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
293     "bpp = (int) 32," \
294     "depth = (int) 32," \
295     "red_mask = (int) 255," \
296     "green_mask = (int) 65280," \
297     "blue_mask = (int) 16711680," \
298     "alpha_mask = (int) -16777216," \
299     "endianness = (int) 4321;" \
300   "video/x-raw-rgb," \
301     "width = (int) [ 1, 2147483647 ]," \
302     "height = (int) [ 1, 2147483647 ]," \
303     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
304     "bpp = (int) 32," \
305     "depth = (int) 32," \
306     "red_mask = (int) -16777216," \
307     "green_mask = (int) 16711680," \
308     "blue_mask = (int) 65280," \
309     "alpha_mask = (int) 255," \
310     "endianness = (int) 4321;" \
311   "video/x-raw-rgb," \
312     "width = (int) [ 1, 2147483647 ]," \
313     "height = (int) [ 1, 2147483647 ]," \
314     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
315     "bpp = (int) 32," \
316     "depth = (int) 24," \
317     "red_mask = (int) 65280," \
318     "green_mask = (int) 16711680," \
319     "blue_mask = (int) -16777216," \
320     "endianness = (int) 4321;" \
321   "video/x-raw-rgb," \
322     "width = (int) [ 1, 2147483647 ]," \
323     "height = (int) [ 1, 2147483647 ]," \
324     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
325     "bpp = (int) 32," \
326     "depth = (int) 24," \
327     "red_mask = (int) 255," \
328     "green_mask = (int) 65280," \
329     "blue_mask = (int) 16711680," \
330     "endianness = (int) 4321;" \
331   "video/x-raw-rgb," \
332     "width = (int) [ 1, 2147483647 ]," \
333     "height = (int) [ 1, 2147483647 ]," \
334     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
335     "bpp = (int) 32," \
336     "depth = (int) 24," \
337     "red_mask = (int) 16711680," \
338     "green_mask = (int) 65280," \
339     "blue_mask = (int) 255," \
340     "endianness = (int) 4321;" \
341   "video/x-raw-rgb," \
342     "width = (int) [ 1, 2147483647 ]," \
343     "height = (int) [ 1, 2147483647 ]," \
344     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
345     "bpp = (int) 32," \
346     "depth = (int) 24," \
347     "red_mask = (int) -16777216," \
348     "green_mask = (int) 16711680," \
349     "blue_mask = (int) 65280," \
350     "endianness = (int) 4321;" \
351   "video/x-raw-yuv," \
352     "width = (int) [ 1, 2147483647 ]," \
353     "height = (int) [ 1, 2147483647 ]," \
354     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
355     "format = (fourcc) YUV9;" \
356   "video/x-raw-yuv," \
357     "width = (int) [ 1, 2147483647 ]," \
358     "height = (int) [ 1, 2147483647 ]," \
359     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
360     "format = (fourcc) YVU9;" \
361   "video/x-raw-yuv," \
362     "width = (int) [ 1, 2147483647 ]," \
363     "height = (int) [ 1, 2147483647 ]," \
364     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
365     "format = (fourcc) Y41B;" \
366   "video/x-raw-rgb," \
367     "width = (int) [ 1, 2147483647 ]," \
368     "height = (int) [ 1, 2147483647 ]," \
369     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
370     "bpp = (int) 16," \
371     "depth = (int) 16," \
372     "red_mask = (int) 63488," \
373     "green_mask = (int) 2016," \
374     "blue_mask = (int) 31," \
375     "endianness = (int) 1234;" \
376   "video/x-raw-rgb," \
377     "width = (int) [ 1, 2147483647 ]," \
378     "height = (int) [ 1, 2147483647 ]," \
379     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
380     "bpp = (int) 16," \
381     "depth = (int) 15," \
382     "red_mask = (int) 31744," \
383     "green_mask = (int) 992," \
384     "blue_mask = (int) 31," \
385     "endianness = (int) 1234;" \
386   "video/x-raw-gray," \
387     "width = (int) [ 1, 2147483647 ]," \
388     "height = (int) [ 1, 2147483647 ]," \
389     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
390     "bpp = (int) 8," \
391     "depth = (int) 8;" \
392   "video/x-raw-rgb," \
393     "width = (int) [ 1, 2147483647 ]," \
394     "height = (int) [ 1, 2147483647 ]," \
395     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
396     "bpp = (int) 8," \
397     "depth = (int) 8," \
398     "endianness = (int) 1234;" \
399   "video/x-raw-yuv," \
400     "width = (int) [ 1, 2147483647 ]," \
401     "height = (int) [ 1, 2147483647 ]," \
402     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
403     "format = (fourcc) UYVY;" \
404   "video/x-raw-yuv," \
405     "width = (int) [ 1, 2147483647 ]," \
406     "height = (int) [ 1, 2147483647 ]," \
407     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
408     "format = (fourcc) IYU1;" \
409   "video/x-raw-yuv," \
410     "width = (int) [ 1, 2147483647 ]," \
411     "height = (int) [ 1, 2147483647 ]," \
412     "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
413     "format = (fourcc) AYUV " \
414 )
415
416
417 static GstStaticPadTemplate encoder_bin_src_template =
418 GST_STATIC_PAD_TEMPLATE ("src",
419     GST_PAD_SRC,
420     GST_PAD_ALWAYS,
421     GST_STATIC_CAPS_ANY);
422
423 static GstStaticPadTemplate encoder_bin_video_sink_template =
424 GST_STATIC_PAD_TEMPLATE ("video",
425     GST_PAD_SINK,
426     GST_PAD_REQUEST,
427     STATIC_VIDEO_CAPS
428     );
429
430 static GstStaticPadTemplate encoder_bin_audio_sink_template =
431 GST_STATIC_PAD_TEMPLATE ("audio",
432     GST_PAD_SINK,
433     GST_PAD_REQUEST,
434     STATIC_AUDIO_CAPS
435     );
436
437 static GstStaticPadTemplate encoder_bin_image_sink_template =
438 GST_STATIC_PAD_TEMPLATE ("image",
439     GST_PAD_SINK,
440     GST_PAD_REQUEST,
441     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
442     );
443
444 GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug);
445 #define GST_CAT_DEFAULT gst_encode_bin_debug
446
447 static void gst_encode_bin_class_init (GstEncodeBinClass *klass);
448 static void gst_encode_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
449 static void gst_encode_bin_set_property (GObject * object,  guint prop_id, const GValue * value, GParamSpec * pspec);
450 static void gst_encode_bin_init (GstEncodeBin * encodebin);
451 static void gst_encode_bin_dispose (GObject * object);
452 static void gst_encode_bin_finalize (GObject * object);
453 static GstPad *gst_encode_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name);
454
455 static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, GstStateChange transition);
456 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
457 static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad);
458 static gint pad_compare_name (GstPad * pad1, const gchar * name);
459 static gboolean gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
460 #if 0 //disable unused function
461 static gboolean gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean profile);
462 static void gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement);
463 static gboolean gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
464 static gboolean gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element);
465 #endif //disable unused function
466 static gboolean gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element);
467 static gboolean gst_encode_bin_link_elements (GstEncodeBin *encodebin);
468 static gboolean gst_encode_bin_unlink_elements (GstEncodeBin *encodebin);
469 static gboolean gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data);
470 static gboolean gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data);
471 static gboolean gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data);
472 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value);
473 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value);
474 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
475 static gboolean gst_encode_bin_release_pipeline (GstElement *element, gpointer user_data);
476 static gboolean gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps);
477 static gboolean gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps);
478 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps);
479 static GstPad*  gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type);
480
481 //Data probe
482 static gboolean gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
483 static gboolean gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
484 static gboolean gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
485
486 static GstElementClass *parent_class;
487
488 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
489 static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 };
490 #endif
491
492 static const GstElementDetails gst_encode_bin_details =
493 GST_ELEMENT_DETAILS ("Samsung Electronics Co. Encoder Bin",
494         "Generic/Bin/Encoder",
495         "Autoplug and encode to muxed media",
496         "Jeonghoon Park <jh1979.park@samsung.com>, Wonhyung Cho <wh01.cho@samsung.com>, Sangho Park <sangho.g.park@samsung.com>");
497
498 typedef enum {
499         GST_ENCODE_BIN_PROFILE_AV,
500         GST_ENCODE_BIN_PROFILE_AUDIO,
501         GST_ENCODE_BIN_PROFILE_IMAGE,
502 } GstEncodeBinProfile;
503
504 GType
505 gst_encode_bin_profile_get_type (void)
506 {
507         static GType encode_bin_profile_type = 0;
508         static const GEnumValue profile_types[] = {
509                 {GST_ENCODE_BIN_PROFILE_AV, "Audio and Video Recording", "A/V"},
510                 {GST_ENCODE_BIN_PROFILE_AUDIO, "Audio Only Recording", "Audio"},
511                 {GST_ENCODE_BIN_PROFILE_IMAGE, "Image Stillshot", "Image"},
512                 {0, NULL, NULL}
513         };
514
515         if (!encode_bin_profile_type) {
516                 encode_bin_profile_type =
517                 g_enum_register_static ("GstEncodeBinProfile",profile_types);
518         }
519         return encode_bin_profile_type;
520 }
521
522 GType
523 gst_encode_bin_get_type (void)
524 {
525         static GType gst_encode_bin_type = 0;
526
527         if (!gst_encode_bin_type) {
528                 static const GTypeInfo gst_encode_bin_info = {
529                         sizeof (GstEncodeBinClass),
530                         NULL,
531                         NULL,
532                         (GClassInitFunc) gst_encode_bin_class_init,
533                         NULL,
534                         NULL,
535                         sizeof (GstEncodeBin),
536                         0,
537                         (GInstanceInitFunc) gst_encode_bin_init,
538                         NULL
539         };
540
541         gst_encode_bin_type =
542                 g_type_register_static (GST_TYPE_BIN, "GstEncodeBin",
543                 &gst_encode_bin_info, 0);
544   }
545
546         return gst_encode_bin_type;
547 }
548
549 static void
550 queue_overun_cb (GstElement * queue, GstEncodeBin *encodebin)
551 {
552 #if 0
553         guint queue_size = 0;
554         guint queue_bufnum = 0;
555 //      guint64 queue_time= (guint64)0;
556
557         GstClockTime now = gst_util_get_timestamp ();
558
559         g_object_get(G_OBJECT(queue), "current-level-bytes", &queue_size,
560                                                                 "current-level-buffers", &queue_bufnum,
561         //                                                      "current-level-time", &queue_time,
562                                                                 NULL);
563        GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
564            ("[%" GST_TIME_FORMAT "][%s], [%u b], [%u]",
565            GST_TIME_ARGS(now), GST_OBJECT_NAME(queue), queue_size, queue_bufnum), (NULL));
566 #else
567        GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
568            ("%s overrun", GST_OBJECT_NAME(queue)), (NULL));
569 #endif
570 }
571
572 static void
573 gst_encode_bin_get_property (GObject * object,
574     guint prop_id, GValue * value, GParamSpec * pspec)
575 {
576         GstEncodeBin *encodebin;
577
578         encodebin = GST_ENCODE_BIN (object);
579
580         switch (prop_id) {
581                 case PROP_PROFILE:
582                         g_value_set_enum (value, encodebin->profile);
583                         break;
584                 case PROP_HIGH_SPEED:
585                         g_value_set_int (value, encodebin->high_speed_fps);
586                         break;
587                 //elements name
588                 case PROP_VENC_NAME:
589                         g_value_set_string (value, encodebin->venc_name);
590                         break;
591                 case PROP_AENC_NAME:
592                         g_value_set_string (value, encodebin->aenc_name);
593                         break;
594                 case PROP_IENC_NAME:
595                         g_value_set_string (value, encodebin->ienc_name);
596                         break;
597                 case PROP_MUX_NAME:
598                         g_value_set_string (value, encodebin->mux_name);
599                         break;
600                 case PROP_VCONV_NAME:
601                         g_value_set_string (value, encodebin->vconv_name);
602                         break;
603                 //caps
604                 case PROP_VCAPS:
605                         gst_value_set_caps (value, encodebin->vcaps);
606                         break;
607                 case PROP_ACAPS:
608                         gst_value_set_caps (value, encodebin->acaps);
609                         break;
610                 case PROP_ICAPS:
611                         gst_value_set_caps (value, encodebin->icaps);
612                         break;
613                 //functions
614                 case PROP_AUTO_AUDIO_CONVERT:
615                         g_value_set_boolean (value, encodebin->auto_audio_convert);
616                         break;
617                 case PROP_AUTO_AUDIO_RESAMPLE:
618                         g_value_set_boolean (value, encodebin->auto_audio_resample);
619                         break;
620                 case PROP_AUTO_COLORSPACE:
621                         g_value_set_boolean (value, encodebin->auto_color_space);
622                         break;
623                 case PROP_BLOCK:
624                         g_value_set_boolean (value, encodebin->block);
625                         break;
626                 case PROP_PAUSE:
627                         g_value_set_boolean (value, encodebin->pause);
628                         break;
629                 case PROP_VENC_QUEUE:
630 //                      g_value_set_boolean (value, encodebin->use_venc_queue);
631                         if((encodebin->video_encode_queue == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
632                                 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
633                                 if(encodebin->video_encode_queue != NULL)
634                                         gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
635                         }
636                         g_value_set_object (value, encodebin->video_encode_queue);
637                         break;
638                 case PROP_AENC_QUEUE:
639 //                      g_value_set_boolean (value, encodebin->use_aenc_queue);
640                         if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
641                                 encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue");
642                                 if(encodebin->audio_encode_queue != NULL)
643                                         gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
644                         }
645                         g_value_set_object (value, encodebin->audio_encode_queue);
646                         break;
647                 //elements pointer
648                 case PROP_VIDEO_ENC:
649                         if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
650                                 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, NULL);
651                                 if(encodebin->video_encode != NULL)
652                                         gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
653                         }
654                         g_value_set_object (value, encodebin->video_encode);
655                         break;
656                 case PROP_AUDIO_ENC:
657                         if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
658                                 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
659                                 if(encodebin->audio_encode != NULL)
660                                         gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
661                         }
662                         g_value_set_object (value, encodebin->audio_encode);
663                         break;
664                 case PROP_IMAGE_ENC:
665                         if(encodebin->image_encode == NULL && (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE)) {
666                                 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
667                                 if(encodebin->image_encode != NULL)
668                                         gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
669                         }
670                         g_value_set_object (value, encodebin->image_encode);
671                         break;
672                 case PROP_MUX:
673                         if(encodebin->mux == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
674                                 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
675                                 if(encodebin->mux != NULL)
676                                         gst_bin_add(GST_BIN(encodebin), encodebin->mux);
677                         }
678                         g_value_set_object (value, encodebin->mux);
679                         break;
680                 case PROP_VIDEO_CONV:
681                         if(encodebin->color_space == NULL && (encodebin->profile != GST_ENCODE_BIN_PROFILE_AUDIO)) {
682                                 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
683                                 if(encodebin->color_space != NULL)
684                                         gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
685                         }
686                         g_value_set_object (value, encodebin->color_space);
687                         break;
688                 case PROP_USE_VIDEO_TOGGLE:
689                         g_value_set_boolean( value, encodebin->use_video_toggle );
690                         break;
691                 default:
692                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
693                         break;
694         }
695 }
696
697 static void
698 gst_encode_bin_set_property (GObject * object,
699     guint prop_id, const GValue * value, GParamSpec * pspec)
700 {
701         GstEncodeBin *encodebin;
702
703         encodebin = GST_ENCODE_BIN (object);
704
705         switch (prop_id) {
706                 case PROP_PROFILE:
707                         encodebin->profile = g_value_get_enum (value);
708                         /*
709                         gboolean newprofile = g_value_get_enum (value);
710                         if(encodebin->profile != newprofile) {
711                           gst_encode_bin_change_profile(encodebin, newprofile);
712                         encodebin->profile = newprofile;
713                                 }
714                         */
715                         break;
716                 case PROP_HIGH_SPEED:
717                         encodebin->high_speed_fps = g_value_get_int (value);
718                         break;
719                 case PROP_VENC_NAME: {
720                         const gchar  *new_name;
721                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
722                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
723                                 break;
724                         }
725                         new_name = g_value_get_string (value);
726
727                         if(encodebin->video_encode == NULL) {
728                                 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
729                                         encodebin->venc_name = g_strdup (new_name);
730                         } else {
731                                 if(strcmp (encodebin->venc_name, new_name)) {
732                                         gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
733                                         if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
734                                                 encodebin->venc_name = g_strdup (new_name);
735                                 }
736                         }
737                         break;
738                 }
739                 case PROP_AENC_NAME: {
740                         const gchar  *new_name;
741                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
742                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
743                                 break;
744                         }
745                         new_name = g_value_get_string (value);
746
747                         if(encodebin->audio_encode == NULL) {
748                                 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
749                                         encodebin->aenc_name = g_strdup (new_name);
750                         } else {
751                                 if(strcmp (encodebin->aenc_name, new_name)) {
752                                         gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
753                                         if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
754                                                 encodebin->aenc_name = g_strdup (new_name);
755                                 }
756                         }
757                         break;
758                 }
759                 case PROP_IENC_NAME: {
760                         const gchar  *new_name;
761                         if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
762                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
763                                 break;
764                         }
765                         new_name = g_value_get_string (value);
766
767                         if(encodebin->image_encode == NULL) {
768                                 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
769                                         encodebin->ienc_name = g_strdup (new_name);
770                         } else {
771                                 if(strcmp (encodebin->ienc_name, new_name)) {
772                                         gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
773                                         if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
774                                                 encodebin->ienc_name = g_strdup (new_name);
775                                 }
776                         }
777                         break;
778                 }
779                 case PROP_MUX_NAME: {
780                         const gchar  *new_name;
781                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
782                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
783                                 break;
784                         }
785                         new_name = g_value_get_string (value);
786
787                         if(encodebin->mux == NULL) {
788                                 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
789                                         encodebin->mux_name = g_strdup (new_name);
790                         } else {
791                                 if(strcmp (encodebin->mux_name, new_name)) {
792                                         gst_encode_bin_remove_element(encodebin, encodebin->mux);
793                                         if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
794                                                 encodebin->mux_name = g_strdup (new_name);
795                                 }
796                         }
797                         break;
798                 }
799                 case PROP_VCONV_NAME: {
800                         const gchar  *new_name;
801                         if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
802                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
803                                 break;
804                         }
805                         new_name = g_value_get_string(value);
806
807                         if (encodebin->color_space == NULL) {
808                                 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
809                                         encodebin->vconv_name = g_strdup (new_name);
810                         } else {
811                                 if(strcmp (encodebin->vconv_name, new_name)) {
812                                         gst_encode_bin_remove_element(encodebin, encodebin->color_space);
813                                         if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
814                                                 encodebin->vconv_name = g_strdup (new_name);
815                                 }
816                         }
817                         break;
818                 }
819                 //caps
820                 case PROP_VCAPS: {
821                         GstCaps *new_caps;
822                         GstCaps *old_caps;
823                         const GstCaps *new_caps_val = gst_value_get_caps (value);
824
825                         if (new_caps_val == NULL) {
826                                 new_caps = gst_caps_new_any ();
827                         } else {
828                                 new_caps = (GstCaps *) new_caps_val;
829                                 gst_caps_ref (new_caps);
830                         }
831
832                         old_caps = encodebin->vcaps;
833                         encodebin->vcaps = new_caps;
834                         gst_caps_unref (old_caps);
835                         break;
836                 }
837                 case PROP_ACAPS: {
838                         GstCaps *new_caps;
839                         GstCaps *old_caps;
840                         const GstCaps *new_caps_val = gst_value_get_caps (value);
841
842                         if (new_caps_val == NULL) {
843                                 new_caps = gst_caps_new_any ();
844                         } else {
845                                 new_caps = (GstCaps *) new_caps_val;
846                                 gst_caps_ref (new_caps);
847                         }
848
849                         old_caps = encodebin->acaps;
850                         encodebin->acaps = new_caps;
851                         gst_caps_unref (old_caps);
852                         break;
853                 }
854                 case PROP_ICAPS: {
855                         GstCaps *new_caps;
856                         GstCaps *old_caps;
857                         const GstCaps *new_caps_val = gst_value_get_caps (value);
858
859                         if (new_caps_val == NULL) {
860                                 new_caps = gst_caps_new_any ();
861                         } else {
862                                 new_caps = (GstCaps *) new_caps_val;
863                                 gst_caps_ref (new_caps);
864                         }
865
866                         old_caps = encodebin->icaps;
867                         encodebin->icaps = new_caps;
868                         gst_caps_unref (old_caps);
869                         break;
870                 }
871                 //functions
872                 case PROP_AUTO_AUDIO_CONVERT:
873                    encodebin->auto_audio_convert = g_value_get_boolean (value);
874                   break;
875                 case PROP_AUTO_AUDIO_RESAMPLE:
876                   encodebin->auto_audio_resample = g_value_get_boolean (value);
877                   break;
878                 case PROP_AUTO_COLORSPACE:
879                   encodebin->auto_color_space = g_value_get_boolean (value);
880                   break;
881                 case PROP_BLOCK: {
882                         gboolean newval = g_value_get_boolean (value);
883                         if(encodebin->block != newval) {
884                                 if(!gst_encode_bin_block(encodebin, newval)) {
885 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
886                                         if(newval) {
887                                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, FALSE);
888                                         } else {
889                                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, FALSE);
890                                         }
891 #endif
892                                         break;
893                                 }
894                         }
895 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
896                         if(newval) {
897                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, TRUE);
898                         } else {
899                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, TRUE);
900                         }
901 #endif
902                         break;
903                 }
904                 case PROP_PAUSE: {
905                         gboolean newval = g_value_get_boolean (value);
906                         if(encodebin->pause != newval) {
907                                 if(!gst_encode_bin_pause(encodebin, newval))
908                                         break;
909                         }
910 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
911                         if(newval) {
912                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
913                         } else {
914                                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
915                         }
916 #endif
917                         break;
918                 }
919                 case PROP_VENC_QUEUE:
920 //                encodebin->use_venc_queue = g_value_get_boolean (value);
921                 {
922                         GstElement *newelement = g_value_get_object (value);
923                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
924                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
925                                 break;
926                         }
927                         if(newelement != NULL) {
928                                 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
929                                 encodebin->video_encode_queue = newelement;
930                                 gst_object_ref (encodebin->video_encode_queue);
931                                 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode_queue)); // take ownership ??
932                                 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
933                         }
934                         break;
935                 }
936                   break;
937                 case PROP_AENC_QUEUE:
938 //                encodebin->use_aenc_queue = g_value_get_boolean (value);
939                 {
940                         GstElement *newelement = g_value_get_object (value);
941                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
942                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
943                                 break;
944                         }
945                         if(newelement != NULL) {
946                                 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
947                                 encodebin->audio_encode_queue = newelement;
948                                 gst_object_ref (encodebin->audio_encode_queue);
949                                 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode_queue));
950                                 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
951                         }
952                         break;
953                 }
954                   break;
955                 case PROP_VIDEO_ENC:
956                 {
957                         GstElement *newelement = g_value_get_object (value);
958                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
959                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
960                                 break;
961                         }
962                         if(newelement != NULL) {
963                                 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
964                                 encodebin->video_encode = newelement;
965                                 gst_object_ref (encodebin->video_encode);
966                                 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
967                                 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
968                         }
969                         break;
970                 }
971                 case PROP_AUDIO_ENC:
972                 {
973                         GstElement *newelement = g_value_get_object (value);
974                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
975                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
976                                 break;
977                         }
978                         if(newelement != NULL) {
979                                 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
980                                 encodebin->audio_encode = newelement;
981                                 gst_object_ref (encodebin->audio_encode);
982                                 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
983                                 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
984                         }
985                         break;
986                 }
987                 case PROP_IMAGE_ENC: {
988                         GstElement *newelement = g_value_get_object (value);
989                         if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
990                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
991                                 break;
992                         }
993                         if(newelement != NULL) {
994                                 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
995                                 encodebin->image_encode = newelement;
996                                 gst_object_ref (encodebin->image_encode);
997                                 gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
998                                 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
999                         }
1000                         break;
1001                 }
1002                 case PROP_MUX: {
1003                         GstElement *newelement = g_value_get_object (value);
1004                         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
1005                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
1006                                 break;
1007                         }
1008                         if(newelement != NULL) {
1009                                 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1010                                 encodebin->mux = newelement;
1011                                 gst_object_ref (encodebin->mux);
1012                                 gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
1013                                 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1014                         }
1015                         break;
1016                 }
1017                 case PROP_VIDEO_CONV: {
1018                         GstElement *newelement = g_value_get_object (value);
1019                         if(encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
1020                                 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
1021                                 break;
1022                         }
1023                         if(newelement != NULL) {
1024                                 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1025                                 encodebin->color_space = newelement;
1026                                 gst_object_ref (encodebin->color_space);
1027                                 gst_object_sink (GST_OBJECT_CAST (encodebin->color_space));
1028                                 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1029                         }
1030                         break;
1031                 }
1032                 case PROP_USE_VIDEO_TOGGLE:
1033                         encodebin->use_video_toggle = g_value_get_boolean( value );
1034                         break;
1035                 default:
1036                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1037                         break;
1038         }
1039 }
1040
1041 static GstPad *
1042 gst_encode_bin_request_new_pad (GstElement * element,
1043     GstPadTemplate * templ, const gchar * req_name)
1044 {
1045         GstEncodeBin *encodebin = NULL;
1046         GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
1047         GstPad *pad = NULL;
1048
1049         g_return_val_if_fail (templ != NULL, NULL);
1050
1051         if (templ->direction != GST_PAD_SINK) {
1052                 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: request pad that is not a SINK pad\n");
1053                 return NULL;
1054         }
1055
1056         g_return_val_if_fail (GST_IS_ENCODE_BIN (element), NULL);
1057
1058         encodebin = GST_ENCODE_BIN (element);
1059
1060  /* FIXME */
1061         if (templ == gst_element_class_get_pad_template (klass, "audio")) {
1062                 if (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO) {
1063                         gst_encode_bin_init_audio_elements(element, NULL); //??
1064
1065                         if(encodebin->audio_sinkpad == NULL)
1066                         {
1067                                 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
1068                                 encodebin->audio_sinkpad = gst_ghost_pad_new ("audio", pad);
1069                                 gst_object_unref(pad);
1070                                 pad = NULL;
1071                         }
1072                         else
1073                         {
1074                                 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: audio pad is aleady existed, return existing audio pad\n");
1075                                 return encodebin->audio_sinkpad;
1076                         }
1077
1078                         gst_element_add_pad (element, encodebin->audio_sinkpad);
1079                         gst_pad_set_setcaps_function (encodebin->audio_sinkpad,
1080                                 GST_DEBUG_FUNCPTR (gst_encode_bin_audsink_set_caps));
1081                         return encodebin->audio_sinkpad;
1082                 } else
1083                         return NULL;
1084         } else if (templ == gst_element_class_get_pad_template (klass, "video")) {
1085                 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV) {
1086                         gst_encode_bin_init_video_elements(element, NULL); //??
1087
1088                         if(encodebin->video_sinkpad == NULL)
1089                         {
1090                                 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
1091                                 encodebin->video_sinkpad = gst_ghost_pad_new ("video", pad);
1092                                 gst_object_unref(pad);
1093                                 pad = NULL;
1094                         }
1095                         else
1096                         {
1097                                 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: video pad is aleady existed, return existing video pad\n");
1098                                 return encodebin->video_sinkpad;
1099                         }
1100
1101                         gst_element_add_pad (element, encodebin->video_sinkpad);
1102                         gst_pad_set_setcaps_function (encodebin->video_sinkpad,
1103                         GST_DEBUG_FUNCPTR (gst_encode_bin_vidsink_set_caps));
1104                         return encodebin->video_sinkpad;
1105                 } else if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1106                         gst_encode_bin_init_image_elements(element, NULL); //??
1107
1108                         if(encodebin->image_sinkpad == NULL)
1109                         {
1110                                 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1111                                 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1112                                 gst_object_unref(pad);
1113                                 pad = NULL;
1114                         }
1115                         else
1116                         {
1117                                 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1118                                 return encodebin->image_sinkpad;
1119                         }
1120
1121                         gst_element_add_pad (element, encodebin->image_sinkpad);
1122                         gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1123                         GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1124                         return encodebin->image_sinkpad;
1125                 } else
1126                         return NULL;
1127         } else {
1128                 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1129                         gst_encode_bin_init_image_elements(element, NULL); //??
1130
1131                         if(encodebin->image_sinkpad == NULL)
1132                         {
1133                                 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1134                                 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1135                                 gst_object_unref(pad);
1136                                 pad = NULL;
1137                         }
1138                         else
1139                         {
1140                                 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1141                                 return encodebin->image_sinkpad;
1142                         }
1143
1144                         gst_element_add_pad (element, encodebin->image_sinkpad);
1145                         gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1146                         GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1147                         return encodebin->image_sinkpad;
1148                 } else
1149                         return NULL;
1150         }
1151 }
1152
1153 static void
1154 gst_encode_bin_class_init (GstEncodeBinClass *klass)
1155 {
1156         GObjectClass *gobject_klass;
1157         GstElementClass *gstelement_klass;
1158         GstBinClass *gstbin_klass;
1159
1160         gobject_klass = (GObjectClass *) klass;
1161         gstelement_klass = (GstElementClass *) klass;
1162         gstbin_klass = (GstBinClass *) klass;
1163
1164         parent_class = g_type_class_peek_parent (klass);
1165
1166         gobject_klass->get_property = gst_encode_bin_get_property;
1167         gobject_klass->set_property = gst_encode_bin_set_property;
1168         gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_encode_bin_dispose);
1169         gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_encode_bin_finalize);
1170
1171
1172         g_object_class_install_property (gobject_klass, PROP_PROFILE,
1173           g_param_spec_enum ("profile", "PROFILE", "Profile of the media to record",
1174               GST_TYPE_ENCODE_BIN_PROFILE, DEFAULT_PROP_PROFILE,
1175               G_PARAM_READWRITE));
1176
1177         g_object_class_install_property (gobject_klass, PROP_HIGH_SPEED,
1178           g_param_spec_int ("high-speed-fps", "high speed rec. fps", "framerate for high speed recording", 0, G_MAXINT,
1179                 DEFAULT_PROP_HIGH_SPEED, G_PARAM_READWRITE));
1180
1181         g_object_class_install_property (gobject_klass, PROP_VENC_NAME,
1182           g_param_spec_string ("venc-name", "video encoder name", "the name of video encoder to use",
1183               DEFAULT_PROP_VENC_NAME, G_PARAM_READWRITE));
1184
1185         g_object_class_install_property (gobject_klass, PROP_AENC_NAME,
1186           g_param_spec_string ("aenc-name", "audio encoder name", "the name of audio encoder to use",
1187               DEFAULT_PROP_AENC_NAME, G_PARAM_READWRITE));
1188
1189         g_object_class_install_property (gobject_klass, PROP_IENC_NAME,
1190           g_param_spec_string ("ienc-name", "image encoder name", "the name of image encoder to use",
1191               DEFAULT_PROP_IENC_NAME, G_PARAM_READWRITE));
1192
1193         g_object_class_install_property (gobject_klass, PROP_MUX_NAME,
1194           g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use",
1195               DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE));
1196
1197         g_object_class_install_property (gobject_klass, PROP_VCONV_NAME,
1198           g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use",
1199               DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE));
1200
1201         g_object_class_install_property (gobject_klass, PROP_VCAPS,
1202           g_param_spec_boxed ("vcaps", "caps for video","caps for video recording",
1203               GST_TYPE_CAPS, G_PARAM_READWRITE));
1204
1205         g_object_class_install_property (gobject_klass, PROP_ACAPS,
1206           g_param_spec_boxed ("acaps", "caps for audio","caps for audio recording",
1207               GST_TYPE_CAPS, G_PARAM_READWRITE));
1208
1209         g_object_class_install_property (gobject_klass, PROP_ICAPS,
1210           g_param_spec_boxed ("icaps", "caps for image","caps for image stillshot",
1211               GST_TYPE_CAPS, G_PARAM_READWRITE));
1212
1213         g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_CONVERT,
1214           g_param_spec_boolean ("auto-audio-convert", "auto audio convert",
1215               "Support for auto audio convert", TRUE, G_PARAM_READWRITE));
1216
1217         g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_RESAMPLE,
1218           g_param_spec_boolean ("auto-audio-resample", "auto audio resample",
1219               "Support for auto audio resample", TRUE, G_PARAM_READWRITE));
1220
1221         g_object_class_install_property (gobject_klass, PROP_AUTO_COLORSPACE,
1222           g_param_spec_boolean ("auto-colorspace", "auto colorspace",
1223               "Support for auto colorspace", TRUE, G_PARAM_READWRITE));
1224
1225         g_object_class_install_property (gobject_klass, PROP_BLOCK,
1226           g_param_spec_boolean ("block", "stream block",
1227               "Support for stream block", FALSE, G_PARAM_READWRITE));
1228
1229         g_object_class_install_property (gobject_klass, PROP_PAUSE,
1230           g_param_spec_boolean ("runtime-pause", "recording pause",
1231               "Support for recording pause/resume", FALSE, G_PARAM_READWRITE));
1232
1233 #if 0
1234         g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1235           g_param_spec_boolean ("use-venc-queue", "use queue between venc and mux",
1236               "add queue between venc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1237
1238         g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1239           g_param_spec_boolean ("use-aenc-queue", "use queue between aenc and mux",
1240               "add queue between aenc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1241 #else
1242         g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1243           g_param_spec_object ("use-venc-queue", "Video Encoder queue",
1244               "add queue between venc and mux(only for custom optimization)",
1245               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1246
1247         g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1248           g_param_spec_object ("use-aenc-queue", "Audio Encoder queue",
1249               "add queue between aenc and mux(only for custom optimization)",
1250               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1251 #endif
1252
1253         g_object_class_install_property (gobject_klass, PROP_VIDEO_ENC,
1254           g_param_spec_object ("video-encode", "Video Encoder",
1255               "the video encoder element to use",
1256               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1257
1258         g_object_class_install_property (gobject_klass, PROP_AUDIO_ENC,
1259           g_param_spec_object ("audio-encode", "Audio Encoder",
1260               "the audio encoder element to use",
1261               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1262
1263         g_object_class_install_property (gobject_klass, PROP_IMAGE_ENC,
1264           g_param_spec_object ("image-encode", "Image Encoder",
1265               "the Image encoder element to use",
1266               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1267
1268         g_object_class_install_property (gobject_klass, PROP_MUX,
1269           g_param_spec_object ("mux", "Muxer",
1270               "the muxer element to use",
1271               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1272
1273         g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV,
1274           g_param_spec_object ("video-convert", "Video converter",
1275               "the video converter element to use",
1276               GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1277
1278         g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE,
1279                 g_param_spec_boolean ("use-video-toggle", "Use video toggle",
1280                 "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE));
1281
1282 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
1283         gst_encode_bin_signals[SIGNAL_STREAM_BLOCK] =
1284                 g_signal_new ("stream-block", G_TYPE_FROM_CLASS (klass),
1285                 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_block),
1286                 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1287
1288         gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK] =
1289                 g_signal_new ("stream-unblock", G_TYPE_FROM_CLASS (klass),
1290                 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_unblock),
1291                 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1292
1293         gst_encode_bin_signals[SIGNAL_STREAM_PAUSE] =
1294                 g_signal_new ("stream-pause", G_TYPE_FROM_CLASS (klass),
1295                 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_pause),
1296                 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1297
1298         gst_encode_bin_signals[SIGNAL_STREAM_RESUME] =
1299                 g_signal_new ("stream-resume", G_TYPE_FROM_CLASS (klass),
1300                 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_resume),
1301                 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1302 #endif
1303
1304         gst_element_class_add_pad_template (gstelement_klass,
1305           gst_static_pad_template_get (&encoder_bin_src_template));
1306         gst_element_class_add_pad_template (gstelement_klass,
1307           gst_static_pad_template_get (&encoder_bin_audio_sink_template));
1308         gst_element_class_add_pad_template (gstelement_klass,
1309           gst_static_pad_template_get (&encoder_bin_video_sink_template));
1310         gst_element_class_add_pad_template (gstelement_klass,
1311           gst_static_pad_template_get (&encoder_bin_image_sink_template));
1312
1313         gst_element_class_set_details (gstelement_klass, &gst_encode_bin_details);
1314
1315         gstelement_klass->request_new_pad =
1316           GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad);
1317         gstelement_klass->release_pad =
1318           GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad);
1319         gstelement_klass->change_state =
1320           GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
1321 }
1322
1323 static void
1324 gst_encode_bin_init (GstEncodeBin *encodebin)
1325 {
1326         encodebin->mutex = g_mutex_new();
1327
1328         if (encodebin->srcpad == NULL) {
1329                 encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
1330                 gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
1331         }
1332
1333         encodebin->video_sinkpad = NULL;
1334         encodebin->audio_sinkpad = NULL;
1335         encodebin->image_sinkpad = NULL;
1336         encodebin->mux_audio_sinkpad = NULL;
1337         encodebin->mux_video_sinkpad = NULL;
1338
1339         encodebin->profile = DEFAULT_PROP_PROFILE;
1340         encodebin->fps = 0;
1341         encodebin->high_speed_fps = DEFAULT_PROP_HIGH_SPEED;
1342         encodebin->multiple = 1;
1343
1344         encodebin->auto_audio_convert = TRUE;
1345         encodebin->auto_audio_resample = TRUE;
1346         encodebin->auto_color_space = TRUE;
1347         encodebin->block = FALSE;
1348         encodebin->pause= FALSE;
1349         encodebin->use_video_toggle = TRUE;
1350         encodebin->use_venc_queue= FALSE;
1351         encodebin->use_aenc_queue= FALSE;
1352
1353         encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME);
1354         encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME);
1355         encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);
1356         encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);
1357         encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME);
1358
1359         encodebin->vcaps = gst_caps_new_any ();
1360         encodebin->acaps = gst_caps_new_any ();
1361         encodebin->icaps = gst_caps_new_any ();
1362
1363         encodebin->audio_queue = NULL;
1364         encodebin->video_queue = NULL;
1365         encodebin->video_encode_queue = NULL;
1366         encodebin->image_queue = NULL;
1367
1368         encodebin->audio_encode = NULL;
1369         encodebin->video_encode = NULL;
1370         encodebin->image_encode = NULL;
1371
1372         encodebin->vcapsfilter = NULL;
1373         encodebin->acapsfilter = NULL;
1374         encodebin->icapsfilter = NULL;
1375
1376         encodebin->video_toggle = NULL;
1377         encodebin->image_toggle = NULL;
1378         encodebin->color_space = NULL;
1379         encodebin->audio_conv = NULL;
1380         encodebin->audio_sample = NULL;
1381
1382         encodebin->mux = NULL;
1383
1384         encodebin->paused_time = 0;
1385         encodebin->total_offset_time = 0;
1386
1387         encodebin->vsink_probeid = 0;
1388         encodebin->vsink_hs_probeid = 0;
1389         encodebin->asink_probeid = 0;
1390         encodebin->veque_sig_id = 0;
1391         encodebin->aeque_sig_id = 0;
1392 }
1393
1394 static void
1395 gst_encode_bin_dispose (GObject * object)
1396 {
1397         GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1398
1399         g_free(encodebin->venc_name);
1400         encodebin->venc_name = NULL;
1401
1402         g_free(encodebin->aenc_name);
1403         encodebin->aenc_name = NULL;
1404
1405         g_free(encodebin->ienc_name);
1406         encodebin->ienc_name = NULL;
1407
1408         g_free(encodebin->mux_name);
1409         encodebin->mux_name = NULL;
1410
1411         g_free(encodebin->vconv_name);
1412         encodebin->vconv_name = NULL;
1413
1414         gst_caps_replace (&encodebin->vcaps, NULL);
1415         gst_caps_replace (&encodebin->acaps, NULL);
1416         gst_caps_replace (&encodebin->icaps, NULL);
1417
1418         if (encodebin->srcpad != NULL) {
1419                 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad);
1420                 encodebin->srcpad = NULL;
1421         }
1422
1423         G_OBJECT_CLASS (parent_class)->dispose (object);
1424
1425         encodebin->video_sinkpad = NULL;
1426         encodebin->audio_sinkpad = NULL;
1427         encodebin->image_sinkpad = NULL;
1428         encodebin->mux_audio_sinkpad = NULL;
1429         encodebin->mux_video_sinkpad = NULL;
1430
1431         encodebin->audio_queue = NULL;
1432         encodebin->video_queue = NULL;
1433         encodebin->image_queue = NULL;
1434
1435         encodebin->audio_encode = NULL;
1436         encodebin->video_encode = NULL;
1437         encodebin->video_encode_queue = NULL;
1438         encodebin->image_encode = NULL;
1439
1440         encodebin->vcapsfilter = NULL;
1441         encodebin->acapsfilter = NULL;
1442         encodebin->icapsfilter = NULL;
1443
1444         encodebin->video_toggle = NULL;
1445         encodebin->image_toggle = NULL;
1446         encodebin->color_space = NULL;
1447         encodebin->audio_conv = NULL;
1448         encodebin->audio_sample = NULL;
1449
1450         if (encodebin->mux && GST_IS_ELEMENT(encodebin->mux)) {
1451                 int remain_count= 0;
1452                 remain_count = GST_OBJECT_REFCOUNT_VALUE(encodebin->mux);
1453                 while (remain_count) {
1454                         gst_object_unref(encodebin->mux);
1455                         remain_count--;
1456                 }
1457         }
1458
1459         encodebin->mux = NULL;
1460 }
1461
1462 static void
1463 gst_encode_bin_finalize (GObject * object)
1464 {
1465         GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1466
1467         g_mutex_free (encodebin->mutex);
1468
1469         G_OBJECT_CLASS (parent_class)->finalize (object);
1470 }
1471
1472 static GstStateChangeReturn
1473 gst_encode_bin_change_state (GstElement * element, GstStateChange transition)
1474 {
1475         GstStateChangeReturn ret;
1476         GstEncodeBin *encode_bin;
1477
1478         encode_bin = GST_ENCODE_BIN (element);
1479
1480         switch (transition) {
1481                 case GST_STATE_CHANGE_NULL_TO_READY:
1482                         gst_encode_bin_link_elements(encode_bin);
1483                         break;
1484                 case GST_STATE_CHANGE_READY_TO_PAUSED:
1485                         /* reset time related values */
1486                         encode_bin->paused_time = 0;
1487                         encode_bin->total_offset_time = 0;
1488                         break;
1489                 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1490                         break;
1491                 case GST_STATE_CHANGE_PAUSED_TO_READY:
1492                         break;
1493                 default:
1494                         break;
1495         }
1496
1497         ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1498
1499         switch (transition) {
1500         case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1501                 break;
1502         case GST_STATE_CHANGE_PAUSED_TO_READY:
1503                 break;
1504         case GST_STATE_CHANGE_READY_TO_NULL:
1505                 gst_encode_bin_unlink_elements(encode_bin);
1506                 break;
1507         default:
1508                 break;
1509         }
1510
1511 //  if (ret == GST_STATE_CHANGE_FAILURE)
1512 //    goto done;
1513 //done:
1514         return ret;
1515 }
1516
1517 static void
1518 gst_encode_bin_release_all_pads (GstEncodeBin *encodebin)
1519 {
1520         gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->video_sinkpad);
1521         gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->audio_sinkpad);
1522         gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->image_sinkpad);
1523 }
1524
1525 static void
1526 gst_encode_bin_release_pad (GstElement * element, GstPad * pad)
1527 {
1528         GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
1529         GstPad *muxpad = NULL;
1530
1531         if(!pad_compare_name(pad, "video")) {
1532 #if 0
1533                 gst_encode_bin_remove_element(encodebin, encodebin->video_queue);
1534                 encodebin->video_queue = NULL;
1535                 gst_encode_bin_remove_element(encodebin, encodebin->video_toggle);
1536                 encodebin->video_toggle = NULL;
1537                 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1538                 encodebin->color_space = NULL;
1539                 gst_encode_bin_remove_element(encodebin, encodebin->vcapsfilter);
1540                 encodebin->vcapsfilter = NULL;
1541                 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
1542                 encodebin->video_encode_queue =  NULL;
1543                 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1544                 encodebin->video_encode =  NULL;
1545
1546                 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1547                 encodebin->mux_video_sinkpad = NULL;
1548
1549                 if(encodebin->mux_audio_sinkpad == NULL) {
1550                         gst_encode_bin_remove_element(encodebin, encodebin->mux);
1551                         encodebin->mux = NULL;
1552                 }
1553                 else
1554                 {
1555                         encodebin->mux_audio_sinkpad = NULL;
1556                 }
1557 #endif
1558
1559                 if(encodebin->mux_video_sinkpad != NULL)
1560                 {
1561                         gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1562                         encodebin->mux_video_sinkpad = NULL;
1563                 }
1564
1565                 gst_pad_set_active (pad, FALSE); //??
1566                 gst_element_remove_pad(element, pad);
1567                 encodebin->video_sinkpad = NULL;
1568         } else if(!pad_compare_name(pad, "audio")) {
1569 #if 0
1570                 gst_encode_bin_remove_element(encodebin, encodebin->audio_queue);
1571                 encodebin->audio_queue = NULL;
1572                 gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
1573                 encodebin->audio_sample = NULL;
1574                 gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
1575                 encodebin->audio_conv = NULL;
1576                 gst_encode_bin_remove_element(encodebin, encodebin->acapsfilter);
1577                 encodebin->acapsfilter = NULL;
1578                 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
1579                 encodebin->audio_encode_queue =  NULL;
1580                 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1581                 encodebin->audio_encode = NULL;
1582
1583                 encodebin->mux_audio_sinkpad;
1584                 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1585                 muxpad = NULL;
1586
1587                 if(encodebin->mux_video_sinkpad == NULL) {
1588                         gst_encode_bin_remove_element(encodebin, encodebin->mux);
1589                         encodebin->mux = NULL;
1590                 }
1591                 else
1592                 {
1593                         encodebin->mux_video_sinkpad = NULL;
1594                 }
1595 #endif
1596                 if(encodebin->mux_audio_sinkpad != NULL)
1597                 {
1598                         gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1599 //                      gst_object_unref(encodebin->mux_audio_sinkpad);         //***
1600                         encodebin->mux_audio_sinkpad = NULL;
1601                 }
1602
1603                 gst_pad_set_active (pad, FALSE); //??
1604                 gst_element_remove_pad(element, pad);
1605                 encodebin->audio_sinkpad = NULL;
1606         } else {
1607 #if 0
1608                 gst_encode_bin_remove_element(encodebin, encodebin->image_queue);
1609                 encodebin->image_queue = NULL;
1610                 gst_encode_bin_remove_element(encodebin, encodebin->image_toggle);
1611                 encodebin->image_toggle = NULL;
1612                 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1613                 encodebin->color_space = NULL;
1614                 gst_encode_bin_remove_element(encodebin, encodebin->icapsfilter);
1615                 encodebin->icapsfilter = NULL;
1616                 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1617                 encodebin->image_encode = NULL;
1618 #endif
1619                 gst_pad_set_active (pad, FALSE); //??
1620                 gst_element_remove_pad(element, pad);
1621                 encodebin->image_sinkpad = NULL;
1622         }
1623 }
1624
1625 static gint
1626 pad_compare_name (GstPad * pad1, const gchar * name)
1627 {
1628         gint result;
1629
1630         GST_OBJECT_LOCK (pad1);
1631                 result = strcmp (GST_PAD_NAME (pad1), name);
1632         GST_OBJECT_UNLOCK (pad1);
1633
1634         return result;
1635 }
1636
1637 static gboolean
1638 gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1639 {
1640         switch(type) {
1641                 case ENCODEBIN_ELEMENT_VENC:
1642                         encodebin->video_encode = gst_element_factory_make (name, NULL);
1643                         if(encodebin->video_encode != NULL) {
1644                                 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1645                                 g_free(encodebin->venc_name);
1646                                 encodebin->venc_name = NULL;
1647                         } else {
1648                                 goto element_make_fail;
1649                         }
1650                         break;
1651                 case ENCODEBIN_ELEMENT_AENC:
1652                         encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");
1653                         if(encodebin->audio_encode != NULL) {
1654                                 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1655                                 g_free(encodebin->aenc_name);
1656                                 encodebin->aenc_name = NULL;
1657                         } else {
1658                                 goto element_make_fail;
1659                         }
1660                         break;
1661                 case ENCODEBIN_ELEMENT_IENC:
1662                         encodebin->image_encode = gst_element_factory_make (name, "image_encode");
1663                         if(encodebin->image_encode != NULL) {
1664                                 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1665                                 g_free(encodebin->ienc_name);
1666                                 encodebin->ienc_name = NULL;
1667                         } else {
1668                                 goto element_make_fail;
1669                         }
1670                         break;
1671                 case ENCODEBIN_ELEMENT_MUX:
1672                         encodebin->mux = gst_element_factory_make (name, "mux");
1673                         if(encodebin->mux != NULL) {
1674                                 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1675                                 g_free(encodebin->mux_name);
1676                                 encodebin->mux_name = NULL;
1677                         } else {
1678                                 goto element_make_fail;
1679                         }
1680                         break;
1681                 case ENCODEBIN_ELEMENT_VIDEO_CONV:
1682                         encodebin->color_space = gst_element_factory_make(name, "video_convert");
1683                         if (encodebin->color_space != NULL) {
1684                                 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1685                                 g_free(encodebin->vconv_name);
1686                                 encodebin->vconv_name = NULL;
1687                         } else {
1688                                 goto element_make_fail;
1689                         }
1690                         break;
1691                 default:
1692                         GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1693                         break;
1694         }
1695
1696         return TRUE;
1697
1698 element_make_fail:
1699         GST_WARNING_OBJECT(encodebin, "no such element factory \"%s\"!", name);
1700         return FALSE;
1701 }
1702
1703 #if 0 //disable unused function
1704 static gboolean
1705 gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean newprofile)
1706 {
1707
1708   gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1709   gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1710   gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1711   gst_encode_bin_remove_element(encodebin, encodebin->mux);
1712
1713   switch (newprofile) {
1714     case GST_ENCODE_BIN_PROFILE_AV :
1715         encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1716         encodebin->video_encode = gst_element_factory_make (encodebin->venc_name,"video_encode");
1717         encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1718
1719           gst_bin_add_many (GST_BIN (encodebin),
1720                             encodebin->audio_encode,
1721                             encodebin->video_encode,
1722                             encodebin->mux,
1723                            NULL);
1724         break;
1725     case GST_ENCODE_BIN_PROFILE_AUDIO :
1726         encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1727         encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1728
1729           gst_bin_add_many (GST_BIN (encodebin),
1730                             encodebin->audio_encode,
1731                             encodebin->mux,
1732                            NULL);
1733         break;
1734     case GST_ENCODE_BIN_PROFILE_IMAGE :
1735         encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name,"image_encode");
1736
1737         gst_bin_add_many (GST_BIN (encodebin),
1738                             encodebin->image_encode,
1739                            NULL);
1740         break;
1741     default:
1742       GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
1743       return FALSE;
1744       break;
1745         }
1746   return TRUE;
1747
1748 }
1749
1750 static void
1751 gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement)
1752 {
1753   if(newelement == NULL) {
1754         GST_ERROR_OBJECT(encodebin, "some elements are null\n");
1755         return;
1756   }
1757   switch(type) {
1758     case PROP_VIDEO_ENC:
1759         gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1760         encodebin->video_encode = newelement;
1761         gst_object_ref (encodebin->video_encode);
1762        gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
1763         gst_bin_add(GST_BIN(encodebin),  encodebin->video_encode);
1764         break;
1765     case PROP_AUDIO_ENC:
1766         gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1767         encodebin->audio_encode = newelement;
1768         gst_object_ref (encodebin->audio_encode);
1769        gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
1770         gst_bin_add(GST_BIN(encodebin),  encodebin->audio_encode);
1771         break;
1772     case PROP_IMAGE_ENC:
1773         gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1774         encodebin->image_encode = newelement;
1775         gst_object_ref (encodebin->image_encode);
1776        gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
1777         gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1778         break;
1779     case PROP_MUX:
1780         gst_encode_bin_remove_element(encodebin, encodebin->mux);
1781         encodebin->mux = newelement;
1782         gst_object_ref (encodebin->mux);
1783        gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
1784         gst_bin_add(GST_BIN(encodebin),  encodebin->mux);
1785         break;
1786     default:
1787         GST_WARNING_OBJECT(encodebin, "Invalid type = %d", type);
1788       return;
1789         break;
1790   }
1791 }
1792
1793 static gboolean
1794 gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1795 {
1796         GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1797
1798         switch(type) {
1799                 case ENCODEBIN_ELEMENT_VENC:
1800                         if(encodebin->video_encode == NULL) {
1801                                 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1802                                 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1803                         } else {
1804                                 sink1 = gst_element_get_static_pad(encodebin->video_encode, "sink");
1805                                 src = gst_element_get_static_pad(encodebin->video_encode, "src");
1806                                 if(sink1 != NULL) {
1807                                         peersink1 = gst_pad_get_peer(sink1);
1808                                         if(peersink1 != NULL) {
1809                                                 if(!gst_pad_unlink(peersink1, sink1)) {
1810                                                         goto unlink_fail;
1811                                                 }
1812                                         }
1813                                 }
1814
1815                                 if(src !=NULL) {
1816                                         peersrc = gst_pad_get_peer(src);
1817                                         if(peersrc != NULL) {
1818                                                 if(!gst_pad_unlink(src, peersrc)) {
1819                                                         goto unlink_fail;
1820                                                 }
1821                                         }
1822                                 }
1823
1824                                 if(gst_encode_bin_remove_element(encodebin, encodebin->video_encode)) {
1825                                         if(encodebin->video_encode = gst_element_factory_make (name, "video_encode") != NULL) {
1826                                                 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1827                                                 if(peersink1 != NULL) {
1828                                                         if(!gst_pad_link(peersink1, gst_element_get_pad(encodebin->video_encode, "sink"))) {
1829                                                                 goto link_fail;
1830                                                         }
1831                                                 }
1832
1833                                                 if(peersrc != NULL) {
1834                                                         if(!gst_pad_link(gst_element_get_pad(encodebin->video_encode, "src"), peersrc)) {
1835                                                                 goto link_fail;
1836                                                         }
1837                                                 }
1838                                         } else {
1839                                                 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] make fail\n", type);
1840                                                 return FALSE;
1841                                         }
1842                                 } else {
1843                                         GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] remove fail\n", type);
1844                                         return FALSE;
1845                                 }
1846                         }
1847                         break;
1848                 case ENCODEBIN_ELEMENT_AENC:
1849                         break;
1850                 case ENCODEBIN_ELEMENT_IENC:
1851                         break;
1852                 case ENCODEBIN_ELEMENT_MUX:
1853                         break;
1854                 default :
1855                         GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1856                         break;
1857         }
1858         gst_object_unref(sink1);
1859         gst_object_unref(sink2);
1860         gst_object_unref(src);
1861         gst_object_unref(peersink1);
1862         gst_object_unref(peersink2);
1863         gst_object_unref(peersrc);
1864         return TRUE;
1865
1866 unlink_fail:
1867         gst_object_unref(sink1);
1868         gst_object_unref(sink2);
1869         gst_object_unref(src);
1870         gst_object_unref(peersink1);
1871         gst_object_unref(peersink2);
1872         gst_object_unref(peersrc);
1873         GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] unlink fail\n", type);
1874         return FALSE;
1875
1876
1877 link_fail:
1878         gst_object_unref(sink1);
1879         gst_object_unref(sink2);
1880         gst_object_unref(src);
1881         gst_object_unref(peersink1);
1882         gst_object_unref(peersink2);
1883         gst_object_unref(peersrc);
1884         GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] link fail\n", type);
1885         return FALSE;
1886 }
1887
1888 static gboolean
1889 gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element)
1890 {
1891         GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1892
1893         switch(type)
1894                 case ENCODEBIN_ELEMENT_VENC:
1895                         if(encodebin->video_encode == NULL) {
1896                                 encodebin->video_encode = element
1897                         }
1898                         break;
1899                 case ENCODEBIN_ELEMENT_AENC:
1900                         break;
1901                 case ENCODEBIN_ELEMENT_IENC:
1902                         break;
1903                 case ENCODEBIN_ELEMENT_MUX:
1904                         break;
1905                 default :
1906                         GST_WARNING_OBJECT (encodebin,"Invalid element type = %d", type);
1907                         break;
1908 }
1909 #endif //disable unused function
1910
1911 static gboolean
1912 gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element)
1913 {
1914         GstObject *parent;
1915         gchar *ename = NULL;
1916         GST_INFO_OBJECT (encodebin, "gst_encode_bin_remove_element");
1917
1918         if (element == NULL) {
1919                 GST_INFO_OBJECT (encodebin, "element is already NULL");
1920                 return TRUE;
1921         }
1922
1923         gst_element_set_state (element, GST_STATE_NULL);
1924         parent = gst_element_get_parent (element);
1925
1926         if (parent != NULL) {
1927                 if(!gst_bin_remove (GST_BIN_CAST (parent), element)) {
1928                         gst_object_unref (parent);
1929                         ename = gst_element_get_name (element);
1930                         GST_ERROR_OBJECT (encodebin, "gst_encode_bin_remove_element() [%s] remove fail", ename);
1931                         g_free (ename);
1932                         return FALSE;
1933                 } else {
1934                         gst_object_unref(parent);
1935                 }
1936         } else {
1937                 gst_object_unref(element);
1938         }
1939
1940         return TRUE;
1941   }
1942
1943 static gboolean
1944 gst_encode_bin_link_elements (GstEncodeBin *encodebin)  // need to return ????
1945 {
1946         GstPad *srcpad = NULL, *sinkpad = NULL;
1947         switch(encodebin->profile) {
1948                 case GST_ENCODE_BIN_PROFILE_AV :
1949                         if (!gst_caps_is_any(encodebin->vcaps)) {
1950                                 gchar *caps_str = NULL;
1951                                 caps_str = gst_caps_to_string(encodebin->vcaps);
1952                                 if (caps_str) {
1953                                         GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str);
1954                                         g_free(caps_str);
1955                                         caps_str = NULL;
1956                                 }
1957
1958                                 g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL);
1959                         }
1960
1961                         if (encodebin->auto_color_space) {
1962                                 if(encodebin->color_space == NULL) {
1963                                         encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
1964                                         gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
1965                                 }
1966
1967                                 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
1968                                 if( encodebin->video_toggle )
1969                                 {
1970                                         sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
1971                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1972
1973                                         srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
1974                                 }
1975                                 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
1976                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1977
1978                                 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
1979                                 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
1980                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1981
1982                                 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
1983                                 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
1984                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1985 #if 0
1986                                 if(encodebin->use_venc_queue)
1987                                 {
1988                                         if(encodebin->video_encode_queue == NULL) {
1989                                             encodebin->video_encode_queue  = gst_element_factory_make ("queue","video_encode_queue");
1990                                             gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
1991
1992                                             ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1993                                             encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1994                                                                                                                                 G_CALLBACK(queue_overun_cb), encodebin);
1995
1996                                         }
1997
1998                                         srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1999                                         sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2000                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2001                                 }
2002 #else
2003                                 if(encodebin->video_encode_queue)
2004                                 {
2005                                     ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2006                                     encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2007                                                                                                                                 G_CALLBACK(queue_overun_cb), encodebin);
2008 #if 0
2009                                     g_object_set(G_OBJECT(encodebin->video_queue),
2010                                                 "max-size-bytes", (guint)0,
2011                                                 "max-size-buffers", (guint)1,
2012                                                 "max-size-time", (guint64)0,
2013                                                 NULL);
2014 #endif
2015                                         srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2016                                         sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2017                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2018                                 }
2019 #endif
2020
2021                         }
2022                         else {
2023                                 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
2024                                 if( encodebin->video_toggle )
2025                                 {
2026                                         sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
2027                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2028
2029                                         srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
2030                                 }
2031                                 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
2032                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2033
2034                                 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
2035                                 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
2036                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2037  #if 0
2038                                 if(encodebin->use_venc_queue)
2039                                 {
2040                                         if(encodebin->video_encode_queue == NULL) {
2041                                             encodebin->video_encode_queue  = gst_element_factory_make ("queue","video_encode_queue");
2042                                             gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
2043
2044                                             ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2045                                             encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2046                                                                                                                                 G_CALLBACK(queue_overun_cb), encodebin);
2047                                         }
2048
2049                                         srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2050                                         sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2051                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2052
2053                                 }
2054 #else
2055                                 if(encodebin->video_encode_queue)
2056                                 {
2057                                     ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2058                                     encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2059                                                                                                                                 G_CALLBACK(queue_overun_cb), encodebin);
2060 #if 0
2061                                     g_object_set(G_OBJECT(encodebin->video_queue),
2062                                                 "max-size-bytes", (guint)0,
2063                                                 "max-size-buffers", (guint)1,
2064                                                 "max-size-time", (guint64)0,
2065                                                 NULL);
2066 #endif
2067
2068                                         srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2069                                         sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2070                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2071                                 }
2072 #endif
2073
2074                         }
2075
2076 //                      gst_element_get_request_pad (encodebin->mux, "video_%d");
2077 #if 0
2078                         if(encodebin->use_venc_queue)
2079                         {
2080                                 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2081                                 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2082                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2083                         }
2084 #else
2085                         if(encodebin->video_encode_queue)
2086                         {
2087                                 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2088                                 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2089                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2090                         }
2091 #endif
2092                         else
2093                         {
2094                                 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2095                                 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2096                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2097                         }
2098
2099                         srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2100                         if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2101                                 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2102                         gst_object_unref(srcpad);
2103                         srcpad = NULL;
2104
2105                         /* For pause/resume control */
2106 //                      encodebin->vsink_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_queue, "sink"),
2107                         sinkpad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2108                         encodebin->vsink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe), encodebin);
2109                         gst_object_unref(sinkpad);
2110                         sinkpad = NULL;
2111
2112                         if(encodebin->high_speed_fps > DEFAULT_PROP_HIGH_SPEED)
2113                         {
2114 //                              encodebin->vsink_hs_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_encode, "sink"),
2115                                 sinkpad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2116                                 encodebin->vsink_hs_probeid = gst_pad_add_buffer_probe (sinkpad,        G_CALLBACK (gst_encode_bin_video_probe_hs), encodebin);
2117                                 gst_object_unref(sinkpad);
2118                                 sinkpad = NULL;
2119                         }
2120
2121                         if(encodebin->audio_queue == NULL)
2122                         {
2123                                 GST_WARNING_OBJECT(encodebin, "Audio pad isn't requested, recording video only mode");
2124                                 break;
2125                         }
2126                 case GST_ENCODE_BIN_PROFILE_AUDIO :
2127                         if(!gst_caps_is_any(encodebin->acaps))
2128                         {
2129                                 g_object_set(encodebin->acapsfilter, "caps", encodebin->acaps, NULL);
2130                         }
2131                         if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2132                                 if (!encodebin->auto_audio_convert) {
2133                                         if(encodebin->audio_sample == NULL) {
2134                                                 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2135                                                gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2136                                         }
2137                                         srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2138                                         sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2139                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2140
2141                                         srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2142                                         sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2143                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2144
2145                                         srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2146                                         sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2147                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2148 #if 0
2149                                         if(encodebin->use_aenc_queue)
2150                                         {
2151                                                 if(encodebin->audio_encode_queue == NULL) {
2152                                                     encodebin->audio_encode_queue  = gst_element_factory_make ("queue","audio_encode_queue");
2153                                                     gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2154
2155                                                    ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2156                                                    encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2157                                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2158                                                 }
2159
2160                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2161                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2162                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2163                                         }
2164 #else
2165                                         if(encodebin->audio_encode_queue)
2166                                         {
2167
2168                                                 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2169                                                 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2170                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2171
2172                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2173                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2174                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2175                                         }
2176 #endif
2177
2178                                 } else if (!encodebin->auto_audio_resample) {
2179                                           if (encodebin->audio_conv == NULL) {
2180                                                 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2181                                               gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2182                                            }
2183
2184                                         srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2185                                         sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2186                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2187
2188                                         srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2189                                         sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2190                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2191
2192                                         srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2193                                         sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2194                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2195 #if 0
2196                                         if(encodebin->use_aenc_queue)
2197                                         {
2198                                                 if(encodebin->audio_encode_queue == NULL) {
2199                                                     encodebin->audio_encode_queue  = gst_element_factory_make ("queue","audio_encode_queue");
2200                                                     gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2201
2202                                                     ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2203                                                    encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2204                                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2205                                                 }
2206
2207                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2208                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2209                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2210
2211                                         }
2212 #else
2213                                         if(encodebin->audio_encode_queue)
2214                                         {
2215
2216                                                 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2217                                                 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2218                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2219
2220                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2221                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2222                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2223                                         }
2224 #endif
2225
2226                                 } else {
2227                                         if(encodebin->audio_sample == NULL) {
2228                                                 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2229                                                gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2230                                         }
2231                                         if (encodebin->audio_conv == NULL) {
2232                                                 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2233                                               gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2234                                         }
2235
2236                                         srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2237                                         sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2238                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2239
2240                                         srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2241                                         sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2242                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2243
2244                                         srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2245                                         sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2246                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2247
2248                                         srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2249                                         sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2250                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2251 #if 0
2252                                         if(encodebin->use_aenc_queue)
2253                                         {
2254                                                 if(encodebin->audio_encode_queue == NULL) {
2255                                                     encodebin->audio_encode_queue  = gst_element_factory_make ("queue","audio_encode_queue");
2256                                                     gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2257
2258                                                     ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2259                                                    encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2260                                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2261                                                 }
2262
2263                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2264                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2265                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2266
2267                                         }
2268 #else
2269                                         if(encodebin->audio_encode_queue)
2270                                         {
2271
2272                                                 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2273                                                 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2274                                                                                                                         G_CALLBACK(queue_overun_cb), encodebin);
2275
2276                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2277                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2278                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2279                                         }
2280 #endif
2281
2282                                 }
2283                         }else {
2284
2285                                 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2286                                 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2287                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2288
2289                                 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2290                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2291                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2292 #if 0
2293                                 if(encodebin->use_aenc_queue)
2294                                 {
2295                                         if(encodebin->audio_encode_queue == NULL) {
2296                                             encodebin->audio_encode_queue  = gst_element_factory_make ("queue","audio_encode_queue");
2297                                             gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2298
2299                                             ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2300                                            encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2301                                                                                                                                 G_CALLBACK(queue_overun_cb), encodebin);
2302                                         }
2303
2304                                         srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2305                                         sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2306                                         _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2307                                 }
2308 #else
2309                                         if(encodebin->audio_encode_queue)
2310                                         {
2311
2312                                                 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2313                         encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2314                                                                     G_CALLBACK(queue_overun_cb), encodebin);
2315
2316                                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2317                                                 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2318                                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2319                                         }
2320 #endif
2321
2322                         }
2323 #if 0
2324                         if(encodebin->use_aenc_queue)
2325                         {
2326                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2327                                 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2328                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2329
2330                         }
2331 #else
2332
2333                         if(encodebin->audio_encode_queue)
2334                         {
2335                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2336                                 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2337                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2338
2339                         }
2340 #endif
2341                         else
2342                         {
2343                                 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2344                                 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2345                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2346
2347                         }
2348
2349                         srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2350                         if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2351                                 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2352                         gst_object_unref(srcpad);
2353                         srcpad = NULL;
2354
2355                         /* For pause/resume control */
2356                         sinkpad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2357                         encodebin->asink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_audio_probe), encodebin);
2358                         gst_object_unref(sinkpad);
2359                         sinkpad = NULL;
2360
2361                         break;
2362                 case GST_ENCODE_BIN_PROFILE_IMAGE :
2363                         if(!gst_caps_is_any(encodebin->icaps))
2364                         {
2365                                 g_object_set(encodebin->icapsfilter, "caps", encodebin->icaps, NULL);
2366                         }
2367
2368                         if (encodebin->auto_color_space) {
2369                                 if(encodebin->color_space == NULL) {
2370                                     encodebin->color_space  = gst_element_factory_make ("ffmpegcolorspace","color_space");
2371                                     gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
2372                                 }
2373
2374                                 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
2375                                 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
2376                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2377
2378                                 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
2379                                 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
2380                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2381
2382                                 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
2383                                 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
2384                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2385
2386                                 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2387                                 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2388                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2389
2390                         }
2391                         else {
2392
2393                                 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
2394                                 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
2395                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2396
2397                                 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
2398                                 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
2399                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2400
2401                                 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2402                                 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2403                                 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2404
2405                         }
2406                         srcpad =  gst_element_get_static_pad (encodebin->image_encode, "src");
2407                         if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2408                                 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2409                         gst_object_unref(srcpad);
2410                         srcpad = NULL;
2411                         break;
2412                 default:
2413                       GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2414                       return FALSE;
2415                       break;
2416         }
2417 //      gst_pad_set_active(encodebin->srcpad, TRUE);
2418         return TRUE;
2419
2420 video_link_fail:
2421         // remove elements
2422         gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2423         GST_WARNING_OBJECT(encodebin, "encodebin link video elements fail");
2424         return FALSE;
2425
2426 audio_link_fail:
2427         // remove element
2428         gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
2429         gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
2430         GST_WARNING_OBJECT(encodebin, "encodebin link audio elements fail");
2431         return FALSE;
2432
2433 image_link_fail:
2434         // remove element
2435         gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2436         GST_WARNING_OBJECT(encodebin, "encodebin link image elements fail");
2437         return FALSE;
2438
2439
2440 }
2441
2442 static gboolean
2443 gst_encode_bin_unlink_elements (GstEncodeBin *encodebin)
2444 {
2445         GstPad *pad = NULL, *muxpad = NULL;
2446
2447         switch(encodebin->profile) {
2448                 case GST_ENCODE_BIN_PROFILE_AV :
2449                         if (encodebin->auto_color_space) {
2450                                 if (encodebin->video_toggle) {
2451                                         gst_element_unlink_many(
2452                                                 encodebin->video_queue,
2453                                                 encodebin->video_toggle,
2454                                                 encodebin->color_space,
2455                                                 encodebin->vcapsfilter,
2456                                                 encodebin->video_encode,
2457                                                 //encodebin->video_encode_queue,
2458                                                 NULL);
2459                                 } else {
2460                                         gst_element_unlink_many(
2461                                                 encodebin->video_queue,
2462                                                 encodebin->color_space,
2463                                                 encodebin->vcapsfilter,
2464                                                 encodebin->video_encode,
2465                                                 //encodebin->video_encode_queue,
2466                                                 NULL);
2467                                 }
2468                         } else {
2469                                 if (encodebin->video_toggle) {
2470                                         gst_element_unlink_many(
2471                                                 encodebin->video_queue,
2472                                                 encodebin->video_toggle,
2473                                                 encodebin->vcapsfilter,
2474                                                 encodebin->video_encode,
2475                                                 //encodebin->video_encode_queue,
2476                                                 NULL);
2477                                 } else {
2478                                         gst_element_unlink_many(
2479                                                 encodebin->video_queue,
2480                                                 encodebin->vcapsfilter,
2481                                                 encodebin->video_encode,
2482                                                 //encodebin->video_encode_queue,
2483                                                 NULL);
2484                                 }
2485                         }
2486
2487                         if(encodebin->mux_video_sinkpad != NULL)
2488                         {
2489 #if 0
2490                                 if(encodebin->use_venc_queue)
2491                                 {
2492                                         gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2493
2494                                         pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2495                                         gst_pad_unlink(pad, muxpad);
2496                                         gst_object_unref(pad);
2497                                         pad = NULL;
2498
2499                                         if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2500                                         {
2501                                                 g_signal_handler_disconnect (  encodebin->video_encode_queue, encodebin->veque_sig_id );
2502                                         }
2503                                 }
2504 #else
2505                                 if(encodebin->video_encode_queue)
2506                                 {
2507                                         gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2508
2509                                         pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2510                                         gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2511                                         gst_object_unref(pad);
2512                                         pad = NULL;
2513
2514                                         if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2515                                         {
2516                                                 g_signal_handler_disconnect (  encodebin->video_encode_queue, encodebin->veque_sig_id );
2517                                         }
2518                                 }
2519 #endif
2520                                 else
2521                                 {
2522                                         pad = gst_element_get_static_pad (encodebin->video_encode, "src");
2523                                         gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2524                                         gst_object_unref(pad);
2525                                         pad = NULL;
2526                                 }
2527
2528                                 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
2529 //                              gst_object_unref(encodebin->mux_video_sinkpad); //***
2530                                 encodebin->mux_video_sinkpad = NULL;
2531                         }
2532
2533                         if(encodebin->vsink_probeid)
2534                         {
2535                                 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2536                                 gst_pad_remove_buffer_probe(pad, encodebin->vsink_probeid);
2537                                 encodebin->vsink_probeid = 0;
2538                                 gst_object_unref(pad);
2539                                 pad = NULL;
2540                         }
2541
2542
2543                         if(encodebin->vsink_hs_probeid)
2544                         {
2545                                 pad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2546                                 gst_pad_remove_buffer_probe(pad, encodebin->vsink_hs_probeid);
2547                                 encodebin->vsink_hs_probeid = 0;
2548                                 gst_object_unref(pad);
2549                                 pad = NULL;
2550                         }
2551
2552                         if(encodebin->audio_queue == NULL)
2553                         {
2554                                 break;
2555                         }
2556                 case GST_ENCODE_BIN_PROFILE_AUDIO :
2557                         if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2558                                 if (!encodebin->auto_audio_convert) {
2559                                                 gst_element_unlink_many  (
2560                                                         encodebin->audio_queue,
2561                                                         encodebin->audio_sample,
2562                                                         encodebin->acapsfilter,
2563                                                         encodebin->audio_encode,
2564                                                         NULL);
2565                                 } else if (!encodebin->auto_audio_resample) {
2566                                                 gst_element_unlink_many  (
2567                                                         encodebin->audio_queue,
2568                                                         encodebin->audio_conv,
2569                                                         encodebin->acapsfilter,
2570                                                         encodebin->audio_encode,
2571                                                         NULL);
2572                                 } else {
2573                                                 gst_element_unlink_many  (
2574                                                         encodebin->audio_queue,
2575                                                         encodebin->audio_conv,
2576                                                         encodebin->audio_sample,
2577                                                         encodebin->acapsfilter,
2578                                                         encodebin->audio_encode,
2579                                                         NULL);
2580                                 }
2581                         }
2582                         else {
2583                                 gst_element_unlink_many  (
2584                                         encodebin->audio_queue,
2585                                         encodebin->acapsfilter,
2586                                         encodebin->audio_encode,
2587                                         NULL);
2588                         }
2589
2590                         if(encodebin->mux_audio_sinkpad != NULL)
2591                         {
2592 #if 0
2593                                 if(encodebin->use_aenc_queue)
2594                                 {
2595                                         gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2596
2597                                         pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2598                                         gst_pad_unlink(pad, muxpad);
2599                                         gst_object_unref(pad);
2600                                         pad = NULL;
2601
2602                                         if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2603                                         {
2604                                                 g_signal_handler_disconnect (  encodebin->audio_encode_queue, encodebin->veque_sig_id );
2605                                         }
2606                                 }
2607 #else
2608                                 if(encodebin->audio_encode_queue)
2609                                 {
2610                                         gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2611
2612                                         pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2613                                         gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2614                                         gst_object_unref(pad);
2615                                         pad = NULL;
2616
2617                                         if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2618                                         {
2619                                                 g_signal_handler_disconnect (  encodebin->audio_encode_queue, encodebin->veque_sig_id );
2620                                         }
2621                                 }
2622 #endif
2623                                 else
2624                                 {
2625                                         pad = gst_element_get_static_pad (encodebin->audio_encode, "src");
2626                                         gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2627                                         gst_object_unref(pad);
2628                                         pad = NULL;
2629                                 }
2630
2631                                 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
2632 //                              gst_object_unref(encodebin->mux_audio_sinkpad);         //***
2633                                 encodebin->mux_audio_sinkpad = NULL;
2634                         }
2635
2636                         if(encodebin->asink_probeid)
2637                         {
2638                                 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2639                                 gst_pad_remove_buffer_probe(pad, encodebin->asink_probeid);
2640                                 encodebin->asink_probeid =0;
2641                                 gst_object_unref(pad);
2642                                 pad = NULL;
2643                         }
2644
2645                         break;
2646                 case GST_ENCODE_BIN_PROFILE_IMAGE :
2647                         if (encodebin->auto_color_space) {
2648                                 gst_element_unlink_many  (
2649                                         encodebin->image_queue,
2650                                         encodebin->image_toggle,
2651                                         encodebin->color_space,
2652                                         encodebin->icapsfilter,
2653                                         encodebin->image_encode,
2654                                         NULL);
2655                         }
2656                         else {
2657                                 gst_element_unlink_many  (
2658                                         encodebin->image_queue,
2659                                         encodebin->image_toggle,
2660                                         encodebin->icapsfilter,
2661                                         encodebin->image_encode,
2662                                         NULL);
2663                         }
2664                         break;
2665                 default:
2666                           GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2667                           return FALSE;
2668                   break;
2669         }
2670         //      gst_pad_set_active(encodebin->srcpad, TRUE);
2671         return TRUE;
2672
2673 }
2674
2675 static gboolean
2676 gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data)
2677 {
2678         GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2679
2680         if(encodebin->profile != GST_ENCODE_BIN_PROFILE_AV)
2681                 return FALSE;
2682
2683         if(encodebin->video_queue == NULL) {
2684                 encodebin->video_queue = gst_element_factory_make ("queue","video_queue");
2685                 gst_bin_add (GST_BIN (element), encodebin->video_queue);
2686         }
2687
2688         if( encodebin->use_video_toggle )
2689         {
2690                 if( encodebin->video_toggle == NULL )
2691                 {
2692                         encodebin->video_toggle = gst_element_factory_make ("toggle","video_toggle");
2693                         gst_bin_add (GST_BIN (element), encodebin->video_toggle);
2694                 }
2695                 GST_INFO_OBJECT( encodebin, "Video toggle is Enabled" );
2696         }
2697         else
2698         {
2699                 GST_INFO_OBJECT( encodebin, "Video toggle is Disabled" );
2700         }
2701
2702         if(encodebin->vcapsfilter == NULL) {
2703                 encodebin->vcapsfilter = gst_element_factory_make ("capsfilter","vcapsfilter");
2704                 gst_bin_add (GST_BIN (element), encodebin->vcapsfilter);
2705         }
2706 #if 0
2707         encodebin->vcaps = gst_caps_new_simple("video/x-raw-yuv",
2708                 "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
2709                 "width", G_TYPE_INT, 320,
2710                 "height", G_TYPE_INT, 240,
2711                 "framerate", GST_TYPE_FRACTION, 30, 1,
2712                 NULL);
2713
2714 #endif
2715         if(encodebin->video_encode == NULL) {
2716                 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, NULL);
2717                 gst_bin_add (GST_BIN (element), encodebin->video_encode);
2718         }
2719
2720 #if 0
2721         if(encodebin->video_encode_queue == NULL) {
2722                 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
2723                 gst_bin_add (GST_BIN (element), encodebin->video_encode_queue);
2724         }
2725
2726         g_object_set(G_OBJECT(encodebin->video_encode_queue), "max-size-bytes", (unsigned int)0, NULL);
2727 #endif
2728
2729         if(encodebin->mux == NULL) {
2730                 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2731                 gst_bin_add (GST_BIN (element), encodebin->mux);
2732         }
2733
2734         if (!encodebin->video_encode
2735 //              || !encodebin->video_encode_queue
2736                 || !encodebin->mux
2737                 || !encodebin->video_queue
2738                 || !encodebin->vcapsfilter
2739                 || !encodebin->srcpad )
2740         {
2741                 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2742                 return FALSE;
2743         }
2744
2745         if( encodebin->use_video_toggle && !encodebin->video_toggle )
2746         {
2747                 GST_ERROR_OBJECT(encodebin, "Faild create video toggle element \n");
2748                 return FALSE;
2749         }
2750
2751 #if 0
2752   if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2753         encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2754       gst_bin_add (GST_BIN (element), encodebin->color_space);
2755    }
2756 #endif
2757   return TRUE;
2758 }
2759
2760 static gboolean
2761 gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data)
2762 {
2763         GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2764
2765         if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO)
2766                 return FALSE;
2767
2768         if(encodebin->audio_queue == NULL) {
2769                 encodebin->audio_queue = gst_element_factory_make ("queue","audio_queue");
2770                 gst_bin_add (GST_BIN (element), encodebin->audio_queue);
2771         }
2772
2773         if(encodebin->acapsfilter == NULL) {
2774                 encodebin->acapsfilter = gst_element_factory_make ("capsfilter","acapsfilter");
2775                 gst_bin_add (GST_BIN (element), encodebin->acapsfilter);
2776         }
2777 #if 0
2778 encodebin->acaps = gst_caps_new_simple("audio/x-raw-int",
2779         "rate", G_TYPE_INT, 8000,
2780         "channels", G_TYPE_INT, 2,
2781         "depth", G_TYPE_INT, 16,
2782         NULL);
2783 #endif
2784
2785         if(encodebin->audio_encode == NULL) {
2786                 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
2787                 gst_bin_add (GST_BIN (element), encodebin->audio_encode);
2788         }
2789
2790         if(encodebin->mux == NULL) {
2791                 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2792                 gst_bin_add (GST_BIN (element), encodebin->mux);
2793         }
2794
2795         if (!encodebin->audio_encode
2796                 || !encodebin->audio_queue
2797                 || !encodebin->mux
2798                 || !encodebin->acapsfilter
2799                 || !encodebin->srcpad )
2800         {
2801                 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2802                 return FALSE;
2803         }
2804 #if 0
2805         if (encodebin->auto_audio_convert && (encodebin->audio_conv == NULL)) {
2806                 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2807                 gst_bin_add (GST_BIN (element), encodebin->audio_conv);
2808         }
2809
2810         if (encodebin->auto_audio_resample && (encodebin->audio_sample == NULL)) {
2811                 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2812                 gst_bin_add (GST_BIN (element), encodebin->audio_sample);
2813         }
2814 #endif
2815         return TRUE;
2816 }
2817
2818
2819 static gboolean
2820 gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data)
2821 {
2822         GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2823
2824         if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE)
2825                 return FALSE;
2826
2827         if(encodebin->image_queue == NULL) {
2828                 encodebin->image_queue = gst_element_factory_make ("queue","image_queue");
2829                 gst_bin_add (GST_BIN (element), encodebin->image_queue);
2830         }
2831
2832         if(encodebin->image_toggle == NULL) {
2833                 encodebin->image_toggle = gst_element_factory_make ("toggle","image_toggle");
2834                 gst_bin_add (GST_BIN (element), encodebin->image_toggle);
2835         }
2836
2837         if(encodebin->icapsfilter == NULL) {
2838                 encodebin->icapsfilter = gst_element_factory_make ("capsfilter","icapsfilter");
2839                 gst_bin_add (GST_BIN (element), encodebin->icapsfilter);
2840         }
2841
2842         if(encodebin->image_encode == NULL) {
2843                 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
2844                 gst_bin_add (GST_BIN (element), encodebin->image_encode);
2845         }
2846
2847         if (!encodebin->image_encode
2848                 || !encodebin->image_queue
2849                 || !encodebin->image_toggle
2850                 || !encodebin->icapsfilter
2851                 || !encodebin->srcpad )
2852         {
2853                 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2854                 return FALSE;
2855         }
2856 #if 0
2857         if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2858                 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2859                 gst_bin_add (GST_BIN (element), encodebin->color_space);
2860         }
2861 #endif
2862         return TRUE;
2863 }
2864
2865 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value)
2866 {
2867
2868         if(value) { //block stream
2869                 switch(encodebin->profile) {
2870                         case GST_ENCODE_BIN_PROFILE_AV:
2871                                 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2872                                         goto block_fail;
2873                                 } else {
2874                                         if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2875                                                 "empty-buffers") == NULL) {
2876                                                 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2877                                                 goto block_fail;
2878                                         }
2879                                         if( encodebin->video_toggle )
2880                                         {
2881                                                 g_object_set(encodebin->video_toggle, "block-data", TRUE , NULL);
2882                                                 GST_INFO_OBJECT( encodebin, "video_toggle block-data TRUE" );
2883                                         }
2884
2885                                         g_object_set(encodebin->video_queue, "empty-buffers", TRUE , NULL);
2886                                         GST_INFO_OBJECT( encodebin, "video_queue empty-buffers TRUE" );
2887                                         if(encodebin->audio_queue != NULL)
2888                                         {
2889                                                 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2890                                                 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2891                                         }
2892                                 }
2893                                 break;
2894                         case GST_ENCODE_BIN_PROFILE_AUDIO:
2895                                 if(encodebin->audio_queue == NULL) {
2896                                         goto block_fail;
2897                                 } else {
2898                                         if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2899                                                 "empty-buffers") == NULL) {
2900                                                 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2901                                                 goto block_fail;
2902                                         }
2903                                         g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2904                                         GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2905                                 }
2906                                 break;
2907                         case GST_ENCODE_BIN_PROFILE_IMAGE:
2908                                 if(encodebin->image_toggle == NULL) {
2909                                         goto block_fail;
2910                                 } else {
2911                                         g_object_set(encodebin->image_toggle, "block_data", TRUE, NULL);
2912                                         GST_INFO_OBJECT( encodebin, "image_toggle block_data TRUE" );
2913                                 }
2914                                 break;
2915                         default:
2916                                 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2917                                 goto block_fail;
2918                                 break;
2919                 }
2920         } else { //release blocked-stream
2921                 switch(encodebin->profile) {
2922                         case GST_ENCODE_BIN_PROFILE_AV:
2923                                 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2924                                         goto unblock_fail;
2925                                 } else {
2926                                         if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2927                                                 "empty-buffers") == NULL) {
2928                                                 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2929                                                 goto unblock_fail;
2930                                         }
2931                                         if( encodebin->video_toggle )
2932                                         {
2933                                                 g_object_set(encodebin->video_toggle, "block-data", FALSE , NULL);
2934                                                 GST_INFO_OBJECT( encodebin, "video_toggle block-data FALSE" );
2935                                         }
2936
2937                                         if(encodebin->audio_queue != NULL)
2938                                         {
2939                                                 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2940                                                 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2941                                         }
2942                                         g_object_set(encodebin->video_queue, "empty-buffers", FALSE , NULL);
2943                                         GST_INFO_OBJECT( encodebin, "video_queue empty-buffers FALSE" );
2944                                 }
2945                                 break;
2946                         case GST_ENCODE_BIN_PROFILE_AUDIO:
2947                                 if(encodebin->audio_queue == NULL) {
2948                                         goto unblock_fail;
2949                                 } else {
2950                                         if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2951                                                 "empty-buffers") == NULL) {
2952                                                 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2953                                                 goto unblock_fail;
2954                                         }
2955                                         g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2956                                         GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2957                                 }
2958                                 break;
2959                         case GST_ENCODE_BIN_PROFILE_IMAGE:
2960                                 if(encodebin->image_toggle == NULL) {
2961                                         goto unblock_fail;
2962                                 } else {
2963                                         g_object_set(encodebin->image_toggle, "block_data", FALSE, NULL);
2964                                         GST_INFO_OBJECT( encodebin, "image_toggle block_data FALSE" );
2965                                 }
2966                                 break;
2967                         default:
2968                                 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2969                                 goto unblock_fail;
2970                                 break;
2971                 }
2972         }
2973         encodebin->block = value;
2974         return TRUE;
2975
2976 block_fail:
2977         GST_ERROR_OBJECT(encodebin, "encodebin block failed");
2978         return FALSE;
2979
2980 unblock_fail:
2981         GST_ERROR_OBJECT(encodebin, "encodebin unblock failed");
2982         return FALSE;
2983 }
2984
2985 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value)
2986 {
2987         GstClock *clock = NULL;
2988
2989         if(value) {
2990                 /* pause stream*/
2991                 //Block src of encode bin
2992                 if (!gst_encode_bin_block(encodebin, TRUE))
2993                 {
2994                         GST_WARNING_OBJECT (encodebin, "Fail to block Encodebin.");
2995                         goto pause_fail;
2996                 }
2997
2998                 if (encodebin->paused_time == 0)
2999                 {
3000                         //get steam time
3001                         if (clock = GST_ELEMENT_CLOCK(encodebin))               //before PLAYING, this would be NULL. Need to check.
3002                         {
3003                                 GstClockTime current_time, base_time;
3004
3005                                 current_time = gst_clock_get_time(clock);
3006                                 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
3007
3008                                 encodebin->paused_time = current_time - base_time;
3009
3010                                 GST_INFO_OBJECT (encodebin, "Encodebin is in running-pause at [%"GST_TIME_FORMAT"]."
3011                                         , GST_TIME_ARGS(encodebin->paused_time));
3012                         }
3013                         else
3014                         {
3015                                 encodebin->paused_time = 0;
3016                                 encodebin->total_offset_time = 0;
3017
3018                                 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3019                         }
3020                 }
3021 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3022                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
3023 #endif
3024         }
3025         else {
3026                 /* release paused-stream*/
3027                 if (encodebin->paused_time != 0)
3028                 {
3029                         if (clock = GST_ELEMENT_CLOCK(encodebin))
3030                         {
3031                                 GstClockTime current_time, base_time;
3032                                 GstClockTime paused_gap;
3033
3034                                 current_time = gst_clock_get_time(clock);
3035                                 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
3036                                 paused_gap = current_time - base_time - encodebin->paused_time;
3037
3038                                 encodebin->total_offset_time += paused_gap;
3039                                 encodebin->paused_time = 0;
3040
3041                                 GST_INFO_OBJECT (encodebin, "Encodebin now resumes. Offset delay [%"GST_TIME_FORMAT"], Total offset delay [%"GST_TIME_FORMAT"]"
3042                                         , GST_TIME_ARGS(paused_gap) , GST_TIME_ARGS(encodebin->total_offset_time));
3043                         }
3044                         else
3045                         {
3046                                 encodebin->paused_time = 0;
3047                                 encodebin->total_offset_time = 0;
3048
3049                                 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3050                         }
3051                 }
3052
3053                 //TODO : How about qos?
3054
3055                 //Unblock src of encode bin
3056                 if (!gst_encode_bin_block(encodebin, FALSE))
3057                 {
3058                         GST_WARNING_OBJECT (encodebin, "Fail to Unblock Encodebin.");
3059                         goto resume_fail;
3060                 }
3061 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3062                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
3063 #endif
3064         }
3065         encodebin->pause = value;
3066         return TRUE;
3067
3068 pause_fail:
3069         GST_WARNING_OBJECT (encodebin, "Fail to pause Encodebin");
3070 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3071                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, FALSE);
3072 #endif
3073         return FALSE;
3074
3075 resume_fail:
3076         GST_WARNING_OBJECT (encodebin, "Fail to resume Encodebin");
3077 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3078                 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, FALSE);
3079 #endif
3080         return FALSE;
3081 }
3082
3083 static gboolean
3084 gst_encode_bin_release_pipeline (GstElement *element,
3085       gpointer user_data)
3086 {
3087 #if 0
3088   GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
3089
3090   gst_element_set_state (encodebin->audio_queue, GST_STATE_NULL);
3091   gst_element_set_state (encodebin->audio_encode, GST_STATE_NULL);
3092   gst_element_set_state (encodebin->video_queue, GST_STATE_NULL);
3093   gst_element_set_state (encodebin->video_encode, GST_STATE_NULL);
3094   gst_element_set_state (encodebin->mux, GST_STATE_NULL);
3095
3096   if (encodebin->auto_video_scale) {
3097     gst_element_set_state (encodebin->video_scale, GST_STATE_NULL);
3098     gst_element_unlink (encodebin->video_queue, encodebin->video_scale);
3099     gst_element_unlink (encodebin->video_scale, encodebin->video_encode);
3100     gst_bin_remove (GST_BIN (element), encodebin->video_scale);
3101
3102     encodebin->video_scale = NULL;
3103   } else {
3104     gst_element_unlink (encodebin->video_queue, encodebin->video_encode);
3105   }
3106
3107   gst_pad_unlink (gst_element_get_pad (encodebin->audio_encode, "src"),
3108                        encodebin->mux_audio_sinkpad);
3109   gst_pad_unlink (gst_element_get_pad (encodebin->video_encode, "src"),
3110                        encodebin->mux_video_sinkpad);
3111
3112   gst_bin_remove_many (GST_BIN (element),
3113                                encodebin->audio_queue,
3114                                encodebin->audio_encode,
3115                                encodebin->video_queue,
3116                                encodebin->video_encode,
3117                                encodebin->mux,
3118                                NULL);
3119
3120   encodebin->audio_queue = NULL;
3121   encodebin->audio_encode = NULL;
3122   encodebin->video_queue = NULL;
3123   encodebin->video_encode = NULL;
3124   encodebin->mux = NULL;
3125 #endif
3126   return TRUE;
3127 }
3128
3129 static gboolean
3130 gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
3131 {
3132         GstEncodeBin *encodebin;
3133         GstStructure *structure;
3134 //      const gchar *mimetype;
3135 //      const GValue *codec_data;
3136         gint channels, rate;
3137
3138         encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3139
3140         structure = gst_caps_get_structure (vscaps, 0);
3141 //      mimetype = gst_structure_get_name (structure);
3142
3143         /* we want these for all */
3144         if (!gst_structure_get_int (structure, "channels", &channels) ||
3145                 !gst_structure_get_int (structure, "rate", &rate)) {
3146                         goto refuse_caps;
3147         }
3148
3149 //      codec_data = gst_structure_get_value (structure, "codec_data");
3150         /* FIXME */
3151         //  g_return_val_if_fail (!strcmp (mimetype, "audio/x-raw-int"), FALSE);
3152         gst_object_unref (encodebin);
3153         return TRUE;
3154
3155 refuse_caps:
3156         {
3157                 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3158                 gst_object_unref (encodebin);
3159                 return FALSE;
3160         }
3161 }
3162
3163 static gboolean
3164 gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
3165 {
3166         GstEncodeBin *encodebin;
3167         GstStructure *structure;
3168 //      const gchar *mimetype;
3169         const GValue *fps;
3170 //      const GValue *codec_data;
3171         gint width, height;
3172
3173         encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3174
3175         structure = gst_caps_get_structure (vscaps, 0);
3176 //      mimetype = gst_structure_get_name (structure);
3177
3178         if (!gst_structure_get_int (structure, "width", &width) ||
3179                 !gst_structure_get_int (structure, "height", &height)) {
3180                         goto refuse_caps;
3181         }
3182
3183 //      codec_data = gst_structure_get_value (structure, "codec_data");
3184
3185         fps = gst_structure_get_value (structure, "framerate");
3186         if (fps == NULL)
3187                 goto refuse_caps;
3188
3189         encodebin->fps = gst_value_get_fraction_numerator(fps);
3190
3191         if(encodebin->high_speed_fps > 0 && encodebin->fps > 0)
3192         {
3193                 encodebin->multiple =(encodebin->high_speed_fps)/(encodebin->fps);
3194         }
3195
3196         {
3197                 guint32 format;
3198
3199                 gst_structure_get_fourcc (structure, "format", &format);
3200
3201                 switch (format) {
3202                         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3203                                 break;
3204                         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3205                                 break;
3206                 }
3207         }
3208 /* FIXME */
3209 //  g_return_val_if_fail (!strcmp (mimetype, "video/x-raw-yuv"), FALSE);
3210
3211 #if 0
3212         switch (encodebin->profile) {
3213         case GST_ENCODE_BIN_PROFILE_3GP:
3214         //   need_videoscale
3215                 break;
3216         case GST_ENCODE_BIN_PROFILE_MP4:
3217                 break;
3218         default :
3219                 break;
3220         }
3221 #endif
3222         gst_object_unref (encodebin);
3223         return TRUE;
3224
3225 refuse_caps:
3226         {
3227                 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3228                 gst_object_unref (encodebin);
3229                 return FALSE;
3230         }
3231 }
3232
3233 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps)
3234 {
3235         GstEncodeBin *encodebin;
3236         GstStructure *structure;
3237 //      const gchar *mimetype;
3238 //      const GValue *codec_data;
3239         gint width, height;
3240
3241         encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3242
3243         structure = gst_caps_get_structure (vscaps, 0);
3244 //      mimetype = gst_structure_get_name (structure);
3245
3246         if (!gst_structure_get_int (structure, "width", &width) ||
3247                 !gst_structure_get_int (structure, "height", &height)) {
3248                         goto refuse_caps;
3249         }
3250
3251 //      codec_data = gst_structure_get_value (structure, "codec_data");
3252
3253         {
3254                 guint32 format;
3255
3256                 gst_structure_get_fourcc (structure, "format", &format);
3257
3258                 switch (format) {
3259                         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3260                                 break;
3261                         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3262                                 break;
3263                 }
3264         }
3265         gst_object_unref (encodebin);
3266         return TRUE;
3267
3268 refuse_caps:
3269         {
3270                 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3271                 gst_object_unref (encodebin);
3272                 return FALSE;
3273         }
3274
3275 }
3276
3277 static gboolean
3278 gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3279 {
3280         if (!encodebin)
3281         {
3282                 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3283                 return TRUE;
3284         }
3285
3286         //Adjusting timestamp of video source
3287         GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3288
3289         return TRUE;
3290 }
3291
3292 static gboolean
3293 gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3294 {
3295         if (!encodebin)
3296         {
3297                 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3298                 return TRUE;
3299         }
3300
3301         GST_BUFFER_TIMESTAMP(buffer)    *= encodebin->multiple;
3302         return TRUE;
3303 }
3304
3305 static gboolean
3306 gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3307 {
3308         if (!encodebin)
3309         {
3310                 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3311                 return TRUE;
3312         }
3313
3314         //Adjusting timestamp of video source
3315         GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3316
3317         return TRUE;
3318 }
3319
3320 static GstPad*
3321 gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type)
3322 {
3323         GstElementClass *elemclass = NULL;
3324         GList *walk = NULL;
3325         GstPad *pad = NULL;
3326
3327         elemclass = GST_ELEMENT_GET_CLASS (mux);
3328
3329         walk = gst_element_class_get_pad_template_list (elemclass);
3330
3331         while (walk) {
3332                 GstPadTemplate *templ;
3333
3334                 templ = (GstPadTemplate *) walk->data;
3335                 if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SINK) {
3336                         /* ENHANCE ME: Please add other specific mux's case */
3337                         if (((type == ENCODEBIN_MUX_AUDIO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "audio")) ||  //audio, audio_%d,... ex)ffmux_3gp
3338                                 ((type == ENCODEBIN_MUX_VIDEO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "video")) ||      //video, video_%d,... ex)ffmux_3gp
3339                                 strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "sink")  //sink, sink_%d, wavparse_sink, ... ex)oggmux, wavparse
3340                         ) {
3341                                 g_print("PRINT TEMPLATE(%s)\n", GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3342                                 pad = gst_element_get_request_pad (mux, GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3343                                 break;
3344                         }
3345                 }
3346                 walk = g_list_next (walk);
3347         }
3348
3349         return pad;
3350 }
3351
3352 static gboolean
3353 plugin_init (GstPlugin * plugin)
3354 {
3355   GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin");
3356
3357 #ifdef ENABLE_NLS
3358   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
3359       LOCALEDIR);
3360   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
3361 #endif /* ENABLE_NLS */
3362
3363   return gst_element_register (plugin, "encodebin", GST_RANK_NONE,
3364       GST_TYPE_ENCODE_BIN);
3365 }
3366
3367 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
3368     GST_VERSION_MINOR,
3369     "encodebin",
3370     "EXT encoder bin",
3371     plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/")