tizen beta release
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_stillshot.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jeongmo Yang <jm80.yang@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 /*=======================================================================================
23 |  INCLUDE FILES                                                                        |
24 =======================================================================================*/
25 #include <sys/time.h>
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"
32
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) { \
39                 goto exit; \
40         }
41
42 /*---------------------------------------------------------------------------------------
43 |    LOCAL VARIABLE DEFINITIONS for internal                                            |
44 ---------------------------------------------------------------------------------------*/
45
46
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);
56
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);
62
63 /*=======================================================================================
64 |  FUNCTION DEFINITIONS                                                                 |
65 =======================================================================================*/
66
67 /*---------------------------------------------------------------------------------------
68 |    GLOBAL FUNCTION DEFINITIONS:                                                       |
69 ---------------------------------------------------------------------------------------*/
70
71
72 int _mmcamcorder_add_stillshot_pipeline(MMHandleType handle)
73 {
74         int err = MM_ERROR_UNKNOWN;
75
76         GstPad *srcpad = NULL;
77         GstPad *sinkpad = NULL;
78
79         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
80         _MMCamcorderSubContext *sc = NULL;
81         _MMCamcorderImageInfo *info = NULL;
82         
83         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
84
85         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
86         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
87
88         info = sc->info;
89
90         _mmcam_dbg_log("");
91
92         //Create gstreamer element
93         //Check main pipeline
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;
98         }
99
100         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
101                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
102                                         "UseEncodebin",
103                                         &sc->bencbin_capture);
104
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);
109                 );
110                 if (err != MM_ERROR_NONE) {
111                         return err;
112                 }
113
114                 gst_bin_add_many(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
115                                  sc->element[_MMCAMCORDER_ENCSINK_BIN].gst,
116                                  NULL);
117
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)
122
123                 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,
124                                            _MMCAMCORDER_HANDLER_STILLSHOT, "handoff",
125                                            G_CALLBACK(__mmcamcorder_encodesink_handoff_callback),
126                                            hcamcorder);
127         } else {
128                 _mmcam_dbg_log("NOT using Encodebin for capturing");
129
130                 /*set video source element*/
131                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "signal-still-capture", TRUE);
132
133                 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
134                                            _MMCAMCORDER_HANDLER_STILLSHOT, "still-capture",
135                                            G_CALLBACK(__mmcamcorder_image_capture_cb),
136                                            hcamcorder);
137         }
138
139         return MM_ERROR_NONE;
140
141 element_link_error:
142         if (sc->bencbin_capture) {
143                 _mmcam_dbg_err("Link encodebin failed!");
144
145                 if (sc->element[_MMCAMCORDER_ENCSINK_BIN].gst != NULL) {
146                         int ret = MM_ERROR_NONE;
147
148                         __ta__( "        EncodeBin Set NULL",
149                         ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, GST_STATE_NULL);
150                         );
151                         if (ret != MM_ERROR_NONE) {
152                                 _mmcam_dbg_err("Faile to change encode bin state[%d]", ret);
153                                 /* Can't return here. */
154                                 /* return ret; */
155                         }
156
157                         gst_bin_remove(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
158                                        sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
159
160                         _mmcamcorder_remove_element_handle(handle, _MMCAMCORDER_ENCSINK_BIN, _MMCAMCORDER_ENCSINK_SINK);
161
162                         _mmcam_dbg_log("Encodebin removed");
163                 }
164         }
165
166         return MM_ERROR_CAMCORDER_GST_LINK;
167
168 pipeline_creation_error:
169         return err;
170 }
171
172
173 int _mmcamcorder_remove_stillshot_pipeline(MMHandleType handle)
174 {
175         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
176         _MMCamcorderSubContext *sc = NULL;
177         _MMCamcorderImageInfo *info = NULL;
178
179         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
180
181         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
182         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
183
184         info = sc->info;
185
186         _mmcam_dbg_log("");
187
188         /* Check pipeline */
189         if (sc->element[_MMCAMCORDER_MAIN_PIPE].gst) {
190                 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_STILLSHOT);
191
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");
196                         } else {
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);
201
202                                 gst_bin_remove(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
203                                         sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
204
205                                 _mmcamcorder_remove_element_handle(handle, _MMCAMCORDER_ENCSINK_BIN, _MMCAMCORDER_ENCSINK_SINK);
206                         }
207                 }
208         } else {
209                 _mmcam_dbg_log("MAIN_PIPE is already removed");
210         }
211
212         return MM_ERROR_NONE;
213 }
214
215
216 void _mmcamcorder_destroy_image_pipeline(MMHandleType handle)
217 {
218         GstPad *reqpad1 = NULL;
219         GstPad *reqpad2 = NULL;
220
221         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
222         _MMCamcorderSubContext *sc = NULL;
223
224         mmf_return_if_fail(hcamcorder);
225
226         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
227         mmf_return_if_fail(sc && sc->element);
228         
229         _mmcam_dbg_log("");
230
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);
234
235                 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_CATEGORY_ALL);
236
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);
243
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);
250                         }
251                 }
252
253                 gst_object_unref(sc->element[_MMCAMCORDER_MAIN_PIPE].gst);
254                 /* Why is this commented? */
255                 /* sc->element[_MMCAMCORDER_MAIN_PIPE].gst = NULL; */
256         }
257 }
258
259
260 int _mmcamcorder_image_cmd_capture(MMHandleType handle)
261 {
262         int ret = MM_ERROR_NONE;
263         int UseCaptureMode = 0;
264         int width = 0;
265         int height = 0;
266         int fps = 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;
271
272         char *err_name = NULL;
273         char *videosrc_name = NULL;
274
275         GstElement *pipeline = NULL;
276         GstCameraControl *control = NULL;
277         GstCaps *caps = NULL;
278         GstClock *clock = NULL;
279
280         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
281         _MMCamcorderImageInfo *info = NULL;
282         _MMCamcorderSubContext *sc = NULL;
283         type_element *VideosrcElement = NULL;
284
285         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
286
287         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
288         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
289
290         _mmcam_dbg_log("");
291
292         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
293         info = sc->info;
294
295         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
296                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
297                                         "UseCaptureMode",
298                                         &UseCaptureMode);
299
300         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
301                                       CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
302                                       "VideosrcElement",
303                                       &VideosrcElement);
304
305         _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
306
307         if (info->capturing) {
308                 ret = MM_ERROR_CAMCORDER_DEVICE_BUSY;
309                 goto cmd_error;
310         }
311
312         MMTA_ACUM_ITEM_BEGIN("Real First Capture Start",false);
313
314         /* set capture flag */
315         info->capturing = TRUE;
316
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,
328                                           NULL);
329         if (ret != MM_ERROR_NONE) {
330                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
331                 SAFE_FREE (err_name);
332                 goto cmd_error;
333         }
334
335         if (info->count < 1) {
336                 _mmcam_dbg_err("capture count[%d] is invalid", info->count);
337                 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
338                 goto cmd_error;
339         } else if (info->count == 1) {
340                 info->type = _MMCamcorder_SINGLE_SHOT;
341         } else {
342                 info->type = _MMCamcorder_MULTI_SHOT;
343                 info->next_shot_time = 0;
344                 info->multi_shot_stop = FALSE;
345         }
346
347         info->capture_cur_count = 0;
348         info->capture_send_count = 0;
349
350         _mmcam_dbg_log("videosource(%dx%d), capture(%dx%d), count(%d)",
351                        width, height, info->width, info->height, info->count);
352
353         sc->internal_encode = FALSE;
354
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");
361                         } else {
362                                 int raw_capture_format = MM_PIXEL_FORMAT_I420;
363
364                                 ret = mm_camcorder_get_attributes(handle, &err_name,
365                                                                   MMCAM_RECOMMEND_PREVIEW_FORMAT_FOR_CAPTURE, &raw_capture_format,
366                                                                   NULL );
367                                 if (ret != MM_ERROR_NONE) {
368                                         _mmcam_dbg_warn("Get Recommend capture format failed.");
369                                         SAFE_FREE(err_name);
370                                         goto cmd_error;
371                                 }
372
373                                 cap_fourcc = _mmcamcorder_get_fourcc(raw_capture_format, image_encoder, hcamcorder->use_zero_copy_format);
374                                 sc->internal_encode = TRUE;
375
376                                 _mmcam_dbg_log("MSL JPEG Capture");
377                         }
378                 } else {
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 );
383                         }
384                 }
385
386                 _mmcam_dbg_log("capture format (%d), jpeg quality (%d)", cap_format, cap_jpeg_quality);
387
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);
393
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;
397                 }
398
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);
401         } else {
402                 int need_change = 0;
403                 int set_width = 0;
404                 int set_height = 0;
405
406                 if (UseCaptureMode) {
407                         if (width != MMFCAMCORDER_HIGHQUALITY_WIDTH || height != MMFCAMCORDER_HIGHQUALITY_HEIGHT) {
408                                 need_change = 1;
409                         }
410                 } else {
411                         if (width != info->width || height != info->height) {
412                                 need_change = 1;
413                         }
414                 }
415
416                 if (need_change) {
417                         _mmcam_dbg_log("Need to change resolution");
418
419                         if (UseCaptureMode) {
420                                 set_width = MMFCAMCORDER_HIGHQUALITY_WIDTH;
421                                 set_height = MMFCAMCORDER_HIGHQUALITY_HEIGHT;
422                         } else {
423                                 set_width = info->width;
424                                 set_height = info->height;
425                         }
426
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,
433                                                    NULL);
434                         if (caps == NULL) {
435                                 _mmcam_dbg_err("failed to create caps");
436                                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
437                                 goto cmd_error;
438                         }
439
440                         info->resolution_change = TRUE;
441                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
442                         gst_caps_unref(caps);
443
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);
446
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);
451
452                         _mmcam_dbg_log("Change to target resolution(%d, %d)", set_width, set_height);
453                 } else {
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);
456                 }
457         }
458
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);
462         }
463
464 cmd_error:
465         return ret;
466 }
467
468
469 int _mmcamcorder_image_cmd_preview_start(MMHandleType handle)
470 {
471         int ret = MM_ERROR_NONE;
472         int width = 0;
473         int height = 0;
474         int fps = 0;
475         int cap_width = 0;
476         int cap_height = 0;
477         int rotation = 0;
478         int input_index = 0;
479         int set_width = 0;
480         int set_height = 0;
481         int set_rotate = 0;
482         int current_framecount = 0;
483         gboolean fps_auto = FALSE;
484         char *err_name = NULL;
485         char *videosrc_name = NULL;
486
487         GstState state;
488         GstCaps *caps = NULL;
489         GstElement *pipeline = NULL;
490         GstCameraControl *control = NULL;
491
492         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
493         _MMCamcorderImageInfo *info = NULL;
494         _MMCamcorderSubContext *sc = NULL;
495         type_element *VideosrcElement = NULL;
496
497         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
498
499         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
500         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
501
502         _mmcam_dbg_log("");
503
504         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
505         info = sc->info;
506
507         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
508
509         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
510                                       CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
511                                       "VideosrcElement",
512                                       &VideosrcElement);
513
514         _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
515
516         sc->display_interval = 0;
517         sc->previous_slot_time = 0;
518
519         /* Image info */
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;
525
526         _mmcamcorder_vframe_stablize(handle);
527
528         if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
529                 _mmcam_dbg_log("Capture Preview start : avsysvideosrc - No need to set new caps.");
530
531                 ret = mm_camcorder_get_attributes(handle, &err_name,
532                                                   MMCAM_CAMERA_FPS_AUTO, &fps_auto,
533                                                   NULL);
534                 if (ret != MM_ERROR_NONE) {
535                         _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
536                         SAFE_FREE (err_name);
537                         goto cmd_error;
538                 }
539
540                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "fps-auto", fps_auto);
541
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;
546                         }
547
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);
550
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);
555                         }
556                 }
557         } else {
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,
568                                                   NULL);
569                 if (ret != MM_ERROR_NONE) {
570                         _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
571                         SAFE_FREE (err_name);
572                         goto cmd_error;
573                 }
574
575                 if (_mmcamcorder_get_state((MMHandleType)hcamcorder) == MM_CAMCORDER_STATE_CAPTURING) {
576                         switch (rotation) {
577                         case MM_VIDEO_INPUT_ROTATION_90:
578                                 set_width = height;
579                                 set_height = width;
580                                 set_rotate = 90;
581                                 break;
582                         case MM_VIDEO_INPUT_ROTATION_180:
583                                 set_width = width;
584                                 set_height = height;
585                                 set_rotate = 180;
586                                 break;
587                         case MM_VIDEO_INPUT_ROTATION_270:
588                                 set_width = height;
589                                 set_height = width;
590                                 set_rotate = 270;
591                                 break;
592                         case MM_VIDEO_INPUT_ROTATION_NONE:
593                         default:
594                                 set_width = width;
595                                 set_height = height;
596                                 set_rotate = 0;
597                                 break;
598                         }
599
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,
606                                                    NULL);
607                         if (caps != NULL) {
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);
611                         } else {
612                                 _mmcam_dbg_err("failed to create caps");
613                                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
614                                 goto cmd_error;
615                         }
616                 }
617         }
618
619         gst_element_get_state(pipeline, &state, NULL, -1);
620
621         if (state == GST_STATE_PLAYING) {
622                 if (!strcmp(videosrc_name, "avsysvideosrc") || !strcmp(videosrc_name, "camerasrc")) {
623                         int try_count = 0;
624
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);
629                         }
630                         );
631
632                         if (info->type == _MMCamcorder_MULTI_SHOT) {
633                                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
634                         }
635
636                         _mmcam_dbg_log("Wait Frame Done. count before[%d],after[%d], try_count[%d]",
637                                        current_framecount, sc->kpi.video_framecount, try_count);
638                 } else {
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);
641
642                         if (ret != MM_ERROR_NONE) {
643                                 goto cmd_error;
644                         }
645
646                         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
647                         if (ret != MM_ERROR_NONE) {
648                                 goto cmd_error;
649                         }
650                 }
651         } else {
652                 int cap_count = 0;
653                 int sound_ret = FALSE;
654
655                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
656
657                 __ta__("        _MMCamcorder_CMD_PREVIEW_START:GST_STATE_PLAYING",  
658                 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
659                 );
660                 if (ret != MM_ERROR_NONE) {
661                         goto cmd_error;
662                 }
663
664                 mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_COUNT, &cap_count, NULL);
665                 if (cap_count > 1) {
666                         __ta__("_mmcamcorder_sound_init",
667                         sound_ret = _mmcamcorder_sound_init(handle, _MMCAMCORDER_FILEPATH_CAPTURE2_SND);
668                         );
669                         if (sound_ret) {
670                                 __ta__("_mmcamcorder_sound_prepare",
671                                 sound_ret = _mmcamcorder_sound_prepare(handle);
672                                 );
673                                 _mmcam_dbg_log("sound prepare [%d]", sound_ret);
674                         }
675                 }
676         }
677
678 cmd_error:
679         return ret;
680 }
681
682
683 int _mmcamcorder_image_cmd_preview_stop(MMHandleType handle)
684 {
685         int ret = MM_ERROR_NONE;
686
687         GstElement *pipeline = NULL;
688
689         _MMCamcorderSubContext *sc = NULL;
690
691         _mmcam_dbg_log("");
692
693         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
694
695         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
696         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
697
698         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
699
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);
703
704         return ret;
705 }
706
707
708 int _mmcamcorder_image_cmd_capture_with_encbin(MMHandleType handle)
709 {
710         int ret = MM_ERROR_NONE;
711         int UseCaptureMode = 0;
712         int width = 0;
713         int height = 0;
714         int fps = 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;
721
722         GstCaps *caps = NULL;
723         GstClock *clock = NULL;
724         GstElement *pipeline = NULL;
725         GstCameraControl *control = NULL;
726
727         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
728         _MMCamcorderImageInfo *info = NULL;
729         _MMCamcorderSubContext *sc = NULL;
730         type_element *VideosrcElement = NULL;
731
732         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
733
734         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
735         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
736
737         _mmcam_dbg_log("");
738
739         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
740         info = sc->info;
741
742         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
743                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
744                                         "UseCaptureMode",
745                                         &UseCaptureMode);
746
747         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
748                                       CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
749                                       "VideosrcElement",
750                                       &VideosrcElement);
751
752         _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
753
754         if (info->capturing) {
755                 ret = MM_ERROR_CAMCORDER_DEVICE_BUSY;
756                 goto cmd_error;
757         }
758
759         MMTA_ACUM_ITEM_BEGIN("Real First Capture Start",false);
760
761         info->capturing = TRUE;
762
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,
774                                           NULL);
775         if (ret != MM_ERROR_NONE) {
776                 _mmcam_dbg_err("Get attrs fail. (%s:%x)", err_name, ret);
777                 SAFE_FREE (err_name);
778                 goto cmd_error;
779         }
780
781         if (info->count < 1) {
782                 _mmcam_dbg_err("capture count[%d] is invalid", info->count);
783                 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
784                 goto cmd_error;
785         } else if (info->count == 1) {
786                 info->type = _MMCamcorder_SINGLE_SHOT;
787         } else {
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;
793         }
794
795         _mmcam_dbg_log("videosource(%dx%d), capture(%dx%d), count(%d)",
796                        width, height, info->width, info->height, info->count);
797
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);
801
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);
808
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;
812                 }
813
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 );
816         } else {
817                 int need_change = 0;
818                 int set_width = 0;
819                 int set_height = 0;
820
821                 if (UseCaptureMode) {
822                         if (width != MMFCAMCORDER_HIGHQUALITY_WIDTH || height != MMFCAMCORDER_HIGHQUALITY_HEIGHT) {
823                                 need_change = 1;
824                         }
825                 } else {
826                         if (width != info->width || height != info->height) {
827                                 need_change = 1;
828                         }
829                 }
830
831                 if (need_change) {
832                         _mmcam_dbg_log("Need to change resolution");
833
834                         if (UseCaptureMode) {
835                                 set_width = MMFCAMCORDER_HIGHQUALITY_WIDTH;
836                                 set_height = MMFCAMCORDER_HIGHQUALITY_HEIGHT;
837                         } else {
838                                 set_width = info->width;
839                                 set_height = info->height;
840                         }
841
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,
848                                                    NULL);
849                         if (caps == NULL) {
850                                 _mmcam_dbg_err("failed to create caps");
851                                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
852                                 goto cmd_error;
853                         }
854
855                         info->resolution_change = TRUE;
856                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
857                         gst_caps_unref(caps);
858                         
859                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "req-negotiation",TRUE);
860
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);
867
868                 } else {
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);
872                 }
873         }
874
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);
878         }
879
880 cmd_error:
881         return ret;
882 }
883
884
885 int _mmcamcorder_image_cmd_preview_start_with_encbin(MMHandleType handle)
886 {
887         int ret = MM_ERROR_NONE;
888         int width = 0;
889         int height = 0;
890         int fps = 0;
891         int cap_width = 0;
892         int cap_height = 0;
893         int rotation = 0;
894         int input_index = 0;
895         int set_width = 0;
896         int set_height = 0;
897         int set_rotate = 0;
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;
903
904         GstState state = GST_STATE_NULL;
905         GstCaps *caps = NULL;
906         GstElement *pipeline = NULL;
907         GstCameraControl *control = NULL;
908
909         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
910         _MMCamcorderImageInfo *info = NULL;
911         _MMCamcorderSubContext *sc = NULL;
912         type_element *VideosrcElement = NULL;
913
914         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
915
916         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
917         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
918
919         _mmcam_dbg_log("");
920
921         info = sc->info;
922         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
923
924         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
925                                       CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
926                                       "VideosrcElement",
927                                       &VideosrcElement);
928
929         _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
930
931         sc->display_interval = 0;
932         sc->previous_slot_time = 0;
933
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;
940
941         _mmcamcorder_vframe_stablize(handle);
942
943         current_state = _mmcamcorder_get_state(handle);
944         _mmcam_dbg_log("current state [%d]", current_state);
945
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);
948
949                 ret = mm_camcorder_get_attributes(handle, &err_name,
950                                                   MMCAM_CAMERA_FPS_AUTO, &fps_auto,
951                                                   NULL);
952                 if (ret != MM_ERROR_NONE) {
953                         _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
954                         SAFE_FREE (err_name);
955                         goto cmd_error;
956                 }
957
958                 /* set fps-auto to videosrc */
959                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "fps-auto", fps_auto);
960
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;
965                         }
966
967                         current_framecount = sc->kpi.video_framecount;
968
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);
971                 }
972         } else {
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,
983                                                   NULL);
984                 if (ret != MM_ERROR_NONE) {
985                         _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
986                         SAFE_FREE (err_name);
987                         goto cmd_error;
988                 }
989
990                 if (current_state == MM_CAMCORDER_STATE_CAPTURING) {
991                         switch (rotation) {
992                         case MM_VIDEO_INPUT_ROTATION_90:
993                                 set_width = height;
994                                 set_height = width;
995                                 set_rotate = 90;
996                                 break;
997                         case MM_VIDEO_INPUT_ROTATION_180:
998                                 set_width = width;
999                                 set_height = height;
1000                                 set_rotate = 180;
1001                                 break;
1002                         case MM_VIDEO_INPUT_ROTATION_270:
1003                                 set_width = height;
1004                                 set_height = width;
1005                                 set_rotate = 270;
1006                                 break;
1007                         case MM_VIDEO_INPUT_ROTATION_NONE:
1008                         default:
1009                                 set_width = width;
1010                                 set_height = height;
1011                                 set_rotate = 0;
1012                                 break;
1013                         }
1014
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,
1021                                                    NULL);
1022                         if (caps == NULL) {
1023                                 _mmcam_dbg_err("failed to create caps");
1024                                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1025                                 goto cmd_error;
1026                         }
1027
1028                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
1029                         gst_caps_unref(caps);
1030                         caps = NULL;
1031                         _mmcam_dbg_log("Rollback to original resolution(%d, %d)", width, height);
1032                 }
1033         }
1034
1035         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
1036
1037         gst_element_get_state(pipeline, &state, NULL, -1);
1038
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);
1044                         }
1045                         );
1046
1047                         _mmcam_dbg_log("Wait Frame Done. count before[%d],after[%d]",
1048                                        current_framecount, sc->kpi.video_framecount);
1049                 } else {
1050 #if 1
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);
1059 #endif
1060                         if (ret != MM_ERROR_NONE) {
1061                                 goto cmd_error;
1062                         }
1063
1064                         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1065                         if (ret != MM_ERROR_NONE) {
1066                                 goto cmd_error;
1067                         }
1068                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
1069                 }
1070         } else {
1071                 __ta__("        _MMCamcorder_CMD_PREVIEW_START:GST_STATE_PLAYING",  
1072                 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1073                 );
1074                 if (ret != MM_ERROR_NONE) {
1075                         goto cmd_error;
1076                 }
1077         }
1078
1079 cmd_error:
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);
1082         return ret;
1083 }
1084
1085
1086 int _mmcamcorder_image_cmd_preview_stop_with_encbin(MMHandleType handle)
1087 {
1088         int ret = MM_ERROR_NONE;
1089
1090         GstElement *pipeline = NULL;
1091
1092         _MMCamcorderSubContext *sc = NULL;
1093
1094         _mmcam_dbg_log("");
1095
1096         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1097
1098         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1099         mmf_return_val_if_fail(sc && sc->info && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1100
1101         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
1102
1103         /* set signal handler off */
1104         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst,"signal-handoffs",FALSE);
1105
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) {
1110                 goto cmd_error;
1111         }
1112
1113 cmd_error:
1114         return ret;
1115 }
1116
1117
1118 int _mmcamcorder_image_command(MMHandleType handle, int command)
1119 {
1120         int ret = MM_ERROR_NONE;
1121
1122         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1123         _MMCamcorderSubContext *sc = NULL;
1124
1125         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1126
1127         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1128         mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1129
1130         _mmcam_dbg_log("command=%d", command);
1131
1132         switch (command) {
1133         case _MMCamcorder_CMD_CAPTURE:
1134                 if (!sc->bencbin_capture) {
1135                         ret = _mmcamcorder_image_cmd_capture(handle);
1136                 } else {
1137                         ret = _mmcamcorder_image_cmd_capture_with_encbin(handle);
1138                 }
1139                 break;
1140         case _MMCamcorder_CMD_CAPTURE_CANCEL:
1141                 /* TODO: Is this needed? */
1142                 break;
1143         case _MMCamcorder_CMD_PREVIEW_START:
1144                 if (!sc->bencbin_capture) {
1145                         ret = _mmcamcorder_image_cmd_preview_start(handle);
1146                 } else {
1147                         ret = _mmcamcorder_image_cmd_preview_start_with_encbin(handle);
1148                 }
1149                 /* I place this function last because it miscalculates a buffer that sents in GST_STATE_PAUSED */
1150                 _mmcamcorder_video_current_framerate_init(handle);
1151                 break;
1152         case _MMCamcorder_CMD_PREVIEW_STOP:
1153                 if (!sc->bencbin_capture) {
1154                         ret = _mmcamcorder_image_cmd_preview_stop(handle);
1155                 } else {
1156                         ret = _mmcamcorder_image_cmd_preview_stop_with_encbin(handle);
1157                 }
1158                 break;
1159         default:
1160                 ret =  MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1161                 break;
1162         }
1163
1164         if (ret != MM_ERROR_NONE && sc->element && sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
1165                 int op_status = 0;
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);
1168         }
1169
1170         return ret;
1171 }
1172
1173
1174 void __mmcamcorder_init_stillshot_info (MMHandleType handle)
1175 {
1176         int type = _MMCamcorder_SINGLE_SHOT;
1177
1178         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1179         _MMCamcorderSubContext *sc = NULL;
1180         _MMCamcorderImageInfo *info = NULL;
1181
1182         mmf_return_if_fail(hcamcorder);
1183
1184         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1185         mmf_return_if_fail(sc && sc->info);
1186
1187         info = sc->info;
1188         type = info->type;
1189
1190         _mmcam_dbg_log("capture type[%d], capture send count[%d]", type, info->capture_send_count);
1191
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;
1198
1199                 /* capturing flag set to FALSE here */
1200                 info->capturing = FALSE;
1201                 MMTA_ACUM_ITEM_END("Real First Capture Start", FALSE);
1202         }
1203
1204         return;
1205 }
1206
1207
1208 gboolean __mmcamcorder_capture_save_exifinfo(MMHandleType handle, MMCamcorderCaptureDataType *original, MMCamcorderCaptureDataType *thumbnail)
1209 {
1210         int ret = MM_ERROR_NONE;
1211         unsigned char *data = NULL;
1212         unsigned int datalen = 0;
1213
1214         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1215
1216         mmf_return_val_if_fail(hcamcorder, FALSE);
1217
1218         _mmcam_dbg_log("");
1219
1220         if (!original || original->data == NULL || original->length == 0) {
1221                 _mmcam_dbg_err("original=%p, data=%p, length=%d", original, original->data, original->length);
1222                 return FALSE;
1223         } else {
1224                 /* original is input/output param. save original values to local var. */
1225                 data = original->data;
1226                 datalen = original->length;
1227         }
1228
1229         /* exif 090227 */
1230         ret = mm_exif_create_exif_info(&(hcamcorder->exif_info));
1231         if (hcamcorder->exif_info == NULL || ret != MM_ERROR_NONE) {
1232                 _MMCamcorderMsgItem msg;
1233
1234                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1235                 msg.param.code = ret;
1236                 _mmcamcroder_send_message(handle, &msg);
1237
1238                 _mmcam_dbg_err("Failed to create exif_info [%x]", ret);
1239                 return FALSE;
1240         }
1241
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);
1246         );
1247         if (ret != MM_ERROR_NONE) {
1248                 _MMCamcorderMsgItem msg;
1249
1250                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1251                 msg.param.code = ret;
1252                 _mmcamcroder_send_message(handle, &msg);
1253
1254                 _mmcam_dbg_err("Failed to set_exif_basic_info [%x]", ret);
1255         }
1256
1257         if (thumbnail != NULL) {
1258                 int bthumbnail = TRUE;
1259
1260                 /* check whether thumbnail should be included */
1261                 mm_camcorder_get_attributes(handle, NULL, "capture-thumbnail", &bthumbnail, NULL);
1262
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);
1266
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);
1270                         );
1271                         if (ret != MM_ERROR_NONE) {
1272                                 _MMCamcorderMsgItem msg;
1273
1274                                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1275                                 msg.param.code = ret;
1276                                 _mmcamcroder_send_message(handle, &msg);
1277
1278                                 _mmcam_dbg_err("Failed to set_exif_thumbnail [%x]",ret);
1279                         }
1280                 } else {
1281                         _mmcam_dbg_err("Skip adding thumbnail (data=%p, length=%d, capture-thumbnail=%d)",
1282                                        thumbnail->data, thumbnail->length , bthumbnail);
1283                 }
1284         }
1285
1286         /* write jpeg with exif */
1287         ret = mm_exif_write_exif_jpeg_to_memory(&original->data, &original->length ,hcamcorder->exif_info,  data, datalen);
1288
1289         if (ret != MM_ERROR_NONE) {
1290                 _MMCamcorderMsgItem msg;
1291         
1292                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
1293                 msg.param.code = ret;
1294                 _mmcamcroder_send_message(handle, &msg);
1295
1296                 _mmcam_dbg_err("mm_exif_write_exif_jpeg_to_memory error! [%x]",ret);
1297         }
1298
1299         /* destroy exif info */
1300         mm_exif_destory_exif_info(hcamcorder->exif_info);
1301         hcamcorder->exif_info = NULL;
1302
1303         _mmcam_dbg_log("END");
1304
1305         if (ret != MM_ERROR_NONE) {
1306                 return FALSE;
1307         } else {
1308                 return TRUE;
1309         }
1310 }
1311
1312
1313 gboolean __mmcamcorder_capture_send_msg(MMHandleType handle, int type, int count)
1314 {
1315         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1316         _MMCamcorderImageInfo *info = NULL;
1317         _MMCamcorderSubContext *sc = NULL;
1318         _MMCamcorderMsgItem msg;
1319
1320         mmf_return_val_if_fail(hcamcorder, FALSE);
1321
1322         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1323         mmf_return_val_if_fail(sc && sc->info, FALSE);
1324
1325         info = sc->info;
1326
1327         _mmcam_dbg_log("type [%d], capture count [%d]", type, count);
1328
1329         msg.id = MM_MESSAGE_CAMCORDER_CAPTURED;
1330         msg.param.code = count;
1331
1332         _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
1333
1334         _mmcam_dbg_log("END");
1335         return TRUE;
1336 }
1337
1338
1339 void __mmcamcorder_get_capture_data_from_buffer(MMCamcorderCaptureDataType *capture_data, int pixtype, GstBuffer *buffer)
1340 {
1341         GstCaps *caps = NULL;
1342         const GstStructure *structure;
1343
1344         mmf_return_if_fail(capture_data && buffer);
1345
1346         caps = gst_buffer_get_caps(buffer);
1347         if (caps == NULL) {
1348                 _mmcam_dbg_err("failed to get caps");
1349                 goto GET_FAILED;
1350         }
1351
1352         structure = gst_caps_get_structure(caps, 0);
1353         if (caps == NULL) {
1354                 _mmcam_dbg_err("failed to get structure");
1355                 goto GET_FAILED;
1356         }
1357
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);
1363
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);
1368         caps = NULL;
1369
1370         return;
1371
1372 GET_FAILED:
1373         capture_data->data = NULL;
1374         capture_data->format = MM_PIXEL_FORMAT_INVALID;
1375         capture_data->length = 0;
1376
1377         return;
1378 }
1379
1380
1381 gboolean __mmcamcorder_set_jpeg_data(MMHandleType handle, MMCamcorderCaptureDataType *dest, MMCamcorderCaptureDataType *thumbnail)
1382 {
1383         int tag_enable = 0;
1384         int provide_exif = FALSE;
1385
1386         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1387         _MMCamcorderSubContext *sc = NULL;
1388
1389         mmf_return_val_if_fail(hcamcorder, FALSE);
1390         mmf_return_val_if_fail(dest, FALSE);
1391
1392         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1393         mmf_return_val_if_fail(sc, FALSE);
1394
1395         _mmcam_dbg_log("");
1396
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);
1399
1400         _mmcam_dbg_log("tag enable[%d], provide exif[%d]", tag_enable, provide_exif);
1401
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)) {
1407                                 return FALSE;
1408                         }
1409                 } else {
1410                         if (!__mmcamcorder_capture_save_exifinfo(handle, dest, NULL)) {
1411                                 return FALSE;
1412                         }
1413                 }
1414         }
1415
1416         return TRUE;
1417 }
1418
1419
1420 void __mmcamcorder_release_jpeg_data(MMHandleType handle, MMCamcorderCaptureDataType *dest)
1421 {
1422         int tag_enable = 0;
1423         int provide_exif = FALSE;
1424
1425         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1426         _MMCamcorderSubContext *sc = NULL;
1427
1428         mmf_return_if_fail(hcamcorder);
1429         mmf_return_if_fail(dest);
1430
1431         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1432         mmf_return_if_fail(sc);
1433
1434         _mmcam_dbg_log("");
1435
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);
1438
1439         /* if dest->data is allocated in MSL, release it */
1440         if (tag_enable && !provide_exif) {
1441                 if (dest->data) {
1442                         free(dest->data);
1443                         dest->length = 0;
1444                         dest->data = NULL;
1445                         _mmcam_dbg_log("Jpeg is released!");
1446                 }
1447         } else {
1448                 _mmcam_dbg_log("No need to release");
1449         }
1450
1451         return;
1452 }
1453
1454
1455 static void __mmcamcorder_image_capture_cb(GstElement *element, GstBuffer *buffer1, GstBuffer *buffer2, GstBuffer *buffer3, gpointer u_data)
1456 {
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;
1462         int attr_index = 0;
1463         int count = 0;
1464         int stop_cont_shot = 0;
1465         gboolean send_msg = FALSE;
1466
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,};
1473
1474         mmf_attrs_t *attrs = NULL;
1475         mmf_attribute_t *item = NULL;
1476
1477         void *encoded_data = NULL;
1478         char *err_attr_name = NULL;
1479
1480         mmf_return_if_fail(hcamcorder);
1481
1482         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1483         mmf_return_if_fail(sc && sc->info);
1484
1485         info = sc->info;
1486
1487         _mmcam_dbg_err("START");
1488
1489         MMTA_ACUM_ITEM_BEGIN("            MSL capture callback", FALSE);
1490
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 );
1497                         goto error;
1498                 }
1499         }
1500
1501         if (!info->capturing) {
1502                 _mmcam_dbg_err("It's Not capturing now.");
1503                 goto error;
1504         }
1505
1506         /* play capture sound here if multi capture */
1507         if (info->type == _MMCamcorder_MULTI_SHOT) {
1508                 _mmcamcorder_sound_play((MMHandleType)hcamcorder);
1509         }
1510
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");
1515                 goto error;
1516         }
1517
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);
1521         } else {
1522                 _mmcam_dbg_err("buffer1 has wrong pointer. (buffer1=%p)",buffer1);
1523                 goto error;
1524         }
1525
1526         /* Encode JPEG */
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,
1531                                                   NULL);
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);
1535                         goto error;
1536                 }
1537
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));
1541                 );
1542                 if (ret == FALSE) {
1543                         goto error;
1544                 }
1545
1546                 encoded_data = dest.data;
1547                 dest.format = MM_PIXEL_FORMAT_ENCODED;
1548         }
1549
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);
1554
1555                 __mmcamcorder_get_capture_data_from_buffer(&thumb, pixtype_sub, buffer2);
1556         } else {
1557                 _mmcam_dbg_log("buffer2 has wrong pointer. Not Error. (buffer2=%p)",buffer2);
1558         }
1559
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];
1564
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));
1567
1568                 pixtype_sub = _mmcamcorder_get_pixel_format(buffer3);
1569                 __mmcamcorder_get_capture_data_from_buffer(&scrnail, pixtype_sub, buffer3);
1570
1571                 /* Set screennail attribute for application */
1572                 mmf_attribute_set_data(item, &scrnail, sizeof(scrnail));
1573         } else {
1574                 mmf_attribute_set_data(item, NULL, 0);
1575
1576                 _mmcam_dbg_log("buffer3 has wrong pointer. Not Error. (buffer3=%p)",buffer3);
1577         }
1578
1579         mmf_attrs_commit_err((MMHandleType)attrs, &err_attr_name);
1580
1581         /* Set extra data for jpeg */
1582         if (dest.format == MM_PIXEL_FORMAT_ENCODED) {
1583                 int err = 0;
1584                 char *err_attr_name = NULL;
1585
1586                 err = mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_attr_name,
1587                                                   MMCAM_IMAGE_ENCODER, &codectype,
1588                                                   NULL);
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);
1592                         goto error;
1593                 }
1594
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);
1601                         );
1602                         if (!ret) {
1603                                 _mmcam_dbg_err("Error on setting extra data to jpeg");
1604                                 goto error;
1605                         }
1606                         break;
1607                 default:
1608                         _mmcam_dbg_err("The codectype is not supported. (%d)", codectype);
1609                         goto error;
1610                 }
1611         }
1612
1613         /* Handle Capture Callback */
1614         _MMCAMCORDER_LOCK_VCAPTURE_CALLBACK(hcamcorder);
1615
1616         if (hcamcorder->vcapture_cb) {
1617                 _mmcam_dbg_log("APPLICATION CALLBACK START");
1618                 MMTA_ACUM_ITEM_BEGIN("                Application capture callback", 0);
1619                 if (thumb.data) {
1620                         ret = hcamcorder->vcapture_cb(&dest, &thumb, hcamcorder->vcapture_cb_param);
1621                 } else {
1622                         ret = hcamcorder->vcapture_cb(&dest, NULL, hcamcorder->vcapture_cb_param);
1623                 }
1624                 MMTA_ACUM_ITEM_END("                Application capture callback", 0);
1625                 _mmcam_dbg_log("APPLICATION CALLBACK END");
1626         } else {
1627                 _mmcam_dbg_err("Capture callback is NULL.");
1628                 goto err_release_exif;
1629         }
1630
1631         /* Set send msg flag and capture count */
1632         send_msg = TRUE;
1633         type = info->type;
1634         count = ++(info->capture_send_count);
1635
1636 err_release_exif:
1637         _MMCAMCORDER_UNLOCK_VCAPTURE_CALLBACK(hcamcorder);
1638
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);
1643                 );
1644         }
1645
1646 error:
1647         /* Check end condition and set proper value */
1648         __mmcamcorder_init_stillshot_info((MMHandleType)hcamcorder);
1649
1650         /* send captured message if no problem */
1651         if (send_msg) {
1652                 __mmcamcorder_capture_send_msg((MMHandleType)hcamcorder, type, count);
1653         }
1654
1655         /* release internal allocated data */
1656         if (encoded_data) {
1657                 if (dest.data == encoded_data) {
1658                         dest.data = NULL;
1659                 }
1660
1661                 free(encoded_data);
1662                 encoded_data = NULL;
1663         }
1664
1665         /*free GstBuffer*/
1666         if (buffer1) {
1667                 gst_buffer_unref(buffer1);
1668         }
1669         if (buffer2) {
1670                 gst_buffer_unref(buffer2);
1671         }
1672         if (buffer3) {
1673                 gst_buffer_unref(buffer3);
1674         }
1675
1676         MMTA_ACUM_ITEM_END( "            MSL capture callback", FALSE );
1677
1678         _mmcam_dbg_err("END");
1679
1680         return;
1681 }
1682
1683
1684 static gboolean __mmcamcorder_encodesink_handoff_callback(GstElement *fakesink, GstBuffer *buffer, GstPad *pad, gpointer u_data)
1685 {
1686         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1687         _MMCamcorderSubContext *sc = NULL;
1688
1689         mmf_return_val_if_fail(hcamcorder, FALSE);
1690
1691         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
1692         mmf_return_val_if_fail(sc && sc->element, FALSE);
1693
1694         _mmcam_dbg_log("");
1695
1696         /* FIXME. How could you get a thumbnail? */
1697         __mmcamcorder_image_capture_cb(fakesink, buffer, NULL, NULL, u_data);
1698
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);
1702         }
1703
1704         return TRUE;
1705 }
1706
1707
1708 /* Take a picture with capture mode */
1709 int _mmcamcorder_set_resize_property(MMHandleType handle, int capture_width, int capture_height)
1710 {
1711         int ELEMENT_CROP = 0;
1712         int ELEMENT_FILTER = 0;
1713
1714         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1715         _MMCamcorderSubContext *sc = NULL;
1716
1717         _mmcam_dbg_log("");
1718
1719         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1720
1721         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1722         mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1723
1724         ELEMENT_CROP = _MMCAMCORDER_ENCSINK_ICROP;
1725         ELEMENT_FILTER = _MMCAMCORDER_ENCSINK_IFILT;
1726
1727         /*TODO: this is not needed now. */
1728
1729         return MM_ERROR_NONE;
1730 }
1731
1732
1733 int __mmcamcorder_set_exif_basic_info(MMHandleType handle)
1734 {
1735         int ret = MM_ERROR_NONE;
1736         int value;
1737         int str_val_len = 0;
1738         int gps_enable = TRUE;
1739         int cntl = 0;
1740         int cnts = 0;
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;
1745         char *maker = NULL;
1746         char *user_comment = NULL;
1747         char *err_name = NULL;
1748         ExifData *ed = NULL;
1749         ExifLong config;
1750         ExifLong ExifVersion;
1751         static ExifShort eshort[20];
1752         static ExifLong elong[10];
1753
1754         GstCameraControl *control = NULL;
1755         GstCameraControlExifInfo avsys_exif_info = {0,};
1756
1757         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1758         _MMCamcorderSubContext *sc = NULL;
1759
1760         _mmcam_dbg_log("");
1761
1762         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1763
1764         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1765         mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1766
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;
1770         }
1771
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);
1775
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;
1781         }
1782
1783         /* Receive attribute info */
1784
1785         /* START INSERT IFD_0 */
1786
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);
1793         }
1794
1795         /*1. EXIF_TAG_IMAGE_WIDTH */ /*EXIF_TAG_PIXEL_X_DIMENSION*/
1796         mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_WIDTH, &value, NULL);
1797
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);
1803         }
1804
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);
1809         }
1810         _mmcam_dbg_log("width[%d]", value);
1811
1812         /*2. EXIF_TAG_IMAGE_LENGTH*/ /*EXIF_TAG_PIXEL_Y_DIMENSION*/
1813         mm_camcorder_get_attributes(handle, NULL, MMCAM_CAPTURE_HEIGHT, &value, NULL);
1814
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);
1820         }
1821
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);
1826         }
1827         _mmcam_dbg_log("height[%d]", value);
1828
1829         /*4. EXIF_TAG_DATE_TIME */
1830
1831         /*12. EXIF_TAG_DATE_TIME_ORIGINAL */
1832
1833         /*13. EXIF_TAG_DATE_TIME_DIGITIZED*/
1834         {
1835                 unsigned char *b;
1836                 time_t t;
1837                 struct tm tm;
1838
1839                 b = malloc(20 * sizeof(unsigned char));
1840                 if (b == NULL) {
1841                         _mmcam_dbg_err("failed to alloc b");
1842                         ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1843                         EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME);
1844                 }
1845
1846                 memset(b, '\0', 20);
1847
1848                 t = time(NULL);
1849                 tzset();
1850                 localtime_r(&t, &tm);
1851
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);
1855
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) {
1859                                 free(b);
1860                         }
1861                         EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME);
1862                 }
1863
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) {
1867                                 free(b);
1868                         }
1869                         EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME_ORIGINAL);
1870                 }
1871
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) {
1875                                 free(b);
1876                         }
1877                         EXIF_SET_ERR(ret, EXIF_TAG_DATE_TIME_DIGITIZED);
1878                 }
1879
1880                 free(b);
1881         }
1882
1883         /*5. EXIF_TAG_MAKE */
1884         maker = strdup(MM_MAKER_NAME);
1885         if (maker) {
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);
1889                 free(maker);
1890                 if (ret != MM_ERROR_NONE) {
1891                         EXIF_SET_ERR(ret, EXIF_TAG_MAKE);
1892                 }
1893         } else {
1894                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1895                 EXIF_SET_ERR(ret, EXIF_TAG_MAKE);
1896         }
1897
1898         /*6. EXIF_TAG_MODEL */
1899         _mmcamcorder_conf_get_value_string(hcamcorder->conf_main,
1900                                            CONFIGURE_CATEGORY_MAIN_GENERAL,
1901                                            "ModelName",
1902                                            &str_value);
1903         _mmcam_dbg_log("model_name [%s]", str_value);
1904         if (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);
1907                 free(model);
1908                 str_value = NULL;
1909                 if (ret != MM_ERROR_NONE) {
1910                         EXIF_SET_ERR(ret, EXIF_TAG_MODEL);
1911                 }
1912         } else {
1913                 _mmcam_dbg_warn("failed to get model name");
1914         }
1915
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);
1923                 free(description);
1924                 str_value = NULL;
1925                 str_val_len = 0;
1926                 if (ret != MM_ERROR_NONE) {
1927                         EXIF_SET_ERR(ret, EXIF_TAG_IMAGE_DESCRIPTION);
1928                 }
1929         } else {
1930                 _mmcam_dbg_warn("failed to get description");
1931         }
1932
1933         /*7. EXIF_TAG_SOFTWARE*/
1934 /*
1935         {
1936                 char software[50] = {0,};
1937                 unsigned int len = 0;
1938
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);
1945                 }
1946         }
1947 */
1948
1949         /*8. EXIF_TAG_ORIENTATION */ 
1950         mm_camcorder_get_attributes(handle, NULL, MMCAM_TAG_ORIENTATION, &value, NULL);
1951
1952         _mmcam_dbg_log("orientation [%d]",value);
1953         if (value == 0) {
1954                 value = MM_EXIF_ORIENTATION;
1955         }
1956
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);
1962         }
1963
1964         /* START INSERT EXIF_IFD */
1965
1966         /*3. User Comment*/
1967         /*FIXME : get user comment from real user */
1968         user_comment = strdup(MM_USER_COMMENT);
1969         if (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);
1973                 free(user_comment);
1974                 if (ret != MM_ERROR_NONE) {
1975                         EXIF_SET_ERR(ret, EXIF_TAG_USER_COMMENT);
1976                 }
1977         } else {
1978                 ret = MM_ERROR_CAMCORDER_LOW_MEMORY;
1979                 EXIF_SET_ERR(ret, EXIF_TAG_USER_COMMENT);
1980         }
1981
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);
1988         }
1989
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);
1997         }
1998
1999         /*11. EXIF_TAG_COMPRESSED_BITS_PER_PIXEL */
2000         /* written  the device_info */
2001
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;
2007                 ExifRational rData;
2008
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)
2011
2012                 b = malloc(sizeof(ExifRational));
2013                 if (b) {
2014                         rData.numerator = avsys_exif_info.exposure_time_numerator;
2015                         rData.denominator = avsys_exif_info.exposure_time_denominator;
2016
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);
2020                         free(b);
2021                         if (ret != MM_ERROR_NONE) {
2022                                 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_TIME);
2023                         }
2024                 } else {
2025                         _mmcam_dbg_warn("malloc failed.");
2026                 }
2027         } else {
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);
2030         }
2031
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;
2035                 ExifRational rData;
2036
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);
2039
2040                 b = malloc(sizeof(ExifRational));
2041                 if (b) {
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);
2047                         free(b);
2048                         if(ret != MM_ERROR_NONE) {
2049                                 EXIF_SET_ERR(ret, EXIF_TAG_FNUMBER);
2050                         }
2051                 } else {
2052                         _mmcam_dbg_warn( "malloc failed." );
2053                 }
2054         } else {
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);
2057         }
2058
2059         /*16. EXIF_TAG_EXPOSURE_PROGRAM*/
2060         /*FIXME*/
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);
2067         }
2068
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);
2077                 }
2078         }
2079
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;
2084
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);
2087
2088                 b = malloc(sizeof(ExifSRational));
2089                 if (b) {
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);
2095                         free(b);
2096                         if (ret != MM_ERROR_NONE) {
2097                                 EXIF_SET_ERR(ret, EXIF_TAG_SHUTTER_SPEED_VALUE);
2098                         }
2099                 } else {
2100                         _mmcam_dbg_warn("malloc failed.");
2101                 }
2102         } else {
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);
2105         }
2106
2107         /*19. EXIF_TAG_APERTURE_VALUE*/
2108         if (avsys_exif_info.aperture_in_APEX) {
2109                 unsigned char *b = NULL;
2110                 ExifRational rData;
2111
2112                 _mmcam_dbg_log("EXIF_TAG_APERTURE_VALUE [%d]", avsys_exif_info.aperture_in_APEX);
2113
2114                 b = malloc(sizeof(ExifRational));
2115                 if (b) {
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);
2121                         free(b);
2122                         if(ret != MM_ERROR_NONE) {
2123                                 EXIF_SET_ERR(ret, EXIF_TAG_APERTURE_VALUE);
2124                         }
2125                 } else {
2126                         _mmcam_dbg_warn("malloc failed.");
2127                 }
2128         } else {
2129                 _mmcam_dbg_log("Skip set EXIF_TAG_APERTURE_VALUE [%d]", avsys_exif_info.aperture_in_APEX);
2130         }
2131
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;
2136
2137                 _mmcam_dbg_log("EXIF_TAG_BRIGHTNESS_VALUE numerator [%d], denominator [%d]",
2138                                avsys_exif_info.brigtness_numerator, avsys_exif_info.brightness_denominator);
2139
2140                 b = malloc(sizeof(ExifSRational));
2141                 if (b) {
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);
2147                         free(b);
2148                         if (ret != MM_ERROR_NONE) {
2149                                 EXIF_SET_ERR(ret, EXIF_TAG_BRIGHTNESS_VALUE);
2150                         }
2151                 } else {
2152                         _mmcam_dbg_warn( "malloc failed." );
2153                 }
2154         } else {
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);
2157         }
2158
2159         /*21. EXIF_TAG_EXPOSURE_BIAS_VALUE*/
2160         value = 0;
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;
2165
2166                 _mmcam_dbg_log("EXIF_TAG_BRIGHTNESS_VALUE %d",value);
2167
2168                 b = malloc(sizeof(ExifSRational));
2169                 if (b) {
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);
2175                         free(b);
2176                         if (ret != MM_ERROR_NONE) {
2177                                 EXIF_SET_ERR(ret, EXIF_TAG_EXPOSURE_BIAS_VALUE);
2178                         }
2179                 } else {
2180                         _mmcam_dbg_warn("malloc failed.");
2181                 }
2182         } else {
2183                 _mmcam_dbg_log("failed to get MMCAM_FILTER_BRIGHTNESS [%x]", ret);
2184         }
2185
2186         /*22  EXIF_TAG_MAX_APERTURE_VALUE*/
2187 /*
2188         if (avsys_exif_info.max_lens_aperture_in_APEX) {
2189                 unsigned char *b = NULL;
2190                 ExifRational rData;
2191
2192                 _mmcam_dbg_log("EXIF_TAG_MAX_APERTURE_VALUE [%d]", avsys_exif_info.max_lens_aperture_in_APEX);
2193
2194                 b = malloc(sizeof(ExifRational));
2195                 if (b) {
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);
2201                         free(b);
2202                         if (ret != MM_ERROR_NONE) {
2203                                 EXIF_SET_ERR(ret, EXIF_TAG_MAX_APERTURE_VALUE);
2204                         }
2205                 } else {
2206                         _mmcam_dbg_warn("failed to alloc for MAX aperture value");
2207                 }
2208         }
2209 */
2210
2211         /*23. EXIF_TAG_SUBJECT_DISTANCE*/
2212         /* defualt : none */
2213
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);
2221         }
2222
2223         /*25. EXIF_TAG_LIGHT_SOURCE*/
2224
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);
2232         }
2233
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;
2237                 ExifRational rData;
2238
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);
2241
2242                 b = malloc(sizeof(ExifRational));
2243                 if (b) {
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);
2249                         free(b);
2250                         if (ret != MM_ERROR_NONE) {
2251                                 EXIF_SET_ERR(ret, EXIF_TAG_FOCAL_LENGTH);
2252                         }
2253                 } else {
2254                         _mmcam_dbg_warn("malloc failed.");
2255                 }
2256         } else {
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);
2259         }
2260
2261         /*28. EXIF_TAG_SENSING_METHOD*/
2262         /*FIXME*/
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);
2269         }
2270
2271         /*29. EXIF_TAG_FILE_SOURCE*/
2272 /*
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);
2279         }
2280 */
2281
2282         /*30. EXIF_TAG_SCENE_TYPE*/
2283 /*
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);
2290         }
2291 */
2292
2293         /*31. EXIF_TAG_EXPOSURE_MODE*/
2294         /*FIXME*/
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);
2301         }
2302
2303
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) {
2307                 int set_value = 0;
2308                 _mmcam_dbg_log("WHITE BALANCE [%d]", value);
2309         
2310                 if (value == MM_CAMCORDER_WHITE_BALANCE_AUTOMATIC) {
2311                         set_value = 0;
2312                 } else {
2313                         set_value = 1;
2314                 }
2315
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);
2321                 }
2322         } else {
2323                 _mmcam_dbg_warn("failed to get white balance [%x]", ret);
2324         }
2325
2326         /*33. EXIF_TAG_DIGITAL_ZOOM_RATIO*/
2327 /*
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);
2331
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);
2337                 }
2338         } else {
2339                 _mmcam_dbg_warn("failed to get digital zoom [%x]", ret);
2340         }
2341 */
2342
2343         /*34. EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM*/
2344         /*FIXME*/
2345 /*
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);
2352         }
2353 */
2354
2355         /*35. EXIF_TAG_SCENE_CAPTURE_TYPE*/
2356         {
2357                 int scene_capture_type;
2358
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);
2362
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 */
2371                         } else {
2372                                 scene_capture_type = 4; /* Others */
2373                         }
2374
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);
2380                         }
2381                 } else {
2382                         _mmcam_dbg_warn("failed to get scene mode [%x]", ret);
2383                 }
2384         }
2385
2386         /*36. EXIF_TAG_GAIN_CONTROL*/
2387         /*FIXME*/
2388 /*
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);
2395         }
2396 */
2397
2398
2399         /*37. EXIF_TAG_CONTRAST */
2400         {
2401                 type_int_range *irange = NULL;
2402                 int level = 0;
2403
2404                 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2405                                                       CONFIGURE_CATEGORY_CTRL_EFFECT,
2406                                                       "Contrast",
2407                                                       &irange);
2408                 if (irange != NULL) {
2409                         mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_CONTRAST, &value, NULL);
2410
2411                         _mmcam_dbg_log("CONTRAST currentt [%d], default [%d]", value, irange->default_value);
2412
2413                         if (value == irange->default_value) {
2414                                 level = MM_VALUE_NORMAL;
2415                         } else if (value < irange->default_value) {
2416                                 level = MM_VALUE_LOW;
2417                         } else {
2418                                 level = MM_VALUE_HARD;
2419                         }
2420
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);
2426                         }
2427                 } else {
2428                         _mmcam_dbg_warn("failed to get range of contrast");
2429                 }
2430         }
2431
2432         /*38. EXIF_TAG_SATURATION*/
2433         {
2434                 type_int_range *irange = NULL;
2435                 int level = 0;
2436
2437                 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2438                                                       CONFIGURE_CATEGORY_CTRL_EFFECT,
2439                                                       "Saturation",
2440                                                       &irange);
2441                 if (irange != NULL) {
2442                         mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_SATURATION, &value, NULL);
2443
2444                         _mmcam_dbg_log("SATURATION current [%d], default [%d]", value, irange->default_value);
2445
2446                         if (value == irange->default_value) {
2447                                 level = MM_VALUE_NORMAL;
2448                         } else if (value < irange->default_value) {
2449                                 level = MM_VALUE_LOW;
2450                         } else {
2451                                 level=MM_VALUE_HARD;
2452                         }
2453
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);
2459                         }
2460                 } else {
2461                         _mmcam_dbg_warn("failed to get range of saturation");
2462                 }
2463         }
2464
2465         /*39. EXIF_TAG_SHARPNESS*/
2466         {
2467                 type_int_range *irange = NULL;
2468                 int level = 0;
2469
2470                 _mmcamcorder_conf_get_value_int_range(hcamcorder->conf_ctrl,
2471                                                       CONFIGURE_CATEGORY_CTRL_EFFECT,
2472                                                       "Sharpness",
2473                                                       &irange);
2474                 if (irange != NULL) {
2475                         mm_camcorder_get_attributes(handle, NULL, MMCAM_FILTER_SHARPNESS, &value, NULL);
2476
2477                         _mmcam_dbg_log("SHARPNESS current [%d], default [%d]", value, irange->default_value);
2478
2479                         if (value == irange->default_value) {
2480                                 level = MM_VALUE_NORMAL;
2481                         } else if (value < irange->default_value) {
2482                                 level = MM_VALUE_LOW;
2483                         } else {
2484                                 level = MM_VALUE_HARD;
2485                         }
2486
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);
2492                         }
2493                 } else {
2494                         _mmcam_dbg_warn("failed to get range of sharpness");
2495                 }
2496         }
2497
2498         /*40. EXIF_TAG_SUBJECT_DISTANCE_RANGE*/
2499         /*FIXME*/
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);
2507         }
2508
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};
2513
2514                 _mmcam_dbg_log("Tag for GPS is ENABLED.");
2515
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);
2520                 }
2521
2522                 /*41. Latitude*/
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);
2530                         goto exit;
2531                 }
2532
2533                 _mmcam_dbg_log("f_latitude [%f]", f_latitude);
2534                 if (f_latitude != INVALID_GPS_VALUE) {
2535                         unsigned char *b = NULL;
2536                         unsigned int deg;
2537                         unsigned int min;
2538                         unsigned int sec;
2539                         ExifRational rData;
2540
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);
2546                                 }
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);
2553                                 }
2554                         }
2555
2556                         deg = (unsigned int)(f_latitude);
2557                         min = (unsigned int)((f_latitude-deg)*60);
2558                         sec = (unsigned int)(((f_latitude-deg)*3600)-min*60);
2559
2560                         _mmcam_dbg_log("f_latitude deg[%d], min[%d], sec[%d]", deg, min, sec);
2561                         b = malloc(3 * sizeof(ExifRational));
2562                         if (b) {
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);
2570
2571                                 ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,
2572                                                             EXIF_FORMAT_RATIONAL, 3, (unsigned char *)b);
2573                                 free(b);
2574                                 if (ret != MM_ERROR_NONE) {
2575                                         EXIF_SET_ERR(ret, EXIF_TAG_GPS_LATITUDE);
2576                                 }
2577                         } else {
2578                                 _mmcam_dbg_warn("malloc failed");
2579                         }
2580                 }
2581
2582                 /*42. Longitude*/
2583                 _mmcam_dbg_log("f_longitude [%f]", f_longitude);
2584                 if (f_longitude != INVALID_GPS_VALUE) {
2585                         unsigned char *b = NULL;
2586                         unsigned int deg;
2587                         unsigned int min;
2588                         unsigned int sec;
2589                         ExifRational rData;
2590
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);
2596                                 }
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);
2603                                 }
2604                         }
2605
2606                         deg = (unsigned int)(f_longitude);
2607                         min = (unsigned int)((f_longitude-deg)*60);
2608                         sec = (unsigned int)(((f_longitude-deg)*3600)-min*60);
2609
2610                         _mmcam_dbg_log("f_longitude deg[%d], min[%d], sec[%d]", deg, min, sec);
2611                         b = malloc(3 * sizeof(ExifRational));
2612                         if (b) {
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);
2622                                 free(b);
2623                                 if (ret != MM_ERROR_NONE) {
2624                                         EXIF_SET_ERR(ret, EXIF_TAG_GPS_LONGITUDE);
2625                                 }
2626                         } else {
2627                                 _mmcam_dbg_warn("malloc failed");
2628                         }
2629                 }
2630
2631                 /*43. Altitude*/
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;
2636                         ExifRational rData;
2637                         b = malloc(sizeof(ExifRational));
2638                         if (b) {
2639                                 if (f_altitude < 0) {
2640                                         alt_ref = 1;
2641                                         f_altitude = -f_altitude;
2642                                 }
2643
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) {
2649                                                 free(b);
2650                                                 b = NULL;
2651                                                 goto exit;
2652                                         }
2653                                 }
2654
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);
2660                                 free(b);
2661                                 if (ret != MM_ERROR_NONE) {
2662                                         EXIF_SET_ERR(ret, EXIF_TAG_GPS_ALTITUDE);
2663                                 }
2664                         } else {
2665                                 _mmcam_dbg_warn("malloc failed");
2666                         }
2667                 }
2668
2669                 /*44. EXIF_TAG_GPS_TIME_STAMP*/
2670                 {
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;
2676                                 unsigned int hour;
2677                                 unsigned int min;
2678                                 unsigned int microsec;
2679                                 ExifRational rData;
2680
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);
2684
2685                                 _mmcam_dbg_log("Gps timestamp hour[%d], min[%d], microsec[%d]", hour, min, microsec);
2686                                 b = malloc(3 * sizeof(ExifRational));
2687                                 if (b) {
2688                                         rData.numerator = hour;
2689                                         rData.denominator = 1;
2690                                         exif_set_rational(b, exif_data_get_byte_order(ed), rData);
2691
2692                                         rData.numerator = min;
2693                                         rData.denominator = 1;
2694                                         exif_set_rational(b + 8, exif_data_get_byte_order(ed), rData);
2695
2696                                         rData.numerator = microsec;
2697                                         rData.denominator = 1000000;
2698                                         exif_set_rational(b + 16, exif_data_get_byte_order(ed), rData);
2699
2700                                         ret = mm_exif_set_add_entry(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_TIME_STAMP,
2701                                                                     EXIF_FORMAT_RATIONAL, 3, b);
2702                                         free(b);
2703                                         if (ret != MM_ERROR_NONE) {
2704                                                 EXIF_SET_ERR(ret, EXIF_TAG_GPS_TIME_STAMP);
2705                                         }
2706                                 } else {
2707                                         _mmcam_dbg_warn( "malloc failed." );
2708                                 }
2709                         }
2710                 }
2711
2712                 /*45. EXIF_TAG_GPS_DATE_STAMP*/
2713                 {
2714                         unsigned char *date_stamp = NULL;
2715                         int date_stamp_len = 0;
2716
2717                         mm_camcorder_get_attributes(handle, NULL, "tag-gps-date-stamp", &date_stamp, &date_stamp_len, NULL);
2718
2719                         if (date_stamp) {
2720                                 _mmcam_dbg_log("Date stamp [%s]", date_stamp);
2721
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);
2727                                 }
2728                         }
2729                 }
2730
2731                 /*46. EXIF_TAG_GPS_PROCESSING_METHOD */
2732                 {
2733                         unsigned char *processing_method = NULL;
2734                         int processing_method_len = 0;
2735
2736                         mm_camcorder_get_attributes(handle, NULL, "tag-gps-processing-method", &processing_method, &processing_method_len, NULL);
2737
2738                         if (processing_method) {
2739                                 _mmcam_dbg_log("Processing method [%s]", processing_method);
2740
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);
2745                                 }
2746                         }
2747                 }
2748         } else {
2749                 _mmcam_dbg_log( "Tag for GPS is DISABLED." );
2750         }
2751
2752
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);
2758         }
2759
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);
2764         } else {
2765                 _mmcam_dbg_log("Samsung makernote created");
2766
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);
2771                 }
2772         /*
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);
2776                 }
2777
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);
2781                 }
2782
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);
2786                 }
2787         */
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);
2791                 }
2792         /*
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);
2796                 }
2797         */
2798         }
2799
2800         _mmcam_dbg_log("");
2801
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);
2805         }
2806
2807 exit:
2808         _mmcam_dbg_log("finished!! [%x]", ret);
2809
2810         if (ed) {
2811                 exif_data_unref (ed);
2812         }
2813
2814         return ret;
2815 }