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