3dphotoshoot
view src/android/camera.c @ 18:dccbd7d65517
moved to android-19 to make it work with android 4.x
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 10 Jun 2015 18:53:28 +0300 |
parents | 9fc7d52f578d |
children | ac80210d5fbe |
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <jni.h>
5 #include "opengl.h"
6 #include "camera.h"
9 static JavaVM *jvm;
10 static JNIEnv *jni;
11 static jclass activity_class;
12 static unsigned int tex;
13 static float tex_matrix[16];
14 static const float identity_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
15 static jfloatArray jtex_matrix;
16 static int capturing;
18 int cam_init(void *platform_data)
19 {
20 int glerr;
21 struct cam_android_platform_data *pdata = platform_data;
23 jvm = pdata->vm;
24 jni = pdata->jni;
25 activity_class = pdata->activity_class;
27 jtex_matrix = (*jni)->NewFloatArray(jni, 16);
29 // create the camera texture
30 assert(glGetError() == GL_NO_ERROR);
31 glGenTextures(1, &tex);
32 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
33 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
34 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
36 glerr = glGetError();
37 assert(glerr == GL_NO_ERROR);
38 return glerr == GL_NO_ERROR ? 0 : -1;
39 }
41 void cam_shutdown(void)
42 {
43 cam_stop_video();
44 glDeleteTextures(1, &tex);
45 tex = 0;
47 if(jni) {
48 (*jni)->DeleteGlobalRef(jni, jtex_matrix);
49 }
50 }
52 unsigned int cam_texture(void)
53 {
54 return tex;
55 }
57 const float *cam_texture_matrix(void)
58 {
59 return tex_matrix;
60 }
62 int cam_start_video(void)
63 {
64 jmethodID method;
66 if(!jvm) {
67 fprintf(stderr, "failed to start video, camera not initialized\n");
68 return -1;
69 }
70 if(cam_is_capturing()) {
71 return 0;
72 }
74 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "start_video", "(I)I"))) {
75 fprintf(stderr, "failed to find static method: start_video\n");
76 return -1;
77 }
78 if((*jni)->CallStaticIntMethod(jni, activity_class, method, tex) == -1) {
79 fprintf(stderr, "failed to start video capture\n");
80 capturing = 0;
81 return -1;
82 }
83 capturing = 1;
85 printf("video started\n");
87 return 1;
88 }
90 int cam_stop_video(void)
91 {
92 jmethodID method;
94 if(!jvm) {
95 fprintf(stderr, "failed to stop video, camera not initialized\n");
96 return -1;
97 }
99 if(!cam_is_capturing()) {
100 return 0;
101 }
103 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "stop_video", "()V"))) {
104 fprintf(stderr, "failed to find static method: stop_video\n");
105 return -1;
106 }
107 (*jni)->CallStaticVoidMethod(jni, activity_class, method);
108 capturing = 0;
110 printf("video stopped\n");
112 return 0;
113 }
115 int cam_update(void)
116 {
117 static int texmat_fail_warned;
118 jmethodID method;
119 float *ptr;
121 if(!jvm) {
122 fprintf(stderr, "failed to update camera\n");
123 return -1;
124 }
125 if(!cam_is_capturing()) {
126 return 0;
127 }
129 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "update", "([F)V"))) {
130 fprintf(stderr, "failed to find static method: update\n");
131 return -1;
132 }
133 (*jni)->CallStaticVoidMethod(jni, activity_class, method, jtex_matrix);
135 if(!(ptr = (*jni)->GetFloatArrayElements(jni, jtex_matrix, 0))) {
136 if(!texmat_fail_warned) {
137 fprintf(stderr, "failed to get texture matrix\n");
138 texmat_fail_warned = 1;
139 }
140 memcpy(tex_matrix, identity_matrix, sizeof identity_matrix);
141 } else {
142 memcpy(tex_matrix, ptr, 16 * sizeof *ptr);
143 (*jni)->ReleaseFloatArrayElements(jni, jtex_matrix, ptr, JNI_ABORT);
144 }
146 return 0;
147 }
149 int cam_is_capturing(void)
150 {
151 return capturing; // XXX is it better to do this properly through JNI?
152 }
154 int cam_video_size(int *xsz, int *ysz)
155 {
156 jfieldID jwidth, jheight;
158 if(!(jwidth = (*jni)->GetStaticFieldID(jni, activity_class, "preview_width", "I")) ||
159 !(jheight = (*jni)->GetStaticFieldID(jni, activity_class, "preview_height", "I"))) {
160 fprintf(stderr, "failed to retrieve preview width/height fields\n");
161 *xsz = *ysz = 0;
162 return -1;
163 }
165 *xsz = (*jni)->GetStaticIntField(jni, activity_class, jwidth);
166 *ysz = (*jni)->GetStaticIntField(jni, activity_class, jheight);
167 return 0;
168 }
170 int cam_take_picture(void)
171 {
172 return -1; // TODO
173 }