Delete unused function
[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 : %x", 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 audio_enable = FALSE;
162         GstBus *bus = NULL;
163         GstPad *srcpad = NULL;
164         GstPad *sinkpad = NULL;
165
166         unsigned int video_codec = MM_VIDEO_CODEC_INVALID;
167         unsigned int file_format = MM_FILE_FORMAT_INVALID;
168         char *err_name = NULL;
169
170         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
171         _MMStreamRecorderSubContext *sc = NULL;
172
173         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
174
175         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
176         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
177
178         _mmstreamrec_dbg_warn("start");
179
180         err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, NULL);
181         if (err != MM_ERROR_NONE) {
182                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
183                 SAFE_FREE(err_name);
184                 return err;
185         }
186
187         err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format);
188         if (err != MM_ERROR_NONE)
189                 return err;
190
191         /* Main pipeline */
192         _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err);
193
194         /* get audio disable */
195         mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL);
196         sc->audio_enable = audio_enable;
197
198         _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable);
199
200         if (sc->audio_enable == TRUE) {
201                 /* create audiosrc bin */
202                 err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder);
203                 if (err != MM_ERROR_NONE)
204                         return err;
205         }
206
207         err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO);
208         if (err != MM_ERROR_NONE)
209                 return err;
210
211         if (sc->audio_enable == TRUE)
212                 gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
213
214         /* add element and encodesink bin to encode main pipeline */
215         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);
216
217         /* Link each element : appsrc - capsfilter - encodesink bin */
218         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src");
219         sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink");
220         _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
221
222         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src");
223         sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0");
224         _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
225
226         if (sc->audio_enable == TRUE) {
227                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
228                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
229                 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
230         }
231
232         if (sc->audio_enable == TRUE) {
233                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink");
234                 MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder);
235                 gst_object_unref(sinkpad);
236                 sinkpad = NULL;
237
238                 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) {
239                         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src");
240                         MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
241                         gst_object_unref(srcpad);
242                         srcpad = NULL;
243                 }
244         }
245
246         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) {
247                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src");
248                 MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder);
249                 gst_object_unref(srcpad);
250                 srcpad = NULL;
251         }
252
253         if (sc->audio_enable == FALSE) {
254                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink");
255                 MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder);
256                 gst_object_unref(sinkpad);
257                 sinkpad = NULL;
258         }
259
260         srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
261         MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_record, hstreamrecorder);
262         gst_object_unref(srcpad);
263         srcpad = NULL;
264
265         if (sc->audio_enable == TRUE) {
266                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
267                 MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audio_dataprobe_check, hstreamrecorder);
268                 gst_object_unref(srcpad);
269                 srcpad = NULL;
270         }
271
272         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
273
274         /* register pipeline message callback */
275         hstreamrecorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder);
276
277         gst_object_unref(bus);
278         bus = NULL;
279
280         return MM_ERROR_NONE;
281
282  pipeline_creation_error:
283         for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++)
284                 _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, i);
285
286         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE);
287         return err;
288 }
289
290 int _mmstreamrecorder_destroy_recorder_pipeline(MMHandleType handle)
291 {
292         int ret = MM_ERROR_NONE;
293         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
294         _MMStreamRecorderSubContext *sc = NULL;
295
296         GstBus *bus = NULL;
297
298         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
299         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
300         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
301
302         _mmstreamrec_dbg_log("start");
303
304         if (!sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) {
305                 _mmstreamrec_dbg_warn("pipeline is not existed.");
306                 return MM_ERROR_NONE;
307         }
308
309         _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_VIDEOREC);
310
311         ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL);
312         if (ret != MM_ERROR_NONE) {
313                 _mmstreamrec_dbg_err("Faile to change encode main pipeline [0x%x]", ret);
314                 return ret;
315         }
316
317         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst));
318
319         /* Remove remained message */
320         if (bus) {
321                 GstMessage *gst_msg = NULL;
322                 while ((gst_msg = gst_bus_pop(bus)) != NULL) {
323                         _mmstreamrecorder_pipeline_cb_message(bus, gst_msg, (gpointer) hstreamrecorder);
324                         gst_message_unref(gst_msg);
325                         gst_msg = NULL;
326                 }
327                 gst_object_unref(bus);
328                 bus = NULL;
329         }
330
331         /* remove audio pipeline first */
332         ret = _mmstreamrecorder_destroy_audiosrc_bin(handle);
333         if (ret != MM_ERROR_NONE) {
334                 _mmstreamrec_dbg_err("Fail to remove audio pipeline");
335                 return ret;
336         }
337
338         ret = _mmstreamrecorder_destroy_encodesink_bin(handle);
339         if (ret != MM_ERROR_NONE) {
340                 _mmstreamrec_dbg_err("Fail to remove encoder pipeline");
341                 return ret;
342         }
343
344         /* Remove pipeline message callback */
345         if (hstreamrecorder->encode_pipeline_cb_event_id != 0) {
346                 g_source_remove(hstreamrecorder->encode_pipeline_cb_event_id);
347                 hstreamrecorder->encode_pipeline_cb_event_id = 0;
348         }
349
350         _mmstreamrec_dbg_log("done");
351
352         return ret;
353 }
354
355 int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorderEncodebinProfile profile)
356 {
357         int err = MM_ERROR_NONE;
358         int result = 0;
359         int channel = 0;
360         int audio_enc = 0;
361         int video_enc = 0;
362         int v_bitrate = 0;
363         int a_bitrate = 0;
364         int video_width = 0;
365         int video_height = 0;
366         int video_fps = 0;
367         int file_format = 0;
368         int audio_src_format = 0;
369         int video_src_format = 0;
370         int audio_samplerate = 0;
371         const char *str_profile = NULL;
372         const char *str_aac = NULL;
373         const char *str_aar = NULL;
374         const char *str_acs = NULL;
375         char *err_name = NULL;
376         int ret = MM_ERROR_NONE;
377         GstCaps *caps = NULL;
378         GstPad *pad = NULL;
379         GList *element_list = NULL;
380         char *temp_filename = NULL;
381         int fileformat = 0;
382         int size = 0;
383         guint imax_size = 0;
384         guint imax_time = 0;
385         int rec_mode = 0;
386
387         _MMStreamRecorderVideoInfo *info = NULL;
388         _MMStreamRecorderFileInfo *finfo = NULL;
389
390         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
391         _MMStreamRecorderSubContext *sc = NULL;
392         /* type_element *VideoencElement = NULL; */
393         /* type_element *AudioencElement = NULL; */
394         /* type_element *MuxElement = NULL; */
395         /* type_element *RecordsinkElement = NULL; */
396
397         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
398
399         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
400         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
401
402         _mmstreamrec_dbg_log("start - profile : %d", profile);
403
404         info = sc->info_video;
405         finfo = sc->info_file;
406
407         /* check element availability */
408         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);
409         if (ret != MM_ERROR_NONE) {
410                 _mmstreamrec_dbg_err("Get attrs fail. (%s:%x)", err_name, ret);
411                 SAFE_FREE(err_name);
412                 return err;
413         }
414
415         _mmstreamrec_dbg_err("audio encoder - %d , video encoder : %d", audio_enc, video_enc);
416         _mmstreamrec_dbg_err("audio channel - %d , video v_bitrate : %d", channel, v_bitrate);
417         _mmstreamrec_dbg_err("audio a_bitrate - %d , video video_width : %d ,video video_height : %d ", a_bitrate, video_width, video_height);
418         _mmstreamrec_dbg_err("video_fps - %d , video file_format : %d", video_fps, file_format);
419
420         /* Check existence */
421         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst) {
422                 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst)->ref_count > 0)
423                         gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst);
424
425                 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_ENCSINK_BIN is Already existed.");
426         }
427
428         /* Create bin element */
429         _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN, "encodesink_bin", err);
430
431         /* Create child element */
432         if (hstreamrecorder->ini.encsink_bin_profile != MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
433                 /* create appsrc and capsfilter */
434                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC, hstreamrecorder->ini.name_of_encsink_src, "encodesink_src", element_list, err);
435                 _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT, "capsfilter", "encodesink_filter", element_list, err);
436
437                 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
438                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "caps", caps);
439                 if (caps) {
440                         gst_caps_unref(caps);
441                         caps = NULL;
442                 }
443
444                 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
445                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "caps", caps);
446                 if (caps) {
447                         gst_caps_unref(caps);
448                         caps = NULL;
449                 }
450
451
452                 /* release element_list, they will be placed out of encodesink bin */
453                 if (element_list) {
454                         g_list_free(element_list);
455                         element_list = NULL;
456                 }
457                 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) {
458                         /* set appsrc as live source */
459                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "is-live", hstreamrecorder->ini.encsink_src_islive);
460                 }
461
462         }
463
464         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "encodebin", "encodesink_encbin", element_list, err);
465
466         _mmstreamrec_dbg_log("Profile[%d]", profile);
467
468         /* Set information */
469         if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
470                 str_profile = "VideoProfile";
471                 str_aac = "VideoAutoAudioConvert";
472                 str_aar = "VideoAutoAudioResample";
473                 str_acs = "VideoAutoColorSpace";
474         } else if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
475                 str_profile = "AudioProfile";
476                 str_aac = "AudioAutoAudioConvert";
477                 str_aar = "AudioAutoAudioResample";
478                 str_acs = "AudioAutoColorSpace";
479         }
480
481         /* TODO : check the last value ( set ) */
482         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "profile", hstreamrecorder->ini.encsink_bin_profile);
483         if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER)
484                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", hstreamrecorder->ini.encsink_bin_auto_audio_convert);
485
486         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", hstreamrecorder->ini.encsink_bin_auto_audio_resample);
487         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
488         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", hstreamrecorder->ini.encsink_bin_use_video_toggle);
489
490         /* Codec */
491         if (hstreamrecorder->ini.encsink_bin_profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
492                 switch (video_enc) {
493                 case MM_VIDEO_CODEC_H263:
494                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h263_video_encoder);
495                         break;
496                 case MM_VIDEO_CODEC_H264:
497                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
498                         break;
499                 case MM_VIDEO_CODEC_MPEG4:
500                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.mpeg4_video_encoder);
501                         break;
502                 default:
503                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "venc-name", hstreamrecorder->ini.h264_video_encoder);
504                         break;
505                 }
506                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VENC, "video-encode", err);
507
508                 /* set color converter size */
509                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vconv-name", hstreamrecorder->ini.name_of_encsink_bin_video_converter);
510                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VCONV, "video-convert", err);
511
512                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace);
513
514                 if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12)
515                         video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_I420;
516
517                 caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1);
518                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vcaps", caps);
519                 if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12)
520                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VCONV].gst, "dst-buffer-num", hstreamrecorder->ini.convert_output_buffer_num);
521
522                 /* state tuning */
523                 err = gst_pad_set_caps(gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"), caps);
524                 err = MM_ERROR_NONE;
525                 /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "state-tuning", TRUE); */
526
527                 if (caps) {
528                         gst_caps_unref(caps);
529                         caps = NULL;
530                 }
531                 _mmstreamrec_dbg_log("size %dx%d, dst-buffer-num %d", video_width, video_height, hstreamrecorder->ini.convert_output_buffer_num);
532
533                 _mmstreamrec_dbg_warn("encoder set caps result : 0x%x", err);
534
535                 if (hstreamrecorder->ini.encsink_bin_use_parser[0]) {
536                         GstElement *parser = gst_element_factory_make(hstreamrecorder->ini.encsink_bin_use_parser, "parse");
537                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-venc-queue", parser);
538                         _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_PARSER, "use-venc-queue", err);
539                 }
540         }
541
542         if (sc->audio_enable == TRUE) {
543
544                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "aenc-name", hstreamrecorder->ini.name_of_encsink_bin_audio_encoder);
545                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC, "audio-encode", err);
546                 _mmstreamrec_dbg_err("audio-encode err = %x ", err);
547
548                 /* Set basic infomation */
549                 if (audio_enc != MM_AUDIO_CODEC_VORBIS) {
550                         int depth = 0;
551
552                         if (audio_src_format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
553                                 depth = 16;
554                         } else {                        /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
555                                 depth = 8;
556                         }
557
558                         /* TODO : set rate , channel , depth */
559
560                         caps = gst_set_audiosrcpad_caps(audio_samplerate, 2, depth, 16, 1);
561                         /* MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE); */
562                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
563                         {
564                                 gchar *type = gst_caps_to_string(caps);
565
566                                 _mmstreamrec_dbg_warn("Set srcpad caps: %s", type);
567                         }
568                         gst_caps_unref(caps);
569                         caps = NULL;
570                 } else {
571                         /* what are the audio encoder which should get audio/x-raw-float? */
572                         caps = gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, audio_samplerate, "channels", G_TYPE_INT, channel, "endianness", G_TYPE_INT, BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
573                         _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", audio_samplerate, channel, BYTE_ORDER);
574                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
575                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
576                         gst_caps_unref(caps);
577                         caps = NULL;
578                 }
579
580 #if 0
581                 if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
582                         caps = gst_caps_new_simple("audio/x-raw-int", "channels", G_TYPE_INT, 1, NULL);
583                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
584                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
585                         gst_caps_unref(caps);
586                         caps = NULL;
587                 }
588
589                 if (audio_enc == MM_AUDIO_CODEC_OGG) {
590                         caps = gst_caps_new_simple("audio/x-raw-int", NULL);
591                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
592                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
593                         gst_caps_unref(caps);
594                         caps = NULL;
595                 }
596 #endif
597
598                 _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
599         }
600
601         /* Mux */
602         switch (file_format) {
603         case MM_FILE_FORMAT_3GP:{
604                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_3GPMUXER);
605                 }
606                 break;
607
608         case MM_FILE_FORMAT_MP4:{
609                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
610                 }
611                 break;
612
613         default:{
614                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "mux-name", hstreamrecorder->ini.name_of_encsink_bin_MP4MUXER);
615                 }
616                 break;
617
618         }
619         _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_MUX, "mux", err);
620
621         /* Sink */
622         /* for recording */
623         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
624         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "async", 0);
625
626         err = mm_streamrecorder_get_attributes(handle, &err_name,
627                                                                                    MMSTR_FILE_FORMAT, &fileformat, MMSTR_FILENAME, &temp_filename, &size,
628                                                                                    MMSTR_TARGET_MAX_SIZE, &imax_size,
629                                                                                    MMSTR_TARGET_TIME_LIMIT, &imax_time,
630                                                                                    NULL);
631
632         if (err != MM_ERROR_NONE) {
633                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
634                 SAFE_FREE(err_name);
635                 return err;
636         }
637
638         finfo->fileformat = fileformat;
639
640         /* set max size */
641         if (imax_size <= 0)
642                 info->max_size = 0;             /* do not check */
643         else
644                 info->max_size = ((guint64) imax_size) << 10;   /* to byte */
645
646         /* set max time */
647         if (imax_time <= 0)
648                 info->max_time = 0;             /* do not check */
649         else
650                 info->max_time = ((guint64) imax_time) * 1000;  /* to millisecond */
651
652         finfo->filename = g_strdup(temp_filename);
653         if (!finfo->filename) {
654                 _mmstreamrec_dbg_err("strdup was failed");
655                 return err;
656         }
657
658         _mmstreamrec_dbg_log("Record start : set file name using attribute - %s ", finfo->filename);
659
660         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename);
661
662         if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
663                 /* video encoder attribute setting */
664                 if (v_bitrate > 0)
665                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
666                 else
667                         _mmstreamrec_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
668         }
669
670         if (sc->audio_enable == TRUE) {
671                 /* audio encoder attribute setting */
672                 if (a_bitrate > 0) {
673                         switch (audio_enc) {
674                         case MM_AUDIO_CODEC_AMR:
675                                 result = _mmstreamrecorder_get_amrnb_bitrate_mode(a_bitrate);
676                                 _mmstreamrec_dbg_log("Set AMR encoder mode [%d]", result);
677                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "band-mode", result);
678                                 break;
679                         case MM_AUDIO_CODEC_AAC:
680                                 _mmstreamrec_dbg_log("Set AAC encoder bitrate [%d]", a_bitrate);
681                                 MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
682                                 break;
683                         default:
684                                 _mmstreamrec_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
685                                 break;
686                         }
687                 } else {
688                         _mmstreamrec_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
689                 }
690         }
691
692         _mmstreamrec_dbg_log("Element creation complete");
693
694         /* Add element to bin */
695         if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst), element_list)) {
696                 _mmstreamrec_dbg_err("element add error.");
697                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
698                 goto pipeline_creation_error;
699         }
700
701         _mmstreamrec_dbg_log("Element add complete");
702
703         if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) {
704                 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
705                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
706                         gst_object_unref(pad);
707                         pad = NULL;
708                         _mmstreamrec_dbg_err("failed to create ghost video_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
709                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
710                         goto pipeline_creation_error;
711                 }
712                 gst_object_unref(pad);
713                 pad = NULL;
714
715                 if (sc->audio_enable == TRUE) {
716                         pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
717                         if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
718                                 gst_object_unref(pad);
719                                 pad = NULL;
720                                 _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
721                                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
722                                 goto pipeline_creation_error;
723                         }
724                         gst_object_unref(pad);
725                         pad = NULL;
726                 }
727         } else if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) {
728                 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
729                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
730                         gst_object_unref(pad);
731                         pad = NULL;
732                         _mmstreamrec_dbg_err("failed to create ghost audio_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
733                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
734                         goto pipeline_creation_error;
735                 }
736                 gst_object_unref(pad);
737                 pad = NULL;
738         } else {
739                 /* for stillshot */
740                 pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image");
741                 if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
742                         gst_object_unref(pad);
743                         pad = NULL;
744                         _mmstreamrec_dbg_err("failed to create ghost image_sink0 on _MMSTREAMRECORDER_ENCSINK_BIN.");
745                         err = MM_ERROR_STREAMRECORDER_GST_LINK;
746                         goto pipeline_creation_error;
747                 }
748                 gst_object_unref(pad);
749                 pad = NULL;
750         }
751
752         _mmstreamrec_dbg_log("Get pad complete");
753
754         /* Link internal element */
755         if (!_mmstreamrecorder_link_elements(element_list)) {
756                 _mmstreamrec_dbg_err("element link error.");
757                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
758                 goto pipeline_creation_error;
759         }
760
761         if (element_list) {
762                 g_list_free(element_list);
763                 element_list = NULL;
764         }
765
766         _mmstreamrec_dbg_log("done");
767
768         return MM_ERROR_NONE;
769
770  pipeline_creation_error:
771         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN);
772         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC);
773         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT);
774         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_VENC);
775         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC);
776         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_IENC);
777         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_MUX);
778         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK);
779         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN);
780
781         if (element_list) {
782                 g_list_free(element_list);
783                 element_list = NULL;
784         }
785
786         return err;
787 }
788
789 int _mmstreamrecorder_destroy_encodesink_bin(MMHandleType handle)
790 {
791         GstPad *reqpad = NULL;
792         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
793         _MMStreamRecorderSubContext *sc = NULL;
794
795         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
796
797         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
798         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
799
800         _mmstreamrec_dbg_log("");
801
802         if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {
803                 /* release request pad */
804                 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio");
805                 if (reqpad) {
806                         gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
807                         gst_object_unref(reqpad);
808                         reqpad = NULL;
809                 }
810
811                 reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video");
812                 if (reqpad) {
813                         gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad);
814                         gst_object_unref(reqpad);
815                         reqpad = NULL;
816                 }
817
818                 /* release encode main pipeline */
819                 gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst);
820
821                 _mmstreamrec_dbg_log("Encoder pipeline removed");
822         }
823
824         return MM_ERROR_NONE;
825 }
826
827 int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle)
828 {
829         int err = MM_ERROR_NONE;
830         int val = 0;
831         int rate = 0;
832         int format = 0;
833         int channel = 0;
834         unsigned int a_enc = MM_AUDIO_CODEC_INVALID;
835         unsigned int file_format = MM_FILE_FORMAT_INVALID;
836         char *err_name = NULL;
837         int rec_mode = 0;
838
839         GstCaps *caps = NULL;
840         GstPad *pad = NULL;
841         GList *element_list = NULL;
842
843         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
844         _MMStreamRecorderSubContext *sc = NULL;
845         _MMStreamRecorderGstElement *last_element = NULL;
846         /* type_element *AudiosrcElement = NULL; */
847
848         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
849
850         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
851         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
852
853         _mmstreamrec_dbg_log("");
854
855         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);
856
857         if (err != MM_ERROR_NONE) {
858                 _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
859                 SAFE_FREE(err_name);
860                 return err;
861         }
862
863         err = _mmstreamrecorder_check_audiocodec_fileformat_compatibility(a_enc, file_format);
864         if (err != MM_ERROR_NONE) {
865                 _mmstreamrec_dbg_err("error name :%s , audio format %d , fileformat %d. error : %x)", err_name, a_enc, file_format, err);
866                 SAFE_FREE(err_name);
867                 return err;
868         }
869
870         /* Check existence */
871         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst) {
872                 if (((GObject *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst)->ref_count > 0)
873                         gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
874
875                 _mmstreamrec_dbg_log("_MMSTREAMRECORDER_AUDIOSRC_BIN is Already existed. Unref once...");
876         }
877
878         /* Create bin element */
879         _MMSTREAMRECORDER_BIN_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, "audiosource_bin", err);
880
881         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC, "appsrc", hstreamrecorder->ini.name_of_audio_src, element_list, err);
882
883         _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err);
884
885         /* Set basic infomation */
886         if (a_enc != MM_AUDIO_CODEC_VORBIS) {
887                 int depth = 0;
888
889                 if (format == MM_STREAMRECORDER_AUDIO_FORMAT_PCM_S16_LE) {
890                         depth = 16;
891                 } else {                                /* MM_STREAMRECORDER_AUDIO_FORMAT_PCM_U8 */
892                         depth = 8;
893                 }
894
895                 caps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
896
897                 _mmstreamrec_dbg_log("caps [x-raw-int, rate:%d, channel:%d, depth:%d]", rate, channel, depth);
898         } else {
899                 /* what are the audio encoder which should get audio/x-raw-float? */
900                 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);
901                 _mmstreamrec_dbg_log("caps [x-raw-float, rate:%d, channel:%d, endianness:%d, width:32]", rate, channel, BYTE_ORDER);
902         }
903
904         if (caps) {
905                 if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER)
906                         MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "caps", caps);
907
908                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_FILT].gst), "caps", caps);
909                 {
910                         gchar *type = gst_caps_to_string(caps);
911
912                         _mmstreamrec_dbg_err("_MMSTREAMRECORDER_AUDIOSRC_FILT %s", type);
913
914                 }
915                 gst_caps_unref(caps);
916                 caps = NULL;
917         } else {
918                 _mmstreamrec_dbg_err("create caps error");
919                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
920                 goto pipeline_creation_error;
921         }
922
923         if (rec_mode == MM_STREAMRECORDER_MODE_SCREENRECORD) {
924 #if 1                                                   /* mic mode */
925                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", TRUE);
926 #else                                                   /* speaker mode with alsasrc */
927                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "device", "hw:0,8");
928                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "latency-time", 256000);
929                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "buffer-time", 10000);
930                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
931 #endif
932         } else {
933                 MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", FALSE);
934         }
935
936         if (!_mmstreamrecorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst), element_list)) {
937                 _mmstreamrec_dbg_err("element add error.");
938                 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
939                 goto pipeline_creation_error;
940         }
941
942         if (!_mmstreamrecorder_link_elements(element_list)) {
943                 _mmstreamrec_dbg_err("element link error.");
944                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
945                 goto pipeline_creation_error;
946         }
947
948         last_element = (_MMStreamRecorderGstElement *) (g_list_last(element_list)->data);
949         pad = gst_element_get_static_pad(last_element->gst, "src");
950         if ((gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad))) < 0) {
951                 gst_object_unref(pad);
952                 pad = NULL;
953                 _mmstreamrec_dbg_err("failed to create ghost pad on _MMSTREAMRECORDER_AUDIOSRC_BIN.");
954                 err = MM_ERROR_STREAMRECORDER_GST_LINK;
955                 goto pipeline_creation_error;
956         }
957
958         gst_object_unref(pad);
959         pad = NULL;
960
961         if (element_list) {
962                 g_list_free(element_list);
963                 element_list = NULL;
964         }
965
966         return MM_ERROR_NONE;
967
968  pipeline_creation_error:
969         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_SRC);
970         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_FILT);
971         _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_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_audiosrc_bin(MMHandleType handle)
982 {
983         GstPad *srcpad = NULL;
984         GstPad *sinkpad = NULL;
985         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
986         _MMStreamRecorderSubContext *sc = NULL;
987
988         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
989
990         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
991         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
992
993         _mmstreamrec_dbg_log("");
994
995         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst != NULL) {
996                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src");
997                 sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0");
998                 _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad);
999
1000                 /* release audiosrc bin */
1001                 gst_bin_remove(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst);
1002
1003                 _mmstreamrecorder_remove_element_handle(handle, (void *)sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN, _MMSTREAMRECORDER_AUDIOSRC_FILT);
1004
1005                 _mmstreamrec_dbg_log("Audio pipeline removed");
1006         }
1007
1008         return MM_ERROR_NONE;
1009 }
1010
1011 /* COMMAND - VIDEO */
1012 int _mmstreamrecorder_video_command(MMHandleType handle, int command)
1013 {
1014         int ret = MM_ERROR_NONE;
1015         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1016         _MMStreamRecorderVideoInfo *info = NULL;
1017         _MMStreamRecorderAudioInfo *info_audio = NULL;
1018         _MMStreamRecorderFileInfo *finfo = NULL;
1019         _MMStreamRecorderSubContext *sc = NULL;
1020         GstElement *pipeline = NULL;
1021         GstPad *pad = NULL;
1022         guint count = 0;
1023
1024         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1025
1026         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1027         mmf_return_val_if_fail(sc && sc->encode_element, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1028
1029         mmf_return_val_if_fail(sc->info_video, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1030         if (sc->audio_enable == TRUE)
1031                 mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1032
1033         mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1034
1035         info = sc->info_video;
1036         if (sc->audio_enable == TRUE)
1037                 info_audio = sc->info_audio;
1038
1039         finfo = sc->info_file;
1040
1041         _mmstreamrec_dbg_log("command %d", command);
1042
1043         pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst;
1044
1045         switch (command) {
1046         case _MM_STREAMRECORDER_CMD_RECORD:
1047                 {
1048
1049                         /* Recording */
1050                         _mmstreamrec_dbg_log("Record Start");
1051                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1052
1053                         /* Adjust display FPS */
1054                         info->video_frame_count = 0;
1055                         if (info_audio)
1056                                 info_audio->audio_frame_count = 0;
1057
1058                         info->filesize = 0;
1059                         sc->ferror_send = FALSE;
1060                         sc->ferror_count = 0;
1061                         sc->error_occurs = FALSE;
1062                         sc->bget_eos = FALSE;
1063
1064                         ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING);
1065                         if (ret != MM_ERROR_NONE) {
1066                                 /* Remove recorder pipeline and recording file which size maybe zero */
1067                                 ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1068
1069                                 if (finfo->filename) {
1070                                         _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1071                                         unlink(finfo->filename);
1072                                         g_free(finfo->filename);
1073                                         finfo->filename = NULL;
1074                                 }
1075                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1076                         }
1077
1078                 }
1079                 break;
1080         case _MM_STREAMRECORDER_CMD_PAUSE:
1081                 {
1082
1083                         if (info->b_commiting) {
1084                                 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1085                                 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1086                         }
1087
1088                         for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1089                                 if (sc->audio_enable == FALSE) {
1090                                         /* check only video frame */
1091                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1092                                                 break;
1093                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1094                                                 _mmstreamrec_dbg_err("Pause fail, frame count %" G_GUINT64_FORMAT "", info->video_frame_count);
1095                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1096                                         } else {
1097                                                 _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial[%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1098                                         }
1099
1100                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1101                                 } else {
1102                                         /* check both of video and audio frame */
1103                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1104                                                 break;
1105                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1106                                                 _mmstreamrec_dbg_err("Pause fail, frame count VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1107                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1108                                         } else {
1109                                                 _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);
1110                                         }
1111
1112                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1113                                 }
1114                         }
1115                         /* tee block */
1116                         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "runtime-pause", TRUE);
1117
1118                         break;
1119                 }
1120                 break;
1121         case _MM_STREAMRECORDER_CMD_CANCEL:
1122                 {
1123                         if (info->b_commiting) {
1124                                 _mmstreamrec_dbg_warn("now on commiting previous file!!(command : %d)", command);
1125                                 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1126                         }
1127
1128                         ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1129                         if (ret != MM_ERROR_NONE)
1130                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1131
1132                         /* remove target file */
1133                         if (finfo->filename) {
1134                                 _mmstreamrec_dbg_log("file delete(%s)", finfo->filename);
1135                                 unlink(finfo->filename);
1136                                 g_free(finfo->filename);
1137                                 finfo->filename = NULL;
1138                         }
1139
1140                         sc->isMaxsizePausing = FALSE;
1141                         sc->isMaxtimePausing = FALSE;
1142
1143                         info->video_frame_count = 0;
1144                         if (info_audio)
1145                                 info_audio->audio_frame_count = 0;
1146
1147                         info->filesize = 0;
1148                         break;
1149                 }
1150                 break;
1151         case _MM_STREAMRECORDER_CMD_COMMIT:
1152                 /* video recording command */
1153                 {
1154
1155                         if (info->b_commiting) {
1156                                 _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command);
1157                                 return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
1158                         } else {
1159                                 _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start");
1160                                 info->b_commiting = TRUE;
1161                         }
1162
1163                         for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) {
1164                                 if (sc->audio_enable == FALSE) {
1165                                         /* check only video frame */
1166                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) {
1167                                                 break;
1168                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1169                                                 _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count);
1170                                                 info->b_commiting = FALSE;
1171                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1172                                         } else {
1173                                                 _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count);
1174                                         }
1175
1176                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1177                                 } else {
1178                                         /* check both of video and audio frame */
1179                                         if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) {
1180                                                 break;
1181                                         } else if (count == hstreamrecorder->ini.retrial_count) {
1182                                                 _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count);
1183
1184                                                 info->b_commiting = FALSE;
1185                                                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
1186                                         } else {
1187                                                 _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);
1188                                         }
1189
1190                                         usleep(hstreamrecorder->ini.video_frame_wait_time);
1191                                 }
1192                         }
1193
1194                         if (sc->error_occurs) {
1195                                 GstPad *video = NULL;
1196                                 GstPad *audio = NULL;
1197
1198                                 _mmstreamrec_dbg_err("Committing Error case");
1199 #if 0
1200                                 video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink");
1201                                 ret = gst_pad_send_event(video, gst_event_new_eos());
1202                                 _mmstreamrec_dbg_err("Sending EOS video sink  : %d", ret);
1203                                 gst_object_unref(video);
1204 #endif
1205                                 video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src");
1206                                 gst_pad_push_event(video, gst_event_new_flush_start());
1207                                 gst_pad_push_event(video, gst_event_new_flush_stop(TRUE));
1208                                 ret = gst_pad_push_event(video, gst_event_new_eos());
1209                                 _mmstreamrec_dbg_err("Sending EOS video encoder src pad  : %d", ret);
1210                                 gst_object_unref(video);
1211
1212                                 if (sc->audio_enable == TRUE) {
1213                                         audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src");
1214                                         gst_pad_push_event(audio, gst_event_new_flush_start());
1215                                         gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE));
1216                                         ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1217                                         _mmstreamrec_dbg_err("Sending EOS audio encoder src pad  : %d", ret);
1218                                         gst_object_unref(audio);
1219                                 }
1220                         } else {
1221                                 if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) {
1222                                         ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, gst_event_new_eos());
1223                                         _mmstreamrec_dbg_warn("send eos to appsrc result : %d", ret);
1224                                 }
1225
1226                                 if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) {
1227                                         pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1228                                         ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
1229                                         gst_object_unref(pad);
1230                                         pad = NULL;
1231
1232                                         _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret);
1233                                 }
1234                         }
1235
1236                         /* Wait EOS */
1237                         _mmstreamrec_dbg_log("Start to wait EOS");
1238                         ret = _mmstreamrecorder_get_eos_message(handle);
1239                         if (ret != MM_ERROR_NONE) {
1240                                 info->b_commiting = FALSE;
1241                                 goto _ERR_STREAMRECORDER_VIDEO_COMMAND;
1242                         }
1243                 }
1244                 break;
1245         default:
1246                 ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT;
1247                 break;
1248         }
1249         return MM_ERROR_NONE;
1250
1251  _ERR_STREAMRECORDER_VIDEO_COMMAND:
1252         if (ret != MM_ERROR_NONE)
1253                 _mmstreamrec_dbg_err("Current Videosrc status");
1254
1255         return ret;
1256 }
1257
1258 int _mmstreamrecorder_video_handle_eos(MMHandleType handle)
1259 {
1260         int ret = MM_ERROR_NONE;
1261
1262         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1263         _MMStreamRecorderSubContext *sc = NULL;
1264         _MMStreamRecorderVideoInfo *info = NULL;
1265         _MMStreamRecorderAudioInfo *info_audio = NULL;
1266         _MMStreamRecorderFileInfo *finfo = NULL;
1267         _MMStreamRecorderMsgItem msg;
1268         MMStreamRecordingReport *report = NULL;
1269
1270         mmf_return_val_if_fail(hstreamrecorder, FALSE);
1271
1272         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1273         mmf_return_val_if_fail(sc, FALSE);
1274         mmf_return_val_if_fail(sc->info_video, FALSE);
1275         if (sc->audio_enable == TRUE)
1276                 mmf_return_val_if_fail(sc->info_audio, FALSE);
1277
1278         mmf_return_val_if_fail(sc->info_file, FALSE);
1279
1280         info = sc->info_video;
1281         if (sc->audio_enable == TRUE)
1282                 info_audio = sc->info_audio;
1283
1284         finfo = sc->info_file;
1285
1286         _mmstreamrec_dbg_err("");
1287
1288         /* remove blocking part */
1289         MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1290
1291         ret = _mmstreamrecorder_destroy_recorder_pipeline(handle);
1292         if (ret != MM_ERROR_NONE)
1293                 _mmstreamrec_dbg_warn("_mmstreamrecorder_destroy_recorder_pipeline failed. error[%x]", ret);
1294
1295         /* Send recording report to application */
1296         msg.id = MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED;
1297         report = (MMStreamRecordingReport *) g_malloc(sizeof(MMStreamRecordingReport));
1298         if (!report) {
1299                 _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename);
1300         } else {
1301                 report->recording_filename = g_strdup(finfo->filename);
1302                 msg.param.data = report;
1303                 msg.param.code = 1;
1304                 _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg);
1305         }
1306
1307         /* Finishing */
1308         sc->pipeline_time = 0;
1309         sc->pause_time = 0;
1310         sc->isMaxsizePausing = FALSE;   /*In async function, this variable should set in callback function. */
1311         sc->isMaxtimePausing = FALSE;
1312         sc->error_occurs = FALSE;
1313
1314         info->video_frame_count = 0;
1315         if (info_audio)
1316                 info_audio->audio_frame_count = 0;
1317
1318         info->filesize = 0;
1319         g_free(finfo->filename);
1320         finfo->filename = NULL;
1321         info->b_commiting = FALSE;
1322
1323         _mmstreamrec_dbg_err("_mmstreamrecorder_video_handle_eos : end");
1324
1325         return TRUE;
1326 }
1327
1328 int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
1329 {
1330         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1331         _MMStreamRecorderSubContext *sc = NULL;
1332         /* GstPad *srcpad = NULL; */
1333         GstCaps *srccaps = NULL;
1334         char *err_name = NULL;
1335         int video_fps = 0;
1336         int video_src = 0;
1337         int video_width = 0;
1338         int video_height = 0;
1339         int ret = MM_ERROR_NONE;
1340         int video_source_format = 0;
1341
1342         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1343
1344         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1345         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1346
1347         if (buffer == NULL || size == 0) {
1348                 _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
1349                 return MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
1350         }
1351
1352         _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp);
1353
1354         /* check element availability */
1355         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);
1356
1357         if (ret != MM_ERROR_NONE) {
1358                 _mmstreamrec_dbg_err("Error in mm_streamrecorder_get_attributes (%s:%d)", err_name, ret);
1359                 SAFE_FREE(err_name);
1360                 return ret;
1361         }
1362
1363         if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst) {
1364
1365                 /*_mmstreamrec_dbg_log("Buffer Push start , time stamp %ld",timestamp);*/
1366                 /* srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src"); */
1367                 /* srccaps = gst_pad_get_current_caps(srcpad); */
1368                 srccaps = gst_set_videosrcpad_caps(video_src, video_width, video_height, video_fps, 1);
1369                 if (srccaps) {
1370                         gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps);
1371                         gst_caps_unref(srccaps);
1372                         srccaps = NULL;
1373                 }
1374
1375                 /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/
1376                 ret = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, buffer);
1377                 if (ret) {
1378                         _mmstreamrec_dbg_err("video gst_app_src_push_buffer %d", ret);
1379                         ret = MM_ERROR_STREAMRECORDER_VIDEOBUFFER_PUSH;
1380                 }
1381
1382                 /* g_signal_emit_by_name(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "push-buffer", newbuf, &ret); */
1383         }
1384
1385         return ret;
1386 }
1387
1388 int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size)
1389 {
1390         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
1391         _MMStreamRecorderSubContext *sc = NULL;
1392         _MMStreamRecorderAudioInfo *info = NULL;
1393         GstFlowReturn err = GST_FLOW_OK;
1394         GstPad *srcpad = NULL;
1395         GstCaps *srccaps = NULL;
1396         int rate = 0;
1397         int channel = 0;
1398         int depth = 0;
1399
1400         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1401
1402         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
1403         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1404
1405         info = (_MMStreamRecorderAudioInfo *) sc->info_audio;
1406         mmf_return_val_if_fail(info, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
1407
1408         rate = info->iSamplingRate;
1409         depth = info->audio_encode_depth;
1410         channel = info->iChannels;
1411
1412         /*_mmstreamrec_dbg_log("Audio Buffer Push start , time stamp %ld",timestamp); */
1413
1414         if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst) {
1415
1416                 srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src");
1417                 /* TODO : CHANNEL , WIDTH, DATATYPE */
1418                 srccaps = gst_pad_get_current_caps(srcpad);
1419                 srccaps = gst_set_audiosrcpad_caps(rate, channel, depth, 16, 1);
1420                 gst_base_src_set_caps(GST_BASE_SRC(srcpad), srccaps);
1421
1422                 err = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, buffer);
1423
1424                 if (err) {
1425                         _mmstreamrec_dbg_err("Audio gst_app_src_push_buffer %d", err);
1426                         return MM_ERROR_STREAMRECORDER_AUDIOBUFFER_PUSH;
1427                 }
1428         }
1429
1430         return MM_ERROR_NONE;
1431 }
1432