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 "gsttizenencodebin.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 gst_object_unref( srcpad ); srcpad = NULL;\
70 gst_object_unref( sinkpad ); sinkpad = NULL;\
71 if( ret != GST_PAD_LINK_OK) goto if_fail_goto;\
74 #define _GST_PAD_UNLINK_UNREF( srcpad, sinkpad)\
76 gst_pad_unlink( srcpad, sinkpad );\
77 gst_object_unref( srcpad ); srcpad = NULL;\
78 gst_object_unref( sinkpad ); sinkpad = NULL;\
81 #define DEFAULT_PROP_PROFILE 0
82 #define DEFAULT_PROP_HIGH_SPEED 0
83 #define DEFAULT_PROP_VENC_NAME "avenc_h263"
84 #define DEFAULT_PROP_AENC_NAME "secenc_amr"
85 #define DEFAULT_PROP_IENC_NAME "jpegenc"
86 #define DEFAULT_PROP_MUX_NAME "avmux_3gp"
87 #define DEFAULT_PROP_VCONV_NAME "videoconvert"
93 // encodebin mode : a/v, audio only, stillshot
95 //support slow motion capture
108 PROP_AUTO_AUDIO_CONVERT,
109 PROP_AUTO_AUDIO_RESAMPLE,
110 PROP_AUTO_COLORSPACE,
122 PROP_USE_VIDEO_TOGGLE,
125 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
130 SIGNAL_STREAM_UNBLOCK,
132 SIGNAL_STREAM_RESUME,
138 TIZEN_ENCODEBIN_ELEMENT_VENC,
139 TIZEN_ENCODEBIN_ELEMENT_AENC,
140 TIZEN_ENCODEBIN_ELEMENT_IENC,
141 TIZEN_ENCODEBIN_ELEMENT_MUX,
142 TIZEN_ENCODEBIN_ELEMENT_VIDEO_CONV
143 }GstTizenEncodeBinElement;
146 TIZEN_ENCODEBIN_MUX_AUDIO_SINK,
147 TIZEN_ENCODEBIN_MUX_VIDEO_SINK,
148 }GstTizenEncodeBinMuxSinkPad;
153 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
154 # define ENDIANNESS "LITTLE_ENDIAN, BIG_ENDIAN"
156 # define ENDIANNESS "BIG_ENDIAN, LITTLE_ENDIAN"
159 /* generic templates */
160 #define STATIC_AUDIO_CAPS \
163 "format = (string) { F64LE, F64BE }, " \
164 "rate = (int) [ 1, MAX ], " \
165 "channels = (int) [ 1, 8 ]; " \
167 "format = (string) { F32LE, F32BE }, " \
168 "rate = (int) [ 1, MAX ], " \
169 "channels = (int) [ 1, 8 ]; " \
171 "format = (string) { S32LE, S32BE, U32LE, U32BE }, " \
172 "rate = (int) [ 1, MAX ], " \
173 "channels = (int) [ 1, 8 ]; " \
175 "format = (string) { S24LE, S24BE, U24LE, U24BE }, " \
176 "rate = (int) [ 1, MAX ], " \
177 "channels = (int) [ 1, 8 ]; " \
179 "format = (string) { S16LE, S16BE, U16LE, U16BE }, " \
180 "rate = (int) [ 1, MAX ], " \
181 "channels = (int) [ 1, 8 ]; " \
183 "format = (string) { S8, U8 }, " \
184 "rate = (int) [ 1, MAX ], " \
185 "channels = (int) [ 1, 8 ]; " \
188 #define STATIC_VIDEO_CAPS \
190 GST_VIDEO_CAPS_MAKE("I420") ";" \
191 GST_VIDEO_CAPS_MAKE("YV12") ";" \
192 GST_VIDEO_CAPS_MAKE("YUY2") ";" \
193 GST_VIDEO_CAPS_MAKE("RGB") ";" \
194 GST_VIDEO_CAPS_MAKE("BGR") ";" \
195 GST_VIDEO_CAPS_MAKE("Y42B") ";" \
196 GST_VIDEO_CAPS_MAKE("Y444") ";" \
197 GST_VIDEO_CAPS_MAKE("BGRA") ";" \
198 GST_VIDEO_CAPS_MAKE("ARGB") ";" \
199 GST_VIDEO_CAPS_MAKE("ABGR") ";" \
200 GST_VIDEO_CAPS_MAKE("RGBA") ";" \
201 GST_VIDEO_CAPS_MAKE("BGRx") ";" \
202 GST_VIDEO_CAPS_MAKE("xBGR") ";" \
203 GST_VIDEO_CAPS_MAKE("xRGB") ";" \
204 GST_VIDEO_CAPS_MAKE("RGBx") ";" \
205 GST_VIDEO_CAPS_MAKE("YUV9") ";" \
206 GST_VIDEO_CAPS_MAKE("YVU9") ";" \
207 GST_VIDEO_CAPS_MAKE("Y41B") ";" \
208 GST_VIDEO_CAPS_MAKE("RGB16") ";" \
209 GST_VIDEO_CAPS_MAKE("RGB15") ";" \
210 GST_VIDEO_CAPS_MAKE("GRAY8") ";" \
211 GST_VIDEO_CAPS_MAKE("RGB8P") ";" \
212 GST_VIDEO_CAPS_MAKE("UYVY") ";" \
213 GST_VIDEO_CAPS_MAKE("IYU1") ";" \
214 GST_VIDEO_CAPS_MAKE("AYUV") \
218 static GstStaticPadTemplate tizen_encode_bin_src_template =
219 GST_STATIC_PAD_TEMPLATE ("src",
222 GST_STATIC_CAPS_ANY);
224 static GstStaticPadTemplate tizen_encode_bin_video_sink_template =
225 GST_STATIC_PAD_TEMPLATE ("video",
231 static GstStaticPadTemplate tizen_encode_bin_audio_sink_template =
232 GST_STATIC_PAD_TEMPLATE ("audio",
238 static GstStaticPadTemplate tizen_encode_bin_image_sink_template =
239 GST_STATIC_PAD_TEMPLATE ("image",
242 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420"))
245 GST_DEBUG_CATEGORY_STATIC (gst_tizen_encode_bin_debug);
246 #define GST_CAT_DEFAULT gst_tizen_encode_bin_debug
248 static void gst_tizen_encode_bin_class_init (GstTizenEncodeBinClass *klass);
249 static void gst_tizen_encode_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
250 static void gst_tizen_encode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
251 static void gst_tizen_encode_bin_init (GstTizenEncodeBin * encodebin);
252 static void gst_tizen_encode_bin_dispose (GObject * object);
253 static void gst_tizen_encode_bin_finalize (GObject * object);
254 static GstPad *gst_tizen_encode_bin_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar* name, const GstCaps *caps);
256 static GstStateChangeReturn gst_tizen_encode_bin_change_state (GstElement * element, GstStateChange transition);
257 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
258 static void gst_tizen_encode_bin_release_pad (GstElement * element, GstPad * pad);
259 static gint pad_compare_name (GstPad * pad1, const gchar * name);
260 static gboolean gst_tizen_encode_bin_add_element_by_name (GstTizenEncodeBin *encodebin, GstTizenEncodeBinElement type, const gchar *name);
261 static gboolean gst_tizen_encode_bin_remove_element (GstTizenEncodeBin *encodebin, GstElement * element);
262 static gboolean gst_tizen_encode_bin_link_elements (GstTizenEncodeBin *encodebin);
263 static gboolean gst_tizen_encode_bin_unlink_elements (GstTizenEncodeBin *encodebin);
264 static gboolean gst_tizen_encode_bin_init_video_elements (GstElement *element, gpointer user_data);
265 static gboolean gst_tizen_encode_bin_init_audio_elements (GstElement *element, gpointer user_data);
266 static gboolean gst_tizen_encode_bin_init_image_elements (GstElement *element, gpointer user_data);
267 static gboolean gst_tizen_encode_bin_block(GstTizenEncodeBin *encodebin, gboolean value);
268 static gboolean gst_tizen_encode_bin_pause(GstTizenEncodeBin *encodebin, gboolean value);
269 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
270 static GstPad* gst_tizen_encode_bin_get_mux_sink_pad(GstElement *mux, GstTizenEncodeBinMuxSinkPad type);
273 static GstPadProbeReturn gst_tizen_encode_bin_video_probe(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin);
274 static GstPadProbeReturn gst_tizen_encode_bin_audio_probe(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin);
275 static GstPadProbeReturn gst_tizen_encode_bin_video_probe_hs(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin);
277 static GstElementClass *parent_class;
279 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
280 static guint gst_tizen_encode_bin_signals[LAST_SIGNAL] = { 0 };
284 GST_TIZEN_ENCODE_BIN_PROFILE_AV,
285 GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO,
286 GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE,
287 } GstTizenEncodeBinProfile;
290 gst_tizen_encode_bin_profile_get_type (void)
292 static GType tizen_encode_bin_profile_type = 0;
293 static const GEnumValue profile_types[] = {
294 {GST_TIZEN_ENCODE_BIN_PROFILE_AV, "Audio and Video Recording", "A/V"},
295 {GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO, "Audio Only Recording", "Audio"},
296 {GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE, "Image Stillshot", "Image"},
300 if (!tizen_encode_bin_profile_type) {
301 tizen_encode_bin_profile_type =
302 g_enum_register_static ("GstTizenEncodeBinProfile", profile_types);
304 return tizen_encode_bin_profile_type;
308 gst_tizen_encode_bin_get_type (void)
310 static GType gst_tizen_encode_bin_type = 0;
312 if (!gst_tizen_encode_bin_type) {
313 static const GTypeInfo gst_tizen_encode_bin_info = {
314 sizeof (GstTizenEncodeBinClass),
317 (GClassInitFunc) gst_tizen_encode_bin_class_init,
320 sizeof (GstTizenEncodeBin),
322 (GInstanceInitFunc) gst_tizen_encode_bin_init,
326 gst_tizen_encode_bin_type =
327 g_type_register_static (GST_TYPE_BIN, "GstTizenEncodeBin",
328 &gst_tizen_encode_bin_info, 0);
331 return gst_tizen_encode_bin_type;
335 queue_overun_cb (GstElement * queue, GstTizenEncodeBin *encodebin)
338 guint queue_size = 0;
339 guint queue_bufnum = 0;
340 // guint64 queue_time= (guint64)0;
342 GstClockTime now = gst_util_get_timestamp ();
344 g_object_get(G_OBJECT(queue), "current-level-bytes", &queue_size,
345 "current-level-buffers", &queue_bufnum,
346 // "current-level-time", &queue_time,
348 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
349 ("[%" GST_TIME_FORMAT "][%s], [%u b], [%u]",
350 GST_TIME_ARGS(now), GST_OBJECT_NAME(queue), queue_size, queue_bufnum), (NULL));
352 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
353 ("%s overrun", GST_OBJECT_NAME(queue)), (NULL));
358 gst_tizen_encode_bin_get_property (GObject * object,
359 guint prop_id, GValue * value, GParamSpec * pspec)
361 GstTizenEncodeBin *encodebin;
363 encodebin = GST_TIZEN_ENCODE_BIN (object);
367 g_value_set_enum (value, encodebin->profile);
369 case PROP_HIGH_SPEED:
370 g_value_set_int (value, encodebin->high_speed_fps);
374 g_value_set_string (value, encodebin->venc_name);
377 g_value_set_string (value, encodebin->aenc_name);
380 g_value_set_string (value, encodebin->ienc_name);
383 g_value_set_string (value, encodebin->mux_name);
385 case PROP_VCONV_NAME:
386 g_value_set_string (value, encodebin->vconv_name);
390 gst_value_set_caps (value, encodebin->vcaps);
393 gst_value_set_caps (value, encodebin->acaps);
396 gst_value_set_caps (value, encodebin->icaps);
399 case PROP_AUTO_AUDIO_CONVERT:
400 g_value_set_boolean (value, encodebin->auto_audio_convert);
402 case PROP_AUTO_AUDIO_RESAMPLE:
403 g_value_set_boolean (value, encodebin->auto_audio_resample);
405 case PROP_AUTO_COLORSPACE:
406 g_value_set_boolean (value, encodebin->auto_color_space);
409 g_value_set_boolean (value, encodebin->block);
412 g_value_set_boolean (value, encodebin->pause);
414 case PROP_VENC_QUEUE:
415 // g_value_set_boolean (value, encodebin->use_venc_queue);
416 if((encodebin->video_encode_queue == NULL) && (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_AV)) {
417 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
418 if(encodebin->video_encode_queue != NULL)
419 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
421 g_value_set_object (value, encodebin->video_encode_queue);
423 case PROP_AENC_QUEUE:
424 // g_value_set_boolean (value, encodebin->use_aenc_queue);
425 if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO)) {
426 encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue");
427 if(encodebin->audio_encode_queue != NULL)
428 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
430 g_value_set_object (value, encodebin->audio_encode_queue);
434 if((encodebin->video_encode == NULL) && (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_AV)) {
435 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
436 if(encodebin->video_encode != NULL)
437 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
439 g_value_set_object (value, encodebin->video_encode);
442 if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO)) {
443 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
444 if(encodebin->audio_encode != NULL)
445 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
447 g_value_set_object (value, encodebin->audio_encode);
450 if(encodebin->image_encode == NULL && (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE)) {
451 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
452 if(encodebin->image_encode != NULL)
453 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
455 g_value_set_object (value, encodebin->image_encode);
458 if(encodebin->mux == NULL && (encodebin->profile <= GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO)) {
459 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
460 if(encodebin->mux != NULL)
461 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
463 g_value_set_object (value, encodebin->mux);
465 case PROP_VIDEO_CONV:
466 if(encodebin->color_space == NULL && (encodebin->profile != GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO)) {
467 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
468 if(encodebin->color_space != NULL)
469 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
471 g_value_set_object (value, encodebin->color_space);
473 case PROP_USE_VIDEO_TOGGLE:
474 g_value_set_boolean( value, encodebin->use_video_toggle );
477 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
483 gst_tizen_encode_bin_set_property (GObject * object,
484 guint prop_id, const GValue * value, GParamSpec * pspec)
486 GstTizenEncodeBin *encodebin;
488 encodebin = GST_TIZEN_ENCODE_BIN (object);
492 encodebin->profile = g_value_get_enum (value);
494 gboolean newprofile = g_value_get_enum (value);
495 if(encodebin->profile != newprofile) {
496 gst_tizen_encode_bin_change_profile(encodebin, newprofile);
497 encodebin->profile = newprofile;
501 case PROP_HIGH_SPEED:
502 encodebin->high_speed_fps = g_value_get_int (value);
504 case PROP_VENC_NAME: {
505 const gchar *new_name;
506 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AV) {
507 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
510 new_name = g_value_get_string (value);
512 if(encodebin->video_encode == NULL) {
513 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_VENC, new_name))
514 encodebin->venc_name = g_strdup (new_name);
516 if(strcmp (encodebin->venc_name, new_name)) {
517 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_encode);
518 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_VENC, new_name))
519 encodebin->venc_name = g_strdup (new_name);
524 case PROP_AENC_NAME: {
525 const gchar *new_name;
526 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
527 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
530 new_name = g_value_get_string (value);
532 if(encodebin->audio_encode == NULL) {
533 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_AENC, new_name))
534 encodebin->aenc_name = g_strdup (new_name);
536 if(strcmp (encodebin->aenc_name, new_name)) {
537 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_encode);
538 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_AENC, new_name))
539 encodebin->aenc_name = g_strdup (new_name);
544 case PROP_IENC_NAME: {
545 const gchar *new_name;
546 if(encodebin->profile < GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE) {
547 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
550 new_name = g_value_get_string (value);
552 if(encodebin->image_encode == NULL) {
553 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_IENC, new_name))
554 encodebin->ienc_name = g_strdup (new_name);
556 if(strcmp (encodebin->ienc_name, new_name)) {
557 gst_tizen_encode_bin_remove_element(encodebin, encodebin->image_encode);
558 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_IENC, new_name))
559 encodebin->ienc_name = g_strdup (new_name);
564 case PROP_MUX_NAME: {
565 const gchar *new_name;
566 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
567 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
570 new_name = g_value_get_string (value);
572 if(encodebin->mux == NULL) {
573 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_MUX, new_name))
574 encodebin->mux_name = g_strdup (new_name);
576 if(strcmp (encodebin->mux_name, new_name)) {
577 gst_tizen_encode_bin_remove_element(encodebin, encodebin->mux);
578 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_MUX, new_name))
579 encodebin->mux_name = g_strdup (new_name);
584 case PROP_VCONV_NAME: {
585 const gchar *new_name;
586 if (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
587 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
590 new_name = g_value_get_string(value);
592 if (encodebin->color_space == NULL) {
593 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
594 encodebin->vconv_name = g_strdup (new_name);
596 if(strcmp (encodebin->vconv_name, new_name)) {
597 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
598 if(gst_tizen_encode_bin_add_element_by_name(encodebin, TIZEN_ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
599 encodebin->vconv_name = g_strdup (new_name);
608 const GstCaps *new_caps_val = gst_value_get_caps (value);
610 if (new_caps_val == NULL) {
611 new_caps = gst_caps_new_any ();
613 new_caps = (GstCaps *) new_caps_val;
614 gst_caps_ref (new_caps);
617 old_caps = encodebin->vcaps;
618 encodebin->vcaps = new_caps;
619 gst_caps_unref (old_caps);
625 const GstCaps *new_caps_val = gst_value_get_caps (value);
627 if (new_caps_val == NULL) {
628 new_caps = gst_caps_new_any ();
630 new_caps = (GstCaps *) new_caps_val;
631 gst_caps_ref (new_caps);
634 old_caps = encodebin->acaps;
635 encodebin->acaps = new_caps;
636 gst_caps_unref (old_caps);
642 const GstCaps *new_caps_val = gst_value_get_caps (value);
644 if (new_caps_val == NULL) {
645 new_caps = gst_caps_new_any ();
647 new_caps = (GstCaps *) new_caps_val;
648 gst_caps_ref (new_caps);
651 old_caps = encodebin->icaps;
652 encodebin->icaps = new_caps;
653 gst_caps_unref (old_caps);
657 case PROP_AUTO_AUDIO_CONVERT:
658 encodebin->auto_audio_convert = g_value_get_boolean (value);
660 case PROP_AUTO_AUDIO_RESAMPLE:
661 encodebin->auto_audio_resample = g_value_get_boolean (value);
663 case PROP_AUTO_COLORSPACE:
664 encodebin->auto_color_space = g_value_get_boolean (value);
667 gboolean newval = g_value_get_boolean (value);
668 if(encodebin->block != newval) {
669 if(!gst_tizen_encode_bin_block(encodebin, newval)) {
670 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
672 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, FALSE);
674 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, FALSE);
680 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
682 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, TRUE);
684 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, TRUE);
690 gboolean newval = g_value_get_boolean (value);
691 if(encodebin->pause != newval) {
692 if(!gst_tizen_encode_bin_pause(encodebin, newval))
695 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
697 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
699 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
704 case PROP_VENC_QUEUE:
705 // encodebin->use_venc_queue = g_value_get_boolean (value);
707 GstElement *newelement = g_value_get_object (value);
708 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AV) {
709 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
712 if(newelement != NULL) {
713 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
714 encodebin->video_encode_queue = newelement;
715 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->video_encode_queue)); // take ownership ??
716 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
721 case PROP_AENC_QUEUE:
722 // encodebin->use_aenc_queue = g_value_get_boolean (value);
724 GstElement *newelement = g_value_get_object (value);
725 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
726 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
729 if(newelement != NULL) {
730 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
731 encodebin->audio_encode_queue = newelement;
732 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->audio_encode_queue));
733 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
740 GstElement *newelement = g_value_get_object (value);
741 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AV) {
742 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
745 if(newelement != NULL) {
746 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_encode);
747 encodebin->video_encode = newelement;
748 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
749 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
755 GstElement *newelement = g_value_get_object (value);
756 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
757 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
760 if(newelement != NULL) {
761 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_encode);
762 encodebin->audio_encode = newelement;
763 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->audio_encode));
764 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
768 case PROP_IMAGE_ENC: {
769 GstElement *newelement = g_value_get_object (value);
770 if(encodebin->profile < GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE) {
771 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
774 if(newelement != NULL) {
775 gst_tizen_encode_bin_remove_element(encodebin, encodebin->image_encode);
776 encodebin->image_encode = newelement;
777 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->image_encode));
778 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
783 GstElement *newelement = g_value_get_object (value);
784 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
785 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
788 if(newelement != NULL) {
789 gst_tizen_encode_bin_remove_element(encodebin, encodebin->mux);
790 encodebin->mux = newelement;
791 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->mux));
792 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
796 case PROP_VIDEO_CONV: {
797 GstElement *newelement = g_value_get_object (value);
798 if(encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
799 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
802 if(newelement != NULL) {
803 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
804 encodebin->color_space = newelement;
805 gst_object_ref_sink (GST_OBJECT_CAST (encodebin->color_space));
806 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
810 case PROP_USE_VIDEO_TOGGLE:
811 encodebin->use_video_toggle = g_value_get_boolean( value );
814 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
820 gst_tizen_encode_bin_request_new_pad (GstElement *element, GstPadTemplate *templ,
821 const gchar* name, const GstCaps *caps)
823 GstTizenEncodeBin *encodebin = NULL;
824 GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
827 g_return_val_if_fail (templ != NULL, NULL);
829 if (templ->direction != GST_PAD_SINK) {
830 GST_WARNING_OBJECT (GST_IS_TIZEN_ENCODE_BIN (element), "encodebin: request pad that is not a SINK pad\n");
834 g_return_val_if_fail (GST_IS_TIZEN_ENCODE_BIN (element), NULL);
836 encodebin = GST_TIZEN_ENCODE_BIN (element);
839 if (templ == gst_element_class_get_pad_template (klass, "audio")) {
840 if (encodebin->profile <= GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO) {
841 gst_tizen_encode_bin_init_audio_elements(element, NULL); //??
843 if(encodebin->audio_sinkpad == NULL)
845 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
846 encodebin->audio_sinkpad = gst_ghost_pad_new ("audio", pad);
847 gst_object_unref(pad);
852 GST_WARNING_OBJECT (GST_IS_TIZEN_ENCODE_BIN (element), "encodebin: audio pad is aleady existed, return existing audio pad\n");
853 return encodebin->audio_sinkpad;
856 gst_element_add_pad (element, encodebin->audio_sinkpad);
857 return encodebin->audio_sinkpad;
860 } else if (templ == gst_element_class_get_pad_template (klass, "video")) {
861 if (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_AV) {
862 gst_tizen_encode_bin_init_video_elements(element, NULL); //??
864 if(encodebin->video_sinkpad == NULL)
866 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
867 encodebin->video_sinkpad = gst_ghost_pad_new ("video", pad);
868 gst_object_unref(pad);
873 GST_WARNING_OBJECT (GST_IS_TIZEN_ENCODE_BIN (element), "encodebin: video pad is aleady existed, return existing video pad\n");
874 return encodebin->video_sinkpad;
877 gst_element_add_pad (element, encodebin->video_sinkpad);
878 return encodebin->video_sinkpad;
879 } else if (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE) {
880 gst_tizen_encode_bin_init_image_elements(element, NULL); //??
882 if(encodebin->image_sinkpad == NULL)
884 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
885 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
886 gst_object_unref(pad);
891 GST_WARNING_OBJECT (GST_IS_TIZEN_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
892 return encodebin->image_sinkpad;
895 gst_element_add_pad (element, encodebin->image_sinkpad);
896 return encodebin->image_sinkpad;
900 if (encodebin->profile == GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE) {
901 gst_tizen_encode_bin_init_image_elements(element, NULL); //??
903 if(encodebin->image_sinkpad == NULL)
905 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
906 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
907 gst_object_unref(pad);
912 GST_WARNING_OBJECT (GST_IS_TIZEN_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
913 return encodebin->image_sinkpad;
916 gst_element_add_pad (element, encodebin->image_sinkpad);
917 return encodebin->image_sinkpad;
924 gst_tizen_encode_bin_class_init (GstTizenEncodeBinClass *klass)
926 GObjectClass *gobject_klass;
927 GstElementClass *gstelement_klass;
929 gobject_klass = (GObjectClass *) klass;
930 gstelement_klass = (GstElementClass *) klass;
932 parent_class = g_type_class_peek_parent (klass);
934 gobject_klass->get_property = gst_tizen_encode_bin_get_property;
935 gobject_klass->set_property = gst_tizen_encode_bin_set_property;
936 gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_tizen_encode_bin_dispose);
937 gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_tizen_encode_bin_finalize);
940 g_object_class_install_property (gobject_klass, PROP_PROFILE,
941 g_param_spec_enum ("profile", "PROFILE", "Profile of the media to record",
942 GST_TYPE_TIZEN_ENCODE_BIN_PROFILE, DEFAULT_PROP_PROFILE,
945 g_object_class_install_property (gobject_klass, PROP_HIGH_SPEED,
946 g_param_spec_int ("high-speed-fps", "high speed rec. fps", "framerate for high speed recording", 0, G_MAXINT,
947 DEFAULT_PROP_HIGH_SPEED, G_PARAM_READWRITE));
949 g_object_class_install_property (gobject_klass, PROP_VENC_NAME,
950 g_param_spec_string ("venc-name", "video encoder name", "the name of video encoder to use",
951 DEFAULT_PROP_VENC_NAME, G_PARAM_READWRITE));
953 g_object_class_install_property (gobject_klass, PROP_AENC_NAME,
954 g_param_spec_string ("aenc-name", "audio encoder name", "the name of audio encoder to use",
955 DEFAULT_PROP_AENC_NAME, G_PARAM_READWRITE));
957 g_object_class_install_property (gobject_klass, PROP_IENC_NAME,
958 g_param_spec_string ("ienc-name", "image encoder name", "the name of image encoder to use",
959 DEFAULT_PROP_IENC_NAME, G_PARAM_READWRITE));
961 g_object_class_install_property (gobject_klass, PROP_MUX_NAME,
962 g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use",
963 DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE));
965 g_object_class_install_property (gobject_klass, PROP_VCONV_NAME,
966 g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use",
967 DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE));
969 g_object_class_install_property (gobject_klass, PROP_VCAPS,
970 g_param_spec_boxed ("vcaps", "caps for video","caps for video recording",
971 GST_TYPE_CAPS, G_PARAM_READWRITE));
973 g_object_class_install_property (gobject_klass, PROP_ACAPS,
974 g_param_spec_boxed ("acaps", "caps for audio","caps for audio recording",
975 GST_TYPE_CAPS, G_PARAM_READWRITE));
977 g_object_class_install_property (gobject_klass, PROP_ICAPS,
978 g_param_spec_boxed ("icaps", "caps for image","caps for image stillshot",
979 GST_TYPE_CAPS, G_PARAM_READWRITE));
981 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_CONVERT,
982 g_param_spec_boolean ("auto-audio-convert", "auto audio convert",
983 "Support for auto audio convert", TRUE, G_PARAM_READWRITE));
985 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_RESAMPLE,
986 g_param_spec_boolean ("auto-audio-resample", "auto audio resample",
987 "Support for auto audio resample", TRUE, G_PARAM_READWRITE));
989 g_object_class_install_property (gobject_klass, PROP_AUTO_COLORSPACE,
990 g_param_spec_boolean ("auto-colorspace", "auto colorspace",
991 "Support for auto colorspace", TRUE, G_PARAM_READWRITE));
993 g_object_class_install_property (gobject_klass, PROP_BLOCK,
994 g_param_spec_boolean ("block", "stream block",
995 "Support for stream block", FALSE, G_PARAM_READWRITE));
997 g_object_class_install_property (gobject_klass, PROP_PAUSE,
998 g_param_spec_boolean ("runtime-pause", "recording pause",
999 "Support for recording pause/resume", FALSE, G_PARAM_READWRITE));
1002 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1003 g_param_spec_boolean ("use-venc-queue", "use queue between venc and mux",
1004 "add queue between venc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1006 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1007 g_param_spec_boolean ("use-aenc-queue", "use queue between aenc and mux",
1008 "add queue between aenc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1010 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1011 g_param_spec_object ("use-venc-queue", "Video Encoder queue",
1012 "add queue between venc and mux(only for custom optimization)",
1013 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1015 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1016 g_param_spec_object ("use-aenc-queue", "Audio Encoder queue",
1017 "add queue between aenc and mux(only for custom optimization)",
1018 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1021 g_object_class_install_property (gobject_klass, PROP_VIDEO_ENC,
1022 g_param_spec_object ("video-encode", "Video Encoder",
1023 "the video encoder element to use",
1024 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1026 g_object_class_install_property (gobject_klass, PROP_AUDIO_ENC,
1027 g_param_spec_object ("audio-encode", "Audio Encoder",
1028 "the audio encoder element to use",
1029 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1031 g_object_class_install_property (gobject_klass, PROP_IMAGE_ENC,
1032 g_param_spec_object ("image-encode", "Image Encoder",
1033 "the Image encoder element to use",
1034 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1036 g_object_class_install_property (gobject_klass, PROP_MUX,
1037 g_param_spec_object ("mux", "Muxer",
1038 "the muxer element to use",
1039 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1041 g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV,
1042 g_param_spec_object ("video-convert", "Video converter",
1043 "the video converter element to use",
1044 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1046 g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE,
1047 g_param_spec_boolean ("use-video-toggle", "Use video toggle",
1048 "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE));
1050 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
1051 gst_tizen_encode_bin_signals[SIGNAL_STREAM_BLOCK] =
1052 g_signal_new ("stream-block", G_TYPE_FROM_CLASS (klass),
1053 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTizenEncodeBinClass, stream_block),
1054 NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1056 gst_tizen_encode_bin_signals[SIGNAL_STREAM_UNBLOCK] =
1057 g_signal_new ("stream-unblock", G_TYPE_FROM_CLASS (klass),
1058 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTizenEncodeBinClass, stream_unblock),
1059 NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1061 gst_tizen_encode_bin_signals[SIGNAL_STREAM_PAUSE] =
1062 g_signal_new ("stream-pause", G_TYPE_FROM_CLASS (klass),
1063 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTizenEncodeBinClass, stream_pause),
1064 NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1066 gst_tizen_encode_bin_signals[SIGNAL_STREAM_RESUME] =
1067 g_signal_new ("stream-resume", G_TYPE_FROM_CLASS (klass),
1068 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTizenEncodeBinClass, stream_resume),
1069 NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1072 gst_element_class_add_pad_template (gstelement_klass,
1073 gst_static_pad_template_get (&tizen_encode_bin_src_template));
1074 gst_element_class_add_pad_template (gstelement_klass,
1075 gst_static_pad_template_get (&tizen_encode_bin_audio_sink_template));
1076 gst_element_class_add_pad_template (gstelement_klass,
1077 gst_static_pad_template_get (&tizen_encode_bin_video_sink_template));
1078 gst_element_class_add_pad_template (gstelement_klass,
1079 gst_static_pad_template_get (&tizen_encode_bin_image_sink_template));
1081 gst_element_class_set_static_metadata(gstelement_klass, "Samsung Electronics Co. Encoder Bin",
1082 "Generic/Bin/Encoder",
1083 "Autoplug and encode to muxed media",
1084 "Jeonghoon Park <jh1979.park@samsung.com>, Wonhyung Cho <wh01.cho@samsung.com>, Sangho Park <sangho.g.park@samsung.com>");
1086 gstelement_klass->request_new_pad =
1087 GST_DEBUG_FUNCPTR (gst_tizen_encode_bin_request_new_pad);
1088 gstelement_klass->release_pad =
1089 GST_DEBUG_FUNCPTR (gst_tizen_encode_bin_release_pad);
1090 gstelement_klass->change_state =
1091 GST_DEBUG_FUNCPTR (gst_tizen_encode_bin_change_state);
1095 gst_tizen_encode_bin_init (GstTizenEncodeBin *encodebin)
1097 if (encodebin->srcpad == NULL) {
1098 encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
1099 gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
1102 encodebin->video_sinkpad = NULL;
1103 encodebin->audio_sinkpad = NULL;
1104 encodebin->image_sinkpad = NULL;
1105 encodebin->mux_audio_sinkpad = NULL;
1106 encodebin->mux_video_sinkpad = NULL;
1108 encodebin->profile = DEFAULT_PROP_PROFILE;
1110 encodebin->high_speed_fps = DEFAULT_PROP_HIGH_SPEED;
1111 encodebin->multiple = 1;
1113 encodebin->auto_audio_convert = TRUE;
1114 encodebin->auto_audio_resample = TRUE;
1115 encodebin->auto_color_space = TRUE;
1116 encodebin->block = FALSE;
1117 encodebin->pause= FALSE;
1118 encodebin->use_video_toggle = TRUE;
1119 encodebin->use_venc_queue= FALSE;
1120 encodebin->use_aenc_queue= FALSE;
1122 encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME);
1123 encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME);
1124 encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);
1125 encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);
1126 encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME);
1128 encodebin->vcaps = gst_caps_new_any ();
1129 encodebin->acaps = gst_caps_new_any ();
1130 encodebin->icaps = gst_caps_new_any ();
1132 encodebin->audio_queue = NULL;
1133 encodebin->video_queue = NULL;
1134 encodebin->video_encode_queue = NULL;
1135 encodebin->image_queue = NULL;
1137 encodebin->audio_encode = NULL;
1138 encodebin->video_encode = NULL;
1139 encodebin->image_encode = NULL;
1141 encodebin->vcapsfilter = NULL;
1142 encodebin->acapsfilter = NULL;
1143 encodebin->icapsfilter = NULL;
1145 encodebin->video_toggle = NULL;
1146 encodebin->image_toggle = NULL;
1147 encodebin->color_space = NULL;
1148 encodebin->audio_conv = NULL;
1149 encodebin->audio_sample = NULL;
1151 encodebin->mux = NULL;
1153 encodebin->paused_time = 0;
1154 encodebin->total_offset_time = 0;
1156 encodebin->vsink_probeid = 0;
1157 encodebin->vsink_hs_probeid = 0;
1158 encodebin->asink_probeid = 0;
1159 encodebin->veque_sig_id = 0;
1160 encodebin->aeque_sig_id = 0;
1164 gst_tizen_encode_bin_dispose (GObject * object)
1166 GstTizenEncodeBin *encodebin = GST_TIZEN_ENCODE_BIN (object);
1168 g_free(encodebin->venc_name);
1169 encodebin->venc_name = NULL;
1171 g_free(encodebin->aenc_name);
1172 encodebin->aenc_name = NULL;
1174 g_free(encodebin->ienc_name);
1175 encodebin->ienc_name = NULL;
1177 g_free(encodebin->mux_name);
1178 encodebin->mux_name = NULL;
1180 g_free(encodebin->vconv_name);
1181 encodebin->vconv_name = NULL;
1183 gst_caps_replace (&encodebin->vcaps, NULL);
1184 gst_caps_replace (&encodebin->acaps, NULL);
1185 gst_caps_replace (&encodebin->icaps, NULL);
1187 if (encodebin->srcpad != NULL) {
1188 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad);
1189 encodebin->srcpad = NULL;
1192 G_OBJECT_CLASS (parent_class)->dispose (object);
1194 encodebin->video_sinkpad = NULL;
1195 encodebin->audio_sinkpad = NULL;
1196 encodebin->image_sinkpad = NULL;
1197 encodebin->mux_audio_sinkpad = NULL;
1198 encodebin->mux_video_sinkpad = NULL;
1200 encodebin->audio_queue = NULL;
1201 encodebin->video_queue = NULL;
1202 encodebin->image_queue = NULL;
1204 encodebin->audio_encode = NULL;
1205 encodebin->video_encode = NULL;
1206 encodebin->video_encode_queue = NULL;
1207 encodebin->image_encode = NULL;
1209 encodebin->vcapsfilter = NULL;
1210 encodebin->acapsfilter = NULL;
1211 encodebin->icapsfilter = NULL;
1213 encodebin->video_toggle = NULL;
1214 encodebin->image_toggle = NULL;
1215 encodebin->color_space = NULL;
1216 encodebin->audio_conv = NULL;
1217 encodebin->audio_sample = NULL;
1218 encodebin->mux = NULL;
1222 gst_tizen_encode_bin_finalize (GObject * object)
1224 G_OBJECT_CLASS (parent_class)->finalize (object);
1227 static GstStateChangeReturn
1228 gst_tizen_encode_bin_change_state (GstElement * element, GstStateChange transition)
1230 GstStateChangeReturn ret;
1231 GstTizenEncodeBin *encode_bin;
1233 encode_bin = GST_TIZEN_ENCODE_BIN (element);
1235 switch (transition) {
1236 case GST_STATE_CHANGE_NULL_TO_READY:
1237 gst_tizen_encode_bin_link_elements(encode_bin);
1239 case GST_STATE_CHANGE_READY_TO_PAUSED:
1240 /* reset time related values */
1241 encode_bin->paused_time = 0;
1242 encode_bin->total_offset_time = 0;
1244 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1246 case GST_STATE_CHANGE_PAUSED_TO_READY:
1252 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1254 switch (transition) {
1255 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1257 case GST_STATE_CHANGE_PAUSED_TO_READY:
1259 case GST_STATE_CHANGE_READY_TO_NULL:
1260 gst_tizen_encode_bin_unlink_elements(encode_bin);
1266 // if (ret == GST_STATE_CHANGE_FAILURE)
1273 gst_tizen_encode_bin_release_pad (GstElement * element, GstPad * pad)
1275 GstTizenEncodeBin *encodebin = GST_TIZEN_ENCODE_BIN (element);
1277 if(!pad_compare_name(pad, "video")) {
1279 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_queue);
1280 encodebin->video_queue = NULL;
1281 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_toggle);
1282 encodebin->video_toggle = NULL;
1283 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
1284 encodebin->color_space = NULL;
1285 gst_tizen_encode_bin_remove_element(encodebin, encodebin->vcapsfilter);
1286 encodebin->vcapsfilter = NULL;
1287 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
1288 encodebin->video_encode_queue = NULL;
1289 gst_tizen_encode_bin_remove_element(encodebin, encodebin->video_encode);
1290 encodebin->video_encode = NULL;
1292 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1293 encodebin->mux_video_sinkpad = NULL;
1295 if(encodebin->mux_audio_sinkpad == NULL) {
1296 gst_tizen_encode_bin_remove_element(encodebin, encodebin->mux);
1297 encodebin->mux = NULL;
1301 encodebin->mux_audio_sinkpad = NULL;
1305 if(encodebin->mux_video_sinkpad != NULL)
1307 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1308 encodebin->mux_video_sinkpad = NULL;
1311 gst_pad_set_active (pad, FALSE); //??
1312 gst_element_remove_pad(element, pad);
1313 encodebin->video_sinkpad = NULL;
1314 } else if(!pad_compare_name(pad, "audio")) {
1316 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_queue);
1317 encodebin->audio_queue = NULL;
1318 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_sample);
1319 encodebin->audio_sample = NULL;
1320 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_conv);
1321 encodebin->audio_conv = NULL;
1322 gst_tizen_encode_bin_remove_element(encodebin, encodebin->acapsfilter);
1323 encodebin->acapsfilter = NULL;
1324 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
1325 encodebin->audio_encode_queue = NULL;
1326 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1327 encodebin->audio_encode = NULL;
1329 encodebin->mux_audio_sinkpad;
1330 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1332 if(encodebin->mux_video_sinkpad == NULL) {
1333 gst_tizen_encode_bin_remove_element(encodebin, encodebin->mux);
1334 encodebin->mux = NULL;
1338 encodebin->mux_video_sinkpad = NULL;
1341 if(encodebin->mux_audio_sinkpad != NULL)
1343 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1344 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
1345 encodebin->mux_audio_sinkpad = NULL;
1348 gst_pad_set_active (pad, FALSE); //??
1349 gst_element_remove_pad(element, pad);
1350 encodebin->audio_sinkpad = NULL;
1353 gst_tizen_encode_bin_remove_element(encodebin, encodebin->image_queue);
1354 encodebin->image_queue = NULL;
1355 gst_tizen_encode_bin_remove_element(encodebin, encodebin->image_toggle);
1356 encodebin->image_toggle = NULL;
1357 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
1358 encodebin->color_space = NULL;
1359 gst_tizen_encode_bin_remove_element(encodebin, encodebin->icapsfilter);
1360 encodebin->icapsfilter = NULL;
1361 gst_tizen_encode_bin_remove_element(encodebin, encodebin->image_encode);
1362 encodebin->image_encode = NULL;
1364 gst_pad_set_active (pad, FALSE); //??
1365 gst_element_remove_pad(element, pad);
1366 encodebin->image_sinkpad = NULL;
1371 pad_compare_name (GstPad * pad1, const gchar * name)
1375 GST_OBJECT_LOCK (pad1);
1376 result = strcmp (GST_PAD_NAME (pad1), name);
1377 GST_OBJECT_UNLOCK (pad1);
1383 gst_tizen_encode_bin_add_element_by_name (GstTizenEncodeBin *encodebin, GstTizenEncodeBinElement type, const gchar *name)
1386 case TIZEN_ENCODEBIN_ELEMENT_VENC:
1387 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1388 if(encodebin->video_encode != NULL) {
1389 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1390 g_free(encodebin->venc_name);
1391 encodebin->venc_name = NULL;
1393 goto element_make_fail;
1396 case TIZEN_ENCODEBIN_ELEMENT_AENC:
1397 encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");
1398 if(encodebin->audio_encode != NULL) {
1399 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1400 g_free(encodebin->aenc_name);
1401 encodebin->aenc_name = NULL;
1403 goto element_make_fail;
1406 case TIZEN_ENCODEBIN_ELEMENT_IENC:
1407 encodebin->image_encode = gst_element_factory_make (name, "image_encode");
1408 if(encodebin->image_encode != NULL) {
1409 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1410 g_free(encodebin->ienc_name);
1411 encodebin->ienc_name = NULL;
1413 goto element_make_fail;
1416 case TIZEN_ENCODEBIN_ELEMENT_MUX:
1417 encodebin->mux = gst_element_factory_make (name, "mux");
1418 if(encodebin->mux != NULL) {
1419 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1420 g_free(encodebin->mux_name);
1421 encodebin->mux_name = NULL;
1423 goto element_make_fail;
1426 case TIZEN_ENCODEBIN_ELEMENT_VIDEO_CONV:
1427 encodebin->color_space = gst_element_factory_make(name, "video_convert");
1428 if (encodebin->color_space != NULL) {
1429 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1430 g_free(encodebin->vconv_name);
1431 encodebin->vconv_name = NULL;
1433 goto element_make_fail;
1437 GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1444 GST_WARNING_OBJECT(encodebin, "no such element factory \"%s\"!", name);
1450 gst_tizen_encode_bin_remove_element (GstTizenEncodeBin *encodebin, GstElement * element)
1453 gchar *ename = NULL;
1454 GST_INFO_OBJECT (encodebin, "gst_tizen_encode_bin_remove_element");
1456 if (element == NULL) {
1457 GST_INFO_OBJECT (encodebin, "element is already NULL");
1461 gst_element_set_state (element, GST_STATE_NULL);
1462 parent = gst_element_get_parent (element);
1464 if (parent != NULL) {
1465 if(!gst_bin_remove (GST_BIN_CAST (parent), element)) {
1466 gst_object_unref (parent);
1467 ename = gst_element_get_name (element);
1468 GST_ERROR_OBJECT (encodebin, "gst_tizen_encode_bin_remove_element() [%s] remove fail", ename);
1472 gst_object_unref(parent);
1475 gst_object_unref(element);
1482 gst_tizen_encode_bin_link_elements (GstTizenEncodeBin *encodebin) // need to return ????
1484 GstPad *srcpad = NULL, *sinkpad = NULL;
1485 switch(encodebin->profile) {
1486 case GST_TIZEN_ENCODE_BIN_PROFILE_AV :
1487 if (!gst_caps_is_any(encodebin->vcaps)) {
1488 gchar *caps_str = NULL;
1489 caps_str = gst_caps_to_string(encodebin->vcaps);
1491 GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str);
1496 g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL);
1499 if (encodebin->auto_color_space) {
1500 if(encodebin->color_space == NULL) {
1501 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
1502 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
1505 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
1506 if( encodebin->video_toggle )
1508 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
1509 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1511 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
1513 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
1514 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1516 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
1517 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
1518 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1520 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
1521 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
1522 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1524 if(encodebin->use_venc_queue)
1526 if(encodebin->video_encode_queue == NULL) {
1527 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
1528 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
1530 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1531 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1532 G_CALLBACK(queue_overun_cb), encodebin);
1536 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1537 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1538 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1541 if(encodebin->video_encode_queue)
1543 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1544 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1545 G_CALLBACK(queue_overun_cb), encodebin);
1547 g_object_set(G_OBJECT(encodebin->video_queue),
1548 "max-size-bytes", (guint)0,
1549 "max-size-buffers", (guint)1,
1550 "max-size-time", (guint64)0,
1553 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1554 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1555 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1561 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
1562 if( encodebin->video_toggle )
1564 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
1565 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1567 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
1569 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
1570 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1572 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
1573 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
1574 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1576 if(encodebin->use_venc_queue)
1578 if(encodebin->video_encode_queue == NULL) {
1579 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
1580 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
1582 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1583 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1584 G_CALLBACK(queue_overun_cb), encodebin);
1587 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1588 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1589 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1593 if(encodebin->video_encode_queue)
1595 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1596 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1597 G_CALLBACK(queue_overun_cb), encodebin);
1599 g_object_set(G_OBJECT(encodebin->video_queue),
1600 "max-size-bytes", (guint)0,
1601 "max-size-buffers", (guint)1,
1602 "max-size-time", (guint64)0,
1606 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1607 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1608 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1614 // gst_element_get_request_pad (encodebin->mux, "video_%d");
1616 if(encodebin->use_venc_queue)
1618 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
1619 sinkpad = encodebin->mux_video_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_VIDEO_SINK);
1620 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1623 if(encodebin->video_encode_queue)
1625 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
1626 sinkpad = encodebin->mux_video_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_VIDEO_SINK);
1627 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1632 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1633 sinkpad = encodebin->mux_video_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_VIDEO_SINK);
1634 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1637 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
1638 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
1639 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
1640 gst_object_unref(srcpad);
1643 /* For pause/resume control */
1644 // encodebin->vsink_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_queue, "sink"),
1645 sinkpad = gst_element_get_static_pad (encodebin->video_queue, "sink");
1646 encodebin->vsink_probeid = gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)gst_tizen_encode_bin_video_probe, encodebin, NULL);
1647 gst_object_unref(sinkpad);
1650 if(encodebin->high_speed_fps > DEFAULT_PROP_HIGH_SPEED)
1652 // encodebin->vsink_hs_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_encode, "sink"),
1653 sinkpad = gst_element_get_static_pad (encodebin->video_encode, "sink");
1654 encodebin->vsink_hs_probeid = gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)gst_tizen_encode_bin_video_probe_hs, encodebin, NULL);
1655 gst_object_unref(sinkpad);
1659 if(encodebin->audio_queue == NULL)
1661 GST_WARNING_OBJECT(encodebin, "Audio pad isn't requested, recording video only mode");
1664 case GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO :
1665 if(!gst_caps_is_any(encodebin->acaps))
1667 g_object_set(encodebin->acapsfilter, "caps", encodebin->acaps, NULL);
1669 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
1670 if (!encodebin->auto_audio_convert) {
1671 if(encodebin->audio_sample == NULL) {
1672 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
1673 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
1675 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
1676 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
1677 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1679 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
1680 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
1681 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1683 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
1684 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
1685 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1687 if(encodebin->use_aenc_queue)
1689 if(encodebin->audio_encode_queue == NULL) {
1690 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
1691 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
1693 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1694 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1695 G_CALLBACK(queue_overun_cb), encodebin);
1698 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1699 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1700 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1703 if(encodebin->audio_encode_queue)
1706 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1707 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1708 G_CALLBACK(queue_overun_cb), encodebin);
1710 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1711 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1712 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1716 } else if (!encodebin->auto_audio_resample) {
1717 if (encodebin->audio_conv == NULL) {
1718 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
1719 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
1722 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
1723 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
1724 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1726 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
1727 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
1728 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1730 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
1731 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
1732 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1734 if(encodebin->use_aenc_queue)
1736 if(encodebin->audio_encode_queue == NULL) {
1737 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
1738 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
1740 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1741 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1742 G_CALLBACK(queue_overun_cb), encodebin);
1745 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1746 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1747 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1751 if(encodebin->audio_encode_queue)
1754 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1755 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1756 G_CALLBACK(queue_overun_cb), encodebin);
1758 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1759 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1760 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1765 if(encodebin->audio_sample == NULL) {
1766 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
1767 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
1769 if (encodebin->audio_conv == NULL) {
1770 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
1771 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
1774 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
1775 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
1776 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1778 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
1779 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
1780 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1782 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
1783 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
1784 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1786 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
1787 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
1788 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1790 if(encodebin->use_aenc_queue)
1792 if(encodebin->audio_encode_queue == NULL) {
1793 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
1794 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
1796 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1797 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1798 G_CALLBACK(queue_overun_cb), encodebin);
1801 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1802 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1803 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1807 if(encodebin->audio_encode_queue)
1810 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1811 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1812 G_CALLBACK(queue_overun_cb), encodebin);
1814 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1815 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1816 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1823 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
1824 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
1825 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1827 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
1828 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
1829 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1831 if(encodebin->use_aenc_queue)
1833 if(encodebin->audio_encode_queue == NULL) {
1834 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
1835 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
1837 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1838 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1839 G_CALLBACK(queue_overun_cb), encodebin);
1842 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1843 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1844 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1847 if(encodebin->audio_encode_queue)
1850 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
1851 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
1852 G_CALLBACK(queue_overun_cb), encodebin);
1854 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1855 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
1856 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1862 if(encodebin->use_aenc_queue)
1864 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
1865 sinkpad = encodebin->mux_audio_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_AUDIO_SINK);
1866 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1871 if(encodebin->audio_encode_queue)
1873 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
1874 sinkpad = encodebin->mux_audio_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_AUDIO_SINK);
1875 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1881 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
1882 sinkpad = encodebin->mux_audio_sinkpad = gst_tizen_encode_bin_get_mux_sink_pad(encodebin->mux, TIZEN_ENCODEBIN_MUX_AUDIO_SINK);
1883 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
1887 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
1888 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
1889 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
1890 gst_object_unref(srcpad);
1893 /* For pause/resume control */
1894 sinkpad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
1895 encodebin->asink_probeid = gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)gst_tizen_encode_bin_audio_probe, encodebin, NULL);
1896 gst_object_unref(sinkpad);
1900 case GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE :
1901 if(!gst_caps_is_any(encodebin->icaps))
1903 g_object_set(encodebin->icapsfilter, "caps", encodebin->icaps, NULL);
1906 if (encodebin->auto_color_space) {
1907 if(encodebin->color_space == NULL) {
1908 encodebin->color_space = gst_element_factory_make ("videoconvert","color_space");
1909 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
1912 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
1913 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
1914 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1916 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
1917 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
1918 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1920 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
1921 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
1922 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1924 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
1925 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
1926 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1931 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
1932 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
1933 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1935 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
1936 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
1937 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1939 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
1940 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
1941 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
1944 srcpad = gst_element_get_static_pad (encodebin->image_encode, "src");
1945 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
1946 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
1947 gst_object_unref(srcpad);
1951 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
1955 // gst_pad_set_active(encodebin->srcpad, TRUE);
1960 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
1961 GST_WARNING_OBJECT(encodebin, "encodebin link video elements fail");
1966 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_conv);
1967 gst_tizen_encode_bin_remove_element(encodebin, encodebin->audio_sample);
1968 GST_WARNING_OBJECT(encodebin, "encodebin link audio elements fail");
1973 gst_tizen_encode_bin_remove_element(encodebin, encodebin->color_space);
1974 GST_WARNING_OBJECT(encodebin, "encodebin link image elements fail");
1981 gst_tizen_encode_bin_unlink_elements (GstTizenEncodeBin *encodebin)
1985 switch(encodebin->profile) {
1986 case GST_TIZEN_ENCODE_BIN_PROFILE_AV :
1987 if (encodebin->auto_color_space) {
1988 if (encodebin->video_toggle) {
1989 gst_element_unlink_many(
1990 encodebin->video_queue,
1991 encodebin->video_toggle,
1992 encodebin->color_space,
1993 encodebin->vcapsfilter,
1994 encodebin->video_encode,
1995 //encodebin->video_encode_queue,
1998 gst_element_unlink_many(
1999 encodebin->video_queue,
2000 encodebin->color_space,
2001 encodebin->vcapsfilter,
2002 encodebin->video_encode,
2003 //encodebin->video_encode_queue,
2007 if (encodebin->video_toggle) {
2008 gst_element_unlink_many(
2009 encodebin->video_queue,
2010 encodebin->video_toggle,
2011 encodebin->vcapsfilter,
2012 encodebin->video_encode,
2013 //encodebin->video_encode_queue,
2016 gst_element_unlink_many(
2017 encodebin->video_queue,
2018 encodebin->vcapsfilter,
2019 encodebin->video_encode,
2020 //encodebin->video_encode_queue,
2025 if(encodebin->mux_video_sinkpad != NULL)
2027 if(encodebin->video_encode_queue)
2029 gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2031 pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2032 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2033 gst_object_unref(pad);
2036 if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2038 g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id );
2043 pad = gst_element_get_static_pad (encodebin->video_encode, "src");
2044 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2045 gst_object_unref(pad);
2049 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
2050 // gst_object_unref(encodebin->mux_video_sinkpad); //***
2051 encodebin->mux_video_sinkpad = NULL;
2054 if(encodebin->vsink_probeid)
2056 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2057 gst_pad_remove_probe(pad, encodebin->vsink_probeid);
2058 encodebin->vsink_probeid = 0;
2059 gst_object_unref(pad);
2064 if(encodebin->vsink_hs_probeid)
2066 pad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2067 gst_pad_remove_probe(pad, encodebin->vsink_hs_probeid);
2068 encodebin->vsink_hs_probeid = 0;
2069 gst_object_unref(pad);
2073 if(encodebin->audio_queue == NULL)
2077 case GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO :
2078 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2079 if (!encodebin->auto_audio_convert) {
2080 gst_element_unlink_many (
2081 encodebin->audio_queue,
2082 encodebin->audio_sample,
2083 encodebin->acapsfilter,
2084 encodebin->audio_encode,
2086 } else if (!encodebin->auto_audio_resample) {
2087 gst_element_unlink_many (
2088 encodebin->audio_queue,
2089 encodebin->audio_conv,
2090 encodebin->acapsfilter,
2091 encodebin->audio_encode,
2094 gst_element_unlink_many (
2095 encodebin->audio_queue,
2096 encodebin->audio_conv,
2097 encodebin->audio_sample,
2098 encodebin->acapsfilter,
2099 encodebin->audio_encode,
2104 gst_element_unlink_many (
2105 encodebin->audio_queue,
2106 encodebin->acapsfilter,
2107 encodebin->audio_encode,
2111 if(encodebin->mux_audio_sinkpad != NULL)
2114 if(encodebin->use_aenc_queue)
2116 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2118 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2119 gst_pad_unlink(pad, muxpad);
2120 gst_object_unref(pad);
2123 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2125 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2129 if(encodebin->audio_encode_queue)
2131 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2133 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2134 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2135 gst_object_unref(pad);
2138 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2140 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2146 pad = gst_element_get_static_pad (encodebin->audio_encode, "src");
2147 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2148 gst_object_unref(pad);
2152 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
2153 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
2154 encodebin->mux_audio_sinkpad = NULL;
2157 if(encodebin->asink_probeid)
2159 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2160 gst_pad_remove_probe(pad, encodebin->asink_probeid);
2161 encodebin->asink_probeid =0;
2162 gst_object_unref(pad);
2167 case GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE :
2168 if (encodebin->auto_color_space) {
2169 gst_element_unlink_many (
2170 encodebin->image_queue,
2171 encodebin->image_toggle,
2172 encodebin->color_space,
2173 encodebin->icapsfilter,
2174 encodebin->image_encode,
2178 gst_element_unlink_many (
2179 encodebin->image_queue,
2180 encodebin->image_toggle,
2181 encodebin->icapsfilter,
2182 encodebin->image_encode,
2187 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2191 // gst_pad_set_active(encodebin->srcpad, TRUE);
2197 gst_tizen_encode_bin_init_video_elements (GstElement *element, gpointer user_data)
2199 GstTizenEncodeBin *encodebin = GST_TIZEN_ENCODE_BIN (element);
2201 if(encodebin->profile != GST_TIZEN_ENCODE_BIN_PROFILE_AV)
2204 if(encodebin->video_queue == NULL) {
2205 encodebin->video_queue = gst_element_factory_make ("queue","video_queue");
2206 gst_bin_add (GST_BIN (element), encodebin->video_queue);
2209 if( encodebin->use_video_toggle )
2211 if( encodebin->video_toggle == NULL )
2213 encodebin->video_toggle = gst_element_factory_make ("toggle","video_toggle");
2214 gst_bin_add (GST_BIN (element), encodebin->video_toggle);
2216 GST_INFO_OBJECT( encodebin, "Video toggle is Enabled" );
2220 GST_INFO_OBJECT( encodebin, "Video toggle is Disabled" );
2223 if(encodebin->vcapsfilter == NULL) {
2224 encodebin->vcapsfilter = gst_element_factory_make ("capsfilter","vcapsfilter");
2225 gst_bin_add (GST_BIN (element), encodebin->vcapsfilter);
2228 encodebin->vcaps = gst_caps_new_simple("video/x-raw",
2229 "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
2230 "width", G_TYPE_INT, 320,
2231 "height", G_TYPE_INT, 240,
2232 "framerate", GST_TYPE_FRACTION, 30, 1,
2236 if(encodebin->video_encode == NULL) {
2237 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
2238 gst_bin_add (GST_BIN (element), encodebin->video_encode);
2242 if(encodebin->video_encode_queue == NULL) {
2243 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
2244 gst_bin_add (GST_BIN (element), encodebin->video_encode_queue);
2247 g_object_set(G_OBJECT(encodebin->video_encode_queue), "max-size-bytes", (unsigned int)0, NULL);
2250 if(encodebin->mux == NULL) {
2251 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2252 gst_bin_add (GST_BIN (element), encodebin->mux);
2255 if (!encodebin->video_encode
2256 // || !encodebin->video_encode_queue
2258 || !encodebin->video_queue
2259 || !encodebin->vcapsfilter
2260 || !encodebin->srcpad )
2262 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2266 if( encodebin->use_video_toggle && !encodebin->video_toggle )
2268 GST_ERROR_OBJECT(encodebin, "Faild create video toggle element \n");
2273 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2274 encodebin->color_space = gst_element_factory_make ("videoconvert","color_space");
2275 gst_bin_add (GST_BIN (element), encodebin->color_space);
2282 gst_tizen_encode_bin_init_audio_elements (GstElement *element, gpointer user_data)
2284 GstTizenEncodeBin *encodebin = GST_TIZEN_ENCODE_BIN (element);
2286 if(encodebin->profile > GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO)
2289 if(encodebin->audio_queue == NULL) {
2290 encodebin->audio_queue = gst_element_factory_make ("queue","audio_queue");
2291 gst_bin_add (GST_BIN (element), encodebin->audio_queue);
2294 if(encodebin->acapsfilter == NULL) {
2295 encodebin->acapsfilter = gst_element_factory_make ("capsfilter","acapsfilter");
2296 gst_bin_add (GST_BIN (element), encodebin->acapsfilter);
2299 encodebin->acaps = gst_caps_new_simple("audio/x-raw",
2300 "rate", G_TYPE_INT, 8000,
2301 "channels", G_TYPE_INT, 2,
2302 "depth", G_TYPE_INT, 16,
2306 if(encodebin->audio_encode == NULL) {
2307 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
2308 gst_bin_add (GST_BIN (element), encodebin->audio_encode);
2311 if(encodebin->mux == NULL) {
2312 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2313 gst_bin_add (GST_BIN (element), encodebin->mux);
2316 if (!encodebin->audio_encode
2317 || !encodebin->audio_queue
2319 || !encodebin->acapsfilter
2320 || !encodebin->srcpad )
2322 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2326 if (encodebin->auto_audio_convert && (encodebin->audio_conv == NULL)) {
2327 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2328 gst_bin_add (GST_BIN (element), encodebin->audio_conv);
2331 if (encodebin->auto_audio_resample && (encodebin->audio_sample == NULL)) {
2332 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2333 gst_bin_add (GST_BIN (element), encodebin->audio_sample);
2341 gst_tizen_encode_bin_init_image_elements (GstElement *element, gpointer user_data)
2343 GstTizenEncodeBin *encodebin = GST_TIZEN_ENCODE_BIN (element);
2345 if(encodebin->profile < GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE)
2348 if(encodebin->image_queue == NULL) {
2349 encodebin->image_queue = gst_element_factory_make ("queue","image_queue");
2350 gst_bin_add (GST_BIN (element), encodebin->image_queue);
2353 if(encodebin->image_toggle == NULL) {
2354 encodebin->image_toggle = gst_element_factory_make ("toggle","image_toggle");
2355 gst_bin_add (GST_BIN (element), encodebin->image_toggle);
2358 if(encodebin->icapsfilter == NULL) {
2359 encodebin->icapsfilter = gst_element_factory_make ("capsfilter","icapsfilter");
2360 gst_bin_add (GST_BIN (element), encodebin->icapsfilter);
2363 if(encodebin->image_encode == NULL) {
2364 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
2365 gst_bin_add (GST_BIN (element), encodebin->image_encode);
2368 if (!encodebin->image_encode
2369 || !encodebin->image_queue
2370 || !encodebin->image_toggle
2371 || !encodebin->icapsfilter
2372 || !encodebin->srcpad )
2374 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2378 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2379 encodebin->color_space = gst_element_factory_make ("videoconvert","color_space");
2380 gst_bin_add (GST_BIN (element), encodebin->color_space);
2386 static gboolean gst_tizen_encode_bin_block(GstTizenEncodeBin *encodebin, gboolean value)
2389 if(value) { //block stream
2390 switch(encodebin->profile) {
2391 case GST_TIZEN_ENCODE_BIN_PROFILE_AV:
2392 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2395 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2396 "empty-buffers") == NULL) {
2397 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2400 if( encodebin->video_toggle )
2402 g_object_set(encodebin->video_toggle, "block-data", TRUE , NULL);
2403 GST_INFO_OBJECT( encodebin, "video_toggle block-data TRUE" );
2406 g_object_set(encodebin->video_queue, "empty-buffers", TRUE , NULL);
2407 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers TRUE" );
2408 if(encodebin->audio_queue != NULL)
2410 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2411 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2415 case GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO:
2416 if(encodebin->audio_queue == NULL) {
2419 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2420 "empty-buffers") == NULL) {
2421 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2424 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2425 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2428 case GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE:
2429 if(encodebin->image_toggle == NULL) {
2432 g_object_set(encodebin->image_toggle, "block_data", TRUE, NULL);
2433 GST_INFO_OBJECT( encodebin, "image_toggle block_data TRUE" );
2437 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2441 } else { //release blocked-stream
2442 switch(encodebin->profile) {
2443 case GST_TIZEN_ENCODE_BIN_PROFILE_AV:
2444 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2447 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2448 "empty-buffers") == NULL) {
2449 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2452 if( encodebin->video_toggle )
2454 g_object_set(encodebin->video_toggle, "block-data", FALSE , NULL);
2455 GST_INFO_OBJECT( encodebin, "video_toggle block-data FALSE" );
2458 if(encodebin->audio_queue != NULL)
2460 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2461 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2463 g_object_set(encodebin->video_queue, "empty-buffers", FALSE , NULL);
2464 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers FALSE" );
2467 case GST_TIZEN_ENCODE_BIN_PROFILE_AUDIO:
2468 if(encodebin->audio_queue == NULL) {
2471 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2472 "empty-buffers") == NULL) {
2473 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2476 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2477 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2480 case GST_TIZEN_ENCODE_BIN_PROFILE_IMAGE:
2481 if(encodebin->image_toggle == NULL) {
2484 g_object_set(encodebin->image_toggle, "block_data", FALSE, NULL);
2485 GST_INFO_OBJECT( encodebin, "image_toggle block_data FALSE" );
2489 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2494 encodebin->block = value;
2498 GST_ERROR_OBJECT(encodebin, "encodebin block failed");
2502 GST_ERROR_OBJECT(encodebin, "encodebin unblock failed");
2506 static gboolean gst_tizen_encode_bin_pause(GstTizenEncodeBin *encodebin, gboolean value)
2508 GstClock *clock = NULL;
2512 //Block src of encode bin
2513 if (!gst_tizen_encode_bin_block(encodebin, TRUE))
2515 GST_WARNING_OBJECT (encodebin, "Fail to block Encodebin.");
2519 if (encodebin->paused_time == 0)
2522 clock = GST_ELEMENT_CLOCK(encodebin);
2523 if (clock) //before PLAYING, this would be NULL. Need to check.
2525 GstClockTime current_time, base_time;
2527 current_time = gst_clock_get_time(clock);
2528 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
2530 encodebin->paused_time = current_time - base_time;
2532 GST_INFO_OBJECT (encodebin, "Encodebin is in running-pause at [%"GST_TIME_FORMAT"]."
2533 , GST_TIME_ARGS(encodebin->paused_time));
2537 encodebin->paused_time = 0;
2538 encodebin->total_offset_time = 0;
2540 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
2543 #if 0 //def TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
2544 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
2548 /* release paused-stream*/
2549 if (encodebin->paused_time != 0)
2551 clock = GST_ELEMENT_CLOCK(encodebin);
2554 GstClockTime current_time, base_time;
2555 GstClockTime paused_gap;
2557 current_time = gst_clock_get_time(clock);
2558 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
2559 paused_gap = current_time - base_time - encodebin->paused_time;
2561 encodebin->total_offset_time += paused_gap;
2562 encodebin->paused_time = 0;
2564 GST_INFO_OBJECT (encodebin, "Encodebin now resumes. Offset delay [%"GST_TIME_FORMAT"], Total offset delay [%"GST_TIME_FORMAT"]"
2565 , GST_TIME_ARGS(paused_gap) , GST_TIME_ARGS(encodebin->total_offset_time));
2569 encodebin->paused_time = 0;
2570 encodebin->total_offset_time = 0;
2572 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
2576 //TODO : How about qos?
2578 //Unblock src of encode bin
2579 if (!gst_tizen_encode_bin_block(encodebin, FALSE))
2581 GST_WARNING_OBJECT (encodebin, "Fail to Unblock Encodebin.");
2584 #if 0 //def TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
2585 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
2588 encodebin->pause = value;
2592 GST_WARNING_OBJECT (encodebin, "Fail to pause Encodebin");
2593 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
2594 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, FALSE);
2599 GST_WARNING_OBJECT (encodebin, "Fail to resume Encodebin");
2600 #ifdef TIZEN_FEATURE_TIZEN_ENCODE_BIN_SIGNAL_ENABLE
2601 g_signal_emit (G_OBJECT (encodebin), gst_tizen_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, FALSE);
2606 static GstPadProbeReturn
2607 gst_tizen_encode_bin_video_probe(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin)
2611 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
2612 return GST_PAD_PROBE_OK;
2615 //Adjusting timestamp of video source
2616 GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info)) -= encodebin->total_offset_time;
2617 GST_BUFFER_DTS(gst_pad_probe_info_get_buffer(info)) = GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info));
2619 return GST_PAD_PROBE_OK;
2622 static GstPadProbeReturn
2623 gst_tizen_encode_bin_video_probe_hs(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin)
2627 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
2628 return GST_PAD_PROBE_OK;
2631 GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info)) *= encodebin->multiple;
2632 GST_BUFFER_DTS(gst_pad_probe_info_get_buffer(info)) = GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info));
2634 return GST_PAD_PROBE_OK;
2637 static GstPadProbeReturn
2638 gst_tizen_encode_bin_audio_probe(GstPad *pad, GstPadProbeInfo *info, GstTizenEncodeBin *encodebin)
2642 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
2643 return GST_PAD_PROBE_OK;
2646 //Adjusting timestamp of video source
2647 GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info)) -= encodebin->total_offset_time;
2648 GST_BUFFER_DTS(gst_pad_probe_info_get_buffer(info)) = GST_BUFFER_PTS(gst_pad_probe_info_get_buffer(info));
2650 return GST_PAD_PROBE_OK;
2654 gst_tizen_encode_bin_get_mux_sink_pad(GstElement *mux, GstTizenEncodeBinMuxSinkPad type)
2656 GstElementClass *elemclass = NULL;
2660 elemclass = GST_ELEMENT_GET_CLASS (mux);
2662 walk = gst_element_class_get_pad_template_list (elemclass);
2665 GstPadTemplate *templ;
2667 templ = (GstPadTemplate *) walk->data;
2668 if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SINK) {
2669 /* ENHANCE ME: Please add other specific mux's case */
2670 if (((type == TIZEN_ENCODEBIN_MUX_AUDIO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "audio")) || //audio, audio_%d,... ex)ffmux_3gp
2671 ((type == TIZEN_ENCODEBIN_MUX_VIDEO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "video")) || //video, video_%d,... ex)ffmux_3gp
2672 strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "sink") //sink, sink_%d, wavparse_sink, ... ex)oggmux, wavparse
2674 g_print("PRINT TEMPLATE(%s)\n", GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
2675 pad = gst_element_get_request_pad (mux, GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
2679 walk = g_list_next (walk);
2686 plugin_init (GstPlugin * plugin)
2688 GST_DEBUG_CATEGORY_INIT (gst_tizen_encode_bin_debug, "tizenencodebin", 0, "Tizen encodebin");
2691 GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
2693 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
2694 #endif /* ENABLE_NLS */
2696 return gst_element_register (plugin, "tizenencodebin", GST_RANK_NONE,
2697 GST_TYPE_TIZEN_ENCODE_BIN);
2700 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
2703 "Tizen encodebin plugin",
2704 plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/")