Skip to content

Broken RGB Image #6

@sma1

Description

@sma1

I found a problem in the XnUncompressedBayerProcessor::OnEndOfFrame() which was causing RGB broken image. This was happening on windows 7 at least.

XnImageProcessor has the general framework to reject images if not enough data was collected, but since the bayer conversion is always done in OnEndOfFrame() regardless of how much data was collected, the size of the RGB buffer will always be the expected size.

void XnImageProcessor::OnEndOfFrame(const XnSensorProtocolResponseHeader* pHeader)
{
if (!m_bCompressedOutput)
{
// make sure data size is right
XnUInt32 nExpectedSize = CalculateExpectedSize();
if (GetWriteBuffer()->GetSize() != nExpectedSize)
{
xnLogWarning(XN_MASK_SENSOR_READ, "Read: Image buffer is corrupt. Size is %u (!= %u)", GetWriteBuffer()->GetSize(), nExpectedSize);
FrameIsCorrupted();
}
}

// call base
XnFrameStreamProcessor::OnEndOfFrame(pHeader);

}

I did something like this and now when the frames don't have the expected size the frame is thrown away

void XnUncompressedBayerProcessor::OnEndOfFrame(const XnSensorProtocolResponseHeader* pHeader)
{
XN_PROFILING_START_SECTION("XnUncompressedBayerProcessor::OnEndOfFrame")

xnOSEnterCriticalSection(&m_hLockCS);
try
{
    // if data was written to temp buffer, convert it now
    switch (GetStream()->GetOutputFormat())
    {
    case XN_OUTPUT_FORMAT_GRAYSCALE8:
        break;
    case XN_OUTPUT_FORMAT_RGB24:
        {
            if (m_UncompressedBayerBuffer.GetSize() != GetActualXRes() * GetActualYRes())
            {
                FrameIsCorrupted();
            }
            else
            {
                Bayer2RGB888(m_UncompressedBayerBuffer.GetData(), GetWriteBuffer()->GetUnsafeWritePointer(), GetActualXRes(), GetActualYRes(), 1, 0);
                                    GetWriteBuffer()->UnsafeUpdateSize(GetActualXRes()*GetActualYRes()*3); 
            }   
            m_UncompressedBayerBuffer.Reset();
        }
        break;
    }

    XnImageProcessor::OnEndOfFrame(pHeader);

}
catch (...)
{
}
xnOSLeaveCriticalSection(&m_hLockCS);
XN_PROFILING_END_SECTION

}

I saw some people think it happened more often under a heavy CPU load so I tried to simulate that by having the conversion take longer with a 50 ms sleep in Bayer.cpp before returning from Bayer2RGB888(). This caused the problem to happen a lot for us which was helpful in tracking the problem down. Before that sometimes it would happen several times in a row and other times we wouldn't see it for days.

This problem seems to be in both avin2's version and also in the non modded version from the OpenNI website (https://github.com/PrimeSense/Sensor/blob/unstable/Source/XnDeviceSensorV2/XnUncompressedBayerProcessor.cpp).

How do I go about submitting this code so it gets into different distributions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions