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