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