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