Updated to version 0.7.16 from tizendev
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_audiorec.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jeongmo Yang <jm80.yang@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_camcorder_internal.h"
26 #include "mm_camcorder_audiorec.h"
27 #include <math.h>
28
29 /*---------------------------------------------------------------------------------------
30 |    GLOBAL VARIABLE DEFINITIONS for internal                                           |
31 ---------------------------------------------------------------------------------------*/
32 #define MM_CAMCORDER_START_CHANGE_STATE _MMCamcorderStartHelperFunc((void *)hcamcorder)
33 #define MM_CAMCORDER_STOP_CHANGE_STATE _MMCamcorderStopHelperFunc((void *)hcamcorder)
34 /*---------------------------------------------------------------------------------------
35 |    LOCAL VARIABLE DEFINITIONS for internal                                            |
36 ---------------------------------------------------------------------------------------*/
37 #define RESET_PAUSE_TIME                        0
38 #define _MMCAMCORDER_AUDIO_MINIMUM_SPACE        (100*1024)
39 #define _MMCAMCORDER_AUDIO_MARGIN_SPACE         (1*1024)
40 #define _MMCAMCORDER_RETRIAL_COUNT              10
41 #define _MMCAMCORDER_FRAME_WAIT_TIME            20000 /* micro second */
42 #define _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL  5
43 /*---------------------------------------------------------------------------------------
44 |    LOCAL FUNCTION PROTOTYPES:                                                         |
45 ---------------------------------------------------------------------------------------*/
46 /* STATIC INTERNAL FUNCTION */
47 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
48 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
49 static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle);
50 static void __mmcamcorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle);
51
52 /*=======================================================================================
53 |  FUNCTION DEFINITIONS                                                                 |
54 =======================================================================================*/
55
56 /*---------------------------------------------------------------------------------------
57 |    GLOBAL FUNCTION DEFINITIONS:                                                       |
58 ---------------------------------------------------------------------------------------*/
59
60 static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
61 {
62         int err = MM_ERROR_NONE;
63         char *aenc_name = NULL;
64         char *mux_name = NULL;
65
66         GstBus *bus = NULL;
67         GstPad *srcpad = NULL;
68         GstPad *sinkpad = NULL;
69         GList *element_list = NULL;
70
71         _MMCamcorderAudioInfo *info = NULL;
72         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
73         _MMCamcorderSubContext *sc = NULL;
74         type_element *aenc_elem = NULL;
75         type_element *mux_elem = NULL;
76
77         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
78         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
79
80         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
81         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
82         mmf_return_val_if_fail(sc->info_audio, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
83
84         info = (_MMCamcorderAudioInfo *)sc->info_audio;
85         
86         _mmcam_dbg_log("");
87
88         mux_elem = _mmcamcorder_get_type_element(handle, MM_CAM_FILE_FORMAT);
89         err = _mmcamcorder_conf_get_value_element_name( mux_elem, &mux_name );
90
91         if (!mux_name || !strcmp( mux_name, "wavenc" ) ) /* IF MUX in not chosen then record in raw amr file */
92         {
93                 //But shoud we support non-mux recording??
94                 _mmcam_dbg_log("Record without muxing.");
95                 info->bMuxing = FALSE;
96         }
97         else
98         {
99                 _mmcam_dbg_log("Record with mux.");
100                 info->bMuxing = TRUE;
101         }
102
103         //Create gstreamer element
104         //Main pipeline
105         __ta__("            camcorder_pipeline",  
106         _MMCAMCORDER_PIPELINE_MAKE(sc, _MMCAMCORDER_MAIN_PIPE, "camcorder_pipeline", err);
107         );
108
109         __ta__("        __mmcamcorder_create_audiosrc_bin",
110         err = _mmcamcorder_create_audiosrc_bin(handle);
111         );
112         if (err != MM_ERROR_NONE) {
113                 return err;
114         }
115
116         if (info->bMuxing) {
117                 /* Muxing. can use encodebin. */
118                 __ta__("        _mmcamcorder_create_encodesink_bin",
119                 err = _mmcamcorder_create_encodesink_bin((MMHandleType)hcamcorder, MM_CAMCORDER_ENCBIN_PROFILE_AUDIO);
120                 );
121                 if (err != MM_ERROR_NONE ) {
122                         return err;
123                 }
124         } else {
125                 /* without muxing. can't use encodebin. */
126                 aenc_elem = _mmcamcorder_get_type_element(handle, MM_CAM_AUDIO_ENCODER);
127                 if (!aenc_elem)
128                 {
129                         _mmcam_dbg_err("Fail to get type element");
130                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
131                         goto pipeline_creation_error;
132                 }
133
134                 err = _mmcamcorder_conf_get_value_element_name(aenc_elem, &aenc_name);
135
136                 if ((!err) || (!aenc_name))
137                 {
138                         _mmcam_dbg_err("Fail to get element name");
139                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
140                         goto pipeline_creation_error;
141                 }
142
143                 __ta__("        audiopipeline_audioqueue",  
144                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_AQUE, "queue",  NULL, element_list, err);
145                 );
146
147                 if( strcmp( aenc_name, "wavenc" ) != 0 )
148                 {
149                         __ta__("        audiopipeline_audioconvertor",
150                         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_CONV, "audioconvert",  NULL, element_list, err);
151                         );
152                 }
153
154                 __ta__("        audiopipeline_audioencoder",  
155                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_AENC, aenc_name, NULL, element_list, err);
156                 );
157
158                 __ta__("        audiopipeline_filesink",  
159                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
160                 );
161
162                 /* audio encoder attribute setting */
163                 if(strcmp(aenc_name,"ari_amrnbenc") == 0) //ari_armnbenc supports attatching amr header
164                 {
165                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "write-header", TRUE);
166                 }
167                 
168         }
169
170         //Set basic infomation
171
172         if (info->bMuxing) /* IF MUX is indicated create MUX */
173         {
174                 gst_bin_add_many(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
175                                                                  sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
176                                                                  sc->element[_MMCAMCORDER_ENCSINK_BIN].gst,
177                                                                  NULL);
178
179                 srcpad = gst_element_get_static_pad (sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst, "src");
180                 sinkpad = gst_element_get_static_pad (sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, "audio_sink0");
181                 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
182         }
183         else /* IF MUX in not chosen then record in raw amr file */
184         {
185                 if( !strcmp( aenc_name, "wavenc" ) )
186                 {
187                         gst_bin_add_many( GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
188                                           sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
189                                           sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst,
190                                           sc->element[_MMCAMCORDER_ENCSINK_AENC].gst,
191                                           sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
192                                           NULL );
193
194                         if (!_MM_GST_ELEMENT_LINK_MANY( sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
195                                                         sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst,
196                                                         sc->element[_MMCAMCORDER_ENCSINK_AENC].gst,
197                                                         sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
198                                                         NULL ))
199                         {
200                                 err = MM_ERROR_CAMCORDER_GST_LINK;
201                                 goto pipeline_creation_error;
202                         }
203                 }
204                 else
205                 {
206                         gst_bin_add_many( GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
207                                           sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
208                                           sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst,
209                                           sc->element[_MMCAMCORDER_ENCSINK_CONV].gst,
210                                           sc->element[_MMCAMCORDER_ENCSINK_AENC].gst,
211                                           sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
212                                           NULL );
213
214                         if (!_MM_GST_ELEMENT_LINK_MANY( sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
215                                                         sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst,
216                                                         sc->element[_MMCAMCORDER_ENCSINK_CONV].gst,
217                                                         sc->element[_MMCAMCORDER_ENCSINK_AENC].gst,
218                                                         sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
219                                                         NULL ))
220                         {
221                                 err = MM_ERROR_CAMCORDER_GST_LINK;
222                                 goto pipeline_creation_error;
223                         }
224                 }
225         }       
226
227
228         //set data probe function
229         srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_AUDIOSRC_SRC].gst, "src");
230         MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_AUDIOREC,
231                 __mmcamcorder_audio_dataprobe_voicerecorder, hcamcorder);       
232         gst_object_unref(srcpad);
233         srcpad = NULL;
234
235         if(info->bMuxing)
236         {
237                 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst, 
238                                                                                 _MMCAMCORDER_HANDLER_AUDIOREC, 
239                                                                                 "pad-added", 
240                                                                                 __mmcamcorder_audiorec_pad_added_cb, 
241                                                                                 hcamcorder);            
242         }
243         else
244         {
245                 srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "src");
246                 MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_AUDIOREC,
247                         __mmcamcorder_audio_dataprobe_record, hcamcorder);
248                 gst_object_unref(srcpad);
249                 srcpad = NULL;          
250         }
251
252         /*
253          * To get the message callback from the gstreamer.
254          * This can be used to make the API calls asynchronous
255          * as per LiMO compliancy
256          */
257         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
258         hcamcorder->pipeline_cb_event_id = gst_bus_add_watch( bus, (GstBusFunc)_mmcamcorder_pipeline_cb_message, hcamcorder );
259     gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, hcamcorder, NULL);
260         gst_object_unref(bus);
261
262         return MM_ERROR_NONE;
263
264 pipeline_creation_error:
265         return err;
266 }
267
268
269 int
270 _mmcamcorder_create_audio_pipeline(MMHandleType handle)
271 {
272         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
273         _MMCamcorderSubContext *sc = NULL;
274         
275         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
276         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
277
278         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
279
280         return __mmcamcorder_create_audiop_with_encodebin(handle);
281 }
282
283
284 /**
285  * This function destroy audio pipeline.
286  *
287  * @param[in]   handle          Handle of camcorder.
288  * @return      void
289  * @remarks
290  * @see         _mmcamcorder_destroy_pipeline()
291  *
292  */
293 void
294 _mmcamcorder_destroy_audio_pipeline(MMHandleType handle)
295 {
296         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
297         _MMCamcorderSubContext *sc = NULL;
298         _MMCamcorderAudioInfo *info = NULL;
299         mmf_return_if_fail(hcamcorder);
300         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
301
302         mmf_return_if_fail(sc && sc->info_audio);
303         mmf_return_if_fail(sc->element);
304
305         info = sc->info_audio;
306         
307         _mmcam_dbg_log("");
308
309         if(sc->element[_MMCAMCORDER_MAIN_PIPE].gst)
310         {
311                 _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_NULL);
312
313                 _mmcamcorder_remove_all_handlers((MMHandleType)hcamcorder, _MMCAMCORDER_HANDLER_CATEGORY_ALL);
314                 
315                 if( info->bMuxing)
316                 {
317                         GstPad *reqpad = NULL;
318                         //release request pad
319                         /* FIXME */
320                         /*
321                             The ref_count of mux is always # of streams in here, i don't know why it happens. 
322                             So, i unref the mux manually 
323                         */                              
324                         reqpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "audio");
325                         gst_element_release_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, reqpad);
326                         gst_object_unref(reqpad);       
327                         
328                         if(GST_IS_ELEMENT(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst) && \
329                                 GST_OBJECT_REFCOUNT_VALUE(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst) > 1)                                       
330                                 gst_object_unref(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst);
331                 }
332                 gst_object_unref(sc->element[_MMCAMCORDER_MAIN_PIPE].gst);
333 //              sc->element[_MMCAMCORDER_MAIN_PIPE].gst = NULL;
334         }
335
336 }
337
338
339 /**
340  * This function operates each command on audio mode.
341  *
342  * @param       c               [in]    Handle of camcorder context.
343  * @param       command [in]    command type received from Multimedia Framework.
344  *
345  * @return      This function returns MM_ERROR_NONE on success, or the other values
346  *                      on error.
347  * @remark
348  * @see         _mmcamcorder_set_functions()
349  *
350  */
351  /* ADDED BY SISO */
352
353
354 void* _MMCamcorderStartHelperFunc(void *handle)
355 {
356         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
357         _mmcamcorder_set_state((MMHandleType)hcamcorder, hcamcorder->target_state);
358
359         return NULL;
360 }
361
362 void* _MMCamcorderStopHelperFunc(void *handle)
363 {
364         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);     
365         _mmcamcorder_set_state((MMHandleType)hcamcorder, hcamcorder->target_state);
366
367         return NULL;
368 }
369
370
371 int
372 _mmcamcorder_audio_command(MMHandleType handle, int command)
373 {
374         int cmd = command;
375         int ret = MM_ERROR_NONE;
376         int err = 0;
377         int size=0;
378         guint64 free_space = 0;
379         char *dir_name = NULL;
380         char *err_attr_name = NULL;
381
382         GstElement *pipeline = NULL;
383         GstElement *audioSrc = NULL;
384
385         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
386         _MMCamcorderSubContext *sc = NULL;
387         _MMCamcorderAudioInfo *info = NULL;
388
389         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
390         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
391
392         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
393         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
394         mmf_return_val_if_fail(sc->info_audio, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
395         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
396         info = sc->info_audio;
397
398         _mmcam_dbg_log("");
399
400         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
401         audioSrc = sc->element[_MMCAMCORDER_AUDIOSRC_SRC].gst;
402         switch(cmd)
403         {
404                 case _MMCamcorder_CMD_RECORD:
405                         //check status for resume case
406                         if (_mmcamcorder_get_state((MMHandleType)hcamcorder) != MM_CAMCORDER_STATE_PAUSED) 
407                         {
408                                 guint imax_size = 0;
409                                 guint imax_time = 0;
410                                 char *temp_filename = NULL;
411
412                                 if(sc->pipeline_time) {
413                     gst_element_set_start_time(GST_ELEMENT(pipeline), sc->pipeline_time);
414                                 }
415                                 sc->pipeline_time = RESET_PAUSE_TIME;
416
417                                 ret = mm_camcorder_get_attributes(handle, &err_attr_name,
418                                                                   MMCAM_TARGET_MAX_SIZE, &imax_size,
419                                                                   MMCAM_TARGET_TIME_LIMIT, &imax_time,
420                                                                   MMCAM_FILE_FORMAT, &(info->fileformat),
421                                                                   MMCAM_TARGET_FILENAME, &temp_filename, &size,
422                                                                   NULL);
423                                 if (ret != MM_ERROR_NONE) {
424                                         _mmcam_dbg_warn("failed to get attribute. (%s:%x)", err_attr_name, ret);
425                                         SAFE_FREE (err_attr_name);
426                                         goto _ERR_CAMCORDER_AUDIO_COMMAND;
427                                 }
428
429                                 info->filename = strdup(temp_filename);
430                                 if (!info->filename)
431                                 {
432                                         _mmcam_dbg_err("STRDUP was failed");
433                                         goto _ERR_CAMCORDER_AUDIO_COMMAND;
434                                 }
435                                 
436                                 _mmcam_dbg_log("Record start : set file name using attribute - %s\n ",info->filename);
437
438                                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
439
440                                 sc->ferror_send = FALSE;
441                                 sc->ferror_count = 0;
442                                 sc->bget_eos = FALSE;
443                                 info->filesize =0;
444
445                                 /* set max size */
446                                 if (imax_size <= 0) {
447                                         info->max_size = 0; /* do not check */
448                                 } else {
449                                         info->max_size = ((guint64)imax_size) << 10; /* to byte */
450                                 }
451
452                                 /* set max time */
453                                 if (imax_time <= 0) {
454                                         info->max_time = 0; /* do not check */
455                                 } else {
456                                         info->max_time = ((guint64)imax_time) * 1000; /* to millisecond */
457                                 }
458
459                                 dir_name = g_path_get_dirname(info->filename);
460                                 if (dir_name) {
461                                         err = _mmcamcorder_get_freespace(dir_name, &free_space);
462
463                                         _mmcam_dbg_warn("current space for recording - %s : [%" G_GUINT64_FORMAT "]",
464                                                         dir_name, free_space);
465
466                                         g_free(dir_name);
467                                         dir_name = NULL;
468                                 } else {
469                                         _mmcam_dbg_err("failed to get directory name");
470                                         err = -1;
471                                 }
472
473                                 if ((err == -1) || free_space <= (_MMCAMCORDER_AUDIO_MINIMUM_SPACE+(5*1024))) {
474                                         _mmcam_dbg_err("OUT of STORAGE [err:%d or free space [%" G_GUINT64_FORMAT "] is smaller than [%d]",
475                                                        err, free_space, (_MMCAMCORDER_AUDIO_MINIMUM_SPACE+(5*1024)));
476                                         return MM_ERROR_OUT_OF_STORAGE;
477                                 }
478                         }
479
480                         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
481                         if(ret<0) {
482                                 goto _ERR_CAMCORDER_AUDIO_COMMAND;
483                         }
484                         break;
485
486                 case _MMCamcorder_CMD_PAUSE:
487                         {
488                                 GstClock *clock = NULL;
489                                 int count = 0;
490                                 
491                                 if (info->b_commiting)
492                                 {
493                                         _mmcam_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
494                                         return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
495                                 }
496
497                                 for(count=0; count <= _MMCAMCORDER_RETRIAL_COUNT ; count++)
498                                 {
499                                         if(info->filesize > 0)
500                                         {
501                                                 break;
502                                         }
503                                         else if(count == _MMCAMCORDER_RETRIAL_COUNT)
504                                         {
505                                                 _mmcam_dbg_err("Pause fail, we are waiting for 100 milisecond, but still file size is %" G_GUINT64_FORMAT "", 
506                                                                         info->filesize);
507                                                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
508                                         }
509                                         else
510                                         {
511                                                 _mmcam_dbg_warn("Pause is Waiting for enough audio frame, retrial count[%d], file size is %" G_GUINT64_FORMAT "", 
512                                                                         count, info->filesize);                                 
513                                         }
514                                         usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
515                                 }
516
517                                 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PAUSED);
518                                 if(ret<0) {
519                                         goto _ERR_CAMCORDER_AUDIO_COMMAND;
520                                 }       
521                                 //fixed me. consider delay.
522                                 clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
523                                 sc->pipeline_time = gst_clock_get_time(clock) - gst_element_get_base_time(GST_ELEMENT(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
524                         }
525                         break;
526
527                 case _MMCamcorder_CMD_CANCEL:
528                         if (info->b_commiting)
529                         {
530                                 _mmcam_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
531                                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
532                         }
533                         
534 //                      ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_NULL);
535                         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
536                         if(ret<0) {
537                                 goto _ERR_CAMCORDER_AUDIO_COMMAND;
538                         }
539
540                         if(info->bMuxing)
541                         {
542                                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
543                         }
544                         else
545                         {
546                                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
547                         }
548
549                         _mmcamcorder_gst_set_state(handle,  sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, GST_STATE_NULL);
550
551                         sc->pipeline_time = 0;
552                         sc->pause_time = 0;
553                         sc->isMaxsizePausing = FALSE;
554                         sc->isMaxtimePausing = FALSE;
555                         
556                         if(info->filename)
557                         {
558                                 _mmcam_dbg_log("file delete(%s)", info->filename);
559                                 unlink(info->filename);
560                                 g_free(info->filename);
561                                 info->filename = NULL;                                  
562                         }
563
564                         break;
565                 case _MMCamcorder_CMD_COMMIT:
566                 {
567                         int count = 0;
568                         g_print("\n\n _MMCamcorder_CMD_COMMIT\n\n");
569
570                         if (info->b_commiting)
571                         {
572                                 _mmcam_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd);
573                                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
574                         }
575                         else
576                         {
577                                 _mmcam_dbg_log("_MMCamcorder_CMD_COMMIT : start");
578                                 info->b_commiting = TRUE;
579                         }                       
580                         
581                         for(count=0; count <= _MMCAMCORDER_RETRIAL_COUNT ; count++)
582                         {
583                                 if(info->filesize > 0)
584                                 {
585                                         break;
586                                 }
587                                 else if(count == _MMCAMCORDER_RETRIAL_COUNT)
588                                 {
589                                         _mmcam_dbg_err("Commit fail, we are waiting for 100 milisecond, but still file size is %" G_GUINT64_FORMAT "", 
590                                                                 info->filesize);
591                                         info->b_commiting = FALSE;
592                                         return MM_ERROR_CAMCORDER_INVALID_CONDITION;                                            
593                                 }
594                                 else
595                                 {
596                                         _mmcam_dbg_warn("Commit is Waiting for enough audio frame, retrial count[%d], file size is %" G_GUINT64_FORMAT "", 
597                                                                 count, info->filesize);                                 
598                                 }
599                                 usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
600                         }
601                         
602                         if (audioSrc) {
603                                 GstPad *pad = gst_element_get_static_pad (audioSrc, "src");
604 //                              gst_pad_push_event (pad, gst_event_new_eos());
605                                 ret = gst_element_send_event(audioSrc, gst_event_new_eos());
606                                 gst_object_unref(pad);
607                                 pad = NULL;                                     
608                                 if (_mmcamcorder_get_state((MMHandleType)hcamcorder) == MM_CAMCORDER_STATE_PAUSED) // for pause -> commit case
609                                 {                               
610                                         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);  
611                                         if(ret<0) {
612                                                 goto _ERR_CAMCORDER_AUDIO_COMMAND;
613                                         }                               
614                                 }
615                                 
616                         }
617
618                         //wait until finishing EOS
619                         _mmcam_dbg_log("Start to wait EOS");
620                         if ((ret =_mmcamcorder_get_eos_message(handle)) != MM_ERROR_NONE)
621                         {
622                                 goto _ERR_CAMCORDER_AUDIO_COMMAND;
623                         }
624 /*
625                          while ((!sc->get_eos)&&((retry_cnt--) > 0)) {
626                                 if ((gMessage = gst_bus_timed_pop (bus, timeout)) != NULL)
627                                 {
628                                         if (GST_MESSAGE_TYPE(gMessage) ==GST_MESSAGE_EOS)
629                                         {
630                                                 _mmcam_dbg_log("Get a EOS message");
631                                                 gst_message_unref(gMessage);
632                                                 break;
633                                         }
634                                         else
635                                         {
636                                                 _mmcam_dbg_log("Get another message(%x). Post this message to bus again.", GST_MESSAGE_TYPE(gMessage));
637                                                 gst_bus_post(bus, gMessage);
638                                         }
639                                 }
640                                 else
641                                 {
642                                         _mmcam_dbg_log("timeout of gst_bus_timed_pop()");
643                                         break;
644                                 }                                       
645                                 
646                                 usleep(100);            //To Prevent busy waiting
647                         }
648
649                         _mmcamcorder_audio_handle_eos((MMHandleType)hcamcorder);
650 */
651
652
653                 }
654                         break;
655
656                 case _MMCamcorder_CMD_PREVIEW_START:
657                 //      MM_CAMCORDER_START_CHANGE_STATE; 
658                         break;
659                 case _MMCamcorder_CMD_PREVIEW_STOP:
660                 //      MM_CAMCORDER_STOP_CHANGE_STATE; 
661                         //void
662                         break;
663
664                 default:
665                         ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
666                         break;
667         }
668
669 _ERR_CAMCORDER_AUDIO_COMMAND:
670         return ret;
671
672 }
673
674 int
675 _mmcamcorder_audio_handle_eos(MMHandleType handle)
676 {
677         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
678         _MMCamcorderSubContext *sc = NULL;
679         _MMCamcorderAudioInfo   *info   = NULL;
680         GstElement                              *pipeline = NULL;
681         _MMCamcorderMsgItem msg;
682         MMCamRecordingReport * report;
683
684         int err = MM_ERROR_NONE;
685                 
686         mmf_return_val_if_fail(hcamcorder, FALSE);
687         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
688
689         mmf_return_val_if_fail(sc, FALSE);
690         mmf_return_val_if_fail(sc->info_audio, FALSE);
691         
692         _mmcam_dbg_err("");
693
694         info = sc->info_audio;
695
696         //changing pipeline for display
697         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
698         
699
700         __ta__("        _MMCamcorder_CMD_COMMIT:GST_STATE_READY",  
701         err = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
702         );
703
704         if( err != MM_ERROR_NONE )
705         {
706                 _mmcam_dbg_warn( "Failed:_MMCamcorder_CMD_COMMIT:GST_STATE_READY. err[%x]", err );
707         }
708
709 //      __ta__("        _MMCamcorder_CMD_COMMIT:GST_STATE_NULL",  
710 //      _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_NULL);
711 //      )       
712
713         //Send message  
714         //Send recording report to application
715         msg.id = MM_MESSAGE_CAMCORDER_AUDIO_CAPTURED;
716
717         report = (MMCamRecordingReport*) malloc(sizeof(MMCamRecordingReport));  //who free this?
718         if (!report)
719         {
720                 //think more.
721                 _mmcam_dbg_err("Recording report fail(%s). Out of memory.", info->filename);
722                 return FALSE;
723         }
724
725         report->recording_filename = strdup(info->filename);
726         msg.param.data= report;
727
728         _mmcamcroder_send_message(handle, &msg);
729
730         
731         if(info->bMuxing)
732         {
733                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
734         }
735         else
736         {
737                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE);
738         }       
739         _mmcamcorder_gst_set_state(handle,  sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, GST_STATE_NULL);
740
741         sc->pipeline_time = 0;
742         sc->pause_time = 0;
743         sc->isMaxsizePausing = FALSE;
744         sc->isMaxtimePausing = FALSE;
745
746         g_free(info->filename);
747         info->filename = NULL;
748
749         _mmcam_dbg_err("_MMCamcorder_CMD_COMMIT : end");
750
751         info->b_commiting = FALSE;
752
753         return TRUE;
754 }
755
756
757 static float
758 __mmcamcorder_get_decibel(unsigned char* raw, int size, MMCamcorderAudioFormat format)
759 {
760         #define MAX_AMPLITUDE_MEAN_16BIT 23170.115738161934
761         #define MAX_AMPLITUDE_MEAN_08BIT    89.803909382810
762
763         int i = 0;
764         int depthByte = 0;
765         int count = 0;
766
767         short* pcm16 = 0;
768         char* pcm8 = 0;
769
770         float db = 0.0;
771         float rms = 0.0;
772         unsigned long long square_sum = 0;
773
774         if (format == MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE)
775                 depthByte = 2;
776         else            //MM_CAMCORDER_AUDIO_FORMAT_PCM_U8
777                 depthByte = 1;
778
779         for( ; i < size ; i += (depthByte<<1) )
780         {
781                 if (depthByte == 1)
782                 {
783                         pcm8 = (char *)(raw + i);
784                         square_sum += (*pcm8)*(*pcm8);
785                 }
786                 else            //2byte
787                 {
788                         pcm16 = (short*)(raw + i);
789                         square_sum += (*pcm16)*(*pcm16);
790                 }
791
792                 count++;
793         }
794
795         rms = sqrt( square_sum/count );
796
797         if (depthByte == 1)
798                 db = 20 * log10( rms/MAX_AMPLITUDE_MEAN_08BIT );
799         else
800                 db = 20 * log10( rms/MAX_AMPLITUDE_MEAN_16BIT );
801
802         /*
803         _mmcam_dbg_log("size[%d],depthByte[%d],count[%d],rms[%f],db[%f]",
804                        size, depthByte, count, rms, db);
805         */
806
807         return db;
808 }
809
810
811 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
812 {
813         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
814         double volume = 0.0;
815         int format = 0;
816         int channel = 0;
817         float curdcb = 0.0;
818         _MMCamcorderMsgItem msg;
819         int err = MM_ERROR_UNKNOWN;
820         char *err_name = NULL;
821     GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
822     GstMapInfo mapinfo = GST_MAP_INFO_INIT;
823
824         mmf_return_val_if_fail(hcamcorder, FALSE);
825
826         /* Set volume to audio input */
827         err = mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_name,
828                                                                         MMCAM_AUDIO_VOLUME, &volume,
829                                                                         MMCAM_AUDIO_FORMAT, &format,
830                                                                         MMCAM_AUDIO_CHANNEL, &channel,
831                                                                         NULL);
832         if (err < 0) 
833         {
834                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
835                 SAFE_FREE (err_name);
836                 return err;
837         }
838         
839         if(volume == 0) //mute
840     {
841         gst_buffer_map(buffer, &mapinfo, GST_MAP_WRITE);
842         memset(mapinfo.data, 0, mapinfo.size);
843         gst_buffer_unmap(buffer, &mapinfo);
844     }
845
846         /* Get current volume level of real input stream */
847     gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
848 //      currms = __mmcamcorder_get_RMS(GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer), depth);
849         __ta__( "__mmcamcorder_get_decibel",
850     curdcb = __mmcamcorder_get_decibel(mapinfo.data, mapinfo.size, format);
851         );
852
853         msg.id = MM_MESSAGE_CAMCORDER_CURRENT_VOLUME;
854         msg.param.rec_volume_dB = curdcb;
855         _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
856
857         /* CALL audio stream callback */
858     if ((hcamcorder->astream_cb) && buffer && mapinfo.data && mapinfo.size > 0)
859         {
860                 MMCamcorderAudioStreamDataType stream;
861
862                 if (_mmcamcorder_get_state((MMHandleType)hcamcorder) < MM_CAMCORDER_STATE_PREPARE)
863                 {
864                         _mmcam_dbg_warn("Not ready for stream callback");
865             gst_buffer_unmap(buffer, &mapinfo);
866             return GST_PAD_PROBE_OK;
867                 }
868
869                 /*
870                 _mmcam_dbg_log("Call audio steramCb, data[%p], format[%d], channel[%d], length[%d], volume_dB[%f]",
871                                GST_BUFFER_DATA(buffer), format, channel, GST_BUFFER_SIZE(buffer), curdcb);
872                 */
873
874         stream.data = mapinfo.data;
875                 stream.format = format;
876                 stream.channel = channel;
877         stream.length = mapinfo.size;
878                 stream.timestamp = (unsigned int)(GST_BUFFER_TIMESTAMP(buffer)/1000000);        //nano -> msecond
879                 stream.volume_dB = curdcb;
880
881                 _MMCAMCORDER_LOCK_ASTREAM_CALLBACK( hcamcorder );
882
883                 if(hcamcorder->astream_cb)
884                 {
885                         hcamcorder->astream_cb(&stream, hcamcorder->astream_cb_param);
886                 }
887
888                 _MMCAMCORDER_UNLOCK_ASTREAM_CALLBACK( hcamcorder );
889         }
890     gst_buffer_unmap(buffer, &mapinfo);
891
892     return GST_PAD_PROBE_OK;
893 }
894
895
896 static void
897 __mmcamcorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad,  MMHandleType handle)
898 {
899         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
900
901         _mmcam_dbg_log("ENTER(%s)", GST_PAD_NAME(pad));
902         //FIXME : the name of audio sink pad of wavparse, oggmux doesn't have 'audio'. How could I handle the name?
903         if((strstr(GST_PAD_NAME(pad), "audio")) || (strstr(GST_PAD_NAME(pad), "sink")))
904         {
905                 MMCAMCORDER_ADD_BUFFER_PROBE(pad, _MMCAMCORDER_HANDLER_AUDIOREC,
906                         __mmcamcorder_audio_dataprobe_record, hcamcorder);
907         }
908         else
909         {
910                 _mmcam_dbg_warn("Unknow pad is added, check it : [%s]", GST_PAD_NAME(pad));     
911         }
912
913         return;
914 }
915
916
917 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
918 {
919         static int count = 0;
920         guint64 rec_pipe_time = 0;
921         guint64 free_space = 0;
922         guint64 buffer_size = 0;
923         guint64 trailer_size = 0;
924         char *filename = NULL;
925         unsigned long long remained_time = 0;
926
927         _MMCamcorderSubContext *sc = NULL;
928         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
929     _MMCamcorderAudioInfo *audioinfo = NULL;
930         _MMCamcorderMsgItem msg;
931     GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
932
933         mmf_return_val_if_fail(hcamcorder, FALSE);
934         mmf_return_val_if_fail(buffer, FALSE);
935
936         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
937         mmf_return_val_if_fail(sc && sc->info_audio, FALSE);
938     audioinfo = sc->info_audio;
939
940         if (sc->isMaxtimePausing || sc->isMaxsizePausing) {
941                 _mmcam_dbg_warn("isMaxtimePausing[%d],isMaxsizePausing[%d]",
942                                 sc->isMaxtimePausing, sc->isMaxsizePausing);
943         return GST_PAD_PROBE_DROP;
944         }
945
946     buffer_size = gst_buffer_get_size(buffer);
947
948     if (audioinfo->filesize == 0) {
949         if (audioinfo->fileformat == MM_FILE_FORMAT_WAV) {
950             audioinfo->filesize += 44; /* wave header size */
951         } else if (audioinfo->fileformat == MM_FILE_FORMAT_AMR) {
952             audioinfo->filesize += 6; /* amr header size */
953                 }
954
955         audioinfo->filesize += buffer_size;
956         return GST_PAD_PROBE_OK;
957         }
958
959         if (sc->ferror_send) {
960                 _mmcam_dbg_warn("file write error, drop frames");
961         return GST_PAD_PROBE_DROP;
962         }
963
964         /* get trailer size */
965     if (audioinfo->fileformat == MM_FILE_FORMAT_3GP ||
966         audioinfo->fileformat == MM_FILE_FORMAT_MP4 ||
967         audioinfo->fileformat == MM_FILE_FORMAT_AAC) {
968                 MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
969                 /*_mmcam_dbg_log("trailer_size %d", trailer_size);*/
970         } else {
971                 trailer_size = 0; /* no trailer */
972         }
973
974     filename = audioinfo->filename;
975
976         /* to minimizing free space check overhead */
977         count = count % _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL;
978         if (count++ == 0) {
979                 gint free_space_ret = _mmcamcorder_get_freespace(filename, &free_space);
980
981                 /*_mmcam_dbg_log("check free space for recording");*/
982
983                 switch (free_space_ret) {
984                 case -2: /* file not exist */
985                 case -1: /* failed to get free space */
986                         _mmcam_dbg_err("Error occured. [%d]", free_space_ret);
987                         if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
988                                 sc->ferror_send = TRUE;
989                                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
990                                 if (free_space_ret == -2) {
991                                         msg.param.code = MM_ERROR_FILE_NOT_FOUND;
992                                 } else {
993                                         msg.param.code = MM_ERROR_FILE_READ;
994                                 }
995                                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
996                         } else {
997                                 sc->ferror_count++;
998                         }
999
1000             return GST_PAD_PROBE_DROP; /* skip this buffer */
1001
1002                 default: /* succeeded to get free space */
1003                         /* check free space for recording */
1004                         if (free_space < (guint64)(_MMCAMCORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
1005                                 _mmcam_dbg_warn("No more space for recording!!!");
1006                                 _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]",
1007                                 free_space, audioinfo->filesize);
1008
1009                 if (audioinfo->bMuxing) {
1010                                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1011                                 } else {
1012                                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
1013                                 }
1014
1015                                 sc->isMaxsizePausing = TRUE;
1016                                 msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
1017                                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1018
1019                 return GST_PAD_PROBE_DROP; /* skip this buffer */
1020                         }
1021                         break;
1022                 }
1023         }
1024
1025         if (!GST_CLOCK_TIME_IS_VALID(GST_BUFFER_TIMESTAMP(buffer))) {
1026                 _mmcam_dbg_err("Buffer timestamp is invalid, check it");
1027                 return FALSE;
1028         }
1029
1030         rec_pipe_time = GST_TIME_AS_MSECONDS(GST_BUFFER_TIMESTAMP(buffer));
1031
1032         /* calculate remained time can be recorded */
1033     if (audioinfo->max_time > 0 && audioinfo->max_time < (remained_time + rec_pipe_time)) {
1034         remained_time = audioinfo->max_time - rec_pipe_time;
1035     } else if (audioinfo->max_size > 0) {
1036         long double max_size = (long double)audioinfo->max_size;
1037         long double current_size = (long double)(audioinfo->filesize + buffer_size + trailer_size);
1038
1039                 remained_time = (unsigned long long)((long double)rec_pipe_time * (max_size/current_size)) - rec_pipe_time;
1040         }
1041
1042         /*_mmcam_dbg_log("remained time : %u", remained_time);*/
1043
1044         /* check max size of recorded file */
1045     if (audioinfo->max_size > 0 &&
1046         audioinfo->max_size < audioinfo->filesize + buffer_size + trailer_size + _MMCAMCORDER_MMS_MARGIN_SPACE) {
1047                 _mmcam_dbg_warn("Max size!!! Recording is paused.");
1048                 _mmcam_dbg_warn("Max [%" G_GUINT64_FORMAT "], file [%" G_GUINT64_FORMAT "], trailer : [%" G_GUINT64_FORMAT "]", \
1049                         audioinfo->max_size, audioinfo->filesize, trailer_size);
1050
1051                 /* just same as pause status. After blocking two queue, this function will not call again. */
1052         if (audioinfo->bMuxing) {
1053                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1054                 } else {
1055                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
1056                 }
1057
1058                 msg.id = MM_MESSAGE_CAMCORDER_RECORDING_STATUS;
1059                 msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
1060         msg.param.recording_status.filesize = (unsigned long long)((audioinfo->filesize + trailer_size) >> 10);
1061                 msg.param.recording_status.remained_time = 0;
1062                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1063
1064         _mmcam_dbg_log("Last filesize sent by message : %d", audioinfo->filesize + trailer_size);
1065
1066                 sc->isMaxsizePausing = TRUE;
1067                 msg.id = MM_MESSAGE_CAMCORDER_MAX_SIZE;
1068                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1069
1070                 /* skip this buffer */
1071         return GST_PAD_PROBE_DROP;
1072         }
1073
1074         /* check recording time limit and send recording status message */
1075     if (audioinfo->max_time > 0 && rec_pipe_time > audioinfo->max_time) {
1076                 _mmcam_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", \
1077                         rec_pipe_time, audioinfo->max_time);
1078
1079         if (audioinfo->bMuxing) {
1080                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1081                 } else {
1082                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
1083                 }
1084
1085                 sc->isMaxtimePausing = TRUE;
1086                 msg.id = MM_MESSAGE_CAMCORDER_TIME_LIMIT;
1087                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1088
1089                 /* skip this buffer */
1090         return GST_PAD_PROBE_DROP;
1091         }
1092
1093         /* send message for recording time and recorded file size */
1094     if (audioinfo->b_commiting == FALSE) {
1095         audioinfo->filesize += buffer_size;
1096
1097                 msg.id = MM_MESSAGE_CAMCORDER_RECORDING_STATUS;
1098                 msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
1099         msg.param.recording_status.filesize = (unsigned long long)((audioinfo->filesize + trailer_size) >> 10);
1100                 msg.param.recording_status.remained_time = remained_time;
1101                 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1102
1103         return GST_PAD_PROBE_OK;
1104         } else {
1105                 /* skip this buffer if commit process has been started */
1106         return GST_PAD_PROBE_DROP;
1107         }
1108 }