- 论坛徽章:
- 11
|
不知道写的对不对, 还没测试呢, android 的代码写的太费劲了; 各种鸟限制- class video_message_handler extends Handler {
- private video_cap_thread obj = null;
- public video_message_handler(video_cap_thread obj) {
- this.obj = obj;
- }
- public void handleMessage(Message msg) {
- int n = 0;
- switch (msg.what) {
- case 0: obj.timer_expires(this); break;
- default: Log.i("zylthinking", "impossible cmd " + msg.what + " issued"); break;
- }
- }
- }
- class video_cap_thread extends Thread implements SurfaceTexture.OnFrameAvailableListener, Camera.PreviewCallback {
- private static EGL11 egl = null;
- private static EGLDisplay display = null;
- private static EGLSurface surface = null;
- private static EGLContext context = null;
- private static int texname = egl_initialize(0);
- private SurfaceTexture texture = null;
- public int width = 0;
- public int height = 0;
- private int fps = 0;
- private long something = -1;
- private boolean running = false;
- private Camera camera = null;
- private Semaphore sem = null;
- public video_cap_thread(int width, int height, int fps, long something) {
- this.with = with;
- this.height = height;
- this.fps = fps * 1000;
- this.something = something;
- this.sem = new Semaphore(1);
- sem.acquire(1);
- }
- private int start_camera() {
- camera = Camera.open(0);
- Camera.Parameters params = camera.getParameters();
- List<Camera.Size> sizes = params.getSupportedPictureSizes();
- int[] intp = {0, 0};
- find_picture_size(list, this.width, this.height, intp);
- if (intp[0] == 0 || intp[1] == 0) {
- camera.release();
- camera = null;
- return -1;
- }
- params.setPictureSize(intp[0], intp[1]);
- List<int[]> range = params.getSupportedPreviewFpsRange();
- int selected_fps = find_fps(range, this.fps);
- if (selected_fps == 0) {
- camera.release();
- camera = null;
- return -1;
- }
- params.setPreviewFpsRange(selected_fps, selected_fps);
- params.set("orientation", "portrait");
- params.set("rotation", 90);
- camera.setParameters(params);
- if (-1 == reinit_camera(false)) {
- camera.release();
- camera = null;
- return -1;
- }
- int nb = intp[0] * intp[1] * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
- camera.addCallbackBuffer(new byte[nb]);
- camera.addCallbackBuffer(new byte[nb]);
- camera.addCallbackBuffer(new byte[nb]);
- camera.addCallbackBuffer(new byte[nb]);
- camera.setPreviewCallbackWithBuffer(this);
- camera.startPreview();
- running = true;
- return 0;
- }
- public void onPreviewFrame (byte[] data, Camera camera) {
- int n = mmapi.video_push(something, data);
- if (n == -1) {
- Looper.quit();
- } else {
- camera.addCallbackBuffer(data);
- }
- }
- public void onFrameAvailable(SurfaceTexture texture) {
- texture.updateTexImage();
- long stamp = texture.getTimestamp();
- }
- private int reinit_camera(boolean need_run) {
- if (running) {
- camera.stopPreview();
- running = false;
- if (texture != null) {
- texture->release();
- texture = null;
- }
- if (texname != 0) {
- int[] intp = {texname};
- glDeleteTextures(1, texname, 0);
- texname = 0;
- }
- if (context != null) {
- egl.eglDestroyContext(display, context);
- context = null;
- }
- }
- texname = egl_initialize(texname);
- if (texname == 0) {
- return -1;
- }
- Camera.Parameters params = camera.getParameters();
- try {
- texture = new SurfaceTexture(texname);
- camera.setPreviewTexture(texture);
- } catch (Exception e) {
- texture = null;
- return -1;
- }
- texture.setOnFrameAvailableListener(this);
- if (need_run) {
- camera.startPreview();
- running = true;
- }
- return 0;
- }
- public boolean camera_start_failed() {
- sem.acquire(1);
- sem = null;
- return !this.running;
- }
- public void timer_expires(video_message_handler handler) {
- if (!egl.eglMakeCurrent(display, surface, surface, context)) {
- int n = egl.eglGetError();
- if (n == EGL11.EGL_CONTEXT_LOST) {
- reinit_camera(true);
- } else {
- Log.i("zylthinking", "eglMakeCurrent failed with " + n);
- }
- }
- handler.sendEmptyMessageDelayed(0, 1000);
- }
- public void run() {
- Looper.prepare();
- video_message_handler handler = new video_message_handler(this);
- if (!handler.sendEmptyMessageDelayed(0, 1000)) {
- sem.release();
- sem = null;
- return;
- }
- int n = obj.start_camera();
- sem.release();
- sem = null;
- if (-1 == n) {
- return;
- }
- Looper.loop();
- handler = null;
- if (running) {
- camera.stopPreview();
- if (texture != null) {
- texture->release();
- texture = null;
- }
- running = false;
- }
- }
- private int find_fps(List<int[]> range, int fps) {
- int nearest = 0;
- for (int i = 0; i < range.size(); ++i) {
- int[] r = range.get(i);
- if (r[0] <= fps && r[1] >= fps) {
- return fps;
- }
- int differ = nearest - fps;
- if (r[0] > fps) {
- int n = r[0] - fps;
- if (n * n < differ * differ) {
- nearest = r[0];
- }
- } else {
- int n = r[1] - fps;
- if (n * n < differ * differ) {
- nearest = r[1];
- }
- }
- }
- return nearest;
- }
- private void find_picture_size(List<Camera.Size> list, int width, int height, int[] dim) {
- int i;
- for (i = 0; i < list.size(); ++i) {
- Camera.Size size = (Size) list.get(i);
- if (size.width == width && size.height == height) {
- dim[0] = width;
- dim[1] = height;
- return;
- }
- }
- int w1 = Integer.MAX_VALUE;
- int h1 = Integer.MAX_VALUE;
- for (i = 0; i < list.size(); ++i) {
- Camera.Size size = (Size) list.get(i);
- if (size.width >= width && size.height >= height) {
- if (w1 >= size.width && h1 >= size.height) {
- w1 = size.width;
- h1 = size.height;
- continue;
- }
- if (w1 * h1 > size.width * size.height) {
- w1 = size.width;
- h1 = size.height;
- continue;
- }
- }
- }
- if (w1 != Integer.MAX_VALUE && h1 != Integer.MAX_VALUE) {
- dim[0] = w1;
- dim[1] = h1;
- return;
- }
- w1 = 0;
- h1 = 0;
- int w2 = 0;
- int h2 = 0;
- int w3 = 0;
- int h3 = 0;
- for (i = 0; i < list.size(); ++i) {
- Camera.Size size = (Size) list.get(i);
- if (size.width >= width) {
- if (size.height > h1) {
- w1 = size.width;
- h1 = size.height;
- continue;
- }
- } else if (size.height >= height) {
- if (size.width > w2) {
- w2 = size.width;
- h2 = size.height;
- continue;
- }
- } else {
- if (w3 * h3 < size.width * size.height) {
- w3 = size.width;
- h3 = size.height;
- }
- }
- }
- if (width * h1 > w2 * height) {
- dim[0] = w1;
- dim[1] = h1;
- } else if (w2 * height > width * h1) {
- dim[0] = w2;
- dim[1] = h2;
- } else {
- dim[0] = w3;
- dim[1] = h3;
- }
- }
- private static int egl_initialize(int name) {
- if (name != 0) {
- return 0;
- }
- if (egl == null) {
- egl = (EGL11) EGLContext.getEGL();
- if (egl == null) {
- return 0;
- }
- }
- if (display == null) {
- display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- if (display == null || display == EGL10.EGL_NO_DISPLAY) {
- display = null
- return 0;
- }
- }
- // reinitialize is allowed by egl spec
- if (!egl.eglInitialize(display, null)) {
- return 0;
- }
- int[] attr = {
- EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
- EGL10.EGL_NONE
- };
- EGLConfig[] conf = new EGLConfig[1];
- if (!egl.eglChooseConfig(display, attr, conf, 1, new int[1])) {
- return 0;
- }
- if (surface == null) {
- int[] surface_attr = {
- EGL10.EGL_WIDTH, 32,
- EGL10.EGL_HEIGHT, 32,
- EGL10.EGL_NONE
- };
- surface = egl.eglCreatePbufferSurface(display, conf, surface_attr);
- if (surface == EGL10.EGL_NO_SURFACE) {
- return 0;
- }
- }
- if (context == null) {
- attr[0] = 0x3098;
- attr[1] = 2;
- attr[2] = GL10.EGL_NONE;
- context = egl.eglCreateContext(display, conf, EGL10.EGL_NO_CONTEXT, attr);
- if (context == null || context == EGL10.EGL_NO_CONTEXT) {
- context = null;
- return 0;
- }
- }
- int intp[] = new int[1];
- GLES20.glGenTextures(1, intp, 0);
- return intp[0];
- }
- }
复制代码 |
|