【发布时间】:2023-03-30 05:59:01
【问题描述】:
我在我的应用程序中使用 UVCCamera。这个库使用了大量的线程工作,这让我很困惑,我无法跟踪调用回调的位置。例如,我需要在onFrame 方法中抓取预览帧并对它们应用效果,但问题是不清楚何时调用 onFrame 方法(如果有的话)。 Android 线程文档和专业人士说,在可运行对象中设置的回调在同一线程中调用。所以,我在启动相机的线程内定义了一个IFrameCallback,但Logcat 仍然显示onFrame 方法从未被调用。
private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() {
@Override
public void onAttach(final UsbDevice device) {
Toast.makeText(MainActivity.this, "USB_DEVICE_ATTACHED", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) {
releaseCamera();
queueEvent(new Runnable() {
@Override
public void run() {
final UVCCamera camera = new UVCCamera();
camera.open(ctrlBlock);
camera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_YUV);
Log.d(TAG, "run: mIFrameCallback set");
camera.setStatusCallback(new IStatusCallback() {
@Override
public void onStatus(final int statusClass, final int event, final int selector,
final int statusAttribute, final ByteBuffer data) {
Log.d(TAG, "onStatus: ");
runOnUiThread(new Runnable() {
@Override
public void run() {
final Toast toast = Toast.makeText(MainActivity.this, "onStatus(statusClass=" + statusClass
+ "; " +
"event=" + event + "; " +
"selector=" + selector + "; " +
"statusAttribute=" + statusAttribute + "; " +
"data=...)", Toast.LENGTH_SHORT);
synchronized (mSync) {
if (mToast != null) {
mToast.cancel();
}
toast.show();
mToast = toast;
}
}
});
}
});
camera.setButtonCallback(new IButtonCallback() {
@Override
public void onButton(final int button, final int state) {
Log.d(TAG, "onButton: button callback");
runOnUiThread(new Runnable() {
@Override
public void run() {
final Toast toast = Toast.makeText(MainActivity.this, "onButton(button=" + button + "; " +
"state=" + state + ")", Toast.LENGTH_SHORT);
synchronized (mSync) {
if (mToast != null) {
mToast.cancel();
}
mToast = toast;
toast.show();
}
}
});
}
});
// camera.setPreviewTexture(camera.getSurfaceTexture());
if (mPreviewSurface != null) {
mPreviewSurface.release();
mPreviewSurface = null;
}
try {
camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.FRAME_FORMAT_MJPEG);
} catch (final IllegalArgumentException e) {
// fallback to YUV mode
try {
camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.DEFAULT_PREVIEW_MODE);
} catch (final IllegalArgumentException e1) {
camera.destroy();
return;
}
}
final SurfaceTexture st = mUVCCameraView.getSurfaceTexture();
if (st != null) {
mPreviewSurface = new Surface(st);
camera.setPreviewDisplay(mPreviewSurface);
// camera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_RGB565/*UVCCamera.PIXEL_FORMAT_NV21*/);
camera.startPreview();
}
synchronized (mSync) {
mUVCCamera = camera;
mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21);
}
}
private final IFrameCallback mIFrameCallback = new IFrameCallback() {
@Override
public void onFrame(final ByteBuffer frame) {
frame.clear();
synchronized (bitmap) {
bitmap.copyPixelsFromBuffer(frame);
Log.d(TAG, "onFrame: frame length: " + frame.array().length);
}
mImageView.post(mUpdateImageTask);
}
};
}, 0);
}
@Override
public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) {
// XXX you should check whether the coming device equal to camera device that currently using
releaseCamera();
}
@Override
public void onDettach(final UsbDevice device) {
Toast.makeText(MainActivity.this, "USB_DEVICE_DETACHED", Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel(final UsbDevice device) {
}
};
【问题讨论】:
-
您对这个问题有所了解吗?