2 * Copyright (C) 2012 Canonical Ltd
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <hybris/camera/camera_compatibility_layer.h>
19 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
21 #include <hybris/input/input_stack_compatibility_layer.h>
22 #include <hybris/input/input_stack_compatibility_layer_codes_key.h>
23 #include <hybris/input/input_stack_compatibility_layer_flags_key.h>
24 #include <hybris/input/input_stack_compatibility_layer_flags_motion.h>
27 #include <GLES2/gl2.h>
28 #include <GLES2/gl2ext.h>
38 #include <sys/types.h>
41 int32_t current_zoom_level
= 1;
42 bool new_camera_frame_available
= true;
44 static GLuint gProgram
;
45 static GLuint gaPositionHandle
, gaTexHandle
, gsTextureHandle
, gmTexMatrix
;
47 EffectMode
next_effect()
49 static EffectMode current_effect
= EFFECT_MODE_NONE
;
51 EffectMode next
= current_effect
;
53 switch (current_effect
) {
54 case EFFECT_MODE_NONE
:
55 next
= EFFECT_MODE_MONO
;
57 case EFFECT_MODE_MONO
:
58 next
= EFFECT_MODE_NEGATIVE
;
60 case EFFECT_MODE_NEGATIVE
:
61 next
= EFFECT_MODE_SOLARIZE
;
63 case EFFECT_MODE_SOLARIZE
:
64 next
= EFFECT_MODE_SEPIA
;
66 case EFFECT_MODE_SEPIA
:
67 next
= EFFECT_MODE_POSTERIZE
;
69 case EFFECT_MODE_POSTERIZE
:
70 next
= EFFECT_MODE_WHITEBOARD
;
72 case EFFECT_MODE_WHITEBOARD
:
73 next
= EFFECT_MODE_BLACKBOARD
;
75 case EFFECT_MODE_BLACKBOARD
:
76 next
= EFFECT_MODE_AQUA
;
78 case EFFECT_MODE_AQUA
:
79 next
= EFFECT_MODE_NONE
;
83 current_effect
= next
;
87 void error_msg_cb(void* context
)
89 printf("%s \n", __PRETTY_FUNCTION__
);
92 void shutter_msg_cb(void* context
)
94 printf("%s \n", __PRETTY_FUNCTION__
);
97 void zoom_msg_cb(void* context
, int32_t new_zoom_level
)
99 printf("%s \n", __PRETTY_FUNCTION__
);
101 struct CameraControl
* cc
= (struct CameraControl
*) context
;
103 current_zoom_level
= new_zoom_level
;
106 void autofocus_msg_cb(void* context
)
108 printf("%s \n", __PRETTY_FUNCTION__
);
111 void raw_data_cb(void* data
, uint32_t data_size
, void* context
)
113 printf("%s: %d \n", __PRETTY_FUNCTION__
, data_size
);
116 void jpeg_data_cb(void* data
, uint32_t data_size
, void* context
)
118 printf("%s: %d \n", __PRETTY_FUNCTION__
, data_size
);
121 sprintf(fn
, "/tmp/shot_%d.jpeg", shot_counter
);
122 int fd
= open(fn
, O_RDWR
| O_CREAT
, S_IRUSR
| S_IWUSR
);
123 ssize_t ret
= write(fd
, data
, data_size
);
127 struct CameraControl
* cc
= (struct CameraControl
*) context
;
128 android_camera_start_preview(cc
);
131 void size_cb(void* ctx
, int width
, int height
)
133 printf("Supported size: [%d,%d]\n", width
, height
);
136 void preview_texture_needs_update_cb(void* ctx
)
138 new_camera_frame_available
= true;
141 void on_new_input_event(struct Event
* event
, void* context
)
145 if (event
->type
== KEY_EVENT_TYPE
&& event
->action
== ISCL_KEY_EVENT_ACTION_UP
) {
146 printf("We have got a key event: %d \n", event
->details
.key
.key_code
);
148 struct CameraControl
* cc
= (struct CameraControl
*) context
;
150 switch(event
->details
.key
.key_code
) {
151 case ISCL_KEYCODE_VOLUME_UP
:
152 printf("\tZooming in now.\n");
153 android_camera_start_zoom(cc
, current_zoom_level
+1);
155 case ISCL_KEYCODE_VOLUME_DOWN
:
156 printf("\tZooming out now.\n");
157 android_camera_start_zoom(cc
, current_zoom_level
-1);
159 case ISCL_KEYCODE_POWER
:
160 printf("\tTaking a photo now.\n");
161 android_camera_take_snapshot(cc
);
163 case ISCL_KEYCODE_HEADSETHOOK
:
164 printf("\tSwitching effect.\n");
165 android_camera_set_effect_mode(cc
, next_effect());
168 } else if (event
->type
== MOTION_EVENT_TYPE
&&
169 event
->details
.motion
.pointer_count
== 1) {
170 if ((event
->action
& ISCL_MOTION_EVENT_ACTION_MASK
) == ISCL_MOTION_EVENT_ACTION_UP
) {
171 printf("\tMotion event(Action up): (%f, %f) \n",
172 event
->details
.motion
.pointer_coordinates
[0].x
,
173 event
->details
.motion
.pointer_coordinates
[0].y
);
176 if ((event
->action
& ISCL_MOTION_EVENT_ACTION_MASK
) == ISCL_MOTION_EVENT_ACTION_DOWN
) {
177 printf("\tMotion event(Action down): (%f, %f) \n",
178 event
->details
.motion
.pointer_coordinates
[0].x
,
179 event
->details
.motion
.pointer_coordinates
[0].y
);
184 static const char* vertex_shader()
187 "#extension GL_OES_EGL_image_external : require \n"
188 "attribute vec4 a_position; \n"
189 "attribute vec2 a_texCoord; \n"
190 "uniform mat4 m_texMatrix; \n"
191 "varying vec2 v_texCoord; \n"
192 "varying float topDown; \n"
195 " gl_Position = a_position; \n"
196 " v_texCoord = a_texCoord; \n"
197 // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
198 // " topDown = v_texCoord.y; \n"
202 static const char* fragment_shader()
205 "#extension GL_OES_EGL_image_external : require \n"
206 "precision mediump float; \n"
207 "varying vec2 v_texCoord; \n"
208 "uniform samplerExternalOES s_texture; \n"
211 " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
215 static GLuint
loadShader(GLenum shaderType
, const char* pSource
) {
216 GLuint shader
= glCreateShader(shaderType
);
219 glShaderSource(shader
, 1, &pSource
, NULL
);
220 glCompileShader(shader
);
222 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &compiled
);
226 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &infoLen
);
228 char* buf
= (char*) malloc(infoLen
);
230 glGetShaderInfoLog(shader
, infoLen
, NULL
, buf
);
231 fprintf(stderr
, "Could not compile shader %d:\n%s\n",
235 glDeleteShader(shader
);
240 printf("Error, during shader creation: %i\n", glGetError());
246 static GLuint
create_program(const char* pVertexSource
, const char* pFragmentSource
) {
247 GLuint vertexShader
= loadShader(GL_VERTEX_SHADER
, pVertexSource
);
249 printf("vertex shader not compiled\n");
253 GLuint pixelShader
= loadShader(GL_FRAGMENT_SHADER
, pFragmentSource
);
255 printf("frag shader not compiled\n");
259 GLuint program
= glCreateProgram();
261 glAttachShader(program
, vertexShader
);
262 glAttachShader(program
, pixelShader
);
263 glLinkProgram(program
);
264 GLint linkStatus
= GL_FALSE
;
265 glGetProgramiv(program
, GL_LINK_STATUS
, &linkStatus
);
267 if (linkStatus
!= GL_TRUE
) {
269 glGetProgramiv(program
, GL_INFO_LOG_LENGTH
, &bufLength
);
271 char* buf
= (char*) malloc(bufLength
);
273 glGetProgramInfoLog(program
, bufLength
, NULL
, buf
);
274 fprintf(stderr
, "Could not link program:\n%s\n", buf
);
278 glDeleteProgram(program
);
286 int main(int argc
, char** argv
)
288 struct CameraControlListener listener
;
289 memset(&listener
, 0, sizeof(listener
));
290 listener
.on_msg_error_cb
= error_msg_cb
;
291 listener
.on_msg_shutter_cb
= shutter_msg_cb
;
292 listener
.on_msg_focus_cb
= autofocus_msg_cb
;
293 listener
.on_msg_zoom_cb
= zoom_msg_cb
;
295 listener
.on_data_raw_image_cb
= raw_data_cb
;
296 listener
.on_data_compressed_image_cb
= jpeg_data_cb
;
297 listener
.on_preview_texture_needs_update_cb
= preview_texture_needs_update_cb
;
298 struct CameraControl
* cc
= android_camera_connect_to(FRONT_FACING_CAMERA_TYPE
,
301 printf("Problem connecting to camera");
305 listener
.context
= cc
;
307 struct AndroidEventListener event_listener
;
308 event_listener
.on_new_event
= on_new_input_event
;
309 event_listener
.context
= cc
;
311 struct InputStackConfiguration input_configuration
= { false, 25000, 1024, 1024 };
313 android_input_stack_initialize(&event_listener
, &input_configuration
);
314 android_input_stack_start();
316 android_camera_dump_parameters(cc
);
317 android_camera_enumerate_supported_picture_sizes(cc
, size_cb
, NULL
);
318 android_camera_enumerate_supported_preview_sizes(cc
, size_cb
, NULL
);
320 int min_fps
, max_fps
, current_fps
;
321 android_camera_get_preview_fps_range(cc
, &min_fps
, &max_fps
);
322 printf("Preview fps range: [%d,%d]\n", min_fps
, max_fps
);
323 android_camera_get_preview_fps(cc
, ¤t_fps
);
324 printf("Current preview fps range: %d\n", current_fps
);
326 android_camera_set_preview_size(cc
, 960, 720);
329 android_camera_get_preview_size(cc
, &width
, &height
);
330 printf("Current preview size: [%d,%d]\n", width
, height
);
331 android_camera_get_picture_size(cc
, &width
, &height
);
332 printf("Current picture size: [%d,%d]\n", width
, height
);
334 android_camera_get_max_zoom(cc
, &zoom
);
335 printf("Max zoom: %d \n", zoom
);
336 android_camera_set_zoom(cc
, 10);
338 EffectMode effect_mode
;
339 FlashMode flash_mode
;
340 WhiteBalanceMode wb_mode
;
341 SceneMode scene_mode
;
342 AutoFocusMode af_mode
;
343 android_camera_get_effect_mode(cc
, &effect_mode
);
344 android_camera_get_flash_mode(cc
, &flash_mode
);
345 android_camera_get_white_balance_mode(cc
, &wb_mode
);
346 android_camera_get_scene_mode(cc
, &scene_mode
);
347 android_camera_get_auto_focus_mode(cc
, &af_mode
);
348 printf("Current effect mode: %d \n", effect_mode
);
349 printf("Current flash mode: %d \n", flash_mode
);
350 printf("Current wb mode: %d \n", wb_mode
);
351 printf("Current scene mode: %d \n", scene_mode
);
352 printf("Current af mode: %d \n", af_mode
);
353 FocusRegion fr
= { top
: -200, left
: -200, bottom
: 200, right
: 200, weight
: 300};
354 android_camera_set_focus_region(cc
, &fr
);
368 EGL_CONTEXT_CLIENT_VERSION
, 2,
372 EGLDisplay disp
= eglGetDisplay(NULL
);
373 assert(eglGetError() == EGL_SUCCESS
);
374 assert(disp
!= EGL_NO_DISPLAY
);
376 rv
= eglInitialize(disp
, 0, 0);
377 assert(eglGetError() == EGL_SUCCESS
);
378 assert(rv
== EGL_TRUE
);
380 eglChooseConfig((EGLDisplay
) disp
, attr
, &ecfg
, 1, &num_config
);
381 assert(eglGetError() == EGL_SUCCESS
);
382 assert(rv
== EGL_TRUE
);
384 EGLSurface surface
= eglCreateWindowSurface((EGLDisplay
) disp
, ecfg
,
385 (EGLNativeWindowType
) NULL
, NULL
);
386 assert(eglGetError() == EGL_SUCCESS
);
387 assert(surface
!= EGL_NO_SURFACE
);
389 context
= eglCreateContext((EGLDisplay
) disp
, ecfg
, EGL_NO_CONTEXT
, ctxattr
);
390 assert(eglGetError() == EGL_SUCCESS
);
391 assert(context
!= EGL_NO_CONTEXT
);
393 assert(eglMakeCurrent((EGLDisplay
) disp
, surface
, surface
, context
) == EGL_TRUE
);
395 gProgram
= create_program(vertex_shader(), fragment_shader());
396 gaPositionHandle
= glGetAttribLocation(gProgram
, "a_position");
397 gaTexHandle
= glGetAttribLocation(gProgram
, "a_texCoord");
398 gsTextureHandle
= glGetUniformLocation(gProgram
, "s_texture");
399 gmTexMatrix
= glGetUniformLocation(gProgram
, "m_texMatrix");
401 GLuint preview_texture_id
;
402 glGenTextures(1, &preview_texture_id
);
403 glClearColor(1.0, 0., 0.5, 1.);
404 glTexParameteri(GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
405 glTexParameteri(GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
407 GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
409 GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
410 android_camera_set_preview_texture(cc
, preview_texture_id
);
411 android_camera_set_effect_mode(cc
, EFFECT_MODE_SEPIA
);
412 android_camera_set_flash_mode(cc
, FLASH_MODE_AUTO
);
413 android_camera_set_auto_focus_mode(cc
, AUTO_FOCUS_MODE_CONTINUOUS_PICTURE
);
414 android_camera_start_preview(cc
);
416 GLfloat transformation_matrix
[16];
417 android_camera_get_preview_texture_transformation(cc
, transformation_matrix
);
418 glUniformMatrix4fv(gmTexMatrix
, 1, GL_FALSE
, transformation_matrix
);
420 printf("Started camera preview.\n");
423 /*if (new_camera_frame_available)
425 printf("Updating texture");
426 new_camera_frame_available = false;
428 static GLfloat vVertices
[] = { 0.0f
, 0.0f
, 0.0f
, // Position 0
429 0.0f
, 0.0f
, // TexCoord 0
430 0.0f
, 1.0f
, 0.0f
, // Position 1
431 0.0f
, 1.0f
, // TexCoord 1
432 1.0f
, 1.0f
, 0.0f
, // Position 2
433 1.0f
, 1.0f
, // TexCoord 2
434 1.0f
, 0.0f
, 0.0f
, // Position 3
435 1.0f
, 0.0f
// TexCoord 3
438 GLushort indices
[] = { 0, 1, 2, 0, 2, 3 };
441 // Clear the color buffer
442 glClear(GL_COLOR_BUFFER_BIT
);
443 // Use the program object
444 glUseProgram(gProgram
);
446 glEnableVertexAttribArray(gaPositionHandle
);
447 glEnableVertexAttribArray(gaTexHandle
);
448 // Load the vertex position
449 glVertexAttribPointer(gaPositionHandle
,
455 // Load the texture coordinate
456 glVertexAttribPointer(gaTexHandle
,
463 glActiveTexture(GL_TEXTURE0
);
464 // Set the sampler texture unit to 0
465 glUniform1i(gsTextureHandle
, 0);
466 glUniform1i(gmTexMatrix
, 0);
467 android_camera_update_preview_texture(cc
);
468 glDrawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, indices
);
469 glDisableVertexAttribArray(gaPositionHandle
);
470 glDisableVertexAttribArray(gaTexHandle
);
472 eglSwapBuffers((EGLDisplay
) disp
, surface
);