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 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 "ffenc_h263"
84 #define DEFAULT_PROP_AENC_NAME "secenc_amr"
85 #define DEFAULT_PROP_IENC_NAME "jpegenc"
86 #define DEFAULT_PROP_MUX_NAME "ffmux_3gp"
87 #define DEFAULT_PROP_VCONV_NAME "ffmpegcolorspace"
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 GST_ENCODE_BIN_SIGNAL_ENABLE
130 SIGNAL_STREAM_UNBLOCK,
132 SIGNAL_STREAM_RESUME,
138 ENCODEBIN_ELEMENT_VENC,
139 ENCODEBIN_ELEMENT_AENC,
140 ENCODEBIN_ELEMENT_IENC,
141 ENCODEBIN_ELEMENT_MUX,
142 ENCODEBIN_ELEMENT_VIDEO_CONV
143 }GstEncodeBinElement;
146 ENCODEBIN_MUX_AUDIO_SINK,
147 ENCODEBIN_MUX_VIDEO_SINK,
148 }GstEncodeBinMuxSinkPad;
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 \
162 "audio/x-raw-float, " \
163 "rate = (int) [ 1, MAX ], " \
164 "channels = (int) [ 1, 8 ], " \
165 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
166 "width = (int) 64;" \
167 "audio/x-raw-float, " \
168 "rate = (int) [ 1, MAX ], " \
169 "channels = (int) [ 1, 8 ], " \
170 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
171 "width = (int) 32;" \
172 "audio/x-raw-int, " \
173 "rate = (int) [ 1, MAX ], " \
174 "channels = (int) [ 1, 8 ], " \
175 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
176 "width = (int) 32, " \
177 "depth = (int) [ 1, 32 ], " \
178 "signed = (boolean) { true, false }; " \
179 "audio/x-raw-int, " \
180 "rate = (int) [ 1, MAX ], " \
181 "channels = (int) [ 1, 8 ], " \
182 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
183 "width = (int) 24, " \
184 "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; " \
185 "audio/x-raw-int, " \
186 "rate = (int) [ 1, MAX ], " \
187 "channels = (int) [ 1, 8 ], " \
188 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
189 "width = (int) 16, " \
190 "depth = (int) [ 1, 16 ], " \
191 "signed = (boolean) { true, false }; " \
192 "audio/x-raw-int, " \
193 "rate = (int) [ 1, MAX ], " \
194 "channels = (int) [ 1, 8 ], " \
195 "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
196 "width = (int) 8, " \
197 "depth = (int) [ 1, 8 ], " \
198 "signed = (boolean) { true, false } " \
201 #define STATIC_VIDEO_CAPS \
204 "width = (int) [ 1, 2147483647 ]," \
205 "height = (int) [ 1, 2147483647 ]," \
206 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
207 "format = (fourcc) I420;" \
209 "width = (int) [ 1, 2147483647 ]," \
210 "height = (int) [ 1, 2147483647 ]," \
211 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
212 "format = (fourcc) YV12;" \
214 "width = (int) [ 1, 2147483647 ]," \
215 "height = (int) [ 1, 2147483647 ]," \
216 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
217 "format = (fourcc) YUY2;" \
219 "width = (int) [ 1, 2147483647 ]," \
220 "height = (int) [ 1, 2147483647 ]," \
221 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
223 "depth = (int) 24," \
224 "red_mask = (int) 16711680," \
225 "green_mask = (int) 65280," \
226 "blue_mask = (int) 255," \
227 "endianness = (int) 4321;" \
229 "width = (int) [ 1, 2147483647 ]," \
230 "height = (int) [ 1, 2147483647 ]," \
231 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
233 "depth = (int) 24," \
234 "red_mask = (int) 255," \
235 "green_mask = (int) 65280," \
236 "blue_mask = (int) 16711680," \
237 "endianness = (int) 4321;" \
239 "width = (int) [ 1, 2147483647 ]," \
240 "height = (int) [ 1, 2147483647 ]," \
241 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
242 "format = (fourcc) Y42B;" \
244 "width = (int) [ 1, 2147483647 ]," \
245 "height = (int) [ 1, 2147483647 ]," \
246 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
247 "format = (fourcc) Y444;" \
249 "width = (int) [ 1, 2147483647 ]," \
250 "height = (int) [ 1, 2147483647 ]," \
251 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
253 "depth = (int) 32," \
254 "red_mask = (int) 65280," \
255 "green_mask = (int) 16711680," \
256 "blue_mask = (int) -16777216," \
257 "alpha_mask = (int) 255," \
258 "endianness = (int) 4321;" \
260 "width = (int) [ 1, 2147483647 ]," \
261 "height = (int) [ 1, 2147483647 ]," \
262 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
264 "depth = (int) 32," \
265 "red_mask = (int) 16711680," \
266 "green_mask = (int) 65280," \
267 "blue_mask = (int) 255," \
268 "alpha_mask = (int) -16777216," \
269 "endianness = (int) 4321;" \
271 "width = (int) [ 1, 2147483647 ]," \
272 "height = (int) [ 1, 2147483647 ]," \
273 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
275 "depth = (int) 32," \
276 "red_mask = (int) 255," \
277 "green_mask = (int) 65280," \
278 "blue_mask = (int) 16711680," \
279 "alpha_mask = (int) -16777216," \
280 "endianness = (int) 4321;" \
282 "width = (int) [ 1, 2147483647 ]," \
283 "height = (int) [ 1, 2147483647 ]," \
284 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
286 "depth = (int) 32," \
287 "red_mask = (int) -16777216," \
288 "green_mask = (int) 16711680," \
289 "blue_mask = (int) 65280," \
290 "alpha_mask = (int) 255," \
291 "endianness = (int) 4321;" \
293 "width = (int) [ 1, 2147483647 ]," \
294 "height = (int) [ 1, 2147483647 ]," \
295 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
297 "depth = (int) 24," \
298 "red_mask = (int) 65280," \
299 "green_mask = (int) 16711680," \
300 "blue_mask = (int) -16777216," \
301 "endianness = (int) 4321;" \
303 "width = (int) [ 1, 2147483647 ]," \
304 "height = (int) [ 1, 2147483647 ]," \
305 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
307 "depth = (int) 24," \
308 "red_mask = (int) 255," \
309 "green_mask = (int) 65280," \
310 "blue_mask = (int) 16711680," \
311 "endianness = (int) 4321;" \
313 "width = (int) [ 1, 2147483647 ]," \
314 "height = (int) [ 1, 2147483647 ]," \
315 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
317 "depth = (int) 24," \
318 "red_mask = (int) 16711680," \
319 "green_mask = (int) 65280," \
320 "blue_mask = (int) 255," \
321 "endianness = (int) 4321;" \
323 "width = (int) [ 1, 2147483647 ]," \
324 "height = (int) [ 1, 2147483647 ]," \
325 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
327 "depth = (int) 24," \
328 "red_mask = (int) -16777216," \
329 "green_mask = (int) 16711680," \
330 "blue_mask = (int) 65280," \
331 "endianness = (int) 4321;" \
333 "width = (int) [ 1, 2147483647 ]," \
334 "height = (int) [ 1, 2147483647 ]," \
335 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
336 "format = (fourcc) YUV9;" \
338 "width = (int) [ 1, 2147483647 ]," \
339 "height = (int) [ 1, 2147483647 ]," \
340 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
341 "format = (fourcc) YVU9;" \
343 "width = (int) [ 1, 2147483647 ]," \
344 "height = (int) [ 1, 2147483647 ]," \
345 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
346 "format = (fourcc) Y41B;" \
348 "width = (int) [ 1, 2147483647 ]," \
349 "height = (int) [ 1, 2147483647 ]," \
350 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
352 "depth = (int) 16," \
353 "red_mask = (int) 63488," \
354 "green_mask = (int) 2016," \
355 "blue_mask = (int) 31," \
356 "endianness = (int) 1234;" \
358 "width = (int) [ 1, 2147483647 ]," \
359 "height = (int) [ 1, 2147483647 ]," \
360 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
362 "depth = (int) 15," \
363 "red_mask = (int) 31744," \
364 "green_mask = (int) 992," \
365 "blue_mask = (int) 31," \
366 "endianness = (int) 1234;" \
367 "video/x-raw-gray," \
368 "width = (int) [ 1, 2147483647 ]," \
369 "height = (int) [ 1, 2147483647 ]," \
370 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
374 "width = (int) [ 1, 2147483647 ]," \
375 "height = (int) [ 1, 2147483647 ]," \
376 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
379 "endianness = (int) 1234;" \
381 "width = (int) [ 1, 2147483647 ]," \
382 "height = (int) [ 1, 2147483647 ]," \
383 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
384 "format = (fourcc) UYVY;" \
386 "width = (int) [ 1, 2147483647 ]," \
387 "height = (int) [ 1, 2147483647 ]," \
388 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
389 "format = (fourcc) IYU1;" \
391 "width = (int) [ 1, 2147483647 ]," \
392 "height = (int) [ 1, 2147483647 ]," \
393 "framerate = (fraction) [ 0/1, 2147483647/1 ]," \
394 "format = (fourcc) AYUV " \
398 static GstStaticPadTemplate encoder_bin_src_template =
399 GST_STATIC_PAD_TEMPLATE ("src",
402 GST_STATIC_CAPS_ANY);
404 static GstStaticPadTemplate encoder_bin_video_sink_template =
405 GST_STATIC_PAD_TEMPLATE ("video",
411 static GstStaticPadTemplate encoder_bin_audio_sink_template =
412 GST_STATIC_PAD_TEMPLATE ("audio",
418 static GstStaticPadTemplate encoder_bin_image_sink_template =
419 GST_STATIC_PAD_TEMPLATE ("image",
422 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
425 GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug);
426 #define GST_CAT_DEFAULT gst_encode_bin_debug
428 static void gst_encode_bin_class_init (GstEncodeBinClass *klass);
429 static void gst_encode_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
430 static void gst_encode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
431 static void gst_encode_bin_init (GstEncodeBin * encodebin);
432 static void gst_encode_bin_dispose (GObject * object);
433 static void gst_encode_bin_finalize (GObject * object);
434 static GstPad *gst_encode_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name);
436 static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, GstStateChange transition);
437 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
438 static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad);
439 static gint pad_compare_name (GstPad * pad1, const gchar * name);
440 static gboolean gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
441 #if 0 //disable unused function
442 static gboolean gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean profile);
443 static void gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement);
444 static gboolean gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name);
445 static gboolean gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element);
446 #endif //disable unused function
447 static gboolean gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element);
448 static gboolean gst_encode_bin_link_elements (GstEncodeBin *encodebin);
449 static gboolean gst_encode_bin_unlink_elements (GstEncodeBin *encodebin);
450 static gboolean gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data);
451 static gboolean gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data);
452 static gboolean gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data);
453 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value);
454 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value);
455 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
456 static gboolean gst_encode_bin_release_pipeline (GstElement *element, gpointer user_data);
457 static gboolean gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps);
458 static gboolean gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps);
459 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps);
460 static GstPad* gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type);
463 static gboolean gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
464 static gboolean gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
465 static gboolean gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin);
467 static GstElementClass *parent_class;
469 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
470 static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 };
473 static const GstElementDetails gst_encode_bin_details =
474 GST_ELEMENT_DETAILS ("Samsung Electronics Co. Encoder Bin",
475 "Generic/Bin/Encoder",
476 "Autoplug and encode to muxed media",
477 "Jeonghoon Park <jh1979.park@samsung.com>, Wonhyung Cho <wh01.cho@samsung.com>, Sangho Park <sangho.g.park@samsung.com>");
480 GST_ENCODE_BIN_PROFILE_AV,
481 GST_ENCODE_BIN_PROFILE_AUDIO,
482 GST_ENCODE_BIN_PROFILE_IMAGE,
483 } GstEncodeBinProfile;
486 gst_encode_bin_profile_get_type (void)
488 static GType encode_bin_profile_type = 0;
489 static const GEnumValue profile_types[] = {
490 {GST_ENCODE_BIN_PROFILE_AV, "Audio and Video Recording", "A/V"},
491 {GST_ENCODE_BIN_PROFILE_AUDIO, "Audio Only Recording", "Audio"},
492 {GST_ENCODE_BIN_PROFILE_IMAGE, "Image Stillshot", "Image"},
496 if (!encode_bin_profile_type) {
497 encode_bin_profile_type =
498 g_enum_register_static ("GstEncodeBinProfile",profile_types);
500 return encode_bin_profile_type;
504 gst_encode_bin_get_type (void)
506 static GType gst_encode_bin_type = 0;
508 if (!gst_encode_bin_type) {
509 static const GTypeInfo gst_encode_bin_info = {
510 sizeof (GstEncodeBinClass),
513 (GClassInitFunc) gst_encode_bin_class_init,
516 sizeof (GstEncodeBin),
518 (GInstanceInitFunc) gst_encode_bin_init,
522 gst_encode_bin_type =
523 g_type_register_static (GST_TYPE_BIN, "GstEncodeBin",
524 &gst_encode_bin_info, 0);
527 return gst_encode_bin_type;
531 queue_overun_cb (GstElement * queue, GstEncodeBin *encodebin)
534 guint queue_size = 0;
535 guint queue_bufnum = 0;
536 // guint64 queue_time= (guint64)0;
538 GstClockTime now = gst_util_get_timestamp ();
540 g_object_get(G_OBJECT(queue), "current-level-bytes", &queue_size,
541 "current-level-buffers", &queue_bufnum,
542 // "current-level-time", &queue_time,
544 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
545 ("[%" GST_TIME_FORMAT "][%s], [%u b], [%u]",
546 GST_TIME_ARGS(now), GST_OBJECT_NAME(queue), queue_size, queue_bufnum), (NULL));
548 GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY,
549 ("%s overrun", GST_OBJECT_NAME(queue)), (NULL));
554 gst_encode_bin_get_property (GObject * object,
555 guint prop_id, GValue * value, GParamSpec * pspec)
557 GstEncodeBin *encodebin;
559 encodebin = GST_ENCODE_BIN (object);
563 g_value_set_enum (value, encodebin->profile);
565 case PROP_HIGH_SPEED:
566 g_value_set_int (value, encodebin->high_speed_fps);
570 g_value_set_string (value, encodebin->venc_name);
573 g_value_set_string (value, encodebin->aenc_name);
576 g_value_set_string (value, encodebin->ienc_name);
579 g_value_set_string (value, encodebin->mux_name);
581 case PROP_VCONV_NAME:
582 g_value_set_string (value, encodebin->vconv_name);
586 gst_value_set_caps (value, encodebin->vcaps);
589 gst_value_set_caps (value, encodebin->acaps);
592 gst_value_set_caps (value, encodebin->icaps);
595 case PROP_AUTO_AUDIO_CONVERT:
596 g_value_set_boolean (value, encodebin->auto_audio_convert);
598 case PROP_AUTO_AUDIO_RESAMPLE:
599 g_value_set_boolean (value, encodebin->auto_audio_resample);
601 case PROP_AUTO_COLORSPACE:
602 g_value_set_boolean (value, encodebin->auto_color_space);
605 g_value_set_boolean (value, encodebin->block);
608 g_value_set_boolean (value, encodebin->pause);
610 case PROP_VENC_QUEUE:
611 // g_value_set_boolean (value, encodebin->use_venc_queue);
612 if((encodebin->video_encode_queue == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
613 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
614 if(encodebin->video_encode_queue != NULL)
615 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
617 g_value_set_object (value, encodebin->video_encode_queue);
619 case PROP_AENC_QUEUE:
620 // g_value_set_boolean (value, encodebin->use_aenc_queue);
621 if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
622 encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue");
623 if(encodebin->audio_encode_queue != NULL)
624 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
626 g_value_set_object (value, encodebin->audio_encode_queue);
630 if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) {
631 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
632 if(encodebin->video_encode != NULL)
633 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
635 g_value_set_object (value, encodebin->video_encode);
638 if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
639 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
640 if(encodebin->audio_encode != NULL)
641 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
643 g_value_set_object (value, encodebin->audio_encode);
646 if(encodebin->image_encode == NULL && (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE)) {
647 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
648 if(encodebin->image_encode != NULL)
649 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
651 g_value_set_object (value, encodebin->image_encode);
654 if(encodebin->mux == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) {
655 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
656 if(encodebin->mux != NULL)
657 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
659 g_value_set_object (value, encodebin->mux);
661 case PROP_VIDEO_CONV:
662 if(encodebin->color_space == NULL && (encodebin->profile != GST_ENCODE_BIN_PROFILE_AUDIO)) {
663 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
664 if(encodebin->color_space != NULL)
665 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
667 g_value_set_object (value, encodebin->color_space);
669 case PROP_USE_VIDEO_TOGGLE:
670 g_value_set_boolean( value, encodebin->use_video_toggle );
673 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
679 gst_encode_bin_set_property (GObject * object,
680 guint prop_id, const GValue * value, GParamSpec * pspec)
682 GstEncodeBin *encodebin;
684 encodebin = GST_ENCODE_BIN (object);
688 encodebin->profile = g_value_get_enum (value);
690 gboolean newprofile = g_value_get_enum (value);
691 if(encodebin->profile != newprofile) {
692 gst_encode_bin_change_profile(encodebin, newprofile);
693 encodebin->profile = newprofile;
697 case PROP_HIGH_SPEED:
698 encodebin->high_speed_fps = g_value_get_int (value);
700 case PROP_VENC_NAME: {
701 const gchar *new_name;
702 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
703 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
706 new_name = g_value_get_string (value);
708 if(encodebin->video_encode == NULL) {
709 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
710 encodebin->venc_name = g_strdup (new_name);
712 if(strcmp (encodebin->venc_name, new_name)) {
713 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
714 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name))
715 encodebin->venc_name = g_strdup (new_name);
720 case PROP_AENC_NAME: {
721 const gchar *new_name;
722 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
723 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
726 new_name = g_value_get_string (value);
728 if(encodebin->audio_encode == NULL) {
729 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
730 encodebin->aenc_name = g_strdup (new_name);
732 if(strcmp (encodebin->aenc_name, new_name)) {
733 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
734 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name))
735 encodebin->aenc_name = g_strdup (new_name);
740 case PROP_IENC_NAME: {
741 const gchar *new_name;
742 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
743 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
746 new_name = g_value_get_string (value);
748 if(encodebin->image_encode == NULL) {
749 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
750 encodebin->ienc_name = g_strdup (new_name);
752 if(strcmp (encodebin->ienc_name, new_name)) {
753 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
754 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name))
755 encodebin->ienc_name = g_strdup (new_name);
760 case PROP_MUX_NAME: {
761 const gchar *new_name;
762 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
763 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
766 new_name = g_value_get_string (value);
768 if(encodebin->mux == NULL) {
769 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
770 encodebin->mux_name = g_strdup (new_name);
772 if(strcmp (encodebin->mux_name, new_name)) {
773 gst_encode_bin_remove_element(encodebin, encodebin->mux);
774 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name))
775 encodebin->mux_name = g_strdup (new_name);
780 case PROP_VCONV_NAME: {
781 const gchar *new_name;
782 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
783 GST_WARNING_OBJECT(encodebin, "Profile isn't match");
786 new_name = g_value_get_string(value);
788 if (encodebin->color_space == NULL) {
789 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
790 encodebin->vconv_name = g_strdup (new_name);
792 if(strcmp (encodebin->vconv_name, new_name)) {
793 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
794 if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name))
795 encodebin->vconv_name = g_strdup (new_name);
804 const GstCaps *new_caps_val = gst_value_get_caps (value);
806 if (new_caps_val == NULL) {
807 new_caps = gst_caps_new_any ();
809 new_caps = (GstCaps *) new_caps_val;
810 gst_caps_ref (new_caps);
813 old_caps = encodebin->vcaps;
814 encodebin->vcaps = new_caps;
815 gst_caps_unref (old_caps);
821 const GstCaps *new_caps_val = gst_value_get_caps (value);
823 if (new_caps_val == NULL) {
824 new_caps = gst_caps_new_any ();
826 new_caps = (GstCaps *) new_caps_val;
827 gst_caps_ref (new_caps);
830 old_caps = encodebin->acaps;
831 encodebin->acaps = new_caps;
832 gst_caps_unref (old_caps);
838 const GstCaps *new_caps_val = gst_value_get_caps (value);
840 if (new_caps_val == NULL) {
841 new_caps = gst_caps_new_any ();
843 new_caps = (GstCaps *) new_caps_val;
844 gst_caps_ref (new_caps);
847 old_caps = encodebin->icaps;
848 encodebin->icaps = new_caps;
849 gst_caps_unref (old_caps);
853 case PROP_AUTO_AUDIO_CONVERT:
854 encodebin->auto_audio_convert = g_value_get_boolean (value);
856 case PROP_AUTO_AUDIO_RESAMPLE:
857 encodebin->auto_audio_resample = g_value_get_boolean (value);
859 case PROP_AUTO_COLORSPACE:
860 encodebin->auto_color_space = g_value_get_boolean (value);
863 gboolean newval = g_value_get_boolean (value);
864 if(encodebin->block != newval) {
865 if(!gst_encode_bin_block(encodebin, newval)) {
866 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
868 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, FALSE);
870 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, FALSE);
876 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
878 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, TRUE);
880 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, TRUE);
886 gboolean newval = g_value_get_boolean (value);
887 if(encodebin->pause != newval) {
888 if(!gst_encode_bin_pause(encodebin, newval))
891 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
893 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
895 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
900 case PROP_VENC_QUEUE:
901 // encodebin->use_venc_queue = g_value_get_boolean (value);
903 GstElement *newelement = g_value_get_object (value);
904 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
905 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
908 if(newelement != NULL) {
909 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
910 encodebin->video_encode_queue = newelement;
911 gst_object_ref (encodebin->video_encode_queue);
912 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode_queue)); // take ownership ??
913 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue);
918 case PROP_AENC_QUEUE:
919 // encodebin->use_aenc_queue = g_value_get_boolean (value);
921 GstElement *newelement = g_value_get_object (value);
922 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
923 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
926 if(newelement != NULL) {
927 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
928 encodebin->audio_encode_queue = newelement;
929 gst_object_ref (encodebin->audio_encode_queue);
930 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode_queue));
931 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue);
938 GstElement *newelement = g_value_get_object (value);
939 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) {
940 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
943 if(newelement != NULL) {
944 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
945 encodebin->video_encode = newelement;
946 gst_object_ref (encodebin->video_encode);
947 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
948 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
954 GstElement *newelement = g_value_get_object (value);
955 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
956 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
959 if(newelement != NULL) {
960 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
961 encodebin->audio_encode = newelement;
962 gst_object_ref (encodebin->audio_encode);
963 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
964 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
968 case PROP_IMAGE_ENC: {
969 GstElement *newelement = g_value_get_object (value);
970 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) {
971 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
974 if(newelement != NULL) {
975 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
976 encodebin->image_encode = newelement;
977 gst_object_ref (encodebin->image_encode);
978 gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
979 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
984 GstElement *newelement = g_value_get_object (value);
985 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) {
986 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
989 if(newelement != NULL) {
990 gst_encode_bin_remove_element(encodebin, encodebin->mux);
991 encodebin->mux = newelement;
992 gst_object_ref (encodebin->mux);
993 gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
994 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
998 case PROP_VIDEO_CONV: {
999 GstElement *newelement = g_value_get_object (value);
1000 if(encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) {
1001 GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!");
1004 if(newelement != NULL) {
1005 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1006 encodebin->color_space = newelement;
1007 gst_object_ref (encodebin->color_space);
1008 gst_object_sink (GST_OBJECT_CAST (encodebin->color_space));
1009 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1013 case PROP_USE_VIDEO_TOGGLE:
1014 encodebin->use_video_toggle = g_value_get_boolean( value );
1017 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1023 gst_encode_bin_request_new_pad (GstElement * element,
1024 GstPadTemplate * templ, const gchar * req_name)
1026 GstEncodeBin *encodebin = NULL;
1027 GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
1030 g_return_val_if_fail (templ != NULL, NULL);
1032 if (templ->direction != GST_PAD_SINK) {
1033 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: request pad that is not a SINK pad\n");
1037 g_return_val_if_fail (GST_IS_ENCODE_BIN (element), NULL);
1039 encodebin = GST_ENCODE_BIN (element);
1042 if (templ == gst_element_class_get_pad_template (klass, "audio")) {
1043 if (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO) {
1044 gst_encode_bin_init_audio_elements(element, NULL); //??
1046 if(encodebin->audio_sinkpad == NULL)
1048 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
1049 encodebin->audio_sinkpad = gst_ghost_pad_new ("audio", pad);
1050 gst_object_unref(pad);
1055 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: audio pad is aleady existed, return existing audio pad\n");
1056 return encodebin->audio_sinkpad;
1059 gst_element_add_pad (element, encodebin->audio_sinkpad);
1060 gst_pad_set_setcaps_function (encodebin->audio_sinkpad,
1061 GST_DEBUG_FUNCPTR (gst_encode_bin_audsink_set_caps));
1062 return encodebin->audio_sinkpad;
1065 } else if (templ == gst_element_class_get_pad_template (klass, "video")) {
1066 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV) {
1067 gst_encode_bin_init_video_elements(element, NULL); //??
1069 if(encodebin->video_sinkpad == NULL)
1071 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
1072 encodebin->video_sinkpad = gst_ghost_pad_new ("video", pad);
1073 gst_object_unref(pad);
1078 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: video pad is aleady existed, return existing video pad\n");
1079 return encodebin->video_sinkpad;
1082 gst_element_add_pad (element, encodebin->video_sinkpad);
1083 gst_pad_set_setcaps_function (encodebin->video_sinkpad,
1084 GST_DEBUG_FUNCPTR (gst_encode_bin_vidsink_set_caps));
1085 return encodebin->video_sinkpad;
1086 } else if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1087 gst_encode_bin_init_image_elements(element, NULL); //??
1089 if(encodebin->image_sinkpad == NULL)
1091 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1092 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1093 gst_object_unref(pad);
1098 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1099 return encodebin->image_sinkpad;
1102 gst_element_add_pad (element, encodebin->image_sinkpad);
1103 gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1104 GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1105 return encodebin->image_sinkpad;
1109 if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) {
1110 gst_encode_bin_init_image_elements(element, NULL); //??
1112 if(encodebin->image_sinkpad == NULL)
1114 pad = gst_element_get_static_pad (encodebin->image_queue, "sink");
1115 encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad);
1116 gst_object_unref(pad);
1121 GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n");
1122 return encodebin->image_sinkpad;
1125 gst_element_add_pad (element, encodebin->image_sinkpad);
1126 gst_pad_set_setcaps_function (encodebin->image_sinkpad,
1127 GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps));
1128 return encodebin->image_sinkpad;
1135 gst_encode_bin_class_init (GstEncodeBinClass *klass)
1137 GObjectClass *gobject_klass;
1138 GstElementClass *gstelement_klass;
1139 GstBinClass *gstbin_klass;
1141 gobject_klass = (GObjectClass *) klass;
1142 gstelement_klass = (GstElementClass *) klass;
1143 gstbin_klass = (GstBinClass *) klass;
1145 parent_class = g_type_class_peek_parent (klass);
1147 gobject_klass->get_property = gst_encode_bin_get_property;
1148 gobject_klass->set_property = gst_encode_bin_set_property;
1149 gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_encode_bin_dispose);
1150 gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_encode_bin_finalize);
1153 g_object_class_install_property (gobject_klass, PROP_PROFILE,
1154 g_param_spec_enum ("profile", "PROFILE", "Profile of the media to record",
1155 GST_TYPE_ENCODE_BIN_PROFILE, DEFAULT_PROP_PROFILE,
1156 G_PARAM_READWRITE));
1158 g_object_class_install_property (gobject_klass, PROP_HIGH_SPEED,
1159 g_param_spec_int ("high-speed-fps", "high speed rec. fps", "framerate for high speed recording", 0, G_MAXINT,
1160 DEFAULT_PROP_HIGH_SPEED, G_PARAM_READWRITE));
1162 g_object_class_install_property (gobject_klass, PROP_VENC_NAME,
1163 g_param_spec_string ("venc-name", "video encoder name", "the name of video encoder to use",
1164 DEFAULT_PROP_VENC_NAME, G_PARAM_READWRITE));
1166 g_object_class_install_property (gobject_klass, PROP_AENC_NAME,
1167 g_param_spec_string ("aenc-name", "audio encoder name", "the name of audio encoder to use",
1168 DEFAULT_PROP_AENC_NAME, G_PARAM_READWRITE));
1170 g_object_class_install_property (gobject_klass, PROP_IENC_NAME,
1171 g_param_spec_string ("ienc-name", "image encoder name", "the name of image encoder to use",
1172 DEFAULT_PROP_IENC_NAME, G_PARAM_READWRITE));
1174 g_object_class_install_property (gobject_klass, PROP_MUX_NAME,
1175 g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use",
1176 DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE));
1178 g_object_class_install_property (gobject_klass, PROP_VCONV_NAME,
1179 g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use",
1180 DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE));
1182 g_object_class_install_property (gobject_klass, PROP_VCAPS,
1183 g_param_spec_boxed ("vcaps", "caps for video","caps for video recording",
1184 GST_TYPE_CAPS, G_PARAM_READWRITE));
1186 g_object_class_install_property (gobject_klass, PROP_ACAPS,
1187 g_param_spec_boxed ("acaps", "caps for audio","caps for audio recording",
1188 GST_TYPE_CAPS, G_PARAM_READWRITE));
1190 g_object_class_install_property (gobject_klass, PROP_ICAPS,
1191 g_param_spec_boxed ("icaps", "caps for image","caps for image stillshot",
1192 GST_TYPE_CAPS, G_PARAM_READWRITE));
1194 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_CONVERT,
1195 g_param_spec_boolean ("auto-audio-convert", "auto audio convert",
1196 "Support for auto audio convert", TRUE, G_PARAM_READWRITE));
1198 g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_RESAMPLE,
1199 g_param_spec_boolean ("auto-audio-resample", "auto audio resample",
1200 "Support for auto audio resample", TRUE, G_PARAM_READWRITE));
1202 g_object_class_install_property (gobject_klass, PROP_AUTO_COLORSPACE,
1203 g_param_spec_boolean ("auto-colorspace", "auto colorspace",
1204 "Support for auto colorspace", TRUE, G_PARAM_READWRITE));
1206 g_object_class_install_property (gobject_klass, PROP_BLOCK,
1207 g_param_spec_boolean ("block", "stream block",
1208 "Support for stream block", FALSE, G_PARAM_READWRITE));
1210 g_object_class_install_property (gobject_klass, PROP_PAUSE,
1211 g_param_spec_boolean ("runtime-pause", "recording pause",
1212 "Support for recording pause/resume", FALSE, G_PARAM_READWRITE));
1215 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1216 g_param_spec_boolean ("use-venc-queue", "use queue between venc and mux",
1217 "add queue between venc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1219 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1220 g_param_spec_boolean ("use-aenc-queue", "use queue between aenc and mux",
1221 "add queue between aenc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE));
1223 g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE,
1224 g_param_spec_object ("use-venc-queue", "Video Encoder queue",
1225 "add queue between venc and mux(only for custom optimization)",
1226 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1228 g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE,
1229 g_param_spec_object ("use-aenc-queue", "Audio Encoder queue",
1230 "add queue between aenc and mux(only for custom optimization)",
1231 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1234 g_object_class_install_property (gobject_klass, PROP_VIDEO_ENC,
1235 g_param_spec_object ("video-encode", "Video Encoder",
1236 "the video encoder element to use",
1237 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1239 g_object_class_install_property (gobject_klass, PROP_AUDIO_ENC,
1240 g_param_spec_object ("audio-encode", "Audio Encoder",
1241 "the audio encoder element to use",
1242 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1244 g_object_class_install_property (gobject_klass, PROP_IMAGE_ENC,
1245 g_param_spec_object ("image-encode", "Image Encoder",
1246 "the Image encoder element to use",
1247 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1249 g_object_class_install_property (gobject_klass, PROP_MUX,
1250 g_param_spec_object ("mux", "Muxer",
1251 "the muxer element to use",
1252 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1254 g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV,
1255 g_param_spec_object ("video-convert", "Video converter",
1256 "the video converter element to use",
1257 GST_TYPE_ELEMENT, G_PARAM_READWRITE));
1259 g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE,
1260 g_param_spec_boolean ("use-video-toggle", "Use video toggle",
1261 "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE));
1263 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
1264 gst_encode_bin_signals[SIGNAL_STREAM_BLOCK] =
1265 g_signal_new ("stream-block", G_TYPE_FROM_CLASS (klass),
1266 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_block),
1267 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1269 gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK] =
1270 g_signal_new ("stream-unblock", G_TYPE_FROM_CLASS (klass),
1271 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_unblock),
1272 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1274 gst_encode_bin_signals[SIGNAL_STREAM_PAUSE] =
1275 g_signal_new ("stream-pause", G_TYPE_FROM_CLASS (klass),
1276 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_pause),
1277 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1279 gst_encode_bin_signals[SIGNAL_STREAM_RESUME] =
1280 g_signal_new ("stream-resume", G_TYPE_FROM_CLASS (klass),
1281 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_resume),
1282 NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1285 gst_element_class_add_pad_template (gstelement_klass,
1286 gst_static_pad_template_get (&encoder_bin_src_template));
1287 gst_element_class_add_pad_template (gstelement_klass,
1288 gst_static_pad_template_get (&encoder_bin_audio_sink_template));
1289 gst_element_class_add_pad_template (gstelement_klass,
1290 gst_static_pad_template_get (&encoder_bin_video_sink_template));
1291 gst_element_class_add_pad_template (gstelement_klass,
1292 gst_static_pad_template_get (&encoder_bin_image_sink_template));
1294 gst_element_class_set_details (gstelement_klass, &gst_encode_bin_details);
1296 gstelement_klass->request_new_pad =
1297 GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad);
1298 gstelement_klass->release_pad =
1299 GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad);
1300 gstelement_klass->change_state =
1301 GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
1305 gst_encode_bin_init (GstEncodeBin *encodebin)
1307 encodebin->mutex = g_mutex_new();
1309 if (encodebin->srcpad == NULL) {
1310 encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
1311 gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad);
1314 encodebin->video_sinkpad = NULL;
1315 encodebin->audio_sinkpad = NULL;
1316 encodebin->image_sinkpad = NULL;
1317 encodebin->mux_audio_sinkpad = NULL;
1318 encodebin->mux_video_sinkpad = NULL;
1320 encodebin->profile = DEFAULT_PROP_PROFILE;
1322 encodebin->high_speed_fps = DEFAULT_PROP_HIGH_SPEED;
1323 encodebin->multiple = 1;
1325 encodebin->auto_audio_convert = TRUE;
1326 encodebin->auto_audio_resample = TRUE;
1327 encodebin->auto_color_space = TRUE;
1328 encodebin->block = FALSE;
1329 encodebin->pause= FALSE;
1330 encodebin->use_video_toggle = TRUE;
1331 encodebin->use_venc_queue= FALSE;
1332 encodebin->use_aenc_queue= FALSE;
1334 encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME);
1335 encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME);
1336 encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME);
1337 encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME);
1338 encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME);
1340 encodebin->vcaps = gst_caps_new_any ();
1341 encodebin->acaps = gst_caps_new_any ();
1342 encodebin->icaps = gst_caps_new_any ();
1344 encodebin->audio_queue = NULL;
1345 encodebin->video_queue = NULL;
1346 encodebin->video_encode_queue = NULL;
1347 encodebin->image_queue = NULL;
1349 encodebin->audio_encode = NULL;
1350 encodebin->video_encode = NULL;
1351 encodebin->image_encode = NULL;
1353 encodebin->vcapsfilter = NULL;
1354 encodebin->acapsfilter = NULL;
1355 encodebin->icapsfilter = NULL;
1357 encodebin->video_toggle = NULL;
1358 encodebin->image_toggle = NULL;
1359 encodebin->color_space = NULL;
1360 encodebin->audio_conv = NULL;
1361 encodebin->audio_sample = NULL;
1363 encodebin->mux = NULL;
1365 encodebin->paused_time = 0;
1366 encodebin->total_offset_time = 0;
1368 encodebin->vsink_probeid = 0;
1369 encodebin->vsink_hs_probeid = 0;
1370 encodebin->asink_probeid = 0;
1371 encodebin->veque_sig_id = 0;
1372 encodebin->aeque_sig_id = 0;
1376 gst_encode_bin_dispose (GObject * object)
1378 GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1380 g_free(encodebin->venc_name);
1381 encodebin->venc_name = NULL;
1383 g_free(encodebin->aenc_name);
1384 encodebin->aenc_name = NULL;
1386 g_free(encodebin->ienc_name);
1387 encodebin->ienc_name = NULL;
1389 g_free(encodebin->mux_name);
1390 encodebin->mux_name = NULL;
1392 g_free(encodebin->vconv_name);
1393 encodebin->vconv_name = NULL;
1395 gst_caps_replace (&encodebin->vcaps, NULL);
1396 gst_caps_replace (&encodebin->acaps, NULL);
1397 gst_caps_replace (&encodebin->icaps, NULL);
1399 if (encodebin->srcpad != NULL) {
1400 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad);
1401 encodebin->srcpad = NULL;
1404 G_OBJECT_CLASS (parent_class)->dispose (object);
1406 encodebin->video_sinkpad = NULL;
1407 encodebin->audio_sinkpad = NULL;
1408 encodebin->image_sinkpad = NULL;
1409 encodebin->mux_audio_sinkpad = NULL;
1410 encodebin->mux_video_sinkpad = NULL;
1412 encodebin->audio_queue = NULL;
1413 encodebin->video_queue = NULL;
1414 encodebin->image_queue = NULL;
1416 encodebin->audio_encode = NULL;
1417 encodebin->video_encode = NULL;
1418 encodebin->video_encode_queue = NULL;
1419 encodebin->image_encode = NULL;
1421 encodebin->vcapsfilter = NULL;
1422 encodebin->acapsfilter = NULL;
1423 encodebin->icapsfilter = NULL;
1425 encodebin->video_toggle = NULL;
1426 encodebin->image_toggle = NULL;
1427 encodebin->color_space = NULL;
1428 encodebin->audio_conv = NULL;
1429 encodebin->audio_sample = NULL;
1431 if (encodebin->mux && GST_IS_ELEMENT(encodebin->mux)) {
1432 int remain_count= 0;
1433 remain_count = GST_OBJECT_REFCOUNT_VALUE(encodebin->mux);
1434 while (remain_count) {
1435 gst_object_unref(encodebin->mux);
1440 encodebin->mux = NULL;
1444 gst_encode_bin_finalize (GObject * object)
1446 GstEncodeBin *encodebin = GST_ENCODE_BIN (object);
1448 g_mutex_free (encodebin->mutex);
1450 G_OBJECT_CLASS (parent_class)->finalize (object);
1453 static GstStateChangeReturn
1454 gst_encode_bin_change_state (GstElement * element, GstStateChange transition)
1456 GstStateChangeReturn ret;
1457 GstEncodeBin *encode_bin;
1459 encode_bin = GST_ENCODE_BIN (element);
1461 switch (transition) {
1462 case GST_STATE_CHANGE_NULL_TO_READY:
1463 gst_encode_bin_link_elements(encode_bin);
1465 case GST_STATE_CHANGE_READY_TO_PAUSED:
1466 /* reset time related values */
1467 encode_bin->paused_time = 0;
1468 encode_bin->total_offset_time = 0;
1470 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1472 case GST_STATE_CHANGE_PAUSED_TO_READY:
1478 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1480 switch (transition) {
1481 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1483 case GST_STATE_CHANGE_PAUSED_TO_READY:
1485 case GST_STATE_CHANGE_READY_TO_NULL:
1486 gst_encode_bin_unlink_elements(encode_bin);
1492 // if (ret == GST_STATE_CHANGE_FAILURE)
1499 gst_encode_bin_release_all_pads (GstEncodeBin *encodebin)
1501 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->video_sinkpad);
1502 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->audio_sinkpad);
1503 gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->image_sinkpad);
1507 gst_encode_bin_release_pad (GstElement * element, GstPad * pad)
1509 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
1510 GstPad *muxpad = NULL;
1512 if(!pad_compare_name(pad, "video")) {
1514 gst_encode_bin_remove_element(encodebin, encodebin->video_queue);
1515 encodebin->video_queue = NULL;
1516 gst_encode_bin_remove_element(encodebin, encodebin->video_toggle);
1517 encodebin->video_toggle = NULL;
1518 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1519 encodebin->color_space = NULL;
1520 gst_encode_bin_remove_element(encodebin, encodebin->vcapsfilter);
1521 encodebin->vcapsfilter = NULL;
1522 gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue);
1523 encodebin->video_encode_queue = NULL;
1524 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1525 encodebin->video_encode = NULL;
1527 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1528 encodebin->mux_video_sinkpad = NULL;
1530 if(encodebin->mux_audio_sinkpad == NULL) {
1531 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1532 encodebin->mux = NULL;
1536 encodebin->mux_audio_sinkpad = NULL;
1540 if(encodebin->mux_video_sinkpad != NULL)
1542 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
1543 encodebin->mux_video_sinkpad = NULL;
1546 gst_pad_set_active (pad, FALSE); //??
1547 gst_element_remove_pad(element, pad);
1548 encodebin->video_sinkpad = NULL;
1549 } else if(!pad_compare_name(pad, "audio")) {
1551 gst_encode_bin_remove_element(encodebin, encodebin->audio_queue);
1552 encodebin->audio_queue = NULL;
1553 gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
1554 encodebin->audio_sample = NULL;
1555 gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
1556 encodebin->audio_conv = NULL;
1557 gst_encode_bin_remove_element(encodebin, encodebin->acapsfilter);
1558 encodebin->acapsfilter = NULL;
1559 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue);
1560 encodebin->audio_encode_queue = NULL;
1561 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1562 encodebin->audio_encode = NULL;
1564 encodebin->mux_audio_sinkpad;
1565 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1568 if(encodebin->mux_video_sinkpad == NULL) {
1569 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1570 encodebin->mux = NULL;
1574 encodebin->mux_video_sinkpad = NULL;
1577 if(encodebin->mux_audio_sinkpad != NULL)
1579 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
1580 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
1581 encodebin->mux_audio_sinkpad = NULL;
1584 gst_pad_set_active (pad, FALSE); //??
1585 gst_element_remove_pad(element, pad);
1586 encodebin->audio_sinkpad = NULL;
1589 gst_encode_bin_remove_element(encodebin, encodebin->image_queue);
1590 encodebin->image_queue = NULL;
1591 gst_encode_bin_remove_element(encodebin, encodebin->image_toggle);
1592 encodebin->image_toggle = NULL;
1593 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
1594 encodebin->color_space = NULL;
1595 gst_encode_bin_remove_element(encodebin, encodebin->icapsfilter);
1596 encodebin->icapsfilter = NULL;
1597 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1598 encodebin->image_encode = NULL;
1600 gst_pad_set_active (pad, FALSE); //??
1601 gst_element_remove_pad(element, pad);
1602 encodebin->image_sinkpad = NULL;
1607 pad_compare_name (GstPad * pad1, const gchar * name)
1611 GST_OBJECT_LOCK (pad1);
1612 result = strcmp (GST_PAD_NAME (pad1), name);
1613 GST_OBJECT_UNLOCK (pad1);
1619 gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1622 case ENCODEBIN_ELEMENT_VENC:
1623 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1624 if(encodebin->video_encode != NULL) {
1625 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1626 g_free(encodebin->venc_name);
1627 encodebin->venc_name = NULL;
1629 goto element_make_fail;
1632 case ENCODEBIN_ELEMENT_AENC:
1633 encodebin->audio_encode = gst_element_factory_make (name, "audio_encode");
1634 if(encodebin->audio_encode != NULL) {
1635 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1636 g_free(encodebin->aenc_name);
1637 encodebin->aenc_name = NULL;
1639 goto element_make_fail;
1642 case ENCODEBIN_ELEMENT_IENC:
1643 encodebin->image_encode = gst_element_factory_make (name, "image_encode");
1644 if(encodebin->image_encode != NULL) {
1645 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1646 g_free(encodebin->ienc_name);
1647 encodebin->ienc_name = NULL;
1649 goto element_make_fail;
1652 case ENCODEBIN_ELEMENT_MUX:
1653 encodebin->mux = gst_element_factory_make (name, "mux");
1654 if(encodebin->mux != NULL) {
1655 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1656 g_free(encodebin->mux_name);
1657 encodebin->mux_name = NULL;
1659 goto element_make_fail;
1662 case ENCODEBIN_ELEMENT_VIDEO_CONV:
1663 encodebin->color_space = gst_element_factory_make(name, "video_convert");
1664 if (encodebin->color_space != NULL) {
1665 gst_bin_add(GST_BIN(encodebin), encodebin->color_space);
1666 g_free(encodebin->vconv_name);
1667 encodebin->vconv_name = NULL;
1669 goto element_make_fail;
1673 GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1680 GST_WARNING_OBJECT(encodebin, "no such element factory \"%s\"!", name);
1684 #if 0 //disable unused function
1686 gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean newprofile)
1689 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1690 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1691 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1692 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1694 switch (newprofile) {
1695 case GST_ENCODE_BIN_PROFILE_AV :
1696 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1697 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name,"video_encode");
1698 encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1700 gst_bin_add_many (GST_BIN (encodebin),
1701 encodebin->audio_encode,
1702 encodebin->video_encode,
1706 case GST_ENCODE_BIN_PROFILE_AUDIO :
1707 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
1708 encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux");
1710 gst_bin_add_many (GST_BIN (encodebin),
1711 encodebin->audio_encode,
1715 case GST_ENCODE_BIN_PROFILE_IMAGE :
1716 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name,"image_encode");
1718 gst_bin_add_many (GST_BIN (encodebin),
1719 encodebin->image_encode,
1723 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
1732 gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement)
1734 if(newelement == NULL) {
1735 GST_ERROR_OBJECT(encodebin, "some elements are null\n");
1739 case PROP_VIDEO_ENC:
1740 gst_encode_bin_remove_element(encodebin, encodebin->video_encode);
1741 encodebin->video_encode = newelement;
1742 gst_object_ref (encodebin->video_encode);
1743 gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ??
1744 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1746 case PROP_AUDIO_ENC:
1747 gst_encode_bin_remove_element(encodebin, encodebin->audio_encode);
1748 encodebin->audio_encode = newelement;
1749 gst_object_ref (encodebin->audio_encode);
1750 gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode));
1751 gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode);
1753 case PROP_IMAGE_ENC:
1754 gst_encode_bin_remove_element(encodebin, encodebin->image_encode);
1755 encodebin->image_encode = newelement;
1756 gst_object_ref (encodebin->image_encode);
1757 gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode));
1758 gst_bin_add(GST_BIN(encodebin), encodebin->image_encode);
1761 gst_encode_bin_remove_element(encodebin, encodebin->mux);
1762 encodebin->mux = newelement;
1763 gst_object_ref (encodebin->mux);
1764 gst_object_sink (GST_OBJECT_CAST (encodebin->mux));
1765 gst_bin_add(GST_BIN(encodebin), encodebin->mux);
1768 GST_WARNING_OBJECT(encodebin, "Invalid type = %d", type);
1775 gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name)
1777 GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1780 case ENCODEBIN_ELEMENT_VENC:
1781 if(encodebin->video_encode == NULL) {
1782 encodebin->video_encode = gst_element_factory_make (name, "video_encode");
1783 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1785 sink1 = gst_element_get_static_pad(encodebin->video_encode, "sink");
1786 src = gst_element_get_static_pad(encodebin->video_encode, "src");
1788 peersink1 = gst_pad_get_peer(sink1);
1789 if(peersink1 != NULL) {
1790 if(!gst_pad_unlink(peersink1, sink1)) {
1797 peersrc = gst_pad_get_peer(src);
1798 if(peersrc != NULL) {
1799 if(!gst_pad_unlink(src, peersrc)) {
1805 if(gst_encode_bin_remove_element(encodebin, encodebin->video_encode)) {
1806 if(encodebin->video_encode = gst_element_factory_make (name, "video_encode") != NULL) {
1807 gst_bin_add(GST_BIN(encodebin), encodebin->video_encode);
1808 if(peersink1 != NULL) {
1809 if(!gst_pad_link(peersink1, gst_element_get_pad(encodebin->video_encode, "sink"))) {
1814 if(peersrc != NULL) {
1815 if(!gst_pad_link(gst_element_get_pad(encodebin->video_encode, "src"), peersrc)) {
1820 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] make fail\n", type);
1824 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] remove fail\n", type);
1829 case ENCODEBIN_ELEMENT_AENC:
1831 case ENCODEBIN_ELEMENT_IENC:
1833 case ENCODEBIN_ELEMENT_MUX:
1836 GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type);
1839 gst_object_unref(sink1);
1840 gst_object_unref(sink2);
1841 gst_object_unref(src);
1842 gst_object_unref(peersink1);
1843 gst_object_unref(peersink2);
1844 gst_object_unref(peersrc);
1848 gst_object_unref(sink1);
1849 gst_object_unref(sink2);
1850 gst_object_unref(src);
1851 gst_object_unref(peersink1);
1852 gst_object_unref(peersink2);
1853 gst_object_unref(peersrc);
1854 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] unlink fail\n", type);
1859 gst_object_unref(sink1);
1860 gst_object_unref(sink2);
1861 gst_object_unref(src);
1862 gst_object_unref(peersink1);
1863 gst_object_unref(peersink2);
1864 gst_object_unref(peersrc);
1865 GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] link fail\n", type);
1870 gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element)
1872 GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc;
1875 case ENCODEBIN_ELEMENT_VENC:
1876 if(encodebin->video_encode == NULL) {
1877 encodebin->video_encode = element
1880 case ENCODEBIN_ELEMENT_AENC:
1882 case ENCODEBIN_ELEMENT_IENC:
1884 case ENCODEBIN_ELEMENT_MUX:
1887 GST_WARNING_OBJECT (encodebin,"Invalid element type = %d", type);
1890 #endif //disable unused function
1893 gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element)
1896 gchar *ename = NULL;
1897 GST_INFO_OBJECT (encodebin, "gst_encode_bin_remove_element");
1899 if (element == NULL) {
1900 GST_INFO_OBJECT (encodebin, "element is already NULL");
1904 gst_element_set_state (element, GST_STATE_NULL);
1905 parent = gst_element_get_parent (element);
1907 if (parent != NULL) {
1908 if(!gst_bin_remove (GST_BIN_CAST (parent), element)) {
1909 gst_object_unref (parent);
1910 ename = gst_element_get_name (element);
1911 GST_ERROR_OBJECT (encodebin, "gst_encode_bin_remove_element() [%s] remove fail", ename);
1915 gst_object_unref(parent);
1918 gst_object_unref(element);
1925 gst_encode_bin_link_elements (GstEncodeBin *encodebin) // need to return ????
1927 GstPad *srcpad = NULL, *sinkpad = NULL;
1928 switch(encodebin->profile) {
1929 case GST_ENCODE_BIN_PROFILE_AV :
1930 if (!gst_caps_is_any(encodebin->vcaps)) {
1931 gchar *caps_str = NULL;
1932 caps_str = gst_caps_to_string(encodebin->vcaps);
1934 GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str);
1939 g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL);
1942 if (encodebin->auto_color_space) {
1943 if(encodebin->color_space == NULL) {
1944 encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert");
1945 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
1948 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
1949 if( encodebin->video_toggle )
1951 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
1952 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1954 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
1956 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
1957 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1959 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
1960 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
1961 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1963 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
1964 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
1965 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1967 if(encodebin->use_venc_queue)
1969 if(encodebin->video_encode_queue == NULL) {
1970 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
1971 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
1973 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1974 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1975 G_CALLBACK(queue_overun_cb), encodebin);
1979 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1980 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1981 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
1984 if(encodebin->video_encode_queue)
1986 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
1987 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
1988 G_CALLBACK(queue_overun_cb), encodebin);
1990 g_object_set(G_OBJECT(encodebin->video_queue),
1991 "max-size-bytes", (guint)0,
1992 "max-size-buffers", (guint)1,
1993 "max-size-time", (guint64)0,
1996 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
1997 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
1998 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2004 srcpad = gst_element_get_static_pad(encodebin->video_queue, "src");
2005 if( encodebin->video_toggle )
2007 sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink");
2008 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2010 srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src");
2012 sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink");
2013 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2015 srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src");
2016 sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink");
2017 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2019 if(encodebin->use_venc_queue)
2021 if(encodebin->video_encode_queue == NULL) {
2022 encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue");
2023 gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue);
2025 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2026 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2027 G_CALLBACK(queue_overun_cb), encodebin);
2030 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2031 sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink");
2032 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2036 if(encodebin->video_encode_queue)
2038 ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME);
2039 encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun",
2040 G_CALLBACK(queue_overun_cb), encodebin);
2042 g_object_set(G_OBJECT(encodebin->video_queue),
2043 "max-size-bytes", (guint)0,
2044 "max-size-buffers", (guint)1,
2045 "max-size-time", (guint64)0,
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);
2057 // gst_element_get_request_pad (encodebin->mux, "video_%d");
2059 if(encodebin->use_venc_queue)
2061 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2062 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2063 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2066 if(encodebin->video_encode_queue)
2068 srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src");
2069 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2070 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2075 srcpad = gst_element_get_static_pad(encodebin->video_encode, "src");
2076 sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK);
2077 _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail);
2080 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2081 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2082 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2083 gst_object_unref(srcpad);
2086 /* For pause/resume control */
2087 // encodebin->vsink_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_queue, "sink"),
2088 sinkpad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2089 encodebin->vsink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe), encodebin);
2090 gst_object_unref(sinkpad);
2093 if(encodebin->high_speed_fps > DEFAULT_PROP_HIGH_SPEED)
2095 // encodebin->vsink_hs_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_encode, "sink"),
2096 sinkpad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2097 encodebin->vsink_hs_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe_hs), encodebin);
2098 gst_object_unref(sinkpad);
2102 if(encodebin->audio_queue == NULL)
2104 GST_WARNING_OBJECT(encodebin, "Audio pad isn't requested, recording video only mode");
2107 case GST_ENCODE_BIN_PROFILE_AUDIO :
2108 if(!gst_caps_is_any(encodebin->acaps))
2110 g_object_set(encodebin->acapsfilter, "caps", encodebin->acaps, NULL);
2112 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2113 if (!encodebin->auto_audio_convert) {
2114 if(encodebin->audio_sample == NULL) {
2115 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2116 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2118 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2119 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2120 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2122 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2123 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2124 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2126 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2127 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2128 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2130 if(encodebin->use_aenc_queue)
2132 if(encodebin->audio_encode_queue == NULL) {
2133 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2134 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2136 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2137 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2138 G_CALLBACK(queue_overun_cb), encodebin);
2141 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2142 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2143 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2146 if(encodebin->audio_encode_queue)
2149 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2150 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2151 G_CALLBACK(queue_overun_cb), encodebin);
2153 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2154 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2155 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2159 } else if (!encodebin->auto_audio_resample) {
2160 if (encodebin->audio_conv == NULL) {
2161 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2162 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2165 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2166 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2167 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2169 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2170 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2171 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2173 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2174 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2175 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2177 if(encodebin->use_aenc_queue)
2179 if(encodebin->audio_encode_queue == NULL) {
2180 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2181 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2183 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2184 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2185 G_CALLBACK(queue_overun_cb), encodebin);
2188 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2189 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2190 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2194 if(encodebin->audio_encode_queue)
2197 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2198 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2199 G_CALLBACK(queue_overun_cb), encodebin);
2201 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2202 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2203 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2208 if(encodebin->audio_sample == NULL) {
2209 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2210 gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample);
2212 if (encodebin->audio_conv == NULL) {
2213 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2214 gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv);
2217 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2218 sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink");
2219 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2221 srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src");
2222 sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink");
2223 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2225 srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src");
2226 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2227 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2229 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2230 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2231 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2233 if(encodebin->use_aenc_queue)
2235 if(encodebin->audio_encode_queue == NULL) {
2236 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2237 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2239 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2240 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2241 G_CALLBACK(queue_overun_cb), encodebin);
2244 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2245 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2246 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2250 if(encodebin->audio_encode_queue)
2253 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2254 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2255 G_CALLBACK(queue_overun_cb), encodebin);
2257 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2258 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2259 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2266 srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src");
2267 sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink");
2268 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2270 srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src");
2271 sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink");
2272 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2274 if(encodebin->use_aenc_queue)
2276 if(encodebin->audio_encode_queue == NULL) {
2277 encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue");
2278 gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue);
2280 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2281 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2282 G_CALLBACK(queue_overun_cb), encodebin);
2285 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2286 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2287 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2290 if(encodebin->audio_encode_queue)
2293 ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME);
2294 encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun",
2295 G_CALLBACK(queue_overun_cb), encodebin);
2297 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2298 sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink");
2299 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2305 if(encodebin->use_aenc_queue)
2307 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2308 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2309 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2314 if(encodebin->audio_encode_queue)
2316 srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src");
2317 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2318 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2324 srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src");
2325 sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK);
2326 _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail);
2330 srcpad = gst_element_get_static_pad(encodebin->mux, "src");
2331 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2332 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2333 gst_object_unref(srcpad);
2336 /* For pause/resume control */
2337 sinkpad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2338 encodebin->asink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_audio_probe), encodebin);
2339 gst_object_unref(sinkpad);
2343 case GST_ENCODE_BIN_PROFILE_IMAGE :
2344 if(!gst_caps_is_any(encodebin->icaps))
2346 g_object_set(encodebin->icapsfilter, "caps", encodebin->icaps, NULL);
2349 if (encodebin->auto_color_space) {
2350 if(encodebin->color_space == NULL) {
2351 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2352 gst_bin_add (GST_BIN (encodebin), encodebin->color_space);
2355 srcpad = gst_element_get_static_pad(encodebin->image_queue, "src");
2356 sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink");
2357 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2359 srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src");
2360 sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink");
2361 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2363 srcpad = gst_element_get_static_pad(encodebin->color_space, "src");
2364 sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink");
2365 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2367 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2368 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2369 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
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->icapsfilter, "sink");
2380 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2382 srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src");
2383 sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink");
2384 _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail);
2387 srcpad = gst_element_get_static_pad (encodebin->image_encode, "src");
2388 if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad)
2389 gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad);
2390 gst_object_unref(srcpad);
2394 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2398 // gst_pad_set_active(encodebin->srcpad, TRUE);
2403 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2404 GST_WARNING_OBJECT(encodebin, "encodebin link video elements fail");
2409 gst_encode_bin_remove_element(encodebin, encodebin->audio_conv);
2410 gst_encode_bin_remove_element(encodebin, encodebin->audio_sample);
2411 GST_WARNING_OBJECT(encodebin, "encodebin link audio elements fail");
2416 gst_encode_bin_remove_element(encodebin, encodebin->color_space);
2417 GST_WARNING_OBJECT(encodebin, "encodebin link image elements fail");
2424 gst_encode_bin_unlink_elements (GstEncodeBin *encodebin)
2426 GstPad *pad = NULL, *muxpad = NULL;
2428 switch(encodebin->profile) {
2429 case GST_ENCODE_BIN_PROFILE_AV :
2430 if (encodebin->auto_color_space) {
2431 if (encodebin->video_toggle) {
2432 gst_element_unlink_many(
2433 encodebin->video_queue,
2434 encodebin->video_toggle,
2435 encodebin->color_space,
2436 encodebin->vcapsfilter,
2437 encodebin->video_encode,
2438 //encodebin->video_encode_queue,
2441 gst_element_unlink_many(
2442 encodebin->video_queue,
2443 encodebin->color_space,
2444 encodebin->vcapsfilter,
2445 encodebin->video_encode,
2446 //encodebin->video_encode_queue,
2450 if (encodebin->video_toggle) {
2451 gst_element_unlink_many(
2452 encodebin->video_queue,
2453 encodebin->video_toggle,
2454 encodebin->vcapsfilter,
2455 encodebin->video_encode,
2456 //encodebin->video_encode_queue,
2459 gst_element_unlink_many(
2460 encodebin->video_queue,
2461 encodebin->vcapsfilter,
2462 encodebin->video_encode,
2463 //encodebin->video_encode_queue,
2468 if(encodebin->mux_video_sinkpad != NULL)
2471 if(encodebin->use_venc_queue)
2473 gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2475 pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2476 gst_pad_unlink(pad, muxpad);
2477 gst_object_unref(pad);
2480 if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2482 g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id );
2486 if(encodebin->video_encode_queue)
2488 gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue);
2490 pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src");
2491 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2492 gst_object_unref(pad);
2495 if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) )
2497 g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id );
2503 pad = gst_element_get_static_pad (encodebin->video_encode, "src");
2504 gst_pad_unlink(pad, encodebin->mux_video_sinkpad);
2505 gst_object_unref(pad);
2509 gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad);
2510 // gst_object_unref(encodebin->mux_video_sinkpad); //***
2511 encodebin->mux_video_sinkpad = NULL;
2514 if(encodebin->vsink_probeid)
2516 pad = gst_element_get_static_pad (encodebin->video_queue, "sink");
2517 gst_pad_remove_buffer_probe(pad, encodebin->vsink_probeid);
2518 encodebin->vsink_probeid = 0;
2519 gst_object_unref(pad);
2524 if(encodebin->vsink_hs_probeid)
2526 pad = gst_element_get_static_pad (encodebin->video_encode, "sink");
2527 gst_pad_remove_buffer_probe(pad, encodebin->vsink_hs_probeid);
2528 encodebin->vsink_hs_probeid = 0;
2529 gst_object_unref(pad);
2533 if(encodebin->audio_queue == NULL)
2537 case GST_ENCODE_BIN_PROFILE_AUDIO :
2538 if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) {
2539 if (!encodebin->auto_audio_convert) {
2540 gst_element_unlink_many (
2541 encodebin->audio_queue,
2542 encodebin->audio_sample,
2543 encodebin->acapsfilter,
2544 encodebin->audio_encode,
2546 } else if (!encodebin->auto_audio_resample) {
2547 gst_element_unlink_many (
2548 encodebin->audio_queue,
2549 encodebin->audio_conv,
2550 encodebin->acapsfilter,
2551 encodebin->audio_encode,
2554 gst_element_unlink_many (
2555 encodebin->audio_queue,
2556 encodebin->audio_conv,
2557 encodebin->audio_sample,
2558 encodebin->acapsfilter,
2559 encodebin->audio_encode,
2564 gst_element_unlink_many (
2565 encodebin->audio_queue,
2566 encodebin->acapsfilter,
2567 encodebin->audio_encode,
2571 if(encodebin->mux_audio_sinkpad != NULL)
2574 if(encodebin->use_aenc_queue)
2576 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2578 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2579 gst_pad_unlink(pad, muxpad);
2580 gst_object_unref(pad);
2583 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2585 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2589 if(encodebin->audio_encode_queue)
2591 gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue);
2593 pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src");
2594 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2595 gst_object_unref(pad);
2598 if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) )
2600 g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id );
2606 pad = gst_element_get_static_pad (encodebin->audio_encode, "src");
2607 gst_pad_unlink(pad, encodebin->mux_audio_sinkpad);
2608 gst_object_unref(pad);
2612 gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad);
2613 // gst_object_unref(encodebin->mux_audio_sinkpad); //***
2614 encodebin->mux_audio_sinkpad = NULL;
2617 if(encodebin->asink_probeid)
2619 pad = gst_element_get_static_pad (encodebin->audio_queue, "sink");
2620 gst_pad_remove_buffer_probe(pad, encodebin->asink_probeid);
2621 encodebin->asink_probeid =0;
2622 gst_object_unref(pad);
2627 case GST_ENCODE_BIN_PROFILE_IMAGE :
2628 if (encodebin->auto_color_space) {
2629 gst_element_unlink_many (
2630 encodebin->image_queue,
2631 encodebin->image_toggle,
2632 encodebin->color_space,
2633 encodebin->icapsfilter,
2634 encodebin->image_encode,
2638 gst_element_unlink_many (
2639 encodebin->image_queue,
2640 encodebin->image_toggle,
2641 encodebin->icapsfilter,
2642 encodebin->image_encode,
2647 GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile);
2651 // gst_pad_set_active(encodebin->srcpad, TRUE);
2657 gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data)
2659 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2661 if(encodebin->profile != GST_ENCODE_BIN_PROFILE_AV)
2664 if(encodebin->video_queue == NULL) {
2665 encodebin->video_queue = gst_element_factory_make ("queue","video_queue");
2666 gst_bin_add (GST_BIN (element), encodebin->video_queue);
2669 if( encodebin->use_video_toggle )
2671 if( encodebin->video_toggle == NULL )
2673 encodebin->video_toggle = gst_element_factory_make ("toggle","video_toggle");
2674 gst_bin_add (GST_BIN (element), encodebin->video_toggle);
2676 GST_INFO_OBJECT( encodebin, "Video toggle is Enabled" );
2680 GST_INFO_OBJECT( encodebin, "Video toggle is Disabled" );
2683 if(encodebin->vcapsfilter == NULL) {
2684 encodebin->vcapsfilter = gst_element_factory_make ("capsfilter","vcapsfilter");
2685 gst_bin_add (GST_BIN (element), encodebin->vcapsfilter);
2688 encodebin->vcaps = gst_caps_new_simple("video/x-raw-yuv",
2689 "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
2690 "width", G_TYPE_INT, 320,
2691 "height", G_TYPE_INT, 240,
2692 "framerate", GST_TYPE_FRACTION, 30, 1,
2696 if(encodebin->video_encode == NULL) {
2697 encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode");
2698 gst_bin_add (GST_BIN (element), encodebin->video_encode);
2702 if(encodebin->video_encode_queue == NULL) {
2703 encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue");
2704 gst_bin_add (GST_BIN (element), encodebin->video_encode_queue);
2707 g_object_set(G_OBJECT(encodebin->video_encode_queue), "max-size-bytes", (unsigned int)0, NULL);
2710 if(encodebin->mux == NULL) {
2711 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2712 gst_bin_add (GST_BIN (element), encodebin->mux);
2715 if (!encodebin->video_encode
2716 // || !encodebin->video_encode_queue
2718 || !encodebin->video_queue
2719 || !encodebin->vcapsfilter
2720 || !encodebin->srcpad )
2722 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2726 if( encodebin->use_video_toggle && !encodebin->video_toggle )
2728 GST_ERROR_OBJECT(encodebin, "Faild create video toggle element \n");
2733 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2734 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2735 gst_bin_add (GST_BIN (element), encodebin->color_space);
2742 gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data)
2744 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2746 if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO)
2749 if(encodebin->audio_queue == NULL) {
2750 encodebin->audio_queue = gst_element_factory_make ("queue","audio_queue");
2751 gst_bin_add (GST_BIN (element), encodebin->audio_queue);
2754 if(encodebin->acapsfilter == NULL) {
2755 encodebin->acapsfilter = gst_element_factory_make ("capsfilter","acapsfilter");
2756 gst_bin_add (GST_BIN (element), encodebin->acapsfilter);
2759 encodebin->acaps = gst_caps_new_simple("audio/x-raw-int",
2760 "rate", G_TYPE_INT, 8000,
2761 "channels", G_TYPE_INT, 2,
2762 "depth", G_TYPE_INT, 16,
2766 if(encodebin->audio_encode == NULL) {
2767 encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode");
2768 gst_bin_add (GST_BIN (element), encodebin->audio_encode);
2771 if(encodebin->mux == NULL) {
2772 encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux");
2773 gst_bin_add (GST_BIN (element), encodebin->mux);
2776 if (!encodebin->audio_encode
2777 || !encodebin->audio_queue
2779 || !encodebin->acapsfilter
2780 || !encodebin->srcpad )
2782 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2786 if (encodebin->auto_audio_convert && (encodebin->audio_conv == NULL)) {
2787 encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv");
2788 gst_bin_add (GST_BIN (element), encodebin->audio_conv);
2791 if (encodebin->auto_audio_resample && (encodebin->audio_sample == NULL)) {
2792 encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample");
2793 gst_bin_add (GST_BIN (element), encodebin->audio_sample);
2801 gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data)
2803 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
2805 if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE)
2808 if(encodebin->image_queue == NULL) {
2809 encodebin->image_queue = gst_element_factory_make ("queue","image_queue");
2810 gst_bin_add (GST_BIN (element), encodebin->image_queue);
2813 if(encodebin->image_toggle == NULL) {
2814 encodebin->image_toggle = gst_element_factory_make ("toggle","image_toggle");
2815 gst_bin_add (GST_BIN (element), encodebin->image_toggle);
2818 if(encodebin->icapsfilter == NULL) {
2819 encodebin->icapsfilter = gst_element_factory_make ("capsfilter","icapsfilter");
2820 gst_bin_add (GST_BIN (element), encodebin->icapsfilter);
2823 if(encodebin->image_encode == NULL) {
2824 encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode");
2825 gst_bin_add (GST_BIN (element), encodebin->image_encode);
2828 if (!encodebin->image_encode
2829 || !encodebin->image_queue
2830 || !encodebin->image_toggle
2831 || !encodebin->icapsfilter
2832 || !encodebin->srcpad )
2834 GST_ERROR_OBJECT(encodebin, "Faild create element \n");
2838 if (encodebin->auto_color_space && (encodebin->color_space == NULL)) {
2839 encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space");
2840 gst_bin_add (GST_BIN (element), encodebin->color_space);
2846 static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value)
2849 if(value) { //block stream
2850 switch(encodebin->profile) {
2851 case GST_ENCODE_BIN_PROFILE_AV:
2852 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2855 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2856 "empty-buffers") == NULL) {
2857 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2860 if( encodebin->video_toggle )
2862 g_object_set(encodebin->video_toggle, "block-data", TRUE , NULL);
2863 GST_INFO_OBJECT( encodebin, "video_toggle block-data TRUE" );
2866 g_object_set(encodebin->video_queue, "empty-buffers", TRUE , NULL);
2867 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers TRUE" );
2868 if(encodebin->audio_queue != NULL)
2870 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2871 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2875 case GST_ENCODE_BIN_PROFILE_AUDIO:
2876 if(encodebin->audio_queue == NULL) {
2879 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2880 "empty-buffers") == NULL) {
2881 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2884 g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL);
2885 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" );
2888 case GST_ENCODE_BIN_PROFILE_IMAGE:
2889 if(encodebin->image_toggle == NULL) {
2892 g_object_set(encodebin->image_toggle, "block_data", TRUE, NULL);
2893 GST_INFO_OBJECT( encodebin, "image_toggle block_data TRUE" );
2897 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2901 } else { //release blocked-stream
2902 switch(encodebin->profile) {
2903 case GST_ENCODE_BIN_PROFILE_AV:
2904 if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) {
2907 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)),
2908 "empty-buffers") == NULL) {
2909 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2912 if( encodebin->video_toggle )
2914 g_object_set(encodebin->video_toggle, "block-data", FALSE , NULL);
2915 GST_INFO_OBJECT( encodebin, "video_toggle block-data FALSE" );
2918 if(encodebin->audio_queue != NULL)
2920 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2921 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2923 g_object_set(encodebin->video_queue, "empty-buffers", FALSE , NULL);
2924 GST_INFO_OBJECT( encodebin, "video_queue empty-buffers FALSE" );
2927 case GST_ENCODE_BIN_PROFILE_AUDIO:
2928 if(encodebin->audio_queue == NULL) {
2931 if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)),
2932 "empty-buffers") == NULL) {
2933 GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property");
2936 g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL);
2937 GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" );
2940 case GST_ENCODE_BIN_PROFILE_IMAGE:
2941 if(encodebin->image_toggle == NULL) {
2944 g_object_set(encodebin->image_toggle, "block_data", FALSE, NULL);
2945 GST_INFO_OBJECT( encodebin, "image_toggle block_data FALSE" );
2949 GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile);
2954 encodebin->block = value;
2958 GST_ERROR_OBJECT(encodebin, "encodebin block failed");
2962 GST_ERROR_OBJECT(encodebin, "encodebin unblock failed");
2966 static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value)
2968 GstClock *clock = NULL;
2972 //Block src of encode bin
2973 if (!gst_encode_bin_block(encodebin, TRUE))
2975 GST_WARNING_OBJECT (encodebin, "Fail to block Encodebin.");
2979 if (encodebin->paused_time == 0)
2982 if (clock = GST_ELEMENT_CLOCK(encodebin)) //before PLAYING, this would be NULL. Need to check.
2984 GstClockTime current_time, base_time;
2986 current_time = gst_clock_get_time(clock);
2987 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
2989 encodebin->paused_time = current_time - base_time;
2991 GST_INFO_OBJECT (encodebin, "Encodebin is in running-pause at [%"GST_TIME_FORMAT"]."
2992 , GST_TIME_ARGS(encodebin->paused_time));
2996 encodebin->paused_time = 0;
2997 encodebin->total_offset_time = 0;
2999 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3002 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3003 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE);
3007 /* release paused-stream*/
3008 if (encodebin->paused_time != 0)
3010 if (clock = GST_ELEMENT_CLOCK(encodebin))
3012 GstClockTime current_time, base_time;
3013 GstClockTime paused_gap;
3015 current_time = gst_clock_get_time(clock);
3016 base_time = gst_element_get_base_time(GST_ELEMENT(encodebin));
3017 paused_gap = current_time - base_time - encodebin->paused_time;
3019 encodebin->total_offset_time += paused_gap;
3020 encodebin->paused_time = 0;
3022 GST_INFO_OBJECT (encodebin, "Encodebin now resumes. Offset delay [%"GST_TIME_FORMAT"], Total offset delay [%"GST_TIME_FORMAT"]"
3023 , GST_TIME_ARGS(paused_gap) , GST_TIME_ARGS(encodebin->total_offset_time));
3027 encodebin->paused_time = 0;
3028 encodebin->total_offset_time = 0;
3030 GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin.");
3034 //TODO : How about qos?
3036 //Unblock src of encode bin
3037 if (!gst_encode_bin_block(encodebin, FALSE))
3039 GST_WARNING_OBJECT (encodebin, "Fail to Unblock Encodebin.");
3042 #if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE
3043 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE);
3046 encodebin->pause = value;
3050 GST_WARNING_OBJECT (encodebin, "Fail to pause Encodebin");
3051 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3052 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, FALSE);
3057 GST_WARNING_OBJECT (encodebin, "Fail to resume Encodebin");
3058 #ifdef GST_ENCODE_BIN_SIGNAL_ENABLE
3059 g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, FALSE);
3065 gst_encode_bin_release_pipeline (GstElement *element,
3069 GstEncodeBin *encodebin = GST_ENCODE_BIN (element);
3071 gst_element_set_state (encodebin->audio_queue, GST_STATE_NULL);
3072 gst_element_set_state (encodebin->audio_encode, GST_STATE_NULL);
3073 gst_element_set_state (encodebin->video_queue, GST_STATE_NULL);
3074 gst_element_set_state (encodebin->video_encode, GST_STATE_NULL);
3075 gst_element_set_state (encodebin->mux, GST_STATE_NULL);
3077 if (encodebin->auto_video_scale) {
3078 gst_element_set_state (encodebin->video_scale, GST_STATE_NULL);
3079 gst_element_unlink (encodebin->video_queue, encodebin->video_scale);
3080 gst_element_unlink (encodebin->video_scale, encodebin->video_encode);
3081 gst_bin_remove (GST_BIN (element), encodebin->video_scale);
3083 encodebin->video_scale = NULL;
3085 gst_element_unlink (encodebin->video_queue, encodebin->video_encode);
3088 gst_pad_unlink (gst_element_get_pad (encodebin->audio_encode, "src"),
3089 encodebin->mux_audio_sinkpad);
3090 gst_pad_unlink (gst_element_get_pad (encodebin->video_encode, "src"),
3091 encodebin->mux_video_sinkpad);
3093 gst_bin_remove_many (GST_BIN (element),
3094 encodebin->audio_queue,
3095 encodebin->audio_encode,
3096 encodebin->video_queue,
3097 encodebin->video_encode,
3101 encodebin->audio_queue = NULL;
3102 encodebin->audio_encode = NULL;
3103 encodebin->video_queue = NULL;
3104 encodebin->video_encode = NULL;
3105 encodebin->mux = NULL;
3111 gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
3113 GstEncodeBin *encodebin;
3114 GstStructure *structure;
3115 // const gchar *mimetype;
3116 // const GValue *codec_data;
3117 gint channels, rate;
3119 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3121 structure = gst_caps_get_structure (vscaps, 0);
3122 // mimetype = gst_structure_get_name (structure);
3124 /* we want these for all */
3125 if (!gst_structure_get_int (structure, "channels", &channels) ||
3126 !gst_structure_get_int (structure, "rate", &rate)) {
3130 // codec_data = gst_structure_get_value (structure, "codec_data");
3132 // g_return_val_if_fail (!strcmp (mimetype, "audio/x-raw-int"), FALSE);
3133 gst_object_unref (encodebin);
3138 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3139 gst_object_unref (encodebin);
3145 gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
3147 GstEncodeBin *encodebin;
3148 GstStructure *structure;
3149 // const gchar *mimetype;
3151 // const GValue *codec_data;
3154 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3156 structure = gst_caps_get_structure (vscaps, 0);
3157 // mimetype = gst_structure_get_name (structure);
3159 if (!gst_structure_get_int (structure, "width", &width) ||
3160 !gst_structure_get_int (structure, "height", &height)) {
3164 // codec_data = gst_structure_get_value (structure, "codec_data");
3166 fps = gst_structure_get_value (structure, "framerate");
3170 encodebin->fps = gst_value_get_fraction_numerator(fps);
3172 if(encodebin->high_speed_fps > 0)
3174 encodebin->multiple =(encodebin->high_speed_fps)/(encodebin->fps);
3180 gst_structure_get_fourcc (structure, "format", &format);
3183 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3185 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3190 // g_return_val_if_fail (!strcmp (mimetype, "video/x-raw-yuv"), FALSE);
3193 switch (encodebin->profile) {
3194 case GST_ENCODE_BIN_PROFILE_3GP:
3197 case GST_ENCODE_BIN_PROFILE_MP4:
3203 gst_object_unref (encodebin);
3208 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3209 gst_object_unref (encodebin);
3214 static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps)
3216 GstEncodeBin *encodebin;
3217 GstStructure *structure;
3218 // const gchar *mimetype;
3219 // const GValue *codec_data;
3222 encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad));
3224 structure = gst_caps_get_structure (vscaps, 0);
3225 // mimetype = gst_structure_get_name (structure);
3227 if (!gst_structure_get_int (structure, "width", &width) ||
3228 !gst_structure_get_int (structure, "height", &height)) {
3232 // codec_data = gst_structure_get_value (structure, "codec_data");
3237 gst_structure_get_fourcc (structure, "format", &format);
3240 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
3242 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
3246 gst_object_unref (encodebin);
3251 GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps);
3252 gst_object_unref (encodebin);
3259 gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3263 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3267 //Adjusting timestamp of video source
3268 GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3274 gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3278 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3282 GST_BUFFER_TIMESTAMP(buffer) *= encodebin->multiple;
3287 gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin)
3291 GST_WARNING_OBJECT (encodebin, "encodebin is Null.");
3295 //Adjusting timestamp of video source
3296 GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time;
3302 gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type)
3304 GstElementClass *elemclass = NULL;
3308 elemclass = GST_ELEMENT_GET_CLASS (mux);
3310 walk = gst_element_class_get_pad_template_list (elemclass);
3313 GstPadTemplate *templ;
3315 templ = (GstPadTemplate *) walk->data;
3316 if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SINK) {
3317 /* ENHANCE ME: Please add other specific mux's case */
3318 if (((type == ENCODEBIN_MUX_AUDIO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "audio")) || //audio, audio_%d,... ex)ffmux_3gp
3319 ((type == ENCODEBIN_MUX_VIDEO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "video")) || //video, video_%d,... ex)ffmux_3gp
3320 strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "sink") //sink, sink_%d, wavparse_sink, ... ex)oggmux, wavparse
3322 g_print("PRINT TEMPLATE(%s)\n", GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3323 pad = gst_element_get_request_pad (mux, GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3327 walk = g_list_next (walk);
3334 plugin_init (GstPlugin * plugin)
3336 GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin");
3339 GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
3341 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
3342 #endif /* ENABLE_NLS */
3344 return gst_element_register (plugin, "encodebin", GST_RANK_NONE,
3345 GST_TYPE_ENCODE_BIN);
3348 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
3352 plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/")