PreviewCallback for Camera视频

时间:2013-04-01 06:15:30

标签: java android android-camera

有人可以使用PreviewCallback界面为我提供示例代码或示例来阅读Camera视频的每一帧吗?

我想在没有使用曲面的情况下获取帧,因为我想要首先拍摄相机视频的帧而不在屏幕上显示,然后我可以将该帧传递给cocos2dx的CCLayer。

1 个答案:

答案 0 :(得分:1)

这是一个缓慢的过程,无法处理传递给预览回调的每一帧数据。仅当您对实时预览应用程序的要求无法显示来自摄像机的视频或带有模板类型覆盖的摄像机视频时,才应使用它,并且您的显示器只能容忍几帧第二,有一些延迟。

一些重要步骤

  1. 您的活动必须延伸Surface Holder,您不应该开始 相机直到表面被创建。
  2. 预览仅支持每台设备上的特定尺寸( 480 x 320在我检查的最后一台设备上 - 前一段时间),但是 您的请求不会导致任何问题,它会被忽略。 当您最终收到预览回调时,请检查实际情况 onPreviewFrame()中的帧大小。
  3. 发送到byte[]的{​​{1}}数组数据位于YCbCr_422_SP中 格式。即使您尝试设置,也没有其他格式可用 他们。数据在此处描述:http://groups.google.com/group/android-developers/msg/d3b29d3ddc8abf9b
  4. 请勿尝试解码onPreviewFrame()中的数据。还不够 时间 - 如果您尝试将系统挂起,则会对相机进行软管扫描 这个功能这么久了。将数据复制到您自己的缓冲区和 在单独的onPreviewFrame()
  5. 中解码
  6. 您必须跳过处理Thread时收到的新框架 正在处理任何特定的帧。等到Thread完成之前 使用下一个可用框架中的数据。
  7. 解码YUV预览数据

    Thread

    // decode Y, U, and V values on the YUV 420 buffer // described as YCbCr_422_SP by Android - David Manpearl public static void decodeYUV(int[] out, byte[] fg, int width, int height) throws NullPointerException, IllegalArgumentException { final int sz = width * height; if(out == null) throw new NullPointerException("buffer 'out' is null"); if(out.length < sz) throw new IllegalArgumentException("buffer 'out' size " + out.length + " < minimum " + sz); if(fg == null) throw new NullPointerException("buffer 'fg' is null"); if(fg.length < sz) throw new IllegalArgumentException("buffer 'fg' size " + fg.length + " < minimum " + sz * 3/ 2); int i, j; int Y, Cr = 0, Cb = 0; for(j = 0; j < height; j++) { int pixPtr = j * width; final int jDiv2 = j >> 1; for(i = 0; i < width; i++) { Y = fg[pixPtr]; if(Y < 0) Y += 255; if((i & 0x1) != 1) { final int cOff = sz + jDiv2 * width + (i >> 1) * 2; Cb = fg[cOff]; if(Cb < 0) Cb += 127; else Cb -= 128; Cr = fg[cOff + 1]; if(Cr < 0) Cr += 127; else Cr -= 128; } int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); if(R < 0) R = 0; else if(R > 255) R = 255; int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); if(G < 0) G = 0; else if(G > 255) G = 255; int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); if(B < 0) B = 0; else if(B > 255) B = 255; out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; } } } 数组转换为byte[]

    Bitmap