4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 /*=======================================================================================
24 ========================================================================================*/
29 #include <media_packet.h>
31 #include "mm_streamrecorder_internal.h"
32 #include "mm_streamrecorder_recorder.h"
33 #include "mm_streamrecorder_attribute.h"
34 #include "mm_streamrecorder_gstdispatch.h"
36 #include <asm/types.h>
38 /*---------------------------------------------------------------------------------------
39 | GLOBAL VARIABLE DEFINITIONS for internal |
40 ---------------------------------------------------------------------------------------*/
42 /*---------------------------------------------------------------------------------------
43 | LOCAL VARIABLE DEFINITIONS for internal |
44 ---------------------------------------------------------------------------------------*/
45 #define __MMSTREAMRECORDER_CMD_ITERATE_MAX 3
47 /*---------------------------------------------------------------------------------------
48 | LOCAL FUNCTION PROTOTYPES: |
49 ---------------------------------------------------------------------------------------*/
50 void _mmstreamrecorder_set_state(MMHandleType handle, int state);
53 /*=======================================================================================
54 | FUNCTION DEFINITIONS |
55 =======================================================================================*/
57 /*---------------------------------------------------------------------------------------
58 | GLOBAL FUNCTION DEFINITIONS: |
59 ---------------------------------------------------------------------------------------*/
61 /* Internal command functions {*/
62 int _mmstreamrecorder_create(MMHandleType *handle)
64 int ret = MM_ERROR_NONE;
65 /* char *err_attr_name = NULL; */
66 mmf_streamrecorder_t *hstreamrecorder = NULL;
68 _mmstreamrec_dbg_log("Entered");
69 mmf_return_val_if_fail(handle, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
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));
77 hstreamrecorder->sub_context = NULL;
79 pthread_mutex_init(&((hstreamrecorder->mtsafe).lock), NULL);
80 pthread_cond_init(&((hstreamrecorder->mtsafe).cond), NULL);
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);
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;
93 hstreamrecorder->attributes = _mmstreamrecorder_alloc_attribute((MMHandleType) hstreamrecorder);
95 if (!(hstreamrecorder->attributes)) {
96 _mmstreamrec_dbg_err("_mmstreamrecorder_create::alloc attribute error.");
98 ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
99 goto _ERR_ALLOC_ATTRIBUTE;
102 _mmstreamrecorder_alloc_subcontext((MMHandleType) hstreamrecorder);
103 if (!hstreamrecorder->sub_context) {
104 ret = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION;
105 goto _ERR_ALLOC_SUBCONTEXT;
108 /* Initial GSTREAMER */
109 ret = _mmstreamrecorder_gstreamer_init();
112 _mmstreamrec_dbg_err("Failed to initialize gstreamer!!");
113 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
114 goto _ERR_INITIAL_GSTREAMER;
117 _mmstreamrecorder_set_state((MMHandleType)hstreamrecorder, MM_STREAMRECORDER_STATE_CREATED);
119 *handle = (MMHandleType) hstreamrecorder;
121 return MM_ERROR_NONE;
123 _ERR_INITIAL_GSTREAMER:
124 _mmstreamrecorder_dealloc_subcontext((MMHandleType) hstreamrecorder);
125 _ERR_ALLOC_ATTRIBUTE:
126 _ERR_ALLOC_SUBCONTEXT:
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));
135 memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
136 free(hstreamrecorder);
141 MMStreamRecorderStateType _mmstreamrecorder_get_state(MMHandleType handle)
144 mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
146 mmf_return_val_if_fail(streamrecorder, MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT);
148 _MMSTREAMRECORDER_LOCK_STATE(handle);
150 state = streamrecorder->state;
152 _MMSTREAMRECORDER_UNLOCK_STATE(handle);
157 void _mmstreamrecorder_set_state(MMHandleType handle, int state)
160 mmf_streamrecorder_t *streamrecorder = MMF_STREAMRECORDER(handle);
161 _MMStreamRecorderMsgItem msg;
163 mmf_return_if_fail(streamrecorder);
165 /*_mmstreamrec_dbg_log("");*/
167 _MMSTREAMRECORDER_LOCK_STATE(handle);
169 old_state = streamrecorder->state;
171 if (old_state != state) {
172 streamrecorder->state = state;
174 _mmstreamrec_dbg_log("set state[%d] and send state-changed message", state);
176 msg.id = MM_MESSAGE_STREAMRECORDER_STATE_CHANGED;
177 msg.param.state.code = MM_ERROR_NONE;
179 msg.param.state.previous = old_state;
180 msg.param.state.current = state;
182 /*_mmstreamrec_dbg_log("_mmstreamcorder_send_message : msg : %p, id:%x", &msg, msg.id);*/
183 _mmstreamrecorder_send_message(handle, &msg);
186 _MMSTREAMRECORDER_UNLOCK_STATE(handle);
193 int _mmstreamrecorder_destroy(MMHandleType handle)
195 int ret = MM_ERROR_NONE;
197 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
199 _mmstreamrec_dbg_log("");
201 if (!hstreamrecorder) {
202 _mmstreamrec_dbg_err("Not initialized");
203 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
204 goto _ERR_STREAMRECORDER_CMD_PRECON;
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;
213 /* Release SubContext and pipeline */
214 if (hstreamrecorder->sub_context) {
215 if (hstreamrecorder->sub_context->encode_element)
216 _mmstreamrecorder_destroy_pipeline(handle);
218 _mmstreamrecorder_dealloc_subcontext(handle);
221 /* Remove attributes */
222 if (hstreamrecorder->attributes) {
223 _mmstreamrecorder_dealloc_attribute(hstreamrecorder->attributes);
224 hstreamrecorder->attributes = 0;
227 /* Remove messages which are not called yet */
228 _mmstreamrecorder_remove_message_all(handle);
230 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
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));
241 memset(hstreamrecorder, 0x00, sizeof(mmf_streamrecorder_t));
242 free(hstreamrecorder);
244 return MM_ERROR_NONE;
246 _ERR_STREAMRECORDER_CMD_PRECON:
248 _mmstreamrec_dbg_err("Destroy fail (ret %x)", ret);
253 int _mmstreamrecorder_realize(MMHandleType handle)
255 int ret = MM_ERROR_NONE;
256 /* int errorcode = MM_ERROR_NONE;
257 char *videosink_element_type = NULL;
258 char *videosink_name = NULL; */
260 _mmstreamrec_dbg_log("");
262 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
264 if (!hstreamrecorder) {
265 _mmstreamrec_dbg_err("Not initialized");
266 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
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);
284 /* release sub context */
285 _mmstreamrecorder_dealloc_subcontext(handle);
286 goto _ERR_STREAMRECORDER_CMD;
289 /* set command function */
290 _mmstreamrecorder_set_functions(handle);
292 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
294 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
296 return MM_ERROR_NONE;
298 _ERR_STREAMRECORDER_CMD:
299 /* _ERR_STREAMRECORDER_CMD_PRECON_AFTER_LOCK: */
300 /* Security thread release */
301 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
303 _ERR_STREAMRECORDER_CMD_PRECON:
304 /* _mmstreamrec_dbg_err("Realize fail (type %d, state %d, ret %x)", hstreamrecorder->type, state, ret); */
309 int _mmstreamrecorder_unrealize(MMHandleType handle)
311 int ret = MM_ERROR_NONE;
313 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
315 _mmstreamrec_dbg_log("");
317 if (!hstreamrecorder) {
318 _mmstreamrec_dbg_err("Not initialized");
319 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
329 /* Release SubContext */
330 if (hstreamrecorder->sub_context) {
331 /* destroy pipeline */
332 _mmstreamrecorder_destroy_pipeline(handle);
333 /* Deallocate SubContext */
336 /* Deinitialize main context member */
337 _mmstreamrecorder_unset_functions(handle);
339 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_CREATED);
341 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
343 return MM_ERROR_NONE;
345 _ERR_STREAMRECORDER_CMD_PRECON:
350 int _mmstreamrecorder_record(MMHandleType handle)
352 int ret = MM_ERROR_NONE;
354 _MMStreamRecorderSubContext *sc = NULL;
355 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
357 _mmstreamrec_dbg_log("");
359 if (!hstreamrecorder) {
360 _mmstreamrec_dbg_err("Not initialized");
361 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
365 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
366 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
368 /* initialize error code */
369 hstreamrecorder->sub_context->error_code = MM_ERROR_NONE;
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;
377 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_RECORDING);
379 return MM_ERROR_NONE;
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;
387 _mmstreamrec_dbg_log("gstreamer error is occurred. return it %x", ret);
392 int _mmstreamrecorder_push_video_packet(MMHandleType handle, media_packet_h media_packet, unsigned long long timestamp, void *buffer)
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;
400 int image_height = 0;
401 unsigned char *data_buffer = NULL;
402 int size = 0, total_size = 0;
404 if (!hstreamrecorder) {
405 _mmstreamrec_dbg_err("Not initialized");
406 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
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;
422 stream_buffer->str_handle = handle;
423 stream_buffer->buffer = gst_buffer_new();
424 if (stream_buffer->buffer == NULL) {
426 stream_buffer = NULL;
427 _mmstreamrec_dbg_err("gst buffer allocation fail");
428 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
430 stream_buffer->user_buffer = buffer;
431 stream_buffer->buffer->pts = timestamp;
432 GST_BUFFER_DURATION(stream_buffer->buffer) = GST_CLOCK_TIME_NONE;
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);
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;
444 size = image_width * image_height;
446 _mmstreamrec_dbg_err("Plane[%d] info : %d x %d (%p) size = %d\n", ind, image_width, image_height, data_buffer, total_size);
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));
452 gst_buffer_append_memory(stream_buffer->buffer, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY,
453 data_buffer, size, 0, size, NULL, NULL));
456 ret = _mmstreamrecorder_push_videostream_buffer(handle, timestamp, stream_buffer->buffer, total_size);
461 int _mmstreamrecorder_push_stream_buffer(MMHandleType handle, MMStreamRecorderStreamType streamtype, unsigned long long timestamp, void *buffer, int size)
463 int ret = MM_ERROR_NONE;
466 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
468 /* _mmstreamrec_dbg_log(""); */
470 if (!hstreamrecorder) {
471 _mmstreamrec_dbg_err("Not initialized");
472 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
475 mm_streamrecorder_get_attributes(handle, NULL,
476 MMSTR_VIDEO_SOURCE_FORMAT, &format,
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;
484 stream_buffer->str_handle = handle;
485 stream_buffer->buffer = gst_buffer_new();
486 if (stream_buffer->buffer == NULL) {
488 stream_buffer = NULL;
489 _mmstreamrec_dbg_err("gst buffer allocation fail");
490 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
492 stream_buffer->user_buffer = buffer;
493 /* Get Media Packet to Surface to MMVideoBuffer */
495 stream_buffer->buffer->pts = timestamp;
496 GST_BUFFER_DURATION(stream_buffer->buffer) = GST_CLOCK_TIME_NONE;
498 if (streamtype == MM_STREAM_TYPE_VIDEO) {
499 if (format == MM_STREAMRECORDER_INPUT_FORMAT_NV12 || format == MM_STREAMRECORDER_INPUT_FORMAT_NV21) {
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));
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));
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);
518 gst_object_unref(stream_buffer->buffer);
520 stream_buffer = NULL;
521 return MM_ERROR_STREAMRECORDER_INVALID_CONDITION;
527 int _mmstreamrecorder_pause(MMHandleType handle)
529 int ret = MM_ERROR_NONE;
530 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
532 _mmstreamrec_dbg_log("");
534 if (!hstreamrecorder) {
535 _mmstreamrec_dbg_err("Not initialized");
536 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
546 ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_PAUSE);
547 if (ret != MM_ERROR_NONE)
548 goto _ERR_STREAMRECORDER_CMD;
550 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PAUSED);
552 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
554 return MM_ERROR_NONE;
556 _ERR_STREAMRECORDER_CMD:
557 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
558 _ERR_STREAMRECORDER_CMD_PRECON:
563 int _mmstreamrecorder_commit(MMHandleType handle)
565 int ret = MM_ERROR_NONE;
567 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
569 _mmstreamrec_dbg_log("");
571 if (!hstreamrecorder) {
572 _mmstreamrec_dbg_err("Not initialized");
573 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
583 ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_COMMIT);
584 if (ret != MM_ERROR_NONE)
585 goto _ERR_STREAMRECORDER_CMD;
587 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
589 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
591 return MM_ERROR_NONE;
593 _ERR_STREAMRECORDER_CMD:
594 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
595 _ERR_STREAMRECORDER_CMD_PRECON:
601 int _mmstreamrecorder_cancel(MMHandleType handle)
603 int ret = MM_ERROR_NONE;
605 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
607 _mmstreamrec_dbg_log("");
609 if (!hstreamrecorder) {
610 _mmstreamrec_dbg_err("Not initialized");
611 ret = MM_ERROR_STREAMRECORDER_NOT_INITIALIZED;
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;
621 ret = hstreamrecorder->command((MMHandleType) hstreamrecorder, _MM_STREAMRECORDER_CMD_CANCEL);
622 if (ret != MM_ERROR_NONE)
623 goto _ERR_STREAMRECORDER_CMD;
625 _mmstreamrecorder_set_state(handle, MM_STREAMRECORDER_STATE_PREPARED);
627 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
629 return MM_ERROR_NONE;
631 _ERR_STREAMRECORDER_CMD:
632 _MMSTREAMRECORDER_UNLOCK_CMD(hstreamrecorder);
633 _ERR_STREAMRECORDER_CMD_PRECON:
639 /* } Internal command functions */
641 int _mmstreamrecorder_set_message_callback(MMHandleType handle, MMMessageCallback callback, void *user_data)
643 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
645 _mmstreamrec_dbg_log("%p", hstreamrecorder);
647 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
649 if (callback == NULL) {
650 _mmstreamrec_dbg_warn("Message Callback is disabled");
651 _mmstreamrec_dbg_warn("Application sets callback as NULL");
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;
659 /* set message callback to message handle */
660 hstreamrecorder->msg_cb = callback;
661 hstreamrecorder->msg_cb_param = user_data;
663 _MMSTREAMRECORDER_UNLOCK_MESSAGE_CALLBACK(hstreamrecorder);
665 return MM_ERROR_NONE;
668 int _mmstreamrecorder_alloc_subcontext(MMHandleType handle)
671 int ret = MM_ERROR_NONE;
672 _MMStreamRecorderSubContext *sc = NULL;
674 _mmstreamrec_dbg_log("");
676 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
678 mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_RESOURCE_CREATION);
680 /* alloc container */
681 sc = (_MMStreamRecorderSubContext *) malloc(sizeof(_MMStreamRecorderSubContext));
682 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_LOW_MEMORY);
685 memset(sc, 0x00, sizeof(_MMStreamRecorderSubContext));
687 sc->encode_element_num = _MMSTREAMRECORDER_ENCODE_PIPELINE_ELEMENT_NUM;
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;
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;
701 sc->fourcc = 0x80000000;
703 hstreamrecorder->sub_context = sc;
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;
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;
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;
723 return MM_ERROR_NONE;
725 ALLOC_SUBCONTEXT_FAILED:
728 if (sc->encode_element) {
729 free(sc->encode_element);
730 sc->encode_element = NULL;
735 if (hstreamrecorder->sub_context != NULL)
736 hstreamrecorder->sub_context = NULL;
737 return MM_ERROR_STREAMRECORDER_LOW_MEMORY;
740 int _mmstreamrecorder_alloc_subcontext_videoinfo(MMHandleType handle)
742 _MMStreamRecorderSubContext *sc = NULL;
744 _mmstreamrec_dbg_log("");
746 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
747 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
749 /* alloc info for each mode */
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;
756 memset(sc->info_video, 0x00, sizeof(_MMStreamRecorderVideoInfo));
758 return MM_ERROR_NONE;
761 int _mmstreamrecorder_alloc_subcontext_audioinfo(MMHandleType handle)
763 _MMStreamRecorderSubContext *sc = NULL;
765 _mmstreamrec_dbg_log("");
767 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
768 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
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;
776 memset(sc->info_audio, 0x00, sizeof(_MMStreamRecorderAudioInfo));
778 return MM_ERROR_NONE;
781 int _mmstreamrecorder_alloc_subcontext_fileinfo(MMHandleType handle)
783 _MMStreamRecorderSubContext *sc = NULL;
785 _mmstreamrec_dbg_log("");
787 sc = MMF_STREAMRECORDER_SUBCONTEXT(handle);
788 mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED);
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;
796 memset(sc->info_file, 0x00, sizeof(_MMStreamRecorderFileInfo));
798 return MM_ERROR_NONE;
801 void _mmstreamrecorder_dealloc_subcontext(MMHandleType handle)
803 _MMStreamRecorderSubContext *sc = NULL;
805 _mmstreamrec_dbg_log("");
807 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
809 mmf_return_if_fail(hstreamrecorder);
810 mmf_return_if_fail(hstreamrecorder->sub_context);
812 sc = hstreamrecorder->sub_context;
816 if (sc->encode_element) {
817 _mmstreamrec_dbg_log("release encode_element");
818 free(sc->encode_element);
819 sc->encode_element = NULL;
822 if (sc->info_video) {
823 _mmstreamrec_dbg_log("release info_video");
824 free(sc->info_video);
825 sc->info_video = NULL;
828 if (sc->info_audio) {
829 _mmstreamrec_dbg_log("release info_audio");
830 free(sc->info_audio);
831 sc->info_audio = NULL;
835 _mmstreamrec_dbg_log("release info_file");
837 sc->info_file = NULL;
843 if (hstreamrecorder->sub_context != NULL)
844 hstreamrecorder->sub_context = NULL;
849 void _mmstreamrecorder_set_functions(MMHandleType handle)
851 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
853 _mmstreamrec_dbg_log("");
855 /* Now only video type */
857 hstreamrecorder->command = _mmstreamrecorder_video_command;
862 void _mmstreamrecorder_unset_functions(MMHandleType handle)
864 mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle);
866 _mmstreamrec_dbg_log("");
868 hstreamrecorder->command = NULL;