4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>
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)
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.
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
30 #include <gst/video/video.h>
32 #include "gstencodebin.h"
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
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
44 #ifndef VIDEO_ENC_QUE_TIME
45 #define VIDEO_ENC_QUE_TIME 1
47 #ifndef AUDIO_ENC_QUE_TIME
48 #define AUDIO_ENC_QUE_TIME 1
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*/) \
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), \
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);\
63 #define ENCODER_QUEUE_SET(x_queue, x_byte, x_buffer, x_time)
66 #define _GST_PAD_LINK_UNREF(srcpad, sinkpad, if_fail_goto)\
68 GstPadLinkReturn ret = _GST_PAD_LINK(srcpad, sinkpad);\
69 if(ret != GST_PAD_LINK_OK) { \
70 GstObject *src_parent = gst_pad_get_parent(srcpad);\
71 GstObject *sink_parent = gst_pad_get_parent(sinkpad);\
72 char *src_name = NULL;\
73 char *sink_name = NULL;\
74 g_object_get((GObject *)src_parent, "name", &src_name, NULL);\
75 g_object_get((GObject *)sink_parent, "name", &sink_name, NULL);\
76 GST_ERROR("src[%s] - sink[%s] link failed", src_name, sink_name);\
77 gst_object_unref(src_parent); src_parent = NULL;\
78 gst_object_unref(sink_parent); sink_parent = NULL;\
80 free(src_name); src_name = NULL;\
83 free(sink_name); sink_name = NULL;\
85 gst_object_unref(srcpad); srcpad = NULL;\
86 gst_object_unref(sinkpad); sinkpad = NULL;\
89 gst_object_unref(srcpad); srcpad = NULL;\
90 gst_object_unref(sinkpad); sinkpad = NULL;\
93 #define _GST_PAD_UNLINK_UNREF(srcpad, sinkpad)\
95 gst_pad_unlink(srcpad, sinkpad);\
96 gst_object_unref(srcpad); srcpad = NULL;\
97 gst_object_unref(sinkpad); sinkpad = NULL;\
100 #define DEFAULT_PROP_PROFILE 0
101 #define DEFAULT_PROP_HIGH_SPEED 0
102 #define DEFAULT_PROP_VENC_NAME "ffenc_h263"
103 #define DEFAULT_PROP_AENC_NAME "secenc_amr"
104 #define DEFAULT_PROP_IENC_NAME "jpegenc"
105 #define DEFAULT_PROP_MUX_NAME "ffmux_3gp"
106 #define DEFAULT_PROP_VCONV_NAME "ffmpegcolorspace"
112 // encodebin mode : a/v, audio only, stillshot
114 //support slow motion capture
127 PROP_AUTO_AUDIO_CONVERT,
128 PROP_AUTO_AUDIO_RESAMPLE,
129 PROP_AUTO_COLORSPACE,
141 PROP_USE_VIDEO_TOGGLE,
144 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
149 SIGNAL_STREAM_UNBLOCK,
151 SIGNAL_STREAM_RESUME,
157 ENCODEBIN_ELEMENT_VENC,
158 ENCODEBIN_ELEMENT_AENC,
159 ENCODEBIN_ELEMENT_IENC,
160 ENCODEBIN_ELEMENT_MUX,
161 ENCODEBIN_ELEMENT_VIDEO_CONV
162 }GstEncodeBinElement;
165 ENCODEBIN_MUX_AUDIO_SINK,
166 ENCODEBIN_MUX_VIDEO_SINK,
167 }GstEncodeBinMuxSinkPad;
172 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
173 # define ENDIANNESS "LITTLE_ENDIAN, BIG_ENDIAN"
175 # define ENDIANNESS "BIG_ENDIAN, LITTLE_ENDIAN"
178 /* generic templates */
179 #define STATIC_AUDIO_CAPS \
181 "audio/x-raw-float, " \
182 "rate = (int) [ 1, MAX ], " \
183 "channels = (int) [ 1, 8 ], " \
184 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
185 "width = (int) 64;" \
186 "audio/x-raw-float, " \
187 "rate = (int) [ 1, MAX ], " \
188 "channels = (int) [ 1, 8 ], " \
189 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
190 "width = (int) 32;" \
191 "audio/x-raw-int, " \
192 "rate = (int) [ 1, MAX ], " \
193 "channels = (int) [ 1, 8 ], " \
194 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
195 "width = (int) 32, " \
196 "depth = (int) [ 1, 32 ], " \
197 "signed = (boolean) { true, false }; " \
198 "audio/x-raw-int, " \
199 "rate = (int) [ 1, MAX ], " \
200 "channels = (int) [ 1, 8 ], " \
201 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
202 "width = (int) 24, " \
203 "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; " \
204 "audio/x-raw-int, " \
205 "rate = (int) [ 1, MAX ], " \
206 "channels = (int) [ 1, 8 ], " \
207 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
208 "width = (int) 16, " \
209 "depth = (int) [ 1, 16 ], " \
210 "signed = (boolean) { true, false }; " \
211 "audio/x-raw-int, " \
212 "rate = (int) [ 1, MAX ], " \
213 "channels = (int) [ 1, 8 ], " \
214 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
215 "width = (int) 8, " \
216 "depth = (int) [ 1, 8 ], " \
217 "signed = (boolean) { true, false } " \
220 #define STATIC_VIDEO_CAPS \
223 "width = (int) [ 1, 2147483647 ]," \
224 "height = (int) [ 1, 2147483647 ]," \
225 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
226 "format = (fourcc) I420;" \
228 "width = (int) [ 1, 2147483647 ]," \
229 "height = (int) [ 1, 2147483647 ]," \
230 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
231 "format = (fourcc) YV12;" \
233 "width = (int) [ 1, 2147483647 ]," \
234 "height = (int) [ 1, 2147483647 ]," \
235 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
236 "format = (fourcc) YUY2;" \
238 "width = (int) [ 1, 2147483647 ]," \
239 "height = (int) [ 1, 2147483647 ]," \
240 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
242 "depth = (int) 24," \
243 "red_mask = (int) 16711680," \
244 "green_mask = (int) 65280," \
245 "blue_mask = (int) 255," \
246 "endianness = (int) 4321;" \
248 "width = (int) [ 1, 2147483647 ]," \
249 "height = (int) [ 1, 2147483647 ]," \
250 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
252 "depth = (int) 24," \
253 "red_mask = (int) 255," \
254 "green_mask = (int) 65280," \
255 "blue_mask = (int) 16711680," \
256 "endianness = (int) 4321;" \
258 "width = (int) [ 1, 2147483647 ]," \
259 "height = (int) [ 1, 2147483647 ]," \
260 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
261 "format = (fourcc) Y42B;" \
263 "width = (int) [ 1, 2147483647 ]," \
264 "height = (int) [ 1, 2147483647 ]," \
265 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
266 "format = (fourcc) Y444;" \
268 "width = (int) [ 1, 2147483647 ]," \
269 "height = (int) [ 1, 2147483647 ]," \
270 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
272 "depth = (int) 32," \
273 "red_mask = (int) 65280," \
274 "green_mask = (int) 16711680," \
275 "blue_mask = (int) -16777216," \
276 "alpha_mask = (int) 255," \
277 "endianness = (int) 4321;" \
279 "width = (int) [ 1, 2147483647 ]," \
280 "height = (int) [ 1, 2147483647 ]," \
281 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
283 "depth = (int) 32," \
284 "red_mask = (int) 16711680," \
285 "green_mask = (int) 65280," \
286 "blue_mask = (int) 255," \
287 "alpha_mask = (int) -16777216," \
288 "endianness = (int) 4321;" \
290 "width = (int) [ 1, 2147483647 ]," \
291 "height = (int) [ 1, 2147483647 ]," \
292 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
294 "depth = (int) 32," \
295 "red_mask = (int) 255," \
296 "green_mask = (int) 65280," \
297 "blue_mask = (int) 16711680," \
298 "alpha_mask = (int) -16777216," \
299 "endianness = (int) 4321;" \
301 "width = (int) [ 1, 2147483647 ]," \
302 "height = (int) [ 1, 2147483647 ]," \
303 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
305 "depth = (int) 32," \
306 "red_mask = (int) -16777216," \
307 "green_mask = (int) 16711680," \
308 "blue_mask = (int) 65280," \
309 "alpha_mask = (int) 255," \
310 "endianness = (int) 4321;" \
312 "width = (int) [ 1, 2147483647 ]," \
313 "height = (int) [ 1, 2147483647 ]," \
314 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
316 "depth = (int) 24," \
317 "red_mask = (int) 65280," \
318 "green_mask = (int) 16711680," \
319 "blue_mask = (int) -16777216," \
320 "endianness = (int) 4321;" \
322 "width = (int) [ 1, 2147483647 ]," \
323 "height = (int) [ 1, 2147483647 ]," \
324 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
326 "depth = (int) 24," \
327 "red_mask = (int) 255," \
328 "green_mask = (int) 65280," \
329 "blue_mask = (int) 16711680," \
330 "endianness = (int) 4321;" \
332 "width = (int) [ 1, 2147483647 ]," \
333 "height = (int) [ 1, 2147483647 ]," \
334 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
336 "depth = (int) 24," \
337 "red_mask = (int) 16711680," \
338 "green_mask = (int) 65280," \
339 "blue_mask = (int) 255," \
340 "endianness = (int) 4321;" \
342 "width = (int) [ 1, 2147483647 ]," \
343 "height = (int) [ 1, 2147483647 ]," \
344 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
346 "depth = (int) 24," \
347 "red_mask = (int) -16777216," \
348 "green_mask = (int) 16711680," \
349 "blue_mask = (int) 65280," \
350 "endianness = (int) 4321;" \
352 "width = (int) [ 1, 2147483647 ]," \
353 "height = (int) [ 1, 2147483647 ]," \
354 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
355 "format = (fourcc) YUV9;" \
357 "width = (int) [ 1, 2147483647 ]," \
358 "height = (int) [ 1, 2147483647 ]," \
359 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
360 "format = (fourcc) YVU9;" \
362 "width = (int) [ 1, 2147483647 ]," \
363 "height = (int) [ 1, 2147483647 ]," \
364 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
365 "format = (fourcc) Y41B;" \
367 "width = (int) [ 1, 2147483647 ]," \
368 "height = (int) [ 1, 2147483647 ]," \
369 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
371 "depth = (int) 16," \
372 "red_mask = (int) 63488," \
373 "green_mask = (int) 2016," \
374 "blue_mask = (int) 31," \
375 "endianness = (int) 1234;" \
377 "width = (int) [ 1, 2147483647 ]," \
378 "height = (int) [ 1, 2147483647 ]," \
379 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
381 "depth = (int) 15," \
382 "red_mask = (int) 31744," \
383 "green_mask = (int) 992," \
384 "blue_mask = (int) 31," \
385 "endianness = (int) 1234;" \
386 "video/x-raw-gray," \
387 "width = (int) [ 1, 2147483647 ]," \
388 "height = (int) [ 1, 2147483647 ]," \
389 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
393 "width = (int) [ 1, 2147483647 ]," \
394 "height = (int) [ 1, 2147483647 ]," \
395 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
398 "endianness = (int) 1234;" \
400 "width = (int) [ 1, 2147483647 ]," \
401 "height = (int) [ 1, 2147483647 ]," \
402 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
403 "format = (fourcc) UYVY;" \
405 "width = (int) [ 1, 2147483647 ]," \
406 "height = (int) [ 1, 2147483647 ]," \
407 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
408 "format = (fourcc) IYU1;" \
410 "width = (int) [ 1, 2147483647 ]," \
411 "height = (int) [ 1, 2147483647 ]," \
412 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
413 "format = (fourcc) AYUV " \
417 static GstStaticPadTemplate encoder_bin_src_template =
418 GST_STATIC_PAD_TEMPLATE ("src",
421 GST_STATIC_CAPS_ANY);
423 static GstStaticPadTemplate encoder_bin_video_sink_template =
424 GST_STATIC_PAD_TEMPLATE ("video",
430 static GstStaticPadTemplate encoder_bin_audio_sink_template =
431 GST_STATIC_PAD_TEMPLATE ("audio",
437 static GstStaticPadTemplate encoder_bin_image_sink_template =
438 GST_STATIC_PAD_TEMPLATE ("image",
441 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
444 GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug);
445 #define GST_CAT_DEFAULT gst_encode_bin_debug
447 static void gst_encode_bin_class_init (GstEncodeBinClass *klass);
448 static void gst_encode_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
449 static void gst_encode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
450 static void gst_encode_bin_init (GstEncodeBin * encodebin);
451 static void gst_encode_bin_dispose (GObject * object);
452 static void gst_encode_bin_finalize (GObject * object);
453 static GstPad *gst_encode_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name);
455 static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, GstStateChange transition);
456 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
457 static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad);
458 static gint pad_compare_name (GstPad * pad1, const gchar * name);
459 static gboolean gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
460 #if 0 //disable unused function
461 static gboolean gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean profile);
462 static void gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement);
463 static gboolean gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
464 static gboolean gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element);
465 #endif //disable unused function
466 static gboolean gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element);
467 static gboolean gst_encode_bin_link_elements (GstEncodeBin *encodebin);
468 static gboolean gst_encode_bin_unlink_elements (GstEncodeBin *encodebin);
469 static gboolean gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data);
470 static gboolean gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data);
471 static gboolean gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data);
472 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value);
473 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value);
474 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
475 static gboolean gst_encode_bin_release_pipeline (GstElement *element, gpointer user_data);
476 static gboolean gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps);
477 static gboolean gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps);
478 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps);
479 static GstPad* gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type);
482 static gboolean gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
483 static gboolean gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
484 static gboolean gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
486 static GstElementClass *parent_class;
488 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
489 static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 };
492 static const GstElementDetails gst_encode_bin_details =
493 GST_ELEMENT_DETAILS ("Samsung Electronics Co. Encoder Bin",
494 "Generic/Bin/Encoder",
495 "Autoplug and encode to muxed media",
496 "Jeonghoon Park <jh1979.park@samsung.com>, Wonhyung Cho <wh01.cho@samsung.com>, Sangho Park <sangho.g.park@samsung.com>");
499 GST_ENCODE_BIN_PROFILE_AV,
500 GST_ENCODE_BIN_PROFILE_AUDIO,
501 GST_ENCODE_BIN_PROFILE_IMAGE,
502 } GstEncodeBinProfile;
505 gst_encode_bin_profile_get_type (void)
507 static GType encode_bin_profile_type = 0;
508 static const GEnumValue profile_types[] = {
509 {GST_ENCODE_BIN_PROFILE_AV, "Audio and Video Recording", "A/V"},
510 {GST_ENCODE_BIN_PROFILE_AUDIO, "Audio Only Recording", "Audio"},
511 {GST_ENCODE_BIN_PROFILE_IMAGE, "Image Stillshot", "Image"},
515 if (!encode_bin_profile_type) {
516 encode_bin_profile_type =
517 g_enum_register_static ("GstEncodeBinProfile",profile_types);
519 return encode_bin_profile_type;
523 gst_encode_bin_get_type (void)
525 static GType gst_encode_bin_type = 0;
527 if (!gst_encode_bin_type) {
528 static const GTypeInfo gst_encode_bin_info = {
529 sizeof (GstEncodeBinClass),
532 (GClassInitFunc) gst_encode_bin_class_init,
535 sizeof (GstEncodeBin),
537 (GInstanceInitFunc) gst_encode_bin_init,
541 gst_encode_bin_type =
542 g_type_register_static (GST_TYPE_BIN, "GstEncodeBin",
543 &gst_encode_bin_info, 0);
546 return gst_encode_bin_type;
550 queue_overun_cb (GstElement * queue, GstEncodeBin *encodebin)
553 guint queue_size = 0;
554 guint queue_bufnum = 0;
555 // guint64 queue_time= (guint64)0;
557 GstClockTime now = gst_util_get_timestamp ();
559 g_object_get(G_OBJECT(queue), "current-level-bytes", &queue_size,
560 "current-level-buffers", &queue_bufnum,
561 // "current-level-time", &queue_time,
563 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
564 ("[%" GST_TIME_FORMAT "][%s], [%u b], [%u]",
565 GST_TIME_ARGS(now), GST_OBJECT_NAME(queue), queue_size, queue_bufnum), (NULL));
567 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
568 ("%s overrun", GST_OBJECT_NAME(queue)), (NULL));
573 gst_encode_bin_get_property (GObject * object,
574 guint prop_id, GValue * value, GParamSpec * pspec)
576 GstEncodeBin *encodebin;
578 encodebin = GST_ENCODE_BIN (object);
582 g_value_set_enum (value, encodebin->profile);
584 case PROP_HIGH_SPEED:
585 g_value_set_int (value, encodebin->high_speed_fps);
589 g_value_set_string (value, encodebin->venc_name);
592 g_value_set_string (value, encodebin->aenc_name);
595 g_value_set_string (value, encodebin->ienc_name);
598 g_value_set_string (value, encodebin->mux_name);
600 case PROP_VCONV_NAME:
601 g_value_set_string (value, encodebin->vconv_name);
605 gst_value_set_caps (value, encodebin->vcaps);
608 gst_value_set_caps (value, encodebin->acaps);
611 gst_value_set_caps (value, encodebin->icaps);
614 case PROP_AUTO_AUDIO_CONVERT:
615 g_value_set_boolean (value, encodebin->auto_audio_convert);
617 case PROP_AUTO_AUDIO_RESAMPLE:
618 g_value_set_boolean (value, encodebin->auto_audio_resample);
620 case PROP_AUTO_COLORSPACE:
621 g_value_set_boolean (value, encodebin->auto_color_space);
624 g_value_set_boolean (value, encodebin->block);
627 g_value_set_boolean (value, encodebin->pause);
629 case PROP_VENC_QUEUE:
630 // g_value_set_boolean (value, encodebin->use_venc_queue);
631 if((encodebin->video_encode_queue == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
632 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
633 if(encodebin->video_encode_queue != NULL)
634 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
636 g_value_set_object (value, encodebin->video_encode_queue);
638 case PROP_AENC_QUEUE:
639 // g_value_set_boolean (value, encodebin->use_aenc_queue);
640 if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
641 encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue");
642 if(encodebin->audio_encode_queue != NULL)
643 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
645 g_value_set_object (value, encodebin->audio_encode_queue);
649 if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
650 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
651 if(encodebin->video_encode != NULL)
652 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
654 g_value_set_object (value, encodebin->video_encode);
657 if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
658 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
659 if(encodebin->audio_encode != NULL)
660 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
662 g_value_set_object (value, encodebin->audio_encode);
665 if(encodebin->image_encode == NULL && (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE)) {
666 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
667 if(encodebin->image_encode != NULL)
668 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
670 g_value_set_object (value, encodebin->image_encode);
673 if(encodebin->mux == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
674 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
675 if(encodebin->mux != NULL)
676 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
678 g_value_set_object (value, encodebin->mux);
680 case PROP_VIDEO_CONV:
681 if(encodebin->color_space == NULL && (encodebin->profile != GST_ENCODE_BIN_PROFILE_AUDIO)) {
682 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
683 if(encodebin->color_space != NULL)
684 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
686 g_value_set_object (value, encodebin->color_space);
688 case PROP_USE_VIDEO_TOGGLE:
689 g_value_set_boolean( value, encodebin->use_video_toggle );
692 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
698 gst_encode_bin_set_property (GObject * object,
699 guint prop_id, const GValue * value, GParamSpec * pspec)
701 GstEncodeBin *encodebin;
703 encodebin = GST_ENCODE_BIN (object);
707 encodebin->profile = g_value_get_enum (value);
709 gboolean newprofile = g_value_get_enum (value);
710 if(encodebin->profile != newprofile) {
711 gst_encode_bin_change_profile(encodebin, newprofile);
712 encodebin->profile = newprofile;
716 case PROP_HIGH_SPEED:
717 encodebin->high_speed_fps = g_value_get_int (value);
719 case PROP_VENC_NAME: {
720 const gchar *new_name;
721 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
722 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
725 new_name = g_value_get_string (value);
727 if(encodebin->video_encode == NULL) {
728 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
729 encodebin->venc_name = g_strdup (new_name);
731 if(strcmp (encodebin->venc_name, new_name)) {
732 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
733 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
734 encodebin->venc_name = g_strdup (new_name);
739 case PROP_AENC_NAME: {
740 const gchar *new_name;
741 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
742 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
745 new_name = g_value_get_string (value);
747 if(encodebin->audio_encode == NULL) {
748 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
749 encodebin->aenc_name = g_strdup (new_name);
751 if(strcmp (encodebin->aenc_name, new_name)) {
752 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
753 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
754 encodebin->aenc_name = g_strdup (new_name);
759 case PROP_IENC_NAME: {
760 const gchar *new_name;
761 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
762 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
765 new_name = g_value_get_string (value);
767 if(encodebin->image_encode == NULL) {
768 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
769 encodebin->ienc_name = g_strdup (new_name);
771 if(strcmp (encodebin->ienc_name, new_name)) {
772 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
773 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
774 encodebin->ienc_name = g_strdup (new_name);
779 case PROP_MUX_NAME: {
780 const gchar *new_name;
781 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
782 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
785 new_name = g_value_get_string (value);
787 if(encodebin->mux == NULL) {
788 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
789 encodebin->mux_name = g_strdup (new_name);
791 if(strcmp (encodebin->mux_name, new_name)) {
792 gst_encode_bin_remove_element(encodebin, encodebin->mux);
793 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
794 encodebin->mux_name = g_strdup (new_name);
799 case PROP_VCONV_NAME: {
800 const gchar *new_name;
801 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
802 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
805 new_name = g_value_get_string(value);
807 if (encodebin->color_space == NULL) {
808 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
809 encodebin->vconv_name = g_strdup (new_name);
811 if(strcmp (encodebin->vconv_name, new_name)) {
812 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
813 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
814 encodebin->vconv_name = g_strdup (new_name);
823 const GstCaps *new_caps_val = gst_value_get_caps (value);
825 if (new_caps_val == NULL) {
826 new_caps = gst_caps_new_any ();
828 new_caps = (GstCaps *) new_caps_val;
829 gst_caps_ref (new_caps);
832 old_caps = encodebin->vcaps;
833 encodebin->vcaps = new_caps;
834 gst_caps_unref (old_caps);
840 const GstCaps *new_caps_val = gst_value_get_caps (value);
842 if (new_caps_val == NULL) {
843 new_caps = gst_caps_new_any ();
845 new_caps = (GstCaps *) new_caps_val;
846 gst_caps_ref (new_caps);
849 old_caps = encodebin->acaps;
850 encodebin->acaps = new_caps;
851 gst_caps_unref (old_caps);
857 const GstCaps *new_caps_val = gst_value_get_caps (value);
859 if (new_caps_val == NULL) {
860 new_caps = gst_caps_new_any ();
862 new_caps = (GstCaps *) new_caps_val;
863 gst_caps_ref (new_caps);
866 old_caps = encodebin->icaps;
867 encodebin->icaps = new_caps;
868 gst_caps_unref (old_caps);
872 case PROP_AUTO_AUDIO_CONVERT:
873 encodebin->auto_audio_convert = g_value_get_boolean (value);
875 case PROP_AUTO_AUDIO_RESAMPLE:
876 encodebin->auto_audio_resample = g_value_get_boolean (value);
878 case PROP_AUTO_COLORSPACE:
879 encodebin->auto_color_space = g_value_get_boolean (value);
882 gboolean newval = g_value_get_boolean (value);
883 if(encodebin->block != newval) {
884 if(!gst_encode_bin_block(encodebin, newval)) {
885 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
887 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, FALSE);
889 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, FALSE);
895 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
897 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, TRUE);
899 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, TRUE);
905 gboolean newval = g_value_get_boolean (value);
906 if(encodebin->pause != newval) {
907 if(!gst_encode_bin_pause(encodebin, newval))
910 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
912 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
914 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
919 case PROP_VENC_QUEUE:
920 // encodebin->use_venc_queue = g_value_get_boolean (value);
922 GstElement *newelement = g_value_get_object (value);
923 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
924 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
927 if(newelement != NULL) {
928 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
929 encodebin->video_encode_queue = newelement;
930 gst_object_ref (encodebin->video_encode_queue);
931 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode_queue)); // take ownership ??
932 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
937 case PROP_AENC_QUEUE:
938 // encodebin->use_aenc_queue = g_value_get_boolean (value);
940 GstElement *newelement = g_value_get_object (value);
941 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
942 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
945 if(newelement != NULL) {
946 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
947 encodebin->audio_encode_queue = newelement;
948 gst_object_ref (encodebin->audio_encode_queue);
949 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode_queue));
950 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
957 GstElement *newelement = g_value_get_object (value);
958 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
959 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
962 if(newelement != NULL) {
963 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
964 encodebin->video_encode = newelement;
965 gst_object_ref (encodebin->video_encode);
966 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
967 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
973 GstElement *newelement = g_value_get_object (value);
974 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
975 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
978 if(newelement != NULL) {
979 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
980 encodebin->audio_encode = newelement;
981 gst_object_ref (encodebin->audio_encode);
982 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
983 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
987 case PROP_IMAGE_ENC: {
988 GstElement *newelement = g_value_get_object (value);
989 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
990 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
993 if(newelement != NULL) {
994 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
995 encodebin->image_encode = newelement;
996 gst_object_ref (encodebin->image_encode);
997 gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
998 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1003 GstElement *newelement = g_value_get_object (value);
1004 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
1005 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
1008 if(newelement != NULL) {
1009 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1010 encodebin->mux = newelement;
1011 gst_object_ref (encodebin->mux);
1012 gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
1013 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1017 case PROP_VIDEO_CONV: {
1018 GstElement *newelement = g_value_get_object (value);
1019 if(encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
1020 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
1023 if(newelement != NULL) {
1024 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1025 encodebin->color_space = newelement;
1026 gst_object_ref (encodebin->color_space);
1027 gst_object_sink (GST_OBJECT_CAST (encodebin->color_space));
1028 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1032 case PROP_USE_VIDEO_TOGGLE:
1033 encodebin->use_video_toggle = g_value_get_boolean( value );
1036 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1042 gst_encode_bin_request_new_pad (GstElement * element,
1043 GstPadTemplate * templ, const gchar * req_name)
1045 GstEncodeBin *encodebin = NULL;
1046 GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
1049 g_return_val_if_fail (templ != NULL, NULL);
1051 if (templ->direction != GST_PAD_SINK) {
1052 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: request pad that is not a SINK pad\n");
1056 g_return_val_if_fail (GST_IS_ENCODE_BIN (element), NULL);
1058 encodebin = GST_ENCODE_BIN (element);
1061 if (templ == gst_element_class_get_pad_template (klass, "audio")) {
1062 if (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO) {
1063 gst_encode_bin_init_audio_elements(element, NULL); //??
1065 if(encodebin->audio_sinkpad == NULL)
1067 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
1068 encodebin->audio_sinkpad = gst_ghost_pad_new ("audio", pad);
1069 gst_object_unref(pad);
1074 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: audio pad is aleady existed, return existing audio pad\n");
1075 return encodebin->audio_sinkpad;
1078 gst_element_add_pad (element, encodebin->audio_sinkpad);
1079 gst_pad_set_setcaps_function (encodebin->audio_sinkpad,
1080 GST_DEBUG_FUNCPTR (gst_encode_bin_audsink_set_caps));
1081 return encodebin->audio_sinkpad;
1084 } else if (templ == gst_element_class_get_pad_template (klass, "video")) {
1085 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV) {
1086 gst_encode_bin_init_video_elements(element, NULL); //??
1088 if(encodebin->video_sinkpad == NULL)
1090 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
1091 encodebin->video_sinkpad = gst_ghost_pad_new ("video", pad);
1092 gst_object_unref(pad);
1097 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: video pad is aleady existed, return existing video pad\n");
1098 return encodebin->video_sinkpad;
1101 gst_element_add_pad (element, encodebin->video_sinkpad);
1102 gst_pad_set_setcaps_function (encodebin->video_sinkpad,
1103 GST_DEBUG_FUNCPTR (gst_encode_bin_vidsink_set_caps));
1104 return encodebin->video_sinkpad;
1105 } else if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1106 gst_encode_bin_init_image_elements(element, NULL); //??
1108 if(encodebin->image_sinkpad == NULL)
1110 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1111 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1112 gst_object_unref(pad);
1117 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1118 return encodebin->image_sinkpad;
1121 gst_element_add_pad (element, encodebin->image_sinkpad);
1122 gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1123 GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1124 return encodebin->image_sinkpad;
1128 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1129 gst_encode_bin_init_image_elements(element, NULL); //??
1131 if(encodebin->image_sinkpad == NULL)
1133 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1134 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1135 gst_object_unref(pad);
1140 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1141 return encodebin->image_sinkpad;
1144 gst_element_add_pad (element, encodebin->image_sinkpad);
1145 gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1146 GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1147 return encodebin->image_sinkpad;
1154 gst_encode_bin_class_init (GstEncodeBinClass *klass)
1156 GObjectClass *gobject_klass;
1157 GstElementClass *gstelement_klass;
1158 GstBinClass *gstbin_klass;
1160 gobject_klass = (GObjectClass *) klass;
1161 gstelement_klass = (GstElementClass *) klass;
1162 gstbin_klass = (GstBinClass *) klass;
1164 parent_class = g_type_class_peek_parent (klass);
1166 gobject_klass->get_property = gst_encode_bin_get_property;
1167 gobject_klass->set_property = gst_encode_bin_set_property;
1168 gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_encode_bin_dispose);
1169 gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_encode_bin_finalize);
1172 g_object_class_install_property (gobject_klass, PROP_PROFILE,
1173 g_param_spec_enum ("profile", "PROFILE", "Profile of the media to record",
1174 GST_TYPE_ENCODE_BIN_PROFILE, DEFAULT_PROP_PROFILE,
1175 G_PARAM_READWRITE));
1177 g_object_class_install_property (gobject_klass, PROP_HIGH_SPEED,
1178 g_param_spec_int ("high-speed-fps", "high speed rec. fps", "framerate for high speed recording", 0, G_MAXINT,
1179 DEFAULT_PROP_HIGH_SPEED, G_PARAM_READWRITE));
1181 g_object_class_install_property (gobject_klass, PROP_VENC_NAME,
1182 g_param_spec_string ("venc-name", "video encoder name", "the name of video encoder to use",
1183 DEFAULT_PROP_VENC_NAME, G_PARAM_READWRITE));
1185 g_object_class_install_property (gobject_klass, PROP_AENC_NAME,
1186 g_param_spec_string ("aenc-name", "audio encoder name", "the name of audio encoder to use",
1187 DEFAULT_PROP_AENC_NAME, G_PARAM_READWRITE));
1189 g_object_class_install_property (gobject_klass, PROP_IENC_NAME,
1190 g_param_spec_string ("ienc-name", "image encoder name", "the name of image encoder to use",
1191 DEFAULT_PROP_IENC_NAME, G_PARAM_READWRITE));
1193 g_object_class_install_property (gobject_klass, PROP_MUX_NAME,
1194 g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use",
1195 DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE));
1197 g_object_class_install_property (gobject_klass, PROP_VCONV_NAME,
1198 g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use",
1199 DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE));
1201 g_object_class_install_property (gobject_klass, PROP_VCAPS,
1202 g_param_spec_boxed ("vcaps", "caps for video","caps for video recording",
1203 GST_TYPE_CAPS, G_PARAM_READWRITE));
1205 g_object_class_install_property (gobject_klass, PROP_ACAPS,
1206 g_param_spec_boxed ("acaps", "caps for audio","caps for audio recording",
1207 GST_TYPE_CAPS, G_PARAM_READWRITE));
1209 g_object_class_install_property (gobject_klass, PROP_ICAPS,
1210 g_param_spec_boxed ("icaps", "caps for image","caps for image stillshot",
1211 GST_TYPE_CAPS, G_PARAM_READWRITE));
1213 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_CONVERT,
1214 g_param_spec_boolean ("auto-audio-convert", "auto audio convert",
1215 "Support for auto audio convert", TRUE, G_PARAM_READWRITE));
1217 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_RESAMPLE,
1218 g_param_spec_boolean ("auto-audio-resample", "auto audio resample",
1219 "Support for auto audio resample", TRUE, G_PARAM_READWRITE));
1221 g_object_class_install_property (gobject_klass, PROP_AUTO_COLORSPACE,
1222 g_param_spec_boolean ("auto-colorspace", "auto colorspace",
1223 "Support for auto colorspace", TRUE, G_PARAM_READWRITE));
1225 g_object_class_install_property (gobject_klass, PROP_BLOCK,
1226 g_param_spec_boolean ("block", "stream block",
1227 "Support for stream block", FALSE, G_PARAM_READWRITE));
1229 g_object_class_install_property (gobject_klass, PROP_PAUSE,
1230 g_param_spec_boolean ("runtime-pause", "recording pause",
1231 "Support for recording pause/resume", FALSE, G_PARAM_READWRITE));
1234 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1235 g_param_spec_boolean ("use-venc-queue", "use queue between venc and mux",
1236 "add queue between venc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1238 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1239 g_param_spec_boolean ("use-aenc-queue", "use queue between aenc and mux",
1240 "add queue between aenc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1242 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1243 g_param_spec_object ("use-venc-queue", "Video Encoder queue",
1244 "add queue between venc and mux(only for custom optimization)",
1245 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1247 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1248 g_param_spec_object ("use-aenc-queue", "Audio Encoder queue",
1249 "add queue between aenc and mux(only for custom optimization)",
1250 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1253 g_object_class_install_property (gobject_klass, PROP_VIDEO_ENC,
1254 g_param_spec_object ("video-encode", "Video Encoder",
1255 "the video encoder element to use",
1256 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1258 g_object_class_install_property (gobject_klass, PROP_AUDIO_ENC,
1259 g_param_spec_object ("audio-encode", "Audio Encoder",
1260 "the audio encoder element to use",
1261 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1263 g_object_class_install_property (gobject_klass, PROP_IMAGE_ENC,
1264 g_param_spec_object ("image-encode", "Image Encoder",
1265 "the Image encoder element to use",
1266 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1268 g_object_class_install_property (gobject_klass, PROP_MUX,
1269 g_param_spec_object ("mux", "Muxer",
1270 "the muxer element to use",
1271 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1273 g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV,
1274 g_param_spec_object ("video-convert", "Video converter",
1275 "the video converter element to use",
1276 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1278 g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE,
1279 g_param_spec_boolean ("use-video-toggle", "Use video toggle",
1280 "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE));
1282 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
1283 gst_encode_bin_signals[SIGNAL_STREAM_BLOCK] =
1284 g_signal_new ("stream-block", G_TYPE_FROM_CLASS (klass),
1285 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_block),
1286 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1288 gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK] =
1289 g_signal_new ("stream-unblock", G_TYPE_FROM_CLASS (klass),
1290 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_unblock),
1291 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1293 gst_encode_bin_signals[SIGNAL_STREAM_PAUSE] =
1294 g_signal_new ("stream-pause", G_TYPE_FROM_CLASS (klass),
1295 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_pause),
1296 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1298 gst_encode_bin_signals[SIGNAL_STREAM_RESUME] =
1299 g_signal_new ("stream-resume", G_TYPE_FROM_CLASS (klass),
1300 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_resume),
1301 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1304 gst_element_class_add_pad_template (gstelement_klass,
1305 gst_static_pad_template_get (&encoder_bin_src_template));
1306 gst_element_class_add_pad_template (gstelement_klass,
1307 gst_static_pad_template_get (&encoder_bin_audio_sink_template));
1308 gst_element_class_add_pad_template (gstelement_klass,
1309 gst_static_pad_template_get (&encoder_bin_video_sink_template));
1310 gst_element_class_add_pad_template (gstelement_klass,
1311 gst_static_pad_template_get (&encoder_bin_image_sink_template));
1313 gst_element_class_set_details (gstelement_klass, &gst_encode_bin_details);
1315 gstelement_klass->request_new_pad =
1316 GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad);
1317 gstelement_klass->release_pad =
1318 GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad);
1319 gstelement_klass->change_state =
1320 GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
1324 gst_encode_bin_init (GstEncodeBin *encodebin)
1326 encodebin->mutex = g_mutex_new();
1328 if (encodebin->srcpad == NULL) {
1329 encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
1330 gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
1333 encodebin->video_sinkpad = NULL;
1334 encodebin->audio_sinkpad = NULL;
1335 encodebin->image_sinkpad = NULL;
1336 encodebin->mux_audio_sinkpad = NULL;
1337 encodebin->mux_video_sinkpad = NULL;
1339 encodebin->profile = DEFAULT_PROP_PROFILE;
1341 encodebin->high_speed_fps = DEFAULT_PROP_HIGH_SPEED;
1342 encodebin->multiple = 1;
1344 encodebin->auto_audio_convert = TRUE;
1345 encodebin->auto_audio_resample = TRUE;
1346 encodebin->auto_color_space = TRUE;
1347 encodebin->block = FALSE;
1348 encodebin->pause= FALSE;
1349 encodebin->use_video_toggle = TRUE;
1350 encodebin->use_venc_queue= FALSE;
1351 encodebin->use_aenc_queue= FALSE;
1353 encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME);
1354 encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME);
1355 encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);
1356 encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);
1357 encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME);
1359 encodebin->vcaps = gst_caps_new_any ();
1360 encodebin->acaps = gst_caps_new_any ();
1361 encodebin->icaps = gst_caps_new_any ();
1363 encodebin->audio_queue = NULL;
1364 encodebin->video_queue = NULL;
1365 encodebin->video_encode_queue = NULL;
1366 encodebin->image_queue = NULL;
1368 encodebin->audio_encode = NULL;
1369 encodebin->video_encode = NULL;
1370 encodebin->image_encode = NULL;
1372 encodebin->vcapsfilter = NULL;
1373 encodebin->acapsfilter = NULL;
1374 encodebin->icapsfilter = NULL;
1376 encodebin->video_toggle = NULL;
1377 encodebin->image_toggle = NULL;
1378 encodebin->color_space = NULL;
1379 encodebin->audio_conv = NULL;
1380 encodebin->audio_sample = NULL;
1382 encodebin->mux = NULL;
1384 encodebin->paused_time = 0;
1385 encodebin->total_offset_time = 0;
1387 encodebin->vsink_probeid = 0;
1388 encodebin->vsink_hs_probeid = 0;
1389 encodebin->asink_probeid = 0;
1390 encodebin->veque_sig_id = 0;
1391 encodebin->aeque_sig_id = 0;
1395 gst_encode_bin_dispose (GObject * object)
1397 GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1399 g_free(encodebin->venc_name);
1400 encodebin->venc_name = NULL;
1402 g_free(encodebin->aenc_name);
1403 encodebin->aenc_name = NULL;
1405 g_free(encodebin->ienc_name);
1406 encodebin->ienc_name = NULL;
1408 g_free(encodebin->mux_name);
1409 encodebin->mux_name = NULL;
1411 g_free(encodebin->vconv_name);
1412 encodebin->vconv_name = NULL;
1414 gst_caps_replace (&encodebin->vcaps, NULL);
1415 gst_caps_replace (&encodebin->acaps, NULL);
1416 gst_caps_replace (&encodebin->icaps, NULL);
1418 if (encodebin->srcpad != NULL) {
1419 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad);
1420 encodebin->srcpad = NULL;
1423 G_OBJECT_CLASS (parent_class)->dispose (object);
1425 encodebin->video_sinkpad = NULL;
1426 encodebin->audio_sinkpad = NULL;
1427 encodebin->image_sinkpad = NULL;
1428 encodebin->mux_audio_sinkpad = NULL;
1429 encodebin->mux_video_sinkpad = NULL;
1431 encodebin->audio_queue = NULL;
1432 encodebin->video_queue = NULL;
1433 encodebin->image_queue = NULL;
1435 encodebin->audio_encode = NULL;
1436 encodebin->video_encode = NULL;
1437 encodebin->video_encode_queue = NULL;
1438 encodebin->image_encode = NULL;
1440 encodebin->vcapsfilter = NULL;
1441 encodebin->acapsfilter = NULL;
1442 encodebin->icapsfilter = NULL;
1444 encodebin->video_toggle = NULL;
1445 encodebin->image_toggle = NULL;
1446 encodebin->color_space = NULL;
1447 encodebin->audio_conv = NULL;
1448 encodebin->audio_sample = NULL;
1450 if (encodebin->mux && GST_IS_ELEMENT(encodebin->mux)) {
1451 int remain_count= 0;
1452 remain_count = GST_OBJECT_REFCOUNT_VALUE(encodebin->mux);
1453 while (remain_count) {
1454 gst_object_unref(encodebin->mux);
1459 encodebin->mux = NULL;
1463 gst_encode_bin_finalize (GObject * object)
1465 GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1467 g_mutex_free (encodebin->mutex);
1469 G_OBJECT_CLASS (parent_class)->finalize (object);
1472 static GstStateChangeReturn
1473 gst_encode_bin_change_state (GstElement * element, GstStateChange transition)
1475 GstStateChangeReturn ret;
1476 GstEncodeBin *encode_bin;
1478 encode_bin = GST_ENCODE_BIN (element);
1480 switch (transition) {
1481 case GST_STATE_CHANGE_NULL_TO_READY:
1482 gst_encode_bin_link_elements(encode_bin);
1484 case GST_STATE_CHANGE_READY_TO_PAUSED:
1485 /* reset time related values */
1486 encode_bin->paused_time = 0;
1487 encode_bin->total_offset_time = 0;
1489 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1491 case GST_STATE_CHANGE_PAUSED_TO_READY:
1497 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1499 switch (transition) {
1500 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1502 case GST_STATE_CHANGE_PAUSED_TO_READY:
1504 case GST_STATE_CHANGE_READY_TO_NULL:
1505 gst_encode_bin_unlink_elements(encode_bin);
1511 // if (ret == GST_STATE_CHANGE_FAILURE)
1518 gst_encode_bin_release_all_pads (GstEncodeBin *encodebin)
1520 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->video_sinkpad);
1521 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->audio_sinkpad);
1522 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->image_sinkpad);
1526 gst_encode_bin_release_pad (GstElement * element, GstPad * pad)
1528 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
1529 GstPad *muxpad = NULL;
1531 if(!pad_compare_name(pad, "video")) {
1533 gst_encode_bin_remove_element(encodebin, encodebin->video_queue);
1534 encodebin->video_queue = NULL;
1535 gst_encode_bin_remove_element(encodebin, encodebin->video_toggle);
1536 encodebin->video_toggle = NULL;
1537 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1538 encodebin->color_space = NULL;
1539 gst_encode_bin_remove_element(encodebin, encodebin->vcapsfilter);
1540 encodebin->vcapsfilter = NULL;
1541 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
1542 encodebin->video_encode_queue = NULL;
1543 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1544 encodebin->video_encode = NULL;
1546 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1547 encodebin->mux_video_sinkpad = NULL;
1549 if(encodebin->mux_audio_sinkpad == NULL) {
1550 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1551 encodebin->mux = NULL;
1555 encodebin->mux_audio_sinkpad = NULL;
1559 if(encodebin->mux_video_sinkpad != NULL)
1561 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1562 encodebin->mux_video_sinkpad = NULL;
1565 gst_pad_set_active (pad, FALSE); //??
1566 gst_element_remove_pad(element, pad);
1567 encodebin->video_sinkpad = NULL;
1568 } else if(!pad_compare_name(pad, "audio")) {
1570 gst_encode_bin_remove_element(encodebin, encodebin->audio_queue);
1571 encodebin->audio_queue = NULL;
1572 gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
1573 encodebin->audio_sample = NULL;
1574 gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
1575 encodebin->audio_conv = NULL;
1576 gst_encode_bin_remove_element(encodebin, encodebin->acapsfilter);
1577 encodebin->acapsfilter = NULL;
1578 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
1579 encodebin->audio_encode_queue = NULL;
1580 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1581 encodebin->audio_encode = NULL;
1583 encodebin->mux_audio_sinkpad;
1584 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1587 if(encodebin->mux_video_sinkpad == NULL) {
1588 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1589 encodebin->mux = NULL;
1593 encodebin->mux_video_sinkpad = NULL;
1596 if(encodebin->mux_audio_sinkpad != NULL)
1598 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1599 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
1600 encodebin->mux_audio_sinkpad = NULL;
1603 gst_pad_set_active (pad, FALSE); //??
1604 gst_element_remove_pad(element, pad);
1605 encodebin->audio_sinkpad = NULL;
1608 gst_encode_bin_remove_element(encodebin, encodebin->image_queue);
1609 encodebin->image_queue = NULL;
1610 gst_encode_bin_remove_element(encodebin, encodebin->image_toggle);
1611 encodebin->image_toggle = NULL;
1612 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1613 encodebin->color_space = NULL;
1614 gst_encode_bin_remove_element(encodebin, encodebin->icapsfilter);
1615 encodebin->icapsfilter = NULL;
1616 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1617 encodebin->image_encode = NULL;
1619 gst_pad_set_active (pad, FALSE); //??
1620 gst_element_remove_pad(element, pad);
1621 encodebin->image_sinkpad = NULL;
1626 pad_compare_name (GstPad * pad1, const gchar * name)
1630 GST_OBJECT_LOCK (pad1);
1631 result = strcmp (GST_PAD_NAME (pad1), name);
1632 GST_OBJECT_UNLOCK (pad1);
1638 gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1641 case ENCODEBIN_ELEMENT_VENC:
1642 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1643 if(encodebin->video_encode != NULL) {
1644 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1645 g_free(encodebin->venc_name);
1646 encodebin->venc_name = NULL;
1648 goto element_make_fail;
1651 case ENCODEBIN_ELEMENT_AENC:
1652 encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");
1653 if(encodebin->audio_encode != NULL) {
1654 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1655 g_free(encodebin->aenc_name);
1656 encodebin->aenc_name = NULL;
1658 goto element_make_fail;
1661 case ENCODEBIN_ELEMENT_IENC:
1662 encodebin->image_encode = gst_element_factory_make (name, "image_encode");
1663 if(encodebin->image_encode != NULL) {
1664 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1665 g_free(encodebin->ienc_name);
1666 encodebin->ienc_name = NULL;
1668 goto element_make_fail;
1671 case ENCODEBIN_ELEMENT_MUX:
1672 encodebin->mux = gst_element_factory_make (name, "mux");
1673 if(encodebin->mux != NULL) {
1674 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1675 g_free(encodebin->mux_name);
1676 encodebin->mux_name = NULL;
1678 goto element_make_fail;
1681 case ENCODEBIN_ELEMENT_VIDEO_CONV:
1682 encodebin->color_space = gst_element_factory_make(name, "video_convert");
1683 if (encodebin->color_space != NULL) {
1684 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1685 g_free(encodebin->vconv_name);
1686 encodebin->vconv_name = NULL;
1688 goto element_make_fail;
1692 GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1699 GST_WARNING_OBJECT(encodebin, "no such element factory \"%s\"!", name);
1703 #if 0 //disable unused function
1705 gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean newprofile)
1708 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1709 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1710 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1711 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1713 switch (newprofile) {
1714 case GST_ENCODE_BIN_PROFILE_AV :
1715 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1716 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name,"video_encode");
1717 encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1719 gst_bin_add_many (GST_BIN (encodebin),
1720 encodebin->audio_encode,
1721 encodebin->video_encode,
1725 case GST_ENCODE_BIN_PROFILE_AUDIO :
1726 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1727 encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1729 gst_bin_add_many (GST_BIN (encodebin),
1730 encodebin->audio_encode,
1734 case GST_ENCODE_BIN_PROFILE_IMAGE :
1735 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name,"image_encode");
1737 gst_bin_add_many (GST_BIN (encodebin),
1738 encodebin->image_encode,
1742 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
1751 gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement)
1753 if(newelement == NULL) {
1754 GST_ERROR_OBJECT(encodebin, "some elements are null\n");
1758 case PROP_VIDEO_ENC:
1759 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1760 encodebin->video_encode = newelement;
1761 gst_object_ref (encodebin->video_encode);
1762 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
1763 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1765 case PROP_AUDIO_ENC:
1766 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1767 encodebin->audio_encode = newelement;
1768 gst_object_ref (encodebin->audio_encode);
1769 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
1770 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1772 case PROP_IMAGE_ENC:
1773 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1774 encodebin->image_encode = newelement;
1775 gst_object_ref (encodebin->image_encode);
1776 gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
1777 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1780 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1781 encodebin->mux = newelement;
1782 gst_object_ref (encodebin->mux);
1783 gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
1784 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1787 GST_WARNING_OBJECT(encodebin, "Invalid type = %d", type);
1794 gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1796 GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1799 case ENCODEBIN_ELEMENT_VENC:
1800 if(encodebin->video_encode == NULL) {
1801 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1802 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1804 sink1 = gst_element_get_static_pad(encodebin->video_encode, "sink");
1805 src = gst_element_get_static_pad(encodebin->video_encode, "src");
1807 peersink1 = gst_pad_get_peer(sink1);
1808 if(peersink1 != NULL) {
1809 if(!gst_pad_unlink(peersink1, sink1)) {
1816 peersrc = gst_pad_get_peer(src);
1817 if(peersrc != NULL) {
1818 if(!gst_pad_unlink(src, peersrc)) {
1824 if(gst_encode_bin_remove_element(encodebin, encodebin->video_encode)) {
1825 if(encodebin->video_encode = gst_element_factory_make (name, "video_encode") != NULL) {
1826 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1827 if(peersink1 != NULL) {
1828 if(!gst_pad_link(peersink1, gst_element_get_pad(encodebin->video_encode, "sink"))) {
1833 if(peersrc != NULL) {
1834 if(!gst_pad_link(gst_element_get_pad(encodebin->video_encode, "src"), peersrc)) {
1839 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] make fail\n", type);
1843 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] remove fail\n", type);
1848 case ENCODEBIN_ELEMENT_AENC:
1850 case ENCODEBIN_ELEMENT_IENC:
1852 case ENCODEBIN_ELEMENT_MUX:
1855 GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1858 gst_object_unref(sink1);
1859 gst_object_unref(sink2);
1860 gst_object_unref(src);
1861 gst_object_unref(peersink1);
1862 gst_object_unref(peersink2);
1863 gst_object_unref(peersrc);
1867 gst_object_unref(sink1);
1868 gst_object_unref(sink2);
1869 gst_object_unref(src);
1870 gst_object_unref(peersink1);
1871 gst_object_unref(peersink2);
1872 gst_object_unref(peersrc);
1873 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] unlink fail\n", type);
1878 gst_object_unref(sink1);
1879 gst_object_unref(sink2);
1880 gst_object_unref(src);
1881 gst_object_unref(peersink1);
1882 gst_object_unref(peersink2);
1883 gst_object_unref(peersrc);
1884 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] link fail\n", type);
1889 gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element)
1891 GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1894 case ENCODEBIN_ELEMENT_VENC:
1895 if(encodebin->video_encode == NULL) {
1896 encodebin->video_encode = element
1899 case ENCODEBIN_ELEMENT_AENC:
1901 case ENCODEBIN_ELEMENT_IENC:
1903 case ENCODEBIN_ELEMENT_MUX:
1906 GST_WARNING_OBJECT (encodebin,"Invalid element type = %d", type);
1909 #endif //disable unused function
1912 gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element)
1915 gchar *ename = NULL;
1916 GST_INFO_OBJECT (encodebin, "gst_encode_bin_remove_element");
1918 if (element == NULL) {
1919 GST_INFO_OBJECT (encodebin, "element is already NULL");
1923 gst_element_set_state (element, GST_STATE_NULL);
1924 parent = gst_element_get_parent (element);
1926 if (parent != NULL) {
1927 if(!gst_bin_remove (GST_BIN_CAST (parent), element)) {
1928 gst_object_unref (parent);
1929 ename = gst_element_get_name (element);
1930 GST_ERROR_OBJECT (encodebin, "gst_encode_bin_remove_element() [%s] remove fail", ename);
1934 gst_object_unref(parent);
1937 gst_object_unref(element);
1944 gst_encode_bin_link_elements (GstEncodeBin *encodebin) // need to return ????
1946 GstPad *srcpad = NULL, *sinkpad = NULL;
1947 switch(encodebin->profile) {
1948 case GST_ENCODE_BIN_PROFILE_AV :
1949 if (!gst_caps_is_any(encodebin->vcaps)) {
1950 gchar *caps_str = NULL;
1951 caps_str = gst_caps_to_string(encodebin->vcaps);
1953 GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str);
1958 g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL);
1961 if (encodebin->auto_color_space) {
1962 if(encodebin->color_space == NULL) {
1963 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
1964 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
1967 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
1968 if( encodebin->video_toggle )
1970 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
1971 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1973 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
1975 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
1976 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1978 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
1979 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
1980 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1982 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
1983 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
1984 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1986 if(encodebin->use_venc_queue)
1988 if(encodebin->video_encode_queue == NULL) {
1989 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
1990 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
1992 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1993 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1994 G_CALLBACK(queue_overun_cb), encodebin);
1998 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1999 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2000 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2003 if(encodebin->video_encode_queue)
2005 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2006 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2007 G_CALLBACK(queue_overun_cb), encodebin);
2009 g_object_set(G_OBJECT(encodebin->video_queue),
2010 "max-size-bytes", (guint)0,
2011 "max-size-buffers", (guint)1,
2012 "max-size-time", (guint64)0,
2015 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2016 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2017 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2023 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
2024 if( encodebin->video_toggle )
2026 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
2027 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2029 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
2031 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
2032 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2034 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
2035 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
2036 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2038 if(encodebin->use_venc_queue)
2040 if(encodebin->video_encode_queue == NULL) {
2041 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
2042 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
2044 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2045 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2046 G_CALLBACK(queue_overun_cb), encodebin);
2049 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2050 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2051 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2055 if(encodebin->video_encode_queue)
2057 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2058 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2059 G_CALLBACK(queue_overun_cb), encodebin);
2061 g_object_set(G_OBJECT(encodebin->video_queue),
2062 "max-size-bytes", (guint)0,
2063 "max-size-buffers", (guint)1,
2064 "max-size-time", (guint64)0,
2068 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2069 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2070 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2076 // gst_element_get_request_pad (encodebin->mux, "video_%d");
2078 if(encodebin->use_venc_queue)
2080 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2081 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2082 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2085 if(encodebin->video_encode_queue)
2087 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2088 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2089 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2094 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2095 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2096 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2099 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2100 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2101 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2102 gst_object_unref(srcpad);
2105 /* For pause/resume control */
2106 // encodebin->vsink_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_queue, "sink"),
2107 sinkpad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2108 encodebin->vsink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe), encodebin);
2109 gst_object_unref(sinkpad);
2112 if(encodebin->high_speed_fps > DEFAULT_PROP_HIGH_SPEED)
2114 // encodebin->vsink_hs_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_encode, "sink"),
2115 sinkpad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2116 encodebin->vsink_hs_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe_hs), encodebin);
2117 gst_object_unref(sinkpad);
2121 if(encodebin->audio_queue == NULL)
2123 GST_WARNING_OBJECT(encodebin, "Audio pad isn't requested, recording video only mode");
2126 case GST_ENCODE_BIN_PROFILE_AUDIO :
2127 if(!gst_caps_is_any(encodebin->acaps))
2129 g_object_set(encodebin->acapsfilter, "caps", encodebin->acaps, NULL);
2131 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2132 if (!encodebin->auto_audio_convert) {
2133 if(encodebin->audio_sample == NULL) {
2134 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2135 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2137 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2138 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2139 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2141 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2142 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2143 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2145 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2146 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2147 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2149 if(encodebin->use_aenc_queue)
2151 if(encodebin->audio_encode_queue == NULL) {
2152 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2153 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2155 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2156 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2157 G_CALLBACK(queue_overun_cb), encodebin);
2160 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2161 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2162 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2165 if(encodebin->audio_encode_queue)
2168 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2169 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2170 G_CALLBACK(queue_overun_cb), encodebin);
2172 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2173 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2174 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2178 } else if (!encodebin->auto_audio_resample) {
2179 if (encodebin->audio_conv == NULL) {
2180 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2181 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2184 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2185 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2186 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2188 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2189 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2190 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2192 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2193 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2194 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2196 if(encodebin->use_aenc_queue)
2198 if(encodebin->audio_encode_queue == NULL) {
2199 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2200 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2202 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2203 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2204 G_CALLBACK(queue_overun_cb), encodebin);
2207 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2208 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2209 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2213 if(encodebin->audio_encode_queue)
2216 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2217 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2218 G_CALLBACK(queue_overun_cb), encodebin);
2220 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2221 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2222 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2227 if(encodebin->audio_sample == NULL) {
2228 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2229 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2231 if (encodebin->audio_conv == NULL) {
2232 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2233 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2236 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2237 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2238 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2240 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2241 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2242 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2244 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2245 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2246 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2248 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2249 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2250 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2252 if(encodebin->use_aenc_queue)
2254 if(encodebin->audio_encode_queue == NULL) {
2255 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2256 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2258 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2259 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2260 G_CALLBACK(queue_overun_cb), encodebin);
2263 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2264 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2265 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2269 if(encodebin->audio_encode_queue)
2272 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2273 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2274 G_CALLBACK(queue_overun_cb), encodebin);
2276 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2277 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2278 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2285 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2286 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2287 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2289 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2290 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2291 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2293 if(encodebin->use_aenc_queue)
2295 if(encodebin->audio_encode_queue == NULL) {
2296 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2297 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2299 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2300 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2301 G_CALLBACK(queue_overun_cb), encodebin);
2304 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2305 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2306 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2309 if(encodebin->audio_encode_queue)
2312 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2313 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2314 G_CALLBACK(queue_overun_cb), encodebin);
2316 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2317 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2318 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2324 if(encodebin->use_aenc_queue)
2326 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2327 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2328 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2333 if(encodebin->audio_encode_queue)
2335 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2336 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2337 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2343 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2344 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2345 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2349 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2350 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2351 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2352 gst_object_unref(srcpad);
2355 /* For pause/resume control */
2356 sinkpad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2357 encodebin->asink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_audio_probe), encodebin);
2358 gst_object_unref(sinkpad);
2362 case GST_ENCODE_BIN_PROFILE_IMAGE :
2363 if(!gst_caps_is_any(encodebin->icaps))
2365 g_object_set(encodebin->icapsfilter, "caps", encodebin->icaps, NULL);
2368 if (encodebin->auto_color_space) {
2369 if(encodebin->color_space == NULL) {
2370 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2371 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
2374 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
2375 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
2376 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2378 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
2379 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
2380 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2382 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
2383 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
2384 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2386 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2387 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2388 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2393 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
2394 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
2395 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2397 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
2398 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
2399 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2401 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2402 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2403 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2406 srcpad = gst_element_get_static_pad (encodebin->image_encode, "src");
2407 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2408 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2409 gst_object_unref(srcpad);
2413 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2417 // gst_pad_set_active(encodebin->srcpad, TRUE);
2422 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2423 GST_WARNING_OBJECT(encodebin, "encodebin link video elements fail");
2428 gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
2429 gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
2430 GST_WARNING_OBJECT(encodebin, "encodebin link audio elements fail");
2435 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2436 GST_WARNING_OBJECT(encodebin, "encodebin link image elements fail");
2443 gst_encode_bin_unlink_elements (GstEncodeBin *encodebin)
2445 GstPad *pad = NULL, *muxpad = NULL;
2447 switch(encodebin->profile) {
2448 case GST_ENCODE_BIN_PROFILE_AV :
2449 if (encodebin->auto_color_space) {
2450 if (encodebin->video_toggle) {
2451 gst_element_unlink_many(
2452 encodebin->video_queue,
2453 encodebin->video_toggle,
2454 encodebin->color_space,
2455 encodebin->vcapsfilter,
2456 encodebin->video_encode,
2457 //encodebin->video_encode_queue,
2460 gst_element_unlink_many(
2461 encodebin->video_queue,
2462 encodebin->color_space,
2463 encodebin->vcapsfilter,
2464 encodebin->video_encode,
2465 //encodebin->video_encode_queue,
2469 if (encodebin->video_toggle) {
2470 gst_element_unlink_many(
2471 encodebin->video_queue,
2472 encodebin->video_toggle,
2473 encodebin->vcapsfilter,
2474 encodebin->video_encode,
2475 //encodebin->video_encode_queue,
2478 gst_element_unlink_many(
2479 encodebin->video_queue,
2480 encodebin->vcapsfilter,
2481 encodebin->video_encode,
2482 //encodebin->video_encode_queue,
2487 if(encodebin->mux_video_sinkpad != NULL)
2490 if(encodebin->use_venc_queue)
2492 gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2494 pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2495 gst_pad_unlink(pad, muxpad);
2496 gst_object_unref(pad);
2499 if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2501 g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id );
2505 if(encodebin->video_encode_queue)
2507 gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2509 pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2510 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2511 gst_object_unref(pad);
2514 if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2516 g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id );
2522 pad = gst_element_get_static_pad (encodebin->video_encode, "src");
2523 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2524 gst_object_unref(pad);
2528 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
2529 // gst_object_unref(encodebin->mux_video_sinkpad); //***
2530 encodebin->mux_video_sinkpad = NULL;
2533 if(encodebin->vsink_probeid)
2535 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2536 gst_pad_remove_buffer_probe(pad, encodebin->vsink_probeid);
2537 encodebin->vsink_probeid = 0;
2538 gst_object_unref(pad);
2543 if(encodebin->vsink_hs_probeid)
2545 pad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2546 gst_pad_remove_buffer_probe(pad, encodebin->vsink_hs_probeid);
2547 encodebin->vsink_hs_probeid = 0;
2548 gst_object_unref(pad);
2552 if(encodebin->audio_queue == NULL)
2556 case GST_ENCODE_BIN_PROFILE_AUDIO :
2557 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2558 if (!encodebin->auto_audio_convert) {
2559 gst_element_unlink_many (
2560 encodebin->audio_queue,
2561 encodebin->audio_sample,
2562 encodebin->acapsfilter,
2563 encodebin->audio_encode,
2565 } else if (!encodebin->auto_audio_resample) {
2566 gst_element_unlink_many (
2567 encodebin->audio_queue,
2568 encodebin->audio_conv,
2569 encodebin->acapsfilter,
2570 encodebin->audio_encode,
2573 gst_element_unlink_many (
2574 encodebin->audio_queue,
2575 encodebin->audio_conv,
2576 encodebin->audio_sample,
2577 encodebin->acapsfilter,
2578 encodebin->audio_encode,
2583 gst_element_unlink_many (
2584 encodebin->audio_queue,
2585 encodebin->acapsfilter,
2586 encodebin->audio_encode,
2590 if(encodebin->mux_audio_sinkpad != NULL)
2593 if(encodebin->use_aenc_queue)
2595 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2597 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2598 gst_pad_unlink(pad, muxpad);
2599 gst_object_unref(pad);
2602 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2604 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2608 if(encodebin->audio_encode_queue)
2610 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2612 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2613 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2614 gst_object_unref(pad);
2617 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2619 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2625 pad = gst_element_get_static_pad (encodebin->audio_encode, "src");
2626 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2627 gst_object_unref(pad);
2631 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
2632 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
2633 encodebin->mux_audio_sinkpad = NULL;
2636 if(encodebin->asink_probeid)
2638 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2639 gst_pad_remove_buffer_probe(pad, encodebin->asink_probeid);
2640 encodebin->asink_probeid =0;
2641 gst_object_unref(pad);
2646 case GST_ENCODE_BIN_PROFILE_IMAGE :
2647 if (encodebin->auto_color_space) {
2648 gst_element_unlink_many (
2649 encodebin->image_queue,
2650 encodebin->image_toggle,
2651 encodebin->color_space,
2652 encodebin->icapsfilter,
2653 encodebin->image_encode,
2657 gst_element_unlink_many (
2658 encodebin->image_queue,
2659 encodebin->image_toggle,
2660 encodebin->icapsfilter,
2661 encodebin->image_encode,
2666 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2670 // gst_pad_set_active(encodebin->srcpad, TRUE);
2676 gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data)
2678 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2680 if(encodebin->profile != GST_ENCODE_BIN_PROFILE_AV)
2683 if(encodebin->video_queue == NULL) {
2684 encodebin->video_queue = gst_element_factory_make ("queue","video_queue");
2685 gst_bin_add (GST_BIN (element), encodebin->video_queue);
2688 if( encodebin->use_video_toggle )
2690 if( encodebin->video_toggle == NULL )
2692 encodebin->video_toggle = gst_element_factory_make ("toggle","video_toggle");
2693 gst_bin_add (GST_BIN (element), encodebin->video_toggle);
2695 GST_INFO_OBJECT( encodebin, "Video toggle is Enabled" );
2699 GST_INFO_OBJECT( encodebin, "Video toggle is Disabled" );
2702 if(encodebin->vcapsfilter == NULL) {
2703 encodebin->vcapsfilter = gst_element_factory_make ("capsfilter","vcapsfilter");
2704 gst_bin_add (GST_BIN (element), encodebin->vcapsfilter);
2707 encodebin->vcaps = gst_caps_new_simple("video/x-raw-yuv",
2708 "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
2709 "width", G_TYPE_INT, 320,
2710 "height", G_TYPE_INT, 240,
2711 "framerate", GST_TYPE_FRACTION, 30, 1,
2715 if(encodebin->video_encode == NULL) {
2716 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
2717 gst_bin_add (GST_BIN (element), encodebin->video_encode);
2721 if(encodebin->video_encode_queue == NULL) {
2722 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
2723 gst_bin_add (GST_BIN (element), encodebin->video_encode_queue);
2726 g_object_set(G_OBJECT(encodebin->video_encode_queue), "max-size-bytes", (unsigned int)0, NULL);
2729 if(encodebin->mux == NULL) {
2730 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2731 gst_bin_add (GST_BIN (element), encodebin->mux);
2734 if (!encodebin->video_encode
2735 // || !encodebin->video_encode_queue
2737 || !encodebin->video_queue
2738 || !encodebin->vcapsfilter
2739 || !encodebin->srcpad )
2741 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2745 if( encodebin->use_video_toggle && !encodebin->video_toggle )
2747 GST_ERROR_OBJECT(encodebin, "Faild create video toggle element \n");
2752 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2753 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2754 gst_bin_add (GST_BIN (element), encodebin->color_space);
2761 gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data)
2763 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2765 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO)
2768 if(encodebin->audio_queue == NULL) {
2769 encodebin->audio_queue = gst_element_factory_make ("queue","audio_queue");
2770 gst_bin_add (GST_BIN (element), encodebin->audio_queue);
2773 if(encodebin->acapsfilter == NULL) {
2774 encodebin->acapsfilter = gst_element_factory_make ("capsfilter","acapsfilter");
2775 gst_bin_add (GST_BIN (element), encodebin->acapsfilter);
2778 encodebin->acaps = gst_caps_new_simple("audio/x-raw-int",
2779 "rate", G_TYPE_INT, 8000,
2780 "channels", G_TYPE_INT, 2,
2781 "depth", G_TYPE_INT, 16,
2785 if(encodebin->audio_encode == NULL) {
2786 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
2787 gst_bin_add (GST_BIN (element), encodebin->audio_encode);
2790 if(encodebin->mux == NULL) {
2791 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2792 gst_bin_add (GST_BIN (element), encodebin->mux);
2795 if (!encodebin->audio_encode
2796 || !encodebin->audio_queue
2798 || !encodebin->acapsfilter
2799 || !encodebin->srcpad )
2801 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2805 if (encodebin->auto_audio_convert && (encodebin->audio_conv == NULL)) {
2806 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2807 gst_bin_add (GST_BIN (element), encodebin->audio_conv);
2810 if (encodebin->auto_audio_resample && (encodebin->audio_sample == NULL)) {
2811 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2812 gst_bin_add (GST_BIN (element), encodebin->audio_sample);
2820 gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data)
2822 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2824 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE)
2827 if(encodebin->image_queue == NULL) {
2828 encodebin->image_queue = gst_element_factory_make ("queue","image_queue");
2829 gst_bin_add (GST_BIN (element), encodebin->image_queue);
2832 if(encodebin->image_toggle == NULL) {
2833 encodebin->image_toggle = gst_element_factory_make ("toggle","image_toggle");
2834 gst_bin_add (GST_BIN (element), encodebin->image_toggle);
2837 if(encodebin->icapsfilter == NULL) {
2838 encodebin->icapsfilter = gst_element_factory_make ("capsfilter","icapsfilter");
2839 gst_bin_add (GST_BIN (element), encodebin->icapsfilter);
2842 if(encodebin->image_encode == NULL) {
2843 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
2844 gst_bin_add (GST_BIN (element), encodebin->image_encode);
2847 if (!encodebin->image_encode
2848 || !encodebin->image_queue
2849 || !encodebin->image_toggle
2850 || !encodebin->icapsfilter
2851 || !encodebin->srcpad )
2853 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2857 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2858 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2859 gst_bin_add (GST_BIN (element), encodebin->color_space);
2865 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value)
2868 if(value) { //block stream
2869 switch(encodebin->profile) {
2870 case GST_ENCODE_BIN_PROFILE_AV:
2871 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2874 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2875 "empty-buffers") == NULL) {
2876 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2879 if( encodebin->video_toggle )
2881 g_object_set(encodebin->video_toggle, "block-data", TRUE , NULL);
2882 GST_INFO_OBJECT( encodebin, "video_toggle block-data TRUE" );
2885 g_object_set(encodebin->video_queue, "empty-buffers", TRUE , NULL);
2886 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers TRUE" );
2887 if(encodebin->audio_queue != NULL)
2889 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2890 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2894 case GST_ENCODE_BIN_PROFILE_AUDIO:
2895 if(encodebin->audio_queue == NULL) {
2898 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2899 "empty-buffers") == NULL) {
2900 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2903 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2904 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2907 case GST_ENCODE_BIN_PROFILE_IMAGE:
2908 if(encodebin->image_toggle == NULL) {
2911 g_object_set(encodebin->image_toggle, "block_data", TRUE, NULL);
2912 GST_INFO_OBJECT( encodebin, "image_toggle block_data TRUE" );
2916 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2920 } else { //release blocked-stream
2921 switch(encodebin->profile) {
2922 case GST_ENCODE_BIN_PROFILE_AV:
2923 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2926 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2927 "empty-buffers") == NULL) {
2928 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2931 if( encodebin->video_toggle )
2933 g_object_set(encodebin->video_toggle, "block-data", FALSE , NULL);
2934 GST_INFO_OBJECT( encodebin, "video_toggle block-data FALSE" );
2937 if(encodebin->audio_queue != NULL)
2939 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2940 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2942 g_object_set(encodebin->video_queue, "empty-buffers", FALSE , NULL);
2943 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers FALSE" );
2946 case GST_ENCODE_BIN_PROFILE_AUDIO:
2947 if(encodebin->audio_queue == NULL) {
2950 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2951 "empty-buffers") == NULL) {
2952 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2955 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2956 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2959 case GST_ENCODE_BIN_PROFILE_IMAGE:
2960 if(encodebin->image_toggle == NULL) {
2963 g_object_set(encodebin->image_toggle, "block_data", FALSE, NULL);
2964 GST_INFO_OBJECT( encodebin, "image_toggle block_data FALSE" );
2968 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2973 encodebin->block = value;
2977 GST_ERROR_OBJECT(encodebin, "encodebin block failed");
2981 GST_ERROR_OBJECT(encodebin, "encodebin unblock failed");
2985 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value)
2987 GstClock *clock = NULL;
2991 //Block src of encode bin
2992 if (!gst_encode_bin_block(encodebin, TRUE))
2994 GST_WARNING_OBJECT (encodebin, "Fail to block Encodebin.");
2998 if (encodebin->paused_time == 0)
3001 if (clock = GST_ELEMENT_CLOCK(encodebin)) //before PLAYING, this would be NULL. Need to check.
3003 GstClockTime current_time, base_time;
3005 current_time = gst_clock_get_time(clock);
3006 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
3008 encodebin->paused_time = current_time - base_time;
3010 GST_INFO_OBJECT (encodebin, "Encodebin is in running-pause at [%"GST_TIME_FORMAT"]."
3011 , GST_TIME_ARGS(encodebin->paused_time));
3015 encodebin->paused_time = 0;
3016 encodebin->total_offset_time = 0;
3018 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3021 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3022 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
3026 /* release paused-stream*/
3027 if (encodebin->paused_time != 0)
3029 if (clock = GST_ELEMENT_CLOCK(encodebin))
3031 GstClockTime current_time, base_time;
3032 GstClockTime paused_gap;
3034 current_time = gst_clock_get_time(clock);
3035 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
3036 paused_gap = current_time - base_time - encodebin->paused_time;
3038 encodebin->total_offset_time += paused_gap;
3039 encodebin->paused_time = 0;
3041 GST_INFO_OBJECT (encodebin, "Encodebin now resumes. Offset delay [%"GST_TIME_FORMAT"], Total offset delay [%"GST_TIME_FORMAT"]"
3042 , GST_TIME_ARGS(paused_gap) , GST_TIME_ARGS(encodebin->total_offset_time));
3046 encodebin->paused_time = 0;
3047 encodebin->total_offset_time = 0;
3049 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3053 //TODO : How about qos?
3055 //Unblock src of encode bin
3056 if (!gst_encode_bin_block(encodebin, FALSE))
3058 GST_WARNING_OBJECT (encodebin, "Fail to Unblock Encodebin.");
3061 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3062 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
3065 encodebin->pause = value;
3069 GST_WARNING_OBJECT (encodebin, "Fail to pause Encodebin");
3070 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3071 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, FALSE);
3076 GST_WARNING_OBJECT (encodebin, "Fail to resume Encodebin");
3077 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3078 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, FALSE);
3084 gst_encode_bin_release_pipeline (GstElement *element,
3088 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
3090 gst_element_set_state (encodebin->audio_queue, GST_STATE_NULL);
3091 gst_element_set_state (encodebin->audio_encode, GST_STATE_NULL);
3092 gst_element_set_state (encodebin->video_queue, GST_STATE_NULL);
3093 gst_element_set_state (encodebin->video_encode, GST_STATE_NULL);
3094 gst_element_set_state (encodebin->mux, GST_STATE_NULL);
3096 if (encodebin->auto_video_scale) {
3097 gst_element_set_state (encodebin->video_scale, GST_STATE_NULL);
3098 gst_element_unlink (encodebin->video_queue, encodebin->video_scale);
3099 gst_element_unlink (encodebin->video_scale, encodebin->video_encode);
3100 gst_bin_remove (GST_BIN (element), encodebin->video_scale);
3102 encodebin->video_scale = NULL;
3104 gst_element_unlink (encodebin->video_queue, encodebin->video_encode);
3107 gst_pad_unlink (gst_element_get_pad (encodebin->audio_encode, "src"),
3108 encodebin->mux_audio_sinkpad);
3109 gst_pad_unlink (gst_element_get_pad (encodebin->video_encode, "src"),
3110 encodebin->mux_video_sinkpad);
3112 gst_bin_remove_many (GST_BIN (element),
3113 encodebin->audio_queue,
3114 encodebin->audio_encode,
3115 encodebin->video_queue,
3116 encodebin->video_encode,
3120 encodebin->audio_queue = NULL;
3121 encodebin->audio_encode = NULL;
3122 encodebin->video_queue = NULL;
3123 encodebin->video_encode = NULL;
3124 encodebin->mux = NULL;
3130 gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
3132 GstEncodeBin *encodebin;
3133 GstStructure *structure;
3134 // const gchar *mimetype;
3135 // const GValue *codec_data;
3136 gint channels, rate;
3138 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3140 structure = gst_caps_get_structure (vscaps, 0);
3141 // mimetype = gst_structure_get_name (structure);
3143 /* we want these for all */
3144 if (!gst_structure_get_int (structure, "channels", &channels) ||
3145 !gst_structure_get_int (structure, "rate", &rate)) {
3149 // codec_data = gst_structure_get_value (structure, "codec_data");
3151 // g_return_val_if_fail (!strcmp (mimetype, "audio/x-raw-int"), FALSE);
3152 gst_object_unref (encodebin);
3157 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3158 gst_object_unref (encodebin);
3164 gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
3166 GstEncodeBin *encodebin;
3167 GstStructure *structure;
3168 // const gchar *mimetype;
3170 // const GValue *codec_data;
3173 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3175 structure = gst_caps_get_structure (vscaps, 0);
3176 // mimetype = gst_structure_get_name (structure);
3178 if (!gst_structure_get_int (structure, "width", &width) ||
3179 !gst_structure_get_int (structure, "height", &height)) {
3183 // codec_data = gst_structure_get_value (structure, "codec_data");
3185 fps = gst_structure_get_value (structure, "framerate");
3189 encodebin->fps = gst_value_get_fraction_numerator(fps);
3191 if(encodebin->high_speed_fps > 0)
3193 encodebin->multiple =(encodebin->high_speed_fps)/(encodebin->fps);
3199 gst_structure_get_fourcc (structure, "format", &format);
3202 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3204 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3209 // g_return_val_if_fail (!strcmp (mimetype, "video/x-raw-yuv"), FALSE);
3212 switch (encodebin->profile) {
3213 case GST_ENCODE_BIN_PROFILE_3GP:
3216 case GST_ENCODE_BIN_PROFILE_MP4:
3222 gst_object_unref (encodebin);
3227 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3228 gst_object_unref (encodebin);
3233 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps)
3235 GstEncodeBin *encodebin;
3236 GstStructure *structure;
3237 // const gchar *mimetype;
3238 // const GValue *codec_data;
3241 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3243 structure = gst_caps_get_structure (vscaps, 0);
3244 // mimetype = gst_structure_get_name (structure);
3246 if (!gst_structure_get_int (structure, "width", &width) ||
3247 !gst_structure_get_int (structure, "height", &height)) {
3251 // codec_data = gst_structure_get_value (structure, "codec_data");
3256 gst_structure_get_fourcc (structure, "format", &format);
3259 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3261 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3265 gst_object_unref (encodebin);
3270 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3271 gst_object_unref (encodebin);
3278 gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3282 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3286 //Adjusting timestamp of video source
3287 GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3293 gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3297 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3301 GST_BUFFER_TIMESTAMP(buffer) *= encodebin->multiple;
3306 gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3310 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3314 //Adjusting timestamp of video source
3315 GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3321 gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type)
3323 GstElementClass *elemclass = NULL;
3327 elemclass = GST_ELEMENT_GET_CLASS (mux);
3329 walk = gst_element_class_get_pad_template_list (elemclass);
3332 GstPadTemplate *templ;
3334 templ = (GstPadTemplate *) walk->data;
3335 if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SINK) {
3336 /* ENHANCE ME: Please add other specific mux's case */
3337 if (((type == ENCODEBIN_MUX_AUDIO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "audio")) || //audio, audio_%d,... ex)ffmux_3gp
3338 ((type == ENCODEBIN_MUX_VIDEO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "video")) || //video, video_%d,... ex)ffmux_3gp
3339 strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "sink") //sink, sink_%d, wavparse_sink, ... ex)oggmux, wavparse
3341 g_print("PRINT TEMPLATE(%s)\n", GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3342 pad = gst_element_get_request_pad (mux, GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3346 walk = g_list_next (walk);
3353 plugin_init (GstPlugin * plugin)
3355 GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin");
3358 GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
3360 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
3361 #endif /* ENABLE_NLS */
3363 return gst_element_register (plugin, "encodebin", GST_RANK_NONE,
3364 GST_TYPE_ENCODE_BIN);
3367 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
3371 plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/")