3dphotoshoot

annotate src/android/camera.c @ 9:d1b456d08713

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