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