replace 'gst_element_get_request_pad' to 'gst_element_request_pad_simple'
[platform/core/multimedia/libmm-streamrecorder.git] / src / mm_streamrecorder_recorder.c
1 /*
2  * libmm-streamrecorder
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 /*=======================================================================================
23 |  INCLUDE FILES                                                                        |
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"
33
34 #include <gst/gst.h>
35 #include <gst/base/gstadapter.h>
36 #include <gst/app/gstappsrc.h>
37 #include <gst/app/gstappsink.h>
38
39
40 /*---------------------------------------------------------------------------------------
41 |    GLOBAL VARIABLE DEFINITIONS for internal                                           |
42 ---------------------------------------------------------------------------------------*/
43
44 /*---------------------------------------------------------------------------------------
45 |    LOCAL VARIABLE DEFINITIONS for internal                                            |
46 ---------------------------------------------------------------------------------------*/
47
48 /*-----------------------------------------------------------------------
49 |    GLOBAL VARIABLE DEFINITIONS for internal                           |
50 -----------------------------------------------------------------------*/
51
52 /*---------------------------------------------------------------------------------------
53 |    LOCAL FUNCTION PROTOTYPES:                                                         |
54 ---------------------------------------------------------------------------------------*/
55 /* STATIC INTERNAL FUNCTION */
56
57 /*=======================================================================================
58 |  FUNCTION DEFINITIONS                                                                 |
59 =======================================================================================*/
60 /*---------------------------------------------------------------------------------------
61 |    GLOBAL FUNCTION DEFINITIONS:                                                       |
62 ---------------------------------------------------------------------------------------*/
63 int _mmstreamrecorder_create_pipeline(MMHandleType handle)
64 {
65         int ret = MM_ERROR_NONE;
66         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
67         _MMStreamRecorderSubContext *sc = NULL;
68         GstElement *pipeline = NULL;
69
70         _mmstreamrec_dbg_log("handle : %p", handle);
71
72         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
73
74         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
75         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
76
77         /* ENCODER MODE */
78         ret = _mmstreamrecorder_create_recorder_pipeline(handle);
79
80         pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
81
82         ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY);
83
84         _mmstreamrec_dbg_log("ret[%x]", ret);
85         return ret;
86 }
87
88 void _mmstreamrecorder_destroy_pipeline(MMHandleType handle)
89 {
90         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
91         _MMStreamRecorderSubContext *sc = NULL;
92         gint i = 0;
93         int element_num = 0;
94         _MMStreamRecorderGstElement *element = NULL;
95         GstBus *bus = NULL;
96
97         mmf_return_if_fail(hstreamrecorder);
98
99         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
100         mmf_return_if_fail(sc);
101
102         _mmstreamrec_dbg_log("");
103
104         element = sc->encode_element;
105         element_num = sc->encode_element_num;
106         if (element == NULL) {
107                 _mmstreamrec_dbg_log("encode element is null!!");
108                 return;
109         }
110
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));
113
114                 _mmstreamrec_dbg_log("Pipeline clear!!");
115
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;
120                 }
121
122                 /* Remove remained message in bus */
123                 if (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);
128                                 gst_msg = NULL;
129                         }
130                         gst_object_unref(bus);
131                         bus = NULL;
132                 }
133
134                 /* Inside each pipeline destroy function, Set GST_STATE_NULL to Main pipeline */
135                 _mmstreamrecorder_destroy_recorder_pipeline(handle);
136         }
137
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);
145                                 } else {
146                                         _mmstreamrec_dbg_warn("The element[%d] is still aliving, check it", element[i].id);
147                                 }
148
149                                 element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
150                                 element[i].gst = NULL;
151                         }
152                 }
153         }
154         return;
155 }
156
157 int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle)
158 {
159         int i = 0;
160         int err = MM_ERROR_NONE;
161         int rec_mode = 0;
162         int width = 0;
163         int height = 0;
164         int video_src_format = 0;
165         int frame_rate = 0;
166         int filename_size = 0;
167         gboolean audio_enable = FALSE;
168         GstBus *bus = NULL;
169         GstPad *srcpad = NULL;
170         GstPad *sinkpad = NULL;
171         GstCaps *caps = NULL;
172         GList *element_list = NULL;
173         GstStructure* pulse_property = NULL;
174         unsigned int video_codec = MM_VIDEO_CODEC_INVALID;
175         unsigned int file_format = MM_FILE_FORMAT_INVALID;
176         char *err_name = NULL;
177         char *filename = NULL;
178         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
179         _MMStreamRecorderSubContext *sc = NULL;
180
181         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
182
183         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
184         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
185
186         _mmstreamrec_dbg_warn("start");
187
188         err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, MMSTR_RECORDER_MODE, &rec_mode, NULL);
189         if (err != MM_ERROR_NONE) {
190                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
191                 SAFE_FREE(err_name);
192                 return err;
193         }
194
195         if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) {
196                 _mmstreamrec_dbg_log("Recording Mode [%d]", MM_STREAMRECORDER_MODE_STREAM_BUFFER);
197                 err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format);
198                 if (err != MM_ERROR_NONE)
199                         return err;
200
201                 /* Main pipeline */
202                 _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
203
204                 /* get audio disable */
205                 mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL);
206                 sc->audio_enable = audio_enable;
207
208                 _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable);
209
210                 if (sc->audio_enable == TRUE) {
211                         /* create audiosrc bin */
212                         err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder);
213                         if (err != MM_ERROR_NONE)
214                                 return err;
215                 }
216
217                 err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO);
218                 if (err != MM_ERROR_NONE)
219                         return err;
220
221                 if (sc->audio_enable == TRUE)
222                         gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
223
224                 /* add element and encodesink bin to encode main pipeline */
225                 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);
226
227                 /* Link each element : appsrc - capsfilter - encodesink bin */
228                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
229                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink");
230                 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
231
232                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src");
233                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0");
234                 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
235
236                 if (sc->audio_enable == TRUE) {
237                         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
238                         sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
239                         _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
240                 }
241
242                 if (sc->audio_enable == TRUE) {
243                         sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink");
244                         MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder);
245                         gst_object_unref(sinkpad);
246                         sinkpad = NULL;
247
248                         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) {
249                                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src");
250                                 MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
251                                 gst_object_unref(srcpad);
252                                 srcpad = NULL;
253                         }
254                 }
255
256                 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) {
257                         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src");
258                         MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
259                         gst_object_unref(srcpad);
260                         srcpad = NULL;
261                 }
262
263                 if (sc->audio_enable == FALSE) {
264                         sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink");
265                         MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder);
266                         gst_object_unref(sinkpad);
267                         sinkpad = NULL;
268                 }
269
270                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
271                 MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_record, hstreamrecorder);
272                 gst_object_unref(srcpad);
273                 srcpad = NULL;
274
275                 if (sc->audio_enable == TRUE) {
276                         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
277                         MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audio_dataprobe_check, hstreamrecorder);
278                         gst_object_unref(srcpad);
279                         srcpad = NULL;
280                 }
281         } else if (rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) {
282                 _mmstreamrec_dbg_log("Recording Mode [%d]", MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK);
283                 err = mm_streamrecorder_get_attributes(handle, NULL, MMSTR_VIDEO_RESOLUTION_WIDTH, &width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &height, MMSTR_AUDIO_ENABLE, &audio_enable, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_VIDEO_FRAMERATE, &frame_rate, MMSTR_FILENAME, &filename, &filename_size, NULL);
284                 _mmstreamrec_dbg_log("width [%d], height [%d], audio enable[%d], format [%d], framerate [%d] filename [%s]", width, height, audio_enable, video_src_format, frame_rate, filename);
285
286                 _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
287
288                 if (!hstreamrecorder->ini.hw_encoder_supported) {
289                         _mmstreamrec_dbg_log("Screen is recorded with SW encoder.");
290                         if (audio_enable) {
291                                 _mmstreamrec_dbg_log("Audio is enabled!");
292
293                                 /* Audio pipeline */
294                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_SRC, "pulsesrc", "audio_source", element_list, err);
295
296                                 pulse_property = gst_structure_new_from_string("props,media.role=loopback-mirroring");
297                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "stream-properties", pulse_property);
298                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "do-timestamp", true);
299                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "provide-clock", false);
300
301                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_CONV, "audioconvert", "audio_converter", element_list, err);
302                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_ENC, "avenc_aac", "audio_encoder", element_list, err);
303                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, "compliance", -2);
304
305                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_QUE, "queue", "audio_queue", element_list, err);
306
307                                 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
308                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst,
309                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst,
310                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst,
311                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst, NULL);
312                         }
313
314                         /* Video pipeline */
315                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_SRC, "waylandsrc", "video_source", element_list, err);
316                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CAPS, "capsfilter", "video_capsfilter", element_list, err);
317
318                         caps = gst_set_videosrcpad_caps_sw(MM_STREAMRECORDER_INPUT_FORMAT_BGRA, width, height, frame_rate, 1);
319                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, "caps", caps);
320                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CONV, "videoconvert", "video_conveter", element_list, err);
321                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_ENC, "avenc_mpeg4", "video_encoder", element_list, err);
322                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_QUE, "queue", "video_queue", element_list, err);
323
324                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_MUX, "avmux_mp4", "av_muxer", element_list, err);
325
326                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_SINK, "filesink", "av_sink", element_list, err);
327                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_SINK].gst, "location", filename);
328
329
330                         gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
331                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst,
332                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst,
333                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_CONV].gst,
334                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst,
335                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst, NULL);
336
337                         gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
338                                                                                 sc->encode_element[_MMSTREAMRECORDER_MUX].gst,
339                                                                                 sc->encode_element[_MMSTREAMRECORDER_SINK].gst, NULL);
340                         if (audio_enable) {
341                                 if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst),
342                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst),
343                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst),
344                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), NULL)) {
345                                                                 _mmstreamrec_dbg_log("AUDIO PIPELINE LINK MANY FAILED");
346                                 }
347
348                                 if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst),
349                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) {
350                                         _mmstreamrec_dbg_log("LINK BETWEEN AUDIO QUE AND MUX FAILED");
351                                 }
352                         }
353
354                         if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst),
355                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst),
356                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CONV].gst),
357                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst),
358                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), NULL)) {
359                                 _mmstreamrec_dbg_log("VIDEO PIPELINE LINK MANY FAILED");
360                         }
361
362                         if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst),
363                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) {
364                                 _mmstreamrec_dbg_log("LINK BETWEEN VIDEO QUE AND MUX FAILED");
365                         }
366
367                         if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst),
368                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_SINK].gst))) {
369                                 _mmstreamrec_dbg_log("LINK BETWEEN MUX AND SINK FAILED");
370                         }
371                 } else {
372                         _mmstreamrec_dbg_log("Screen is recorded with HW encoder.");
373                         if (audio_enable) {
374                                 _mmstreamrec_dbg_log("Audio is enabled!");
375
376                                 /* Audio pipeline */
377                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_SRC, "pulsesrc", "audio_source", element_list, err);
378
379                                 pulse_property = gst_structure_new_from_string("props,media.role=loopback-mirroring");
380                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "stream-properties", pulse_property);
381                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "do-timestamp", true);
382                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "provide-clock", false);
383
384                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_CONV, "audioconvert", "audio_converter", element_list, err);
385
386                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_ENC, "avenc_aac", "audio_encoder", element_list, err);
387                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, "compliance", -2);
388
389                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_QUE, "queue", "audio_queue", element_list, err);
390
391                                 gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
392                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst,
393                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst,
394                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst,
395                                                                                         sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst,
396                                                                                         sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst, NULL);
397                         }
398                         /* Video pipeline */
399                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_SRC, "waylandsrc", "video_source", element_list, err);
400
401                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CAPS, "capsfilter", "video_capsfilter", element_list, err);
402
403                         caps = gst_set_videosrcpad_caps_hw(hstreamrecorder->ini.video_codec_element_hw, width, height, frame_rate, 1);
404                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, "caps", caps);
405
406                         if (!g_strcmp0(hstreamrecorder->ini.video_codec_element_hw, "sprd")){
407                                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_ENC, "sprdenc_h264", "video_encoder", element_list, err);
408                         } else {
409                                 _mmstreamrec_dbg_warn("no matched hw codec element found.");
410                                 goto pipeline_creation_error;
411                         }
412
413                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_QUE, "queue", "video_queue", element_list, err);
414
415                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_MUX, "avmux_mp4", "av_muxer", element_list, err);
416
417                         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_SINK, "filesink", "av_sink", element_list, err);
418                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_SINK].gst, "location", filename);
419
420                         gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
421                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst,
422                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst,
423                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst,
424                                                                                 sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst, NULL);
425
426                         gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst),
427                                                                                 sc->encode_element[_MMSTREAMRECORDER_MUX].gst,
428                                                                                 sc->encode_element[_MMSTREAMRECORDER_SINK].gst, NULL);
429                         if (audio_enable) {
430                                 if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst),
431                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst),
432                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst),
433                                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), NULL)) {
434                                                                 _mmstreamrec_dbg_log("AUDIO PIPELINE LINK MANY FAILED");
435                                 }
436
437                                 if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst),
438                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) {
439                                         _mmstreamrec_dbg_log("LINK BETWEEN AUDIO QUE AND MUX FAILED");
440                                 }
441                         }
442
443                         if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst),
444                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst),
445                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst),
446                                                                                         GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), NULL)) {
447                                 _mmstreamrec_dbg_log("VIDEO PIPELINE LINK MANY FAILED");
448                         }
449
450                         if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst),
451                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) {
452                                 _mmstreamrec_dbg_log("LINK BETWEEN VIDEO QUE AND MUX FAILED");
453                         }
454
455                         if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst),
456                                                                                 GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_SINK].gst))) {
457                                 _mmstreamrec_dbg_log("LINK BETWEEN MUX AND SINK FAILED");
458                         }
459                 }
460         }
461
462         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
463
464         /* register pipeline message callback */
465         hstreamrecorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
466
467         gst_object_unref(bus);
468         bus = NULL;
469         return MM_ERROR_NONE;
470
471  pipeline_creation_error:
472         for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++)
473                 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, i);
474
475         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
476         return err;
477 }
478
479 int _mmstreamrecorder_destroy_recorder_pipeline(MMHandleType handle)
480 {
481         int ret = MM_ERROR_NONE;
482         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
483         _MMStreamRecorderSubContext *sc = NULL;
484
485         GstBus *bus = NULL;
486
487         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
488         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
489         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
490
491         _mmstreamrec_dbg_log("start");
492
493         if (!sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
494                 _mmstreamrec_dbg_warn("pipeline is not existed.");
495                 return MM_ERROR_NONE;
496         }
497
498         _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_VIDEOREC);
499
500         ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
501         if (ret != MM_ERROR_NONE) {
502                 _mmstreamrec_dbg_err("Faile to change encode main pipeline [0x%x]", ret);
503                 return ret;
504         }
505
506         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
507
508         /* Remove remained message */
509         if (bus) {
510                 GstMessage *gst_msg = NULL;
511                 while ((gst_msg = gst_bus_pop(bus)) != NULL) {
512                         _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
513                         gst_message_unref(gst_msg);
514                         gst_msg = NULL;
515                 }
516                 gst_object_unref(bus);
517                 bus = NULL;
518         }
519
520         /* remove audio pipeline first */
521         ret = _mmstreamrecorder_destroy_audiosrc_bin(handle);
522         if (ret != MM_ERROR_NONE) {
523                 _mmstreamrec_dbg_err("Fail to remove audio pipeline");
524                 return ret;
525         }
526
527         ret = _mmstreamrecorder_destroy_encodesink_bin(handle);
528         if (ret != MM_ERROR_NONE) {
529                 _mmstreamrec_dbg_err("Fail to remove encoder pipeline");
530                 return ret;
531         }
532
533         /* Remove pipeline message callback */
534         if (hstreamrecorder->encode_pipeline_cb_event_id != 0) {
535                 g_source_remove(hstreamrecorder->encode_pipeline_cb_event_id);
536                 hstreamrecorder->encode_pipeline_cb_event_id = 0;
537         }
538
539         _mmstreamrec_dbg_log("done");
540
541         return ret;
542 }
543
544 int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorderEncodebinProfile profile)
545 {
546         int err = MM_ERROR_NONE;
547         int result = 0;
548         int channel = 0;
549         int audio_enc = 0;
550         int video_enc = 0;
551         int v_bitrate = 0;
552         int a_bitrate = 0;
553         int video_width = 0;
554         int video_height = 0;
555         int video_fps = 0;
556         int file_format = 0;
557         int audio_src_format = 0;
558         int video_src_format = 0;
559         int audio_samplerate = 0;
560         const char *str_profile = NULL;
561         const char *str_aac = NULL;
562         const char *str_aar = NULL;
563         const char *str_acs = NULL;
564         char *err_name = NULL;
565         int ret = MM_ERROR_NONE;
566         GstCaps *caps = NULL;
567         GstPad *pad = NULL;
568         GList *element_list = NULL;
569         char *temp_filename = NULL;
570         int fileformat = 0;
571         int size = 0;
572         guint imax_size = 0;
573         guint imax_time = 0;
574         int rec_mode = 0;
575
576         _MMStreamRecorderVideoInfo *info = NULL;
577         _MMStreamRecorderFileInfo *finfo = NULL;
578
579         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
580         _MMStreamRecorderSubContext *sc = NULL;
581         /* type_element *VideoencElement = NULL; */
582         /* type_element *AudioencElement = NULL; */
583         /* type_element *MuxElement = NULL; */
584         /* type_element *RecordsinkElement = NULL; */
585
586         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
587
588         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
589         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
590
591         _mmstreamrec_dbg_log("start - profile : %d", profile);
592
593         info = sc->info_video;
594         finfo = sc->info_file;
595
596         /* check element availability */
597         ret = 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);
598         if (ret != MM_ERROR_NONE) {
599                 _mmstreamrec_dbg_err("Get attrs fail. (%s:%x)", err_name, ret);
600                 SAFE_FREE(err_name);
601                 return err;
602         }
603
604         _mmstreamrec_dbg_err("audio encoder - %d , video encoder : %d", audio_enc, video_enc);
605         _mmstreamrec_dbg_err("audio channel - %d , video v_bitrate : %d", channel, v_bitrate);
606         _mmstreamrec_dbg_err("audio a_bitrate - %d , video video_width : %d ,video video_height : %d ", a_bitrate, video_width, video_height);
607         _mmstreamrec_dbg_err("video_fps - %d , video file_format : %d", video_fps, file_format);
608
609         /* Check existence */
610         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst) {
611                 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst)->ref_count > 0)
612                         gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst);
613
614                 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_ENCSINK_BIN is Already existed.");
615         }
616
617         /* Create bin element */
618         _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN, "encodesink_bin", err);
619
620         /* Create child element */
621         if (hstreamrecorder->ini.encsink_bin_profile != MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
622                 /* create appsrc and capsfilter */
623                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC, hstreamrecorder->ini.name_of_encsink_src, "encodesink_src", element_list, err);
624                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT, "capsfilter", "encodesink_filter", element_list, err);
625
626                 caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1);
627                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "caps", caps);
628                 if (caps) {
629                         gst_caps_unref(caps);
630                         caps = NULL;
631                 }
632
633                 caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1);
634                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "caps", caps);
635                 if (caps) {
636                         gst_caps_unref(caps);
637                         caps = NULL;
638                 }
639
640
641                 /* release element_list, they will be placed out of encodesink bin */
642                 if (element_list) {
643                         g_list_free(element_list);
644                         element_list = NULL;
645                 }
646                 if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) {
647                         /* set appsrc as live source */
648                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "is-live", hstreamrecorder->ini.encsink_src_islive);
649                 }
650
651         }
652
653         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "tizenencodebin", "encodesink_encbin", element_list, err);
654
655         _mmstreamrec_dbg_log("Profile[%d]", profile);
656
657         /* Set information */
658         if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
659                 str_profile = "VideoProfile";
660                 str_aac = "VideoAutoAudioConvert";
661                 str_aar = "VideoAutoAudioResample";
662                 str_acs = "VideoAutoColorSpace";
663         } else if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
664                 str_profile = "AudioProfile";
665                 str_aac = "AudioAutoAudioConvert";
666                 str_aar = "AudioAutoAudioResample";
667                 str_acs = "AudioAutoColorSpace";
668         }
669
670         /* TODO : check the last value ( set ) */
671         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "profile", hstreamrecorder->ini.encsink_bin_profile);
672         if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER)
673                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", hstreamrecorder->ini.encsink_bin_auto_audio_convert);
674
675         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", hstreamrecorder->ini.encsink_bin_auto_audio_resample);
676         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
677         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", hstreamrecorder->ini.encsink_bin_use_video_toggle);
678
679         /* Codec */
680         if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
681                 switch (video_enc) {
682                 case MM_VIDEO_CODEC_H263:
683                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h263_video_encoder);
684                         break;
685                 case MM_VIDEO_CODEC_H264:
686                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
687                         break;
688                 case MM_VIDEO_CODEC_MPEG4:
689                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.mpeg4_video_encoder);
690                         break;
691                 default:
692                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
693                         break;
694                 }
695                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VENC, "video-encode", err);
696
697                 /* set color converter size */
698                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vconv-name", hstreamrecorder->ini.name_of_encsink_bin_video_converter);
699                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VCONV, "video-convert", err);
700
701                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
702
703                 if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12 ||
704                         video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV21)
705                         video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_I420;
706
707                 caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1);
708                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vcaps", caps);
709
710                 if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12 ||
711                         video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV21)
712                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VCONV].gst, "dst-buffer-num", hstreamrecorder->ini.convert_output_buffer_num);
713
714                 /* state tuning */
715                 err = gst_pad_set_caps(gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"), caps);
716                 err = MM_ERROR_NONE;
717                 /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "state-tuning", TRUE); */
718
719                 if (caps) {
720                         gst_caps_unref(caps);
721                         caps = NULL;
722                 }
723                 _mmstreamrec_dbg_log("size %dx%d, dst-buffer-num %d", video_width, video_height, hstreamrecorder->ini.convert_output_buffer_num);
724
725                 _mmstreamrec_dbg_warn("encoder set caps result : 0x%x", err);
726
727                 if (hstreamrecorder->ini.encsink_bin_use_parser[0]) {
728                         GstElement *parser = gst_element_factory_make(hstreamrecorder->ini.encsink_bin_use_parser, "parse");
729                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-venc-queue", parser);
730                         _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_PARSER, "use-venc-queue", err);
731                 }
732         }
733
734         if (sc->audio_enable == TRUE) {
735
736                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "aenc-name", hstreamrecorder->ini.name_of_encsink_bin_audio_encoder);
737                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC, "audio-encode", err);
738                 _mmstreamrec_dbg_err("audio-encode err = %x ", err);
739
740                 /* Set basic infomation */
741                 if (audio_enc != MM_AUDIO_CODEC_VORBIS) {
742                         int depth = 0;
743
744                         if (audio_src_format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
745                                 depth = 16;
746                         } else {                        /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
747                                 depth = 8;
748                         }
749
750                         /* TODO : set rate , channel , depth */
751
752                         caps = gst_set_audiosrcpad_caps(audio_samplerate, 2, depth, 16, 1);
753                         /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE); */
754                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
755                         {
756                                 gchar *type = gst_caps_to_string(caps);
757                                 _mmstreamrec_dbg_warn("Set srcpad caps: %s", type);
758                                 g_free(type);
759                         }
760                         gst_caps_unref(caps);
761                         caps = NULL;
762                 } else {
763                         /* what are the audio encoder which should get audio/x-raw-float? */
764                         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);
765                         _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", audio_samplerate, channel, BYTE_ORDER);
766                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
767                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
768                         gst_caps_unref(caps);
769                         caps = NULL;
770                 }
771
772 #if 0
773                 if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
774                         caps = gst_caps_new_simple("audio/x-raw-int", "channels", G_TYPE_INT, 1, NULL);
775                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
776                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
777                         gst_caps_unref(caps);
778                         caps = NULL;
779                 }
780
781                 if (audio_enc == MM_AUDIO_CODEC_OGG) {
782                         caps = gst_caps_new_simple("audio/x-raw-int", NULL);
783                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
784                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
785                         gst_caps_unref(caps);
786                         caps = NULL;
787                 }
788 #endif
789
790                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
791         }
792
793         /* Mux */
794         switch (file_format) {
795         case MM_FILE_FORMAT_3GP:{
796                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_3GPMUXER);
797                 }
798                 break;
799
800         case MM_FILE_FORMAT_MP4:{
801                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
802                 }
803                 break;
804
805         default:{
806                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
807                 }
808                 break;
809
810         }
811         _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_MUX, "mux", err);
812
813         /* Sink */
814         /* for recording */
815         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
816         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "async", 0);
817
818         err = mm_streamrecorder_get_attributes(handle, &err_name,
819                                                                                    MMSTR_FILE_FORMAT, &fileformat, MMSTR_FILENAME, &temp_filename, &size,
820                                                                                    MMSTR_TARGET_MAX_SIZE, &imax_size,
821                                                                                    MMSTR_TARGET_TIME_LIMIT, &imax_time,
822                                                                                    NULL);
823
824         if (err != MM_ERROR_NONE) {
825                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
826                 SAFE_FREE(err_name);
827                 return err;
828         }
829
830         finfo->fileformat = fileformat;
831
832         /* set max size */
833         if (imax_size <= 0)
834                 info->max_size = 0;             /* do not check */
835         else
836                 info->max_size = ((guint64) imax_size) << 10;   /* to byte */
837
838         /* set max time */
839         if (imax_time <= 0)
840                 info->max_time = 0;             /* do not check */
841         else
842                 info->max_time = ((guint64) imax_time) * 1000;  /* to millisecond */
843
844         finfo->filename = g_strdup(temp_filename);
845         if (!finfo->filename) {
846                 _mmstreamrec_dbg_err("strdup was failed");
847                 return err;
848         }
849
850         _mmstreamrec_dbg_log("Record start : set file name using attribute - %s ", finfo->filename);
851
852         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
853
854         if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
855                 /* video encoder attribute setting */
856                 if (v_bitrate > 0)
857                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
858                 else
859                         _mmstreamrec_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
860         }
861
862         if (sc->audio_enable == TRUE) {
863                 /* audio encoder attribute setting */
864                 if (a_bitrate > 0) {
865                         switch (audio_enc) {
866                         case MM_AUDIO_CODEC_AMR:
867                                 result = _mmstreamrecorder_get_amrnb_bitrate_mode(a_bitrate);
868                                 _mmstreamrec_dbg_log("Set AMR encoder mode [%d]", result);
869                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "band-mode", result);
870                                 break;
871                         case MM_AUDIO_CODEC_AAC:
872                                 _mmstreamrec_dbg_log("Set AAC encoder bitrate [%d]", a_bitrate);
873                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
874                                 break;
875                         default:
876                                 _mmstreamrec_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
877                                 break;
878                         }
879                 } else {
880                         _mmstreamrec_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
881                 }
882         }
883
884         _mmstreamrec_dbg_log("Element creation complete");
885
886         /* Add element to bin */
887         if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst), element_list)) {
888                 _mmstreamrec_dbg_err("element add error.");
889                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
890                 goto pipeline_creation_error;
891         }
892
893         _mmstreamrec_dbg_log("Element add complete");
894
895         if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
896                 pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
897                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
898                         gst_object_unref(pad);
899                         pad = NULL;
900                         _mmstreamrec_dbg_err("failed to create ghost video_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
901                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
902                         goto pipeline_creation_error;
903                 }
904                 gst_object_unref(pad);
905                 pad = NULL;
906
907                 if (sc->audio_enable == TRUE) {
908                         pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
909                         if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
910                                 gst_object_unref(pad);
911                                 pad = NULL;
912                                 _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
913                                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
914                                 goto pipeline_creation_error;
915                         }
916                         gst_object_unref(pad);
917                         pad = NULL;
918                 }
919         } else if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
920                 pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
921                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
922                         gst_object_unref(pad);
923                         pad = NULL;
924                         _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
925                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
926                         goto pipeline_creation_error;
927                 }
928                 gst_object_unref(pad);
929                 pad = NULL;
930         } else {
931                 /* for stillshot */
932                 pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image");
933                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
934                         gst_object_unref(pad);
935                         pad = NULL;
936                         _mmstreamrec_dbg_err("failed to create ghost image_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
937                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
938                         goto pipeline_creation_error;
939                 }
940                 gst_object_unref(pad);
941                 pad = NULL;
942         }
943
944         _mmstreamrec_dbg_log("Get pad complete");
945
946         /* Link internal element */
947         if (!_mmstreamrecorder_link_elements(element_list)) {
948                 _mmstreamrec_dbg_err("element link error.");
949                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
950                 goto pipeline_creation_error;
951         }
952
953         if (element_list) {
954                 g_list_free(element_list);
955                 element_list = NULL;
956         }
957
958         _mmstreamrec_dbg_log("done");
959
960         return MM_ERROR_NONE;
961
962 pipeline_creation_error:
963         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN);
964         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC);
965         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT);
966         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_VENC);
967         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
968         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_IENC);
969         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_MUX);
970         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
971         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
972
973         if (element_list) {
974                 g_list_free(element_list);
975                 element_list = NULL;
976         }
977
978         return err;
979 }
980
981 int _mmstreamrecorder_destroy_encodesink_bin(MMHandleType handle)
982 {
983         GstPad *reqpad = NULL;
984         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
985         _MMStreamRecorderSubContext *sc = NULL;
986
987         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
988
989         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
990         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
991
992         _mmstreamrec_dbg_log("");
993
994         if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
995                 /* release request pad */
996                 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
997                 if (reqpad) {
998                         gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
999                         gst_object_unref(reqpad);
1000                         reqpad = NULL;
1001                 }
1002
1003                 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
1004                 if (reqpad) {
1005                         gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
1006                         gst_object_unref(reqpad);
1007                         reqpad = NULL;
1008                 }
1009
1010                 /* release encode main pipeline */
1011                 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
1012
1013                 _mmstreamrec_dbg_log("Encoder pipeline removed");
1014         }
1015
1016         return MM_ERROR_NONE;
1017 }
1018
1019 int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle)
1020 {
1021         int err = MM_ERROR_NONE;
1022         int val = 0;
1023         int rate = 0;
1024         int format = 0;
1025         int channel = 0;
1026         unsigned int a_enc = MM_AUDIO_CODEC_INVALID;
1027         unsigned int file_format = MM_FILE_FORMAT_INVALID;
1028         char *err_name = NULL;
1029         int rec_mode = 0;
1030
1031         GstCaps *caps = NULL;
1032         GstPad *pad = NULL;
1033         GList *element_list = NULL;
1034
1035         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1036         _MMStreamRecorderSubContext *sc = NULL;
1037         _MMStreamRecorderGstElement *last_element = NULL;
1038         /* type_element *AudiosrcElement = NULL; */
1039
1040         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1041
1042         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1043         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1044
1045         _mmstreamrec_dbg_log("");
1046
1047         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);
1048
1049         if (err != MM_ERROR_NONE) {
1050                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
1051                 SAFE_FREE(err_name);
1052                 return err;
1053         }
1054
1055         err = _mmstreamrecorder_check_audiocodec_fileformat_compatibility(a_enc, file_format);
1056         if (err != MM_ERROR_NONE) {
1057                 _mmstreamrec_dbg_err("error name :%s , audio format %d , fileformat %d. error : %x)", err_name, a_enc, file_format, err);
1058                 SAFE_FREE(err_name);
1059                 return err;
1060         }
1061
1062         /* Check existence */
1063         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst) {
1064                 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst)->ref_count > 0)
1065                         gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
1066
1067                 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_AUDIOSRC_BIN is Already existed. Unref once...");
1068         }
1069
1070         /* Create bin element */
1071         _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, "audiosource_bin", err);
1072
1073         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC, "appsrc", hstreamrecorder->ini.name_of_audio_src, element_list, err);
1074
1075         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err);
1076
1077         /* Set basic infomation */
1078         if (a_enc != MM_AUDIO_CODEC_VORBIS) {
1079                 int depth = 0;
1080
1081                 if (format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
1082                         depth = 16;
1083                 } else {                                /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
1084                         depth = 8;
1085                 }
1086
1087                 caps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
1088
1089                 _mmstreamrec_dbg_log("caps [x-raw-int, rate:%d, channel:%d, depth:%d]", rate, channel, depth);
1090         } else {
1091                 /* what are the audio encoder which should get audio/x-raw-float? */
1092                 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);
1093                 _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", rate, channel, BYTE_ORDER);
1094         }
1095
1096         if (caps) {
1097                 if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER)
1098                         MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "caps", caps);
1099
1100                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_FILT].gst), "caps", caps);
1101                 {
1102                         gchar *type = gst_caps_to_string(caps);
1103                         _mmstreamrec_dbg_err("_MMSTREAMRECORDER_AUDIOSRC_FILT %s", type);
1104                         g_free(type);
1105                 }
1106                 gst_caps_unref(caps);
1107                 caps = NULL;
1108         } else {
1109                 _mmstreamrec_dbg_err("create caps error");
1110                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
1111                 goto pipeline_creation_error;
1112         }
1113
1114         if (rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) {
1115 #if 1                                                   /* mic mode */
1116                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", TRUE);
1117 #else                                                   /* speaker mode with alsasrc */
1118                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "device", "hw:0,8");
1119                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "latency-time", 256000);
1120                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "buffer-time", 10000);
1121                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
1122 #endif
1123         } else {
1124                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
1125         }
1126
1127         if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst), element_list)) {
1128                 _mmstreamrec_dbg_err("element add error.");
1129                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
1130                 goto pipeline_creation_error;
1131         }
1132
1133         if (!_mmstreamrecorder_link_elements(element_list)) {
1134                 _mmstreamrec_dbg_err("element link error.");
1135                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
1136                 goto pipeline_creation_error;
1137         }
1138
1139         last_element = (_MMStreamRecorderGstElement *) (g_list_last(element_list)->data);
1140         pad = gst_element_get_static_pad(last_element->gst, "src");
1141         if ((gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad))) < 0) {
1142                 gst_object_unref(pad);
1143                 pad = NULL;
1144                 _mmstreamrec_dbg_err("failed to create ghost pad on _MMSTREAMRECORDER_AUDIOSRC_BIN.");
1145                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
1146                 goto pipeline_creation_error;
1147         }
1148
1149         gst_object_unref(pad);
1150         pad = NULL;
1151
1152         if (element_list) {
1153                 g_list_free(element_list);
1154                 element_list = NULL;
1155         }
1156
1157         return MM_ERROR_NONE;
1158
1159  pipeline_creation_error:
1160         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC);
1161         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT);
1162         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN);
1163
1164         if (element_list) {
1165                 g_list_free(element_list);
1166                 element_list = NULL;
1167         }
1168
1169         return err;
1170 }
1171
1172 int _mmstreamrecorder_destroy_audiosrc_bin(MMHandleType handle)
1173 {
1174         GstPad *srcpad = NULL;
1175         GstPad *sinkpad = NULL;
1176         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1177         _MMStreamRecorderSubContext *sc = NULL;
1178
1179         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1180
1181         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1182         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1183
1184         _mmstreamrec_dbg_log("");
1185
1186         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst != NULL) {
1187                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
1188                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
1189                 _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad);
1190
1191                 /* release audiosrc bin */
1192                 gst_bin_remove(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
1193
1194                 _mmstreamrecorder_remove_element_handle(handle, (void *)sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, _MMSTREAMRECORDER_AUDIOSRC_FILT);
1195
1196                 _mmstreamrec_dbg_log("Audio pipeline removed");
1197         }
1198
1199         return MM_ERROR_NONE;
1200 }
1201
1202 /* COMMAND - VIDEO */
1203 int _mmstreamrecorder_video_command(MMHandleType handle, int command)
1204 {
1205         int ret = MM_ERROR_NONE;
1206         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1207         _MMStreamRecorderVideoInfo *info = NULL;
1208         _MMStreamRecorderAudioInfo *info_audio = NULL;
1209         _MMStreamRecorderFileInfo *finfo = NULL;
1210         _MMStreamRecorderSubContext *sc = NULL;
1211         GstElement *pipeline = NULL;
1212         GstPad *pad = NULL;
1213         guint count = 0;
1214         gboolean audio_enable = FALSE;
1215         int rec_mode = 0;
1216         char *err_name = NULL;
1217
1218         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1219
1220         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1221         mmf_return_val_if_fail(sc && sc->encode_element, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1222
1223         mmf_return_val_if_fail(sc->info_video, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1224         if (sc->audio_enable == TRUE)
1225                 mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1226
1227         mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1228
1229         ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_RECORDER_MODE, &rec_mode, MMSTR_AUDIO_ENABLE, &audio_enable, NULL);
1230
1231         if (ret != MM_ERROR_NONE) {
1232                 _mmstreamrec_dbg_err("Get attrs fail. (%s:%x)", err_name, ret);
1233                 SAFE_FREE(err_name);
1234                 return ret;
1235         }
1236
1237         info = sc->info_video;
1238         if (sc->audio_enable == TRUE)
1239                 info_audio = sc->info_audio;
1240
1241         finfo = sc->info_file;
1242
1243         _mmstreamrec_dbg_log("command %d", command);
1244
1245         pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1246
1247         switch (command) {
1248         case _MM_STREAMRECORDER_CMD_RECORD:
1249                 {
1250
1251                         /* Recording */
1252                         _mmstreamrec_dbg_log("Record Start");
1253                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1254
1255                         /* Adjust display FPS */
1256                         info->video_frame_count = 0;
1257                         if (info_audio)
1258                                 info_audio->audio_frame_count = 0;
1259
1260                         info->filesize = 0;
1261                         sc->ferror_send = FALSE;
1262                         sc->ferror_count = 0;
1263                         sc->error_occurs = FALSE;
1264                         sc->bget_eos = FALSE;
1265                         ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PAUSED);
1266                         ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING);
1267                         if (ret != MM_ERROR_NONE) {
1268                                 /* Remove recorder pipeline and recording file which size maybe zero */
1269                                 ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1270
1271                                 if (finfo->filename) {
1272                                         _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1273                                         unlink(finfo->filename);
1274                                         g_free(finfo->filename);
1275                                         finfo->filename = NULL;
1276                                 }
1277                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1278                         }
1279
1280                 }
1281                 break;
1282         case _MM_STREAMRECORDER_CMD_PAUSE:
1283                 {
1284
1285                         if (info->b_commiting) {
1286                                 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1287                                 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1288                         }
1289
1290                         for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1291                                 if (sc->audio_enable == FALSE) {
1292                                         /* check only video frame */
1293                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1294                                                 break;
1295                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1296                                                 _mmstreamrec_dbg_err("Pause fail, frame count %" G_GUINT64_FORMAT "", info->video_frame_count);
1297                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1298                                         } else {
1299                                                 _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial[%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1300                                         }
1301
1302                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1303                                 } else {
1304                                         /* check both of video and audio frame */
1305                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1306                                                 break;
1307                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1308                                                 _mmstreamrec_dbg_err("Pause fail, frame count VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1309                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1310                                         } else {
1311                                                 _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);
1312                                         }
1313
1314                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1315                                 }
1316                         }
1317                         /* tee block */
1318                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "runtime-pause", TRUE);
1319
1320                         break;
1321                 }
1322                 break;
1323         case _MM_STREAMRECORDER_CMD_CANCEL:
1324                 {
1325                         if (info->b_commiting) {
1326                                 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1327                                 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1328                         }
1329
1330                         ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1331                         if (ret != MM_ERROR_NONE)
1332                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1333
1334                         /* remove target file */
1335                         if (finfo->filename) {
1336                                 _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1337                                 unlink(finfo->filename);
1338                                 g_free(finfo->filename);
1339                                 finfo->filename = NULL;
1340                         }
1341
1342                         sc->isMaxsizePausing = FALSE;
1343                         sc->isMaxtimePausing = FALSE;
1344
1345                         info->video_frame_count = 0;
1346                         if (info_audio)
1347                                 info_audio->audio_frame_count = 0;
1348
1349                         info->filesize = 0;
1350                         break;
1351                 }
1352                 break;
1353         case _MM_STREAMRECORDER_CMD_COMMIT:
1354                 /* video recording command */
1355                 {
1356                         if(rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) {
1357                                 if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {\
1358                                         if (audio_enable) {
1359                                                 ret = gst_element_send_event(gst_bin_get_by_name(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), "audio_source"), gst_event_new_eos());
1360                                         }
1361                                         ret = gst_element_send_event(gst_bin_get_by_name(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), "video_source"), gst_event_new_eos());
1362                                 }
1363                         } else {
1364
1365                                 if (info->b_commiting) {
1366                                         _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command);
1367                                         return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1368                                 } else {
1369                                         _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
1370                                         info->b_commiting = TRUE;
1371                                 }
1372
1373                                 for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1374                                         if (sc->audio_enable == FALSE) {
1375                                                 /* check only video frame */
1376                                                 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1377                                                         break;
1378                                                 } else if (count == hstreamrecorder->ini.retrial_count) {
1379                                                         _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count);
1380                                                         info->b_commiting = FALSE;
1381                                                         return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1382                                                 } else {
1383                                                         _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1384                                                 }
1385
1386                                                 usleep(hstreamrecorder->ini.video_frame_wait_time);
1387                                         } else {
1388                                                 /* check both of video and audio frame */
1389                                                 if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1390                                                         break;
1391                                                 } else if (count == hstreamrecorder->ini.retrial_count) {
1392                                                         _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1393
1394                                                         info->b_commiting = FALSE;
1395                                                         return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1396                                                 } else {
1397                                                         _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);
1398                                                 }
1399
1400                                                 usleep(hstreamrecorder->ini.video_frame_wait_time);
1401                                         }
1402                                 }
1403
1404                                 if (sc->error_occurs) {
1405                                         GstPad *video = NULL;
1406                                         GstPad *audio = NULL;
1407
1408                                         _mmstreamrec_dbg_err("Committing Error case");
1409 #if 0
1410                                         video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink");
1411                                         ret = gst_pad_send_event(video, gst_event_new_eos());
1412                                         _mmstreamrec_dbg_err("Sending EOS video sink  : %d", ret);
1413                                         gst_object_unref(video);
1414 #endif
1415                                         video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
1416                                         gst_pad_push_event(video, gst_event_new_flush_start());
1417                                         gst_pad_push_event(video, gst_event_new_flush_stop(TRUE));
1418                                         ret = gst_pad_push_event(video, gst_event_new_eos());
1419                                         _mmstreamrec_dbg_err("Sending EOS video encoder src pad  : %d", ret);
1420                                         gst_object_unref(video);
1421
1422                                         if (sc->audio_enable == TRUE) {
1423                                                 audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
1424                                                 gst_pad_push_event(audio, gst_event_new_flush_start());
1425                                                 gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE));
1426                                                 ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1427                                                 _mmstreamrec_dbg_err("Sending EOS audio encoder src pad  : %d", ret);
1428                                                 gst_object_unref(audio);
1429                                         }
1430                                 } else {
1431                                         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) {
1432                                         ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, gst_event_new_eos());
1433                                         _mmstreamrec_dbg_warn("send eos to appsrc result : %d", ret);
1434                                         }
1435
1436                                         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) {
1437                                                 pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1438                                                 ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1439                                                 gst_object_unref(pad);
1440                                                 pad = NULL;
1441
1442                                                 _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret);
1443                                         }
1444                                 }
1445                         }
1446                         /* Wait EOS */
1447                         _mmstreamrec_dbg_log("Start to wait EOS");
1448                         ret = _mmstreamrecorder_get_eos_message(handle);
1449                         if (ret != MM_ERROR_NONE) {
1450                                 info->b_commiting = FALSE;
1451                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1452                         }
1453                 }
1454                 break;
1455         default:
1456                 ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
1457                 break;
1458         }
1459         return MM_ERROR_NONE;
1460
1461  _ERR_STREAMRECORDER_VIDEO_COMMAND:
1462         if (ret != MM_ERROR_NONE)
1463                 _mmstreamrec_dbg_err("Current Videosrc status");
1464
1465         return ret;
1466 }
1467
1468 int _mmstreamrecorder_video_handle_eos(MMHandleType handle)
1469 {
1470         int ret = MM_ERROR_NONE;
1471
1472         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1473         _MMStreamRecorderSubContext *sc = NULL;
1474         _MMStreamRecorderVideoInfo *info = NULL;
1475         _MMStreamRecorderAudioInfo *info_audio = NULL;
1476         _MMStreamRecorderFileInfo *finfo = NULL;
1477         _MMStreamRecorderMsgItem msg;
1478         MMStreamRecordingReport *report = NULL;
1479
1480         mmf_return_val_if_fail(hstreamrecorder, FALSE);
1481
1482         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1483         mmf_return_val_if_fail(sc, FALSE);
1484         mmf_return_val_if_fail(sc->info_video, FALSE);
1485         if (sc->audio_enable == TRUE)
1486                 mmf_return_val_if_fail(sc->info_audio, FALSE);
1487
1488         mmf_return_val_if_fail(sc->info_file, FALSE);
1489
1490         info = sc->info_video;
1491         if (sc->audio_enable == TRUE)
1492                 info_audio = sc->info_audio;
1493
1494         finfo = sc->info_file;
1495
1496         _mmstreamrec_dbg_err("");
1497
1498         /* remove blocking part */
1499         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1500
1501         ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1502         if (ret != MM_ERROR_NONE)
1503                 _mmstreamrec_dbg_warn("_mmstreamrecorder_destroy_recorder_pipeline failed. error[%x]", ret);
1504
1505         /* Send recording report to application */
1506         msg.id = MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED;
1507         report = (MMStreamRecordingReport *) g_malloc(sizeof(MMStreamRecordingReport));
1508         if (!report) {
1509                 _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
1510         } else {
1511                 report->recording_filename = g_strdup(finfo->filename);
1512                 msg.param.data = report;
1513                 msg.param.code = 1;
1514                 _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
1515         }
1516
1517         /* Finishing */
1518         sc->pipeline_time = 0;
1519         sc->pause_time = 0;
1520         sc->isMaxsizePausing = FALSE;   /*In async function, this variable should set in callback function. */
1521         sc->isMaxtimePausing = FALSE;
1522         sc->error_occurs = FALSE;
1523
1524         info->video_frame_count = 0;
1525         if (info_audio)
1526                 info_audio->audio_frame_count = 0;
1527
1528         info->filesize = 0;
1529         g_free(finfo->filename);
1530         finfo->filename = NULL;
1531         info->b_commiting = FALSE;
1532
1533         _mmstreamrec_dbg_err("_mmstreamrecorder_video_handle_eos : end");
1534
1535         return TRUE;
1536 }
1537
1538 int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long long timestamp, GstBuffer *buffer, int size)
1539 {
1540         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1541         _MMStreamRecorderSubContext *sc = NULL;
1542         /* GstPad *srcpad = NULL; */
1543         GstCaps *srccaps = NULL;
1544         char *err_name = NULL;
1545         int video_fps = 0;
1546         int video_src = 0;
1547         int video_width = 0;
1548         int video_height = 0;
1549         int ret = MM_ERROR_NONE;
1550         int video_source_format = 0;
1551
1552         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1553
1554         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1555         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1556
1557         if (buffer == NULL || size == 0) {
1558                 _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %lld", buffer, size, timestamp);
1559                 return MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
1560         }
1561
1562         _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %lld", buffer, size, timestamp);
1563
1564         /* check element availability */
1565         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);
1566
1567         if (ret != MM_ERROR_NONE) {
1568                 _mmstreamrec_dbg_err("Error in mm_streamrecorder_get_attributes (%s:%d)", err_name, ret);
1569                 SAFE_FREE(err_name);
1570                 return ret;
1571         }
1572
1573         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst) {
1574
1575                 srccaps = gst_set_videosrcpad_caps_sw(video_src, video_width, video_height, video_fps, 1);
1576                 if (srccaps) {
1577                         gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps);
1578                         gst_caps_unref(srccaps);
1579                         srccaps = NULL;
1580                 }
1581
1582                 /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/
1583                 ret = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, buffer);
1584
1585                 if (ret) {
1586                         _mmstreamrec_dbg_err("video gst_app_src_push_buffer %d", ret);
1587                         ret = MM_ERROR_STREAMRECORDER_VIDEOBUFFER_PUSH;
1588                 }
1589
1590                 /* g_signal_emit_by_name(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "push-buffer", newbuf, &ret); */
1591         }
1592
1593         return ret;
1594 }
1595
1596 int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long long timestamp, GstBuffer *buffer, int size)
1597 {
1598         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1599         _MMStreamRecorderSubContext *sc = NULL;
1600         _MMStreamRecorderAudioInfo *info = NULL;
1601         GstFlowReturn err = GST_FLOW_OK;
1602         GstPad *srcpad = NULL;
1603         GstCaps *srccaps = NULL;
1604         int rate = 0;
1605         int channel = 0;
1606         int depth = 0;
1607
1608         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1609
1610         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1611         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1612
1613         info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
1614         mmf_return_val_if_fail(info, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1615
1616         rate = info->iSamplingRate;
1617         depth = info->audio_encode_depth;
1618         channel = info->iChannels;
1619
1620         /*_mmstreamrec_dbg_log("Audio Buffer Push start , time stamp %ld",timestamp); */
1621
1622         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst) {
1623
1624                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1625                 /* TODO : CHANNEL , WIDTH, DATATYPE */
1626                 srccaps = gst_pad_get_current_caps(srcpad);
1627                 srccaps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
1628                 gst_base_src_set_caps(GST_BASE_SRC(srcpad), srccaps);
1629
1630                 err = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, buffer);
1631
1632                 if (err) {
1633                         _mmstreamrec_dbg_err("Audio gst_app_src_push_buffer %d", err);
1634                         return MM_ERROR_STREAMRECORDER_AUDIOBUFFER_PUSH;
1635                 }
1636         }
1637
1638         return MM_ERROR_NONE;
1639 }
1640