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 =======================================================================================*/
28 #include <camsrcjpegenc.h>
29 #include <sys/vfs.h> /* struct statfs */
30 #include <gst/video/video-info.h>
32 #include "mm_camcorder_internal.h"
33 #include "mm_camcorder_util.h"
34 #include <mm_util_imgp.h>
36 /*-----------------------------------------------------------------------
37 | GLOBAL VARIABLE DEFINITIONS for internal |
38 -----------------------------------------------------------------------*/
40 /*-----------------------------------------------------------------------
41 | LOCAL VARIABLE DEFINITIONS for internal |
42 -----------------------------------------------------------------------*/
43 #define TIME_STRING_MAX_LEN 64
45 #define FPUTC_CHECK(x_char, x_file)\
47 if (fputc(x_char, x_file) == EOF) \
49 _mmcam_dbg_err("[Critical] fputc() returns fail.\n"); \
53 #define FPUTS_CHECK(x_str, x_file)\
55 if (fputs(x_str, x_file) == EOF) \
57 _mmcam_dbg_err("[Critical] fputs() returns fail.\n");\
63 /*---------------------------------------------------------------------------
64 | LOCAL FUNCTION PROTOTYPES: |
65 ---------------------------------------------------------------------------*/
66 /* STATIC INTERNAL FUNCTION */
68 //static gint skip_mdat(FILE *f);
69 static guint16 get_language_code(const char *str);
70 static gchar* str_to_utf8(const gchar *str);
71 static inline gboolean write_tag(FILE *f, const gchar *tag);
72 static inline gboolean write_to_32(FILE *f, guint val);
73 static inline gboolean write_to_16(FILE *f, guint val);
74 static inline gboolean write_to_24(FILE *f, guint val);
76 /*===========================================================================================
78 | FUNCTION DEFINITIONS |
80 ========================================================================================== */
81 /*---------------------------------------------------------------------------
82 | GLOBAL FUNCTION DEFINITIONS: |
83 ---------------------------------------------------------------------------*/
85 gint32 _mmcamcorder_double_to_fix(gdouble d_number)
87 return (gint32) (d_number * 65536.0);
90 // find top level tag only, do not use this function for finding sub level tags
91 gint _mmcamcorder_find_tag(FILE *f, guint32 tag_fourcc, gboolean do_rewind)
99 while (fread(&buf, sizeof(guchar), 8, f)>0) {
100 unsigned long long buf_size = 0;
101 unsigned int buf_fourcc = MMCAM_FOURCC(buf[4], buf[5], buf[6], buf[7]);
103 if (tag_fourcc == buf_fourcc) {
104 _mmcam_dbg_log("find tag : %c%c%c%c", MMCAM_FOURCC_ARGS(tag_fourcc));
107 _mmcam_dbg_log("skip [%c%c%c%c] tag", MMCAM_FOURCC_ARGS(buf_fourcc));
109 buf_size = (unsigned long long)_mmcamcorder_get_container_size(buf);
110 buf_size = buf_size - 8; /* include tag */
113 if (buf_size > _MMCAMCORDER_MAX_INT) {
114 _mmcam_dbg_log("seek %d", _MMCAMCORDER_MAX_INT);
115 if (fseek(f, _MMCAMCORDER_MAX_INT, SEEK_CUR) != 0) {
116 _mmcam_dbg_err("fseek() fail");
120 buf_size -= _MMCAMCORDER_MAX_INT;
122 _mmcam_dbg_log("seek %d", buf_size);
123 if (fseek(f, buf_size, SEEK_CUR) != 0) {
124 _mmcam_dbg_err("fseek() fail");
133 _mmcam_dbg_log("cannot find tag : %c%c%c%c", MMCAM_FOURCC_ARGS(tag_fourcc));
138 gboolean _mmcamcorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos)
140 _mmcam_dbg_log("size : %"G_GINT64_FORMAT"", curr_pos-prev_pos);
141 if(fseek(f, prev_pos, SEEK_SET) != 0)
143 _mmcam_dbg_err("fseek() fail");
147 if (!write_to_32(f, curr_pos -prev_pos))
150 if(fseek(f, curr_pos, SEEK_SET) != 0)
152 _mmcam_dbg_err("fseek() fail");
159 gboolean _mmcamcorder_write_loci(FILE *f, _MMCamcorderLocationInfo info)
161 gint64 current_pos, pos;
166 if((pos = ftell(f))<0)
168 _mmcam_dbg_err("ftell() returns negative value");
172 if(!write_to_32(f, 0)) //size
175 if(!write_tag(f, "loci")) // type
178 FPUTC_CHECK(0, f); // version
180 if(!write_to_24(f, 0)) // flags
183 if(!write_to_16(f, get_language_code("eng"))) // language
186 str = str_to_utf8("location_name");
188 FPUTS_CHECK(str, f); // name
191 FPUTC_CHECK('\0', f);
192 FPUTC_CHECK(0, f); //role
194 if(!write_to_32(f, info.longitude)) // Longitude
197 if(!write_to_32(f, info.latitude)) // Latitude
200 if(! write_to_32(f, info.altitude)) // Altitude
203 str = str_to_utf8("Astronomical_body");
204 FPUTS_CHECK(str, f);//Astronomical_body
207 FPUTC_CHECK('\0', f);
209 str = str_to_utf8("Additional_notes");
210 FPUTS_CHECK(str, f); // Additional_notes
213 FPUTC_CHECK('\0', f);
215 if((current_pos = ftell(f))<0)
217 _mmcam_dbg_err("ftell() returns negative value");
221 if(! _mmcamcorder_update_size(f, pos, current_pos))
227 gboolean _mmcamcorder_write_udta(FILE *f, _MMCamcorderLocationInfo info)
229 gint64 current_pos, pos;
233 if((pos = ftell(f))<0)
235 _mmcam_dbg_err("ftell() returns negative value");
239 if(!write_to_32(f, 0)) //size
242 if(!write_tag(f, "udta")) // type
245 if(! _mmcamcorder_write_loci(f, info))
248 if((current_pos = ftell(f))<0)
250 _mmcam_dbg_err("ftell() returns negative value");
254 if(! _mmcamcorder_update_size(f, pos, current_pos))
262 guint64 _mmcamcorder_get_container_size(const guchar *size)
270 result = result | (temp << 16);
272 result = result | (temp << 8);
273 result = result | size[3];
275 _mmcam_dbg_log("result : %lld", (unsigned long long)result);
281 gboolean _mmcamcorder_update_composition_matrix(FILE *f, int orientation)
284 guint32 a = 0x00010000;
287 guint32 d = 0x00010000;
289 switch (orientation) {
290 case MM_CAMCORDER_TAG_VIDEO_ORT_90:/* 90 degree */
296 case MM_CAMCORDER_TAG_VIDEO_ORT_180:/* 180 degree */
300 case MM_CAMCORDER_TAG_VIDEO_ORT_270:/* 270 degree */
306 case MM_CAMCORDER_TAG_VIDEO_ORT_NONE:/* 0 degree */
319 write_to_32(f, 0x40000000);
321 _mmcam_dbg_log("orientation : %d, write data 0x%x 0x%x 0x%x 0x%x",
322 orientation, a, b, c, d);
328 int _mmcamcorder_get_freespace(const gchar *path, guint64 *free_space)
334 if (!g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
335 _mmcam_dbg_log("File(%s) doesn't exist.", path);
339 if (-1 == statfs(path, &fs)) {
340 _mmcam_dbg_log("Getting free space is failed.(%s)", path);
344 *free_space = (guint64)fs.f_bsize * fs.f_bavail;
349 int _mmcamcorder_get_file_size(const char *filename, guint64 *size)
353 if (stat(filename, &buf) != 0)
355 *size = (guint64)buf.st_size;
360 void _mmcamcorder_remove_buffer_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
362 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
364 MMCamcorderHandlerItem *item = NULL;
366 mmf_return_if_fail(hcamcorder);
368 if(!hcamcorder->buffer_probes)
370 _mmcam_dbg_err("Fail to remove buffer probe, list for buffer probe is NULL");
373 list = hcamcorder->buffer_probes;
381 _mmcam_dbg_err("Remove buffer probe faild, the item is NULL");
382 list = g_list_next(list);
386 if(item->category & category)
389 if(item->object && GST_IS_PAD(item->object))
391 _mmcam_dbg_log("Remove buffer probe on [%s:%s] - [ID : %lu], [Category : %x]",
392 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
393 gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
397 _mmcam_dbg_warn("Remove buffer probe faild, the pad is null or not pad, just remove item from list and free it");
400 list = g_list_next(list);
401 hcamcorder->buffer_probes = g_list_remove(hcamcorder->buffer_probes, item);
406 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
407 list = g_list_next(list);
411 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
413 g_list_free(hcamcorder->buffer_probes);
414 hcamcorder->buffer_probes = NULL;
418 void _mmcamcorder_remove_event_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
420 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
422 MMCamcorderHandlerItem *item = NULL;
424 mmf_return_if_fail(hcamcorder);
426 if(!hcamcorder->event_probes)
428 _mmcam_dbg_err("Fail to remove event probe, list for event probe is NULL");
431 list = hcamcorder->event_probes;
439 _mmcam_dbg_err("Remove event probe faild, the item is NULL");
440 list = g_list_next(list);
444 if(item->category & category)
447 if(item->object && GST_IS_PAD(item->object))
449 _mmcam_dbg_log("Remove event probe on [%s:%s] - [ID : %lu], [Category : %x]",
450 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
451 gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
455 _mmcam_dbg_warn("Remove event probe faild, the pad is null or not pad, just remove item from list and free it");
458 list = g_list_next(list);
459 hcamcorder->event_probes = g_list_remove(hcamcorder->event_probes, item);
464 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
465 list = g_list_next(list);
469 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
471 g_list_free(hcamcorder->event_probes);
472 hcamcorder->event_probes = NULL;
476 void _mmcamcorder_remove_data_probe(MMHandleType handle, _MMCamcorderHandlerCategory category)
478 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
480 MMCamcorderHandlerItem *item = NULL;
482 mmf_return_if_fail(hcamcorder);
484 if(!hcamcorder->data_probes)
486 _mmcam_dbg_err("Fail to remove data probe, list for data probe is NULL");
489 list = hcamcorder->data_probes;
497 _mmcam_dbg_err("Remove data probe faild, the item is NULL");
498 list = g_list_next(list);
502 if(item->category & category)
505 if(item->object && GST_IS_PAD(item->object))
507 _mmcam_dbg_log("Remove data probe on [%s:%s] - [ID : %lu], [Category : %x]",
508 GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category);
509 gst_pad_remove_probe(GST_PAD(item->object), item->handler_id);
513 _mmcam_dbg_warn("Remove data probe faild, the pad is null or not pad, just remove item from list and free it");
516 list = g_list_next(list);
517 hcamcorder->data_probes = g_list_remove(hcamcorder->data_probes, item);
522 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
523 list = g_list_next(list);
527 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
529 g_list_free(hcamcorder->data_probes);
530 hcamcorder->data_probes = NULL;
534 void _mmcamcorder_disconnect_signal(MMHandleType handle, _MMCamcorderHandlerCategory category)
536 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
538 MMCamcorderHandlerItem *item = NULL;
540 mmf_return_if_fail(hcamcorder);
542 if(!hcamcorder->signals)
544 _mmcam_dbg_err("Fail to disconnect signals, list for signal is NULL");
547 list = hcamcorder->signals;
555 _mmcam_dbg_err("Fail to Disconnecting signal, the item is NULL");
556 list = g_list_next(list);
560 if(item->category & category)
563 if(item->object && GST_IS_ELEMENT(item->object))
565 if ( g_signal_handler_is_connected ( item->object, item->handler_id ) )
567 _mmcam_dbg_log("Disconnect signal from [%s] : [ID : %lu], [Category : %x]",
568 GST_OBJECT_NAME(item->object), item->handler_id, item->category);
569 g_signal_handler_disconnect ( item->object, item->handler_id );
573 _mmcam_dbg_warn("Signal was not connected, cannot disconnect it : [%s] [ID : %lu], [Category : %x]",
574 GST_OBJECT_NAME(item->object), item->handler_id, item->category);
580 _mmcam_dbg_err("Fail to Disconnecting signal, the element is null or not element, just remove item from list and free it");
583 list = g_list_next(list);
584 hcamcorder->signals = g_list_remove(hcamcorder->signals, item);
589 _mmcam_dbg_log("Skip item : [ID : %lu], [Category : %x] ", item->handler_id, item->category);
590 list = g_list_next(list);
594 if( category == _MMCAMCORDER_HANDLER_CATEGORY_ALL)
596 g_list_free(hcamcorder->signals);
597 hcamcorder->signals = NULL;
601 void _mmcamcorder_remove_all_handlers(MMHandleType handle, _MMCamcorderHandlerCategory category)
603 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
605 _mmcam_dbg_log("ENTER");
607 if(hcamcorder->signals)
608 _mmcamcorder_disconnect_signal((MMHandleType)hcamcorder, category);
609 if(hcamcorder->data_probes)
610 _mmcamcorder_remove_data_probe((MMHandleType)hcamcorder, category);
611 if(hcamcorder->event_probes)
612 _mmcamcorder_remove_event_probe((MMHandleType)hcamcorder, category);
613 if(hcamcorder->buffer_probes)
614 _mmcamcorder_remove_buffer_probe((MMHandleType)hcamcorder, category);
616 _mmcam_dbg_log("LEAVE");
620 void _mmcamcorder_element_release_noti(gpointer data, GObject *where_the_object_was)
623 _MMCamcorderSubContext *sc = (_MMCamcorderSubContext *)data;
624 mmf_return_if_fail(sc);
625 mmf_return_if_fail(sc->element);
627 for (i = 0 ; i < _MMCamcorder_PIPELINE_ELEMENT_NUM ; i++) {
628 if (sc->element[i].gst && (G_OBJECT(sc->element[i].gst) == where_the_object_was)) {
629 _mmcam_dbg_log("The element[%d][%p] is finalized", sc->element[i].id, sc->element[i].gst);
630 sc->element[i].gst = NULL;
631 sc->element[i].id = _MMCAMCORDER_NONE;
639 _mmcamcroder_msg_callback(void *data)
641 _MMCamcorderMsgItem *item = (_MMCamcorderMsgItem*)data;
642 mmf_camcorder_t *hcamcorder = NULL;
643 mmf_return_val_if_fail(item, FALSE);
645 hcamcorder = MMF_CAMCORDER(item->handle);
646 mmf_return_val_if_fail(hcamcorder, FALSE);
648 /*_mmcam_dbg_log("msg id:%x, msg_cb:%p, msg_data:%p, item:%p", item->id, hcamcorder->msg_cb, hcamcorder->msg_data, item);*/
650 _MMCAMCORDER_LOCK_MESSAGE_CALLBACK(hcamcorder);
652 /* check delay of CAPTURED message */
653 if (item->id == MM_MESSAGE_CAMCORDER_CAPTURED) {
654 MMTA_ACUM_ITEM_END(" CAPTURED MESSAGE DELAY", FALSE);
657 if ((hcamcorder) && (hcamcorder->msg_cb)) {
658 hcamcorder->msg_cb(item->id, (MMMessageParamType*)(&(item->param)), hcamcorder->msg_cb_param);
661 _MMCAMCORDER_UNLOCK_MESSAGE_CALLBACK(hcamcorder);
663 _MMCAMCORDER_LOCK((MMHandleType)hcamcorder);
665 if (hcamcorder->msg_data) {
666 hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
669 /* release allocated memory */
670 if (item->id == MM_MESSAGE_CAMCORDER_FACE_DETECT_INFO) {
671 MMCamFaceDetectInfo *cam_fd_info = (MMCamFaceDetectInfo *)item->param.data;
673 SAFE_FREE(cam_fd_info->face_info);
678 item->param.data = NULL;
679 item->param.size = 0;
685 _MMCAMCORDER_UNLOCK((MMHandleType)hcamcorder);
687 /* For not being called again */
693 _mmcamcroder_send_message(MMHandleType handle, _MMCamcorderMsgItem *data)
695 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
696 _MMCamcorderMsgItem *item = NULL;
698 mmf_return_val_if_fail(hcamcorder, FALSE);
699 mmf_return_val_if_fail(data, FALSE);
703 case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
704 case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM:
705 data->param.union_type = MM_MSG_UNION_STATE;
707 case MM_MESSAGE_CAMCORDER_RECORDING_STATUS:
708 data->param.union_type = MM_MSG_UNION_RECORDING_STATUS;
710 case MM_MESSAGE_CAMCORDER_FIRMWARE_UPDATE:
711 data->param.union_type = MM_MSG_UNION_FIRMWARE;
713 case MM_MESSAGE_CAMCORDER_CURRENT_VOLUME:
714 data->param.union_type = MM_MSG_UNION_REC_VOLUME_DB;
716 case MM_MESSAGE_CAMCORDER_TIME_LIMIT:
717 case MM_MESSAGE_CAMCORDER_MAX_SIZE:
718 case MM_MESSAGE_CAMCORDER_NO_FREE_SPACE:
719 case MM_MESSAGE_CAMCORDER_ERROR:
720 case MM_MESSAGE_CAMCORDER_FOCUS_CHANGED:
721 case MM_MESSAGE_CAMCORDER_CAPTURED:
722 case MM_MESSAGE_CAMCORDER_VIDEO_CAPTURED:
723 case MM_MESSAGE_CAMCORDER_AUDIO_CAPTURED:
724 case MM_MESSAGE_READY_TO_RESUME:
726 data->param.union_type = MM_MSG_UNION_CODE;
730 item = g_malloc(sizeof(_MMCamcorderMsgItem));
731 memcpy(item, data, sizeof(_MMCamcorderMsgItem));
732 item->handle = handle;
734 _MMCAMCORDER_LOCK(handle);
735 hcamcorder->msg_data = g_list_append(hcamcorder->msg_data, item);
736 // _mmcam_dbg_log("item[%p]", item);
738 /* Use DEFAULT priority */
739 g_idle_add_full(G_PRIORITY_DEFAULT, _mmcamcroder_msg_callback, item, NULL);
741 _MMCAMCORDER_UNLOCK(handle);
748 _mmcamcroder_remove_message_all(MMHandleType handle)
750 mmf_camcorder_t* hcamcorder = MMF_CAMCORDER(handle);
751 _MMCamcorderMsgItem *item = NULL;
755 mmf_return_if_fail(hcamcorder);
757 _MMCAMCORDER_LOCK(handle);
759 if(!hcamcorder->msg_data)
761 _mmcam_dbg_log("No message data is remained.");
765 list = hcamcorder->msg_data;
770 list = g_list_next(list);
774 _mmcam_dbg_err("Fail to remove message. The item is NULL");
778 ret = g_idle_remove_by_data (item);
779 _mmcam_dbg_log("Remove item[%p]. ret[%d]", item, ret);
781 hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
787 g_list_free(hcamcorder->msg_data);
788 hcamcorder->msg_data = NULL;
791 /* remove idle function for playing capture sound */
793 ret = g_idle_remove_by_data(hcamcorder);
794 _mmcam_dbg_log("remove idle function for playing capture sound. ret[%d]", ret);
797 _MMCAMCORDER_UNLOCK(handle);
804 _mmcamcorder_err_trace_write( char *str_filename, char *func_name, int line_num, char *fmt, ... )
808 char time_string[TIME_STRING_MAX_LEN] = {'\0',};
813 mmf_return_if_fail( str_filename );
815 current_time = time( NULL );
816 localtime_r( ¤t_time, &new_time );
818 f = fopen( str_filename, "a" );
821 _mmcam_dbg_warn( "Failed to open file.[%s]", str_filename );
825 asctime_r(&new_time, time_string);
826 fprintf( f, "[%.19s][%05d][%s]", time_string, line_num, func_name );
829 vfprintf( f, fmt, ap );
837 int _mmcamcorder_get_pixel_format(GstCaps *caps)
839 const GstStructure *structure;
840 const char *media_type;
841 GstVideoInfo media_info;
842 MMPixelFormatType type = 0;
843 unsigned int fourcc = 0;
845 mmf_return_val_if_fail( caps != NULL, MM_PIXEL_FORMAT_INVALID );
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")
856 && gst_video_info_from_caps(&media_info, caps)
857 && GST_VIDEO_INFO_IS_YUV(&media_info))
859 _mmcam_dbg_log("It is yuv.");
860 fourcc = gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(&media_info));
861 type = _mmcamcorder_get_pixtype(fourcc);
865 _mmcam_dbg_err("Not supported format");
866 type = MM_PIXEL_FORMAT_INVALID;
869 _mmcam_dbg_log( "Type [%d]", type );
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, (unsigned int*)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, (unsigned int*)dst_width, (unsigned int*)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);