Tizen 2.1 base
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_gstcommon.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 <gst/interfaces/xoverlay.h>
26 #include <gst/interfaces/cameracontrol.h>
27 #include <sys/time.h>
28 #include <unistd.h>
29
30 #include "mm_camcorder_internal.h"
31 #include "mm_camcorder_gstcommon.h"
32
33 /*-----------------------------------------------------------------------
34 |    GLOBAL VARIABLE DEFINITIONS for internal                           |
35 -----------------------------------------------------------------------*/
36 /* Table for compatibility between audio codec and file format */
37 gboolean        audiocodec_fileformat_compatibility_table[MM_AUDIO_CODEC_NUM][MM_FILE_FORMAT_NUM] =
38 {          /* 3GP ASF AVI MATROSKA MP4 OGG NUT QT REAL AMR AAC MP3 AIFF AU WAV MID MMF DIVX FLV VOB IMELODY WMA WMV JPG */
39 /*AMR*/       { 1,  0,  0,       0,  0,  0,  0, 0,   0,  1,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
40 /*G723.1*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
41 /*MP3*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
42 /*OGG*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
43 /*AAC*/       { 1,  0,  1,       1,  1,  0,  0, 0,   0,  0,  1,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
44 /*WMA*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
45 /*MMF*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
46 /*ADPCM*/     { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
47 /*WAVE*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  1,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
48 /*WAVE_NEW*/  { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
49 /*MIDI*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
50 /*IMELODY*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
51 /*MXMF*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
52 /*MPA*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
53 /*MP2*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
54 /*G711*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
55 /*G722*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
56 /*G722.1*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
57 /*G722.2*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
58 /*G723*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
59 /*G726*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
60 /*G728*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
61 /*G729*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
62 /*G729A*/     { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
63 /*G729.1*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
64 /*REAL*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
65 /*AAC_LC*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
66 /*AAC_MAIN*/  { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
67 /*AAC_SRS*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
68 /*AAC_LTP*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
69 /*AAC_HE_V1*/ { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
70 /*AAC_HE_V2*/ { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
71 /*AC3*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
72 /*ALAC*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
73 /*ATRAC*/     { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
74 /*SPEEX*/     { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
75 /*VORBIS*/    { 0,  0,  0,       0,  0,  1,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
76 /*AIFF*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
77 /*AU*/        { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
78 /*NONE*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
79 /*PCM*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
80 /*ALAW*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
81 /*MULAW*/     { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
82 /*MS_ADPCM*/  { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
83 };
84
85 /* Table for compatibility between video codec and file format */
86 gboolean        videocodec_fileformat_compatibility_table[MM_VIDEO_CODEC_NUM][MM_FILE_FORMAT_NUM] =
87 {             /* 3GP ASF AVI MATROSKA MP4 OGG NUT QT REAL AMR AAC MP3 AIFF AU WAV MID MMF DIVX FLV VOB IMELODY WMA WMV JPG */
88 /*NONE*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
89 /*H263*/         { 1,  0,  1,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
90 /*H264*/         { 1,  0,  1,       1,  1,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
91 /*H26L*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
92 /*MPEG4*/        { 1,  0,  1,       1,  1,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
93 /*MPEG1*/        { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
94 /*WMV*/          { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
95 /*DIVX*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
96 /*XVID*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
97 /*H261*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
98 /*H262*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
99 /*H263V2*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
100 /*H263V3*/       { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
101 /*MJPEG*/        { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
102 /*MPEG2*/        { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
103 /*MPEG4_SIMPLE*/ { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
104 /*MPEG4_ADV*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
105 /*MPEG4_MAIN*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
106 /*MPEG4_CORE*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
107 /*MPEG4_ACE*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
108 /*MPEG4_ARTS*/   { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
109 /*MPEG4_AVC*/    { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
110 /*REAL*/         { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
111 /*VC1*/          { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
112 /*AVS*/          { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
113 /*CINEPAK*/      { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
114 /*INDEO*/        { 0,  0,  0,       0,  0,  0,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
115 /*THEORA*/       { 0,  0,  0,       0,  0,  1,  0, 0,   0,  0,  0,  0,   0, 0,  0,  0,  0,   0,  0,  0,      0,  0,  0,  0,  },
116 };
117
118
119 /*-----------------------------------------------------------------------
120 |    LOCAL VARIABLE DEFINITIONS for internal                            |
121 -----------------------------------------------------------------------*/
122 #define USE_AUDIO_CLOCK_TUNE
123 #define _MMCAMCORDER_WAIT_EOS_TIME      5.0             //sec
124
125 /*-----------------------------------------------------------------------
126 |    LOCAL FUNCTION PROTOTYPES:                                         |
127 -----------------------------------------------------------------------*/
128 /* STATIC INTERNAL FUNCTION */
129 /**
130  * These functions are preview video data probing function.
131  * If this function is linked with certain pad by gst_pad_add_buffer_probe(),
132  * this function will be called when data stream pass through the pad.
133  *
134  * @param[in]   pad             probing pad which calls this function.
135  * @param[in]   buffer          buffer which contains stream data.
136  * @param[in]   u_data          user data.
137  * @return      This function returns true on success, or false value with error
138  * @remarks
139  * @see         __mmcamcorder_create_preview_pipeline()
140  */
141 static gboolean __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstBuffer *buffer, gpointer u_data);
142
143 static int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate);
144
145 /*=======================================================================================
146 |  FUNCTION DEFINITIONS                                                                 |
147 =======================================================================================*/
148 /*-----------------------------------------------------------------------
149 |    GLOBAL FUNCTION DEFINITIONS:                                       |
150 -----------------------------------------------------------------------*/
151 int _mmcamcorder_create_videosrc_bin(MMHandleType handle)
152 {
153         int err = MM_ERROR_NONE;
154         int rotate = 0;
155         int flip = 0;
156         int fps = 0;
157         int hold_af = 0;
158         int UseVideoscale = 0;
159         int codectype = 0;
160         int capture_width = 0;
161         int capture_height = 0;
162         int capture_jpg_quality = 100;
163         int video_stabilization = 0;
164         int anti_shake = 0;
165         char *videosrc_name = NULL;
166         char *err_name = NULL;
167
168         GList *element_list = NULL;
169         GstCaps *caps = NULL;
170         GstPad *video_tee0 = NULL;
171         GstPad *video_tee1 = NULL;
172
173         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
174         _MMCamcorderSubContext *sc = NULL;
175         type_element *VideosrcElement = NULL;
176         type_int_array *input_index = NULL;
177
178         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
179
180         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
181         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
182         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
183
184         _mmcam_dbg_log("");
185
186         /* Check existence */
187         if (sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst) {
188                 if (((GObject *)sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst)->ref_count > 0) {
189                         gst_object_unref(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst);
190                 }
191                 _mmcam_dbg_log("_MMCAMCORDER_VIDEOSRC_BIN is Already existed.");
192         }
193
194         /* Get video device index info */
195         _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
196                                               CONFIGURE_CATEGORY_CTRL_CAMERA,
197                                               "InputIndex",
198                                               &input_index );
199         if (input_index == NULL) {
200                 _mmcam_dbg_err("Failed to get input_index");
201                 return MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
202         }
203
204         err = mm_camcorder_get_attributes(handle, &err_name,
205                                           MMCAM_CAMERA_FORMAT, &sc->info_image->preview_format,
206                                           MMCAM_CAMERA_FPS, &fps,
207                                           MMCAM_CAMERA_ROTATION, &rotate,
208                                           MMCAM_CAMERA_FLIP, &flip,
209                                           MMCAM_CAMERA_VIDEO_STABILIZATION, &video_stabilization,
210                                           MMCAM_CAMERA_ANTI_HANDSHAKE, &anti_shake,
211                                           MMCAM_CAPTURE_WIDTH, &capture_width,
212                                           MMCAM_CAPTURE_HEIGHT, &capture_height,
213                                           MMCAM_IMAGE_ENCODER, &codectype,
214                                           MMCAM_IMAGE_ENCODER_QUALITY, &capture_jpg_quality,
215                                           "camera-hold-af-after-capturing", &hold_af,
216                                           NULL);
217         if (err != MM_ERROR_NONE) {
218                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
219                 SAFE_FREE(err_name);
220                 return err;
221         }
222
223         /* Get fourcc from picture format */
224         sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codectype, hcamcorder->use_zero_copy_format);
225
226         /* Get videosrc element and its name from configure */
227         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
228                                       CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
229                                       "VideosrcElement",
230                                       &VideosrcElement);
231         _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
232
233         /* Create bin element */
234         __ta__("                videosrc_bin",
235         _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_VIDEOSRC_BIN, "videosrc_bin", err);
236         );
237
238         /* Create child element */
239         __ta__("                videosrc_src",
240         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_SRC, videosrc_name, "videosrc_src", element_list, err);
241         );
242         __ta__("                videosrc_capsfilter",
243         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_FILT, "capsfilter", "videosrc_filter", element_list, err);
244         );
245         __ta__("                videosrc_queue",
246         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_QUE, "queue", "videosrc_queue", element_list, err);
247         );
248
249         /* init high-speed-fps */
250         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", 0);
251
252         /* set capture size, quality and flip setting which were set before mm_camcorder_realize */
253         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", capture_width);
254         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", capture_height);
255         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-jpg-quality", capture_jpg_quality);
256
257         /* set camera flip */
258         _mmcamcorder_set_videosrc_flip(handle, flip);
259
260         /* set flush cache as FALSE */
261         if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ITLV_JPEG_UYVY) {
262                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "flush-cache", FALSE);
263         }
264
265         /* set video stabilization mode */
266         _mmcamcorder_set_videosrc_stabilization(handle, video_stabilization);
267
268         /* set anti handshake mode */
269         _mmcamcorder_set_videosrc_anti_shake(handle, anti_shake);
270
271         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
272                                         CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
273                                         "UseVideoscale",
274                                         &UseVideoscale);
275         if (UseVideoscale) {
276                 int set_width = 0;
277                 int set_height = 0;
278                 int scale_width = 0;
279                 int scale_height = 0;
280                 int scale_method = 0;
281                 char *videoscale_name = NULL;
282                 type_element *VideoscaleElement = NULL;
283
284                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
285                                               CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
286                                               "VideoscaleElement",
287                                               &VideoscaleElement);
288                 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &videoscale_name);
289                 __ta__("                videosrc_scale",
290                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_SCALE, videoscale_name, "videosrc_scale", element_list, err);
291                 );
292                 __ta__("                videoscale_capsfilter",
293                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_VSFLT, "capsfilter", "videosrc_scalefilter", element_list, err);
294                 );
295
296                 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "width", &scale_width);
297                 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "height", &scale_height);
298                 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "method", &scale_method);
299
300                 if (rotate == MM_VIDEO_INPUT_ROTATION_90 ||
301                         rotate == MM_VIDEO_INPUT_ROTATION_270) {
302                         set_width = scale_height;
303                         set_height = scale_width;
304                 } else {
305                         set_width = scale_width;
306                         set_height = scale_height;
307                 }
308
309                 _mmcam_dbg_log("VideoSRC Scale[%dx%d], Method[%d]", set_width, set_height, scale_method);
310
311                 caps = gst_caps_new_simple("video/x-raw-yuv",
312                                            "format", GST_TYPE_FOURCC, sc->fourcc,
313                                            "width", G_TYPE_INT, set_width,
314                                            "height", G_TYPE_INT, set_height,
315                                            NULL);
316                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_VSFLT].gst, "caps", caps);
317                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SCALE].gst, "method", scale_method);
318
319                 gst_caps_unref(caps);
320                 caps = NULL;
321         }
322
323         if (sc->is_modified_rate) {
324                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", fps);
325         }
326
327         __ta__("                tee",
328         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_TEE, "tee", "videosrc_tee", element_list, err);
329         );
330
331         /* Set basic infomation of videosrc element */
332         _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, VideosrcElement);
333
334         /* Set video device index */
335         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "camera-id", input_index->default_value);
336         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hold-af-after-capturing", hold_af);
337
338         _mmcam_dbg_log("Current mode[%d]", hcamcorder->type);
339
340         /* Set sensor mode as CAMERA */
341         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "sensor-mode", 0);
342
343         /* Set caps by rotation */
344         _mmcamcorder_set_videosrc_rotation(handle, rotate);
345
346         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst), element_list)) {
347                 _mmcam_dbg_err( "element add error." );
348                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
349                 goto pipeline_creation_error;
350         }
351
352         if (!_mmcamcorder_link_elements(element_list)) {
353                 _mmcam_dbg_err( "element link error." );
354                 err = MM_ERROR_CAMCORDER_GST_LINK;
355                 goto pipeline_creation_error;
356         }
357
358         video_tee0 = gst_element_get_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src%d");
359         video_tee1 = gst_element_get_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src%d");
360
361         MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst), "alloc-pad", video_tee0);
362
363         /* Ghost pad */
364         if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, gst_ghost_pad_new("src0", video_tee0) )) < 0) {
365                 _mmcam_dbg_err("failed to create ghost pad1 on _MMCAMCORDER_VIDEOSRC_BIN.");
366                 gst_object_unref(video_tee0);
367                 video_tee0 = NULL;
368                 gst_object_unref(video_tee1);
369                 video_tee1 = NULL;
370                 err = MM_ERROR_CAMCORDER_GST_LINK;
371                 goto pipeline_creation_error;
372         }
373
374         if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, gst_ghost_pad_new("src1", video_tee1) )) < 0) {
375                 _mmcam_dbg_err("failed to create ghost pad2 on _MMCAMCORDER_VIDEOSRC_BIN.");
376                 gst_object_unref(video_tee0);
377                 video_tee0 = NULL;
378                 gst_object_unref(video_tee1);
379                 video_tee1 = NULL;
380                 err = MM_ERROR_CAMCORDER_GST_LINK;
381                 goto pipeline_creation_error;
382         }
383
384         gst_object_unref(video_tee0);
385         video_tee0 = NULL;
386         gst_object_unref(video_tee1);
387         video_tee1 = NULL;
388
389         if (element_list) {
390                 g_list_free(element_list);
391                 element_list = NULL;
392         }
393
394         return MM_ERROR_NONE;
395
396 pipeline_creation_error:
397         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_SRC );
398         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_FILT );
399         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_SCALE );
400         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_VSFLT );
401         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_TEE );
402         _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_BIN );
403         if (element_list) {
404                 g_list_free(element_list);
405                 element_list = NULL;
406         }
407
408         return err;
409 }
410
411
412 int _mmcamcorder_create_audiosrc_bin(MMHandleType handle)
413 {
414         int err = MM_ERROR_NONE;
415         int val = 0;
416         int rate = 0;
417         int format = 0;
418         int channel = 0;
419         int a_enc = MM_AUDIO_CODEC_AMR;
420         int a_dev = MM_AUDIO_DEVICE_MIC;
421         int UseNoiseSuppressor = 0;
422         double volume = 0.0;
423         char *err_name = NULL;
424         char *audiosrc_name = NULL;
425         char *cat_name = NULL;
426
427         GstCaps *caps = NULL;
428         GstPad *pad = NULL;
429         GList *element_list  = NULL;
430
431         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
432         _MMCamcorderSubContext *sc = NULL;
433         _MMCamcorderGstElement *last_element = NULL;
434         type_element *AudiosrcElement = NULL;
435
436         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
437
438         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
439         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
440         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
441
442         _mmcam_dbg_log("");
443
444         err = _mmcamcorder_check_audiocodec_fileformat_compatibility(handle);
445         if (err != MM_ERROR_NONE) {
446                 return err;
447         }
448
449         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
450                                         CONFIGURE_CATEGORY_MAIN_RECORD,
451                                         "UseNoiseSuppressor",
452                                         &UseNoiseSuppressor);
453
454         err = mm_camcorder_get_attributes(handle, &err_name,
455                                           MMCAM_AUDIO_DEVICE, &a_dev,
456                                           MMCAM_AUDIO_ENCODER, &a_enc,
457                                           MMCAM_AUDIO_ENCODER_BITRATE, &val,
458                                           MMCAM_AUDIO_SAMPLERATE, &rate,
459                                           MMCAM_AUDIO_FORMAT, &format,
460                                           MMCAM_AUDIO_CHANNEL, &channel,
461                                           MMCAM_AUDIO_VOLUME, &volume,
462                                           NULL);
463         if (err != MM_ERROR_NONE) {
464                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
465                 SAFE_FREE(err_name);
466                 return err;
467         }
468
469         /* Check existence */
470         if (sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst) {
471                 if (((GObject *)sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst)->ref_count > 0) {
472                         gst_object_unref(sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst);
473                 }
474                 _mmcam_dbg_log("_MMCAMCORDER_AUDIOSRC_BIN is Already existed. Unref once...");
475         }
476
477         /* Create bin element */
478         __ta__("                audiosource_bin",
479         _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_AUDIOSRC_BIN, "audiosource_bin", err);
480         );
481
482         if (a_dev == MM_AUDIO_DEVICE_MODEM) {
483                 cat_name = strdup("AudiomodemsrcElement");
484         } else {
485                 /* MM_AUDIO_DEVICE_MIC or others */
486                 cat_name = strdup("AudiosrcElement");
487         }
488
489         if (cat_name == NULL) {
490                 _mmcam_dbg_err("strdup failed.");
491                 err = MM_ERROR_CAMCORDER_LOW_MEMORY;
492                 goto pipeline_creation_error;
493         }
494
495         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
496                                       CONFIGURE_CATEGORY_MAIN_AUDIO_INPUT,
497                                       cat_name,
498                                       &AudiosrcElement);
499         _mmcamcorder_conf_get_value_element_name(AudiosrcElement, &audiosrc_name);
500
501         free(cat_name);
502         cat_name = NULL;
503
504         _mmcam_dbg_log("Audio src name : %s", audiosrc_name);
505
506         __ta__("                audiosrc",
507         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_SRC, audiosrc_name, NULL, element_list, err);
508         );
509
510         _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_AUDIOSRC_SRC].gst, AudiosrcElement);
511
512         __ta__("                audiosource_capsfilter",
513         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_FILT, "capsfilter", NULL, element_list, err);
514         );
515
516         if (a_enc != MM_AUDIO_CODEC_VORBIS) {
517                 __ta__("                audiosource_volume",
518                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_VOL, "volume", NULL, element_list, err);
519                 );
520         }
521
522         if (UseNoiseSuppressor && a_enc != MM_AUDIO_CODEC_AAC) {
523                 __ta__("                noise_suppressor",
524                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_NS, "noisesuppressor", "audiofilter", element_list, err);
525                 );
526         }
527
528         /* Set basic infomation */
529         if (a_enc != MM_AUDIO_CODEC_VORBIS) {
530                 int depth = 0;
531
532                 if (volume == 0.0) {
533                         /* Because data probe of audio src do the same job, it doesn't need to set "mute" here. Already null raw data. */
534                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "volume", 1.0);
535                 } else {
536                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "mute", FALSE);
537                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "volume", volume);
538                 }
539
540                 if (format == MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE) {
541                         depth = 16;
542                 } else { /* MM_CAMCORDER_AUDIO_FORMAT_PCM_U8 */
543                         depth = 8;
544                 }
545
546                 caps = gst_caps_new_simple("audio/x-raw-int",
547                                            "rate", G_TYPE_INT, rate,
548                                            "channels", G_TYPE_INT, channel,
549                                            "depth", G_TYPE_INT, depth,
550                                            NULL);
551                 _mmcam_dbg_log("caps [x-raw-int,rate:%d,channel:%d,depth:%d]",
552                                rate, channel, depth);
553         } else {
554                 /* what are the audio encoder which should get audio/x-raw-float? */
555                 caps = gst_caps_new_simple("audio/x-raw-float",
556                                            "rate", G_TYPE_INT, rate,
557                                            "channels", G_TYPE_INT, channel,
558                                            "endianness", G_TYPE_INT, BYTE_ORDER,
559                                            "width", G_TYPE_INT, 32,
560                                            NULL);
561                 _mmcam_dbg_log("caps [x-raw-float,rate:%d,channel:%d,endianness:%d,width:32]",
562                                rate, channel, BYTE_ORDER);
563         }
564
565         MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_AUDIOSRC_FILT].gst), "caps", caps);
566         gst_caps_unref(caps);
567
568         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst), element_list)) {
569                 _mmcam_dbg_err("element add error.");
570                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
571                 goto pipeline_creation_error;
572         }
573
574         if (!_mmcamcorder_link_elements(element_list)) {
575                 _mmcam_dbg_err( "element link error." );
576                 err = MM_ERROR_CAMCORDER_GST_LINK;
577                 goto pipeline_creation_error;
578         }
579
580         last_element = (_MMCamcorderGstElement*)(g_list_last(element_list)->data);
581         pad = gst_element_get_static_pad(last_element->gst, "src");
582         if ((gst_element_add_pad( sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad) )) < 0) {
583                 gst_object_unref(pad);
584                 pad = NULL;
585                 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_AUDIOSRC_BIN.");
586                 err = MM_ERROR_CAMCORDER_GST_LINK;
587                 goto pipeline_creation_error;
588         }
589
590         gst_object_unref(pad);
591         pad = NULL;
592
593         if (element_list) {
594                 g_list_free(element_list);
595                 element_list = NULL;
596         }
597
598         return MM_ERROR_NONE;
599
600 pipeline_creation_error:
601         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_SRC);
602         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_FILT);
603         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_VOL);
604         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_QUE);
605         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_CONV);
606         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_ENC);
607         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_BIN);
608         if (element_list) {
609                 g_list_free(element_list);
610                 element_list = NULL;
611         }
612
613         return err;
614 }
615
616
617 int _mmcamcorder_create_videosink_bin(MMHandleType handle)
618 {
619         int err = MM_ERROR_NONE;
620         int rect_width = 0;
621         int rect_height = 0;
622         int camera_width = 0;
623         int camera_height = 0;
624         int rotate = 0;
625         int flip = 0;
626         int UseVideoscale = 0, EnableConvertedSC = 0;
627         int scale_method = 0;
628         char* videosink_name = NULL;
629         char* videoscale_name = NULL;
630         char* err_name = NULL;
631
632         GstCaps *caps = NULL;
633         GstPad *pad = NULL;
634         GList *element_list = NULL;
635
636         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
637         _MMCamcorderSubContext *sc = NULL;
638         _MMCamcorderGstElement *first_element = NULL;
639         type_element *VideoscaleElement = NULL;
640
641         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
642         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
643
644         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
645         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
646
647         _mmcam_dbg_log("START");
648
649         /* Get attributes */
650         err = mm_camcorder_get_attributes(handle, &err_name,
651                                           MMCAM_CAMERA_WIDTH, &camera_width,
652                                           MMCAM_CAMERA_HEIGHT, &camera_height,
653                                           MMCAM_DISPLAY_RECT_WIDTH, &rect_width,
654                                           MMCAM_DISPLAY_RECT_HEIGHT, &rect_height,
655                                           MMCAM_DISPLAY_ROTATION, &rotate,
656                                           MMCAM_DISPLAY_FLIP, &flip,
657                                           "enable-converted-stream-callback", &EnableConvertedSC,
658                                           NULL);
659         if (err != MM_ERROR_NONE) {
660                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
661                 SAFE_FREE(err_name);
662                 return err;
663         }
664
665         /* Get videosink name */
666         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
667
668         /* Check existence */
669         if (sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst) {
670                 if (((GObject *)sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst)->ref_count > 0) {
671                         gst_object_unref(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst);
672                 }
673                 _mmcam_dbg_log("_MMCAMCORDER_VIDEOSINK_BIN is Already existed. Unref once...");
674         }
675
676         /* Create bin element */
677         __ta__("                videosink_bin",
678         _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_VIDEOSINK_BIN, "videosink_bin", err);
679         );
680
681         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
682                                         CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
683                                         "UseVideoscale",
684                                         &UseVideoscale);
685
686         /* Create child element */
687         if (EnableConvertedSC ||
688             !strcmp(videosink_name, "evasimagesink") ||
689             !strcmp(videosink_name, "ximagesink")) {
690                 GstElementFactory *factory = gst_element_factory_find("fimcconvert");
691
692                 if ((sc->fourcc == GST_MAKE_FOURCC('S','N','2','1') ||
693                      sc->fourcc == GST_MAKE_FOURCC('S','N','1','2') ||
694                      sc->fourcc == GST_MAKE_FOURCC('S','T','1','2') ||
695                      sc->fourcc == GST_MAKE_FOURCC('S','4','2','0')) &&
696                     factory) {
697                         int set_rotate = 0;
698                         int set_flip = 0;
699
700                         gst_object_unref(factory);
701                         factory = NULL;
702
703                         __ta__("                videosink_fimcconvert",
704                         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_CLS, "fimcconvert", NULL, element_list, err);
705                         );
706
707                         /* set rotate */
708                         if (rotate > MM_VIDEO_INPUT_ROTATION_NONE &&
709                             rotate < MM_VIDEO_INPUT_ROTATION_NUM) {
710                                 set_rotate = rotate * 90;
711                         } else {
712                                 set_rotate = 0;
713                         }
714
715                         if (rect_width == 0 || rect_height == 0) {
716                                 _mmcam_dbg_warn("rect_width or height is 0. set camera width and height.");
717
718                                 if (rotate == MM_DISPLAY_ROTATION_90 ||
719                                     rotate == MM_DISPLAY_ROTATION_270) {
720                                         rect_width = camera_height;
721                                         rect_height = camera_width;
722                                 } else {
723                                         rect_width = camera_width;
724                                         rect_height = camera_height;
725                                 }
726                         }
727
728                         /* set flip */
729                         switch (flip) {
730                         case MM_FLIP_HORIZONTAL:
731                                 set_flip = FIMCCONVERT_FLIP_HORIZONTAL;
732                                 break;
733                         case MM_FLIP_VERTICAL:
734                                 set_flip = FIMCCONVERT_FLIP_VERTICAL;
735                                 break;
736                         case MM_FLIP_BOTH: /* both flip has same effect with 180 rotation */
737                                 set_rotate = (set_rotate + 180) % 360;
738                         case MM_FLIP_NONE:
739                         default:
740                                 set_flip = FIMCCONVERT_FLIP_NONE;
741                                 break;
742                         }
743
744                         _mmcam_dbg_log("Fimcconvert set values - %dx%d, rotate: %d, flip: %d",
745                                        rect_width, rect_height, set_rotate, set_flip);
746
747                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "src-width", rect_width);
748                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "src-height", rect_height);
749                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "rotate", set_rotate);
750                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "flip", set_flip);
751                 } else {
752                         if (factory) {
753                                 gst_object_unref(factory);
754                                 factory = NULL;
755                         }
756
757                         __ta__("                videosink_ffmpegcolorspace",
758                         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_CLS, "ffmpegcolorspace", NULL, element_list, err);
759                         );
760                 }
761         } else if(UseVideoscale) {
762                 __ta__("                videosink_queue",
763                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_QUE, "queue", NULL, element_list, err);
764                 );
765
766                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
767                                               CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
768                                               "VideoscaleElement",
769                                               &VideoscaleElement);
770                 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &videoscale_name);
771
772                 __ta__("                videosink_videoscale",
773                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_SCALE, videoscale_name, NULL, element_list, err);
774                 );
775                 __ta__("                videosink_capsfilter",
776                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_FILT, "capsfilter", NULL, element_list, err);
777                 );
778
779                 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "method", &scale_method);
780                 _mmcam_dbg_log("VideoSINK Scale[%dx%d], Method[%d]", rect_width, rect_height, scale_method);
781
782                 if (rect_width == 0 || rect_height == 0) {
783                         _mmcam_dbg_warn("rect_width or height is 0. set camera width and height.");
784
785                         rect_width = camera_width;
786                         rect_height = camera_height;
787                 }
788
789                 caps = gst_caps_new_simple("video/x-raw-yuv",
790                                            "width", G_TYPE_INT, rect_width,
791                                            "height", G_TYPE_INT, rect_height,
792                                            NULL);
793                 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSINK_FILT].gst), "caps", caps);
794                 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSINK_SCALE].gst), "method", scale_method);
795                 gst_caps_unref(caps);
796                 caps = NULL;
797         }
798
799         if (sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst == NULL) {
800                 __ta__("                videosink_queue",
801                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_QUE, "queue", "videosink_queue", element_list, err);
802                 );
803         }
804
805         __ta__("                videosink",
806         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, NULL, element_list, err);
807         );
808
809         if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "ximagesink") ||
810             !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) {
811                 if (_mmcamcorder_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) {
812                         _mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
813                         err = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
814                         goto pipeline_creation_error;
815                 }
816         }
817
818         _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement);
819
820         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst), element_list)) {
821                 _mmcam_dbg_err("element add error.");
822                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
823                 goto pipeline_creation_error;
824         }
825
826         if (!_mmcamcorder_link_elements(element_list)) {
827                 _mmcam_dbg_err("element link error.");
828                 err = MM_ERROR_CAMCORDER_GST_LINK;
829                 goto pipeline_creation_error;
830         }
831
832         first_element = (_MMCamcorderGstElement*)(element_list->data);
833         __ta__("                gst_element_get_static_pad",
834         pad = gst_element_get_static_pad( first_element->gst, "sink");
835         );
836         if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst, gst_ghost_pad_new("sink", pad) )) < 0) {
837                 gst_object_unref(pad);
838                 pad = NULL;
839                 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_VIDEOSINK_BIN.");
840                 err = MM_ERROR_CAMCORDER_GST_LINK;
841                 goto pipeline_creation_error;
842         }
843
844         gst_object_unref(pad);
845         pad = NULL;
846
847         if (element_list) {
848                 g_list_free(element_list);
849                 element_list = NULL;
850         }
851
852         _mmcam_dbg_log("END");
853
854         return MM_ERROR_NONE;
855
856 pipeline_creation_error:
857         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_QUE);
858         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_SCALE);
859         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_FILT);
860         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_CLS);
861         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_SINK);
862         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_BIN);
863         if (element_list) {
864                 g_list_free(element_list);
865                 element_list = NULL;
866         }
867
868         return err;
869 }
870
871
872 int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebinProfile profile)
873 {
874         int err = MM_ERROR_NONE;
875         int result = 0;
876         int channel = 0;
877         int audio_enc = 0;
878         int v_bitrate = 0;
879         int a_bitrate = 0;
880         int encodebin_profile = 0;
881         int auto_audio_convert = 0;
882         int auto_audio_resample = 0;
883         int auto_color_space = 0;
884         char *gst_element_venc_name = NULL;
885         char *gst_element_aenc_name = NULL;
886         char *gst_element_ienc_name = NULL;
887         char *gst_element_mux_name = NULL;
888         char *gst_element_rsink_name = NULL;
889         char *str_profile = NULL;
890         char *str_aac = NULL;
891         char *str_aar = NULL;
892         char *str_acs = NULL;
893         char *err_name = NULL;
894
895         GstCaps *caps = NULL;
896         GstPad *pad = NULL;
897         GList *element_list = NULL;
898
899         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
900         _MMCamcorderSubContext *sc = NULL;
901         type_element *VideoencElement = NULL;
902         type_element *AudioencElement = NULL;
903         type_element *ImageencElement = NULL;
904         type_element *MuxElement = NULL;
905         type_element *RecordsinkElement = NULL;
906
907         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
908
909         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
910         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
911         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
912
913         _mmcam_dbg_log("");
914
915         /* Check existence */
916         if (sc->element[_MMCAMCORDER_ENCSINK_BIN].gst) {
917                 if (((GObject *)sc->element[_MMCAMCORDER_ENCSINK_BIN].gst)->ref_count > 0) {
918                         gst_object_unref(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
919                 }
920                 _mmcam_dbg_log("_MMCAMCORDER_ENCSINK_BIN is Already existed.");
921         }
922
923         /* Create bin element */
924         __ta__("                encodesink_bin",
925         _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_ENCSINK_BIN, "encodesink_bin", err);
926         );
927
928         /* Create child element */
929         __ta__("                encodebin",
930         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_ENCBIN, "encodebin", NULL, element_list, err);
931         );
932
933         /* check element availability */
934         mm_camcorder_get_attributes(handle, &err_name,
935                                     MMCAM_AUDIO_ENCODER, &audio_enc,
936                                     MMCAM_AUDIO_CHANNEL, &channel,
937                                     MMCAM_VIDEO_ENCODER_BITRATE, &v_bitrate,
938                                     MMCAM_AUDIO_ENCODER_BITRATE, &a_bitrate,
939                                     NULL);
940
941         _mmcam_dbg_log("Profile[%d]", profile);
942
943         /* Set information */
944         if (profile == MM_CAMCORDER_ENCBIN_PROFILE_VIDEO) {
945                 str_profile = "VideoProfile";
946                 str_aac = "VideoAutoAudioConvert";
947                 str_aar = "VideoAutoAudioResample";
948                 str_acs = "VideoAutoColorSpace";
949         } else if (profile == MM_CAMCORDER_ENCBIN_PROFILE_AUDIO) {
950                 str_profile = "AudioProfile";
951                 str_aac = "AudioAutoAudioConvert";
952                 str_aar = "AudioAutoAudioResample";
953                 str_acs = "AudioAutoColorSpace";
954         } else if (profile == MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
955                 str_profile = "ImageProfile";
956                 str_aac = "ImageAutoAudioConvert";
957                 str_aar = "ImageAutoAudioResample";
958                 str_acs = "ImageAutoColorSpace";
959         }
960
961         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_profile, &encodebin_profile);
962         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_aac, &auto_audio_convert);
963         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_aar, &auto_audio_resample);
964         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_acs, &auto_color_space);
965
966         _mmcam_dbg_log("Profile:%d, AutoAudioConvert:%d, AutoAudioResample:%d, AutoColorSpace:%d",
967                        encodebin_profile, auto_audio_convert, auto_audio_resample, auto_color_space);
968
969         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "profile", encodebin_profile);
970         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", auto_audio_convert);
971         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", auto_audio_resample);
972         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", auto_color_space);
973         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", FALSE);
974
975         /* Codec */
976         if (profile == MM_CAMCORDER_ENCBIN_PROFILE_VIDEO) {
977                 int use_venc_queue = 0;
978
979                 VideoencElement = _mmcamcorder_get_type_element(handle, MM_CAM_VIDEO_ENCODER);
980
981                 if (!VideoencElement) {
982                         _mmcam_dbg_err("Fail to get type element");
983                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
984                         goto pipeline_creation_error;
985                 }
986
987                 _mmcamcorder_conf_get_value_element_name(VideoencElement, &gst_element_venc_name);
988
989                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "venc-name", gst_element_venc_name);
990                 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_VENC, "video-encode", err);
991
992                 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
993                                                 CONFIGURE_CATEGORY_MAIN_RECORD,
994                                                 "UseVideoEncoderQueue",
995                                                 &use_venc_queue);
996                 if (use_venc_queue) {
997                         _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_VENC_QUE, "use-venc-queue", err);
998                 }
999         }
1000
1001         if (sc->audio_disable == FALSE &&
1002             profile != MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
1003                 int use_aenc_queue =0;
1004
1005                 AudioencElement = _mmcamcorder_get_type_element(handle, MM_CAM_AUDIO_ENCODER);
1006                 if (!AudioencElement) {
1007                         _mmcam_dbg_err("Fail to get type element");
1008                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1009                         goto pipeline_creation_error;
1010                 }
1011
1012                 _mmcamcorder_conf_get_value_element_name(AudioencElement, &gst_element_aenc_name);
1013
1014                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "aenc-name", gst_element_aenc_name);
1015                 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_AENC, "audio-encode", err);
1016
1017                 if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
1018                         caps = gst_caps_new_simple("audio/x-raw-int",
1019                                                    "channels", G_TYPE_INT, 1,
1020                                                    NULL);
1021                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
1022                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
1023                         gst_caps_unref (caps);
1024                         caps = NULL;
1025                 }
1026
1027                 if (audio_enc == MM_AUDIO_CODEC_OGG) {
1028                         caps = gst_caps_new_simple("audio/x-raw-int",
1029                                                    NULL);
1030                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
1031                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
1032                         gst_caps_unref (caps);
1033                         caps = NULL;
1034                         _mmcam_dbg_log("***** MM_AUDIO_CODEC_OGG : setting audio/x-raw-int ");
1035                 }
1036
1037                 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
1038                                                 CONFIGURE_CATEGORY_MAIN_RECORD,
1039                                                 "UseAudioEncoderQueue",
1040                                                 &use_aenc_queue);
1041                 if (use_aenc_queue) {
1042                         _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
1043                 }
1044         }
1045
1046         if (profile == MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
1047                 ImageencElement = _mmcamcorder_get_type_element(handle, MM_CAM_IMAGE_ENCODER);
1048                 if (!ImageencElement) {
1049                         _mmcam_dbg_err("Fail to get type element");
1050                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1051                         goto pipeline_creation_error;
1052                 }
1053
1054                 _mmcamcorder_conf_get_value_element_name(ImageencElement, &gst_element_ienc_name);
1055
1056                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "ienc-name", gst_element_ienc_name);
1057                 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_IENC, "image-encode", err);
1058         }
1059
1060         /* Mux */
1061         if (profile != MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
1062                 MuxElement = _mmcamcorder_get_type_element(handle, MM_CAM_FILE_FORMAT);
1063                 if (!MuxElement) {
1064                         _mmcam_dbg_err("Fail to get type element");
1065                         err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1066                         goto pipeline_creation_error;
1067                 }
1068
1069                 _mmcamcorder_conf_get_value_element_name(MuxElement, &gst_element_mux_name);
1070
1071                 __ta__("                mux",
1072                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "mux-name", gst_element_mux_name);
1073                 );
1074                 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_MUX, "mux", err);
1075
1076                 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst, MuxElement);
1077         }
1078
1079         /* Sink */
1080         if (profile != MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
1081                 /* for recording */
1082                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1083                                               CONFIGURE_CATEGORY_MAIN_RECORD,
1084                                               "RecordsinkElement",
1085                                               &RecordsinkElement );
1086                 _mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
1087
1088                 __ta__("                Recordsink_sink",
1089                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_SINK, gst_element_rsink_name, NULL, element_list, err);
1090                 );
1091
1092                 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, RecordsinkElement);
1093         } else {
1094                 /* for stillshot */
1095                 __ta__("                fakesink",
1096                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_SINK, "fakesink", NULL, element_list, err);
1097                 );
1098         }
1099
1100         if (profile == MM_CAMCORDER_ENCBIN_PROFILE_VIDEO) {
1101                 /* video encoder attribute setting */
1102                 if (v_bitrate > 0) {
1103                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
1104                 } else {
1105                         _mmcam_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
1106                 }
1107                 /*MMCAMCORDER_G_OBJECT_SET ((sc->element[_MMCAMCORDER_ENCSINK_VENC].gst),"hw-accel", v_hw);*/
1108                 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_VENC].gst, VideoencElement);
1109         }
1110
1111         if (sc->audio_disable == FALSE &&
1112             profile != MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
1113                 /* audio encoder attribute setting */
1114                 if (a_bitrate > 0) {
1115                         switch (audio_enc) {
1116                         case MM_AUDIO_CODEC_AMR:
1117                                 result = __mmcamcorder_get_amrnb_bitrate_mode(a_bitrate);
1118                                 _mmcam_dbg_log("Set AMR encoder[%s] mode [%d]", gst_element_aenc_name, result);
1119                                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "band-mode", result);
1120                                 break;
1121                         case MM_AUDIO_CODEC_AAC:
1122                                 _mmcam_dbg_log("Set AAC encoder[%s] bitrate [%d]", gst_element_aenc_name, a_bitrate);
1123                                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
1124                                 break;
1125                         default:
1126                                 _mmcam_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
1127                                 break;
1128                         }
1129                 } else {
1130                         _mmcam_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
1131                 }
1132
1133                 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, AudioencElement);
1134         }
1135
1136         _mmcam_dbg_log("Element creation complete");
1137
1138         /* Add element to bin */
1139         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst), element_list)) {
1140                 _mmcam_dbg_err("element add error.");
1141                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1142                 goto pipeline_creation_error;
1143         }
1144
1145         _mmcam_dbg_log("Element add complete");
1146
1147         if (profile == MM_CAMCORDER_ENCBIN_PROFILE_VIDEO) {
1148                 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "video");
1149                 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
1150                         gst_object_unref(pad);
1151                         pad = NULL;
1152                         _mmcam_dbg_err("failed to create ghost video_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1153                         err = MM_ERROR_CAMCORDER_GST_LINK;
1154                         goto pipeline_creation_error;
1155                 }
1156                 gst_object_unref(pad);
1157                 pad = NULL;
1158
1159                 if (sc->audio_disable == FALSE) {
1160                         pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "audio");
1161                         if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
1162                                 gst_object_unref(pad);
1163                                 pad = NULL;
1164                                 _mmcam_dbg_err("failed to create ghost audio_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1165                                 err = MM_ERROR_CAMCORDER_GST_LINK;
1166                                 goto pipeline_creation_error;
1167                         }
1168                         gst_object_unref(pad);
1169                         pad = NULL;
1170                 }
1171         } else if (profile == MM_CAMCORDER_ENCBIN_PROFILE_AUDIO) {
1172                 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "audio");
1173                 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
1174                         gst_object_unref(pad);
1175                         pad = NULL;
1176                         _mmcam_dbg_err("failed to create ghost audio_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1177                         err = MM_ERROR_CAMCORDER_GST_LINK;
1178                         goto pipeline_creation_error;
1179                 }
1180                 gst_object_unref(pad);
1181                 pad = NULL;
1182         } else {
1183                 /* for stillshot */
1184                 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "image");
1185                 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
1186                         gst_object_unref(pad);
1187                         pad = NULL;
1188                         _mmcam_dbg_err("failed to create ghost image_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1189                         err = MM_ERROR_CAMCORDER_GST_LINK;
1190                         goto pipeline_creation_error;
1191                 }
1192                 gst_object_unref(pad);
1193                 pad = NULL;
1194         }
1195
1196         _mmcam_dbg_log("Get pad complete");
1197
1198         /* Link internal element */
1199         if (!_mmcamcorder_link_elements(element_list)) {
1200                 _mmcam_dbg_err("element link error.");
1201                 err = MM_ERROR_CAMCORDER_GST_LINK;
1202                 goto pipeline_creation_error;
1203         }
1204
1205         if (element_list) {
1206                 g_list_free(element_list);
1207                 element_list = NULL;
1208         }
1209
1210         return MM_ERROR_NONE;
1211
1212 pipeline_creation_error :
1213         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_ENCBIN);
1214         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_VENC);
1215         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_AENC);
1216         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_IENC);
1217         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_MUX);
1218         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_SINK);
1219         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_BIN);
1220         if (element_list) {
1221                 g_list_free(element_list);
1222                 element_list = NULL;
1223         }
1224
1225         return err;
1226 }
1227
1228
1229 int _mmcamcorder_create_stillshotsink_bin(MMHandleType handle)
1230 {
1231         int err = MM_ERROR_NONE;
1232         int capture_width  = 0;
1233         int capture_height = 0;
1234         int UseCaptureMode = 0;
1235         char *gst_element_ienc_name = NULL;
1236         char *gst_element_videoscale_name = NULL;
1237
1238         GList *element_list = NULL;
1239         GstPad *pad = NULL;
1240
1241         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1242         _MMCamcorderSubContext *sc = NULL;
1243         _MMCamcorderGstElement *first_element = NULL;
1244         type_element* ImageencElement   = NULL;
1245         type_element* VideoscaleElement = NULL;
1246
1247         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1248
1249         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1250         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1251         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1252
1253         _mmcam_dbg_log("");
1254
1255         /* Check existence */
1256         if (sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst) {
1257                 if (((GObject *)sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst)->ref_count > 0) {
1258                         gst_object_unref(sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst);
1259                 }
1260                 _mmcam_dbg_log("_MMCAMCORDER_STILLSHOTSINK_BIN is Already existed. Unref once...");
1261         }
1262
1263         /* Check element availability */
1264         ImageencElement = _mmcamcorder_get_type_element(handle, MM_CAM_IMAGE_ENCODER);
1265         if (!ImageencElement) {
1266                 _mmcam_dbg_err("Fail to get type element");
1267                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1268                 goto pipeline_creation_error;
1269         }
1270
1271         _mmcamcorder_conf_get_value_element_name(ImageencElement, &gst_element_ienc_name);
1272
1273         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
1274                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
1275                                         "UseCaptureMode",
1276                                         &UseCaptureMode);
1277
1278         /* Create bin element */
1279         __ta__("                stillshotsink_bin",
1280         _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_BIN, "stillshotsink_bin", err);
1281         );
1282
1283         /* Create child element */
1284         __ta__("                stillshotsink_queue",
1285         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_QUE, "queue", NULL, element_list, err);
1286         );
1287         __ta__("                stillshotsink_toggle",
1288         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_TOGGLE, "toggle", NULL, element_list, err);
1289         );
1290
1291         if (UseCaptureMode) {
1292                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1293                                               CONFIGURE_CATEGORY_MAIN_CAPTURE,
1294                                               "VideoscaleElement",
1295                                               &VideoscaleElement);
1296                 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &gst_element_videoscale_name);
1297
1298                 __ta__("                stillshotsink_videoscale",
1299                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_SCALE, "gst_element_videoscale_name", NULL, element_list, err);
1300                 );
1301                 __ta__("                stillshotsink_videocrop",
1302                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_CROP, "videocrop", NULL, element_list, err);
1303                 );
1304                 __ta__("                stillshotsink_capsfiltern",
1305                 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_FILT, "capsfilter", NULL, element_list, err);
1306                 );
1307         }
1308
1309         __ta__("                image encoder",
1310         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_ENC, gst_element_ienc_name, NULL, element_list, err);
1311         );
1312
1313         __ta__("                fakesink",
1314         _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_SINK, "fakesink", NULL, element_list, err);
1315         );
1316
1317         if (UseCaptureMode) {
1318                 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_STILLSHOTSINK_SCALE].gst, VideoscaleElement);
1319                 
1320                 /* Set property */
1321                 mm_camcorder_get_attributes(handle, NULL,
1322                                             MMCAM_CAPTURE_WIDTH, &capture_width,
1323                                             MMCAM_CAPTURE_HEIGHT, &capture_height,
1324                                             NULL);
1325
1326                 __ta__("                _mmcamcorder_set_resize_property",
1327                 err = _mmcamcorder_set_resize_property(handle, capture_width, capture_height);
1328                 );
1329                 if (err != MM_ERROR_NONE) {
1330                         //unref??
1331                         _mmcam_dbg_log("Set resize property failed.");
1332                         goto pipeline_creation_error;
1333                 }
1334         }
1335
1336         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst), element_list)) {
1337                 _mmcam_dbg_err( "element add error." );
1338                 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1339                 goto pipeline_creation_error;
1340         }
1341
1342         if (!_mmcamcorder_link_elements(element_list)) {
1343                 _mmcam_dbg_err( "element link error." );
1344                 err = MM_ERROR_CAMCORDER_GST_LINK;
1345                 goto pipeline_creation_error;
1346         }
1347
1348         first_element = (_MMCamcorderGstElement*)(element_list->data);
1349
1350         pad = gst_element_get_static_pad(first_element->gst, "sink");
1351         if (gst_element_add_pad( sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst, gst_ghost_pad_new("sink", pad)) < 0) {
1352                 gst_object_unref(pad);
1353                 pad = NULL;
1354                 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_STILLSHOTSINK_BIN.");
1355                 err = MM_ERROR_CAMCORDER_GST_LINK;
1356                 goto pipeline_creation_error;
1357         }
1358         gst_object_unref(pad);
1359         pad = NULL;
1360
1361         if (element_list) {
1362                 g_list_free(element_list);
1363                 element_list = NULL;
1364         }
1365
1366         return MM_ERROR_NONE;
1367
1368 pipeline_creation_error :
1369         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_QUE);
1370         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_TOGGLE);
1371         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_CROP);
1372         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_FILT);
1373         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_SCALE);
1374         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_ENC);
1375         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_SINK);
1376         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_BIN);
1377         if (element_list) {
1378                 g_list_free(element_list);
1379                 element_list = NULL;
1380         }
1381
1382         return err;
1383 }
1384
1385
1386 int _mmcamcorder_create_preview_pipeline(MMHandleType handle)
1387 {
1388         int err = MM_ERROR_NONE;
1389
1390         GstPad *srcpad = NULL;
1391         GstPad *sinkpad = NULL;
1392         GstBus *bus = NULL;
1393
1394         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1395         _MMCamcorderSubContext *sc = NULL;
1396
1397         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1398
1399         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1400         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1401         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1402
1403         _mmcam_dbg_log("");
1404
1405         /** Create gstreamer element **/
1406         /* Main pipeline */
1407         _MMCAMCORDER_PIPELINE_MAKE(sc, _MMCAMCORDER_MAIN_PIPE, "camcorder_pipeline", err);
1408
1409         /* Sub pipeline */
1410         __ta__("            __mmcamcorder_create_videosrc_bin",
1411         err = _mmcamcorder_create_videosrc_bin((MMHandleType)hcamcorder);
1412         );
1413         if (err != MM_ERROR_NONE ) {
1414                 goto pipeline_creation_error;
1415         }
1416
1417         __ta__("            _mmcamcorder_create_videosink_bin",
1418         err = _mmcamcorder_create_videosink_bin((MMHandleType)hcamcorder);
1419         );
1420         if (err != MM_ERROR_NONE ) {
1421                 goto pipeline_creation_error;
1422         }
1423
1424         gst_bin_add_many(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
1425                          sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst,
1426                          sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst,
1427                          NULL);
1428
1429         /* Link each element */
1430         srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, "src0");
1431         sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst, "sink");
1432         _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
1433
1434         /* Set data probe function */
1435         srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src");
1436         MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW,
1437                                      __mmcamcorder_video_dataprobe_preview, hcamcorder);
1438         gst_object_unref(srcpad);
1439         srcpad = NULL;
1440
1441         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
1442
1443         /* Register message callback */
1444         hcamcorder->pipeline_cb_event_id = gst_bus_add_watch(bus, _mmcamcorder_pipeline_cb_message, (gpointer)hcamcorder);
1445
1446         /* set sync handler */
1447         gst_bus_set_sync_handler(bus, _mmcamcorder_pipeline_bus_sync_callback, (gpointer)hcamcorder);
1448
1449         gst_object_unref(bus);
1450         bus = NULL;
1451
1452         /* Below signals are meaningfull only when video source is using. */
1453         MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
1454                                    _MMCAMCORDER_HANDLER_PREVIEW,
1455                                    "nego-complete",
1456                                    _mmcamcorder_negosig_handler,
1457                                    hcamcorder);
1458
1459         return MM_ERROR_NONE;
1460
1461 pipeline_creation_error:
1462         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSRC_BIN);
1463         _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_MAIN_PIPE);
1464         return err;
1465 }
1466
1467
1468 void _mmcamcorder_negosig_handler(GstElement *videosrc, MMHandleType handle)
1469 {
1470         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1471         _MMCamcorderSubContext *sc = NULL;
1472
1473         _mmcam_dbg_log("");
1474
1475         mmf_return_if_fail(hcamcorder);
1476         mmf_return_if_fail(hcamcorder->sub_context);
1477         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1478
1479         /* kernel was modified. No need to set.
1480         _mmcamcorder_set_attribute_to_camsensor(handle);
1481         */
1482
1483         if (sc->cam_stability_count != _MMCAMCORDER_CAMSTABLE_COUNT) {
1484                 sc->cam_stability_count = _MMCAMCORDER_CAMSTABLE_COUNT;
1485         }
1486
1487         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1488                 _MMCamcorderImageInfo *info = NULL;
1489                 info = sc->info_image;
1490                 if (info->resolution_change == TRUE) {
1491                         _mmcam_dbg_log("open toggle of stillshot sink.");
1492                         MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1493                         info->resolution_change = FALSE;
1494                 }
1495         }
1496 }
1497
1498
1499 int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* VideosinkElement)
1500 {
1501         int err = MM_ERROR_NONE;
1502         int size = 0;
1503         int retx = 0;
1504         int rety = 0;
1505         int retwidth = 0;
1506         int retheight = 0;
1507         int visible = 0;
1508         int rotation = MM_DISPLAY_ROTATION_NONE;
1509         int rotation_degree = 0;
1510         int flip = MM_FLIP_NONE;
1511         int display_mode = MM_DISPLAY_MODE_DEFAULT;
1512         int display_geometry_method = MM_DISPLAY_METHOD_LETTER_BOX;
1513         int origin_size = 0;
1514         int zoom_attr = 0;
1515         int zoom_level = 0;
1516         int do_scaling = FALSE;
1517         int *overlay = NULL;
1518         gulong xid;
1519         char *err_name = NULL;
1520         char *videosink_name = NULL;
1521
1522         GstElement *vsink = NULL;
1523
1524         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1525         _MMCamcorderSubContext *sc = NULL;
1526
1527         _mmcam_dbg_log("");
1528
1529         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1530
1531         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1532         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1533         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1534         mmf_return_val_if_fail(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1535
1536         vsink = sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst;
1537
1538         /* Get video display information */
1539         __ta__("                videosink get attributes",
1540         err = mm_camcorder_get_attributes(handle, &err_name,
1541                                           MMCAM_DISPLAY_RECT_X, &retx,
1542                                           MMCAM_DISPLAY_RECT_Y, &rety,
1543                                           MMCAM_DISPLAY_RECT_WIDTH, &retwidth,
1544                                           MMCAM_DISPLAY_RECT_HEIGHT, &retheight,
1545                                           MMCAM_DISPLAY_ROTATION, &rotation,
1546                                           MMCAM_DISPLAY_FLIP, &flip,
1547                                           MMCAM_DISPLAY_VISIBLE, &visible,
1548                                           MMCAM_DISPLAY_HANDLE, (void**)&overlay, &size,
1549                                           MMCAM_DISPLAY_MODE, &display_mode,
1550                                           MMCAM_DISPLAY_GEOMETRY_METHOD, &display_geometry_method,
1551                                           MMCAM_DISPLAY_SCALE, &zoom_attr,
1552                                           MMCAM_DISPLAY_EVAS_DO_SCALING, &do_scaling,
1553                                           NULL);
1554         );
1555
1556         _mmcam_dbg_log("(overlay=%p, size=%d)", overlay, size);
1557
1558         _mmcamcorder_conf_get_value_element_name(VideosinkElement, &videosink_name);
1559
1560         /* Set display handle */
1561         if (!strcmp(videosink_name, "xvimagesink") ||
1562             !strcmp(videosink_name, "ximagesink")) {
1563                 if (overlay) {
1564                         xid = *overlay;
1565                         _mmcam_dbg_log("xid = %lu )", xid);
1566                         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink), xid);
1567                 } else {
1568                         _mmcam_dbg_warn("Handle is NULL. Set xid as 0.. but, it's not recommended.");
1569                         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink), 0);
1570                 }
1571
1572                 _mmcam_dbg_log("%s set: display_geometry_method[%d],origin-size[%d],visible[%d],rotate[enum:%d]",
1573                                videosink_name, display_geometry_method, origin_size, visible, rotation);
1574         } else if (!strcmp(videosink_name, "evasimagesink") ||
1575                    !strcmp(videosink_name, "evaspixmapsink")) {
1576                 _mmcam_dbg_log("videosink : %s, handle : %p", videosink_name, overlay);
1577                 if (overlay) {
1578                         MMCAMCORDER_G_OBJECT_SET(vsink, "evas-object", overlay);
1579                         MMCAMCORDER_G_OBJECT_SET(vsink, "origin-size", !do_scaling);
1580                 } else {
1581                         _mmcam_dbg_err("display handle(eavs object) is NULL");
1582                         return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1583                 }
1584         } else {
1585                 _mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name);
1586         }
1587
1588         /* Set attribute */
1589         if (!strcmp(videosink_name, "xvimagesink") ||
1590             !strcmp(videosink_name, "evaspixmapsink")) {
1591
1592                 if (!strcmp(videosink_name, "xvimagesink")) {
1593                         /* set rotation */
1594                         switch (rotation) {
1595                         case MM_DISPLAY_ROTATION_NONE :
1596                                 rotation_degree = 0;
1597                                 break;
1598                         case MM_DISPLAY_ROTATION_90 :
1599                                 rotation_degree = 1;
1600                                 break;
1601                         case MM_DISPLAY_ROTATION_180 :
1602                                 rotation_degree = 2;
1603                                 break;
1604                         case MM_DISPLAY_ROTATION_270 :
1605                                 rotation_degree = 3;
1606                                 break;
1607                         default:
1608                                 _mmcam_dbg_warn("Unsupported rotation value. set as default(0).");
1609                                 rotation_degree = 0;
1610                                 break;
1611                         }
1612                         MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation_degree);
1613
1614                         /* set flip */
1615                         MMCAMCORDER_G_OBJECT_SET(vsink, "flip", flip);
1616
1617                         _mmcam_dbg_log("set videosink[%s] rotate %d, flip %d",
1618                                        videosink_name, rotation_degree, flip);
1619                 }
1620
1621                 switch (zoom_attr) {
1622                 case MM_DISPLAY_SCALE_DEFAULT:
1623                         zoom_level = 1;
1624                         break;
1625                 case MM_DISPLAY_SCALE_DOUBLE_LENGTH:
1626                         zoom_level = 2;
1627                         break;
1628                 case MM_DISPLAY_SCALE_TRIPLE_LENGTH:
1629                         zoom_level = 3;
1630                         break;
1631                 default:
1632                         _mmcam_dbg_warn("Unsupported zoom value. set as default.");
1633                         zoom_level = 1;
1634                         break;
1635                 }
1636
1637                 MMCAMCORDER_G_OBJECT_SET(vsink, "display-geometry-method", display_geometry_method);
1638                 MMCAMCORDER_G_OBJECT_SET(vsink, "display-mode", display_mode);
1639                 MMCAMCORDER_G_OBJECT_SET(vsink, "visible", visible);
1640                 MMCAMCORDER_G_OBJECT_SET(vsink, "zoom", zoom_level);
1641
1642                 if (display_geometry_method == MM_DISPLAY_METHOD_CUSTOM_ROI) {
1643                         g_object_set(vsink,
1644                                      "dst-roi-x", retx,
1645                                      "dst-roi-y", rety,
1646                                      "dst-roi-w", retwidth,
1647                                      "dst-roi-h", retheight,
1648                                      NULL);
1649                 }
1650         }
1651
1652         return MM_ERROR_NONE;
1653 }
1654
1655
1656 int _mmcamcorder_vframe_stablize(MMHandleType handle)
1657 {
1658         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1659         _MMCamcorderSubContext *sc = NULL;
1660
1661         _mmcam_dbg_log("%d", _MMCAMCORDER_CAMSTABLE_COUNT);
1662
1663         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1664
1665         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1666
1667         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1668
1669         if (sc->cam_stability_count != _MMCAMCORDER_CAMSTABLE_COUNT) {
1670                 sc->cam_stability_count = _MMCAMCORDER_CAMSTABLE_COUNT;
1671         }
1672
1673         return MM_ERROR_NONE;
1674 }
1675
1676 /* Retreive device information and set them to attributes */
1677 gboolean _mmcamcorder_get_device_info(MMHandleType handle)
1678 {
1679         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1680         _MMCamcorderSubContext *sc = NULL;
1681         GstCameraControl *control = NULL;
1682         GstCameraControlExifInfo exif_info = {0,};
1683
1684         mmf_return_val_if_fail(hcamcorder, FALSE);
1685         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1686
1687         if (sc && sc->element) {
1688                 int err = MM_ERROR_NONE;
1689                 char *err_name = NULL;
1690                 double focal_len = 0.0;
1691
1692                 /* Video input device */
1693                 if (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
1694                         /* Exif related information */
1695                         control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
1696                         if (control != NULL) {
1697                                 gst_camera_control_get_exif_info(control, &exif_info); //get video input device information
1698                                 focal_len = ((double)exif_info.focal_len_numerator) / ((double) exif_info.focal_len_denominator);
1699                         } else {
1700                                 _mmcam_dbg_err("Fail to get camera control interface!");
1701                                 focal_len = 0.0;
1702                         }
1703                 }
1704
1705                 /* Set values to attributes */
1706                 err = mm_camcorder_set_attributes(handle, &err_name,
1707                                                   MMCAM_CAMERA_FOCAL_LENGTH, focal_len,
1708                                                   NULL);
1709                 if (err != MM_ERROR_NONE) {
1710                         _mmcam_dbg_err("Set attributes error(%s:%x)!", err_name, err);
1711                         if (err_name) {
1712                                 free(err_name);
1713                                 err_name = NULL;
1714                         }
1715                         return FALSE;
1716                 }
1717         } else {
1718                 _mmcam_dbg_warn( "Sub context isn't exist.");
1719                 return FALSE;
1720         }
1721
1722         return TRUE;
1723 }
1724
1725
1726 static gboolean __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstBuffer *buffer, gpointer u_data)
1727 {
1728         int current_state = MM_CAMCORDER_STATE_NONE;
1729
1730         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1731         _MMCamcorderSubContext *sc = NULL;
1732         _MMCamcorderKPIMeasure *kpi = NULL;
1733
1734         mmf_return_val_if_fail(buffer, FALSE);
1735         mmf_return_val_if_fail(GST_BUFFER_DATA(buffer), FALSE);
1736         mmf_return_val_if_fail(hcamcorder, TRUE);
1737
1738         sc = MMF_CAMCORDER_SUBCONTEXT(u_data);
1739         mmf_return_val_if_fail(sc, TRUE);
1740
1741         current_state = hcamcorder->state;
1742
1743         if (sc->drop_vframe > 0) {
1744                 if (sc->pass_first_vframe > 0) {
1745                         sc->pass_first_vframe--;
1746                         _mmcam_dbg_log("Pass video frame by pass_first_vframe");
1747                 } else {
1748                         sc->drop_vframe--;
1749                         _mmcam_dbg_log("Drop video frame by drop_vframe");
1750                         return FALSE;
1751                 }
1752         } else if (sc->cam_stability_count > 0) {
1753                 sc->cam_stability_count--;
1754                 _mmcam_dbg_log("Drop video frame by cam_stability_count");
1755                 return FALSE;
1756         }
1757
1758         if (current_state >= MM_CAMCORDER_STATE_PREPARE) {
1759                 int diff_sec;
1760                 int frame_count = 0;
1761                 struct timeval current_video_time;
1762
1763                 kpi = &(sc->kpi);
1764                 if (kpi->init_video_time.tv_sec == kpi->last_video_time.tv_sec &&
1765                     kpi->init_video_time.tv_usec == kpi->last_video_time.tv_usec &&
1766                     kpi->init_video_time.tv_usec  == 0) {
1767                         _mmcam_dbg_log("START to measure FPS");
1768                         gettimeofday(&(kpi->init_video_time), NULL);
1769                 }
1770
1771                 frame_count = ++(kpi->video_framecount);
1772
1773                 gettimeofday(&current_video_time, NULL);
1774                 diff_sec = current_video_time.tv_sec - kpi->last_video_time.tv_sec;
1775                 if (diff_sec != 0) {
1776                         kpi->current_fps = (frame_count - kpi->last_framecount) / diff_sec;
1777                         if ((current_video_time.tv_sec - kpi->init_video_time.tv_sec) != 0) {
1778                                 int framecount = kpi->video_framecount;
1779                                 int elased_sec = current_video_time.tv_sec - kpi->init_video_time.tv_sec;
1780                                 kpi->average_fps = framecount / elased_sec;
1781                         }
1782
1783                         kpi->last_framecount = frame_count;
1784                         kpi->last_video_time.tv_sec = current_video_time.tv_sec;
1785                         kpi->last_video_time.tv_usec = current_video_time.tv_usec;
1786                         /*
1787                         _mmcam_dbg_log("current fps(%d), average(%d)", kpi->current_fps, kpi->average_fps);
1788                         */
1789                 }
1790         }
1791
1792         /* video stream callback */
1793         if (hcamcorder->vstream_cb && buffer) {
1794                 GstCaps *caps = NULL;
1795                 GstStructure *structure = NULL;
1796                 int state = MM_CAMCORDER_STATE_NULL;
1797                 unsigned int fourcc = 0;
1798                 MMCamcorderVideoStreamDataType stream;
1799
1800                 state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
1801                 if (state < MM_CAMCORDER_STATE_PREPARE) {
1802                         _mmcam_dbg_warn("Not ready for stream callback");
1803                         return TRUE;
1804                 }
1805
1806                 caps = gst_buffer_get_caps(buffer);
1807                 if (caps == NULL) {
1808                         _mmcam_dbg_warn( "Caps is NULL." );
1809                         return TRUE;
1810                 }
1811
1812                 /* clear stream data structure */
1813                 memset(&stream, 0x0, sizeof(MMCamcorderVideoStreamDataType));
1814
1815                 structure = gst_caps_get_structure( caps, 0 );
1816                 gst_structure_get_int(structure, "width", &(stream.width));
1817                 gst_structure_get_int(structure, "height", &(stream.height));
1818                 gst_structure_get_fourcc(structure, "format", &fourcc);
1819                 stream.format = _mmcamcorder_get_pixtype(fourcc);
1820                 gst_caps_unref( caps );
1821                 caps = NULL;
1822
1823                 /*
1824                 _mmcam_dbg_log( "Call video steramCb, data[%p], Width[%d],Height[%d], Format[%d]",
1825                                 GST_BUFFER_DATA(buffer), stream.width, stream.height, stream.format );
1826                 */
1827
1828                 if (stream.width == 0 || stream.height == 0) {
1829                         _mmcam_dbg_warn("Wrong condition!!");
1830                         return TRUE;
1831                 }
1832
1833                 /* set size and timestamp */
1834                 stream.length_total = GST_BUFFER_SIZE(buffer);
1835                 stream.timestamp = (unsigned int)(GST_BUFFER_TIMESTAMP(buffer)/1000000); /* nano sec -> mili sec */
1836
1837                 /* set data pointers */
1838                 if (stream.format == MM_PIXEL_FORMAT_NV12 || stream.format == MM_PIXEL_FORMAT_I420) {
1839                         if (hcamcorder->use_zero_copy_format && GST_BUFFER_MALLOCDATA(buffer)) {
1840                                 SCMN_IMGB *scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buffer);
1841
1842                                 if (stream.format == MM_PIXEL_FORMAT_NV12) {
1843                                         stream.data_type = MM_CAM_STREAM_DATA_YUV420SP;
1844                                         stream.num_planes = 2;
1845                                         stream.data.yuv420sp.y = scmn_imgb->a[0];
1846                                         stream.data.yuv420sp.length_y = stream.width * stream.height;
1847                                         stream.data.yuv420sp.uv = scmn_imgb->a[1];
1848                                         stream.data.yuv420sp.length_uv = stream.data.yuv420sp.length_y >> 1;
1849
1850                                         _mmcam_dbg_log("SN12[num_planes:%d] [Y]p:0x%x,size:%d [UV]p:0x%x,size:%d",
1851                                                        stream.num_planes,
1852                                                        stream.data.yuv420sp.y, stream.data.yuv420sp.length_y,
1853                                                        stream.data.yuv420sp.uv, stream.data.yuv420sp.length_uv);
1854                                 } else {
1855                                         stream.data_type = MM_CAM_STREAM_DATA_YUV420P;
1856                                         stream.num_planes = 3;
1857                                         stream.data.yuv420p.y = scmn_imgb->a[0];
1858                                         stream.data.yuv420p.length_y = stream.width * stream.height;
1859                                         stream.data.yuv420p.u = scmn_imgb->a[1];
1860                                         stream.data.yuv420p.length_u = stream.data.yuv420p.length_y >> 2;
1861                                         stream.data.yuv420p.v = scmn_imgb->a[2];
1862                                         stream.data.yuv420p.length_v = stream.data.yuv420p.length_u;
1863
1864                                         _mmcam_dbg_log("S420[num_planes:%d] [Y]p:0x%x,size:%d [U]p:0x%x,size:%d [V]p:0x%x,size:%d",
1865                                                         stream.num_planes,
1866                                                         stream.data.yuv420p.y, stream.data.yuv420p.length_y,
1867                                                         stream.data.yuv420p.u, stream.data.yuv420p.length_u,
1868                                                         stream.data.yuv420p.v, stream.data.yuv420p.length_v);
1869                                 }
1870                         } else {
1871                                 if (stream.format == MM_PIXEL_FORMAT_NV12) {
1872                                         stream.data_type = MM_CAM_STREAM_DATA_YUV420SP;
1873                                         stream.num_planes = 2;
1874                                         stream.data.yuv420sp.y = GST_BUFFER_DATA(buffer);
1875                                         stream.data.yuv420sp.length_y = stream.width * stream.height;
1876                                         stream.data.yuv420sp.uv = stream.data.yuv420sp.y + stream.data.yuv420sp.length_y;
1877                                         stream.data.yuv420sp.length_uv = stream.data.yuv420sp.length_y >> 1;
1878
1879                                         _mmcam_dbg_log("NV12[num_planes:%d] [Y]p:0x%x,size:%d [UV]p:0x%x,size:%d",
1880                                                        stream.num_planes,
1881                                                        stream.data.yuv420sp.y, stream.data.yuv420sp.length_y,
1882                                                        stream.data.yuv420sp.uv, stream.data.yuv420sp.length_uv);
1883                                 } else {
1884                                         stream.data_type = MM_CAM_STREAM_DATA_YUV420P;
1885                                         stream.num_planes = 3;
1886                                         stream.data.yuv420p.y = GST_BUFFER_DATA(buffer);
1887                                         stream.data.yuv420p.length_y = stream.width * stream.height;
1888                                         stream.data.yuv420p.u = stream.data.yuv420p.y + stream.data.yuv420p.length_y;
1889                                         stream.data.yuv420p.length_u = stream.data.yuv420p.length_y >> 2;
1890                                         stream.data.yuv420p.v = stream.data.yuv420p.u + stream.data.yuv420p.length_u;
1891                                         stream.data.yuv420p.length_v = stream.data.yuv420p.length_u;
1892
1893                                         _mmcam_dbg_log("I420[num_planes:%d] [Y]p:0x%x,size:%d [U]p:0x%x,size:%d [V]p:0x%x,size:%d",
1894                                                         stream.num_planes,
1895                                                         stream.data.yuv420p.y, stream.data.yuv420p.length_y,
1896                                                         stream.data.yuv420p.u, stream.data.yuv420p.length_u,
1897                                                         stream.data.yuv420p.v, stream.data.yuv420p.length_v);
1898                                 }
1899                         }
1900                 } else {
1901                         if (stream.format == MM_PIXEL_FORMAT_YUYV ||
1902                             stream.format == MM_PIXEL_FORMAT_UYVY ||
1903                             stream.format == MM_PIXEL_FORMAT_422P ||
1904                             stream.format == MM_PIXEL_FORMAT_ITLV_JPEG_UYVY) {
1905                                 stream.data_type = MM_CAM_STREAM_DATA_YUV422;
1906                                 stream.data.yuv422.yuv = GST_BUFFER_DATA(buffer);
1907                                 stream.data.yuv422.length_yuv = stream.length_total;
1908                         } else {
1909                                 stream.data_type = MM_CAM_STREAM_DATA_YUV420;
1910                                 stream.data.yuv420.yuv = GST_BUFFER_DATA(buffer);
1911                                 stream.data.yuv420.length_yuv = stream.length_total;
1912                         }
1913
1914                         stream.num_planes = 1;
1915
1916                         _mmcam_dbg_log("%c%c%c%c[num_planes:%d] [0]p:0x%x,size:%d",
1917                                        fourcc, fourcc>>8, fourcc>>16, fourcc>>24,
1918                                        stream.num_planes, stream.data.yuv420.yuv, stream.data.yuv420.length_yuv);
1919                 }
1920
1921                 /* call application callback */
1922                 _MMCAMCORDER_LOCK_VSTREAM_CALLBACK(hcamcorder);
1923                 if (hcamcorder->vstream_cb) {
1924                         hcamcorder->vstream_cb(&stream, hcamcorder->vstream_cb_param);
1925                 }
1926                 _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK(hcamcorder);
1927         }
1928
1929         /* Do force flush cache */
1930         if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ITLV_JPEG_UYVY) {
1931                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "force-flush-cache", FALSE);
1932         }
1933
1934         return TRUE;
1935 }
1936
1937
1938 int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate)
1939 {
1940         int result = MM_CAMCORDER_MR475;
1941
1942         if (bitrate< 5150) {
1943                 result = MM_CAMCORDER_MR475; /*AMR475*/
1944         } else if (bitrate< 5900) {
1945                 result = MM_CAMCORDER_MR515; /*AMR515*/
1946         } else if (bitrate < 6700) {
1947                 result = MM_CAMCORDER_MR59; /*AMR59*/
1948         } else if (bitrate< 7400) {
1949                 result = MM_CAMCORDER_MR67; /*AMR67*/
1950         } else if (bitrate< 7950) {
1951                 result = MM_CAMCORDER_MR74; /*AMR74*/
1952         } else if (bitrate < 10200) {
1953                 result = MM_CAMCORDER_MR795; /*AMR795*/
1954         } else if (bitrate < 12200) {
1955                 result = MM_CAMCORDER_MR102; /*AMR102*/
1956         } else {
1957                 result = MM_CAMCORDER_MR122; /*AMR122*/
1958         }
1959
1960         return result;
1961 }
1962
1963 int _mmcamcorder_get_eos_message(MMHandleType handle)
1964 {
1965         double elapsed = 0.0;
1966
1967         GstMessage *gMessage = NULL;
1968         GstBus *bus = NULL;
1969         GstClockTime timeout = 1 * GST_SECOND; /* maximum waiting time */
1970         GTimer *timer = NULL;
1971
1972         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1973         _MMCamcorderSubContext *sc = NULL;
1974
1975         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1976         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1977
1978         _mmcam_dbg_log("");
1979
1980         bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
1981         timer = g_timer_new();
1982
1983         if (sc && !(sc->bget_eos)) {
1984                  while (1) {
1985                         elapsed = g_timer_elapsed(timer, NULL);
1986
1987                         /*_mmcam_dbg_log("elapsed:%f sec", elapsed);*/
1988
1989                         if (elapsed > _MMCAMCORDER_WAIT_EOS_TIME) {
1990                                 _mmcam_dbg_warn("Timeout. EOS isn't received.");
1991                                  g_timer_destroy(timer);
1992                                  gst_object_unref(bus);
1993                                  return MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT;
1994                         }
1995
1996                         gMessage = gst_bus_timed_pop (bus, timeout);
1997                         if (gMessage != NULL) {
1998                                 _mmcam_dbg_log("Get message(%x).", GST_MESSAGE_TYPE(gMessage));
1999                                 _mmcamcorder_pipeline_cb_message(bus, gMessage, (void*)hcamcorder);
2000
2001                                 if (GST_MESSAGE_TYPE(gMessage) == GST_MESSAGE_EOS || sc->bget_eos) {
2002                                         gst_message_unref(gMessage);
2003                                         break;
2004                                 }
2005                                 gst_message_unref(gMessage);
2006                         } else {
2007                                 _mmcam_dbg_log("timeout of gst_bus_timed_pop()");
2008                                 if (sc->bget_eos) {
2009                                         _mmcam_dbg_log("Get EOS in another thread.");
2010                                         break;
2011                                 }
2012                         }
2013                 }
2014         }
2015
2016          g_timer_destroy(timer);
2017          gst_object_unref(bus);
2018
2019         _mmcam_dbg_log("END");
2020
2021          return MM_ERROR_NONE;
2022 }
2023
2024
2025 void _mmcamcorder_remove_element_handle(MMHandleType handle, int first_elem, int last_elem)
2026 {
2027         int i = 0;
2028         _MMCamcorderSubContext *sc = NULL;
2029
2030         mmf_return_if_fail(handle);
2031
2032         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2033         mmf_return_if_fail(sc);
2034         mmf_return_if_fail(sc->element);
2035         mmf_return_if_fail((first_elem > 0) && (last_elem > 0) && (last_elem > first_elem));
2036
2037         _mmcam_dbg_log("");
2038
2039         for (i = first_elem ; i <= last_elem ; i++) {
2040                 sc->element[i].gst = NULL;
2041                 sc->element[i].id = _MMCAMCORDER_NONE;
2042         }
2043
2044         return;
2045 }
2046
2047
2048 int _mmcamcorder_check_audiocodec_fileformat_compatibility(MMHandleType handle)
2049 {
2050         int err = MM_ERROR_NONE;
2051         int audio_codec = MM_AUDIO_CODEC_INVALID;
2052         int file_format = MM_FILE_FORMAT_INVALID;
2053
2054         char *err_name = NULL;
2055
2056         err = mm_camcorder_get_attributes(handle, &err_name,
2057                                           MMCAM_AUDIO_ENCODER, &audio_codec,
2058                                           MMCAM_FILE_FORMAT, &file_format,
2059                                           NULL);
2060         if (err != MM_ERROR_NONE) {
2061                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
2062                 SAFE_FREE(err_name);
2063                 return err;
2064         }
2065
2066         /* Check compatibility between audio codec and file format */
2067         if (audio_codec >= MM_AUDIO_CODEC_INVALID && audio_codec < MM_AUDIO_CODEC_NUM &&
2068             file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
2069                 if (audiocodec_fileformat_compatibility_table[audio_codec][file_format] == 0) {
2070                         _mmcam_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.",
2071                                        audio_codec, file_format);
2072                         return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2073                 }
2074
2075                 _mmcam_dbg_log("Audio codec[%d] and file format[%d] compatibility SUCCESS.",
2076                                audio_codec, file_format);
2077         } else {
2078                 _mmcam_dbg_err("Audio codec[%d] or file format[%d] is INVALID.",
2079                                audio_codec, file_format);
2080                 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2081         }
2082
2083         return MM_ERROR_NONE;
2084 }
2085
2086
2087 int _mmcamcorder_check_videocodec_fileformat_compatibility(MMHandleType handle)
2088 {
2089         int err = MM_ERROR_NONE;
2090         int video_codec = MM_VIDEO_CODEC_INVALID;
2091         int file_format = MM_FILE_FORMAT_INVALID;
2092
2093         char *err_name = NULL;
2094
2095         err = mm_camcorder_get_attributes(handle, &err_name,
2096                                           MMCAM_VIDEO_ENCODER, &video_codec,
2097                                           MMCAM_FILE_FORMAT, &file_format,
2098                                           NULL);
2099         if (err != MM_ERROR_NONE) {
2100                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
2101                 SAFE_FREE(err_name);
2102                 return err;
2103         }
2104
2105         /* Check compatibility between audio codec and file format */
2106         if (video_codec >= MM_VIDEO_CODEC_INVALID && video_codec < MM_VIDEO_CODEC_NUM &&
2107             file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
2108                 if (videocodec_fileformat_compatibility_table[video_codec][file_format] == 0) {
2109                         _mmcam_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.",
2110                                        video_codec, file_format);
2111                         return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2112                 }
2113
2114                 _mmcam_dbg_log("Video codec[%d] and file format[%d] compatibility SUCCESS.",
2115                                video_codec, file_format);
2116         } else {
2117                 _mmcam_dbg_err("Video codec[%d] or file format[%d] is INVALID.",
2118                                video_codec, file_format);
2119                 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2120         }
2121
2122         return MM_ERROR_NONE;
2123 }
2124
2125
2126 bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate)
2127 {
2128         char* videosink_name = NULL;
2129
2130         mmf_camcorder_t *hcamcorder = NULL;
2131         _MMCamcorderSubContext *sc = NULL;
2132
2133         hcamcorder = MMF_CAMCORDER(handle);
2134         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2135
2136         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2137         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2138         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2139
2140         if (sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst) {
2141                 /* Get videosink name */
2142                 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
2143                 if (!strcmp(videosink_name, "xvimagesink")) {
2144                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst,
2145                                                  "rotate", display_rotate);
2146                         _mmcam_dbg_log("Set display-rotate [%d] done.", display_rotate);
2147                         return TRUE;
2148                 } else {
2149                         _mmcam_dbg_warn("videosink[%s] does not support DISPLAY_ROTATION.", videosink_name);
2150                         return FALSE;
2151                 }
2152         } else {
2153                 _mmcam_dbg_err("Videosink element is null");
2154                 return FALSE;
2155         }
2156 }
2157
2158
2159 bool _mmcamcorder_set_display_flip(MMHandleType handle, int display_flip)
2160 {
2161         char* videosink_name = NULL;
2162
2163         mmf_camcorder_t *hcamcorder = NULL;
2164         _MMCamcorderSubContext *sc = NULL;
2165
2166         hcamcorder = MMF_CAMCORDER(handle);
2167         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2168
2169         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2170         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2171         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2172
2173         if (sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst) {
2174                 /* Get videosink name */
2175                 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
2176                 if (!strcmp(videosink_name, "xvimagesink")) {
2177                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst,
2178                                                  "flip", display_flip);
2179                         _mmcam_dbg_log("Set display flip [%d] done.", display_flip);
2180                         return TRUE;
2181                 } else {
2182                         _mmcam_dbg_warn("videosink[%s] does not support DISPLAY_FLIP", videosink_name);
2183                         return FALSE;
2184                 }
2185         } else {
2186                 _mmcam_dbg_err("Videosink element is null");
2187                 return FALSE;
2188         }
2189 }
2190
2191
2192 bool _mmcamcorder_set_videosrc_rotation(MMHandleType handle, int videosrc_rotate)
2193 {
2194         int width = 0;
2195         int height = 0;
2196         int set_width = 0;
2197         int set_height = 0;
2198         int set_rotate = 0;
2199         int fps = 0;
2200         gboolean do_set_caps = FALSE;
2201
2202         GstCaps *caps = NULL;
2203
2204         type_int_array *input_index = NULL;
2205         mmf_camcorder_t *hcamcorder = NULL;
2206         _MMCamcorderSubContext *sc = NULL;
2207
2208         hcamcorder = MMF_CAMCORDER(handle);
2209         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2210
2211         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2212         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2213         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2214
2215         if (!sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
2216                 _mmcam_dbg_err("Video src is NULL!");
2217                 return FALSE;
2218         }
2219
2220         if (!sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst) {
2221                 _mmcam_dbg_err("Video filter is NULL!");
2222                 return FALSE;
2223         }
2224
2225         mm_camcorder_get_attributes(handle, NULL,
2226                                     MMCAM_CAMERA_WIDTH, &width,
2227                                     MMCAM_CAMERA_HEIGHT, &height,
2228                                     MMCAM_CAMERA_FPS, &fps,
2229                                     NULL);
2230
2231         _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
2232                                               CONFIGURE_CATEGORY_CTRL_CAMERA,
2233                                               "InputIndex",
2234                                               &input_index );
2235         if (input_index == NULL) {
2236                 _mmcam_dbg_err("Failed to get input_index");
2237                 return FALSE;
2238         }
2239
2240         /* Interleaved format does not support rotation */
2241         if (sc->info_image->preview_format != MM_PIXEL_FORMAT_ITLV_JPEG_UYVY) {
2242                 /* store videosrc rotation */
2243                 sc->videosrc_rotate = videosrc_rotate;
2244
2245                 /* Define width, height and rotate in caps */
2246
2247                 /* This will be applied when rotate is 0, 90, 180, 270 if rear camera.
2248                 This will be applied when rotate is 0, 180 if front camera. */
2249                 set_rotate = videosrc_rotate * 90;
2250
2251                 if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_90 ||
2252                     videosrc_rotate == MM_VIDEO_INPUT_ROTATION_270) {
2253                         set_width = height;
2254                         set_height = width;
2255                         if (input_index->default_value == MM_VIDEO_DEVICE_CAMERA1) {
2256                                 if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_90) {
2257                                         set_rotate = 270;
2258                                 } else {
2259                                         set_rotate = 90;
2260                                 }
2261                         }
2262                 } else {
2263                         set_width = width;
2264                         set_height = height;
2265                 }
2266         } else {
2267                 sc->videosrc_rotate = MM_VIDEO_INPUT_ROTATION_NONE;
2268                 set_rotate = 0;
2269                 set_width = width;
2270                 set_height = height;
2271
2272                 _mmcam_dbg_warn("ITLV format doe snot support INPUT ROTATE. Ignore ROTATE[%d]",
2273                                 videosrc_rotate);
2274         }
2275
2276         /* correct size because ITLV does not support QCIF */
2277         if (input_index->default_value == MM_VIDEO_DEVICE_CAMERA0 &&
2278             sc->fourcc == GST_MAKE_FOURCC('I','T','L','V')) {
2279                 if ((set_width == 176 && set_height == 144) ||
2280                     (set_width == 144 && set_height == 176)) {
2281                         set_width = set_width << 1;
2282                         set_height = set_height << 1;
2283                         _mmcam_dbg_log("ITLV format is not supported QCIF, so we set CIF(%dx%d)",
2284                                        set_width, set_height);
2285                 }
2286         }
2287
2288         MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", &caps);
2289         if (caps) {
2290                 GstStructure *structure = NULL;
2291
2292                 structure = gst_caps_get_structure(caps, 0);
2293                 if (structure) {
2294                         int caps_width = 0;
2295                         int caps_height = 0;
2296                         int caps_fps = 0;
2297                         int caps_rotate = 0;
2298
2299                         gst_structure_get_int(structure, "width", &caps_width);
2300                         gst_structure_get_int(structure, "height", &caps_height);
2301                         gst_structure_get_int(structure, "fps", &caps_fps);
2302                         gst_structure_get_int(structure, "rotate", &caps_rotate);
2303                         if (set_width == caps_width && set_height == caps_height &&
2304                             set_rotate == caps_rotate && fps == caps_fps) {
2305                                 _mmcam_dbg_log("No need to replace caps.");
2306                         } else {
2307                                 _mmcam_dbg_log("something is different. set new one...");
2308                                 do_set_caps = TRUE;
2309                         }
2310                 } else {
2311                         _mmcam_dbg_log("can not get structure of caps. set new one...");
2312                         do_set_caps = TRUE;
2313                 }
2314
2315                 gst_caps_unref(caps);
2316                 caps = NULL;
2317         } else {
2318                 _mmcam_dbg_log("No caps. set new one...");
2319                 do_set_caps = TRUE;
2320         }
2321
2322         if (do_set_caps) {
2323                 caps = gst_caps_new_simple("video/x-raw-yuv",
2324                                            "format", GST_TYPE_FOURCC, sc->fourcc,
2325                                            "width", G_TYPE_INT, set_width,
2326                                            "height", G_TYPE_INT, set_height,
2327                                            "framerate", GST_TYPE_FRACTION, fps, 1,
2328                                            "rotate", G_TYPE_INT, set_rotate,
2329                                            NULL);
2330                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
2331                 gst_caps_unref(caps);
2332                 caps = NULL;
2333                 _mmcam_dbg_log("vidoesrc new caps set. format[%c%c%c%c],width[%d],height[%d],fps[%d],rotate[%d]",
2334                                (sc->fourcc), (sc->fourcc)>>8, (sc->fourcc)>>16, (sc->fourcc)>>24,
2335                                set_width, set_height, fps, set_rotate);
2336         }
2337
2338         return TRUE;
2339 }
2340
2341
2342 bool _mmcamcorder_set_videosrc_flip(MMHandleType handle, int videosrc_flip)
2343 {
2344         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2345         _MMCamcorderSubContext *sc = NULL;
2346         type_int_array *input_index = NULL;
2347
2348         mmf_return_val_if_fail(hcamcorder, FALSE);
2349
2350         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2351         mmf_return_val_if_fail(sc, TRUE);
2352
2353         _mmcam_dbg_log("Set FLIP %d", videosrc_flip);
2354
2355         if (sc->element && sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
2356                 int hflip = 0;
2357                 int vflip = 0;
2358
2359                 /* Interleaved format does not support FLIP */
2360                 if (sc->info_image->preview_format != MM_PIXEL_FORMAT_ITLV_JPEG_UYVY) {
2361                         _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
2362                                                               CONFIGURE_CATEGORY_CTRL_CAMERA,
2363                                                               "InputIndex",
2364                                                               &input_index );
2365
2366                         hflip = (videosrc_flip & MM_FLIP_HORIZONTAL) == MM_FLIP_HORIZONTAL;
2367                         vflip = (videosrc_flip & MM_FLIP_VERTICAL) == MM_FLIP_VERTICAL;
2368
2369                         _mmcam_dbg_log("videosrc flip H:%d, V:%d", hflip, vflip);
2370
2371                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hflip", hflip);
2372                         MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "vflip", vflip);
2373                 } else {
2374                         _mmcam_dbg_warn("ITLV format does not support FLIP. Ignore FLIP[%d]",
2375                                         videosrc_flip);
2376                 }
2377         } else {
2378                 _mmcam_dbg_warn("element is NULL");
2379                 return FALSE;
2380         }
2381
2382         return TRUE;
2383 }
2384
2385
2386 bool _mmcamcorder_set_videosrc_anti_shake(MMHandleType handle, int anti_shake)
2387 {
2388         GstCameraControl *control = NULL;
2389         _MMCamcorderSubContext *sc = NULL;
2390         GstElement *v_src = NULL;
2391
2392         int set_value = 0;
2393
2394         mmf_return_val_if_fail(handle, FALSE);
2395
2396         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2397         mmf_return_val_if_fail(sc, TRUE);
2398
2399         v_src = sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst;
2400
2401         if (!v_src) {
2402                 _mmcam_dbg_warn("videosrc element is NULL");
2403                 return FALSE;
2404         }
2405
2406         set_value = _mmcamcorder_convert_msl_to_sensor(handle, MM_CAM_CAMERA_ANTI_HANDSHAKE, anti_shake);
2407
2408         /* set anti-shake with camera control */
2409         if (!GST_IS_CAMERA_CONTROL(v_src)) {
2410                 _mmcam_dbg_warn("Can't cast Video source into camera control.");
2411                 return FALSE;
2412         }
2413
2414         control = GST_CAMERA_CONTROL(v_src);
2415         if (gst_camera_control_set_ahs(control, set_value)) {
2416                 _mmcam_dbg_log("Succeed in operating anti-handshake. value[%d]", set_value);
2417                 return TRUE;
2418         } else {
2419                 _mmcam_dbg_warn("Failed to operate anti-handshake. value[%d]", set_value);
2420         }
2421
2422         return FALSE;
2423 }
2424
2425
2426 bool _mmcamcorder_set_videosrc_stabilization(MMHandleType handle, int stabilization)
2427 {
2428         _MMCamcorderSubContext *sc = NULL;
2429         GstElement *v_src = NULL;
2430
2431         mmf_return_val_if_fail(handle, FALSE);
2432
2433         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2434         mmf_return_val_if_fail(sc, TRUE);
2435
2436         v_src = sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst;
2437
2438         if (!v_src) {
2439                 _mmcam_dbg_warn("videosrc element is NULL");
2440                 return FALSE;
2441         }
2442
2443         /* check property of videosrc element - support VDIS */
2444         if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(v_src)), "enable-vdis-mode")) {
2445                 int camera_format =MM_PIXEL_FORMAT_INVALID;
2446                 int camera_width = 0;
2447                 int camera_height = 0;
2448
2449                 if (stabilization == MM_CAMCORDER_VIDEO_STABILIZATION_ON) {
2450                         _mmcam_dbg_log("ENABLE video stabilization");
2451
2452                         /* VDIS mode only supports NV12 and [720p or 1080p] */
2453                         mm_camcorder_get_attributes(handle, NULL,
2454                                                     MMCAM_CAMERA_FORMAT, &camera_format,
2455                                                     MMCAM_CAMERA_WIDTH, &camera_width,
2456                                                     MMCAM_CAMERA_HEIGHT, &camera_height,
2457                                                     NULL);
2458                         if (camera_format == MM_PIXEL_FORMAT_NV12 &&
2459                             camera_width >= 1280 &&
2460                             camera_height >= 720) {
2461                                 _mmcam_dbg_log("preview format %d, size %dx%d, ENABLE video stabilization",
2462                                                camera_format, camera_width, camera_height, stabilization);
2463                                 /* set vdis mode */
2464                                 g_object_set(G_OBJECT(v_src),
2465                                              "enable-vdis-mode", TRUE,
2466                                              NULL);
2467                         } else {
2468                                 _mmcam_dbg_warn("invalid preview format %d or size %dx%d",
2469                                                 camera_format, camera_width, camera_height);
2470                                 return FALSE;
2471                         }
2472                 } else {
2473                         /* set vdis mode */
2474                         g_object_set(G_OBJECT(v_src),
2475                                      "enable-vdis-mode", FALSE,
2476                                      NULL);
2477
2478                         _mmcam_dbg_log("DISABLE video stabilization");
2479                 }
2480         } else if (stabilization == MM_CAMCORDER_VIDEO_STABILIZATION_ON) {
2481                 _mmcam_dbg_err("no property for video stabilization, so can not set ON");
2482                 return FALSE;
2483         } else {
2484                 _mmcam_dbg_warn("no property for video stabilization");
2485         }
2486
2487         return TRUE;
2488 }
2489