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_ORT_0R_VR_0C_VT:/* 90 degree */
294 case MM_CAMCORDER_TAG_ORT_0R_VB_0C_VR:/* 180 degree */
298 case MM_CAMCORDER_TAG_ORT_0R_VL_0C_VB:/* 270 degree */
304 case MM_CAMCORDER_TAG_ORT_0R_VT_0C_VL:/* 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 g_idle_add(_mmcamcroder_msg_callback, item);
738 _MMCAMCORDER_UNLOCK(handle);
745 _mmcamcroder_remove_message_all(MMHandleType handle)
747 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
748 _MMCamcorderMsgItem *item = NULL;
752 mmf_return_if_fail(hcamcorder);
754 _MMCAMCORDER_LOCK(handle);
756 if(!hcamcorder->msg_data)
758 _mmcam_dbg_log("No message data is remained.");
762 list = hcamcorder->msg_data;
767 list = g_list_next(list);
771 _mmcam_dbg_err("Fail to remove message. The item is NULL");
775 ret = g_idle_remove_by_data (item);
776 _mmcam_dbg_log("Remove item[%p]. ret[%d]", item, ret);
778 hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
784 g_list_free(hcamcorder->msg_data);
785 hcamcorder->msg_data = NULL;
788 /* remove idle function for playing capture sound */
790 ret = g_idle_remove_by_data(hcamcorder);
791 _mmcam_dbg_log("remove idle function for playing capture sound. ret[%d]", ret);
794 _MMCAMCORDER_UNLOCK(handle);
801 _mmcamcorder_err_trace_write( char *str_filename, char *func_name, int line_num, char *fmt, ... )
805 char time_string[TIME_STRING_MAX_LEN] = {'\0',};
810 mmf_return_if_fail( str_filename );
812 current_time = time( NULL );
813 localtime_r( ¤t_time, &new_time );
815 f = fopen( str_filename, "a" );
818 _mmcam_dbg_warn( "Failed to open file.[%s]", str_filename );
822 asctime_r(&new_time, time_string);
823 fprintf( f, "[%.19s][%05d][%s]", time_string, line_num, func_name );
826 vfprintf( f, fmt, ap );
835 _mmcamcorder_get_pixel_format(GstBuffer *buffer)
837 GstCaps *caps = NULL;
838 const GstStructure *structure;
839 const char *media_type;
840 MMPixelFormatType type = 0;
841 unsigned int fourcc = 0;
843 mmf_return_val_if_fail( buffer != NULL, MM_PIXEL_FORMAT_INVALID );
845 caps = gst_buffer_get_caps (buffer);
846 structure = gst_caps_get_structure (caps, 0);
847 media_type = gst_structure_get_name (structure);
849 if (!strcmp (media_type, "image/jpeg") )
851 _mmcam_dbg_log("It is jpeg.");
852 type = MM_PIXEL_FORMAT_ENCODED;
854 else if (!strcmp (media_type, "video/x-raw-yuv"))
856 _mmcam_dbg_log("It is yuv.");
857 gst_structure_get_fourcc (structure, "format", &fourcc);
858 type = _mmcamcorder_get_pixtype(fourcc);
862 _mmcam_dbg_err("Not supported format");
863 type = MM_PIXEL_FORMAT_INVALID;
866 _mmcam_dbg_log( "Type [%d]", type );
868 gst_caps_unref( caps );
874 unsigned int _mmcamcorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format)
876 unsigned int fourcc = 0;
878 _mmcam_dbg_log("pixtype(%d)", pixtype);
881 case MM_PIXEL_FORMAT_NV12:
882 if (use_zero_copy_format) {
883 fourcc = GST_MAKE_FOURCC ('S', 'N', '1', '2');
885 fourcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
888 case MM_PIXEL_FORMAT_YUYV:
889 if (use_zero_copy_format) {
890 fourcc = GST_MAKE_FOURCC ('S', 'U', 'Y', 'V');
892 fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
895 case MM_PIXEL_FORMAT_UYVY:
896 if (use_zero_copy_format) {
897 fourcc = GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y');
899 fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
902 case MM_PIXEL_FORMAT_I420:
903 if (use_zero_copy_format) {
904 fourcc = GST_MAKE_FOURCC ('S', '4', '2', '0');
906 fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
909 case MM_PIXEL_FORMAT_YV12:
910 fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
912 case MM_PIXEL_FORMAT_422P:
913 fourcc = GST_MAKE_FOURCC ('4', '2', '2', 'P');
915 case MM_PIXEL_FORMAT_RGB565:
916 fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', 'P');
918 case MM_PIXEL_FORMAT_RGB888:
919 fourcc = GST_MAKE_FOURCC ('R', 'G', 'B', '3');
921 case MM_PIXEL_FORMAT_ENCODED:
922 if (codectype == MM_IMAGE_CODEC_JPEG) {
923 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G');
924 } else if (codectype == MM_IMAGE_CODEC_JPEG_SRW) {
925 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G'); /*TODO: JPEG+SamsungRAW format */
926 } else if (codectype == MM_IMAGE_CODEC_SRW) {
927 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G'); /*TODO: SamsungRAW format */
928 } else if (codectype == MM_IMAGE_CODEC_PNG) {
929 fourcc = GST_MAKE_FOURCC ('P', 'N', 'G', ' ');
931 /* Please let us know what other fourcces are. ex) BMP, GIF?*/
932 fourcc = GST_MAKE_FOURCC ('J', 'P', 'E', 'G');
935 case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:
936 fourcc = GST_MAKE_FOURCC('I','T','L','V');
939 _mmcam_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
940 if (use_zero_copy_format) {
941 fourcc = GST_MAKE_FOURCC ('S', '4', '2', '0');
943 fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
952 int _mmcamcorder_get_pixtype(unsigned int fourcc)
954 int pixtype = MM_PIXEL_FORMAT_INVALID;
955 char *pfourcc = (char*)&fourcc;
956 _mmcam_dbg_log("fourcc(%c%c%c%c)", pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
959 case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
960 case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
961 pixtype = MM_PIXEL_FORMAT_NV12;
963 case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
964 case GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V'):
965 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
966 pixtype = MM_PIXEL_FORMAT_YUYV;
968 case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
969 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
970 pixtype = MM_PIXEL_FORMAT_UYVY;
972 case GST_MAKE_FOURCC ('S', '4', '2', '0'):
973 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
974 pixtype = MM_PIXEL_FORMAT_I420;
976 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
977 pixtype = MM_PIXEL_FORMAT_YV12;
979 case GST_MAKE_FOURCC ('4', '2', '2', 'P'):
980 pixtype = MM_PIXEL_FORMAT_422P;
982 case GST_MAKE_FOURCC ('R', 'G', 'B', 'P'):
983 pixtype = MM_PIXEL_FORMAT_RGB565;
985 case GST_MAKE_FOURCC ('R', 'G', 'B', '3'):
986 pixtype = MM_PIXEL_FORMAT_RGB888;
988 case GST_MAKE_FOURCC ('A', 'R', 'G', 'B'):
989 case GST_MAKE_FOURCC ('x', 'R', 'G', 'B'):
990 pixtype = MM_PIXEL_FORMAT_ARGB;
992 case GST_MAKE_FOURCC ('B', 'G', 'R', 'A'):
993 case GST_MAKE_FOURCC ('B', 'G', 'R', 'x'):
994 pixtype = MM_PIXEL_FORMAT_RGBA;
996 case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'):
997 case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
998 pixtype = MM_PIXEL_FORMAT_ENCODED;
1001 case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'):
1002 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
1005 _mmcam_dbg_log("Not supported fourcc type(%x)", fourcc);
1006 pixtype = MM_PIXEL_FORMAT_INVALID;
1015 _mmcamcorder_add_elements_to_bin( GstBin *bin, GList *element_list )
1017 GList *local_list = element_list;
1018 _MMCamcorderGstElement *element = NULL;
1020 mmf_return_val_if_fail( bin && local_list, FALSE );
1024 element = (_MMCamcorderGstElement*)local_list->data;
1025 if( element && element->gst )
1027 if( !gst_bin_add( bin, GST_ELEMENT(element->gst) ) )
1029 _mmcam_dbg_err( "Add element [%s] to bin [%s] FAILED",
1030 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
1031 GST_ELEMENT_NAME(GST_ELEMENT(bin)) );
1036 _mmcam_dbg_log( "Add element [%s] to bin [%s] OK",
1037 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
1038 GST_ELEMENT_NAME(GST_ELEMENT(bin)) );
1042 local_list = local_list->next;
1049 _mmcamcorder_link_elements( GList *element_list )
1051 GList *local_list = element_list;
1052 _MMCamcorderGstElement *element = NULL;
1053 _MMCamcorderGstElement *pre_element = NULL;
1055 mmf_return_val_if_fail( local_list, FALSE );
1057 pre_element = (_MMCamcorderGstElement*)local_list->data;
1058 local_list = local_list->next;
1062 element = (_MMCamcorderGstElement*)local_list->data;
1063 if( element && element->gst )
1065 if( _MM_GST_ELEMENT_LINK( GST_ELEMENT(pre_element->gst), GST_ELEMENT(element->gst) ) )
1067 _mmcam_dbg_log( "Link [%s] to [%s] OK",
1068 GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)),
1069 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
1073 _mmcam_dbg_err( "Link [%s] to [%s] FAILED",
1074 GST_ELEMENT_NAME(GST_ELEMENT(pre_element->gst)),
1075 GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
1080 pre_element = element;
1081 local_list = local_list->next;
1088 gboolean _mmcamcorder_resize_frame(unsigned char *src_data, int src_width, int src_height, int src_length, int src_format,
1089 unsigned char **dst_data, int *dst_width, int *dst_height, int *dst_length)
1092 int mm_ret = MM_ERROR_NONE;
1093 int input_format = MM_UTIL_IMG_FMT_YUV420;
1094 unsigned char *dst_tmp_data = NULL;
1096 if (!src_data || !dst_data || !dst_width || !dst_height || !dst_length) {
1097 _mmcam_dbg_err("something is NULL %p,%p,%p,%p,%p",
1098 src_data, dst_data, dst_width, dst_height, dst_length);
1102 /* set input format for mm-util */
1103 switch (src_format) {
1104 case MM_PIXEL_FORMAT_I420:
1105 input_format = MM_UTIL_IMG_FMT_I420;
1107 case MM_PIXEL_FORMAT_YV12:
1108 input_format = MM_UTIL_IMG_FMT_YUV420;
1110 case MM_PIXEL_FORMAT_NV12:
1111 input_format = MM_UTIL_IMG_FMT_NV12;
1113 case MM_PIXEL_FORMAT_YUYV:
1114 input_format = MM_UTIL_IMG_FMT_YUYV;
1116 case MM_PIXEL_FORMAT_UYVY:
1117 input_format = MM_UTIL_IMG_FMT_UYVY;
1120 _mmcam_dbg_err("NOT supported format", src_format);
1124 _mmcam_dbg_log("src size %dx%d -> dst size %dx%d",
1125 src_width, src_height, *dst_width, *dst_height);
1127 /* get length of resized image */
1128 __ta__(" mm_util_get_image_size 2",
1129 mm_ret = mm_util_get_image_size(input_format, *dst_width, *dst_height, dst_length);
1131 if (mm_ret != MM_ERROR_NONE) {
1132 GST_ERROR("mm_util_get_image_size failed 0x%x", ret);
1136 _mmcam_dbg_log("dst_length : %d", *dst_length);
1138 dst_tmp_data = (unsigned char *)malloc(*dst_length);
1139 if (dst_tmp_data == NULL) {
1140 _mmcam_dbg_err("failed to alloc dst_thumb_size(size %d)", *dst_length);
1144 __ta__(" mm_util_resize_image",
1145 mm_ret = mm_util_resize_image(src_data, src_width, src_height, input_format,
1146 dst_tmp_data, dst_width, dst_height);
1148 if (mm_ret != MM_ERROR_NONE) {
1149 GST_ERROR("mm_util_resize_image failed 0x%x", ret);
1154 *dst_data = dst_tmp_data;
1156 _mmcam_dbg_log("resize done %p, %dx%d", *dst_data, *dst_width, *dst_height);
1162 gboolean _mmcamcorder_encode_jpeg(void *src_data, unsigned int src_width, unsigned int src_height,
1163 int src_format, unsigned int src_length, unsigned int jpeg_quality,
1164 void **result_data, unsigned int *result_length)
1168 int enc_type = JPEG_ENCODER_SOFTWARE;
1169 guint32 src_fourcc = 0;
1170 gboolean do_encode = FALSE;
1171 jpegenc_parameter enc_param;
1172 static jpegenc_info enc_info = {-1,};
1174 _mmcam_dbg_log("START");
1176 mmf_return_val_if_fail(src_data && result_data && result_length, FALSE);
1180 if (enc_info.sw_support == -1) {
1182 __ta__("camsrcjpegenc_get_info",
1183 camsrcjpegenc_get_info(&enc_info);
1187 src_fourcc = _mmcamcorder_get_fourcc(src_format, 0, FALSE);
1188 camsrcjpegenc_get_src_fmt(src_fourcc, &(enc_param.src_fmt));
1190 if (enc_param.src_fmt == COLOR_FORMAT_NOT_SUPPORT) {
1191 _mmcam_dbg_err("Not Supported FOURCC(format:%d)", src_format);
1195 /* check H/W encoder */
1196 if (enc_info.hw_support) {
1197 _mmcam_dbg_log("check H/W encoder supported format list");
1198 /* Check supported format */
1199 for (i = 0 ; i < enc_info.hw_enc.input_fmt_num ; i++) {
1200 if (enc_param.src_fmt == enc_info.hw_enc.input_fmt_list[i]) {
1207 enc_type = JPEG_ENCODER_HARDWARE;
1211 /* check S/W encoder */
1212 if (!do_encode && enc_info.sw_support) {
1213 _mmcam_dbg_log("check S/W encoder supported format list");
1214 /* Check supported format */
1215 for (i = 0 ; i < enc_info.sw_enc.input_fmt_num ; i++) {
1216 if (enc_param.src_fmt == enc_info.sw_enc.input_fmt_list[i]) {
1223 enc_type = JPEG_ENCODER_SOFTWARE;
1228 enc_param.src_data = src_data;
1229 enc_param.width = src_width;
1230 enc_param.height = src_height;
1231 enc_param.src_len = src_length;
1232 enc_param.jpeg_mode = JPEG_MODE_BASELINE;
1233 enc_param.jpeg_quality = jpeg_quality;
1235 _mmcam_dbg_log("%ux%u, size %u, quality %u, type %d",
1236 src_width, src_height, src_length,
1237 jpeg_quality, enc_type);
1239 __ta__(" camsrcjpegenc_encode",
1240 ret = camsrcjpegenc_encode(&enc_info, enc_type, &enc_param );
1242 if (ret == CAMSRC_JPEGENC_ERROR_NONE) {
1243 *result_data = enc_param.result_data;
1244 *result_length = enc_param.result_len;
1246 _mmcam_dbg_log("JPEG encode length(%d)", *result_length);
1250 _mmcam_dbg_err("camsrcjpegenc_encode failed(%x)", ret);
1255 _mmcam_dbg_err("No encoder supports %d format", src_format);
1261 static guint16 get_language_code(const char *str)
1263 return (guint16) (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
1266 static gchar * str_to_utf8(const gchar *str)
1268 return g_convert (str, -1, "UTF-8", "ASCII", NULL, NULL, NULL);
1271 static inline gboolean write_tag(FILE *f, const gchar *tag)
1274 FPUTC_CHECK(*tag++, f);
1279 static inline gboolean write_to_32(FILE *f, guint val)
1281 FPUTC_CHECK(val >> 24, f);
1282 FPUTC_CHECK(val >> 16, f);
1283 FPUTC_CHECK(val >> 8, f);
1284 FPUTC_CHECK(val, f);
1288 static inline gboolean write_to_16(FILE *f, guint val)
1290 FPUTC_CHECK(val >> 8, f);
1291 FPUTC_CHECK(val, f);
1295 static inline gboolean write_to_24(FILE *f, guint val)
1297 write_to_16(f, val >> 8);
1298 FPUTC_CHECK(val, f);