This source file includes following definitions.
- numberOfCameras
- getCamParams
- getDeviceSupportedFormats
- setCaptureParameters
- allocateBuffers
- setPreviewCallback
- onPreviewFrame
package org.chromium.media;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.util.Log;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
public class VideoCaptureTango extends VideoCapture {
private ByteBuffer mFrameBuffer = null;
private final int mTangoCameraId;
private static final int DEPTH_CAMERA_ID = 0;
private static final int FISHEYE_CAMERA_ID = 1;
private static final int FOURMP_CAMERA_ID = 2;
private static final VideoCaptureFactory.CamParams s_CAM_PARAMS[] = {
new VideoCaptureFactory.CamParams(DEPTH_CAMERA_ID, "depth", 320, 240),
new VideoCaptureFactory.CamParams(FISHEYE_CAMERA_ID, "fisheye", 640, 480),
new VideoCaptureFactory.CamParams(FOURMP_CAMERA_ID, "4MP", 1280, 720)};
private static final int SF_WIDTH = 1280;
private static final int SF_HEIGHT = 1168;
private static final int SF_FULL_HEIGHT = SF_HEIGHT * 3 / 2;
private static final int SF_LINES_HEADER = 16;
private static final int SF_LINES_FISHEYE = 240;
private static final int SF_LINES_RESERVED = 80;
private static final int SF_LINES_DEPTH = 60;
private static final int SF_LINES_DEPTH_PADDED = 112;
private static final int SF_LINES_BIGIMAGE = 720;
private static final int SF_OFFSET_4MP_CHROMA = 112;
private static final byte CHROMA_ZERO_LEVEL = 127;
private static final String TAG = "VideoCaptureTango";
static int numberOfCameras() {
return s_CAM_PARAMS.length;
}
static VideoCaptureFactory.CamParams getCamParams(int index) {
if (index >= s_CAM_PARAMS.length) return null;
return s_CAM_PARAMS[index];
}
static CaptureFormat[] getDeviceSupportedFormats(int id) {
ArrayList<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
if (id == DEPTH_CAMERA_ID) {
formatList.add(new CaptureFormat(320, 180, 5, ImageFormat.YV12));
} else if (id == FISHEYE_CAMERA_ID) {
formatList.add(new CaptureFormat(640, 480, 30, ImageFormat.YV12));
} else if (id == FOURMP_CAMERA_ID) {
formatList.add(new CaptureFormat(1280, 720, 20, ImageFormat.YV12));
}
return formatList.toArray(new CaptureFormat[formatList.size()]);
}
VideoCaptureTango(Context context,
int id,
long nativeVideoCaptureDeviceAndroid) {
super(context, 0, nativeVideoCaptureDeviceAndroid);
mTangoCameraId = id;
}
@Override
protected void setCaptureParameters(
int width,
int height,
int frameRate,
Camera.Parameters cameraParameters) {
mCaptureFormat = new CaptureFormat(s_CAM_PARAMS[mTangoCameraId].mWidth,
s_CAM_PARAMS[mTangoCameraId].mHeight,
frameRate,
ImageFormat.YV12);
cameraParameters.set("sf-mode", "all");
}
@Override
protected void allocateBuffers() {
mFrameBuffer = ByteBuffer.allocateDirect(
mCaptureFormat.mWidth * mCaptureFormat.mHeight * 3 / 2);
Arrays.fill(mFrameBuffer.array(), CHROMA_ZERO_LEVEL);
}
@Override
protected void setPreviewCallback(Camera.PreviewCallback cb) {
mCamera.setPreviewCallback(cb);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
mPreviewBufferLock.lock();
try {
if (!mIsRunning) {
return;
}
if (data.length == SF_WIDTH * SF_FULL_HEIGHT) {
int rotation = getDeviceOrientation();
if (rotation != mDeviceOrientation) {
mDeviceOrientation = rotation;
}
if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
rotation = 360 - rotation;
}
rotation = (mCameraOrientation + rotation) % 360;
if (mTangoCameraId == DEPTH_CAMERA_ID) {
int sizeY = SF_WIDTH * SF_LINES_DEPTH;
int startY =
SF_WIDTH * (SF_LINES_HEADER + SF_LINES_FISHEYE +
SF_LINES_RESERVED);
byte depthsample;
for (int j = startY; j < startY + 2 * sizeY; j += 2) {
depthsample = (byte)((data[j + 1] << 4) |
((data[j] & 0xF0) >> 4));
mFrameBuffer.put(depthsample);
}
for (int j = 0;
j < mCaptureFormat.mWidth * mCaptureFormat.mHeight -
sizeY;
++j)
mFrameBuffer.put((byte)0);
} else if (mTangoCameraId == FISHEYE_CAMERA_ID) {
int sizeY = SF_WIDTH * SF_LINES_FISHEYE;
int startY = SF_WIDTH * SF_LINES_HEADER;
ByteBuffer.wrap(data, startY, sizeY)
.get(mFrameBuffer.array(), 0, sizeY);
} else if (mTangoCameraId == FOURMP_CAMERA_ID) {
int startY =
SF_WIDTH * (SF_LINES_HEADER + SF_LINES_FISHEYE +
SF_LINES_RESERVED + SF_LINES_DEPTH_PADDED);
int sizeY = SF_WIDTH * SF_LINES_BIGIMAGE;
int startU = SF_WIDTH * (SF_HEIGHT + SF_OFFSET_4MP_CHROMA);
int sizeU = SF_WIDTH * SF_LINES_BIGIMAGE / 4;
int startV = (SF_WIDTH * SF_HEIGHT * 5 / 4) +
SF_WIDTH * SF_OFFSET_4MP_CHROMA;
int sizeV = SF_WIDTH * SF_LINES_BIGIMAGE / 4;
ByteBuffer.wrap(data, startY, sizeY)
.get(mFrameBuffer.array(), 0, sizeY);
ByteBuffer.wrap(data, startU, sizeU)
.get(mFrameBuffer.array(), sizeY, sizeU);
ByteBuffer.wrap(data, startV, sizeV)
.get(mFrameBuffer.array(), sizeY + sizeU, sizeV);
} else {
Log.e(TAG, "Unknown camera, #id: " + mTangoCameraId);
return;
}
mFrameBuffer.rewind();
nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid,
mFrameBuffer.array(),
mFrameBuffer.capacity(),
rotation);
}
} finally {
mPreviewBufferLock.unlock();
}
}
}