4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jeongmo Yang <jm80.yang@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 =======================================================================================*/
27 #include <camsrcjpegenc.h>
28 #include <sys/vfs.h> /* struct statfs */
30 #include "mm_camcorder_internal.h"
31 #include "mm_camcorder_util.h"
32 #include <mm_util_imgp.h>
34 /*-----------------------------------------------------------------------
35 | GLOBAL VARIABLE DEFINITIONS for internal |
36 -----------------------------------------------------------------------*/
38 /*-----------------------------------------------------------------------
39 | LOCAL VARIABLE DEFINITIONS for internal |
40 -----------------------------------------------------------------------*/
41 #define TIME_STRING_MAX_LEN 64
43 #define FPUTC_CHECK(x_char, x_file)\
45 if (fputc(x_char, x_file) == EOF) \
47 _mmcam_dbg_err("[Critical] fputc() returns fail.\n"); \
51 #define FPUTS_CHECK(x_str, x_file)\
53 if (fputs(x_str, x_file) == EOF) \
55 _mmcam_dbg_err("[Critical] fputs() returns fail.\n");\
61 /*---------------------------------------------------------------------------
62 | LOCAL FUNCTION PROTOTYPES: |
63 ---------------------------------------------------------------------------*/
64 /* STATIC INTERNAL FUNCTION */
66 //static gint skip_mdat(FILE *f);
67 static guint16 get_language_code(const char *str);
68 static gchar* str_to_utf8(const gchar *str);
69 static inline gboolean write_tag(FILE *f, const gchar *tag);
70 static inline gboolean write_to_32(FILE *f, guint val);
71 static inline gboolean write_to_16(FILE *f, guint val);
72 static inline gboolean write_to_24(FILE *f, guint val);
74 /*===========================================================================================
76 | FUNCTION DEFINITIONS |
78 ========================================================================================== */
79 /*---------------------------------------------------------------------------
80 | GLOBAL FUNCTION DEFINITIONS: |
81 ---------------------------------------------------------------------------*/
83 gint32 _mmcamcorder_double_to_fix(gdouble d_number)
85 return (gint32) (d_number * 65536.0);
88 // find top level tag only, do not use this function for finding sub level tags
89 gint _mmcamcorder_find_tag(FILE *f, guint32 tag_fourcc, gboolean do_rewind)
97 while (fread(&buf, sizeof(guchar), 8, f)>0) {
98 unsigned long long buf_size = 0;
99 unsigned int buf_fourcc = MMCAM_FOURCC(buf[4], buf[5], buf[6], buf[7]);
101 if (tag_fourcc == buf_fourcc) {
102 _mmcam_dbg_log("find tag : %c%c%c%c", MMCAM_FOURCC_ARGS(tag_fourcc));
105 _mmcam_dbg_log("skip [%c%c%c%c] tag", MMCAM_FOURCC_ARGS(buf_fourcc));
107 buf_size = (unsigned long long)_mmcamcorder_get_container_size(buf);
108 buf_size = buf_size - 8; /* include tag */
111 if (buf_size > _MMCAMCORDER_MAX_INT) {
112 _mmcam_dbg_log("seek %d", _MMCAMCORDER_MAX_INT);
113 if (fseek(f, _MMCAMCORDER_MAX_INT, SEEK_CUR) != 0) {
114 _mmcam_dbg_err("fseek() fail");
118 buf_size -= _MMCAMCORDER_MAX_INT;
120 _mmcam_dbg_log("seek %d", buf_size);
121 if (fseek(f, buf_size, SEEK_CUR) != 0) {
122 _mmcam_dbg_err("fseek() fail");
131 _mmcam_dbg_log("cannot find tag : %c%c%c%c", MMCAM_FOURCC_ARGS(tag_fourcc));
136 gboolean _mmcamcorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos)
138 _mmcam_dbg_log("size : %"G_GINT64_FORMAT"", curr_pos-prev_pos);
139 if(fseek(f, prev_pos, SEEK_SET) != 0)
141 _mmcam_dbg_err("fseek() fail");
145 if (!write_to_32(f, curr_pos -prev_pos))
148 if(fseek(f, curr_pos, SEEK_SET) != 0)
150 _mmcam_dbg_err("fseek() fail");
157 gboolean _mmcamcorder_write_loci(FILE *f, _MMCamcorderLocationInfo info)
159 gint64 current_pos, pos;
164 if((pos = ftell(f))<0)
166 _mmcam_dbg_err("ftell() returns negative value");
170 if(!write_to_32(f, 0)) //size
173 if(!write_tag(f, "loci")) // type
176 FPUTC_CHECK(0, f); // version
178 if(!write_to_24(f, 0)) // flags
181 if(!write_to_16(f, get_language_code("eng"))) // language
184 str = str_to_utf8("location_name");
186 FPUTS_CHECK(str, f); // name
189 FPUTC_CHECK('\0', f);
190 FPUTC_CHECK(0, f); //role
192 if(!write_to_32(f, info.longitude)) // Longitude
195 if(!write_to_32(f, info.latitude)) // Latitude
198 if(! write_to_32(f, info.altitude)) // Altitude
201 str = str_to_utf8("Astronomical_body");
202 FPUTS_CHECK(str, f);//Astronomical_body
205 FPUTC_CHECK('\0', f);
207 str = str_to_utf8("Additional_notes");
208 FPUTS_CHECK(str, f); // Additional_notes
211 FPUTC_CHECK('\0', f);
213 if((current_pos = ftell(f))<0)
215 _mmcam_dbg_err("ftell() returns negative value");
219 if(! _mmcamcorder_update_size(f, pos, current_pos))
225 gboolean _mmcamcorder_write_udta(FILE *f, _MMCamcorderLocationInfo info)
227 gint64 current_pos, pos;
231 if((pos = ftell(f))<0)
233 _mmcam_dbg_err("ftell() returns negative value");
237 if(!write_to_32(f, 0)) //size
240 if(!write_tag(f, "udta")) // type
243 if(! _mmcamcorder_write_loci(f, info))
246 if((current_pos = ftell(f))<0)
248 _mmcam_dbg_err("ftell() returns negative value");
252 if(! _mmcamcorder_update_size(f, pos, current_pos))
260 guint64 _mmcamcorder_get_container_size(const guchar *size)
268 result = result | (temp << 16);
270 result = result | (temp << 8);
271 result = result | size[3];
273 _mmcam_dbg_log("result : %lld", (unsigned long long)result);
279 gboolean _mmcamcorder_update_composition_matrix(FILE *f, int orientation)
282 guint32 a = 0x00010000;
285 guint32 d = 0x00010000;
287 switch (orientation) {
288 case MM_CAMCORDER_TAG_VIDEO_ORT_90:/* 90 degree */
294 case MM_CAMCORDER_TAG_VIDEO_ORT_180:/* 180 degree */
298 case MM_CAMCORDER_TAG_VIDEO_ORT_270:/* 270 degree */
304 case MM_CAMCORDER_TAG_VIDEO_ORT_NONE:/* 0 degree */
317 write_to_32(f, 0x40000000);
319 _mmcam_dbg_log("orientation : %d, write data 0x%x 0x%x 0x%x 0x%x",
320 orientation, a, b, c, d);
326 int _mmcamcorder_get_freespace(const gchar *path, guint64 *free_space)
332 if (!g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
333 _mmcam_dbg_log("File(%s) doesn't exist.", path);
337 if (-1 == statfs(path, &fs)) {
338 _mmcam_dbg_log("Getting free space is failed.(%s)", path);
342 *free_space = (guint64)fs.f_bsize * fs.f_bavail;
347 int _mmcamcorder_get_file_size(const char *filename, guint64 *size)
351 if (stat(filename, &buf) != 0)
353 *size = (guint64)buf.st_size;
358 void _mmcamcorder_remove_buffer_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
360 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
362 MMCamcorderHandlerItem *item = NULL;
364 mmf_return_if_fail(hcamcorder);
366 if(!hcamcorder->buffer_probes)
368 _mmcam_dbg_err("Fail to remove buffer probe, list for buffer probe is NULL");
371 list = hcamcorder->buffer_probes;
379 _mmcam_dbg_err("Remove buffer probe faild, the item is NULL");
380 list = g_list_next(list);
384 if(item->category & category)
387 if(item->object && GST_IS_PAD(item->object))
389 _mmcam_dbg_log("Remove buffer probe on [%s:%s] - [ID : %lu], [Category : %x]",
390 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
391 gst_pad_remove_buffer_probe(GST_PAD(item->object), item->handler_id);
395 _mmcam_dbg_warn("Remove buffer probe faild, the pad is null or not pad, just remove item from list and free it");
398 list = g_list_next(list);
399 hcamcorder->buffer_probes = g_list_remove(hcamcorder->buffer_probes, item);
404 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
405 list = g_list_next(list);
409 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
411 g_list_free(hcamcorder->buffer_probes);
412 hcamcorder->buffer_probes = NULL;
416 void _mmcamcorder_remove_event_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
418 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
420 MMCamcorderHandlerItem *item = NULL;
422 mmf_return_if_fail(hcamcorder);
424 if(!hcamcorder->event_probes)
426 _mmcam_dbg_err("Fail to remove event probe, list for event probe is NULL");
429 list = hcamcorder->event_probes;
437 _mmcam_dbg_err("Remove event probe faild, the item is NULL");
438 list = g_list_next(list);
442 if(item->category & category)
445 if(item->object && GST_IS_PAD(item->object))
447 _mmcam_dbg_log("Remove event probe on [%s:%s] - [ID : %lu], [Category : %x]",
448 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
449 gst_pad_remove_event_probe(GST_PAD(item->object), item->handler_id);
453 _mmcam_dbg_warn("Remove event probe faild, the pad is null or not pad, just remove item from list and free it");
456 list = g_list_next(list);
457 hcamcorder->event_probes = g_list_remove(hcamcorder->event_probes, item);
462 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
463 list = g_list_next(list);
467 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
469 g_list_free(hcamcorder->event_probes);
470 hcamcorder->event_probes = NULL;
474 void _mmcamcorder_remove_data_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
476 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
478 MMCamcorderHandlerItem *item = NULL;
480 mmf_return_if_fail(hcamcorder);
482 if(!hcamcorder->data_probes)
484 _mmcam_dbg_err("Fail to remove data probe, list for data probe is NULL");
487 list = hcamcorder->data_probes;
495 _mmcam_dbg_err("Remove data probe faild, the item is NULL");
496 list = g_list_next(list);
500 if(item->category & category)
503 if(item->object && GST_IS_PAD(item->object))
505 _mmcam_dbg_log("Remove data probe on [%s:%s] - [ID : %lu], [Category : %x]",
506 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
507 gst_pad_remove_data_probe(GST_PAD(item->object), item->handler_id);
511 _mmcam_dbg_warn("Remove data probe faild, the pad is null or not pad, just remove item from list and free it");
514 list = g_list_next(list);
515 hcamcorder->data_probes = g_list_remove(hcamcorder->data_probes, item);
520 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
521 list = g_list_next(list);
525 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
527 g_list_free(hcamcorder->data_probes);
528 hcamcorder->data_probes = NULL;
532 void _mmcamcorder_disconnect_signal(MMHandleType handle, _MMCamcorderHandlerCategory category)
534 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
536 MMCamcorderHandlerItem *item = NULL;
538 mmf_return_if_fail(hcamcorder);
540 if(!hcamcorder->signals)
542 _mmcam_dbg_err("Fail to disconnect signals, list for signal is NULL");
545 list = hcamcorder->signals;
553 _mmcam_dbg_err("Fail to Disconnecting signal, the item is NULL");
554 list = g_list_next(list);
558 if(item->category & category)
561 if(item->object && GST_IS_ELEMENT(item->object))
563 if ( g_signal_handler_is_connected ( item->object, item->handler_id ) )
565 _mmcam_dbg_log("Disconnect signal from [%s] : [ID : %lu], [Category : %x]",
566 GST_OBJECT_NAME(item->object), item->handler_id, item->category);
567 g_signal_handler_disconnect ( item->object, item->handler_id );
571 _mmcam_dbg_warn("Signal was not connected, cannot disconnect it : [%s] [ID : %lu], [Category : %x]",
572 GST_OBJECT_NAME(item->object), item->handler_id, item->category);
578 _mmcam_dbg_err("Fail to Disconnecting signal, the element is null or not element, just remove item from list and free it");
581 list = g_list_next(list);
582 hcamcorder->signals = g_list_remove(hcamcorder->signals, item);
587 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
588 list = g_list_next(list);
592 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
594 g_list_free(hcamcorder->signals);
595 hcamcorder->signals = NULL;
599 void _mmcamcorder_remove_all_handlers(MMHandleType handle, _MMCamcorderHandlerCategory category)
601 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
603 _mmcam_dbg_log("ENTER");
605 if(hcamcorder->signals)
606 _mmcamcorder_disconnect_signal((MMHandleType)hcamcorder, category);
607 if(hcamcorder->data_probes)
608 _mmcamcorder_remove_data_probe((MMHandleType)hcamcorder, category);
609 if(hcamcorder->event_probes)
610 _mmcamcorder_remove_event_probe((MMHandleType)hcamcorder, category);
611 if(hcamcorder->buffer_probes)
612 _mmcamcorder_remove_buffer_probe((MMHandleType)hcamcorder, category);
614 _mmcam_dbg_log("LEAVE");
618 void _mmcamcorder_element_release_noti(gpointer data, GObject *where_the_object_was)
621 _MMCamcorderSubContext *sc = (_MMCamcorderSubContext *)data;
622 mmf_return_if_fail(sc);
623 mmf_return_if_fail(sc->element);
625 for (i = 0 ; i < _MMCamcorder_PIPELINE_ELEMENT_NUM ; i++) {
626 if (sc->element[i].gst && (G_OBJECT(sc->element[i].gst) == where_the_object_was)) {
627 _mmcam_dbg_log("The element[%d][%p] is finalized", sc->element[i].id, sc->element[i].gst);
628 sc->element[i].gst = NULL;
629 sc->element[i].id = _MMCAMCORDER_NONE;
637 _mmcamcroder_msg_callback(void *data)
639 _MMCamcorderMsgItem *item = (_MMCamcorderMsgItem*)data;
640 mmf_camcorder_t *hcamcorder = NULL;
641 mmf_return_val_if_fail(item, FALSE);
643 hcamcorder = MMF_CAMCORDER(item->handle);
644 mmf_return_val_if_fail(hcamcorder, FALSE);
646 /*_mmcam_dbg_log("msg id:%x, msg_cb:%p, msg_data:%p, item:%p", item->id, hcamcorder->msg_cb, hcamcorder->msg_data, item);*/
648 _MMCAMCORDER_LOCK_MESSAGE_CALLBACK(hcamcorder);
650 /* check delay of CAPTURED message */
651 if (item->id == MM_MESSAGE_CAMCORDER_CAPTURED) {
652 MMTA_ACUM_ITEM_END(" CAPTURED MESSAGE DELAY", FALSE);
655 if ((hcamcorder) && (hcamcorder->msg_cb)) {
656 hcamcorder->msg_cb(item->id, (MMMessageParamType*)(&(item->param)), hcamcorder->msg_cb_param);
659 _MMCAMCORDER_UNLOCK_MESSAGE_CALLBACK(hcamcorder);
661 _MMCAMCORDER_LOCK((MMHandleType)hcamcorder);
663 if (hcamcorder->msg_data) {
664 hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
667 /* release allocated memory */
668 if (item->id == MM_MESSAGE_CAMCORDER_FACE_DETECT_INFO) {
669 MMCamFaceDetectInfo *cam_fd_info = (MMCamFaceDetectInfo *)item->param.data;
671 SAFE_FREE(cam_fd_info->face_info);
676 item->param.data = NULL;
677 item->param.size = 0;
683 _MMCAMCORDER_UNLOCK((MMHandleType)hcamcorder);
685 /* For not being called again */
691 _mmcamcroder_send_message(MMHandleType handle, _MMCamcorderMsgItem *data)
693 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
694 _MMCamcorderMsgItem *item = NULL;
696 mmf_return_val_if_fail(hcamcorder, FALSE);
697 mmf_return_val_if_fail(data, FALSE);
701 case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
702 case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM:
703 data->param.union_type = MM_MSG_UNION_STATE;
705 case MM_MESSAGE_CAMCORDER_RECORDING_STATUS:
706 data->param.union_type = MM_MSG_UNION_RECORDING_STATUS;
708 case MM_MESSAGE_CAMCORDER_FIRMWARE_UPDATE:
709 data->param.union_type = MM_MSG_UNION_FIRMWARE;
711 case MM_MESSAGE_CAMCORDER_CURRENT_VOLUME:
712 data->param.union_type = MM_MSG_UNION_REC_VOLUME_DB;
714 case MM_MESSAGE_CAMCORDER_TIME_LIMIT:
715 case MM_MESSAGE_CAMCORDER_MAX_SIZE:
716 case MM_MESSAGE_CAMCORDER_NO_FREE_SPACE:
717 case MM_MESSAGE_CAMCORDER_ERROR:
718 case MM_MESSAGE_CAMCORDER_FOCUS_CHANGED:
719 case MM_MESSAGE_CAMCORDER_CAPTURED:
720 case MM_MESSAGE_CAMCORDER_VIDEO_CAPTURED:
721 case MM_MESSAGE_CAMCORDER_AUDIO_CAPTURED:
722 case MM_MESSAGE_READY_TO_RESUME:
724 data->param.union_type = MM_MSG_UNION_CODE;
728 item = g_malloc(sizeof(_MMCamcorderMsgItem));
729 memcpy(item, data, sizeof(_MMCamcorderMsgItem));
730 item->handle = handle;
732 _MMCAMCORDER_LOCK(handle);
733 hcamcorder->msg_data = g_list_append(hcamcorder->msg_data, item);
734 // _mmcam_dbg_log("item[%p]", item);
736 /* Use DEFAULT priority */
737 g_idle_add_full(G_PRIORITY_DEFAULT, _mmcamcroder_msg_callback, item, NULL);
739 _MMCAMCORDER_UNLOCK(handle);
746 _mmcamcroder_remove_message_all(MMHandleType handle)
748 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
749 _MMCamcorderMsgItem *item = NULL;
753 mmf_return_if_fail(hcamcorder);
755 _MMCAMCORDER_LOCK(handle);
757 if(!hcamcorder->msg_data)
759 _mmcam_dbg_log("No message data is remained.");
763 list = hcamcorder->msg_data;
768 list = g_list_next(list);
772 _mmcam_dbg_err("Fail to remove message. The item is NULL");
776 ret = g_idle_remove_by_data (item);
777 _mmcam_dbg_log("Remove item[%p]. ret[%d]", item, ret);
779 hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
785 g_list_free(hcamcorder->msg_data);
786 hcamcorder->msg_data = NULL;
789 /* remove idle function for playing capture sound */
791 ret = g_idle_remove_by_data(hcamcorder);
792 _mmcam_dbg_log("remove idle function for playing capture sound. ret[%d]", ret);
795 _MMCAMCORDER_UNLOCK(handle);
802 _mmcamcorder_err_trace_write( char *str_filename, char *func_name, int line_num, char *fmt, ... )
806 char time_string[TIME_STRING_MAX_LEN] = {'\0',};
811 mmf_return_if_fail( str_filename );
813 current_time = time( NULL );
814 localtime_r( ¤t_time, &new_time );
816 f = fopen( str_filename, "a" );
819 _mmcam_dbg_warn( "Failed to open file.[%s]", str_filename );
823 asctime_r(&new_time, time_string);
824 fprintf( f, "[%.19s][%05d][%s]", time_string, line_num, func_name );
827 vfprintf( f, fmt, ap );
836 _mmcamcorder_get_pixel_format(GstBuffer *buffer)
838 GstCaps *caps = NULL;
839 const GstStructure *structure;
840 const char *media_type;
841 MMPixelFormatType type = 0;
842 unsigned int fourcc = 0;
844 mmf_return_val_if_fail( buffer != NULL, MM_PIXEL_FORMAT_INVALID );
846 caps = gst_buffer_get_caps (buffer);
847 structure = gst_caps_get_structure (caps, 0);
848 media_type = gst_structure_get_name (structure);
850 if (!strcmp (media_type, "image/jpeg") )
852 _mmcam_dbg_log("It is jpeg.");
853 type = MM_PIXEL_FORMAT_ENCODED;
855 else if (!strcmp (media_type, "video/x-raw-yuv"))
857 _mmcam_dbg_log("It is yuv.");
858 gst_structure_get_fourcc (structure, "format", &fourcc);
859 type = _mmcamcorder_get_pixtype(fourcc);
863 _mmcam_dbg_err("Not supported format");
864 type = MM_PIXEL_FORMAT_INVALID;
867 _mmcam_dbg_log( "Type [%d]", type );
869 gst_caps_unref( caps );
875 unsigned int _mmcamcorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format)
877 unsigned int fourcc = 0;
879 _mmcam_dbg_log("pixtype(%d)", pixtype);
882 case MM_PIXEL_FORMAT_NV12:
883 if (use_zero_copy_format) {
884 fourcc = GST_MAKE_FOURCC ('S', 'N', '1', '2');
886 fourcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
889 case MM_PIXEL_FORMAT_YUYV:
890 if (use_zero_copy_format) {
891 fourcc = GST_MAKE_FOURCC ('S', 'U', 'Y', 'V');
893 fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
896 case MM_PIXEL_FORMAT_UYVY:
897 if (use_zero_copy_format) {
898 fourcc = GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y');
900 fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
903 case MM_PIXEL_FORMAT_I420:
904 if (use_zero_copy_format) {
905 fourcc = GST_MAKE_FOURCC ('S', '4', '2', '0');
907 fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
910 case MM_PIXEL_FORMAT_YV12:
911 fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
913 case MM_PIXEL_FORMAT_422P:
914 fourcc = GST_MAKE_FOURCC ('4', '2', '2', 'P');
916 case MM_PIXEL_FORMAT_RGB565:
917 fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', 'P');
919 case MM_PIXEL_FORMAT_RGB888:
920 fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', '3');
922 case MM_PIXEL_FORMAT_ENCODED:
923 if (codectype == MM_IMAGE_CODEC_JPEG) {
924 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G');
925 } else if (codectype == MM_IMAGE_CODEC_JPEG_SRW) {
926 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G'); /*TODO: JPEG+SamsungRAW format */
927 } else if (codectype == MM_IMAGE_CODEC_SRW) {
928 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G'); /*TODO: SamsungRAW format */
929 } else if (codectype == MM_IMAGE_CODEC_PNG) {
930 fourcc = GST_MAKE_FOURCC ('P', 'N', 'G', ' ');
932 /* Please let us know what other fourcces are. ex) BMP, GIF?*/
933 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G');
936 case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:
937 fourcc = GST_MAKE_FOURCC('I','T','L','V');
940 _mmcam_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
941 if (use_zero_copy_format) {
942 fourcc = GST_MAKE_FOURCC ('S', '4', '2', '0');
944 fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
953 int _mmcamcorder_get_pixtype(unsigned int fourcc)
955 int pixtype = MM_PIXEL_FORMAT_INVALID;
956 char *pfourcc = (char*)&fourcc;
957 _mmcam_dbg_log("fourcc(%c%c%c%c)", pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
960 case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
961 case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
962 pixtype = MM_PIXEL_FORMAT_NV12;
964 case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
965 case GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V'):
966 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
967 pixtype = MM_PIXEL_FORMAT_YUYV;
969 case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
970 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
971 pixtype = MM_PIXEL_FORMAT_UYVY;
973 case GST_MAKE_FOURCC ('S', '4', '2', '0'):
974 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
975 pixtype = MM_PIXEL_FORMAT_I420;
977 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
978 pixtype = MM_PIXEL_FORMAT_YV12;
980 case GST_MAKE_FOURCC ('4', '2', '2', 'P'):
981 pixtype = MM_PIXEL_FORMAT_422P;
983 case GST_MAKE_FOURCC ('R', 'G', 'B', 'P'):
984 pixtype = MM_PIXEL_FORMAT_RGB565;
986 case GST_MAKE_FOURCC ('R', 'G', 'B', '3'):
987 pixtype = MM_PIXEL_FORMAT_RGB888;
989 case GST_MAKE_FOURCC ('A', 'R', 'G', 'B'):
990 case GST_MAKE_FOURCC ('x', 'R', 'G', 'B'):
991 pixtype = MM_PIXEL_FORMAT_ARGB;
993 case GST_MAKE_FOURCC ('B', 'G', 'R', 'A'):
994 case GST_MAKE_FOURCC ('B', 'G', 'R', 'x'):
995 pixtype = MM_PIXEL_FORMAT_RGBA;
997 case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'):
998 case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
999 pixtype = MM_PIXEL_FORMAT_ENCODED;
1002 case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'):
1003 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
1006 _mmcam_dbg_log("Not supported fourcc type(%x)", fourcc);
1007 pixtype = MM_PIXEL_FORMAT_INVALID;
1016 _mmcamcorder_add_elements_to_bin( GstBin *bin, GList *element_list )
1018 GList *local_list = element_list;
1019 _MMCamcorderGstElement *element = NULL;
1021 mmf_return_val_if_fail( bin && local_list, FALSE );
1025 element = (_MMCamcorderGstElement*)local_list->data;
1026 if( element && element->gst )
1028 if( !gst_bin_add( bin, GST_ELEMENT(element->gst) ) )
1030 _mmcam_dbg_err( "Add element [%s] to bin [%s] FAILED",
1031 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
1032 GST_ELEMENT_NAME(GST_ELEMENT(bin)) );
1037 _mmcam_dbg_log( "Add element [%s] to bin [%s] OK",
1038 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
1039 GST_ELEMENT_NAME(GST_ELEMENT(bin)) );
1043 local_list = local_list->next;
1050 _mmcamcorder_link_elements( GList *element_list )
1052 GList *local_list = element_list;
1053 _MMCamcorderGstElement *element = NULL;
1054 _MMCamcorderGstElement *pre_element = NULL;
1056 mmf_return_val_if_fail( local_list, FALSE );
1058 pre_element = (_MMCamcorderGstElement*)local_list->data;
1059 local_list = local_list->next;
1063 element = (_MMCamcorderGstElement*)local_list->data;
1064 if( element && element->gst )
1066 if( _MM_GST_ELEMENT_LINK( GST_ELEMENT(pre_element->gst), GST_ELEMENT(element->gst) ) )
1068 _mmcam_dbg_log( "Link [%s] to [%s] OK",
1069 GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)),
1070 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
1074 _mmcam_dbg_err( "Link [%s] to [%s] FAILED",
1075 GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)),
1076 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
1081 pre_element = element;
1082 local_list = local_list->next;
1089 gboolean _mmcamcorder_resize_frame(unsigned char *src_data, int src_width, int src_height, int src_length, int src_format,
1090 unsigned char **dst_data, int *dst_width, int *dst_height, int *dst_length)
1093 int mm_ret = MM_ERROR_NONE;
1094 int input_format = MM_UTIL_IMG_FMT_YUV420;
1095 unsigned char *dst_tmp_data = NULL;
1097 if (!src_data || !dst_data || !dst_width || !dst_height || !dst_length) {
1098 _mmcam_dbg_err("something is NULL %p,%p,%p,%p,%p",
1099 src_data, dst_data, dst_width, dst_height, dst_length);
1103 /* set input format for mm-util */
1104 switch (src_format) {
1105 case MM_PIXEL_FORMAT_I420:
1106 input_format = MM_UTIL_IMG_FMT_I420;
1108 case MM_PIXEL_FORMAT_YV12:
1109 input_format = MM_UTIL_IMG_FMT_YUV420;
1111 case MM_PIXEL_FORMAT_NV12:
1112 input_format = MM_UTIL_IMG_FMT_NV12;
1114 case MM_PIXEL_FORMAT_YUYV:
1115 input_format = MM_UTIL_IMG_FMT_YUYV;
1117 case MM_PIXEL_FORMAT_UYVY:
1118 input_format = MM_UTIL_IMG_FMT_UYVY;
1121 _mmcam_dbg_err("NOT supported format", src_format);
1125 _mmcam_dbg_log("src size %dx%d -> dst size %dx%d",
1126 src_width, src_height, *dst_width, *dst_height);
1128 /* get length of resized image */
1129 __ta__(" mm_util_get_image_size 2",
1130 mm_ret = mm_util_get_image_size(input_format, *dst_width, *dst_height, dst_length);
1132 if (mm_ret != MM_ERROR_NONE) {
1133 GST_ERROR("mm_util_get_image_size failed 0x%x", ret);
1137 _mmcam_dbg_log("dst_length : %d", *dst_length);
1139 dst_tmp_data = (unsigned char *)malloc(*dst_length);
1140 if (dst_tmp_data == NULL) {
1141 _mmcam_dbg_err("failed to alloc dst_thumb_size(size %d)", *dst_length);
1145 __ta__(" mm_util_resize_image",
1146 mm_ret = mm_util_resize_image(src_data, src_width, src_height, input_format,
1147 dst_tmp_data, dst_width, dst_height);
1149 if (mm_ret != MM_ERROR_NONE) {
1150 GST_ERROR("mm_util_resize_image failed 0x%x", ret);
1155 *dst_data = dst_tmp_data;
1157 _mmcam_dbg_log("resize done %p, %dx%d", *dst_data, *dst_width, *dst_height);
1163 gboolean _mmcamcorder_encode_jpeg(void *src_data, unsigned int src_width, unsigned int src_height,
1164 int src_format, unsigned int src_length, unsigned int jpeg_quality,
1165 void **result_data, unsigned int *result_length)
1169 int enc_type = JPEG_ENCODER_SOFTWARE;
1170 guint32 src_fourcc = 0;
1171 gboolean do_encode = FALSE;
1172 jpegenc_parameter enc_param;
1173 static jpegenc_info enc_info = {-1,};
1175 _mmcam_dbg_log("START");
1177 mmf_return_val_if_fail(src_data && result_data && result_length, FALSE);
1181 if (enc_info.sw_support == -1) {
1183 __ta__("camsrcjpegenc_get_info",
1184 camsrcjpegenc_get_info(&enc_info);
1188 src_fourcc = _mmcamcorder_get_fourcc(src_format, 0, FALSE);
1189 camsrcjpegenc_get_src_fmt(src_fourcc, &(enc_param.src_fmt));
1191 if (enc_param.src_fmt == COLOR_FORMAT_NOT_SUPPORT) {
1192 _mmcam_dbg_err("Not Supported FOURCC(format:%d)", src_format);
1196 /* check H/W encoder */
1197 if (enc_info.hw_support) {
1198 _mmcam_dbg_log("check H/W encoder supported format list");
1199 /* Check supported format */
1200 for (i = 0 ; i < enc_info.hw_enc.input_fmt_num ; i++) {
1201 if (enc_param.src_fmt == enc_info.hw_enc.input_fmt_list[i]) {
1208 enc_type = JPEG_ENCODER_HARDWARE;
1212 /* check S/W encoder */
1213 if (!do_encode && enc_info.sw_support) {
1214 _mmcam_dbg_log("check S/W encoder supported format list");
1215 /* Check supported format */
1216 for (i = 0 ; i < enc_info.sw_enc.input_fmt_num ; i++) {
1217 if (enc_param.src_fmt == enc_info.sw_enc.input_fmt_list[i]) {
1224 enc_type = JPEG_ENCODER_SOFTWARE;
1229 enc_param.src_data = src_data;
1230 enc_param.width = src_width;
1231 enc_param.height = src_height;
1232 enc_param.src_len = src_length;
1233 enc_param.jpeg_mode = JPEG_MODE_BASELINE;
1234 enc_param.jpeg_quality = jpeg_quality;
1236 _mmcam_dbg_log("%ux%u, size %u, quality %u, type %d",
1237 src_width, src_height, src_length,
1238 jpeg_quality, enc_type);
1240 __ta__(" camsrcjpegenc_encode",
1241 ret = camsrcjpegenc_encode(&enc_info, enc_type, &enc_param );
1243 if (ret == CAMSRC_JPEGENC_ERROR_NONE) {
1244 *result_data = enc_param.result_data;
1245 *result_length = enc_param.result_len;
1247 _mmcam_dbg_log("JPEG encode length(%d)", *result_length);
1251 _mmcam_dbg_err("camsrcjpegenc_encode failed(%x)", ret);
1256 _mmcam_dbg_err("No encoder supports %d format", src_format);
1262 static guint16 get_language_code(const char *str)
1264 return (guint16) (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
1267 static gchar * str_to_utf8(const gchar *str)
1269 return g_convert (str, -1, "UTF-8", "ASCII", NULL, NULL, NULL);
1272 static inline gboolean write_tag(FILE *f, const gchar *tag)
1275 FPUTC_CHECK(*tag++, f);
1280 static inline gboolean write_to_32(FILE *f, guint val)
1282 FPUTC_CHECK(val >> 24, f);
1283 FPUTC_CHECK(val >> 16, f);
1284 FPUTC_CHECK(val >> 8, f);
1285 FPUTC_CHECK(val, f);
1289 static inline gboolean write_to_16(FILE *f, guint val)
1291 FPUTC_CHECK(val >> 8, f);
1292 FPUTC_CHECK(val, f);
1296 static inline gboolean write_to_24(FILE *f, guint val)
1298 write_to_16(f, val >> 8);
1299 FPUTC_CHECK(val, f);