[libmm-streamrecorder] initial code for new feature of streamrecorder
[platform/core/multimedia/libmm-streamrecorder.git] / src / mm_streamrecorder_internal.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 <stdio.h>
26 #include <string.h>
27 #include <mm_types.h>
28 #include <mm_error.h>
29
30 #include "mm_streamrecorder_internal.h"
31 #include "mm_streamrecorder_recorder.h"
32 #include "mm_streamrecorder_attribute.h"
33 #include "mm_streamrecorder_gstdispatch.h"
34
35 #include <asm/types.h>
36
37 /*---------------------------------------------------------------------------------------
38 |    GLOBAL VARIABLE DEFINITIONS for internal                                           |
39 ---------------------------------------------------------------------------------------*/
40
41 /*---------------------------------------------------------------------------------------
42 |    LOCAL VARIABLE DEFINITIONS for internal                                            |
43 ---------------------------------------------------------------------------------------*/
44 #define __MMSTREAMRECORDER_CMD_ITERATE_MAX           3
45
46 /*---------------------------------------------------------------------------------------
47 |    LOCAL FUNCTION PROTOTYPES:                                                         |
48 ---------------------------------------------------------------------------------------*/
49
50 /*=======================================================================================
51 |  FUNCTION DEFINITIONS                                                                 |
52 =======================================================================================*/
53 /*---------------------------------------------------------------------------------------
54 |    GLOBAL FUNCTION DEFINITIONS:                                                       |
55 ---------------------------------------------------------------------------------------*/
56
57 /* Internal command functions {*/
58 int _mmstreamrecorder_create(MMHandleType *handle)
59 {
60         int ret = MM_ERROR_NONE;
61         /* char *err_attr_name = NULL; */
62         mmf_streamrecorder_t *hstreamrecorder = NULL;
63
64         _mmstreamrec_dbg_log("Entered");
65         mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
66
67         /* Create mmf_streamrecorder_t handle and initialize every variable */
68         hstreamrecorder = (mmf_streamrecorder_t *) malloc(sizeof(mmf_streamrecorder_t));
69         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_LOW_MEMORY);
70         memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
71
72         /* init values */
73         hstreamrecorder->sub_context = NULL;
74
75         pthread_mutex_init(&((hstreamrecorder->mtsafe).lock), NULL);
76         pthread_cond_init(&((hstreamrecorder->mtsafe).cond), NULL);
77
78         pthread_mutex_init(&((hstreamrecorder->mtsafe).cmd_lock), NULL);
79         pthread_mutex_init(&((hstreamrecorder->mtsafe).state_lock), NULL);
80         pthread_mutex_init(&((hstreamrecorder->mtsafe).gst_state_lock), NULL);
81         pthread_mutex_init(&((hstreamrecorder->mtsafe).message_cb_lock), NULL);
82
83         ret = _mm_streamrecorder_ini_load(&hstreamrecorder->ini);
84         if (ret != MM_ERROR_NONE) {
85                 _mmstreamrec_dbg_warn("failed to load ini file\n");
86                 goto _ERR_INITIAL_INI;
87         }
88
89         hstreamrecorder->attributes = _mmstreamrecorder_alloc_attribute((MMHandleType) hstreamrecorder);
90
91         if (!(hstreamrecorder->attributes)) {
92                 _mmstreamrec_dbg_err("_mmstreamrecorder_create::alloc attribute error.");
93
94                 ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
95                 goto _ERR_ALLOC_ATTRIBUTE;
96         }
97
98         _mmstreamrecorder_alloc_subcontext((MMHandleType) hstreamrecorder);
99         if (!hstreamrecorder->sub_context) {
100                 ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
101                 goto _ERR_ALLOC_SUBCONTEXT;
102         }
103
104         /* Initial GSTREAMER */
105         ret = _mmstreamrecorder_gstreamer_init();
106
107         if (!ret) {
108                 _mmstreamrec_dbg_err("Failed to initialize gstreamer!!");
109                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
110                 goto _ERR_INITIAL_GSTREAMER;
111         }
112
113         _mmstreamrecorder_set_state((MMHandleType)hstreamrecorder, MM_STREAMRECORDER_STATE_CREATED);
114
115         *handle = (MMHandleType) hstreamrecorder;
116
117         return MM_ERROR_NONE;
118
119  _ERR_INITIAL_GSTREAMER:
120         _mmstreamrecorder_dealloc_subcontext((MMHandleType) hstreamrecorder);
121  _ERR_ALLOC_ATTRIBUTE:
122  _ERR_ALLOC_SUBCONTEXT:
123  _ERR_INITIAL_INI:
124         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).lock));
125         pthread_cond_destroy(&((hstreamrecorder->mtsafe).cond));
126         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).cmd_lock));
127         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).state_lock));
128         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).gst_state_lock));
129         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).message_cb_lock));
130         /* Release handle */
131         memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
132         free(hstreamrecorder);
133
134         return ret;
135 }
136
137 MMStreamRecorderStateType _mmstreamrecorder_get_state(MMHandleType handle)
138 {
139         int state;
140         mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
141
142         mmf_return_val_if_fail(streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
143
144         _MMSTREAMRECORDER_LOCK_STATE(handle);
145
146         state = streamrecorder->state;
147
148         _MMSTREAMRECORDER_UNLOCK_STATE(handle);
149
150         return state;
151 }
152
153 void _mmstreamrecorder_set_state(MMHandleType handle, int state)
154 {
155         int old_state;
156         mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
157         _MMStreamRecorderMsgItem msg;
158
159         mmf_return_val_if_fail(streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
160
161         /*_mmstreamrec_dbg_log("");*/
162
163         _MMSTREAMRECORDER_LOCK_STATE(handle);
164
165         old_state = streamrecorder->state;
166
167         if (old_state != state) {
168                 streamrecorder->state = state;
169
170                 _mmstreamrec_dbg_log("set state[%d] and send state-changed message", state);
171
172                 msg.id = MM_MESSAGE_STREAMRECORDER_STATE_CHANGED;
173                 msg.param.state.code = MM_ERROR_NONE;
174
175                 msg.param.state.previous = old_state;
176                 msg.param.state.current = state;
177
178                 /*_mmstreamrec_dbg_log("_mmstreamcorder_send_message : msg : %p, id:%x", &msg, msg.id);*/
179                 _mmstreamrecorder_send_message(handle, &msg);
180         }
181
182         _MMSTREAMRECORDER_UNLOCK_STATE(handle);
183
184         return;
185 }
186
187
188
189 int _mmstreamrecorder_destroy(MMHandleType handle)
190 {
191         int ret = MM_ERROR_NONE;
192
193         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
194
195         _mmstreamrec_dbg_log("");
196
197         if (!hstreamrecorder) {
198                 _mmstreamrec_dbg_err("Not initialized");
199                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
200                 goto _ERR_STREAMRECORDER_CMD_PRECON;
201         }
202
203         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
204                 _mmstreamrec_dbg_err("Another command is running.");
205                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
206                 goto _ERR_STREAMRECORDER_CMD_PRECON;
207         }
208
209         /* Release SubContext and pipeline */
210         if (hstreamrecorder->sub_context) {
211                 if (hstreamrecorder->sub_context->encode_element)
212                         _mmstreamrecorder_destroy_pipeline(handle);
213
214                 _mmstreamrecorder_dealloc_subcontext(handle);
215         }
216
217         /* Remove attributes */
218         if (hstreamrecorder->attributes) {
219                 _mmstreamrecorder_dealloc_attribute(hstreamrecorder->attributes);
220                 hstreamrecorder->attributes = 0;
221         }
222
223         /* Remove messages which are not called yet */
224         _mmstreamrecorder_remove_message_all(handle);
225
226         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
227
228         /* Release lock, cond */
229         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).lock));
230         pthread_cond_destroy(&((hstreamrecorder->mtsafe).cond));
231         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).cmd_lock));
232         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).state_lock));
233         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).gst_state_lock));
234         pthread_mutex_destroy(&((hstreamrecorder->mtsafe).message_cb_lock));
235
236         /* Release handle */
237         memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
238         free(hstreamrecorder);
239
240         return MM_ERROR_NONE;
241
242  _ERR_STREAMRECORDER_CMD_PRECON:
243
244         _mmstreamrec_dbg_err("Destroy fail (ret %x)", ret);
245
246         return ret;
247 }
248
249 int _mmstreamrecorder_realize(MMHandleType handle)
250 {
251         int ret = MM_ERROR_NONE;
252 /*      int errorcode = MM_ERROR_NONE;
253         char *videosink_element_type = NULL;
254         char *videosink_name = NULL; */
255
256         _mmstreamrec_dbg_log("");
257
258         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
259
260         if (!hstreamrecorder) {
261                 _mmstreamrec_dbg_err("Not initialized");
262                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
263                 return ret;
264         }
265
266         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
267                 _mmstreamrec_dbg_err("Another command is running.");
268                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
269                 goto _ERR_STREAMRECORDER_CMD_PRECON;
270         }
271
272         /* create pipeline */
273         ret = _mmstreamrecorder_create_pipeline(handle);
274         if (ret != MM_ERROR_NONE) {
275                 /* check internal error of gstreamer */
276                 if (hstreamrecorder->sub_context->error_code != MM_ERROR_NONE) {
277                         ret = hstreamrecorder->sub_context->error_code;
278                         _mmstreamrec_dbg_log("gstreamer error is occurred. return it %x", ret);
279                 }
280                 /* release sub context */
281                 _mmstreamrecorder_dealloc_subcontext(handle);
282                 goto _ERR_STREAMRECORDER_CMD;
283         }
284
285         /* set command function */
286         _mmstreamrecorder_set_functions(handle);
287
288         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
289
290         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
291
292         return MM_ERROR_NONE;
293
294  _ERR_STREAMRECORDER_CMD:
295 /* _ERR_STREAMRECORDER_CMD_PRECON_AFTER_LOCK: */
296         /* Security thread release */
297         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
298
299  _ERR_STREAMRECORDER_CMD_PRECON:
300 /*      _mmstreamrec_dbg_err("Realize fail (type %d, state %d, ret %x)", hstreamrecorder->type, state, ret); */
301
302         return ret;
303 }
304
305 int _mmstreamrecorder_unrealize(MMHandleType handle)
306 {
307         int ret = MM_ERROR_NONE;
308
309         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
310
311         _mmstreamrec_dbg_log("");
312
313         if (!hstreamrecorder) {
314                 _mmstreamrec_dbg_err("Not initialized");
315                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
316                 return ret;
317         }
318
319         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
320                 _mmstreamrec_dbg_err("Another command is running.");
321                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
322                 goto _ERR_STREAMRECORDER_CMD_PRECON;
323         }
324
325         /* Release SubContext */
326         if (hstreamrecorder->sub_context) {
327                 /* destroy pipeline */
328                 _mmstreamrecorder_destroy_pipeline(handle);
329                 /* Deallocate SubContext */
330         }
331
332         /* Deinitialize main context member */
333         _mmstreamrecorder_unset_functions(handle);
334
335         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_CREATED);
336
337         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
338
339         return MM_ERROR_NONE;
340
341  _ERR_STREAMRECORDER_CMD_PRECON:
342         /* send message */
343         return ret;
344 }
345
346 int _mmstreamrecorder_record(MMHandleType handle)
347 {
348         int ret = MM_ERROR_NONE;
349
350         _MMStreamRecorderSubContext *sc = NULL;
351         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
352
353         _mmstreamrec_dbg_log("");
354
355         if (!hstreamrecorder) {
356                 _mmstreamrec_dbg_err("Not initialized");
357                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
358                 return ret;
359         }
360
361         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
362         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
363
364         /* initialize error code */
365         hstreamrecorder->sub_context->error_code = MM_ERROR_NONE;
366
367         ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_RECORD);
368         if (ret != MM_ERROR_NONE) {
369                 _mmstreamrec_dbg_err("_mmstreamrecorder_record does not work!");
370                 goto _ERR_STREAMRECORDER_CMD;
371         }
372
373         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_RECORDING);
374
375         return MM_ERROR_NONE;
376
377  _ERR_STREAMRECORDER_CMD:
378  _ERR_STREAMRECORDER_CMD_PRECON:
379         /* check internal error of gstreamer */
380         if (hstreamrecorder->sub_context->error_code != MM_ERROR_NONE) {
381                 ret = hstreamrecorder->sub_context->error_code;
382                 hstreamrecorder->sub_context->error_code = MM_ERROR_NONE;
383
384                 _mmstreamrec_dbg_log("gstreamer error is occurred. return it %x", ret);
385         }
386         return ret;
387 }
388
389 int _mmstreamrecorder_push_stream_buffer(MMHandleType handle, MMStreamRecorderStreamType streamtype, unsigned long timestamp, void *buffer, int size)
390 {
391         int ret = MM_ERROR_NONE;
392
393         int format;
394         GstMapInfo map;
395         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
396
397         /* _mmstreamrec_dbg_log(""); */
398
399         if (!hstreamrecorder) {
400                 _mmstreamrec_dbg_err("Not initialized");
401                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
402                 return ret;
403         }
404         mm_streamrecorder_get_attributes(handle, NULL,
405                                         MMSTR_VIDEO_SOURCE_FORMAT, &format,
406                                         NULL);
407         GstStreamRecorderBuffer *stream_buffer = NULL;
408         stream_buffer = (GstStreamRecorderBuffer *) malloc(sizeof(GstStreamRecorderBuffer));
409         if (stream_buffer == NULL) {
410                 _mmstreamrec_dbg_err("stream buffer allocation fail");
411                 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
412         }
413         stream_buffer->str_handle = handle;
414         stream_buffer->buffer = gst_buffer_new();
415         if (stream_buffer->buffer == NULL) {
416                 free(stream_buffer);
417                 stream_buffer = NULL;
418                 _mmstreamrec_dbg_err("gst buffer allocation fail");
419                 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
420         }
421         stream_buffer->user_buffer = buffer;
422         /* Get Media Packet to Surface to MMVideoBuffer */
423
424         stream_buffer->buffer->pts = timestamp;
425         GST_BUFFER_DURATION(stream_buffer->buffer) = GST_CLOCK_TIME_NONE;
426
427         gst_buffer_map(stream_buffer->buffer, &map, GST_MAP_READWRITE);
428         if (streamtype == MM_STREAM_TYPE_VIDEO) {
429                 if (format == MM_STREAMRECORDER_INPUT_FORMAT_NV12 || format == MM_STREAMRECORDER_INPUT_FORMAT_NV21) {
430
431                         MMVideoBuffer *video_buf = (MMVideoBuffer *)buffer;
432                         /* Buffer at 0th position */
433                         gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
434                                                                 video_buf->handle.paddr[0], size, 0, size, video_buf->handle.paddr[0], NULL));
435                         /* Buffer at 1st position */
436                         gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
437                                                                 video_buf, sizeof(MMVideoBuffer), 0, sizeof(MMVideoBuffer), stream_buffer, _mmstreamrecorder_buffer_destroy));
438                 } else {
439                                 gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
440                                                                 buffer, size, 0, size, stream_buffer, _mmstreamrecorder_buffer_destroy));
441                 }
442                 ret = _mmstreamrecorder_push_videostream_buffer(handle, timestamp, stream_buffer->buffer, size);
443         } else if (streamtype == MM_STREAM_TYPE_AUDIO) {
444                 gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
445                                                                 buffer, size, 0, buffer, stream_buffer, _mmstreamrecorder_buffer_destroy));
446                 ret = _mmstreamrecorder_push_audiostream_buffer(handle, timestamp, stream_buffer->buffer, size);
447         } else {
448                 gst_buffer_unmap(stream_buffer->buffer, &map);
449                 gst_object_unref(stream_buffer->buffer);
450                 free(stream_buffer);
451                 stream_buffer = NULL;
452                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
453         }
454         gst_buffer_unmap(stream_buffer->buffer, &map);
455         return ret;
456
457 }
458
459 int _mmstreamrecorder_pause(MMHandleType handle)
460 {
461         int ret = MM_ERROR_NONE;
462         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
463
464         _mmstreamrec_dbg_log("");
465
466         if (!hstreamrecorder) {
467                 _mmstreamrec_dbg_err("Not initialized");
468                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
469                 return ret;
470         }
471
472         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
473                 _mmstreamrec_dbg_err("Another command is running.");
474                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
475                 goto _ERR_STREAMRECORDER_CMD_PRECON;
476         }
477
478         ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_PAUSE);
479         if (ret != MM_ERROR_NONE)
480                 goto _ERR_STREAMRECORDER_CMD;
481
482         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PAUSED);
483
484         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
485
486         return MM_ERROR_NONE;
487
488  _ERR_STREAMRECORDER_CMD:
489         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
490  _ERR_STREAMRECORDER_CMD_PRECON:
491         /* send message */
492         return ret;
493 }
494
495 int _mmstreamrecorder_commit(MMHandleType handle)
496 {
497         int ret = MM_ERROR_NONE;
498
499         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
500
501         _mmstreamrec_dbg_log("");
502
503         if (!hstreamrecorder) {
504                 _mmstreamrec_dbg_err("Not initialized");
505                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
506                 return ret;
507         }
508
509         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
510                 _mmstreamrec_dbg_err("Another command is running.");
511                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
512                 goto _ERR_STREAMRECORDER_CMD_PRECON;
513         }
514
515         ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_COMMIT);
516         if (ret != MM_ERROR_NONE)
517                 goto _ERR_STREAMRECORDER_CMD;
518
519         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
520
521         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
522
523         return MM_ERROR_NONE;
524
525  _ERR_STREAMRECORDER_CMD:
526         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
527  _ERR_STREAMRECORDER_CMD_PRECON:
528         /* send message */
529
530         return ret;
531 }
532
533 int _mmstreamrecorder_cancel(MMHandleType handle)
534 {
535         int ret = MM_ERROR_NONE;
536
537         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
538
539         _mmstreamrec_dbg_log("");
540
541         if (!hstreamrecorder) {
542                 _mmstreamrec_dbg_err("Not initialized");
543                 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
544                 return ret;
545         }
546
547         if (!_MMSTREAMRECORDER_TRYLOCK_CMD(hstreamrecorder)) {
548                 _mmstreamrec_dbg_err("Another command is running.");
549                 ret = MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING;
550                 goto _ERR_STREAMRECORDER_CMD_PRECON;
551         }
552
553         ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_CANCEL);
554         if (ret != MM_ERROR_NONE)
555                 goto _ERR_STREAMRECORDER_CMD;
556
557         _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
558
559         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
560
561         return MM_ERROR_NONE;
562
563  _ERR_STREAMRECORDER_CMD:
564         _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
565  _ERR_STREAMRECORDER_CMD_PRECON:
566         /* send message */
567
568         return ret;
569 }
570
571 /* } Internal command functions */
572
573 int _mmstreamrecorder_set_message_callback(MMHandleType handle, MMMessageCallback callback, void *user_data)
574 {
575         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
576
577         _mmstreamrec_dbg_log("%p", hstreamrecorder);
578
579         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
580
581         if (callback == NULL) {
582                 _mmstreamrec_dbg_warn("Message Callback is disabled");
583                 _mmstreamrec_dbg_warn("Application sets callback as NULL");
584         }
585
586         if (!_MMSTREAMRECORDER_TRYLOCK_MESSAGE_CALLBACK(hstreamrecorder)) {
587                 _mmstreamrec_dbg_warn("Application's message callback is running now");
588                 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
589         }
590
591         /* set message callback to message handle */
592         hstreamrecorder->msg_cb = callback;
593         hstreamrecorder->msg_cb_param = user_data;
594
595         _MMSTREAMRECORDER_UNLOCK_MESSAGE_CALLBACK(hstreamrecorder);
596
597         return MM_ERROR_NONE;
598 }
599
600 int _mmstreamrecorder_alloc_subcontext(MMHandleType handle)
601 {
602         int i;
603         int ret = MM_ERROR_NONE;
604         _MMStreamRecorderSubContext *sc = NULL;
605
606         _mmstreamrec_dbg_log("");
607
608         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
609
610         mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_RESOURCE_CREATION);
611
612         /* alloc container */
613         sc = (_MMStreamRecorderSubContext *) malloc(sizeof(_MMStreamRecorderSubContext));
614         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_LOW_MEMORY);
615
616         /* init members */
617         memset(sc, 0x00, sizeof(_MMStreamRecorderSubContext));
618
619         sc->encode_element_num = _MMSTREAMRECORDER_ENCODE_PIPELINE_ELEMENT_NUM;
620
621         /* alloc element array */
622         sc->encode_element = (_MMStreamRecorderGstElement *) malloc(sizeof(_MMStreamRecorderGstElement) * sc->encode_element_num);
623         if (!sc->encode_element) {
624                 _mmstreamrec_dbg_err("Failed to alloc encode element structure");
625                 goto ALLOC_SUBCONTEXT_FAILED;
626         }
627
628         for (i = 0; i < sc->encode_element_num; i++) {
629                 sc->encode_element[i].id = _MMSTREAMRECORDER_ENCODE_NONE;
630                 sc->encode_element[i].gst = NULL;
631         }
632
633         sc->fourcc = 0x80000000;
634
635         hstreamrecorder->sub_context = sc;
636
637         ret = _mmstreamrecorder_alloc_subcontext_fileinfo((MMHandleType) hstreamrecorder);
638         if (ret != MM_ERROR_NONE) {
639                 _mmstreamrec_dbg_err("Failed to allocate subcontext fileinfo");
640                 goto ALLOC_SUBCONTEXT_FAILED;
641         }
642
643         ret = _mmstreamrecorder_alloc_subcontext_videoinfo((MMHandleType) hstreamrecorder);
644         if (ret != MM_ERROR_NONE) {
645                 _mmstreamrec_dbg_err("Failed to allocate subcontext videoinfo");
646                 goto ALLOC_SUBCONTEXT_FAILED;
647         }
648
649         _mmstreamrecorder_alloc_subcontext_audioinfo((MMHandleType) hstreamrecorder);
650         if (ret != MM_ERROR_NONE) {
651                 _mmstreamrec_dbg_err("Failed to allocate subcontext audioinfo");
652                 goto ALLOC_SUBCONTEXT_FAILED;
653         }
654
655         return MM_ERROR_NONE;
656
657  ALLOC_SUBCONTEXT_FAILED:
658
659         if (sc) {
660                 if (sc->encode_element) {
661                         free(sc->encode_element);
662                         sc->encode_element = NULL;
663                 }
664                 free(sc);
665                 sc = NULL;
666         }
667         if (hstreamrecorder->sub_context != NULL)
668                 hstreamrecorder->sub_context = NULL;
669         return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
670 }
671
672 int _mmstreamrecorder_alloc_subcontext_videoinfo(MMHandleType handle)
673 {
674         _MMStreamRecorderSubContext *sc = NULL;
675
676         _mmstreamrec_dbg_log("");
677
678         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
679         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
680
681         /* alloc info for each mode */
682
683         sc->info_video = malloc(sizeof(_MMStreamRecorderVideoInfo));
684         if (!sc->info_video) {
685                 _mmstreamrec_dbg_err("Failed to alloc info structure");
686                 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
687         }
688         memset(sc->info_video, 0x00, sizeof(_MMStreamRecorderVideoInfo));
689
690         return MM_ERROR_NONE;
691 }
692
693 int _mmstreamrecorder_alloc_subcontext_audioinfo(MMHandleType handle)
694 {
695         _MMStreamRecorderSubContext *sc = NULL;
696
697         _mmstreamrec_dbg_log("");
698
699         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
700         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
701
702         /* alloc info for each mode */
703         sc->info_audio = malloc(sizeof(_MMStreamRecorderAudioInfo));
704         if (!sc->info_audio) {
705                 _mmstreamrec_dbg_err("Failed to alloc info structure");
706                 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
707         }
708         memset(sc->info_audio, 0x00, sizeof(_MMStreamRecorderAudioInfo));
709
710         return MM_ERROR_NONE;
711 }
712
713 int _mmstreamrecorder_alloc_subcontext_fileinfo(MMHandleType handle)
714 {
715         _MMStreamRecorderSubContext *sc = NULL;
716
717         _mmstreamrec_dbg_log("");
718
719         sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
720         mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
721
722         /* alloc info for each mode */
723         sc->info_file = malloc(sizeof(_MMStreamRecorderFileInfo));
724         if (!sc->info_file) {
725                 _mmstreamrec_dbg_err("Failed to alloc info structure");
726                 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
727         }
728         memset(sc->info_file, 0x00, sizeof(_MMStreamRecorderFileInfo));
729
730         return MM_ERROR_NONE;
731 }
732
733 void _mmstreamrecorder_dealloc_subcontext(MMHandleType handle)
734 {
735         _MMStreamRecorderSubContext *sc = NULL;
736
737         _mmstreamrec_dbg_log("");
738
739         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
740
741         mmf_return_if_fail(hstreamrecorder);
742         mmf_return_if_fail(hstreamrecorder->sub_context);
743
744         sc = hstreamrecorder->sub_context;
745
746         if (sc) {
747
748                 if (sc->encode_element) {
749                         _mmstreamrec_dbg_log("release encode_element");
750                         free(sc->encode_element);
751                         sc->encode_element = NULL;
752                 }
753
754                 if (sc->info_video) {
755                         _mmstreamrec_dbg_log("release info_video");
756                         free(sc->info_video);
757                         sc->info_video = NULL;
758                 }
759
760                 if (sc->info_audio) {
761                         _mmstreamrec_dbg_log("release info_audio");
762                         free(sc->info_audio);
763                         sc->info_audio = NULL;
764                 }
765
766                 if (sc->info_file) {
767                         _mmstreamrec_dbg_log("release info_file");
768                         free(sc->info_file);
769                         sc->info_file = NULL;
770                 }
771
772                 free(sc);
773                 sc = NULL;
774         }
775         if (hstreamrecorder->sub_context != NULL)
776                 hstreamrecorder->sub_context = NULL;
777
778         return;
779 }
780
781 void _mmstreamrecorder_set_functions(MMHandleType handle)
782 {
783         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
784
785         _mmstreamrec_dbg_log("");
786
787         /* Now only video type */
788
789         hstreamrecorder->command = _mmstreamrecorder_video_command;
790
791         return;
792 }
793
794 void _mmstreamrecorder_unset_functions(MMHandleType handle)
795 {
796         mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
797
798         _mmstreamrec_dbg_log("");
799
800         hstreamrecorder->command = NULL;
801
802         return;
803 }