我遇到了相机CallBack Buffer的问题。相机添加了4个新的回调缓冲区,并且还将字节数组与字典mBytesToByteBuffer相关联,形式为(Byte [],ByteBuffer)。我认为问题在于字典永远不会将其键更新到最近的帧。导致与当前帧数据的比较失败。并且代码没有超过这一点。
我查看了我一直在研究的谷歌示例,看起来他们根本没有更新他们的mBytesToByteBuffer,但它似乎有效。
从查看AddCallbackBuffer和SetPreviewCallbackWithBuffer的源代码开始,它们似乎没有对传递给它们的字节数组做任何事情。
mBytesToByteBuffer声明
public ConcurrentDictionary<byte[], ByteBuffer> mBytesToByteBuffer = new ConcurrentDictionary<byte[], ByteBuffer>();
添加CallbackBuffers:
camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
camera.SetPreviewCallbackWithBuffer(new CameraPreviewCallback(this));
字典mBytesToByteBuffer包含byteArray的正确大小,但是从不填充它。
此处创建字节缓冲区字典。
private byte[] createPreviewBuffer(Size previewSize)
{
int bitsPerPixel = ImageFormat.GetBitsPerPixel(ImageFormatType.Nv21);
long sizeInBits = previewSize.Height * previewSize.Width * bitsPerPixel;
int bufferSize = (int)System.Math.Ceiling(sizeInBits / 8.0d) + 1;
byte[] byteArray = new byte[bufferSize];
ByteBuffer buffer = ByteBuffer.Wrap(byteArray);
if (!buffer.HasArray)
{
throw new IllegalStateException("Failed to create valid buffer for camera source.");
}
mBytesToByteBuffer[byteArray] = buffer; //(byteArray, buffer);
return byteArray;
}
这里通过mBytesToByteBuffer调用callBackBuffer
public void setNextFrame(byte[] data, Android.Hardware.Camera camera)
{
lock (mLock)
{
if (mPendingFrameData != null)
{
camera.AddCallbackBuffer(mPendingFrameData.ToArray<System.Byte>());
mPendingFrameData = null;
}
if (!cameraSource.mBytesToByteBuffer.ContainsKey(data))
{
Log.Debug(TAG, "Skipping Frame, Could not Find ByteBuffer Associated with image");
return;
}
mPendingTimeMillis = SystemClock.ElapsedRealtime() - mStartTimeMillis;
mPendingFrameId++;
mPendingFrameData = cameraSource.mBytesToByteBuffer[data];
Monitor.PulseAll(mLock);
}
}
但代码永远不会过去
if(!cameraSource.mBytesToByteBuffer.containsKey(data)
数据已完全填充。
CameraPreviewCallback:
private class CameraPreviewCallback : Java.Lang.Object, Android.Hardware.Camera.IPreviewCallback
{
CameraSource cameraSource;
public CameraPreviewCallback(CameraSource cs)
{
cameraSource = cs;
}
public void OnPreviewFrame(byte[] data, Android.Hardware.Camera camera)
{
cameraSource.mFrameProcessor.setNextFrame(data, camera);
}
}