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 =======================================================================================*/
26 #include <sys/times.h>
27 #include <gst/interfaces/cameracontrol.h>
28 #include "mm_camcorder_internal.h"
29 #include "mm_camcorder_stillshot.h"
30 #include "mm_camcorder_exifinfo.h"
31 #include "mm_camcorder_exifdef.h"
33 /*---------------------------------------------------------------------------------------
34 | GLOBAL VARIABLE DEFINITIONS for internal |
35 ---------------------------------------------------------------------------------------*/
36 #define EXIF_SET_ERR( return_type,tag_id) \
37 _mmcam_dbg_err("error=%x,tag=%x",return_type,tag_id); \
38 if (return_type == MM_ERROR_CAMCORDER_LOW_MEMORY) { \
42 /*---------------------------------------------------------------------------------------
43 | LOCAL VARIABLE DEFINITIONS for internal |
44 ---------------------------------------------------------------------------------------*/
47 /*---------------------------------------------------------------------------------------
48 | LOCAL FUNCTION PROTOTYPES: |
49 ---------------------------------------------------------------------------------------*/
50 /** STATIC INTERNAL FUNCTION **/
51 /* Functions for JPEG capture without Encode bin */
52 int _mmcamcorder_image_cmd_capture(MMHandleType handle);
53 int _mmcamcorder_image_cmd_preview_start(MMHandleType handle);
54 int _mmcamcorder_image_cmd_preview_stop(MMHandleType handle);
55 static void __mmcamcorder_image_capture_cb(GstElement *element, GstBuffer *buffer1, GstBuffer *buffer2, GstBuffer *buffer3, gpointer u_data);
57 /* Functions for JPEG capture with Encode bin */
58 int _mmcamcorder_image_cmd_capture_with_encbin(MMHandleType handle);
59 int _mmcamcorder_image_cmd_preview_start_with_encbin(MMHandleType handle);
60 int _mmcamcorder_image_cmd_preview_stop_with_encbin(MMHandleType handle);
61 static gboolean __mmcamcorder_encodesink_handoff_callback(GstElement *fakesink, GstBuffer *buffer, GstPad *pad, gpointer u_data);
63 /*=======================================================================================
64 | FUNCTION DEFINITIONS |
65 =======================================================================================*/
67 /*---------------------------------------------------------------------------------------
68 | GLOBAL FUNCTION DEFINITIONS: |
69 ---------------------------------------------------------------------------------------*/
72 int _mmcamcorder_add_stillshot_pipeline(MMHandleType handle)
74 int err = MM_ERROR_UNKNOWN;
76 GstPad *srcpad = NULL;
77 GstPad *sinkpad = NULL;
79 mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
80 _MMCamcorderSubContext *sc = NULL;
81 _MMCamcorderImageInfo *info = NULL;
83 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
85 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
86 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
92 //Create gstreamer element
94 if (!sc->element[_MMCAMCORDER_MAIN_PIPE].gst) {
95 _mmcam_dbg_err( "Main Pipeline is not existed." );
96 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
97 goto pipeline_creation_error;
100 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
101 CONFIGURE_CATEGORY_MAIN_CAPTURE,
103 &sc->bencbin_capture);
105 if (sc->bencbin_capture) {
106 _mmcam_dbg_log("Using Encodebin for capturing");
107 __ta__(" _mmcamcorder_create_encodesink_bin",
108 err = _mmcamcorder_create_encodesink_bin((MMHandleType)hcamcorder);
110 if (err != MM_ERROR_NONE) {
114 gst_bin_add_many(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
115 sc->element[_MMCAMCORDER_ENCSINK_BIN].gst,
118 /* Link each element */
119 srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, "src1");
120 sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, "image_sink0");
121 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, element_link_error)
123 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
124 _MMCAMCORDER_HANDLER_STILLSHOT, "handoff",
125 G_CALLBACK(__mmcamcorder_encodesink_handoff_callback),
128 _mmcam_dbg_log("NOT using Encodebin for capturing");
130 /*set video source element*/
131 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "signal-still-capture", TRUE);
133 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
134 _MMCAMCORDER_HANDLER_STILLSHOT, "still-capture",
135 G_CALLBACK(__mmcamcorder_image_capture_cb),
139 return MM_ERROR_NONE;
142 if (sc->bencbin_capture) {
143 _mmcam_dbg_err("Link encodebin failed!");
145 if (sc->element[_MMCAMCORDER_ENCSINK_BIN].gst != NULL) {
146 int ret = MM_ERROR_NONE;
148 __ta__( " EncodeBin Set NULL",
149 ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, GST_STATE_NULL);
151 if (ret != MM_ERROR_NONE) {
152 _mmcam_dbg_err("Faile to change encode bin state[%d]", ret);
153 /* Can't return here. */
157 gst_bin_remove(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
158 sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
160 _mmcamcorder_remove_element_handle(handle, _MMCAMCORDER_ENCSINK_BIN, _MMCAMCORDER_ENCSINK_SINK);
162 _mmcam_dbg_log("Encodebin removed");
166 return MM_ERROR_CAMCORDER_GST_LINK;
168 pipeline_creation_error:
173 int _mmcamcorder_remove_stillshot_pipeline(MMHandleType handle)
175 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
176 _MMCamcorderSubContext *sc = NULL;
177 _MMCamcorderImageInfo *info = NULL;
179 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
181 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
182 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
189 if (sc->element[_MMCAMCORDER_MAIN_PIPE].gst) {
190 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_STILLSHOT);
192 if (sc->bencbin_capture) {
193 GstPad *srcpad = NULL, *sinkpad = NULL;
194 if (!sc->element[_MMCAMCORDER_ENCSINK_BIN].gst) {
195 _mmcam_dbg_log("ENCSINK_BIN is already removed");
197 /* Unlink each element */
198 srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, "src1");
199 sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, "image_sink0");
200 _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad);
202 gst_bin_remove(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
203 sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
205 _mmcamcorder_remove_element_handle(handle, _MMCAMCORDER_ENCSINK_BIN, _MMCAMCORDER_ENCSINK_SINK);
209 _mmcam_dbg_log("MAIN_PIPE is already removed");
212 return MM_ERROR_NONE;
216 void _mmcamcorder_destroy_image_pipeline(MMHandleType handle)
218 GstPad *reqpad1 = NULL;
219 GstPad *reqpad2 = NULL;
221 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
222 _MMCamcorderSubContext *sc = NULL;
224 mmf_return_if_fail(hcamcorder);
226 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
227 mmf_return_if_fail(sc && sc->element);
231 if (sc->element[_MMCAMCORDER_MAIN_PIPE].gst) {
232 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
233 _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_NULL);
235 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_CATEGORY_ALL);
237 reqpad1 = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src0");
238 reqpad2 = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src1");
239 gst_element_release_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, reqpad1);
240 gst_element_release_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, reqpad2);
241 gst_object_unref(reqpad1);
242 gst_object_unref(reqpad2);
244 if (sc->bencbin_capture) {
245 if (sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst) {
246 GstPad *reqpad0 = NULL;
247 reqpad0 = gst_element_get_static_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "image");
248 gst_element_release_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, reqpad0);
249 gst_object_unref(reqpad0);
253 gst_object_unref(sc->element[_MMCAMCORDER_MAIN_PIPE].gst);
254 /* Why is this commented? */
255 /* sc->element[_MMCAMCORDER_MAIN_PIPE].gst = NULL; */
260 int _mmcamcorder_image_cmd_capture(MMHandleType handle)
262 int ret = MM_ERROR_NONE;
263 int UseCaptureMode = 0;
267 int cap_format = MM_PIXEL_FORMAT_NV12;
268 int cap_jpeg_quality = 0;
269 int image_encoder = MM_IMAGE_CODEC_JPEG;
270 unsigned int cap_fourcc = 0;
272 char *err_name = NULL;
273 char *videosrc_name = NULL;
275 GstElement *pipeline = NULL;
276 GstCameraControl *control = NULL;
277 GstCaps *caps = NULL;
278 GstClock *clock = NULL;
280 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
281 _MMCamcorderImageInfo *info = NULL;
282 _MMCamcorderSubContext *sc = NULL;
283 type_element *VideosrcElement = NULL;
285 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
287 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
288 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
292 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
295 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
296 CONFIGURE_CATEGORY_MAIN_CAPTURE,
300 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
301 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
305 _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
307 if (info->capturing) {
308 ret = MM_ERROR_CAMCORDER_DEVICE_BUSY;
312 MMTA_ACUM_ITEM_BEGIN("Real First Capture Start",false);
314 /* set capture flag */
315 info->capturing = TRUE;
317 ret = mm_camcorder_get_attributes(handle, &err_name,
318 MMCAM_IMAGE_ENCODER_QUALITY, &cap_jpeg_quality,
319 MMCAM_IMAGE_ENCODER, &image_encoder,
320 MMCAM_CAMERA_WIDTH, &width,
321 MMCAM_CAMERA_HEIGHT, &height,
322 MMCAM_CAMERA_FPS, &fps,
323 MMCAM_CAPTURE_FORMAT, &cap_format,
324 MMCAM_CAPTURE_WIDTH, &info->width,
325 MMCAM_CAPTURE_HEIGHT, &info->height,
326 MMCAM_CAPTURE_COUNT, &info->count,
327 MMCAM_CAPTURE_INTERVAL, &info->interval,
329 if (ret != MM_ERROR_NONE) {
330 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
331 SAFE_FREE (err_name);
335 if (info->count < 1) {
336 _mmcam_dbg_err("capture count[%d] is invalid", info->count);
337 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
339 } else if (info->count == 1) {
340 info->type = _MMCamcorder_SINGLE_SHOT;
342 info->type = _MMCamcorder_MULTI_SHOT;
343 info->next_shot_time = 0;
344 info->multi_shot_stop = FALSE;
347 info->capture_cur_count = 0;
348 info->capture_send_count = 0;
350 _mmcam_dbg_log("videosource(%dx%d), capture(%dx%d), count(%d)",
351 width, height, info->width, info->height, info->count);
353 sc->internal_encode = FALSE;
355 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
356 /* Check encoding method */
357 if (cap_format == MM_PIXEL_FORMAT_ENCODED) {
358 if (sc->SensorEncodedCapture && info->type == _MMCamcorder_SINGLE_SHOT) {
359 cap_fourcc = _mmcamcorder_get_fourcc(cap_format, image_encoder, hcamcorder->use_zero_copy_format);
360 _mmcam_dbg_log("Sensor JPEG Capture");
362 int raw_capture_format = MM_PIXEL_FORMAT_I420;
364 ret = mm_camcorder_get_attributes(handle, &err_name,
365 MMCAM_RECOMMEND_PREVIEW_FORMAT_FOR_CAPTURE, &raw_capture_format,
367 if (ret != MM_ERROR_NONE) {
368 _mmcam_dbg_warn("Get Recommend capture format failed.");
373 cap_fourcc = _mmcamcorder_get_fourcc(raw_capture_format, image_encoder, hcamcorder->use_zero_copy_format);
374 sc->internal_encode = TRUE;
376 _mmcam_dbg_log("MSL JPEG Capture");
379 cap_fourcc = _mmcamcorder_get_fourcc(cap_format, MM_IMAGE_CODEC_INVALID, hcamcorder->use_zero_copy_format);
380 if (info->type == _MMCamcorder_SINGLE_SHOT && !strcmp(videosrc_name, "camerasrc")) {
381 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE );
382 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", TRUE );
386 _mmcam_dbg_log("capture format (%d), jpeg quality (%d)", cap_format, cap_jpeg_quality);
388 /* Note: width/height of capture is set in commit function of attribute or in create function of pipeline */
389 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-fourcc", cap_fourcc);
390 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-interval", info->interval);
391 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-count", info->count);
392 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-jpg-quality", cap_jpeg_quality);
394 if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
395 _mmcam_dbg_err("Can't cast Video source into camera control.");
396 return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
399 control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
400 gst_camera_control_set_capture_command(control, GST_CAMERA_CONTROL_CAPTURE_COMMAND_START);
406 if (UseCaptureMode) {
407 if (width != MMFCAMCORDER_HIGHQUALITY_WIDTH || height != MMFCAMCORDER_HIGHQUALITY_HEIGHT) {
411 if (width != info->width || height != info->height) {
417 _mmcam_dbg_log("Need to change resolution");
419 if (UseCaptureMode) {
420 set_width = MMFCAMCORDER_HIGHQUALITY_WIDTH;
421 set_height = MMFCAMCORDER_HIGHQUALITY_HEIGHT;
423 set_width = info->width;
424 set_height = info->height;
427 caps = gst_caps_new_simple("video/x-raw-yuv",
428 "format", GST_TYPE_FOURCC, sc->fourcc,
429 "width", G_TYPE_INT, set_width,
430 "height", G_TYPE_INT, set_height,
431 "framerate", GST_TYPE_FRACTION, fps, 1,
432 "rotate", G_TYPE_INT, 0,
435 _mmcam_dbg_err("failed to create caps");
436 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
440 info->resolution_change = TRUE;
441 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
442 gst_caps_unref(caps);
444 /*MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "num-buffers", info->count);*/
445 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "req-negotiation",TRUE);
447 /* FIXME: consider delay */
448 clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
449 sc->stillshot_time = gst_clock_get_time(clock) - gst_element_get_base_time(GST_ELEMENT(pipeline));
450 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
452 _mmcam_dbg_log("Change to target resolution(%d, %d)", set_width, set_height);
454 _mmcam_dbg_log("No need to change resolution. Open toggle now.");
455 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
459 /* Play capture sound here if single capture */
460 if (info->type == _MMCamcorder_SINGLE_SHOT) {
461 _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_FILEPATH_CAPTURE_SND, FALSE);
469 int _mmcamcorder_image_cmd_preview_start(MMHandleType handle)
471 int ret = MM_ERROR_NONE;
482 int current_framecount = 0;
483 gboolean fps_auto = FALSE;
484 char *err_name = NULL;
485 char *videosrc_name = NULL;
488 GstCaps *caps = NULL;
489 GstElement *pipeline = NULL;
490 GstCameraControl *control = NULL;
492 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
493 _MMCamcorderImageInfo *info = NULL;
494 _MMCamcorderSubContext *sc = NULL;
495 type_element *VideosrcElement = NULL;
497 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
499 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
500 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
504 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
507 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
509 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
510 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
514 _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
516 sc->display_interval = 0;
517 sc->previous_slot_time = 0;
520 info->capture_cur_count = 0;
521 info->capture_send_count = 0;
522 info->next_shot_time = 0;
523 info->multi_shot_stop = TRUE;
524 info->capturing = FALSE;
526 _mmcamcorder_vframe_stablize(handle);
528 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
529 _mmcam_dbg_log("Capture Preview start : avsysvideosrc - No need to set new caps.");
531 ret = mm_camcorder_get_attributes(handle, &err_name,
532 MMCAM_CAMERA_FPS_AUTO, &fps_auto,
534 if (ret != MM_ERROR_NONE) {
535 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
536 SAFE_FREE (err_name);
540 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "fps-auto", fps_auto);
542 if (_mmcamcorder_get_state(handle) == MM_CAMCORDER_STATE_CAPTURING) {
543 if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
544 _mmcam_dbg_err("Can't cast Video source into camera control.");
545 return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
548 control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
549 gst_camera_control_set_capture_command(control, GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP);
551 current_framecount = sc->kpi.video_framecount;
552 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", FALSE);
553 if (info->type == _MMCamcorder_SINGLE_SHOT) {
554 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
558 /* check if resolution need to rollback */
559 ret = mm_camcorder_get_attributes(handle, &err_name,
560 MMCAM_CAMERA_DEVICE, &input_index,
561 MMCAM_CAMERA_WIDTH, &width,
562 MMCAM_CAMERA_HEIGHT, &height,
563 MMCAM_CAMERA_FPS, &fps,
564 MMCAM_CAMERA_FPS_AUTO, &fps_auto,
565 MMCAM_CAMERA_ROTATION, &rotation,
566 MMCAM_CAPTURE_WIDTH, &cap_width,
567 MMCAM_CAPTURE_HEIGHT, &cap_height,
569 if (ret != MM_ERROR_NONE) {
570 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
571 SAFE_FREE (err_name);
575 if (_mmcamcorder_get_state((MMHandleType)hcamcorder) == MM_CAMCORDER_STATE_CAPTURING) {
577 case MM_VIDEO_INPUT_ROTATION_90:
582 case MM_VIDEO_INPUT_ROTATION_180:
587 case MM_VIDEO_INPUT_ROTATION_270:
592 case MM_VIDEO_INPUT_ROTATION_NONE:
600 caps = gst_caps_new_simple("video/x-raw-yuv",
601 "format", GST_TYPE_FOURCC, sc->fourcc,
602 "width", G_TYPE_INT, set_width,
603 "height", G_TYPE_INT,set_height,
604 "framerate", GST_TYPE_FRACTION, fps, 1,
605 "rotate", G_TYPE_INT, set_rotate,
608 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
609 gst_caps_unref(caps);
610 _mmcam_dbg_log("Rollback to original resolution(%d, %d)", width, height);
612 _mmcam_dbg_err("failed to create caps");
613 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
619 gst_element_get_state(pipeline, &state, NULL, -1);
621 if (state == GST_STATE_PLAYING) {
622 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
625 __ta__( " Wait preview frame after capture",
626 while (current_framecount >= sc->kpi.video_framecount &&
627 try_count++ < _MMCAMCORDER_CAPTURE_STOP_CHECK_COUNT) {
628 usleep(_MMCAMCORDER_CAPTURE_STOP_CHECK_INTERVAL);
632 if (info->type == _MMCamcorder_MULTI_SHOT) {
633 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
636 _mmcam_dbg_log("Wait Frame Done. count before[%d],after[%d], try_count[%d]",
637 current_framecount, sc->kpi.video_framecount, try_count);
639 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
640 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
642 if (ret != MM_ERROR_NONE) {
646 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
647 if (ret != MM_ERROR_NONE) {
653 int sound_ret = FALSE;
655 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
657 __ta__(" _MMCamcorder_CMD_PREVIEW_START:GST_STATE_PLAYING",
658 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
660 if (ret != MM_ERROR_NONE) {
664 mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_COUNT, &cap_count, NULL);
666 __ta__("_mmcamcorder_sound_init",
667 sound_ret = _mmcamcorder_sound_init(handle, _MMCAMCORDER_FILEPATH_CAPTURE2_SND);
670 __ta__("_mmcamcorder_sound_prepare",
671 sound_ret = _mmcamcorder_sound_prepare(handle);
673 _mmcam_dbg_log("sound prepare [%d]", sound_ret);
683 int _mmcamcorder_image_cmd_preview_stop(MMHandleType handle)
685 int ret = MM_ERROR_NONE;
687 GstElement *pipeline = NULL;
689 _MMCamcorderSubContext *sc = NULL;
693 mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
695 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
696 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
698 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
700 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
701 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
702 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
708 int _mmcamcorder_image_cmd_capture_with_encbin(MMHandleType handle)
710 int ret = MM_ERROR_NONE;
711 int UseCaptureMode = 0;
715 int cap_format = MM_PIXEL_FORMAT_ENCODED;
716 int cap_jpeg_quality = 0;
717 int image_encoder = MM_IMAGE_CODEC_JPEG;
718 unsigned int cap_fourcc = GST_MAKE_FOURCC('J','P','E','G');
719 char *err_name = NULL;
720 char *videosrc_name = NULL;
722 GstCaps *caps = NULL;
723 GstClock *clock = NULL;
724 GstElement *pipeline = NULL;
725 GstCameraControl *control = NULL;
727 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
728 _MMCamcorderImageInfo *info = NULL;
729 _MMCamcorderSubContext *sc = NULL;
730 type_element *VideosrcElement = NULL;
732 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
734 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
735 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
739 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
742 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
743 CONFIGURE_CATEGORY_MAIN_CAPTURE,
747 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
748 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
752 _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
754 if (info->capturing) {
755 ret = MM_ERROR_CAMCORDER_DEVICE_BUSY;
759 MMTA_ACUM_ITEM_BEGIN("Real First Capture Start",false);
761 info->capturing = TRUE;
763 ret = mm_camcorder_get_attributes(handle, &err_name,
764 MMCAM_IMAGE_ENCODER_QUALITY, &cap_jpeg_quality,
765 MMCAM_IMAGE_ENCODER, &image_encoder,
766 MMCAM_CAMERA_WIDTH, &width,
767 MMCAM_CAMERA_HEIGHT, &height,
768 MMCAM_CAMERA_FPS, &fps,
769 MMCAM_CAPTURE_FORMAT, &cap_format,
770 MMCAM_CAPTURE_WIDTH, &info->width,
771 MMCAM_CAPTURE_HEIGHT, &info->height,
772 MMCAM_CAPTURE_COUNT, &info->count,
773 MMCAM_CAPTURE_INTERVAL, &info->interval,
775 if (ret != MM_ERROR_NONE) {
776 _mmcam_dbg_err("Get attrs fail. (%s:%x)", err_name, ret);
777 SAFE_FREE (err_name);
781 if (info->count < 1) {
782 _mmcam_dbg_err("capture count[%d] is invalid", info->count);
783 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
785 } else if (info->count == 1) {
786 info->type = _MMCamcorder_SINGLE_SHOT;
788 info->type = _MMCamcorder_MULTI_SHOT;
789 info->capture_cur_count = 0;
790 info->capture_send_count = 0;
791 info->next_shot_time = 0;
792 info->multi_shot_stop = FALSE;
795 _mmcam_dbg_log("videosource(%dx%d), capture(%dx%d), count(%d)",
796 width, height, info->width, info->height, info->count);
798 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
799 cap_fourcc = _mmcamcorder_get_fourcc(cap_format, image_encoder, hcamcorder->use_zero_copy_format);
800 _mmcam_dbg_log("capture format (%d), jpeg quality (%d)", cap_format, cap_jpeg_quality);
802 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-fourcc", cap_fourcc);
803 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-interval", info->interval);
804 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", info->width);
805 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", info->height);
806 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-count", info->count);
807 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-jpg-quality", cap_jpeg_quality);
809 if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
810 _mmcam_dbg_err("Can't cast Video source into camera control.");
811 return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
814 control = GST_CAMERA_CONTROL( sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst );
815 gst_camera_control_set_capture_command( control, GST_CAMERA_CONTROL_CAPTURE_COMMAND_START );
821 if (UseCaptureMode) {
822 if (width != MMFCAMCORDER_HIGHQUALITY_WIDTH || height != MMFCAMCORDER_HIGHQUALITY_HEIGHT) {
826 if (width != info->width || height != info->height) {
832 _mmcam_dbg_log("Need to change resolution");
834 if (UseCaptureMode) {
835 set_width = MMFCAMCORDER_HIGHQUALITY_WIDTH;
836 set_height = MMFCAMCORDER_HIGHQUALITY_HEIGHT;
838 set_width = info->width;
839 set_height = info->height;
842 caps = gst_caps_new_simple("video/x-raw-yuv",
843 "format", GST_TYPE_FOURCC, sc->fourcc,
844 "width", G_TYPE_INT, set_width,
845 "height", G_TYPE_INT, set_height,
846 "framerate", GST_TYPE_FRACTION, fps, 1,
847 "rotate", G_TYPE_INT, 0,
850 _mmcam_dbg_err("failed to create caps");
851 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
855 info->resolution_change = TRUE;
856 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
857 gst_caps_unref(caps);
859 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "req-negotiation",TRUE);
861 /* FIXME: consider delay */
862 clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
863 sc->stillshot_time = gst_clock_get_time(clock) - gst_element_get_base_time(GST_ELEMENT(pipeline));
864 _mmcam_dbg_log("Change to target resolution(%d, %d)", info->width, info->height);
865 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,"signal-handoffs",TRUE);
866 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
869 _mmcam_dbg_log("No need to change resolution. Open toggle now.");
870 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,"signal-handoffs",TRUE);
871 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
875 /* Play capture sound here if single capture */
876 if (info->type == _MMCamcorder_SINGLE_SHOT) {
877 _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_FILEPATH_CAPTURE_SND, FALSE);
885 int _mmcamcorder_image_cmd_preview_start_with_encbin(MMHandleType handle)
887 int ret = MM_ERROR_NONE;
898 int current_framecount = 0;
899 int current_state = MM_CAMCORDER_STATE_NONE;
900 gboolean fps_auto = FALSE;
901 char *err_name = NULL;
902 char *videosrc_name = NULL;
904 GstState state = GST_STATE_NULL;
905 GstCaps *caps = NULL;
906 GstElement *pipeline = NULL;
907 GstCameraControl *control = NULL;
909 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
910 _MMCamcorderImageInfo *info = NULL;
911 _MMCamcorderSubContext *sc = NULL;
912 type_element *VideosrcElement = NULL;
914 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
916 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
917 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
922 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
924 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
925 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
929 _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
931 sc->display_interval = 0;
932 sc->previous_slot_time = 0;
934 /* init image info */
935 info->capture_cur_count = 0;
936 info->capture_send_count = 0;
937 info->next_shot_time = 0;
938 info->multi_shot_stop = TRUE;
939 info->capturing = FALSE;
941 _mmcamcorder_vframe_stablize(handle);
943 current_state = _mmcamcorder_get_state(handle);
944 _mmcam_dbg_log("current state [%d]", current_state);
946 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
947 _mmcam_dbg_log("Capture Preview start : %s - No need to set new caps.", videosrc_name);
949 ret = mm_camcorder_get_attributes(handle, &err_name,
950 MMCAM_CAMERA_FPS_AUTO, &fps_auto,
952 if (ret != MM_ERROR_NONE) {
953 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
954 SAFE_FREE (err_name);
958 /* set fps-auto to videosrc */
959 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "fps-auto", fps_auto);
961 if (current_state == MM_CAMCORDER_STATE_CAPTURING) {
962 if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
963 _mmcam_dbg_err("Can't cast Video source into camera control.");
964 return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
967 current_framecount = sc->kpi.video_framecount;
969 control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
970 gst_camera_control_set_capture_command(control, GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP);
973 /* check if resolution need to roll back */
974 ret = mm_camcorder_get_attributes(handle, &err_name,
975 MMCAM_CAMERA_DEVICE, &input_index,
976 MMCAM_CAMERA_WIDTH, &width,
977 MMCAM_CAMERA_HEIGHT, &height,
978 MMCAM_CAMERA_FPS, &fps,
979 MMCAM_CAMERA_FPS_AUTO, &fps_auto,
980 MMCAM_CAMERA_ROTATION, &rotation,
981 MMCAM_CAPTURE_WIDTH, &cap_width,
982 MMCAM_CAPTURE_HEIGHT, &cap_height,
984 if (ret != MM_ERROR_NONE) {
985 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
986 SAFE_FREE (err_name);
990 if (current_state == MM_CAMCORDER_STATE_CAPTURING) {
992 case MM_VIDEO_INPUT_ROTATION_90:
997 case MM_VIDEO_INPUT_ROTATION_180:
1002 case MM_VIDEO_INPUT_ROTATION_270:
1007 case MM_VIDEO_INPUT_ROTATION_NONE:
1010 set_height = height;
1015 caps = gst_caps_new_simple("video/x-raw-yuv",
1016 "format", GST_TYPE_FOURCC, sc->fourcc,
1017 "width", G_TYPE_INT, set_width,
1018 "height", G_TYPE_INT,set_height,
1019 "framerate", GST_TYPE_FRACTION, fps, 1,
1020 "rotate", G_TYPE_INT, set_rotate,
1023 _mmcam_dbg_err("failed to create caps");
1024 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1028 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
1029 gst_caps_unref(caps);
1031 _mmcam_dbg_log("Rollback to original resolution(%d, %d)", width, height);
1035 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
1037 gst_element_get_state(pipeline, &state, NULL, -1);
1039 if (state == GST_STATE_PLAYING) {
1040 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
1041 __ta__( " Wait preview frame after capture",
1042 while (current_framecount == sc->kpi.video_framecount) {
1043 usleep(_MMCAMCORDER_CAPTURE_STOP_CHECK_INTERVAL);
1047 _mmcam_dbg_log("Wait Frame Done. count before[%d],after[%d]",
1048 current_framecount, sc->kpi.video_framecount);
1051 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
1052 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
1053 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
1054 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1055 #else /* This code wasn't work. So rollback to previous code. Plz tell me why. It's weired. */
1056 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1057 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
1058 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
1060 if (ret != MM_ERROR_NONE) {
1064 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1065 if (ret != MM_ERROR_NONE) {
1068 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1071 __ta__(" _MMCamcorder_CMD_PREVIEW_START:GST_STATE_PLAYING",
1072 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1074 if (ret != MM_ERROR_NONE) {
1080 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,"signal-handoffs",FALSE);
1081 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1086 int _mmcamcorder_image_cmd_preview_stop_with_encbin(MMHandleType handle)
1088 int ret = MM_ERROR_NONE;
1090 GstElement *pipeline = NULL;
1092 _MMCamcorderSubContext *sc = NULL;
1096 mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1098 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1099 mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1101 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
1103 /* set signal handler off */
1104 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,"signal-handoffs",FALSE);
1106 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1107 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
1108 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
1109 if (ret != MM_ERROR_NONE) {
1118 int _mmcamcorder_image_command(MMHandleType handle, int command)
1120 int ret = MM_ERROR_NONE;
1122 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1123 _MMCamcorderSubContext *sc = NULL;
1125 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1127 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1128 mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1130 _mmcam_dbg_log("command=%d", command);
1133 case _MMCamcorder_CMD_CAPTURE:
1134 if (!sc->bencbin_capture) {
1135 ret = _mmcamcorder_image_cmd_capture(handle);
1137 ret = _mmcamcorder_image_cmd_capture_with_encbin(handle);
1140 case _MMCamcorder_CMD_CAPTURE_CANCEL:
1141 /* TODO: Is this needed? */
1143 case _MMCamcorder_CMD_PREVIEW_START:
1144 if (!sc->bencbin_capture) {
1145 ret = _mmcamcorder_image_cmd_preview_start(handle);
1147 ret = _mmcamcorder_image_cmd_preview_start_with_encbin(handle);
1149 /* I place this function last because it miscalculates a buffer that sents in GST_STATE_PAUSED */
1150 _mmcamcorder_video_current_framerate_init(handle);
1152 case _MMCamcorder_CMD_PREVIEW_STOP:
1153 if (!sc->bencbin_capture) {
1154 ret = _mmcamcorder_image_cmd_preview_stop(handle);
1156 ret = _mmcamcorder_image_cmd_preview_stop_with_encbin(handle);
1160 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1164 if (ret != MM_ERROR_NONE && sc->element && sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
1166 MMCAMCORDER_G_OBJECT_GET (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "operation-status", &op_status);
1167 _mmcam_dbg_err("Current Videosrc status[0x%x]", op_status);
1174 void __mmcamcorder_init_stillshot_info (MMHandleType handle)
1176 int type = _MMCamcorder_SINGLE_SHOT;
1178 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1179 _MMCamcorderSubContext *sc = NULL;
1180 _MMCamcorderImageInfo *info = NULL;
1182 mmf_return_if_fail(hcamcorder);
1184 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1185 mmf_return_if_fail(sc && sc->info);
1190 _mmcam_dbg_log("capture type[%d], capture send count[%d]", type, info->capture_send_count);
1192 if (type ==_MMCamcorder_SINGLE_SHOT || info->capture_send_count == info->count) {
1193 info->capture_cur_count = 0;
1194 info->capture_send_count = 0;
1195 info->multi_shot_stop = TRUE;
1196 info->next_shot_time = 0;
1197 info->type = _MMCamcorder_SINGLE_SHOT;
1199 /* capturing flag set to FALSE here */
1200 info->capturing = FALSE;
1201 MMTA_ACUM_ITEM_END("Real First Capture Start", FALSE);
1208 gboolean __mmcamcorder_capture_save_exifinfo(MMHandleType handle, MMCamcorderCaptureDataType *original, MMCamcorderCaptureDataType *thumbnail)
1210 int ret = MM_ERROR_NONE;
1211 unsigned char *data = NULL;
1212 unsigned int datalen = 0;
1214 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1216 mmf_return_val_if_fail(hcamcorder, FALSE);
1220 if (!original || original->data == NULL || original->length == 0) {
1221 _mmcam_dbg_err("original=%p, data=%p, length=%d", original, original->data, original->length);
1224 /* original is input/output param. save original values to local var. */
1225 data = original->data;
1226 datalen = original->length;
1230 ret = mm_exif_create_exif_info(&(hcamcorder->exif_info));
1231 if (hcamcorder->exif_info == NULL || ret != MM_ERROR_NONE) {
1232 _MMCamcorderMsgItem msg;
1234 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1235 msg.param.code = ret;
1236 _mmcamcroder_send_message(handle, &msg);
1238 _mmcam_dbg_err("Failed to create exif_info [%x]", ret);
1242 /* add basic exif info */
1243 _mmcam_dbg_log("add basic exif info");
1244 __ta__(" __mmcamcorder_set_exif_basic_info",
1245 ret = __mmcamcorder_set_exif_basic_info(handle);
1247 if (ret != MM_ERROR_NONE) {
1248 _MMCamcorderMsgItem msg;
1250 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1251 msg.param.code = ret;
1252 _mmcamcroder_send_message(handle, &msg);
1254 _mmcam_dbg_err("Failed to set_exif_basic_info [%x]", ret);
1257 if (thumbnail != NULL) {
1258 int bthumbnail = TRUE;
1260 /* check whether thumbnail should be included */
1261 mm_camcorder_get_attributes(handle, NULL, "capture-thumbnail", &bthumbnail, NULL);
1263 if (thumbnail->data && thumbnail->length >0 && bthumbnail) {
1264 _mmcam_dbg_log("thumbnail is added!thumbnail->data=%p thumbnail->width=%d ,thumbnail->height=%d",
1265 thumbnail->data, thumbnail->width, thumbnail->height);
1267 /* add thumbnail exif info */
1268 __ta__(" mm_exif_add_thumbnail_info",
1269 ret = mm_exif_add_thumbnail_info(hcamcorder->exif_info, thumbnail->data,thumbnail->width, thumbnail->height, thumbnail->length);
1271 if (ret != MM_ERROR_NONE) {
1272 _MMCamcorderMsgItem msg;
1274 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1275 msg.param.code = ret;
1276 _mmcamcroder_send_message(handle, &msg);
1278 _mmcam_dbg_err("Failed to set_exif_thumbnail [%x]",ret);
1281 _mmcam_dbg_err("Skip adding thumbnail (data=%p, length=%d, capture-thumbnail=%d)",
1282 thumbnail->data, thumbnail->length , bthumbnail);
1286 /* write jpeg with exif */
1287 ret = mm_exif_write_exif_jpeg_to_memory(&original->data, &original->length ,hcamcorder->exif_info, data, datalen);
1289 if (ret != MM_ERROR_NONE) {
1290 _MMCamcorderMsgItem msg;
1292 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1293 msg.param.code = ret;
1294 _mmcamcroder_send_message(handle, &msg);
1296 _mmcam_dbg_err("mm_exif_write_exif_jpeg_to_memory error! [%x]",ret);
1299 /* destroy exif info */
1300 mm_exif_destory_exif_info(hcamcorder->exif_info);
1301 hcamcorder->exif_info = NULL;
1303 _mmcam_dbg_log("END");
1305 if (ret != MM_ERROR_NONE) {
1313 gboolean __mmcamcorder_capture_send_msg(MMHandleType handle, int type, int count)
1315 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1316 _MMCamcorderImageInfo *info = NULL;
1317 _MMCamcorderSubContext *sc = NULL;
1318 _MMCamcorderMsgItem msg;
1320 mmf_return_val_if_fail(hcamcorder, FALSE);
1322 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1323 mmf_return_val_if_fail(sc && sc->info, FALSE);
1327 _mmcam_dbg_log("type [%d], capture count [%d]", type, count);
1329 msg.id = MM_MESSAGE_CAMCORDER_CAPTURED;
1330 msg.param.code = count;
1332 _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1334 _mmcam_dbg_log("END");
1339 void __mmcamcorder_get_capture_data_from_buffer(MMCamcorderCaptureDataType *capture_data, int pixtype, GstBuffer *buffer)
1341 GstCaps *caps = NULL;
1342 const GstStructure *structure;
1344 mmf_return_if_fail(capture_data && buffer);
1346 caps = gst_buffer_get_caps(buffer);
1348 _mmcam_dbg_err("failed to get caps");
1352 structure = gst_caps_get_structure(caps, 0);
1354 _mmcam_dbg_err("failed to get structure");
1358 capture_data->data = GST_BUFFER_DATA(buffer);
1359 capture_data->format = pixtype;
1360 gst_structure_get_int(structure, "width", &capture_data->width);
1361 gst_structure_get_int(structure, "height", &capture_data->height);
1362 capture_data->length = GST_BUFFER_SIZE(buffer);
1364 _mmcam_dbg_err("buffer data[%p],size[%dx%d],length[%d],format[%d]",
1365 capture_data->data, capture_data->width, capture_data->height,
1366 capture_data->length, capture_data->format);
1367 gst_caps_unref(caps);
1373 capture_data->data = NULL;
1374 capture_data->format = MM_PIXEL_FORMAT_INVALID;
1375 capture_data->length = 0;
1381 gboolean __mmcamcorder_set_jpeg_data(MMHandleType handle, MMCamcorderCaptureDataType *dest, MMCamcorderCaptureDataType *thumbnail)
1384 int provide_exif = FALSE;
1386 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1387 _MMCamcorderSubContext *sc = NULL;
1389 mmf_return_val_if_fail(hcamcorder, FALSE);
1390 mmf_return_val_if_fail(dest, FALSE);
1392 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1393 mmf_return_val_if_fail(sc, FALSE);
1397 mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_ENABLE, &tag_enable, NULL);
1398 MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "provide-exif", &provide_exif);
1400 _mmcam_dbg_log("tag enable[%d], provide exif[%d]", tag_enable, provide_exif);
1402 /* if tag enable and doesn't provide exif, we make it */
1403 if (tag_enable && !provide_exif) {
1404 _mmcam_dbg_log("Add exif information if existed(thumbnail[%p])", thumbnail);
1405 if (thumbnail && thumbnail->data) {
1406 if (!__mmcamcorder_capture_save_exifinfo(handle, dest, thumbnail)) {
1410 if (!__mmcamcorder_capture_save_exifinfo(handle, dest, NULL)) {
1420 void __mmcamcorder_release_jpeg_data(MMHandleType handle, MMCamcorderCaptureDataType *dest)
1423 int provide_exif = FALSE;
1425 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1426 _MMCamcorderSubContext *sc = NULL;
1428 mmf_return_if_fail(hcamcorder);
1429 mmf_return_if_fail(dest);
1431 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1432 mmf_return_if_fail(sc);
1436 mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_ENABLE, &tag_enable, NULL);
1437 MMCAMCORDER_G_OBJECT_GET (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "provide-exif", &provide_exif);
1439 /* if dest->data is allocated in MSL, release it */
1440 if (tag_enable && !provide_exif) {
1445 _mmcam_dbg_log("Jpeg is released!");
1448 _mmcam_dbg_log("No need to release");
1455 static void __mmcamcorder_image_capture_cb(GstElement *element, GstBuffer *buffer1, GstBuffer *buffer2, GstBuffer *buffer3, gpointer u_data)
1457 int ret = MM_ERROR_NONE;
1458 int pixtype = MM_PIXEL_FORMAT_INVALID;
1459 int pixtype_sub = MM_PIXEL_FORMAT_INVALID;
1460 int codectype = MM_IMAGE_CODEC_JPEG;
1461 int type = _MMCamcorder_SINGLE_SHOT;
1464 int stop_cont_shot = 0;
1465 gboolean send_msg = FALSE;
1467 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1468 _MMCamcorderImageInfo *info = NULL;
1469 _MMCamcorderSubContext *sc = NULL;
1470 MMCamcorderCaptureDataType dest = {0,};
1471 MMCamcorderCaptureDataType thumb = {0,};
1472 MMCamcorderCaptureDataType scrnail = {0,};
1474 mmf_attrs_t *attrs = NULL;
1475 mmf_attribute_t *item = NULL;
1477 void *encoded_data = NULL;
1478 char *err_attr_name = NULL;
1480 mmf_return_if_fail(hcamcorder);
1482 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1483 mmf_return_if_fail(sc && sc->info);
1487 _mmcam_dbg_err("START");
1489 MMTA_ACUM_ITEM_BEGIN(" MSL capture callback", FALSE);
1491 /* check capture state */
1492 if (info->type == _MMCamcorder_MULTI_SHOT && info->capture_send_count > 0) {
1493 mm_camcorder_get_attributes((MMHandleType)hcamcorder, NULL, "capture-break-cont-shot", &stop_cont_shot, NULL);
1494 if (stop_cont_shot == TRUE) {
1495 _mmcam_dbg_warn("capture stop command already come. skip this...");
1496 MMTA_ACUM_ITEM_END( " MSL capture callback", FALSE );
1501 if (!info->capturing) {
1502 _mmcam_dbg_err("It's Not capturing now.");
1506 /* play capture sound here if multi capture */
1507 if (info->type == _MMCamcorder_MULTI_SHOT) {
1508 _mmcamcorder_sound_play((MMHandleType)hcamcorder);
1511 /* Prepare main, thumbnail buffer */
1512 pixtype = _mmcamcorder_get_pixel_format(buffer1);
1513 if (pixtype == MM_PIXEL_FORMAT_INVALID) {
1514 _mmcam_dbg_err("Unsupported pixel type");
1518 /* Main image buffer */
1519 if (buffer1 && GST_BUFFER_DATA(buffer1) && (GST_BUFFER_SIZE(buffer1) !=0)) {
1520 __mmcamcorder_get_capture_data_from_buffer(&dest, pixtype, buffer1);
1522 _mmcam_dbg_err("buffer1 has wrong pointer. (buffer1=%p)",buffer1);
1527 if (sc->internal_encode) {
1528 int capture_quality = 0;
1529 ret = mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_attr_name,
1530 MMCAM_IMAGE_ENCODER_QUALITY, &capture_quality,
1532 if (ret != MM_ERROR_NONE) {
1533 _mmcam_dbg_err("Get attribute failed[%s][%x]", err_attr_name, ret);
1534 SAFE_FREE(err_attr_name);
1538 __ta__(" _mmcamcorder_encode_jpeg",
1539 ret = _mmcamcorder_encode_jpeg(GST_BUFFER_DATA(buffer1), dest.width, dest.height,
1540 pixtype, dest.length, capture_quality, &(dest.data), &(dest.length));
1546 encoded_data = dest.data;
1547 dest.format = MM_PIXEL_FORMAT_ENCODED;
1550 /* Thumbnail image buffer */
1551 if (buffer2 && GST_BUFFER_DATA(buffer2) && (GST_BUFFER_SIZE(buffer2) !=0)) {
1552 pixtype_sub = _mmcamcorder_get_pixel_format(buffer2);
1553 _mmcam_dbg_log("Thumnail (buffer2=%p)",buffer2);
1555 __mmcamcorder_get_capture_data_from_buffer(&thumb, pixtype_sub, buffer2);
1557 _mmcam_dbg_log("buffer2 has wrong pointer. Not Error. (buffer2=%p)",buffer2);
1560 /* Screennail image buffer */
1561 attrs = (mmf_attrs_t*)MMF_CAMCORDER_ATTRS(hcamcorder);
1562 mm_attrs_get_index((MMHandleType)attrs, "captured-screennail", &attr_index);
1563 item = &attrs->items[attr_index];
1565 if (buffer3 && GST_BUFFER_DATA(buffer3) && GST_BUFFER_SIZE(buffer3) != 0) {
1566 _mmcam_dbg_log("Screennail (buffer3=%p,size=%d)", buffer3, GST_BUFFER_SIZE(buffer3));
1568 pixtype_sub = _mmcamcorder_get_pixel_format(buffer3);
1569 __mmcamcorder_get_capture_data_from_buffer(&scrnail, pixtype_sub, buffer3);
1571 /* Set screennail attribute for application */
1572 mmf_attribute_set_data(item, &scrnail, sizeof(scrnail));
1574 mmf_attribute_set_data(item, NULL, 0);
1576 _mmcam_dbg_log("buffer3 has wrong pointer. Not Error. (buffer3=%p)",buffer3);
1579 mmf_attrs_commit_err((MMHandleType)attrs, &err_attr_name);
1581 /* Set extra data for jpeg */
1582 if (dest.format == MM_PIXEL_FORMAT_ENCODED) {
1584 char *err_attr_name = NULL;
1586 err = mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_attr_name,
1587 MMCAM_IMAGE_ENCODER, &codectype,
1589 if (err != MM_ERROR_NONE) {
1590 _mmcam_dbg_warn("Getting codectype failed. (%s:%x)", err_attr_name, err);
1591 SAFE_FREE (err_attr_name);
1595 switch (codectype) {
1596 case MM_IMAGE_CODEC_JPEG:
1597 case MM_IMAGE_CODEC_SRW:
1598 case MM_IMAGE_CODEC_JPEG_SRW:
1599 __ta__( " __mmcamcorder_set_jpeg_data",
1600 ret = __mmcamcorder_set_jpeg_data((MMHandleType)hcamcorder, &dest, &thumb);
1603 _mmcam_dbg_err("Error on setting extra data to jpeg");
1608 _mmcam_dbg_err("The codectype is not supported. (%d)", codectype);
1613 /* Handle Capture Callback */
1614 _MMCAMCORDER_LOCK_VCAPTURE_CALLBACK(hcamcorder);
1616 if (hcamcorder->vcapture_cb) {
1617 _mmcam_dbg_log("APPLICATION CALLBACK START");
1618 MMTA_ACUM_ITEM_BEGIN(" Application capture callback", 0);
1620 ret = hcamcorder->vcapture_cb(&dest, &thumb, hcamcorder->vcapture_cb_param);
1622 ret = hcamcorder->vcapture_cb(&dest, NULL, hcamcorder->vcapture_cb_param);
1624 MMTA_ACUM_ITEM_END(" Application capture callback", 0);
1625 _mmcam_dbg_log("APPLICATION CALLBACK END");
1627 _mmcam_dbg_err("Capture callback is NULL.");
1628 goto err_release_exif;
1631 /* Set send msg flag and capture count */
1634 count = ++(info->capture_send_count);
1637 _MMCAMCORDER_UNLOCK_VCAPTURE_CALLBACK(hcamcorder);
1639 /* Release jpeg data */
1640 if (pixtype == MM_PIXEL_FORMAT_ENCODED) {
1641 __ta__( " __mmcamcorder_release_jpeg_data",
1642 __mmcamcorder_release_jpeg_data((MMHandleType)hcamcorder, &dest);
1647 /* Check end condition and set proper value */
1648 __mmcamcorder_init_stillshot_info((MMHandleType)hcamcorder);
1650 /* send captured message if no problem */
1652 __mmcamcorder_capture_send_msg((MMHandleType)hcamcorder, type, count);
1655 /* release internal allocated data */
1657 if (dest.data == encoded_data) {
1662 encoded_data = NULL;
1667 gst_buffer_unref(buffer1);
1670 gst_buffer_unref(buffer2);
1673 gst_buffer_unref(buffer3);
1676 MMTA_ACUM_ITEM_END( " MSL capture callback", FALSE );
1678 _mmcam_dbg_err("END");
1684 static gboolean __mmcamcorder_encodesink_handoff_callback(GstElement *fakesink, GstBuffer *buffer, GstPad *pad, gpointer u_data)
1686 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1687 _MMCamcorderSubContext *sc = NULL;
1689 mmf_return_val_if_fail(hcamcorder, FALSE);
1691 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1692 mmf_return_val_if_fail(sc && sc->element, FALSE);
1696 /* FIXME. How could you get a thumbnail? */
1697 __mmcamcorder_image_capture_cb(fakesink, buffer, NULL, NULL, u_data);
1699 if (sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst) {
1700 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, "signal-handoffs", FALSE);
1701 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1708 /* Take a picture with capture mode */
1709 int _mmcamcorder_set_resize_property(MMHandleType handle, int capture_width, int capture_height)
1711 int ELEMENT_CROP = 0;
1712 int ELEMENT_FILTER = 0;
1714 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1715 _MMCamcorderSubContext *sc = NULL;
1719 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1721 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1722 mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1724 ELEMENT_CROP = _MMCAMCORDER_ENCSINK_ICROP;
1725 ELEMENT_FILTER = _MMCAMCORDER_ENCSINK_IFILT;
1727 /*TODO: this is not needed now. */
1729 return MM_ERROR_NONE;
1733 int __mmcamcorder_set_exif_basic_info(MMHandleType handle)
1735 int ret = MM_ERROR_NONE;
1737 int str_val_len = 0;
1738 int gps_enable = TRUE;
1741 double f_latitude = INVALID_GPS_VALUE;
1742 double f_longitude = INVALID_GPS_VALUE;
1743 double f_altitude = INVALID_GPS_VALUE;
1744 char *str_value = NULL;
1746 char *user_comment = NULL;
1747 char *err_name = NULL;
1748 ExifData *ed = NULL;
1750 ExifLong ExifVersion;
1751 static ExifShort eshort[20];
1752 static ExifLong elong[10];
1754 GstCameraControl *control = NULL;
1755 GstCameraControlExifInfo avsys_exif_info = {0,};
1757 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1758 _MMCamcorderSubContext *sc = NULL;
1762 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1764 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1765 mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1767 if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
1768 _mmcam_dbg_err("Can't cast Video source into camera control. Just return true.");
1769 return MM_ERROR_NONE;
1772 control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
1773 /* get device information */
1774 gst_camera_control_get_exif_info(control, &avsys_exif_info);
1776 /* get ExifData from exif info */
1777 ed = mm_exif_get_exif_from_info(hcamcorder->exif_info);
1778 if (ed == NULL || ed->ifd == NULL) {
1779 _mmcam_dbg_err("get exif data error!!(%p, %p)", ed, (ed ? ed->ifd : NULL));
1780 return MM_ERROR_INVALID_HANDLE;
1783 /* Receive attribute info */
1785 /* START INSERT IFD_0 */
1787 /*0. EXIF_TAG_EXIF_VERSION */
1788 ExifVersion = MM_EXIF_VERSION;
1789 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION,
1790 EXIF_FORMAT_UNDEFINED, 4, (unsigned char *)&ExifVersion);
1791 if (ret != MM_ERROR_NONE) {
1792 EXIF_SET_ERR(ret, EXIF_TAG_EXIF_VERSION);
1795 /*1. EXIF_TAG_IMAGE_WIDTH */ /*EXIF_TAG_PIXEL_X_DIMENSION*/
1796 mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_WIDTH, &value, NULL);
1798 exif_set_long((unsigned char *)&elong[cntl], exif_data_get_byte_order(ed), value);
1799 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH,
1800 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl]);
1801 if (ret != MM_ERROR_NONE) {
1802 EXIF_SET_ERR(ret, EXIF_TAG_IMAGE_WIDTH);
1805 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION,
1806 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl++]);
1807 if (ret != MM_ERROR_NONE) {
1808 EXIF_SET_ERR(ret, EXIF_TAG_PIXEL_X_DIMENSION);
1810 _mmcam_dbg_log("width[%d]", value);
1812 /*2. EXIF_TAG_IMAGE_LENGTH*/ /*EXIF_TAG_PIXEL_Y_DIMENSION*/
1813 mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_HEIGHT, &value, NULL);
1815 exif_set_long((unsigned char *)&elong[cntl], exif_data_get_byte_order (ed), value);
1816 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH,
1817 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl]);
1818 if (ret != MM_ERROR_NONE) {
1819 EXIF_SET_ERR(ret, EXIF_TAG_IMAGE_LENGTH);
1822 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION,
1823 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl++]);
1824 if (ret != MM_ERROR_NONE) {
1825 EXIF_SET_ERR(ret, EXIF_TAG_PIXEL_Y_DIMENSION);
1827 _mmcam_dbg_log("height[%d]", value);
1829 /*4. EXIF_TAG_DATE_TIME */
1831 /*12. EXIF_TAG_DATE_TIME_ORIGINAL */
1833 /*13. EXIF_TAG_DATE_TIME_DIGITIZED*/
1839 b = malloc(20 * sizeof(unsigned char));
1841 _mmcam_dbg_err("failed to alloc b");
1842 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1843 EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME);
1846 memset(b, '\0', 20);
1850 localtime_r(&t, &tm);
1852 snprintf((char *)b, 20, "%04i:%02i:%02i %02i:%02i:%02i",
1853 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1854 tm.tm_hour, tm.tm_min, tm.tm_sec);
1856 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, 20, b);
1857 if (ret != MM_ERROR_NONE) {
1858 if (ret == MM_ERROR_CAMCORDER_LOW_MEMORY) {
1861 EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME);
1864 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, 20, b);
1865 if (ret != MM_ERROR_NONE) {
1866 if (ret == MM_ERROR_CAMCORDER_LOW_MEMORY) {
1869 EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME_ORIGINAL);
1872 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, 20, b);
1873 if (ret != MM_ERROR_NONE) {
1874 if (ret == MM_ERROR_CAMCORDER_LOW_MEMORY) {
1877 EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME_DIGITIZED);
1883 /*5. EXIF_TAG_MAKE */
1884 maker = strdup(MM_MAKER_NAME);
1886 _mmcam_dbg_log("maker [%s]", maker);
1887 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_MAKE,
1888 EXIF_FORMAT_ASCII, strlen(maker), (unsigned char *)maker);
1890 if (ret != MM_ERROR_NONE) {
1891 EXIF_SET_ERR(ret, EXIF_TAG_MAKE);
1894 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1895 EXIF_SET_ERR(ret, EXIF_TAG_MAKE);
1898 /*6. EXIF_TAG_MODEL */
1899 _mmcamcorder_conf_get_value_string(hcamcorder->conf_main,
1900 CONFIGURE_CATEGORY_MAIN_GENERAL,
1903 _mmcam_dbg_log("model_name [%s]", str_value);
1905 char *model = strdup(str_value);
1906 mm_exif_set_add_entry(ed,EXIF_IFD_0,EXIF_TAG_MODEL,EXIF_FORMAT_ASCII,strlen(model)+1, (unsigned char*)model);
1909 if (ret != MM_ERROR_NONE) {
1910 EXIF_SET_ERR(ret, EXIF_TAG_MODEL);
1913 _mmcam_dbg_warn("failed to get model name");
1916 /*6. EXIF_TAG_IMAGE_DESCRIPTION */
1917 mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_IMAGE_DESCRIPTION, &str_value, &str_val_len, NULL);
1918 _mmcam_dbg_log("desctiption [%s]", str_value);
1919 if (str_value && str_val_len > 0) {
1920 char *description = strdup(str_value);
1921 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION,
1922 EXIF_FORMAT_ASCII, strlen(description), (unsigned char *)description);
1926 if (ret != MM_ERROR_NONE) {
1927 EXIF_SET_ERR(ret, EXIF_TAG_IMAGE_DESCRIPTION);
1930 _mmcam_dbg_warn("failed to get description");
1933 /*7. EXIF_TAG_SOFTWARE*/
1936 char software[50] = {0,};
1937 unsigned int len = 0;
1939 len = snprintf(software, sizeof(software), "%x.%x ", avsys_exif_info.software_used>>8,(avsys_exif_info.software_used & 0xff));
1940 _mmcam_dbg_log("software [%s], len [%d]", software, len);
1941 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_SOFTWARE,
1942 EXIF_FORMAT_ASCII, len, software);
1943 if (ret != MM_ERROR_NONE) {
1944 EXIF_SET_ERR(ret, EXIF_TAG_SOFTWARE);
1949 /*8. EXIF_TAG_ORIENTATION */
1950 mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_ORIENTATION, &value, NULL);
1952 _mmcam_dbg_log("orientation [%d]",value);
1954 value = MM_EXIF_ORIENTATION;
1957 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), value);
1958 ret = mm_exif_set_add_entry(ed, EXIF_IFD_0, EXIF_TAG_ORIENTATION,
1959 EXIF_FORMAT_SHORT, 1, (unsigned char*)&eshort[cnts++]);
1960 if (ret != MM_ERROR_NONE) {
1961 EXIF_SET_ERR(ret, EXIF_TAG_ORIENTATION);
1964 /* START INSERT EXIF_IFD */
1967 /*FIXME : get user comment from real user */
1968 user_comment = strdup(MM_USER_COMMENT);
1970 _mmcam_dbg_log("user_comment=%s",user_comment);
1971 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_USER_COMMENT,
1972 EXIF_FORMAT_ASCII, strlen(user_comment), (unsigned char *)user_comment);
1974 if (ret != MM_ERROR_NONE) {
1975 EXIF_SET_ERR(ret, EXIF_TAG_USER_COMMENT);
1978 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1979 EXIF_SET_ERR(ret, EXIF_TAG_USER_COMMENT);
1982 /*9. EXIF_TAG_COLOR_SPACE */
1983 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), avsys_exif_info.colorspace);
1984 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE,
1985 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
1986 if (ret != MM_ERROR_NONE) {
1987 EXIF_SET_ERR(ret, EXIF_TAG_COLOR_SPACE);
1990 /*10. EXIF_TAG_COMPONENTS_CONFIGURATION */
1991 config = avsys_exif_info.component_configuration;
1992 _mmcam_dbg_log("EXIF_TAG_COMPONENTS_CONFIGURATION [%4x] ",config);
1993 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
1994 EXIF_FORMAT_UNDEFINED, 4, (unsigned char *)&config);
1995 if (ret != MM_ERROR_NONE) {
1996 EXIF_SET_ERR(ret, EXIF_TAG_COMPONENTS_CONFIGURATION);
1999 /*11. EXIF_TAG_COMPRESSED_BITS_PER_PIXEL */
2000 /* written the device_info */
2002 /*12. EXIF_TAG_DATE_TIME_ORIGINAL */
2003 /*13. EXIF_TAG_DATE_TIME_DIGITIZED*/
2004 /*14. EXIF_TAG_EXPOSURE_TIME*/
2005 if (avsys_exif_info.exposure_time_numerator && avsys_exif_info.exposure_time_denominator) {
2006 unsigned char *b = NULL;
2009 _mmcam_dbg_log("EXIF_TAG_EXPOSURE_TIME numerator [%d], denominator [%d]",
2010 avsys_exif_info.exposure_time_numerator, avsys_exif_info.exposure_time_denominator)
2012 b = malloc(sizeof(ExifRational));
2014 rData.numerator = avsys_exif_info.exposure_time_numerator;
2015 rData.denominator = avsys_exif_info.exposure_time_denominator;
2017 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2018 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
2019 EXIF_FORMAT_RATIONAL, 1, b);
2021 if (ret != MM_ERROR_NONE) {
2022 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_TIME);
2025 _mmcam_dbg_warn("malloc failed.");
2028 _mmcam_dbg_log("Skip set EXIF_TAG_EXPOSURE_TIME numerator [%d], denominator [%d]",
2029 avsys_exif_info.exposure_time_numerator, avsys_exif_info.exposure_time_denominator);
2032 /*15. EXIF_TAG_FNUMBER */
2033 if (avsys_exif_info.aperture_f_num_numerator && avsys_exif_info.aperture_f_num_denominator) {
2034 unsigned char *b = NULL;
2037 _mmcam_dbg_log("EXIF_TAG_FNUMBER numerator [%d], denominator [%d]",
2038 avsys_exif_info.aperture_f_num_numerator, avsys_exif_info.aperture_f_num_denominator);
2040 b = malloc(sizeof(ExifRational));
2042 rData.numerator = avsys_exif_info.aperture_f_num_numerator;
2043 rData.denominator = avsys_exif_info.aperture_f_num_denominator;
2044 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2045 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
2046 EXIF_FORMAT_RATIONAL, 1, b);
2048 if(ret != MM_ERROR_NONE) {
2049 EXIF_SET_ERR(ret, EXIF_TAG_FNUMBER);
2052 _mmcam_dbg_warn( "malloc failed." );
2055 _mmcam_dbg_log("Skip set EXIF_TAG_FNUMBER numerator [%d], denominator [%d]",
2056 avsys_exif_info.aperture_f_num_numerator, avsys_exif_info.aperture_f_num_denominator);
2059 /*16. EXIF_TAG_EXPOSURE_PROGRAM*/
2061 value = MM_EXPOSURE_PROGRAM;
2062 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), value);
2063 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM,
2064 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2065 if (ret != MM_ERROR_NONE) {
2066 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_PROGRAM);
2069 /*17. EXIF_TAG_ISO_SPEED_RATINGS*/
2070 if (avsys_exif_info.iso) {
2071 _mmcam_dbg_log("EXIF_TAG_ISO_SPEED_RATINGS [%d]", avsys_exif_info.iso);
2072 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), avsys_exif_info.iso);
2073 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS,
2074 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2075 if (ret != MM_ERROR_NONE) {
2076 EXIF_SET_ERR(ret, EXIF_TAG_ISO_SPEED_RATINGS);
2080 /*18. EXIF_TAG_SHUTTER_SPEED_VALUE*/
2081 if (avsys_exif_info.shutter_speed_numerator && avsys_exif_info.shutter_speed_denominator) {
2082 unsigned char *b = NULL;
2083 ExifSRational rsData;
2085 _mmcam_dbg_log("EXIF_TAG_SHUTTER_SPEED_VALUE numerator [%d], denominator [%d]",
2086 avsys_exif_info.shutter_speed_numerator, avsys_exif_info.shutter_speed_denominator);
2088 b = malloc(sizeof(ExifSRational));
2090 rsData.numerator = avsys_exif_info.shutter_speed_numerator;
2091 rsData.denominator = avsys_exif_info.shutter_speed_denominator;
2092 exif_set_srational(b, exif_data_get_byte_order(ed), rsData);
2093 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
2094 EXIF_FORMAT_SRATIONAL, 1, b);
2096 if (ret != MM_ERROR_NONE) {
2097 EXIF_SET_ERR(ret, EXIF_TAG_SHUTTER_SPEED_VALUE);
2100 _mmcam_dbg_warn("malloc failed.");
2103 _mmcam_dbg_log("Skip set EXIF_TAG_SHUTTER_SPEED_VALUE numerator [%d], denominator [%d]",
2104 avsys_exif_info.shutter_speed_numerator, avsys_exif_info.shutter_speed_denominator);
2107 /*19. EXIF_TAG_APERTURE_VALUE*/
2108 if (avsys_exif_info.aperture_in_APEX) {
2109 unsigned char *b = NULL;
2112 _mmcam_dbg_log("EXIF_TAG_APERTURE_VALUE [%d]", avsys_exif_info.aperture_in_APEX);
2114 b = malloc(sizeof(ExifRational));
2116 rData.numerator = avsys_exif_info.aperture_in_APEX;
2117 rData.denominator = 1;
2118 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2119 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
2120 EXIF_FORMAT_RATIONAL, 1, b);
2122 if(ret != MM_ERROR_NONE) {
2123 EXIF_SET_ERR(ret, EXIF_TAG_APERTURE_VALUE);
2126 _mmcam_dbg_warn("malloc failed.");
2129 _mmcam_dbg_log("Skip set EXIF_TAG_APERTURE_VALUE [%d]", avsys_exif_info.aperture_in_APEX);
2132 /*20. EXIF_TAG_BRIGHTNESS_VALUE*/
2133 if (avsys_exif_info.brigtness_numerator && avsys_exif_info.brightness_denominator) {
2134 unsigned char *b = NULL;
2135 ExifSRational rsData;
2137 _mmcam_dbg_log("EXIF_TAG_BRIGHTNESS_VALUE numerator [%d], denominator [%d]",
2138 avsys_exif_info.brigtness_numerator, avsys_exif_info.brightness_denominator);
2140 b = malloc(sizeof(ExifSRational));
2142 rsData.numerator = avsys_exif_info.brigtness_numerator;
2143 rsData.denominator = avsys_exif_info.brightness_denominator;
2144 exif_set_srational(b, exif_data_get_byte_order(ed), rsData);
2145 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE,
2146 EXIF_FORMAT_SRATIONAL, 1, b);
2148 if (ret != MM_ERROR_NONE) {
2149 EXIF_SET_ERR(ret, EXIF_TAG_BRIGHTNESS_VALUE);
2152 _mmcam_dbg_warn( "malloc failed." );
2155 _mmcam_dbg_log("Skip set EXIF_TAG_BRIGHTNESS_VALUE numerator [%d], denominatorr [%d]",
2156 avsys_exif_info.brigtness_numerator, avsys_exif_info.brightness_denominator);
2159 /*21. EXIF_TAG_EXPOSURE_BIAS_VALUE*/
2161 ret = mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_BRIGHTNESS, &value, NULL);
2162 if (ret == MM_ERROR_NONE) {
2163 unsigned char *b = NULL;
2164 ExifSRational rsData;
2166 _mmcam_dbg_log("EXIF_TAG_BRIGHTNESS_VALUE %d",value);
2168 b = malloc(sizeof(ExifSRational));
2170 rsData.numerator = value - 5;
2171 rsData.denominator = 10;
2172 exif_set_srational(b, exif_data_get_byte_order(ed), rsData);
2173 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
2174 EXIF_FORMAT_SRATIONAL, 1, b);
2176 if (ret != MM_ERROR_NONE) {
2177 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_BIAS_VALUE);
2180 _mmcam_dbg_warn("malloc failed.");
2183 _mmcam_dbg_log("failed to get MMCAM_FILTER_BRIGHTNESS [%x]", ret);
2186 /*22 EXIF_TAG_MAX_APERTURE_VALUE*/
2188 if (avsys_exif_info.max_lens_aperture_in_APEX) {
2189 unsigned char *b = NULL;
2192 _mmcam_dbg_log("EXIF_TAG_MAX_APERTURE_VALUE [%d]", avsys_exif_info.max_lens_aperture_in_APEX);
2194 b = malloc(sizeof(ExifRational));
2196 rData.numerator = avsys_exif_info.max_lens_aperture_in_APEX;
2197 rData.denominator = 1;
2198 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2199 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
2200 EXIF_FORMAT_RATIONAL, 1, b);
2202 if (ret != MM_ERROR_NONE) {
2203 EXIF_SET_ERR(ret, EXIF_TAG_MAX_APERTURE_VALUE);
2206 _mmcam_dbg_warn("failed to alloc for MAX aperture value");
2211 /*23. EXIF_TAG_SUBJECT_DISTANCE*/
2212 /* defualt : none */
2214 /*24. EXIF_TAG_METERING_MODE */
2215 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed),avsys_exif_info.metering_mode);
2216 _mmcam_dbg_log("EXIF_TAG_METERING_MODE [%d]", avsys_exif_info.metering_mode);
2217 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE,
2218 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2219 if (ret != MM_ERROR_NONE) {
2220 EXIF_SET_ERR(ret, EXIF_TAG_METERING_MODE);
2223 /*25. EXIF_TAG_LIGHT_SOURCE*/
2225 /*26. EXIF_TAG_FLASH*/
2226 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order (ed),avsys_exif_info.flash);
2227 _mmcam_dbg_log("EXIF_TAG_FLASH [%d]", avsys_exif_info.flash);
2228 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH,
2229 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2230 if (ret != MM_ERROR_NONE) {
2231 EXIF_SET_ERR(ret, EXIF_TAG_FLASH);
2234 /*27. EXIF_TAG_FOCAL_LENGTH*/
2235 if (avsys_exif_info.focal_len_numerator && avsys_exif_info.focal_len_denominator) {
2236 unsigned char *b = NULL;
2239 _mmcam_dbg_log("EXIF_TAG_FOCAL_LENGTH numerator [%d], denominator [%d]",
2240 avsys_exif_info.focal_len_numerator, avsys_exif_info.focal_len_denominator);
2242 b = malloc(sizeof(ExifRational));
2244 rData.numerator = avsys_exif_info.focal_len_numerator;
2245 rData.denominator = avsys_exif_info.focal_len_denominator;
2246 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2247 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH,
2248 EXIF_FORMAT_RATIONAL, 1, b);
2250 if (ret != MM_ERROR_NONE) {
2251 EXIF_SET_ERR(ret, EXIF_TAG_FOCAL_LENGTH);
2254 _mmcam_dbg_warn("malloc failed.");
2257 _mmcam_dbg_log("Skip set EXIF_TAG_FOCAL_LENGTH numerator [%d], denominator [%d]",
2258 avsys_exif_info.focal_len_numerator, avsys_exif_info.focal_len_denominator);
2261 /*28. EXIF_TAG_SENSING_METHOD*/
2263 value = MM_SENSING_MODE;
2264 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order (ed),value);
2265 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SENSING_METHOD,
2266 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2267 if (ret != MM_ERROR_NONE) {
2268 EXIF_SET_ERR(ret, EXIF_TAG_SENSING_METHOD);
2271 /*29. EXIF_TAG_FILE_SOURCE*/
2273 value = MM_FILE_SOURCE;
2274 exif_set_long(&elong[cntl], exif_data_get_byte_order(ed),value);
2275 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_FILE_SOURCE,
2276 EXIF_FORMAT_UNDEFINED, 4, (unsigned char *)&elong[cntl++]);
2277 if (ret != MM_ERROR_NONE) {
2278 EXIF_SET_ERR(ret, EXIF_TAG_FILE_SOURCE);
2282 /*30. EXIF_TAG_SCENE_TYPE*/
2284 value = MM_SCENE_TYPE;
2285 exif_set_long(&elong[cntl], exif_data_get_byte_order(ed),value);
2286 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SCENE_TYPE,
2287 EXIF_FORMAT_UNDEFINED, 4, (unsigned char *)&elong[cntl++]);
2288 if (ret != MM_ERROR_NONE) {
2289 EXIF_SET_ERR(ret, EXIF_TAG_SCENE_TYPE);
2293 /*31. EXIF_TAG_EXPOSURE_MODE*/
2295 value = MM_EXPOSURE_MODE;
2296 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed),value);
2297 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE,
2298 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2299 if (ret != MM_ERROR_NONE) {
2300 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_MODE);
2304 /*32. EXIF_TAG_WHITE_BALANCE*/
2305 ret = mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_WB, &value, NULL);
2306 if (ret == MM_ERROR_NONE) {
2308 _mmcam_dbg_log("WHITE BALANCE [%d]", value);
2310 if (value == MM_CAMCORDER_WHITE_BALANCE_AUTOMATIC) {
2316 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), set_value);
2317 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE,
2318 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2319 if (ret != MM_ERROR_NONE) {
2320 EXIF_SET_ERR(ret, EXIF_TAG_WHITE_BALANCE);
2323 _mmcam_dbg_warn("failed to get white balance [%x]", ret);
2326 /*33. EXIF_TAG_DIGITAL_ZOOM_RATIO*/
2328 ret = mm_camcorder_get_attributes(handle, NULL, MMCAM_CAMERA_DIGITAL_ZOOM, &value, NULL);
2329 if (ret == MM_ERROR_NONE) {
2330 _mmcam_dbg_log("DIGITAL ZOOM [%d]", value);
2332 exif_set_long(&elong[cntl], exif_data_get_byte_order(ed), value);
2333 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
2334 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl++]);
2335 if (ret != MM_ERROR_NONE) {
2336 EXIF_SET_ERR(ret, EXIF_TAG_DIGITAL_ZOOM_RATIO);
2339 _mmcam_dbg_warn("failed to get digital zoom [%x]", ret);
2343 /*34. EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM*/
2346 value = MM_FOCAL_LENGTH_35MMFILM;
2347 exif_set_short(&eshort[cnts], exif_data_get_byte_order(ed),value);
2348 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
2349 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2350 if (ret != MM_ERROR_NONE) {
2351 EXIF_SET_ERR(ret, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM);
2355 /*35. EXIF_TAG_SCENE_CAPTURE_TYPE*/
2357 int scene_capture_type;
2359 ret = mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_SCENE_MODE, &value, NULL);
2360 if (ret == MM_ERROR_NONE) {
2361 _mmcam_dbg_log("Scene mode(program mode) [%d]", value);
2363 if (value == MM_CAMCORDER_SCENE_MODE_NORMAL) {
2364 scene_capture_type = 0; /* standard */
2365 } else if (value == MM_CAMCORDER_SCENE_MODE_PORTRAIT) {
2366 scene_capture_type = 2; /* portrait */
2367 } else if (value == MM_CAMCORDER_SCENE_MODE_LANDSCAPE) {
2368 scene_capture_type = 1; /* landscape */
2369 } else if (value == MM_CAMCORDER_SCENE_MODE_NIGHT_SCENE) {
2370 scene_capture_type = 3; /* night scene */
2372 scene_capture_type = 4; /* Others */
2375 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), scene_capture_type);
2376 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE,
2377 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2378 if (ret != MM_ERROR_NONE) {
2379 EXIF_SET_ERR(ret, EXIF_TAG_SCENE_CAPTURE_TYPE);
2382 _mmcam_dbg_warn("failed to get scene mode [%x]", ret);
2386 /*36. EXIF_TAG_GAIN_CONTROL*/
2389 value = MM_GAIN_CONTROL;
2390 exif_set_long(&elong[cntl], exif_data_get_byte_order(ed), value);
2391 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL,
2392 EXIF_FORMAT_LONG, 1, (unsigned char *)&elong[cntl++]);
2393 if (ret != MM_ERROR_NONE) {
2394 EXIF_SET_ERR(ret, EXIF_TAG_GAIN_CONTROL);
2399 /*37. EXIF_TAG_CONTRAST */
2401 type_int_range *irange = NULL;
2404 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2405 CONFIGURE_CATEGORY_CTRL_EFFECT,
2408 if (irange != NULL) {
2409 mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_CONTRAST, &value, NULL);
2411 _mmcam_dbg_log("CONTRAST currentt [%d], default [%d]", value, irange->default_value);
2413 if (value == irange->default_value) {
2414 level = MM_VALUE_NORMAL;
2415 } else if (value < irange->default_value) {
2416 level = MM_VALUE_LOW;
2418 level = MM_VALUE_HARD;
2421 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), level);
2422 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_CONTRAST,
2423 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2424 if (ret != MM_ERROR_NONE) {
2425 EXIF_SET_ERR(ret, EXIF_TAG_CONTRAST);
2428 _mmcam_dbg_warn("failed to get range of contrast");
2432 /*38. EXIF_TAG_SATURATION*/
2434 type_int_range *irange = NULL;
2437 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2438 CONFIGURE_CATEGORY_CTRL_EFFECT,
2441 if (irange != NULL) {
2442 mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_SATURATION, &value, NULL);
2444 _mmcam_dbg_log("SATURATION current [%d], default [%d]", value, irange->default_value);
2446 if (value == irange->default_value) {
2447 level = MM_VALUE_NORMAL;
2448 } else if (value < irange->default_value) {
2449 level = MM_VALUE_LOW;
2451 level=MM_VALUE_HARD;
2454 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), level);
2455 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SATURATION,
2456 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2457 if (ret != MM_ERROR_NONE) {
2458 EXIF_SET_ERR(ret, EXIF_TAG_SATURATION);
2461 _mmcam_dbg_warn("failed to get range of saturation");
2465 /*39. EXIF_TAG_SHARPNESS*/
2467 type_int_range *irange = NULL;
2470 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2471 CONFIGURE_CATEGORY_CTRL_EFFECT,
2474 if (irange != NULL) {
2475 mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_SHARPNESS, &value, NULL);
2477 _mmcam_dbg_log("SHARPNESS current [%d], default [%d]", value, irange->default_value);
2479 if (value == irange->default_value) {
2480 level = MM_VALUE_NORMAL;
2481 } else if (value < irange->default_value) {
2482 level = MM_VALUE_LOW;
2484 level = MM_VALUE_HARD;
2487 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), level);
2488 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS,
2489 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2490 if (ret != MM_ERROR_NONE) {
2491 EXIF_SET_ERR(ret, EXIF_TAG_SHARPNESS);
2494 _mmcam_dbg_warn("failed to get range of sharpness");
2498 /*40. EXIF_TAG_SUBJECT_DISTANCE_RANGE*/
2500 value = MM_SUBJECT_DISTANCE_RANGE;
2501 _mmcam_dbg_log("DISTANCE_RANGE [%d]", value);
2502 exif_set_short((unsigned char *)&eshort[cnts], exif_data_get_byte_order(ed), value);
2503 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE,
2504 EXIF_FORMAT_SHORT, 1, (unsigned char *)&eshort[cnts++]);
2505 if (ret != MM_ERROR_NONE) {
2506 EXIF_SET_ERR(ret, EXIF_TAG_SUBJECT_DISTANCE_RANGE);
2509 /* GPS information */
2510 ret = mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_GPS_ENABLE, &gps_enable, NULL);
2511 if (ret == MM_ERROR_NONE && gps_enable) {
2512 ExifByte GpsVersion[4]={2,2,0,0};
2514 _mmcam_dbg_log("Tag for GPS is ENABLED.");
2516 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_VERSION_ID,
2517 EXIF_FORMAT_BYTE, 4, (unsigned char *)&GpsVersion);
2518 if (ret != MM_ERROR_NONE) {
2519 EXIF_SET_ERR(ret, EXIF_TAG_GPS_VERSION_ID);
2523 ret = mm_camcorder_get_attributes(handle, &err_name,
2524 MMCAM_TAG_LATITUDE, &f_latitude,
2525 MMCAM_TAG_LONGITUDE, &f_longitude,
2526 MMCAM_TAG_ALTITUDE, &f_altitude, NULL);
2527 if (ret != MM_ERROR_NONE) {
2528 _mmcam_dbg_err("failed to get gps info [%x][%s]", ret, err_name);
2529 SAFE_FREE(err_name);
2533 _mmcam_dbg_log("f_latitude [%f]", f_latitude);
2534 if (f_latitude != INVALID_GPS_VALUE) {
2535 unsigned char *b = NULL;
2541 if (f_latitude < 0) {
2542 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,
2543 EXIF_FORMAT_ASCII, 2, (unsigned char *)"S");
2544 if (ret != MM_ERROR_NONE) {
2545 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LATITUDE_REF);
2547 f_latitude = -f_latitude;
2548 } else if (f_latitude > 0) {
2549 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,
2550 EXIF_FORMAT_ASCII, 2, (unsigned char *)"N");
2551 if (ret != MM_ERROR_NONE) {
2552 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LATITUDE_REF);
2556 deg = (unsigned int)(f_latitude);
2557 min = (unsigned int)((f_latitude-deg)*60);
2558 sec = (unsigned int)(((f_latitude-deg)*3600)-min*60);
2560 _mmcam_dbg_log("f_latitude deg[%d], min[%d], sec[%d]", deg, min, sec);
2561 b = malloc(3 * sizeof(ExifRational));
2563 rData.numerator = deg;
2564 rData.denominator = 1;
2565 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2566 rData.numerator = min;
2567 exif_set_rational(b+8, exif_data_get_byte_order(ed), rData);
2568 rData.numerator = sec;
2569 exif_set_rational(b+16, exif_data_get_byte_order(ed), rData);
2571 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,
2572 EXIF_FORMAT_RATIONAL, 3, (unsigned char *)b);
2574 if (ret != MM_ERROR_NONE) {
2575 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LATITUDE);
2578 _mmcam_dbg_warn("malloc failed");
2583 _mmcam_dbg_log("f_longitude [%f]", f_longitude);
2584 if (f_longitude != INVALID_GPS_VALUE) {
2585 unsigned char *b = NULL;
2591 if (f_longitude < 0) {
2592 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,
2593 EXIF_FORMAT_ASCII, 2, (unsigned char *)"W");
2594 if (ret != MM_ERROR_NONE) {
2595 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LONGITUDE_REF);
2597 f_longitude = -f_longitude;
2598 } else if (f_longitude > 0) {
2599 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,
2600 EXIF_FORMAT_ASCII, 2, (unsigned char *)"E");
2601 if (ret != MM_ERROR_NONE) {
2602 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LONGITUDE_REF);
2606 deg = (unsigned int)(f_longitude);
2607 min = (unsigned int)((f_longitude-deg)*60);
2608 sec = (unsigned int)(((f_longitude-deg)*3600)-min*60);
2610 _mmcam_dbg_log("f_longitude deg[%d], min[%d], sec[%d]", deg, min, sec);
2611 b = malloc(3 * sizeof(ExifRational));
2613 rData.numerator = deg;
2614 rData.denominator = 1;
2615 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2616 rData.numerator = min;
2617 exif_set_rational(b+8, exif_data_get_byte_order(ed), rData);
2618 rData.numerator = sec;
2619 exif_set_rational(b+16, exif_data_get_byte_order(ed), rData);
2620 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE,
2621 EXIF_FORMAT_RATIONAL, 3, (unsigned char *)b);
2623 if (ret != MM_ERROR_NONE) {
2624 EXIF_SET_ERR(ret, EXIF_TAG_GPS_LONGITUDE);
2627 _mmcam_dbg_warn("malloc failed");
2632 _mmcam_dbg_log("f_altitude [%f]", f_altitude);
2633 if (f_altitude != INVALID_GPS_VALUE) {
2634 ExifByte alt_ref = 0;
2635 unsigned char *b = NULL;
2637 b = malloc(sizeof(ExifRational));
2639 if (f_altitude < 0) {
2641 f_altitude = -f_altitude;
2644 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE_REF,
2645 EXIF_FORMAT_BYTE, 1, (unsigned char *)&alt_ref);
2646 if (ret != MM_ERROR_NONE) {
2647 _mmcam_dbg_err("error [%x], tag [%x]", ret, EXIF_TAG_GPS_ALTITUDE_REF);
2648 if (ret == MM_ERROR_CAMCORDER_LOW_MEMORY) {
2655 rData.numerator = (unsigned int)(f_altitude + 0.5)*100;
2656 rData.denominator = 100;
2657 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2658 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE,
2659 EXIF_FORMAT_RATIONAL, 1, (unsigned char *)b);
2661 if (ret != MM_ERROR_NONE) {
2662 EXIF_SET_ERR(ret, EXIF_TAG_GPS_ALTITUDE);
2665 _mmcam_dbg_warn("malloc failed");
2669 /*44. EXIF_TAG_GPS_TIME_STAMP*/
2671 double gps_timestamp = INVALID_GPS_VALUE;
2672 mm_camcorder_get_attributes(handle, NULL, "tag-gps-time-stamp", &gps_timestamp, NULL);
2673 _mmcam_dbg_log("Gps timestamp [%f]", gps_timestamp);
2674 if (gps_timestamp > 0.0) {
2675 unsigned char *b = NULL;
2678 unsigned int microsec;
2681 hour = (unsigned int)(gps_timestamp / 3600);
2682 min = (unsigned int)((gps_timestamp - 3600 * hour) / 60);
2683 microsec = (unsigned int)(((double)((double)gps_timestamp -(double)(3600 * hour)) -(double)(60 * min)) * 1000000);
2685 _mmcam_dbg_log("Gps timestamp hour[%d], min[%d], microsec[%d]", hour, min, microsec);
2686 b = malloc(3 * sizeof(ExifRational));
2688 rData.numerator = hour;
2689 rData.denominator = 1;
2690 exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2692 rData.numerator = min;
2693 rData.denominator = 1;
2694 exif_set_rational(b + 8, exif_data_get_byte_order(ed), rData);
2696 rData.numerator = microsec;
2697 rData.denominator = 1000000;
2698 exif_set_rational(b + 16, exif_data_get_byte_order(ed), rData);
2700 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_TIME_STAMP,
2701 EXIF_FORMAT_RATIONAL, 3, b);
2703 if (ret != MM_ERROR_NONE) {
2704 EXIF_SET_ERR(ret, EXIF_TAG_GPS_TIME_STAMP);
2707 _mmcam_dbg_warn( "malloc failed." );
2712 /*45. EXIF_TAG_GPS_DATE_STAMP*/
2714 unsigned char *date_stamp = NULL;
2715 int date_stamp_len = 0;
2717 mm_camcorder_get_attributes(handle, NULL, "tag-gps-date-stamp", &date_stamp, &date_stamp_len, NULL);
2720 _mmcam_dbg_log("Date stamp [%s]", date_stamp);
2722 /* cause it should include NULL char */
2723 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_DATE_STAMP,
2724 EXIF_FORMAT_ASCII, date_stamp_len + 1, date_stamp);
2725 if (ret != MM_ERROR_NONE) {
2726 EXIF_SET_ERR(ret, EXIF_TAG_GPS_DATE_STAMP);
2731 /*46. EXIF_TAG_GPS_PROCESSING_METHOD */
2733 unsigned char *processing_method = NULL;
2734 int processing_method_len = 0;
2736 mm_camcorder_get_attributes(handle, NULL, "tag-gps-processing-method", &processing_method, &processing_method_len, NULL);
2738 if (processing_method) {
2739 _mmcam_dbg_log("Processing method [%s]", processing_method);
2741 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_PROCESSING_METHOD,
2742 EXIF_FORMAT_UNDEFINED, processing_method_len, processing_method);
2743 if (ret != MM_ERROR_NONE) {
2744 EXIF_SET_ERR(ret, EXIF_TAG_GPS_PROCESSING_METHOD);
2749 _mmcam_dbg_log( "Tag for GPS is DISABLED." );
2753 /*47. EXIF_TAG_MAKER_NOTE*/
2754 ret = mm_exif_set_add_entry(ed, EXIF_IFD_EXIF, EXIF_TAG_MAKER_NOTE,
2755 EXIF_FORMAT_UNDEFINED, 8, (unsigned char *)"SAMSUNG");
2756 if (ret != MM_ERROR_NONE) {
2757 EXIF_SET_ERR(ret, EXIF_TAG_MAKER_NOTE);
2760 /* create and link samsung maker note */
2761 ret = mm_exif_mnote_create(ed);
2762 if (ret != MM_ERROR_NONE){
2763 EXIF_SET_ERR(ret, EXIF_TAG_MAKER_NOTE);
2765 _mmcam_dbg_log("Samsung makernote created");
2767 /* add samsung maker note entries (param : data, tag, index, subtag index1, subtag index2) */
2768 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_MNOTE_VERSION, 0, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE);
2769 if (ret != MM_ERROR_NONE) {
2770 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! [%x]", ret);
2773 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_DEVICE_ID, 2, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE);
2774 if (ret != MM_ERROR_NONE) {
2775 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! [%x]", ret);
2778 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_SERIAL_NUM, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE);
2779 if (ret != MM_ERROR_NONE) {
2780 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! [%x]", ret);
2783 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_COLOR_SPACE, 1, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE);
2784 if (ret != MM_ERROR_NONE) {
2785 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! [%x]", ret);
2788 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_FACE_DETECTION, 0, _MNOTE_VALUE_NONE, _MNOTE_VALUE_NONE);
2789 if (ret != MM_ERROR_NONE) {
2790 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! ret=%x", ret);
2793 ret = mm_exif_mnote_set_add_entry(ed, MNOTE_SAMSUNG_TAG_MODEL_ID, _MNOTE_VALUE_NONE, 3, 2);
2794 if (ret != MM_ERROR_NONE) {
2795 _mmcam_dbg_err("mm_exif_mnote_set_add_entry error! [%x]", ret);
2802 ret = mm_exif_set_exif_to_info(hcamcorder->exif_info, ed);
2803 if (ret != MM_ERROR_NONE) {
2804 _mmcam_dbg_err("mm_exif_set_exif_to_info err!! [%x]", ret);
2808 _mmcam_dbg_log("finished!! [%x]", ret);
2811 exif_data_unref (ed);