4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jeongmo Yang <jm80.yang@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 /*=======================================================================================
24 =======================================================================================*/
25 #include <gst/interfaces/xoverlay.h>
26 #include <gst/interfaces/cameracontrol.h>
30 #include "mm_camcorder_internal.h"
31 #include "mm_camcorder_gstcommon.h"
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, 0, 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, },
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, },
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 _DPRAM_RAW_PCM_LOCATION "/dev/rawPCM0"
126 /*-----------------------------------------------------------------------
127 | LOCAL FUNCTION PROTOTYPES: |
128 -----------------------------------------------------------------------*/
129 /* STATIC INTERNAL FUNCTION */
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.
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
140 * @see __mmcamcorder_create_preview_pipeline()
142 static gboolean __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstBuffer *buffer, gpointer u_data);
143 static gboolean __mmcamcorder_video_dataprobe_vsink(GstPad *pad, GstBuffer *buffer, gpointer u_data);
144 static gboolean __mmcamcorder_video_dataprobe_vsink_drop_by_time(GstPad *pad, GstBuffer *buffer, gpointer u_data);
146 static int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate);
148 /*=======================================================================================
149 | FUNCTION DEFINITIONS |
150 =======================================================================================*/
151 /*-----------------------------------------------------------------------
152 | GLOBAL FUNCTION DEFINITIONS: |
153 -----------------------------------------------------------------------*/
154 int _mmcamcorder_create_videosrc_bin(MMHandleType handle)
156 int err = MM_ERROR_NONE;
161 int UseVideoscale = 0;
162 int PictureFormat = 0;
164 int capture_width = 0;
165 int capture_height = 0;
166 char *videosrc_name = NULL;
167 char *err_name = NULL;
169 GList *element_list = NULL;
170 GstCaps *caps = NULL;
171 GstPad *video_tee0 = NULL;
172 GstPad *video_tee1 = NULL;
174 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
175 _MMCamcorderSubContext *sc = NULL;
176 type_element *VideosrcElement = NULL;
177 type_int_array *input_index = NULL;
179 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
181 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
182 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
183 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
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);
192 _mmcam_dbg_log("_MMCAMCORDER_VIDEOSRC_BIN is Already existed.");
195 /* Get video device index info */
196 _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
197 CONFIGURE_CATEGORY_CTRL_CAMERA,
200 if (input_index == NULL) {
201 _mmcam_dbg_err("Failed to get input_index");
202 return MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
205 err = mm_camcorder_get_attributes(handle, &err_name,
206 MMCAM_CAMERA_FORMAT, &PictureFormat,
207 MMCAM_CAMERA_FPS, &fps,
208 "camera-slow-motion-fps", &slow_fps,
209 MMCAM_CAMERA_ROTATION, &rotate,
210 MMCAM_CAPTURE_WIDTH, &capture_width,
211 MMCAM_CAPTURE_HEIGHT, &capture_height,
212 MMCAM_IMAGE_ENCODER, &codectype,
213 "camera-hold-af-after-capturing", &hold_af,
215 if (err != MM_ERROR_NONE) {
216 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
221 /* Get fourcc from picture format */
222 sc->fourcc = _mmcamcorder_get_fourcc(PictureFormat, codectype, hcamcorder->use_zero_copy_format);
224 /* Get videosrc element and its name from configure */
225 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
226 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
229 _mmcamcorder_conf_get_value_element_name(VideosrcElement, &videosrc_name);
231 /* Create bin element */
232 __ta__(" videosrc_bin",
233 _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_VIDEOSRC_BIN, "videosrc_bin", err);
236 /* Create child element */
237 __ta__(" videosrc_src",
238 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_SRC, videosrc_name, "videosrc_src", element_list, err);
240 __ta__(" videosrc_capsfilter",
241 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_FILT, "capsfilter", "videosrc_filter", element_list, err);
245 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", 0);
246 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", capture_width);
247 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", capture_height);
249 if (hcamcorder->type == MM_CAMCORDER_MODE_VIDEO) {
250 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
251 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
258 int scale_height = 0;
259 int scale_method = 0;
260 char *videoscale_name = NULL;
261 type_element *VideoscaleElement = NULL;
263 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
264 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
267 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &videoscale_name);
268 __ta__(" videosrc_scale",
269 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_SCALE, videoscale_name, "videosrc_scale", element_list, err);
271 __ta__(" videoscale_capsfilter",
272 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_VSFLT, "capsfilter", "videosrc_scalefilter", element_list, err);
275 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "width", &scale_width);
276 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "height", &scale_height);
277 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "method", &scale_method);
279 if (rotate == MM_VIDEO_INPUT_ROTATION_90 ||
280 rotate == MM_VIDEO_INPUT_ROTATION_270) {
281 set_width = scale_height;
282 set_height = scale_width;
284 set_width = scale_width;
285 set_height = scale_height;
288 _mmcam_dbg_log("VideoSRC Scale[%dx%d], Method[%d]", set_width, set_height, scale_method);
290 caps = gst_caps_new_simple("video/x-raw-yuv",
291 "format", GST_TYPE_FOURCC, sc->fourcc,
292 "width", G_TYPE_INT, set_width,
293 "height", G_TYPE_INT, set_height,
295 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_VSFLT].gst, "caps", caps);
296 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SCALE].gst, "method", scale_method);
298 gst_caps_unref(caps);
304 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", fps);
309 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSRC_TEE, "tee", "videosrc_tee", element_list, err);
312 /* Set basic infomation of videosrc element */
313 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, VideosrcElement);
315 /* Set video device index */
316 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "camera-id", input_index->default_value);
317 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hold-af-after-capturing", hold_af);
319 _mmcam_dbg_log("Current mode[%d]", hcamcorder->type);
321 /* Set sensor mode as CAMERA */
322 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "sensor-mode", 0);
324 /* Set caps by rotation */
325 _mmcamcorder_set_videosrc_rotation(handle, rotate);
327 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst), element_list)) {
328 _mmcam_dbg_err( "element add error." );
329 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
330 goto pipeline_creation_error;
333 if (!_mmcamcorder_link_elements(element_list)) {
334 _mmcam_dbg_err( "element link error." );
335 err = MM_ERROR_CAMCORDER_GST_LINK;
336 goto pipeline_creation_error;
339 video_tee0 = gst_element_get_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src%d");
340 video_tee1 = gst_element_get_request_pad(sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst, "src%d");
342 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSRC_TEE].gst), "alloc-pad", video_tee0);
345 if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, gst_ghost_pad_new("src0", video_tee0) )) < 0) {
346 _mmcam_dbg_err("failed to create ghost pad1 on _MMCAMCORDER_VIDEOSRC_BIN.");
347 gst_object_unref(video_tee0);
349 gst_object_unref(video_tee1);
351 err = MM_ERROR_CAMCORDER_GST_LINK;
352 goto pipeline_creation_error;
355 if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, gst_ghost_pad_new("src1", video_tee1) )) < 0) {
356 _mmcam_dbg_err("failed to create ghost pad2 on _MMCAMCORDER_VIDEOSRC_BIN.");
357 gst_object_unref(video_tee0);
359 gst_object_unref(video_tee1);
361 err = MM_ERROR_CAMCORDER_GST_LINK;
362 goto pipeline_creation_error;
365 gst_object_unref(video_tee0);
367 gst_object_unref(video_tee1);
371 g_list_free(element_list);
375 return MM_ERROR_NONE;
377 pipeline_creation_error:
378 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_SRC );
379 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_FILT );
380 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_SCALE );
381 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_VSFLT );
382 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_TEE );
383 _MMCAMCORDER_ELEMENT_REMOVE( sc, _MMCAMCORDER_VIDEOSRC_BIN );
385 g_list_free(element_list);
393 int _mmcamcorder_create_audiosrc_bin(MMHandleType handle)
395 int err = MM_ERROR_NONE;
400 int a_enc = MM_AUDIO_CODEC_AMR;
401 int a_dev = MM_AUDIO_DEVICE_MIC;
402 int UseNoiseSuppressor = 0;
404 char *err_name = NULL;
405 char *audiosrc_name = NULL;
406 char *cat_name = NULL;
408 GstCaps *caps = NULL;
410 GList *element_list = NULL;
412 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
413 _MMCamcorderSubContext *sc = NULL;
414 _MMCamcorderGstElement *last_element = NULL;
415 type_element *AudiosrcElement = NULL;
417 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
419 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
420 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
421 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
425 err = _mmcamcorder_check_audiocodec_fileformat_compatibility(handle);
426 if (err != MM_ERROR_NONE) {
430 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
431 CONFIGURE_CATEGORY_MAIN_RECORD,
432 "UseNoiseSuppressor",
433 &UseNoiseSuppressor);
435 err = mm_camcorder_get_attributes(handle, &err_name,
436 MMCAM_AUDIO_DEVICE, &a_dev,
437 MMCAM_AUDIO_ENCODER, &a_enc,
438 MMCAM_AUDIO_ENCODER_BITRATE, &val,
439 MMCAM_AUDIO_SAMPLERATE, &rate,
440 MMCAM_AUDIO_FORMAT, &format,
441 MMCAM_AUDIO_CHANNEL, &channel,
442 MMCAM_AUDIO_VOLUME, &volume,
444 if (err != MM_ERROR_NONE) {
445 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
450 /* Check existence */
451 if (sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst) {
452 if (((GObject *)sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst)->ref_count > 0) {
453 gst_object_unref(sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst);
455 _mmcam_dbg_log("_MMCAMCORDER_AUDIOSRC_BIN is Already existed. Unref once...");
458 /* Create bin element */
459 __ta__(" audiosource_bin",
460 _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_AUDIOSRC_BIN, "audiosource_bin", err);
463 if (a_dev == MM_AUDIO_DEVICE_MODEM) {
464 cat_name = strdup("AudiomodemsrcElement");
466 /* MM_AUDIO_DEVICE_MIC or others */
467 cat_name = strdup("AudiosrcElement");
470 if (cat_name == NULL) {
471 _mmcam_dbg_err("strdup failed.");
472 err = MM_ERROR_CAMCORDER_LOW_MEMORY;
473 goto pipeline_creation_error;
476 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
477 CONFIGURE_CATEGORY_MAIN_AUDIO_INPUT,
480 _mmcamcorder_conf_get_value_element_name(AudiosrcElement, &audiosrc_name);
485 _mmcam_dbg_log("Audio src name : %s", audiosrc_name);
488 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_SRC, audiosrc_name, NULL, element_list, err);
491 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_AUDIOSRC_SRC].gst, AudiosrcElement);
493 __ta__(" audiosource_capsfilter",
494 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_FILT, "capsfilter", NULL, element_list, err);
497 if (a_enc != MM_AUDIO_CODEC_VORBIS) {
498 __ta__(" audiosource_volume",
499 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_VOL, "volume", NULL, element_list, err);
503 if (UseNoiseSuppressor && a_enc != MM_AUDIO_CODEC_AAC) {
504 __ta__(" noise_suppressor",
505 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_AUDIOSRC_NS, "noisesuppressor", "audiofilter", element_list, err);
509 /* Set basic infomation */
510 if (a_enc != MM_AUDIO_CODEC_VORBIS) {
514 /* Because data probe of audio src do the same job, it doesn't need to set "mute" here. Already null raw data. */
515 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "volume", 1.0);
517 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "mute", FALSE);
518 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_AUDIOSRC_VOL].gst, "volume", volume);
521 if (format == MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE) {
523 } else { /* MM_CAMCORDER_AUDIO_FORMAT_PCM_U8 */
527 caps = gst_caps_new_simple("audio/x-raw-int",
528 "rate", G_TYPE_INT, rate,
529 "channels", G_TYPE_INT, channel,
530 "depth", G_TYPE_INT, depth,
532 _mmcam_dbg_log("caps [x-raw-int,rate:%d,channel:%d,depth:%d]",
533 rate, channel, depth);
535 /* what are the audio encoder which should get audio/x-raw-float? */
536 caps = gst_caps_new_simple("audio/x-raw-float",
537 "rate", G_TYPE_INT, rate,
538 "channels", G_TYPE_INT, channel,
539 "endianness", G_TYPE_INT, BYTE_ORDER,
540 "width", G_TYPE_INT, 32,
542 _mmcam_dbg_log("caps [x-raw-float,rate:%d,channel:%d,endianness:%d,width:32]",
543 rate, channel, BYTE_ORDER);
546 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_AUDIOSRC_FILT].gst), "caps", caps);
547 gst_caps_unref(caps);
549 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst), element_list)) {
550 _mmcam_dbg_err("element add error.");
551 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
552 goto pipeline_creation_error;
555 if (!_mmcamcorder_link_elements(element_list)) {
556 _mmcam_dbg_err( "element link error." );
557 err = MM_ERROR_CAMCORDER_GST_LINK;
558 goto pipeline_creation_error;
561 last_element = (_MMCamcorderGstElement*)(g_list_last(element_list)->data);
562 pad = gst_element_get_static_pad(last_element->gst, "src");
563 if ((gst_element_add_pad( sc->element[_MMCAMCORDER_AUDIOSRC_BIN].gst, gst_ghost_pad_new("src", pad) )) < 0) {
564 gst_object_unref(pad);
566 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_AUDIOSRC_BIN.");
567 err = MM_ERROR_CAMCORDER_GST_LINK;
568 goto pipeline_creation_error;
571 gst_object_unref(pad);
575 g_list_free(element_list);
579 return MM_ERROR_NONE;
581 pipeline_creation_error:
582 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_SRC);
583 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_FILT);
584 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_VOL);
585 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_QUE);
586 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_CONV);
587 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_ENC);
588 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_AUDIOSRC_BIN);
590 g_list_free(element_list);
598 int _mmcamcorder_create_videosink_bin(MMHandleType handle)
600 int err = MM_ERROR_NONE;
603 int camera_width = 0;
604 int camera_height = 0;
606 int camera_format = MM_PIXEL_FORMAT_NV12;
607 int UseVideoscale = 0, EnableConvertedSC = 0;
608 int scale_method = 0;
609 char* videosink_name = NULL;
610 char* videoscale_name = NULL;
611 char* err_name = NULL;
613 GstCaps *caps = NULL;
615 GList *element_list = NULL;
617 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
618 _MMCamcorderSubContext *sc = NULL;
619 _MMCamcorderGstElement *first_element = NULL;
620 type_element *VideoscaleElement = NULL;
622 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
623 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
625 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
626 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
628 _mmcam_dbg_log("START");
631 err = mm_camcorder_get_attributes(handle, &err_name,
632 MMCAM_CAMERA_WIDTH, &camera_width,
633 MMCAM_CAMERA_HEIGHT, &camera_height,
634 MMCAM_CAMERA_FORMAT, &camera_format,
635 MMCAM_DISPLAY_RECT_WIDTH, &rect_width,
636 MMCAM_DISPLAY_RECT_HEIGHT, &rect_height,
637 MMCAM_DISPLAY_ROTATION, &rotate,
638 "enable-converted-stream-callback", &EnableConvertedSC,
640 if (err != MM_ERROR_NONE) {
641 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
646 /* Get videosink name */
647 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
649 /* Check existence */
650 if (sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst) {
651 if (((GObject *)sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst)->ref_count > 0) {
652 gst_object_unref(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst);
654 _mmcam_dbg_log("_MMCAMCORDER_VIDEOSINK_BIN is Already existed. Unref once...");
657 /* Create bin element */
658 __ta__(" videosink_bin",
659 _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_VIDEOSINK_BIN, "videosink_bin", err);
662 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
663 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
667 /* Create child element */
668 if (EnableConvertedSC ||
669 !strcmp(videosink_name, "evasimagesink") ||
670 !strcmp(videosink_name, "ximagesink")) {
671 if (camera_format == MM_PIXEL_FORMAT_NV12 ||
672 camera_format == MM_PIXEL_FORMAT_NV12T) {
675 __ta__(" videosink_fimcconvert",
676 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_CLS, "fimcconvert", NULL, element_list, err);
679 if (rotate < MM_DISPLAY_ROTATION_FLIP_HORZ) {
680 set_rotate = rotate * 90;
685 if (rect_width == 0 || rect_height == 0) {
686 _mmcam_dbg_warn("rect_width or height is 0. set camera width and height.");
688 if (rotate == MM_DISPLAY_ROTATION_90 ||
689 rotate == MM_DISPLAY_ROTATION_270) {
690 rect_width = camera_height;
691 rect_height = camera_width;
693 rect_width = camera_width;
694 rect_height = camera_height;
698 _mmcam_dbg_log("Fimcconvert set values - %dx%d, rotate: %d", rect_width, rect_height, set_rotate);
699 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "src-width", rect_width);
700 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "src-height", rect_height);
701 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_CLS].gst, "rotate", set_rotate);
703 __ta__(" videosink_ffmpegcolorspace",
704 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_CLS, "ffmpegcolorspace", NULL, element_list, err);
707 } else if(UseVideoscale) {
708 __ta__(" videosink_queue",
709 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_QUE, "queue", NULL, element_list, err);
712 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
713 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
716 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &videoscale_name);
718 __ta__(" videosink_videoscale",
719 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_SCALE, videoscale_name, NULL, element_list, err);
721 __ta__(" videosink_capsfilter",
722 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_FILT, "capsfilter", NULL, element_list, err);
725 _mmcamcorder_conf_get_value_element_int(VideoscaleElement, "method", &scale_method);
726 _mmcam_dbg_log("VideoSINK Scale[%dx%d], Method[%d]", rect_width, rect_height, scale_method);
728 if (rect_width == 0 || rect_height == 0) {
729 _mmcam_dbg_warn("rect_width or height is 0. set camera width and height.");
731 rect_width = camera_width;
732 rect_height = camera_height;
735 caps = gst_caps_new_simple("video/x-raw-yuv",
736 "width", G_TYPE_INT, rect_width,
737 "height", G_TYPE_INT, rect_height,
739 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSINK_FILT].gst), "caps", caps);
740 MMCAMCORDER_G_OBJECT_SET((sc->element[_MMCAMCORDER_VIDEOSINK_SCALE].gst), "method", scale_method);
741 gst_caps_unref(caps);
745 if (sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst == NULL) {
746 __ta__(" videosink_queue",
747 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_QUE, "queue", "videosink_queue", element_list, err);
752 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, NULL, element_list, err);
755 if (!strcmp(videosink_name, "xvimagesink") ||
756 !strcmp(videosink_name, "ximagesink") ||
757 !strcmp(videosink_name, "evasimagesink")) {
758 if (_mmcamcorder_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) {
759 _mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
760 err = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
761 goto pipeline_creation_error;
765 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement);
767 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst), element_list)) {
768 _mmcam_dbg_err("element add error.");
769 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
770 goto pipeline_creation_error;
773 if (!_mmcamcorder_link_elements(element_list)) {
774 _mmcam_dbg_err("element link error.");
775 err = MM_ERROR_CAMCORDER_GST_LINK;
776 goto pipeline_creation_error;
779 first_element = (_MMCamcorderGstElement*)(element_list->data);
780 __ta__(" gst_element_get_static_pad",
781 pad = gst_element_get_static_pad( first_element->gst, "sink");
783 if ((gst_element_add_pad( sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst, gst_ghost_pad_new("sink", pad) )) < 0) {
784 gst_object_unref(pad);
786 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_VIDEOSINK_BIN.");
787 err = MM_ERROR_CAMCORDER_GST_LINK;
788 goto pipeline_creation_error;
791 gst_object_unref(pad);
795 g_list_free(element_list);
799 _mmcam_dbg_log("END");
801 return MM_ERROR_NONE;
803 pipeline_creation_error:
804 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_QUE);
805 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_SCALE);
806 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_FILT);
807 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_CLS);
808 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_SINK);
809 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSINK_BIN);
811 g_list_free(element_list);
819 int _mmcamcorder_create_encodesink_bin(MMHandleType handle)
821 int err = MM_ERROR_NONE;
828 int encodebin_profile = 0;
829 int auto_audio_convert = 0;
830 int auto_audio_resample = 0;
831 int auto_color_space = 0;
832 char *gst_element_venc_name = NULL;
833 char *gst_element_aenc_name = NULL;
834 char *gst_element_ienc_name = NULL;
835 char *gst_element_mux_name = NULL;
836 char *gst_element_rsink_name = NULL;
837 char *str_profile = NULL;
838 char *str_aac = NULL;
839 char *str_aar = NULL;
840 char *str_acs = NULL;
841 char *err_name = NULL;
843 GstCaps *caps = NULL;
845 GList *element_list = NULL;
847 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
848 _MMCamcorderSubContext *sc = NULL;
849 type_element *VideoencElement = NULL;
850 type_element *AudioencElement = NULL;
851 type_element *ImageencElement = NULL;
852 type_element *MuxElement = NULL;
853 type_element *RecordsinkElement = NULL;
855 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
857 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
858 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
859 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
863 /* Check existence */
864 if (sc->element[_MMCAMCORDER_ENCSINK_BIN].gst) {
865 if (((GObject *)sc->element[_MMCAMCORDER_ENCSINK_BIN].gst)->ref_count > 0) {
866 gst_object_unref(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst);
868 _mmcam_dbg_log("_MMCAMCORDER_ENCSINK_BIN is Already existed.");
871 /* Create bin element */
872 __ta__(" encodesink_bin",
873 _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_ENCSINK_BIN, "encodesink_bin", err);
876 /* Create child element */
878 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_ENCBIN, "encodebin", NULL, element_list, err);
881 /* check element availability */
882 err = mm_camcorder_get_attributes(handle, &err_name,
883 MMCAM_MODE, &profile,
884 MMCAM_AUDIO_ENCODER, &audio_enc,
885 MMCAM_AUDIO_CHANNEL, &channel,
886 MMCAM_VIDEO_ENCODER_BITRATE, &v_bitrate,
887 MMCAM_AUDIO_ENCODER_BITRATE, &a_bitrate,
889 if (err != MM_ERROR_NONE) {
890 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
891 SAFE_FREE (err_name);
895 _mmcam_dbg_log("Profile[%d]", profile);
897 /* Set information */
898 if (profile == MM_CAMCORDER_MODE_VIDEO) {
899 str_profile = "VideoProfile";
900 str_aac = "VideoAutoAudioConvert";
901 str_aar = "VideoAutoAudioResample";
902 str_acs = "VideoAutoColorSpace";
903 } else if (profile == MM_CAMCORDER_MODE_AUDIO) {
904 str_profile = "AudioProfile";
905 str_aac = "AudioAutoAudioConvert";
906 str_aar = "AudioAutoAudioResample";
907 str_acs = "AudioAutoColorSpace";
908 } else if (profile == MM_CAMCORDER_MODE_IMAGE) {
909 str_profile = "ImageProfile";
910 str_aac = "ImageAutoAudioConvert";
911 str_aar = "ImageAutoAudioResample";
912 str_acs = "ImageAutoColorSpace";
915 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_profile, &encodebin_profile);
916 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_aac, &auto_audio_convert);
917 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_aar, &auto_audio_resample);
918 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main, CONFIGURE_CATEGORY_MAIN_RECORD, str_acs, &auto_color_space);
920 _mmcam_dbg_log("Profile:%d, AutoAudioConvert:%d, AutoAudioResample:%d, AutoColorSpace:%d",
921 encodebin_profile, auto_audio_convert, auto_audio_resample, auto_color_space);
923 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "profile", encodebin_profile);
924 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", auto_audio_convert);
925 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", auto_audio_resample);
926 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", auto_color_space);
927 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", FALSE);
930 if (profile == MM_CAMCORDER_MODE_VIDEO) {
931 int use_venc_queue = 0;
933 VideoencElement = _mmcamcorder_get_type_element(handle, MM_CAM_VIDEO_ENCODER);
935 if (!VideoencElement) {
936 _mmcam_dbg_err("Fail to get type element");
937 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
938 goto pipeline_creation_error;
941 _mmcamcorder_conf_get_value_element_name(VideoencElement, &gst_element_venc_name);
943 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "venc-name", gst_element_venc_name);
944 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_VENC, "video-encode", err);
946 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
947 CONFIGURE_CATEGORY_MAIN_RECORD,
948 "UseVideoEncoderQueue",
950 if (use_venc_queue) {
951 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_VENC_QUE, "use-venc-queue", err);
954 if (!strcmp(gst_element_venc_name, "ari_h263enc")) {
955 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", TRUE);
959 if (sc->is_slow == FALSE) {
960 if (profile == MM_CAMCORDER_MODE_AUDIO || profile == MM_CAMCORDER_MODE_VIDEO) {
961 int use_aenc_queue =0;
963 AudioencElement = _mmcamcorder_get_type_element(handle, MM_CAM_AUDIO_ENCODER);
964 if (!AudioencElement) {
965 _mmcam_dbg_err("Fail to get type element");
966 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
967 goto pipeline_creation_error;
970 _mmcamcorder_conf_get_value_element_name(AudioencElement, &gst_element_aenc_name);
972 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "aenc-name", gst_element_aenc_name);
973 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_AENC, "audio-encode", err);
975 if (audio_enc == MM_AUDIO_CODEC_AMR && channel == 2) {
976 caps = gst_caps_new_simple("audio/x-raw-int",
977 "channels", G_TYPE_INT, 1,
979 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
980 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
981 gst_caps_unref (caps);
985 if (audio_enc == MM_AUDIO_CODEC_OGG) {
986 caps = gst_caps_new_simple("audio/x-raw-int",
988 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", TRUE);
989 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "acaps", caps);
990 gst_caps_unref (caps);
992 _mmcam_dbg_log("***** MM_AUDIO_CODEC_OGG : setting audio/x-raw-int ");
995 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
996 CONFIGURE_CATEGORY_MAIN_RECORD,
997 "UseAudioEncoderQueue",
999 if (use_aenc_queue) {
1000 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_AENC_QUE, "use-aenc-queue", err);
1005 if (profile == MM_CAMCORDER_MODE_IMAGE) {
1006 ImageencElement = _mmcamcorder_get_type_element(handle, MM_CAM_IMAGE_ENCODER);
1007 if (!ImageencElement) {
1008 _mmcam_dbg_err("Fail to get type element");
1009 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1010 goto pipeline_creation_error;
1013 _mmcamcorder_conf_get_value_element_name(ImageencElement, &gst_element_ienc_name);
1015 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "ienc-name", gst_element_ienc_name);
1016 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_IENC, "image-encode", err);
1020 if (profile == MM_CAMCORDER_MODE_AUDIO || profile == MM_CAMCORDER_MODE_VIDEO) {
1021 MuxElement = _mmcamcorder_get_type_element(handle, MM_CAM_FILE_FORMAT);
1023 _mmcam_dbg_err("Fail to get type element");
1024 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1025 goto pipeline_creation_error;
1028 _mmcamcorder_conf_get_value_element_name(MuxElement, &gst_element_mux_name);
1031 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "mux-name", gst_element_mux_name);
1033 _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_MUX, "mux", err);
1035 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_MUX].gst, MuxElement);
1039 if (profile == MM_CAMCORDER_MODE_AUDIO || profile == MM_CAMCORDER_MODE_VIDEO) {
1040 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1041 CONFIGURE_CATEGORY_MAIN_RECORD,
1042 "RecordsinkElement",
1043 &RecordsinkElement );
1044 _mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
1046 __ta__(" Recordsink_sink",
1047 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_SINK, gst_element_rsink_name, NULL, element_list, err);
1050 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_SINK].gst, RecordsinkElement);
1054 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_ENCSINK_SINK, "fakesink", NULL, element_list, err);
1058 if (profile == MM_CAMCORDER_MODE_VIDEO) {
1059 /* video encoder attribute setting */
1060 if (v_bitrate > 0) {
1061 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate);
1063 _mmcam_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate);
1065 /*MMCAMCORDER_G_OBJECT_SET ((sc->element[_MMCAMCORDER_ENCSINK_VENC].gst),"hw-accel", v_hw);*/
1066 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_ENCSINK_VENC].gst, VideoencElement);
1069 if (sc->is_slow == FALSE) {
1070 if (profile == MM_CAMCORDER_MODE_AUDIO || profile == MM_CAMCORDER_MODE_VIDEO) {
1071 /* audio encoder attribute setting */
1072 if (a_bitrate > 0) {
1073 switch (audio_enc) {
1074 case MM_AUDIO_CODEC_AMR:
1075 result = __mmcamcorder_get_amrnb_bitrate_mode(a_bitrate);
1077 _mmcam_dbg_log("Set AMR encoder[%s] mode [%d]", gst_element_aenc_name, result);
1079 if(!strcmp(gst_element_aenc_name, "ari_amrnbenc")) {
1080 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "mode", result);
1082 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "band-mode", result);
1085 case MM_AUDIO_CODEC_AAC:
1086 _mmcam_dbg_log("Set AAC encoder[%s] bitrate [%d]", gst_element_aenc_name, a_bitrate);
1087 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, "bitrate", a_bitrate);
1090 _mmcam_dbg_log("Audio codec is not AMR or AAC... you need to implement setting function for audio encoder bit-rate");
1094 _mmcam_dbg_warn("Setting bitrate is too small, so skip setting. Use DEFAULT value.");
1096 _mmcamcorder_conf_set_value_element_property( sc->element[_MMCAMCORDER_ENCSINK_AENC].gst, AudioencElement );
1100 _mmcam_dbg_log("Element creation complete");
1102 /* Add element to bin */
1103 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst), element_list)) {
1104 _mmcam_dbg_err("element add error.");
1105 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1106 goto pipeline_creation_error;
1109 _mmcam_dbg_log("Element add complete");
1111 if (profile == MM_CAMCORDER_MODE_VIDEO) {
1112 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "video");
1113 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) {
1114 gst_object_unref(pad);
1116 _mmcam_dbg_err("failed to create ghost video_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1117 err = MM_ERROR_CAMCORDER_GST_LINK;
1118 goto pipeline_creation_error;
1120 gst_object_unref(pad);
1123 if (sc->is_slow == FALSE) {
1124 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "audio");
1125 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
1126 gst_object_unref(pad);
1128 _mmcam_dbg_err("failed to create ghost audio_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1129 err = MM_ERROR_CAMCORDER_GST_LINK;
1130 goto pipeline_creation_error;
1132 gst_object_unref(pad);
1135 } else if (profile == MM_CAMCORDER_MODE_AUDIO) {
1136 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "audio");
1137 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) {
1138 gst_object_unref(pad);
1140 _mmcam_dbg_err("failed to create ghost audio_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1141 err = MM_ERROR_CAMCORDER_GST_LINK;
1142 goto pipeline_creation_error;
1144 gst_object_unref(pad);
1148 pad = gst_element_get_request_pad(sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "image");
1149 if (gst_element_add_pad(sc->element[_MMCAMCORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) {
1150 gst_object_unref(pad);
1152 _mmcam_dbg_err("failed to create ghost image_sink0 on _MMCAMCORDER_ENCSINK_BIN.");
1153 err = MM_ERROR_CAMCORDER_GST_LINK;
1154 goto pipeline_creation_error;
1156 gst_object_unref(pad);
1160 _mmcam_dbg_log("Get pad complete");
1162 /* Link internal element */
1163 if (!_mmcamcorder_link_elements(element_list)) {
1164 _mmcam_dbg_err("element link error.");
1165 err = MM_ERROR_CAMCORDER_GST_LINK;
1166 goto pipeline_creation_error;
1170 g_list_free(element_list);
1171 element_list = NULL;
1174 return MM_ERROR_NONE;
1176 pipeline_creation_error :
1177 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_ENCBIN);
1178 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_VENC);
1179 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_AENC);
1180 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_IENC);
1181 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_MUX);
1182 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_SINK);
1183 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_ENCSINK_BIN);
1185 g_list_free(element_list);
1186 element_list = NULL;
1193 int _mmcamcorder_create_stillshotsink_bin(MMHandleType handle)
1195 int err = MM_ERROR_NONE;
1196 int capture_width = 0;
1197 int capture_height = 0;
1198 int UseCaptureMode = 0;
1199 char *gst_element_ienc_name = NULL;
1200 char *gst_element_videoscale_name = NULL;
1202 GList *element_list = NULL;
1205 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1206 _MMCamcorderSubContext *sc = NULL;
1207 _MMCamcorderGstElement *first_element = NULL;
1208 type_element* ImageencElement = NULL;
1209 type_element* VideoscaleElement = NULL;
1211 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1213 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1214 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1215 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1219 /* Check existence */
1220 if (sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst) {
1221 if (((GObject *)sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst)->ref_count > 0) {
1222 gst_object_unref(sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst);
1224 _mmcam_dbg_log("_MMCAMCORDER_STILLSHOTSINK_BIN is Already existed. Unref once...");
1227 /* Check element availability */
1228 ImageencElement = _mmcamcorder_get_type_element(handle, MM_CAM_IMAGE_ENCODER);
1229 if (!ImageencElement) {
1230 _mmcam_dbg_err("Fail to get type element");
1231 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1232 goto pipeline_creation_error;
1235 _mmcamcorder_conf_get_value_element_name(ImageencElement, &gst_element_ienc_name);
1237 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
1238 CONFIGURE_CATEGORY_MAIN_CAPTURE,
1242 /* Create bin element */
1243 __ta__(" stillshotsink_bin",
1244 _MMCAMCORDER_BIN_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_BIN, "stillshotsink_bin", err);
1247 /* Create child element */
1248 __ta__(" stillshotsink_queue",
1249 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_QUE, "queue", NULL, element_list, err);
1251 __ta__(" stillshotsink_toggle",
1252 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_TOGGLE, "toggle", NULL, element_list, err);
1255 if (UseCaptureMode) {
1256 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1257 CONFIGURE_CATEGORY_MAIN_CAPTURE,
1258 "VideoscaleElement",
1259 &VideoscaleElement);
1260 _mmcamcorder_conf_get_value_element_name(VideoscaleElement, &gst_element_videoscale_name);
1262 __ta__(" stillshotsink_videoscale",
1263 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_SCALE, "gst_element_videoscale_name", NULL, element_list, err);
1265 __ta__(" stillshotsink_videocrop",
1266 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_CROP, "videocrop", NULL, element_list, err);
1268 __ta__(" stillshotsink_capsfiltern",
1269 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_FILT, "capsfilter", NULL, element_list, err);
1273 __ta__(" image encoder",
1274 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_ENC, gst_element_ienc_name, NULL, element_list, err);
1278 _MMCAMCORDER_ELEMENT_MAKE(sc, _MMCAMCORDER_STILLSHOTSINK_SINK, "fakesink", NULL, element_list, err);
1281 if (UseCaptureMode) {
1282 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_STILLSHOTSINK_SCALE].gst, VideoscaleElement);
1285 mm_camcorder_get_attributes(handle, NULL,
1286 MMCAM_CAPTURE_WIDTH, &capture_width,
1287 MMCAM_CAPTURE_HEIGHT, &capture_height,
1290 __ta__(" _mmcamcorder_set_resize_property",
1291 err = _mmcamcorder_set_resize_property(handle, capture_width, capture_height);
1293 if (err != MM_ERROR_NONE) {
1295 _mmcam_dbg_log("Set resize property failed.");
1296 goto pipeline_creation_error;
1300 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst), element_list)) {
1301 _mmcam_dbg_err( "element add error." );
1302 err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1303 goto pipeline_creation_error;
1306 if (!_mmcamcorder_link_elements(element_list)) {
1307 _mmcam_dbg_err( "element link error." );
1308 err = MM_ERROR_CAMCORDER_GST_LINK;
1309 goto pipeline_creation_error;
1312 first_element = (_MMCamcorderGstElement*)(element_list->data);
1314 pad = gst_element_get_static_pad(first_element->gst, "sink");
1315 if (gst_element_add_pad( sc->element[_MMCAMCORDER_STILLSHOTSINK_BIN].gst, gst_ghost_pad_new("sink", pad)) < 0) {
1316 gst_object_unref(pad);
1318 _mmcam_dbg_err("failed to create ghost pad on _MMCAMCORDER_STILLSHOTSINK_BIN.");
1319 err = MM_ERROR_CAMCORDER_GST_LINK;
1320 goto pipeline_creation_error;
1322 gst_object_unref(pad);
1326 g_list_free(element_list);
1327 element_list = NULL;
1330 return MM_ERROR_NONE;
1332 pipeline_creation_error :
1333 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_QUE);
1334 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_TOGGLE);
1335 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_CROP);
1336 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_FILT);
1337 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_SCALE);
1338 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_ENC);
1339 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_SINK);
1340 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_STILLSHOTSINK_BIN);
1342 g_list_free(element_list);
1343 element_list = NULL;
1350 int _mmcamcorder_create_preview_pipeline(MMHandleType handle)
1352 int err = MM_ERROR_NONE;
1354 GstPad *srcpad = NULL;
1355 GstPad *sinkpad = NULL;
1358 mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1359 _MMCamcorderSubContext *sc = NULL;
1361 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1363 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1364 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1365 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1369 /** Create gstreamer element **/
1371 _MMCAMCORDER_PIPELINE_MAKE(sc, _MMCAMCORDER_MAIN_PIPE, "camcorder_pipeline", err);
1374 __ta__(" __mmcamcorder_create_videosrc_bin",
1375 err = _mmcamcorder_create_videosrc_bin((MMHandleType)hcamcorder);
1377 if (err != MM_ERROR_NONE ) {
1378 goto pipeline_creation_error;
1381 __ta__(" _mmcamcorder_create_videosink_bin",
1382 err = _mmcamcorder_create_videosink_bin((MMHandleType)hcamcorder);
1384 if (err != MM_ERROR_NONE ) {
1385 goto pipeline_creation_error;
1388 gst_bin_add_many(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst),
1389 sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst,
1390 sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst,
1393 /* Link each element */
1394 srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_BIN].gst, "src0");
1395 sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_BIN].gst, "sink");
1396 _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
1398 /* Set data probe function */
1399 srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "src");
1400 MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW,
1401 __mmcamcorder_video_dataprobe_preview, hcamcorder);
1402 gst_object_unref(srcpad);
1405 if (hcamcorder->type == MM_CAMCORDER_MODE_IMAGE) {
1406 sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "sink");
1407 MMCAMCORDER_ADD_BUFFER_PROBE(sinkpad, _MMCAMCORDER_HANDLER_PREVIEW,
1408 __mmcamcorder_video_dataprobe_vsink, hcamcorder);
1409 } else if (hcamcorder->type == MM_CAMCORDER_MODE_VIDEO) {
1410 sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "sink");
1411 MMCAMCORDER_ADD_BUFFER_PROBE(sinkpad, _MMCAMCORDER_HANDLER_PREVIEW,
1412 __mmcamcorder_video_dataprobe_vsink_drop_by_time, hcamcorder);
1414 gst_object_unref(sinkpad);
1417 /* Register message callback */
1418 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
1419 hcamcorder->pipeline_cb_event_id = gst_bus_add_watch(bus, _mmcamcorder_pipeline_cb_message, hcamcorder);
1420 gst_object_unref(bus);
1423 /* Below signals are meaningfull only when video source is using. */
1424 MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
1425 _MMCAMCORDER_HANDLER_PREVIEW,
1427 _mmcamcorder_negosig_handler,
1430 return MM_ERROR_NONE;
1432 pipeline_creation_error:
1433 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_VIDEOSRC_BIN);
1434 _MMCAMCORDER_ELEMENT_REMOVE(sc, _MMCAMCORDER_MAIN_PIPE);
1439 void _mmcamcorder_negosig_handler(GstElement *videosrc, MMHandleType handle)
1441 mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1442 _MMCamcorderSubContext *sc = NULL;
1446 mmf_return_if_fail(hcamcorder);
1447 mmf_return_if_fail(hcamcorder->sub_context);
1448 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1450 /* kernel was modified. No need to set.
1451 _mmcamcorder_set_attribute_to_camsensor(handle);
1454 if (sc->cam_stability_count != _MMCAMCORDER_CAMSTABLE_COUNT) {
1455 sc->cam_stability_count = _MMCAMCORDER_CAMSTABLE_COUNT;
1458 if (hcamcorder->type == MM_CAMCORDER_MODE_IMAGE) {
1459 _MMCamcorderImageInfo *info = NULL;
1461 if (info->resolution_change == TRUE) {
1462 _mmcam_dbg_log("open toggle of stillshot sink.");
1463 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
1464 info->resolution_change = FALSE;
1470 int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* VideosinkElement)
1472 int err = MM_ERROR_NONE;
1479 int rotation = MM_DISPLAY_ROTATION_NONE;
1480 int rotation_degree = 0;
1481 int display_device = MM_DISPLAY_DEVICE_MAINLCD;
1482 int display_mode = 0;
1483 int display_geometry_method = MM_DISPLAY_METHOD_LETTER_BOX;
1484 int origin_size = 0;
1487 int *overlay = NULL;
1489 char *err_name = NULL;
1490 char *videosink_name = NULL;
1492 GstElement *vsink = NULL;
1494 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1495 _MMCamcorderSubContext *sc = NULL;
1499 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1501 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1502 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1503 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1504 mmf_return_val_if_fail(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1506 vsink = sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst;
1508 /* Get video display information */
1509 __ta__(" videosink get attributes",
1510 err = mm_camcorder_get_attributes(handle, &err_name,
1511 MMCAM_DISPLAY_RECT_X, &retx,
1512 MMCAM_DISPLAY_RECT_Y, &rety,
1513 MMCAM_DISPLAY_RECT_WIDTH, &retwidth,
1514 MMCAM_DISPLAY_RECT_HEIGHT, &retheight,
1515 MMCAM_DISPLAY_ROTATION, &rotation,
1516 MMCAM_DISPLAY_VISIBLE, &visible,
1517 MMCAM_DISPLAY_HANDLE, (void**)&overlay, &size,
1518 MMCAM_DISPLAY_DEVICE, &display_device,
1519 MMCAM_DISPLAY_GEOMETRY_METHOD, &display_geometry_method,
1520 MMCAM_DISPLAY_SCALE, &zoom_attr,
1523 if (err != MM_ERROR_NONE) {
1524 _mmcam_dbg_warn("Get display attrs fail. (%s:%x)", err_name, err);
1525 SAFE_FREE(err_name);
1529 _mmcam_dbg_log("(overlay=%p, size=%d)", overlay, size);
1531 _mmcamcorder_conf_get_value_element_name(VideosinkElement, &videosink_name);
1534 if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "ximagesink")) {
1537 _mmcam_dbg_log("xid = %lu )", xid);
1538 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink), xid);
1540 _mmcam_dbg_warn( "Set xid as 0.. but, it's not recommended." );
1541 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(vsink), 0);
1544 _mmcam_dbg_log("%s set: display_geometry_method[%d],origin-size[%d],visible[%d],rotate[enum:%d]",
1545 videosink_name, display_geometry_method, origin_size, visible, rotation);
1546 } else if (!strcmp(videosink_name, "evasimagesink")) {
1548 MMCAMCORDER_G_OBJECT_SET( vsink, "evas-object", overlay );
1550 _mmcam_dbg_err("Evas Object pointer is NULL");
1551 return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1554 _mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name);
1558 if (!strcmp(videosink_name, "xvimagesink")) {
1560 case MM_DISPLAY_ROTATION_NONE :
1561 rotation_degree = 0;
1563 case MM_DISPLAY_ROTATION_90 :
1564 rotation_degree = 1;
1566 case MM_DISPLAY_ROTATION_180 :
1567 rotation_degree = 2;
1569 case MM_DISPLAY_ROTATION_270 :
1570 rotation_degree = 3;
1573 _mmcam_dbg_warn("Unsupported rotation value. set as default(0).");
1574 rotation_degree = 0;
1578 switch (zoom_attr) {
1579 case MM_DISPLAY_SCALE_DEFAULT:
1582 case MM_DISPLAY_SCALE_DOUBLE_LENGTH:
1585 case MM_DISPLAY_SCALE_TRIPLE_LENGTH:
1589 _mmcam_dbg_warn("Unsupported zoom value. set as default.");
1594 switch (display_device) {
1595 case MM_DISPLAY_DEVICE_TVOUT:
1598 case MM_DISPLAY_DEVICE_MAINLCD_AND_TVOUT:
1601 case MM_DISPLAY_DEVICE_MAINLCD:
1602 case MM_DISPLAY_DEVICE_SUBLCD:
1603 case MM_DISPLAY_DEVICE_MAINLCD_AND_SUBLCD:
1609 MMCAMCORDER_G_OBJECT_SET(vsink, "display-geometry-method", display_geometry_method);
1610 MMCAMCORDER_G_OBJECT_SET(vsink, "display-mode", display_mode);
1611 MMCAMCORDER_G_OBJECT_SET(vsink, "visible", visible);
1612 MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation_degree);
1613 MMCAMCORDER_G_OBJECT_SET(vsink, "zoom", zoom_level);
1615 if (display_geometry_method == MM_DISPLAY_METHOD_CUSTOM_ROI) {
1619 "dst-roi-w", retwidth,
1620 "dst-roi-h", retheight,
1625 return MM_ERROR_NONE;
1629 int _mmcamcorder_vframe_stablize(MMHandleType handle)
1631 mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
1632 _MMCamcorderSubContext *sc = NULL;
1634 _mmcam_dbg_log("%d", _MMCAMCORDER_CAMSTABLE_COUNT);
1636 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1638 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1640 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1642 if (sc->cam_stability_count != _MMCAMCORDER_CAMSTABLE_COUNT) {
1643 sc->cam_stability_count = _MMCAMCORDER_CAMSTABLE_COUNT;
1646 return MM_ERROR_NONE;
1649 /* Retreive device information and set them to attributes */
1650 gboolean _mmcamcorder_get_device_info(MMHandleType handle)
1652 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1653 _MMCamcorderSubContext *sc = NULL;
1654 GstCameraControl *control = NULL;
1655 GstCameraControlExifInfo exif_info = {0,};
1657 mmf_return_val_if_fail(hcamcorder, FALSE);
1658 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1660 if (sc && sc->element) {
1661 int err = MM_ERROR_NONE;
1662 char *err_name = NULL;
1663 double focal_len = 0.0;
1665 /* Video input device */
1666 if (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
1667 /* Exif related information */
1668 control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
1669 if (control != NULL) {
1670 gst_camera_control_get_exif_info(control, &exif_info); //get video input device information
1671 focal_len = ((double)exif_info.focal_len_numerator) / ((double) exif_info.focal_len_denominator);
1673 _mmcam_dbg_err("Fail to get camera control interface!");
1678 /* Set values to attributes */
1679 err = mm_camcorder_set_attributes(handle, &err_name,
1680 MMCAM_CAMERA_FOCAL_LENGTH, focal_len,
1682 if (err != MM_ERROR_NONE) {
1683 _mmcam_dbg_err("Set attributes error(%s:%x)!", err_name, err);
1691 _mmcam_dbg_warn( "Sub context isn't exist.");
1699 static gboolean __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstBuffer *buffer, gpointer u_data)
1701 int current_state = MM_CAMCORDER_STATE_NONE;
1703 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1704 _MMCamcorderSubContext *sc = NULL;
1705 _MMCamcorderKPIMeasure *kpi = NULL;
1707 mmf_return_val_if_fail(hcamcorder, TRUE);
1709 sc = MMF_CAMCORDER_SUBCONTEXT(u_data);
1710 mmf_return_val_if_fail(sc, TRUE);
1712 current_state = hcamcorder->state;
1714 if (sc->drop_vframe > 0) {
1715 if (sc->pass_first_vframe > 0) {
1716 sc->pass_first_vframe--;
1717 _mmcam_dbg_log("Pass video frame by pass_first_vframe");
1720 _mmcam_dbg_log("Drop video frame by drop_vframe");
1723 } else if (sc->cam_stability_count > 0) {
1724 sc->cam_stability_count--;
1725 _mmcam_dbg_log("Drop video frame by cam_stability_count");
1729 if (current_state >= MM_CAMCORDER_STATE_PREPARE) {
1731 int frame_count = 0;
1732 struct timeval current_video_time;
1735 if (kpi->init_video_time.tv_sec == kpi->last_video_time.tv_sec &&
1736 kpi->init_video_time.tv_usec == kpi->last_video_time.tv_usec &&
1737 kpi->init_video_time.tv_usec == 0) {
1738 _mmcam_dbg_log("START to measure FPS");
1739 gettimeofday(&(kpi->init_video_time), NULL);
1742 frame_count = ++(kpi->video_framecount);
1744 gettimeofday(¤t_video_time, NULL);
1745 diff_sec = current_video_time.tv_sec - kpi->last_video_time.tv_sec;
1746 if (diff_sec != 0) {
1747 kpi->current_fps = (frame_count - kpi->last_framecount) / diff_sec;
1748 if ((current_video_time.tv_sec - kpi->init_video_time.tv_sec) != 0) {
1749 int framecount = kpi->video_framecount;
1750 int elased_sec = current_video_time.tv_sec - kpi->init_video_time.tv_sec;
1751 kpi->average_fps = framecount / elased_sec;
1754 kpi->last_framecount = frame_count;
1755 kpi->last_video_time.tv_sec = current_video_time.tv_sec;
1756 kpi->last_video_time.tv_usec = current_video_time.tv_usec;
1758 _mmcam_dbg_log("current fps(%d), average(%d)", kpi->current_fps, kpi->average_fps);
1767 static gboolean __mmcamcorder_video_dataprobe_vsink(GstPad *pad, GstBuffer *buffer, gpointer u_data)
1769 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1771 mmf_return_val_if_fail(hcamcorder, FALSE);
1773 if (buffer == NULL || GST_BUFFER_DATA(buffer) == NULL) {
1774 _mmcam_dbg_err("Null buffer!!");
1778 if (hcamcorder->vstream_cb && buffer) {
1779 GstCaps *caps = NULL;
1780 GstStructure *structure = NULL;
1781 int state = MM_CAMCORDER_STATE_NULL;
1782 unsigned int fourcc = 0;
1783 MMCamcorderVideoStreamDataType stream;
1785 state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
1786 if (state < MM_CAMCORDER_STATE_PREPARE) {
1787 _mmcam_dbg_warn("Not ready for stream callback");
1791 caps = gst_buffer_get_caps(buffer);
1793 _mmcam_dbg_warn( "Caps is NULL." );
1797 structure = gst_caps_get_structure( caps, 0 );
1798 gst_structure_get_int(structure, "width", &(stream.width));
1799 gst_structure_get_int(structure, "height", &(stream.height));
1800 gst_structure_get_fourcc(structure, "format", &fourcc);
1801 stream.format = _mmcamcorder_get_pixtype(fourcc);
1802 gst_caps_unref( caps );
1806 _mmcam_dbg_log( "Call video steramCb, data[%p], Width[%d],Height[%d], Format[%d]",
1807 GST_BUFFER_DATA(buffer), stream.width, stream.height, stream.format );
1810 if (stream.width == 0 || stream.height == 0) {
1811 _mmcam_dbg_warn("Wrong condition!!");
1815 stream.data = (void *)GST_BUFFER_DATA(buffer);
1816 stream.length = GST_BUFFER_SIZE(buffer);
1817 stream.timestamp = (unsigned int)(GST_BUFFER_TIMESTAMP(buffer)/1000000); /* nano sec -> mili sec */
1819 _MMCAMCORDER_LOCK_VSTREAM_CALLBACK(hcamcorder);
1820 if (hcamcorder->vstream_cb) {
1821 hcamcorder->vstream_cb(&stream, hcamcorder->vstream_cb_param);
1823 _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK(hcamcorder);
1830 static gboolean __mmcamcorder_video_dataprobe_vsink_drop_by_time(GstPad *pad, GstBuffer *buffer, gpointer u_data)
1832 static GstClockTime next_time = 0;
1833 static GstClockTime current_time = 0;
1834 GstClockTime interval = 30 * GST_MSECOND; //30ms(about 33 fps)
1836 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
1837 _MMCamcorderSubContext *sc = NULL;
1839 mmf_return_val_if_fail(hcamcorder, TRUE);
1841 sc = MMF_CAMCORDER_SUBCONTEXT(u_data);
1842 mmf_return_val_if_fail(sc, TRUE);
1845 _mmcam_dbg_log("VIDEO SRC time stamp : [%" GST_TIME_FORMAT "]", GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
1848 /* Call video stream callback */
1849 if (__mmcamcorder_video_dataprobe_vsink(pad, buffer, u_data) == FALSE) {
1850 _mmcam_dbg_warn( "__mmcamcorder_video_dataprobe_vsink failed." );
1855 if (GST_BUFFER_TIMESTAMP(buffer) < current_time) {
1858 current_time = GST_BUFFER_TIMESTAMP(buffer);
1860 if (current_time >= next_time) {
1861 next_time = current_time + interval;
1872 int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate)
1874 int result = MM_CAMCORDER_MR475;
1876 if (bitrate< 5150) {
1877 result = MM_CAMCORDER_MR475; /*AMR475*/
1878 } else if (bitrate< 5900) {
1879 result = MM_CAMCORDER_MR515; /*AMR515*/
1880 } else if (bitrate < 6700) {
1881 result = MM_CAMCORDER_MR59; /*AMR59*/
1882 } else if (bitrate< 7400) {
1883 result = MM_CAMCORDER_MR67; /*AMR67*/
1884 } else if (bitrate< 7950) {
1885 result = MM_CAMCORDER_MR74; /*AMR74*/
1886 } else if (bitrate < 10200) {
1887 result = MM_CAMCORDER_MR795; /*AMR795*/
1888 } else if (bitrate < 12200) {
1889 result = MM_CAMCORDER_MR102; /*AMR102*/
1891 result = MM_CAMCORDER_MR122; /*AMR122*/
1897 int _mmcamcorder_get_eos_message(MMHandleType handle)
1899 double elapsed = 0.0;
1901 GstMessage *gMessage = NULL;
1903 GstClockTime timeout = 1 * GST_SECOND; /* maximum waiting time */
1904 GTimer *timer = NULL;
1906 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1907 _MMCamcorderSubContext *sc = NULL;
1909 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1910 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1914 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
1915 timer = g_timer_new();
1917 if (sc && !(sc->bget_eos)) {
1919 elapsed = g_timer_elapsed(timer, NULL);
1921 /*_mmcam_dbg_log("elapsed:%f sec", elapsed);*/
1923 if (elapsed > _MMCAMCORDER_WAIT_EOS_TIME) {
1924 _mmcam_dbg_warn("Timeout. EOS isn't received.");
1925 g_timer_destroy(timer);
1926 gst_object_unref(bus);
1927 return MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT;
1930 gMessage = gst_bus_timed_pop (bus, timeout);
1931 if (gMessage != NULL) {
1932 _mmcam_dbg_log("Get message(%x).", GST_MESSAGE_TYPE(gMessage));
1933 _mmcamcorder_pipeline_cb_message(bus, gMessage, (void*)hcamcorder);
1935 if (GST_MESSAGE_TYPE(gMessage) == GST_MESSAGE_EOS || sc->bget_eos) {
1936 gst_message_unref(gMessage);
1939 gst_message_unref(gMessage);
1941 _mmcam_dbg_log("timeout of gst_bus_timed_pop()");
1943 _mmcam_dbg_log("Get EOS in another thread.");
1950 g_timer_destroy(timer);
1951 gst_object_unref(bus);
1953 _mmcam_dbg_log("END");
1955 return MM_ERROR_NONE;
1959 void _mmcamcorder_remove_element_handle(MMHandleType handle, int first_elem, int last_elem)
1962 _MMCamcorderSubContext *sc = NULL;
1964 mmf_return_if_fail(handle);
1966 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1967 mmf_return_if_fail(sc);
1968 mmf_return_if_fail(sc->element);
1969 mmf_return_if_fail((first_elem > 0) && (last_elem > 0) && (last_elem > first_elem));
1973 for (i = first_elem ; i <= last_elem ; i++) {
1974 sc->element[i].gst = NULL;
1975 sc->element[i].id = _MMCAMCORDER_NONE;
1982 int _mmcamcorder_check_audiocodec_fileformat_compatibility(MMHandleType handle)
1984 int err = MM_ERROR_NONE;
1985 int audio_codec = MM_AUDIO_CODEC_INVALID;
1986 int file_format = MM_FILE_FORMAT_INVALID;
1988 char *err_name = NULL;
1990 err = mm_camcorder_get_attributes(handle, &err_name,
1991 MMCAM_AUDIO_ENCODER, &audio_codec,
1992 MMCAM_FILE_FORMAT, &file_format,
1994 if (err != MM_ERROR_NONE) {
1995 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
1996 SAFE_FREE(err_name);
2000 /* Check compatibility between audio codec and file format */
2001 if (audio_codec >= MM_AUDIO_CODEC_INVALID && audio_codec < MM_AUDIO_CODEC_NUM &&
2002 file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
2003 if (audiocodec_fileformat_compatibility_table[audio_codec][file_format] == 0) {
2004 _mmcam_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.",
2005 audio_codec, file_format);
2006 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2009 _mmcam_dbg_log("Audio codec[%d] and file format[%d] compatibility SUCCESS.",
2010 audio_codec, file_format);
2012 _mmcam_dbg_err("Audio codec[%d] or file format[%d] is INVALID.",
2013 audio_codec, file_format);
2014 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2017 return MM_ERROR_NONE;
2021 int _mmcamcorder_check_videocodec_fileformat_compatibility(MMHandleType handle)
2023 int err = MM_ERROR_NONE;
2024 int video_codec = MM_VIDEO_CODEC_INVALID;
2025 int file_format = MM_FILE_FORMAT_INVALID;
2027 char *err_name = NULL;
2029 err = mm_camcorder_get_attributes(handle, &err_name,
2030 MMCAM_VIDEO_ENCODER, &video_codec,
2031 MMCAM_FILE_FORMAT, &file_format,
2033 if (err != MM_ERROR_NONE) {
2034 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
2035 SAFE_FREE(err_name);
2039 /* Check compatibility between audio codec and file format */
2040 if (video_codec >= MM_VIDEO_CODEC_INVALID && video_codec < MM_VIDEO_CODEC_NUM &&
2041 file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
2042 if (videocodec_fileformat_compatibility_table[video_codec][file_format] == 0) {
2043 _mmcam_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.",
2044 video_codec, file_format);
2045 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2048 _mmcam_dbg_log("Video codec[%d] and file format[%d] compatibility SUCCESS.",
2049 video_codec, file_format);
2051 _mmcam_dbg_err("Video codec[%d] or file format[%d] is INVALID.",
2052 video_codec, file_format);
2053 return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
2056 return MM_ERROR_NONE;
2060 bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate)
2062 char* videosink_name = NULL;
2064 mmf_camcorder_t *hcamcorder = NULL;
2065 _MMCamcorderSubContext *sc = NULL;
2067 hcamcorder = MMF_CAMCORDER(handle);
2068 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2070 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2071 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2072 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2074 if (sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst) {
2075 /* Get videosink name */
2076 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
2077 if (!strcmp(videosink_name, "xvimagesink")) {
2078 if (display_rotate < MM_DISPLAY_ROTATION_NONE ||
2079 display_rotate > MM_DISPLAY_ROTATION_270) {
2081 _mmcam_dbg_log( "Rotate: Out of range. set as default(0)...");
2083 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst,
2084 "rotate", display_rotate);
2085 _mmcam_dbg_log("Set display-rotate [%d] done.", display_rotate);
2088 _mmcam_dbg_warn("videosink[%s] does not support DISPLAY_ROTATION.", videosink_name);
2092 _mmcam_dbg_err("Videosink element is null");
2098 bool _mmcamcorder_set_videosrc_rotation(MMHandleType handle, int videosrc_rotate)
2108 gboolean do_set_caps = FALSE;
2110 GstCaps *caps = NULL;
2112 type_int_array *input_index = NULL;
2113 mmf_camcorder_t *hcamcorder = NULL;
2114 _MMCamcorderSubContext *sc = NULL;
2116 hcamcorder = MMF_CAMCORDER(handle);
2117 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2119 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
2120 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2121 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2123 if (!sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
2124 _mmcam_dbg_err("Video src is NULL!");
2128 if (!sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst) {
2129 _mmcam_dbg_err("Video filter is NULL!");
2133 mm_camcorder_get_attributes(handle, NULL,
2134 MMCAM_CAMERA_WIDTH, &width,
2135 MMCAM_CAMERA_HEIGHT, &height,
2136 MMCAM_CAMERA_FPS, &fps,
2137 "camera-slow-motion-fps", &slow_fps,
2140 _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
2141 CONFIGURE_CATEGORY_CTRL_CAMERA,
2144 if (input_index == NULL) {
2145 _mmcam_dbg_err("Failed to get input_index");
2149 /* Define width, height, rotate and flip in caps */
2150 if (input_index->default_value == MM_VIDEO_DEVICE_CAMERA1) {
2151 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "vflip", 1);
2153 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "vflip", 0);
2155 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hflip", 0);
2157 /* This will be applied when rotate is 0, 90, 180, 270 if rear camera.
2158 This will be applied when rotate is 0, 180 if front camera. */
2159 set_rotate = videosrc_rotate * 90;
2161 if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_90 ||
2162 videosrc_rotate == MM_VIDEO_INPUT_ROTATION_270) {
2166 if (input_index->default_value == MM_VIDEO_DEVICE_CAMERA1) {
2167 if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_90) {
2175 set_height = height;
2177 if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_FLIP_HORZ) {
2179 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hflip", 1);
2180 } else if (videosrc_rotate == MM_VIDEO_INPUT_ROTATION_FLIP_VERT) {
2182 if (input_index->default_value == MM_VIDEO_DEVICE_CAMERA1) {
2183 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "vflip", 0);
2185 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "vflip", 1);
2190 set_fps = sc->is_slow ? slow_fps : fps;
2192 MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", &caps);
2194 GstStructure *structure = NULL;
2196 structure = gst_caps_get_structure(caps, 0);
2199 int caps_height = 0;
2201 int caps_rotate = 0;
2203 gst_structure_get_int(structure, "width", &caps_width);
2204 gst_structure_get_int(structure, "height", &caps_height);
2205 gst_structure_get_int(structure, "fps", &caps_fps);
2206 gst_structure_get_int(structure, "rotate", &caps_rotate);
2207 if (set_width == caps_width && set_height == caps_height &&
2208 set_rotate == caps_rotate && set_fps == caps_fps) {
2209 _mmcam_dbg_log("No need to replace caps.");
2211 _mmcam_dbg_log("something is different. set new one...");
2215 _mmcam_dbg_log("can not get structure of caps. set new one...");
2219 gst_caps_unref(caps);
2222 _mmcam_dbg_log("No caps. set new one...");
2227 caps = gst_caps_new_simple("video/x-raw-yuv",
2228 "format", GST_TYPE_FOURCC, sc->fourcc,
2229 "width", G_TYPE_INT, set_width,
2230 "height", G_TYPE_INT, set_height,
2231 "framerate", GST_TYPE_FRACTION, set_fps, 1,
2232 "rotate", G_TYPE_INT, set_rotate,
2234 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps);
2235 gst_caps_unref(caps);
2237 _mmcam_dbg_log("vidoesrc new caps set. format[%c%c%c%c],width[%d],height[%d],fps[%d],rotate[%d]",
2238 (sc->fourcc), (sc->fourcc)>>8, (sc->fourcc)>>16, (sc->fourcc)>>24,
2239 set_width, set_height, set_fps, set_rotate);