4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 /*=======================================================================================
24 =======================================================================================*/
25 #include "mm_streamrecorder_internal.h"
26 #include "mm_streamrecorder_video.h"
27 #include "mm_streamrecorder_gstcommon.h"
28 #include "mm_streamrecorder_recorder.h"
29 #include "mm_streamrecorder_util.h"
30 #include "mm_streamrecorder_buffer_manager.h"
31 #include "mm_streamrecorder_fileinfo.h"
32 #include "mm_streamrecorder_attribute.h"
35 #include <gst/base/gstadapter.h>
36 #include <gst/app/gstappsrc.h>
37 #include <gst/app/gstappsink.h>
40 /*---------------------------------------------------------------------------------------
41 | GLOBAL VARIABLE DEFINITIONS for internal |
42 ---------------------------------------------------------------------------------------*/
44 /*---------------------------------------------------------------------------------------
45 | LOCAL VARIABLE DEFINITIONS for internal |
46 ---------------------------------------------------------------------------------------*/
48 /*-----------------------------------------------------------------------
49 | GLOBAL VARIABLE DEFINITIONS for internal |
50 -----------------------------------------------------------------------*/
52 /*---------------------------------------------------------------------------------------
53 | LOCAL FUNCTION PROTOTYPES: |
54 ---------------------------------------------------------------------------------------*/
55 /* STATIC INTERNAL FUNCTION */
57 /*=======================================================================================
58 | FUNCTION DEFINITIONS |
59 =======================================================================================*/
60 /*---------------------------------------------------------------------------------------
61 | GLOBAL FUNCTION DEFINITIONS: |
62 ---------------------------------------------------------------------------------------*/
63 int _mmstreamrecorder_create_pipeline(MMHandleType handle)
65 int ret = MM_ERROR_NONE;
66 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
67 _MMStreamRecorderSubContext *sc = NULL;
68 GstElement *pipeline = NULL;
70 _mmstreamrec_dbg_log("handle : %x", handle);
72 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
74 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
75 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
78 ret = _mmstreamrecorder_create_recorder_pipeline(handle);
80 pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
82 ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
84 _mmstreamrec_dbg_log("ret[%x]", ret);
88 void _mmstreamrecorder_destroy_pipeline(MMHandleType handle)
90 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
91 _MMStreamRecorderSubContext *sc = NULL;
94 _MMStreamRecorderGstElement *element = NULL;
97 mmf_return_if_fail(hstreamrecorder);
99 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
100 mmf_return_if_fail(sc);
102 _mmstreamrec_dbg_log("");
104 element = sc->encode_element;
105 element_num = sc->encode_element_num;
106 if (element == NULL) {
107 _mmstreamrec_dbg_log("encode element is null!!");
111 if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
112 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
114 _mmstreamrec_dbg_log("Pipeline clear!!");
116 /* Remove pipeline message callback */
117 if (hstreamrecorder->pipeline_cb_event_id != 0) {
118 g_source_remove(hstreamrecorder->pipeline_cb_event_id);
119 hstreamrecorder->pipeline_cb_event_id = 0;
122 /* Remove remained message in bus */
124 GstMessage *gst_msg = NULL;
125 while ((gst_msg = gst_bus_pop(bus)) != NULL) {
126 _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
127 gst_message_unref(gst_msg);
130 gst_object_unref(bus);
134 /* Inside each pipeline destroy function, Set GST_STATE_NULL to Main pipeline */
135 _mmstreamrecorder_destroy_recorder_pipeline(handle);
138 if (element != NULL) {
139 /* checking unreleased element */
140 for (i = 0; i < element_num; i++) {
141 if (element[i].gst) {
142 if (GST_IS_ELEMENT(element[i].gst)) {
143 _mmstreamrec_dbg_warn("Still alive element - ID[%d], name [%s], ref count[%d], status[%s]", element[i].id, GST_OBJECT_NAME(element[i].gst), GST_OBJECT_REFCOUNT(element[i].gst), gst_element_state_get_name(GST_STATE(element[i].gst)));
144 g_object_weak_unref(G_OBJECT(element[i].gst), (GWeakNotify) _mmstreamrecorder_element_release_noti, sc);
146 _mmstreamrec_dbg_warn("The element[%d] is still aliving, check it", element[i].id);
149 element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
150 element[i].gst = NULL;
157 int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle)
160 int err = MM_ERROR_NONE;
161 int audio_enable = FALSE;
163 GstPad *srcpad = NULL;
164 GstPad *sinkpad = NULL;
166 unsigned int video_codec = MM_VIDEO_CODEC_INVALID;
167 unsigned int file_format = MM_FILE_FORMAT_INVALID;
168 char *err_name = NULL;
170 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
171 _MMStreamRecorderSubContext *sc = NULL;
173 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
175 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
176 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
178 _mmstreamrec_dbg_warn("start");
180 err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, NULL);
181 if (err != MM_ERROR_NONE) {
182 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
187 err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format);
188 if (err != MM_ERROR_NONE)
192 _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
194 /* get audio disable */
195 mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL);
196 sc->audio_enable = audio_enable;
198 _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable);
200 if (sc->audio_enable == TRUE) {
201 /* create audiosrc bin */
202 err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder);
203 if (err != MM_ERROR_NONE)
207 err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO);
208 if (err != MM_ERROR_NONE)
211 if (sc->audio_enable == TRUE) {
212 gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
215 /* add element and encodesink bin to encode main pipeline */
216 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL);
218 /* Link each element : appsrc - capsfilter - encodesink bin */
219 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
220 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink");
221 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
223 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src");
224 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0");
225 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
227 if (sc->audio_enable == TRUE) {
228 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
229 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
230 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
233 if (sc->audio_enable == TRUE) {
234 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink");
235 MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder);
236 gst_object_unref(sinkpad);
239 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) {
240 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src");
241 MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
242 gst_object_unref(srcpad);
247 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) {
248 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src");
249 MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
250 gst_object_unref(srcpad);
254 if (sc->audio_enable == FALSE) {
255 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink");
256 MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder);
257 gst_object_unref(sinkpad);
261 if (!strcmp(/*gst_element_rsink_name */"filesink", "filesink")) {
262 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
263 MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_record, hstreamrecorder);
264 gst_object_unref(srcpad);
267 if (sc->audio_enable == TRUE) {
268 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
269 MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audio_dataprobe_check, hstreamrecorder);
270 gst_object_unref(srcpad);
275 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
277 /* register pipeline message callback */
278 hstreamrecorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
280 gst_object_unref(bus);
283 return MM_ERROR_NONE;
285 pipeline_creation_error:
286 for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++) {
287 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, i);
289 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
293 int _mmstreamrecorder_destroy_recorder_pipeline(MMHandleType handle)
295 int ret = MM_ERROR_NONE;
296 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
297 _MMStreamRecorderSubContext *sc = NULL;
301 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
302 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
303 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
305 _mmstreamrec_dbg_log("start");
307 if (!sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
308 _mmstreamrec_dbg_warn("pipeline is not existed.");
309 return MM_ERROR_NONE;
312 _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_VIDEOREC);
314 ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
315 if (ret != MM_ERROR_NONE) {
316 _mmstreamrec_dbg_err("Faile to change encode main pipeline [0x%x]", ret);
320 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
322 /* Remove remained message */
324 GstMessage *gst_msg = NULL;
325 while ((gst_msg = gst_bus_pop(bus)) != NULL) {
326 _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
327 gst_message_unref(gst_msg);
330 gst_object_unref(bus);
334 /* remove audio pipeline first */
335 ret = _mmstreamrecorder_destroy_audiosrc_bin(handle);
336 if (ret != MM_ERROR_NONE) {
337 _mmstreamrec_dbg_err("Fail to remove audio pipeline");
341 ret = _mmstreamrecorder_destroy_encodesink_bin(handle);
342 if (ret != MM_ERROR_NONE) {
343 _mmstreamrec_dbg_err("Fail to remove encoder pipeline");
347 /* Remove pipeline message callback */
348 if (hstreamrecorder->encode_pipeline_cb_event_id != 0) {
349 g_source_remove(hstreamrecorder->encode_pipeline_cb_event_id);
350 hstreamrecorder->encode_pipeline_cb_event_id = 0;
353 _mmstreamrec_dbg_log("done");
358 int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorderEncodebinProfile profile)
360 int err = MM_ERROR_NONE;
368 int video_height = 0;
371 int audio_src_format = 0;
372 int video_src_format = 0;
373 int audio_samplerate = 0;
374 const char *str_profile = NULL;
375 const char *str_aac = NULL;
376 const char *str_aar = NULL;
377 const char *str_acs = NULL;
378 char *err_name = NULL;
380 GstCaps *caps = NULL;
382 GList *element_list = NULL;
383 char *temp_filename = NULL;
390 _MMStreamRecorderVideoInfo *info = NULL;
391 _MMStreamRecorderFileInfo *finfo = NULL;
393 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
394 _MMStreamRecorderSubContext *sc = NULL;
395 /* type_element *VideoencElement = NULL; */
396 /* type_element *AudioencElement = NULL; */
397 /* type_element *MuxElement = NULL; */
398 /* type_element *RecordsinkElement = NULL; */
400 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
402 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
403 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
405 _mmstreamrec_dbg_log("start - profile : %d", profile);
407 info = sc->info_video;
408 finfo = sc->info_file;
410 /* check element availability */
411 mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &audio_enc, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_VIDEO_BITRATE, &v_bitrate, MMSTR_VIDEO_ENCODER, &video_enc, MMSTR_AUDIO_BITRATE, &a_bitrate, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_FILE_FORMAT, &file_format, MMSTR_AUDIO_SAMPLERATE, &audio_samplerate, MMSTR_AUDIO_SOURCE_FORMAT, &audio_src_format, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_RECORDER_MODE, &rec_mode, NULL);
413 _mmstreamrec_dbg_err("audio encoder - %d , video encoder : %d", audio_enc, video_enc);
414 _mmstreamrec_dbg_err("audio channel - %d , video v_bitrate : %d", channel, v_bitrate);
415 _mmstreamrec_dbg_err("audio a_bitrate - %d , video video_width : %d ,video video_height : %d ", a_bitrate, video_width, video_height);
416 _mmstreamrec_dbg_err("video_fps - %d , video file_format : %d", video_fps, file_format);
418 /* Check existence */
419 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst) {
420 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst)->ref_count > 0)
421 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst);
423 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_ENCSINK_BIN is Already existed.");
426 /* Create bin element */
427 _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN, "encodesink_bin", err);
429 /* Create child element */
430 if (hstreamrecorder->ini.encsink_bin_profile != MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
431 /* create appsrc and capsfilter */
432 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC, hstreamrecorder->ini.name_of_encsink_src, "encodesink_src", element_list, err);
433 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT, "capsfilter", "encodesink_filter", element_list, err);
435 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
436 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "caps", caps);
438 gst_caps_unref(caps);
442 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
443 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "caps", caps);
445 gst_caps_unref(caps);
450 /* release element_list, they will be placed out of encodesink bin */
452 g_list_free(element_list);
455 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
456 /* set appsrc as live source */
457 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "is-live", hstreamrecorder->ini.encsink_src_islive);
462 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "encodebin", "encodesink_encbin", element_list, err);
464 _mmstreamrec_dbg_log("Profile[%d]", profile);
466 /* Set information */
467 if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
468 str_profile = "VideoProfile";
469 str_aac = "VideoAutoAudioConvert";
470 str_aar = "VideoAutoAudioResample";
471 str_acs = "VideoAutoColorSpace";
472 } else if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
473 str_profile = "AudioProfile";
474 str_aac = "AudioAutoAudioConvert";
475 str_aar = "AudioAutoAudioResample";
476 str_acs = "AudioAutoColorSpace";
479 /* TODO : check the last value ( set ) */
480 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "profile", hstreamrecorder->ini.encsink_bin_profile);
481 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
482 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", hstreamrecorder->ini.encsink_bin_auto_audio_convert);
484 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", hstreamrecorder->ini.encsink_bin_auto_audio_resample);
485 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
486 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", hstreamrecorder->ini.encsink_bin_use_video_toggle);
489 if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
491 case MM_VIDEO_CODEC_H263:
492 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h263_video_encoder);
494 case MM_VIDEO_CODEC_H264:
495 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
497 case MM_VIDEO_CODEC_MPEG4:
498 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.mpeg4_video_encoder);
501 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
504 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VENC, "video-encode", err);
505 /* _mmstreamrec_dbg_err(" hyuntae log = %p sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst = %p" ,sc, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst); */
508 /* set color converter size */
509 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vconv-name", hstreamrecorder->ini.name_of_encsink_bin_video_converter);
510 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VCONV, "video-convert", err);
512 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
514 if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12) {
515 video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_I420;
517 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
518 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vcaps", caps);
519 if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12) {
520 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VCONV].gst, "dst-buffer-num", hstreamrecorder->ini.convert_output_buffer_num);
523 err = gst_pad_set_caps(gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"), caps);
525 /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "state-tuning", TRUE); */
528 gst_caps_unref(caps);
531 _mmstreamrec_dbg_log("size %dx%d, dst-buffer-num %d", video_width, video_height, hstreamrecorder->ini.convert_output_buffer_num);
533 _mmstreamrec_dbg_warn("encoder set caps result : 0x%x", err);
535 if (hstreamrecorder->ini.encsink_bin_use_parser[0]) {
536 GstElement *parser = gst_element_factory_make(hstreamrecorder->ini.encsink_bin_use_parser, "parse");
537 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-venc-queue", parser);
538 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_PARSER, "use-venc-queue", err);
542 if (sc->audio_enable == TRUE) {
544 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "aenc-name", hstreamrecorder->ini.name_of_encsink_bin_audio_encoder);
545 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC, "audio-encode", err);
546 _mmstreamrec_dbg_err("audio-encode err = %x ", err);
548 /* Set basic infomation */
549 if (audio_enc != MM_AUDIO_CODEC_VORBIS) {
552 if (audio_src_format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
554 } else { /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
558 /* TODO : set rate , channel , depth */
560 caps = gst_set_audiosrcpad_caps(audio_samplerate, 2, depth, 16, 1);
561 /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE); */
562 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
564 gchar *type = gst_caps_to_string(caps);
566 _mmstreamrec_dbg_warn("Set srcpad caps: %s", type);
568 gst_caps_unref(caps);
571 /* what are the audio encoder which should get audio/x-raw-float? */
572 caps = gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, audio_samplerate, "channels", G_TYPE_INT, channel, "endianness", G_TYPE_INT, BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
573 _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", audio_samplerate, channel, BYTE_ORDER);
574 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
575 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
576 gst_caps_unref(caps);
581 if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
582 caps = gst_caps_new_simple("audio/x-raw-int", "channels", G_TYPE_INT, 1, NULL);
583 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
584 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
585 gst_caps_unref(caps);
589 if (audio_enc == MM_AUDIO_CODEC_OGG) {
590 caps = gst_caps_new_simple("audio/x-raw-int", NULL);
591 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
592 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
593 gst_caps_unref(caps);
598 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
602 switch (file_format) {
603 case MM_FILE_FORMAT_3GP:{
604 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_3GPMUXER);
608 case MM_FILE_FORMAT_MP4:{
609 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
614 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
619 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_MUX, "mux", err);
623 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
624 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "async", 0);
626 err = mm_streamrecorder_get_attributes(handle, &err_name,
627 MMSTR_FILE_FORMAT, &fileformat, MMSTR_FILENAME, &temp_filename, &size,
628 MMSTR_TARGET_MAX_SIZE, &imax_size,
629 MMSTR_TARGET_TIME_LIMIT, &imax_time,
632 if (err != MM_ERROR_NONE) {
633 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
638 finfo->fileformat = fileformat;
642 info->max_size = 0; /* do not check */
644 info->max_size = ((guint64) imax_size) << 10; /* to byte */
648 info->max_time = 0; /* do not check */
650 info->max_time = ((guint64) imax_time) * 1000; /* to millisecond */
652 finfo->filename = strdup(temp_filename);
653 if (!finfo->filename) {
654 _mmstreamrec_dbg_err("strdup was failed");
658 _mmstreamrec_dbg_log("Record start : set file name using attribute - %s ", finfo->filename);
660 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
662 if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
663 /* video encoder attribute setting */
665 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
667 _mmstreamrec_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
671 if (sc->audio_enable == TRUE) {
672 /* audio encoder attribute setting */
675 case MM_AUDIO_CODEC_AMR:
676 result = _mmstreamrecorder_get_amrnb_bitrate_mode(a_bitrate);
677 _mmstreamrec_dbg_log("Set AMR encoder mode [%d]", result);
678 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "band-mode", result);
680 case MM_AUDIO_CODEC_AAC:
681 _mmstreamrec_dbg_log("Set AAC encoder bitrate [%d]", a_bitrate);
682 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
685 _mmstreamrec_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
689 _mmstreamrec_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
693 _mmstreamrec_dbg_log("Element creation complete");
695 /* Add element to bin */
696 if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst), element_list)) {
697 _mmstreamrec_dbg_err("element add error.");
698 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
699 goto pipeline_creation_error;
702 _mmstreamrec_dbg_log("Element add complete");
704 if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
705 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
706 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
707 gst_object_unref(pad);
709 _mmstreamrec_dbg_err("failed to create ghost video_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
710 err = MM_ERROR_STREAMRECORDER_GST_LINK;
711 goto pipeline_creation_error;
713 gst_object_unref(pad);
716 if (sc->audio_enable == TRUE) {
717 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
718 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
719 gst_object_unref(pad);
721 _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
722 err = MM_ERROR_STREAMRECORDER_GST_LINK;
723 goto pipeline_creation_error;
725 gst_object_unref(pad);
728 } else if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
729 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
730 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
731 gst_object_unref(pad);
733 _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
734 err = MM_ERROR_STREAMRECORDER_GST_LINK;
735 goto pipeline_creation_error;
737 gst_object_unref(pad);
741 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image");
742 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
743 gst_object_unref(pad);
745 _mmstreamrec_dbg_err("failed to create ghost image_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
746 err = MM_ERROR_STREAMRECORDER_GST_LINK;
747 goto pipeline_creation_error;
749 gst_object_unref(pad);
753 _mmstreamrec_dbg_log("Get pad complete");
755 /* Link internal element */
756 if (!_mmstreamrecorder_link_elements(element_list)) {
757 _mmstreamrec_dbg_err("element link error.");
758 err = MM_ERROR_STREAMRECORDER_GST_LINK;
759 goto pipeline_creation_error;
763 g_list_free(element_list);
767 _mmstreamrec_dbg_log("done");
769 return MM_ERROR_NONE;
771 pipeline_creation_error:
772 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN);
773 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC);
774 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT);
775 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_VENC);
776 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
777 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_IENC);
778 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_MUX);
779 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
780 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
783 g_list_free(element_list);
790 int _mmstreamrecorder_destroy_encodesink_bin(MMHandleType handle)
792 GstPad *reqpad = NULL;
793 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
794 _MMStreamRecorderSubContext *sc = NULL;
796 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
798 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
799 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
801 _mmstreamrec_dbg_log("");
803 if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
804 /* release request pad */
805 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
807 gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
808 gst_object_unref(reqpad);
812 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
814 gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
815 gst_object_unref(reqpad);
819 /* release encode main pipeline */
820 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
822 _mmstreamrec_dbg_log("Encoder pipeline removed");
825 return MM_ERROR_NONE;
828 int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle)
830 int err = MM_ERROR_NONE;
835 unsigned int a_enc = MM_AUDIO_CODEC_INVALID;
836 unsigned int file_format = MM_FILE_FORMAT_INVALID;
837 char *err_name = NULL;
840 GstCaps *caps = NULL;
842 GList *element_list = NULL;
844 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
845 _MMStreamRecorderSubContext *sc = NULL;
846 _MMStreamRecorderGstElement *last_element = NULL;
847 /* type_element *AudiosrcElement = NULL; */
849 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
851 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
852 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
854 _mmstreamrec_dbg_log("");
856 err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &a_enc, MMSTR_AUDIO_BITRATE, &val, MMSTR_AUDIO_SAMPLERATE, &rate, MMSTR_AUDIO_SOURCE_FORMAT, &format, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_FILE_FORMAT, &file_format, MMSTR_RECORDER_MODE, &rec_mode, NULL);
858 if (err != MM_ERROR_NONE) {
859 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
864 err = _mmstreamrecorder_check_audiocodec_fileformat_compatibility(a_enc, file_format);
865 if (err != MM_ERROR_NONE) {
866 _mmstreamrec_dbg_err("error name :%s , audio format %d , fileformat %d. error : %x)", err_name, a_enc, file_format, err);
871 /* Check existence */
872 if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst) {
873 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst)->ref_count > 0)
874 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
876 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_AUDIOSRC_BIN is Already existed. Unref once...");
879 /* Create bin element */
880 _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, "audiosource_bin", err);
882 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC, "appsrc", hstreamrecorder->ini.name_of_audio_src, element_list, err);
884 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err);
886 /* Set basic infomation */
887 if (a_enc != MM_AUDIO_CODEC_VORBIS) {
890 if (format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
892 } else { /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
896 caps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
898 _mmstreamrec_dbg_log("caps [x-raw-int, rate:%d, channel:%d, depth:%d]", rate, channel, depth);
900 /* what are the audio encoder which should get audio/x-raw-float? */
901 caps = gst_caps_new_simple("audio/x-raw-float", "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channel, "endianness", G_TYPE_INT, BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
902 _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", rate, channel, BYTE_ORDER);
906 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
907 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "caps", caps);
909 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_FILT].gst), "caps", caps);
911 gchar *type = gst_caps_to_string(caps);
913 _mmstreamrec_dbg_err("_MMSTREAMRECORDER_AUDIOSRC_FILT %s", type);
916 gst_caps_unref(caps);
919 _mmstreamrec_dbg_err("create caps error");
920 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
921 goto pipeline_creation_error;
924 if (rec_mode == MM_STREAMRECORDER_MODE_SCREENRECORD) {
926 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", TRUE);
927 #else /* speaker mode with alsasrc */
928 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "device", "hw:0,8");
929 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "latency-time", 256000);
930 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "buffer-time", 10000);
931 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
934 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
937 if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst), element_list)) {
938 _mmstreamrec_dbg_err("element add error.");
939 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
940 goto pipeline_creation_error;
943 if (!_mmstreamrecorder_link_elements(element_list)) {
944 _mmstreamrec_dbg_err("element link error.");
945 err = MM_ERROR_STREAMRECORDER_GST_LINK;
946 goto pipeline_creation_error;
949 last_element = (_MMStreamRecorderGstElement *) (g_list_last(element_list)->data);
950 pad = gst_element_get_static_pad(last_element->gst, "src");
951 if ((gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad))) < 0) {
952 gst_object_unref(pad);
954 _mmstreamrec_dbg_err("failed to create ghost pad on _MMSTREAMRECORDER_AUDIOSRC_BIN.");
955 err = MM_ERROR_STREAMRECORDER_GST_LINK;
956 goto pipeline_creation_error;
959 gst_object_unref(pad);
963 g_list_free(element_list);
967 return MM_ERROR_NONE;
969 pipeline_creation_error:
970 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC);
971 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT);
972 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN);
975 g_list_free(element_list);
982 int _mmstreamrecorder_destroy_audiosrc_bin(MMHandleType handle)
984 GstPad *srcpad = NULL;
985 GstPad *sinkpad = NULL;
986 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
987 _MMStreamRecorderSubContext *sc = NULL;
989 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
991 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
992 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
994 _mmstreamrec_dbg_log("");
996 if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst != NULL) {
997 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
998 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
999 _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad);
1001 /* release audiosrc bin */
1002 gst_bin_remove(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
1004 _mmstreamrecorder_remove_element_handle(handle, (void *)sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, _MMSTREAMRECORDER_AUDIOSRC_FILT);
1006 _mmstreamrec_dbg_log("Audio pipeline removed");
1009 return MM_ERROR_NONE;
1012 /* COMMAND - VIDEO */
1013 int _mmstreamrecorder_video_command(MMHandleType handle, int command)
1015 int ret = MM_ERROR_NONE;
1016 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1017 _MMStreamRecorderVideoInfo *info = NULL;
1018 _MMStreamRecorderAudioInfo *info_audio = NULL;
1019 _MMStreamRecorderFileInfo *finfo = NULL;
1020 _MMStreamRecorderSubContext *sc = NULL;
1021 GstElement *pipeline = NULL;
1025 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1027 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1028 mmf_return_val_if_fail(sc && sc->encode_element, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1030 mmf_return_val_if_fail(sc->info_video, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1031 if (sc->audio_enable == TRUE) {
1032 mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1034 mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1036 info = sc->info_video;
1037 if (sc->audio_enable == TRUE)
1038 info_audio = sc->info_audio;
1040 finfo = sc->info_file;
1042 _mmstreamrec_dbg_log("command %d", command);
1044 pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1047 case _MM_STREAMRECORDER_CMD_RECORD:
1051 _mmstreamrec_dbg_log("Record Start");
1052 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1054 /* Adjust display FPS */
1055 info->video_frame_count = 0;
1057 info_audio->audio_frame_count = 0;
1060 sc->ferror_send = FALSE;
1061 sc->ferror_count = 0;
1062 sc->error_occurs = FALSE;
1063 sc->bget_eos = FALSE;
1065 ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING);
1066 if (ret != MM_ERROR_NONE) {
1067 /* Remove recorder pipeline and recording file which size maybe zero */
1068 ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1070 if (finfo->filename) {
1071 _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1072 unlink(finfo->filename);
1073 g_free(finfo->filename);
1074 finfo->filename = NULL;
1076 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1081 case _MM_STREAMRECORDER_CMD_PAUSE:
1084 if (info->b_commiting) {
1085 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1086 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1089 for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1090 if (sc->audio_enable == FALSE) {
1091 /* check only video frame */
1092 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1094 } else if (count == hstreamrecorder->ini.retrial_count) {
1095 _mmstreamrec_dbg_err("Pause fail, frame count %" G_GUINT64_FORMAT "", info->video_frame_count);
1096 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1098 _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial[%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1101 usleep(hstreamrecorder->ini.video_frame_wait_time);
1103 /* check both of video and audio frame */
1104 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1106 } else if (count == hstreamrecorder->ini.retrial_count) {
1107 _mmstreamrec_dbg_err("Pause fail, frame count VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1108 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1110 _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count);
1113 usleep(hstreamrecorder->ini.video_frame_wait_time);
1117 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "runtime-pause", TRUE);
1122 case _MM_STREAMRECORDER_CMD_CANCEL:
1124 if (info->b_commiting) {
1125 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1126 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1129 ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1130 if (ret != MM_ERROR_NONE)
1131 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1133 /* remove target file */
1134 if (finfo->filename) {
1135 _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1136 unlink(finfo->filename);
1137 g_free(finfo->filename);
1138 finfo->filename = NULL;
1141 sc->isMaxsizePausing = FALSE;
1142 sc->isMaxtimePausing = FALSE;
1144 info->video_frame_count = 0;
1146 info_audio->audio_frame_count = 0;
1152 case _MM_STREAMRECORDER_CMD_COMMIT:
1153 /* video recording command */
1156 if (info->b_commiting) {
1157 _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command);
1158 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1160 _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
1161 info->b_commiting = TRUE;
1164 for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1165 if (sc->audio_enable == FALSE) {
1166 /* check only video frame */
1167 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1169 } else if (count == hstreamrecorder->ini.retrial_count) {
1170 _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count);
1171 info->b_commiting = FALSE;
1172 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1174 _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1177 usleep(hstreamrecorder->ini.video_frame_wait_time);
1179 /* check both of video and audio frame */
1180 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1182 } else if (count == hstreamrecorder->ini.retrial_count) {
1183 _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1185 info->b_commiting = FALSE;
1186 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1188 _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count);
1191 usleep(hstreamrecorder->ini.video_frame_wait_time);
1195 if (sc->error_occurs) {
1196 GstPad *video = NULL;
1197 GstPad *audio = NULL;
1199 _mmstreamrec_dbg_err("Committing Error case");
1201 video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink");
1202 ret = gst_pad_send_event(video, gst_event_new_eos());
1203 _mmstreamrec_dbg_err("Sending EOS video sink : %d", ret);
1204 gst_object_unref(video);
1206 video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
1207 gst_pad_push_event(video, gst_event_new_flush_start());
1208 gst_pad_push_event(video, gst_event_new_flush_stop(TRUE));
1209 ret = gst_pad_push_event(video, gst_event_new_eos());
1210 _mmstreamrec_dbg_err("Sending EOS video encoder src pad : %d", ret);
1211 gst_object_unref(video);
1213 if (sc->audio_enable == TRUE) {
1214 audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
1215 gst_pad_push_event(audio, gst_event_new_flush_start());
1216 gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE));
1217 ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1218 _mmstreamrec_dbg_err("Sending EOS audio encoder src pad : %d", ret);
1219 gst_object_unref(audio);
1222 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) {
1223 ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, gst_event_new_eos());
1224 _mmstreamrec_dbg_warn("send eos to appsrc result : %d", ret);
1227 if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) {
1228 pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1229 ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1230 gst_object_unref(pad);
1233 _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret);
1238 _mmstreamrec_dbg_log("Start to wait EOS");
1239 ret = _mmstreamrecorder_get_eos_message(handle);
1240 if (ret != MM_ERROR_NONE) {
1241 info->b_commiting = FALSE;
1242 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1247 ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
1250 return MM_ERROR_NONE;
1252 _ERR_STREAMRECORDER_VIDEO_COMMAND:
1253 if (ret != MM_ERROR_NONE)
1254 _mmstreamrec_dbg_err("Current Videosrc status");
1259 int _mmstreamrecorder_video_handle_eos(MMHandleType handle)
1261 int ret = MM_ERROR_NONE;
1263 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1264 _MMStreamRecorderSubContext *sc = NULL;
1265 _MMStreamRecorderVideoInfo *info = NULL;
1266 _MMStreamRecorderAudioInfo *info_audio = NULL;
1267 _MMStreamRecorderFileInfo *finfo = NULL;
1268 _MMStreamRecorderMsgItem msg;
1269 MMStreamRecordingReport *report = NULL;
1271 mmf_return_val_if_fail(hstreamrecorder, FALSE);
1273 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1274 mmf_return_val_if_fail(sc, FALSE);
1275 mmf_return_val_if_fail(sc->info_video, FALSE);
1276 if (sc->audio_enable == TRUE)
1277 mmf_return_val_if_fail(sc->info_audio, FALSE);
1279 mmf_return_val_if_fail(sc->info_file, FALSE);
1281 info = sc->info_video;
1282 if (sc->audio_enable == TRUE)
1283 info_audio = sc->info_audio;
1285 finfo = sc->info_file;
1287 _mmstreamrec_dbg_err("");
1289 /* remove blocking part */
1290 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1292 ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1293 if (ret != MM_ERROR_NONE)
1294 _mmstreamrec_dbg_warn("_mmstreamrecorder_destroy_recorder_pipeline failed. error[%x]", ret);
1296 /* Send recording report to application */
1297 msg.id = MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED;
1298 report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport));
1300 _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
1302 report->recording_filename = strdup(finfo->filename);
1303 msg.param.data = report;
1305 _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
1309 sc->pipeline_time = 0;
1311 sc->isMaxsizePausing = FALSE; /*In async function, this variable should set in callback function. */
1312 sc->isMaxtimePausing = FALSE;
1313 sc->error_occurs = FALSE;
1315 info->video_frame_count = 0;
1317 info_audio->audio_frame_count = 0;
1320 g_free(finfo->filename);
1321 finfo->filename = NULL;
1322 info->b_commiting = FALSE;
1324 _mmstreamrec_dbg_err("_mmstreamrecorder_video_handle_eos : end");
1331 int _mmstreamrecorder_create_audio_pipeline(MMHandleType handle)
1333 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1334 _MMStreamRecorderSubContext *sc = NULL;
1336 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1337 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1339 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1341 return _mmstreamrecorder_create_audiop_with_encodebin(handle);
1345 * This function destroy audio pipeline.
1347 * @param[in] handle Handle of streamrecorder.
1350 * @see _mmstreamrecorder_destroy_audio_pipeline()
1353 void _mmstreamrecorder_destroy_audio_pipeline(MMHandleType handle)
1355 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1356 _MMStreamRecorderSubContext *sc = NULL;
1357 _MMStreamRecorderAudioInfo *info = NULL;
1358 mmf_return_if_fail(hstreamrecorder);
1359 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1361 mmf_return_if_fail(sc && sc->info_audio);
1363 info = sc->info_audio;
1365 _mmstreamrec_dbg_log("start");
1367 if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
1368 _mmstreamrec_dbg_warn("release audio pipeline");
1370 _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
1372 _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL);
1374 if (info->bMuxing) {
1375 GstPad *reqpad = NULL;
1378 The ref_count of mux is always # of streams in here, i don't know why it happens.
1379 So, i unref the mux manually
1381 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
1382 gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
1383 gst_object_unref(reqpad);
1385 if (GST_IS_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) && GST_OBJECT_REFCOUNT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) > 1) {
1386 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst);
1389 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
1392 _mmstreamrec_dbg_log("done");
1397 int _mmstreamrecorder_create_audiop_with_encodebin(MMHandleType handle)
1399 int err = MM_ERROR_NONE;
1400 char *aenc_name = NULL;
1401 char *mux_name = NULL;
1402 char *err_name = NULL;
1406 GstPad *srcpad = NULL;
1407 GstPad *sinkpad = NULL;
1408 GList *element_list = NULL;
1410 _MMStreamRecorderAudioInfo *info = NULL;
1411 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1412 _MMStreamRecorderSubContext *sc = NULL;
1413 /* type_element *aenc_elem = NULL; */
1414 /* type_element *mux_elem = NULL; */
1416 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1417 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1419 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1420 mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1422 info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
1424 _mmstreamrec_dbg_log("");
1426 err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_RECORDER_MODE, &rec_mode, NULL);
1428 if (!mux_name || !strcmp(mux_name, "wavenc")) {
1429 /* IF MUX in not chosen then record in raw file */
1430 _mmstreamrec_dbg_log("Record without muxing.");
1431 info->bMuxing = FALSE;
1433 _mmstreamrec_dbg_log("Record with mux.");
1434 info->bMuxing = TRUE;
1437 /* Create GStreamer pipeline */
1438 _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
1440 err = _mmstreamrecorder_create_audiosrc_bin(handle);
1441 if (err != MM_ERROR_NONE)
1444 if (info->bMuxing) {
1445 /* Muxing. can use encodebin. */
1446 err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO);
1447 if (err != MM_ERROR_NONE)
1451 /* without muxing. can't use encodebin. */
1453 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE, "queue", NULL, element_list, err);
1455 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
1456 if (strcmp(hstreamrecorder->ini.name_of_encsink_bin_audio_encoder, "wavenc") != 0) {
1457 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV, "audioconvert", NULL, element_list, err);
1461 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC, aenc_name, NULL, element_list, err);
1463 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, hstreamrecorder->ini.name_of_encsink_sink, NULL, element_list, err);
1466 /* Add and link elements */
1467 if (info->bMuxing) {
1468 /* IF MUX is indicated create MUX */
1469 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL);
1471 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
1472 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
1473 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
1475 /* IF MUX in not chosen then record in raw amr file */
1476 if (!strcmp(aenc_name, "wavenc")) {
1477 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
1479 if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
1480 err = MM_ERROR_STREAMRECORDER_GST_LINK;
1481 goto pipeline_creation_error;
1484 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
1485 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
1487 if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
1488 err = MM_ERROR_STREAMRECORDER_GST_LINK;
1489 goto pipeline_creation_error;
1492 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL);
1494 if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) {
1495 err = MM_ERROR_STREAMRECORDER_GST_LINK;
1496 goto pipeline_creation_error;
1502 if (info->bMuxing) {
1503 MMSTREAMRECORDER_SIGNAL_CONNECT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, _MMSTREAMRECORDER_HANDLER_AUDIOREC, "pad-added", __mmstreamrecorder_audiorec_pad_added_cb, hstreamrecorder);
1505 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
1506 MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_AUDIOREC, __mmstreamrecorder_audio_dataprobe_record, hstreamrecorder);
1507 gst_object_unref(srcpad);
1511 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
1513 /* register message callback */
1514 hstreamrecorder->pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
1516 /* set sync callback */
1517 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, hstreamrecorder, NULL);
1519 gst_object_unref(bus);
1523 g_list_free(element_list);
1524 element_list = NULL;
1527 return MM_ERROR_NONE;
1529 pipeline_creation_error:
1530 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
1531 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN);
1532 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE);
1533 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
1534 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV);
1536 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
1537 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
1538 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
1541 g_list_free(element_list);
1542 element_list = NULL;
1548 int _mmstreamrecorder_audio_command(MMHandleType handle, int command)
1551 int ret = MM_ERROR_NONE;
1553 guint64 free_space = 0;
1554 guint64 cal_space = 0;
1555 char *dir_name = NULL;
1556 char *err_attr_name = NULL;
1560 GstElement *pipeline = NULL;
1561 GstElement *audioSrc = NULL;
1563 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1564 _MMStreamRecorderSubContext *sc = NULL;
1565 _MMStreamRecorderAudioInfo *info = NULL;
1566 _MMStreamRecorderFileInfo *finfo = NULL;
1568 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1569 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1571 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1572 mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1573 mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1574 pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1575 info = sc->info_audio;
1576 finfo = sc->info_file;
1578 _mmstreamrec_dbg_log("");
1580 pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1581 audioSrc = sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst;
1583 case _MM_STREAMRECORDER_CMD_RECORD:
1584 /* check status for resume case */
1586 guint imax_size = 0;
1587 guint imax_time = 0;
1588 char *temp_filename = NULL;
1590 if (sc->pipeline_time)
1591 gst_element_set_start_time((GstElement *) GST_PIPELINE(pipeline), sc->pipeline_time);
1593 sc->pipeline_time = hstreamrecorder->ini.reset_pause_time;
1595 ret = mm_streamrecorder_get_attributes(handle, &err_attr_name, MMSTR_TARGET_MAX_SIZE, &imax_size, MMSTR_TARGET_TIME_LIMIT, &imax_time, MMSTR_FILE_FORMAT, &(finfo->fileformat), MMSTR_FILENAME, &temp_filename, &size, NULL);
1596 if (ret != MM_ERROR_NONE) {
1597 _mmstreamrec_dbg_warn("failed to get attribute. (%s:%x)", err_attr_name, ret);
1598 SAFE_FREE(err_attr_name);
1599 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1602 finfo->filename = strdup(temp_filename);
1603 if (!finfo->filename) {
1604 _mmstreamrec_dbg_err("STRDUP was failed");
1605 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1608 _mmstreamrec_dbg_log("Record start : set file name using attribute - %s\n ", finfo->filename);
1610 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
1612 sc->ferror_send = FALSE;
1613 sc->ferror_count = 0;
1614 sc->bget_eos = FALSE;
1619 info->max_size = 0; /* do not check */
1621 info->max_size = ((guint64) imax_size) << 10; /* to byte */
1625 info->max_time = 0; /* do not check */
1627 info->max_time = ((guint64) imax_time) * 1000; /* to millisecond */
1629 /* TODO : check free space before recording start, need to more discussion */
1630 dir_name = g_path_get_dirname(finfo->filename);
1631 err = _mmstreamrecorder_get_freespace(dir_name, &free_space);
1633 _mmstreamrec_dbg_warn("current space for recording - %s : [%" G_GUINT64_FORMAT "]", dir_name, free_space);
1639 cal_space = (guint64)(hstreamrecorder->ini.audio_frame_minimum_space);
1640 cal_space = cal_space + (5 * 1024);
1641 if ((err == -1) || free_space <= cal_space) {
1642 _mmstreamrec_dbg_err("No more space for recording");
1643 return MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE;
1647 ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1648 if (ret != MM_ERROR_NONE)
1649 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1653 case _MM_STREAMRECORDER_CMD_PAUSE:
1655 GstClock *l_clock = NULL;
1657 if (info->b_commiting) {
1658 _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
1659 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1662 for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1663 if (info->filesize > 0) {
1665 } else if (count == hstreamrecorder->ini.retrial_count) {
1666 _mmstreamrec_dbg_err("Pause fail, wait 200 ms, but file size is %lld", info->filesize);
1667 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1669 _mmstreamrec_dbg_warn("Wait for enough audio frame, retry count[%d], file size is %lld", count, info->filesize);
1671 usleep(hstreamrecorder->ini.audio_frame_wait_time);
1674 ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PAUSED);
1675 if (ret != MM_ERROR_NONE)
1676 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1678 /* FIXME: consider delay. */
1679 l_clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
1680 sc->pipeline_time = gst_clock_get_time(l_clock) - gst_element_get_base_time(GST_ELEMENT(pipeline));
1684 case _MM_STREAMRECORDER_CMD_CANCEL:
1685 if (info->b_commiting) {
1686 _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
1687 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1690 ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
1691 if (ret != MM_ERROR_NONE)
1692 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1694 if (info->bMuxing) {
1695 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1697 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
1700 _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, GST_STATE_NULL);
1702 sc->pipeline_time = 0;
1704 sc->isMaxsizePausing = FALSE;
1705 sc->isMaxtimePausing = FALSE;
1707 if (finfo->filename) {
1708 _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1709 unlink(finfo->filename);
1710 g_free(finfo->filename);
1711 finfo->filename = NULL;
1715 case _MM_STREAMRECORDER_CMD_COMMIT:
1718 _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT");
1720 if (info->b_commiting) {
1721 _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
1722 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1724 _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
1725 info->b_commiting = TRUE;
1728 for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1729 if (info->filesize > 0) {
1731 } else if (count == hstreamrecorder->ini.retrial_count) {
1732 _mmstreamrec_dbg_err("Commit fail, waited 200 ms, but file size is %lld", info->filesize);
1733 info->b_commiting = FALSE;
1734 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1736 _mmstreamrec_dbg_warn("Waiting for enough audio frame, re-count[%d], file size is %lld", count, info->filesize);
1738 usleep(hstreamrecorder->ini.audio_frame_wait_time);
1742 GstPad *pad = gst_element_get_static_pad(audioSrc, "src");
1743 ret = gst_element_send_event(audioSrc, gst_event_new_eos());
1744 gst_object_unref(pad);
1746 /* for pause -> commit case */
1747 /*if (_mmstreamrecorder_get_state((MMHandleType)hstreamrecorder) == MM_STREAMRECORDER_STATE_PAUSED) {
1748 ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1749 if (ret != MM_ERROR_NONE) {
1750 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1755 /* wait until finishing EOS */
1756 _mmstreamrec_dbg_log("Start to wait EOS");
1757 if ((ret = _mmstreamrecorder_get_eos_message(handle)) != MM_ERROR_NONE)
1758 goto _ERR_STREAMRECORDER_AUDIO_COMMAND;
1763 ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
1767 _ERR_STREAMRECORDER_AUDIO_COMMAND:
1771 int _mmstreamrecorder_audio_handle_eos(MMHandleType handle)
1773 int err = MM_ERROR_NONE;
1774 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1775 _MMStreamRecorderSubContext *sc = NULL;
1776 _MMStreamRecorderAudioInfo *info = NULL;
1777 _MMStreamRecorderFileInfo *finfo = NULL;
1778 GstElement *pipeline = NULL;
1779 _MMStreamRecorderMsgItem msg;
1780 MMStreamRecordingReport *report;
1782 mmf_return_val_if_fail(hstreamrecorder, FALSE);
1783 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1785 mmf_return_val_if_fail(sc, FALSE);
1786 mmf_return_val_if_fail(sc->info_audio, FALSE);
1787 mmf_return_val_if_fail(sc->info_file, FALSE);
1789 _mmstreamrec_dbg_err("");
1791 info = sc->info_audio;
1792 finfo = sc->info_file;
1794 pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1796 err = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
1798 if (err != MM_ERROR_NONE)
1799 _mmstreamrec_dbg_warn("Failed:_MM_STREAMRECORDER_CMD_COMMIT:GST_STATE_READY. err[%x]", err);
1801 /* Send recording report message to application */
1802 msg.id = MM_MESSAGE_STREAMRECORDER_AUDIO_CAPTURED;
1803 report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport));
1805 _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
1809 /* START TAG HERE */
1810 /* MM_AUDIO_CODEC_AAC + MM_FILE_FORMAT_MP4 */
1811 if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4)
1812 _mmstreamrecorder_audio_add_metadata_info_m4a(handle);
1815 report->recording_filename = strdup(finfo->filename);
1816 msg.param.data = report;
1818 _mmstreamrecorder_send_message(handle, &msg);
1820 if (info->bMuxing) {
1821 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1823 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
1826 _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_NULL);
1828 sc->pipeline_time = 0;
1830 sc->isMaxsizePausing = FALSE;
1831 sc->isMaxtimePausing = FALSE;
1833 g_free(finfo->filename);
1834 finfo->filename = NULL;
1836 _mmstreamrec_dbg_err("_MM_STREAMRECORDER_CMD_COMMIT : end");
1838 info->b_commiting = FALSE;
1843 int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
1845 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1846 _MMStreamRecorderSubContext *sc = NULL;
1847 GstPad *srcpad = NULL;
1848 GstCaps *srccaps = NULL;
1849 char *err_name = NULL;
1852 int video_width = 0;
1853 int video_height = 0;
1854 int ret = MM_ERROR_NONE;
1855 int video_source_format = 0;
1857 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1859 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1860 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1862 if (buffer == NULL || size == 0) {
1863 _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
1864 return MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
1867 _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
1869 /* check element availability */
1870 ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_VIDEO_SOURCE_FORMAT, &video_src, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_SOURCE_FORMAT, &video_source_format, NULL);
1872 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst) {
1874 /*_mmstreamrec_dbg_log("Buffer Push start , time stamp %ld",timestamp);*/
1875 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
1876 srccaps = gst_pad_get_current_caps(srcpad);
1877 srccaps = gst_set_videosrcpad_caps(video_src, video_width, video_height, video_fps, 1);
1878 gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps);
1879 /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/
1881 ret = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, buffer);
1883 _mmstreamrec_dbg_err("video gst_app_src_push_buffer %d", ret);
1884 ret = MM_ERROR_STREAMRECORDER_VIDEOBUFFER_PUSH;
1887 /* g_signal_emit_by_name(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "push-buffer", newbuf, &ret); */
1893 int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
1895 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1896 _MMStreamRecorderSubContext *sc = NULL;
1897 _MMStreamRecorderAudioInfo *info = NULL;
1898 GstFlowReturn err = GST_FLOW_OK;
1899 GstPad *srcpad = NULL;
1900 GstCaps *srccaps = NULL;
1905 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1907 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1908 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1910 info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
1911 mmf_return_val_if_fail(info, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1913 rate = info->iSamplingRate;
1914 depth = info->audio_encode_depth;
1915 channel = info->iChannels;
1917 /*_mmstreamrec_dbg_log("Audio Buffer Push start , time stamp %ld",timestamp); */
1919 if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst) {
1921 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1922 /* TODO : CHANNEL , WIDTH, DATATYPE */
1923 srccaps = gst_pad_get_current_caps(srcpad);
1924 srccaps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
1925 gst_base_src_set_caps(GST_BASE_SRC(srcpad), srccaps);
1927 err = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, buffer);
1930 _mmstreamrec_dbg_err("Audio gst_app_src_push_buffer %d", err);
1931 return MM_ERROR_STREAMRECORDER_AUDIOBUFFER_PUSH;
1935 return MM_ERROR_NONE;