Imported Upstream version 0.1.0+git20131207+e452e83
[deb_libhybris.git] / compat / camera / direct_camera_test.cpp
1 /*
2 * Copyright (C) 2013 Canonical Ltd
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
18 */
19
20 #include <hybris/camera/camera_compatibility_layer.h>
21 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
22
23 #include <hybris/input/input_stack_compatibility_layer.h>
24 #include <hybris/input/input_stack_compatibility_layer_codes_key.h>
25 #include <hybris/input/input_stack_compatibility_layer_flags_key.h>
26 #include <hybris/input/input_stack_compatibility_layer_flags_motion.h>
27
28 #include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
29
30 #include <gui/ISurfaceComposer.h>
31
32 #include <GLES2/gl2.h>
33 #include <GLES2/gl2ext.h>
34
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39
40 #include <cassert>
41 #include <cstdio>
42 #include <cstdlib>
43 #include <cstring>
44
45 int shot_counter = 1;
46 int32_t current_zoom_level = 1;
47 bool new_camera_frame_available = true;
48
49 EffectMode next_effect()
50 {
51 static EffectMode current_effect = EFFECT_MODE_NONE;
52
53 EffectMode next = current_effect;
54
55 switch (current_effect) {
56 case EFFECT_MODE_NONE:
57 next = EFFECT_MODE_MONO;
58 break;
59 case EFFECT_MODE_MONO:
60 next = EFFECT_MODE_NEGATIVE;
61 break;
62 case EFFECT_MODE_NEGATIVE:
63 next = EFFECT_MODE_SOLARIZE;
64 break;
65 case EFFECT_MODE_SOLARIZE:
66 next = EFFECT_MODE_SEPIA;
67 break;
68 case EFFECT_MODE_SEPIA:
69 next = EFFECT_MODE_POSTERIZE;
70 break;
71 case EFFECT_MODE_POSTERIZE:
72 next = EFFECT_MODE_WHITEBOARD;
73 break;
74 case EFFECT_MODE_WHITEBOARD:
75 next = EFFECT_MODE_BLACKBOARD;
76 break;
77 case EFFECT_MODE_BLACKBOARD:
78 next = EFFECT_MODE_AQUA;
79 break;
80 case EFFECT_MODE_AQUA:
81 next = EFFECT_MODE_NONE;
82 break;
83 }
84
85 current_effect = next;
86 return next;
87 }
88
89 void error_msg_cb(void* context)
90 {
91 printf("%s \n", __PRETTY_FUNCTION__);
92 }
93
94 void shutter_msg_cb(void* context)
95 {
96 printf("%s \n", __PRETTY_FUNCTION__);
97 }
98
99 void zoom_msg_cb(void* context, int32_t new_zoom_level)
100 {
101 printf("%s \n", __PRETTY_FUNCTION__);
102
103 CameraControl* cc = static_cast<CameraControl*>(context);
104 static int zoom;
105 android_camera_get_current_zoom(cc, &zoom);
106 printf("\t Current zoom: %d\n", zoom);
107 current_zoom_level = new_zoom_level;
108 }
109
110 void autofocus_msg_cb(void* context)
111 {
112 printf("%s \n", __PRETTY_FUNCTION__);
113 }
114
115 void raw_data_cb(void* data, uint32_t data_size, void* context)
116 {
117 printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
118 }
119
120 void jpeg_data_cb(void* data, uint32_t data_size, void* context)
121 {
122 printf("%s: %d \n", __PRETTY_FUNCTION__, data_size);
123
124 char fn[256];
125 sprintf(fn, "/data/shot_%d.jpeg", shot_counter);
126 int fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
127 write(fd, data, data_size);
128 close(fd);
129 shot_counter++;
130
131 CameraControl* cc = static_cast<CameraControl*>(context);
132 android_camera_start_preview(cc);
133 }
134
135 void size_cb(void* ctx, int width, int height)
136 {
137 printf("Supported size: [%d,%d]\n", width, height);
138 }
139
140 void preview_texture_needs_update_cb(void* ctx)
141 {
142 new_camera_frame_available = true;
143 }
144
145 void on_new_input_event(Event* event, void* context)
146 {
147 assert(context);
148
149 if (event->type == KEY_EVENT_TYPE && event->action == ISCL_KEY_EVENT_ACTION_UP) {
150 printf("We have got a key event: %d \n", event->details.key.key_code);
151
152 CameraControl* cc = static_cast<CameraControl*>(context);
153
154 switch(event->details.key.key_code) {
155 case ISCL_KEYCODE_VOLUME_UP:
156 printf("\tZooming in now.\n");
157 android_camera_start_zoom(cc, current_zoom_level+1);
158 break;
159 case ISCL_KEYCODE_VOLUME_DOWN:
160 printf("\tZooming out now.\n");
161 android_camera_start_zoom(cc, current_zoom_level-1);
162 break;
163 case ISCL_KEYCODE_POWER:
164 printf("\tTaking a photo now.\n");
165 android_camera_take_snapshot(cc);
166 break;
167 case ISCL_KEYCODE_HEADSETHOOK:
168 printf("\tSwitching effect.\n");
169 android_camera_set_effect_mode(cc, next_effect());
170 }
171 } else if (event->type == MOTION_EVENT_TYPE &&
172 event->details.motion.pointer_count == 1) {
173 if ((event->action & ISCL_MOTION_EVENT_ACTION_MASK) == ISCL_MOTION_EVENT_ACTION_UP) {
174 printf("\tMotion event(Action up): (%f, %f) \n",
175 event->details.motion.pointer_coordinates[0].x,
176 event->details.motion.pointer_coordinates[0].y);
177 }
178
179 if ((event->action & ISCL_MOTION_EVENT_ACTION_MASK) == ISCL_MOTION_EVENT_ACTION_DOWN) {
180 printf("\tMotion event(Action down): (%f, %f) \n",
181 event->details.motion.pointer_coordinates[0].x,
182 event->details.motion.pointer_coordinates[0].y);
183 }
184 }
185 }
186
187 struct ClientWithSurface
188 {
189 SfClient* client;
190 SfSurface* surface;
191 };
192
193 ClientWithSurface client_with_surface(bool setup_surface_with_egl)
194 {
195 ClientWithSurface cs = ClientWithSurface();
196
197 cs.client = sf_client_create();
198
199 if (!cs.client) {
200 printf("Problem creating client ... aborting now.");
201 return cs;
202 }
203
204 static const size_t primary_display = 0;
205
206 SfSurfaceCreationParameters params = {
207 0,
208 0,
209 (int) sf_get_display_width(primary_display),
210 (int) sf_get_display_height(primary_display),
211 -1, //PIXEL_FORMAT_RGBA_8888,
212 15000,
213 0.5f,
214 setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL
215 "CameraCompatLayerTestSurface"
216 };
217
218 cs.surface = sf_surface_create(cs.client, &params);
219
220 if (!cs.surface) {
221 printf("Problem creating surface ... aborting now.");
222 return cs;
223 }
224
225 sf_surface_make_current(cs.surface);
226
227 return cs;
228 }
229
230 #define PRINT_GLERROR() printf("GL error@%d: %x\n", __LINE__, glGetError());
231
232 struct RenderData
233 {
234 static const char* vertex_shader()
235 {
236 return
237 "#extension GL_OES_EGL_image_external : require \n"
238 "attribute vec4 a_position; \n"
239 "attribute vec2 a_texCoord; \n"
240 "uniform mat4 m_texMatrix; \n"
241 "varying vec2 v_texCoord; \n"
242 "varying float topDown; \n"
243 "void main() \n"
244 "{ \n"
245 " gl_Position = a_position; \n"
246 " v_texCoord = a_texCoord; \n"
247 // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
248 //" topDown = v_texCoord.y; \n"
249 "} \n";
250 }
251
252 static const char* fragment_shader()
253 {
254 return
255 "#extension GL_OES_EGL_image_external : require \n"
256 "precision mediump float; \n"
257 "varying vec2 v_texCoord; \n"
258 "uniform samplerExternalOES s_texture; \n"
259 "void main() \n"
260 "{ \n"
261 " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
262 "} \n";
263 }
264
265 static GLuint loadShader(GLenum shaderType, const char* pSource)
266 {
267 GLuint shader = glCreateShader(shaderType);
268
269 if (shader) {
270 glShaderSource(shader, 1, &pSource, NULL);
271 glCompileShader(shader);
272 GLint compiled = 0;
273 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
274
275 if (!compiled) {
276 GLint infoLen = 0;
277 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
278 if (infoLen) {
279 char* buf = (char*) malloc(infoLen);
280 if (buf) {
281 glGetShaderInfoLog(shader, infoLen, NULL, buf);
282 fprintf(stderr, "Could not compile shader %d:\n%s\n",
283 shaderType, buf);
284 free(buf);
285 }
286 glDeleteShader(shader);
287 shader = 0;
288 }
289 }
290 } else {
291 printf("Error, during shader creation: %i\n", glGetError());
292 }
293
294 return shader;
295 }
296
297 static GLuint create_program(const char* pVertexSource, const char* pFragmentSource)
298 {
299 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
300 if (!vertexShader) {
301 printf("vertex shader not compiled\n");
302 return 0;
303 }
304
305 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
306 if (!pixelShader) {
307 printf("frag shader not compiled\n");
308 return 0;
309 }
310
311 GLuint program = glCreateProgram();
312 if (program) {
313 glAttachShader(program, vertexShader);
314 glAttachShader(program, pixelShader);
315 glLinkProgram(program);
316 GLint linkStatus = GL_FALSE;
317 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
318
319 if (linkStatus != GL_TRUE) {
320 GLint bufLength = 0;
321 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
322 if (bufLength) {
323 char* buf = (char*) malloc(bufLength);
324 if (buf) {
325 glGetProgramInfoLog(program, bufLength, NULL, buf);
326 fprintf(stderr, "Could not link program:\n%s\n", buf);
327 free(buf);
328 }
329 }
330 glDeleteProgram(program);
331 program = 0;
332 }
333 }
334
335 return program;
336 }
337
338 RenderData() : program_object(create_program(vertex_shader(), fragment_shader()))
339 {
340 position_loc = glGetAttribLocation(program_object, "a_position");
341 tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord");
342 sampler_loc = glGetUniformLocation(program_object, "s_texture");
343 matrix_loc = glGetUniformLocation(program_object, "m_texMatrix");
344 }
345
346 // Handle to a program object
347 GLuint program_object;
348 // Attribute locations
349 GLint position_loc;
350 GLint tex_coord_loc;
351 // Sampler location
352 GLint sampler_loc;
353 // Matrix location
354 GLint matrix_loc;
355 };
356
357 int main(int argc, char** argv)
358 {
359 CameraControlListener listener;
360 memset(&listener, 0, sizeof(listener));
361 listener.on_msg_error_cb = error_msg_cb;
362 listener.on_msg_shutter_cb = shutter_msg_cb;
363 listener.on_msg_focus_cb = autofocus_msg_cb;
364 listener.on_msg_zoom_cb = zoom_msg_cb;
365
366 listener.on_data_raw_image_cb = raw_data_cb;
367 listener.on_data_compressed_image_cb = jpeg_data_cb;
368 listener.on_preview_texture_needs_update_cb = preview_texture_needs_update_cb;
369 CameraControl* cc = android_camera_connect_to(FRONT_FACING_CAMERA_TYPE,
370 &listener);
371
372 if (cc == NULL) {
373 printf("Problem connecting to camera");
374 return 1;
375 }
376
377 listener.context = cc;
378
379 AndroidEventListener event_listener;
380 event_listener.on_new_event = on_new_input_event;
381 event_listener.context = cc;
382
383 InputStackConfiguration input_configuration = { true, 25000 };
384
385 android_input_stack_initialize(&event_listener, &input_configuration);
386 android_input_stack_start();
387
388 android_camera_dump_parameters(cc);
389 android_camera_enumerate_supported_picture_sizes(cc, size_cb, NULL);
390 android_camera_enumerate_supported_preview_sizes(cc, size_cb, NULL);
391
392 int min_fps, max_fps, current_fps;
393 android_camera_get_preview_fps_range(cc, &min_fps, &max_fps);
394 printf("Preview fps range: [%d,%d]\n", min_fps, max_fps);
395 android_camera_get_preview_fps(cc, &current_fps);
396 printf("Current preview fps range: %d\n", current_fps);
397
398 android_camera_set_preview_size(cc, 960, 720);
399
400 int width, height;
401 android_camera_get_preview_size(cc, &width, &height);
402 printf("Current preview size: [%d,%d]\n", width, height);
403 android_camera_get_picture_size(cc, &width, &height);
404 printf("Current picture size: [%d,%d]\n", width, height);
405 int zoom;
406 android_camera_get_current_zoom(cc, &zoom);
407 printf("Current zoom: %d \n", zoom);
408 android_camera_get_max_zoom(cc, &zoom);
409 printf("Max zoom: %d \n", zoom);
410
411 EffectMode effect_mode;
412 FlashMode flash_mode;
413 WhiteBalanceMode wb_mode;
414 SceneMode scene_mode;
415 AutoFocusMode af_mode;
416 CameraPixelFormat pixel_format;
417 android_camera_get_effect_mode(cc, &effect_mode);
418 android_camera_get_flash_mode(cc, &flash_mode);
419 android_camera_get_white_balance_mode(cc, &wb_mode);
420 android_camera_get_scene_mode(cc, &scene_mode);
421 android_camera_get_auto_focus_mode(cc, &af_mode);
422 android_camera_get_preview_format(cc, &pixel_format);
423 printf("Current effect mode: %d \n", effect_mode);
424 printf("Current flash mode: %d \n", flash_mode);
425 printf("Current wb mode: %d \n", wb_mode);
426 printf("Current scene mode: %d \n", scene_mode);
427 printf("Current af mode: %d \n", af_mode);
428 printf("Current preview pixel format: %d \n", pixel_format);
429 //android_camera_set_focus_region(cc, -200, -200, 200, 200, 300);
430
431 ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */);
432
433 if (!cs.surface) {
434 printf("Problem acquiring surface for preview");
435 return 1;
436 }
437
438 EGLDisplay disp = sf_client_get_egl_display(cs.client);
439 EGLSurface surface = sf_surface_get_egl_surface(cs.surface);
440
441 RenderData render_data;
442 GLuint preview_texture_id;
443 glGenTextures(1, &preview_texture_id);
444 glClearColor(1.0, 0., 0.5, 1.);
445 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
446 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
447 glTexParameteri(
448 GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
449 glTexParameteri(
450 GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
451 android_camera_set_preview_texture(cc, preview_texture_id);
452 android_camera_set_effect_mode(cc, EFFECT_MODE_SEPIA);
453 android_camera_set_flash_mode(cc, FLASH_MODE_AUTO);
454 android_camera_set_auto_focus_mode(cc, AUTO_FOCUS_MODE_CONTINUOUS_PICTURE);
455 android_camera_start_preview(cc);
456
457 GLfloat transformation_matrix[16];
458 android_camera_get_preview_texture_transformation(cc, transformation_matrix);
459 glUniformMatrix4fv(render_data.matrix_loc, 1, GL_FALSE, transformation_matrix);
460
461 printf("Started camera preview.\n");
462
463 while (true) {
464 /*if (new_camera_frame_available)
465 {
466 printf("Updating texture");
467 new_camera_frame_available = false;
468 }*/
469 static GLfloat vVertices[] = { 0.0f, 0.0f, 0.0f, // Position 0
470 0.0f, 0.0f, // TexCoord 0
471 0.0f, 1.0f, 0.0f, // Position 1
472 0.0f, 1.0f, // TexCoord 1
473 1.0f, 1.0f, 0.0f, // Position 2
474 1.0f, 1.0f, // TexCoord 2
475 1.0f, 0.0f, 0.0f, // Position 3
476 1.0f, 0.0f // TexCoord 3
477 };
478
479 GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
480
481 // Set the viewport
482 // Clear the color buffer
483 glClear(GL_COLOR_BUFFER_BIT);
484 // Use the program object
485 glUseProgram(render_data.program_object);
486 // Enable attributes
487 glEnableVertexAttribArray(render_data.position_loc);
488 glEnableVertexAttribArray(render_data.tex_coord_loc);
489 // Load the vertex position
490 glVertexAttribPointer(render_data.position_loc,
491 3,
492 GL_FLOAT,
493 GL_FALSE,
494 5 * sizeof(GLfloat),
495 vVertices);
496 // Load the texture coordinate
497 glVertexAttribPointer(render_data.tex_coord_loc,
498 2,
499 GL_FLOAT,
500 GL_FALSE,
501 5 * sizeof(GLfloat),
502 vVertices+3);
503
504 glActiveTexture(GL_TEXTURE0);
505 // Set the sampler texture unit to 0
506 glUniform1i(render_data.sampler_loc, 0);
507 glUniform1i(render_data.matrix_loc, 0);
508 android_camera_update_preview_texture(cc);
509 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
510 glDisableVertexAttribArray(render_data.position_loc);
511 glDisableVertexAttribArray(render_data.tex_coord_loc);
512
513 eglSwapBuffers(disp, surface);
514 }
515 }