Android Camera Callback Buffer Empty

I am having a problem with the camera CallBack Buffer. The camera adds 4 new callbackbuffers, and also associates the byte Array to a dictionary mBytesToByteBuffer with the form (Byte[], ByteBuffer). I believe the problem lies with the fact the dictionary never updates its keys to the most recent frame. Leading to comparisons with current frame data failing. And the code not progressing past that point.

I have looked through the google example I have been working through, and it seems that they do not update their mBytesToByteBuffer at all, but that it seems to work.

From having looked at the source code for both AddCallbackBuffer and SetPreviewCallbackWithBuffer, it seems that they do not do anything with the byte arrays passed to them.

Declaration of mBytesToByteBuffer

public ConcurrentDictionary<byte[], ByteBuffer> mBytesToByteBuffer = new ConcurrentDictionary<byte[], ByteBuffer>();

Adding the CallbackBuffers:

    camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
    camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
    camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
    camera.AddCallbackBuffer(createPreviewBuffer(mPreviewSize));
    camera.SetPreviewCallbackWithBuffer(new CameraPreviewCallback(this));

The dictionary mBytesToByteBuffer contains the correct size of byteArray, however this is never populated.

The Byte Buffer Dictionary is created here.

           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;
        }

The callBackBuffer is called here through mBytesToByteBuffer

    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);
                }
            }

But the code never gets past

    if(!cameraSource.mBytesToByteBuffer.containsKey(data)

Data is fully populated.

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);
            }
        }

I have been working through the Google Vison Example Camera Source

My Full Camera Source

Sign In or Register to comment.