Hi Guys,
I wish to extract the YUV planes and use the values to perform some operations. When I try to obtain the YUV using nvbuffer and mmap API to map the buffer to a single character buffer, somehow the planes extracted show some corrupted data. However, when I try to extract the planes into three separate buffers using offset given by NVBufferParam there is no corruption.
The code for single buffer implementation is as follows :
char *m_datamem ;
while (true)
{
// Acquire a Frame.
UniqueObj<Frame> frame(iFrameConsumer->acquireFrame());
cout<<"frame instantiated"<<endl;
IFrame *iFrame = interface_cast<IFrame>(frame);
cout<<"iFrame instantiated : "<<iFrame<< endl;
if (!iFrame)
break;
// Get the Frame's Image.
Image *image = iFrame->getImage();
EGLStream::NV::IImageNativeBuffer *iImageNativeBuffer
= interface_cast<EGLStream::NV::IImageNativeBuffer>(image);
TEST_ERROR_RETURN(!iImageNativeBuffer, "Failed to create an IImageNativeBuffer");
fd = iImageNativeBuffer->createNvBuffer(Argus::Size {m_framesize.width, m_framesize.height},
NvBufferColorFormat_YUV420, NvBufferLayout_Pitch, &status);
if (status != STATUS_OK)
TEST_ERROR_RETURN(status != STATUS_OK, "Failed to create a native buffer");
NvBufferParams params;
NvBufferGetParams(fd, ¶ms);
int fsize = params.pitch[0] * m_framesize.height ;
m_datamem = (char *)mmap(NULL, 1.5*fsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, params.offset[0]);
Mat data = cv::Mat(params.height[0] ,params.width[0], 8UC1, (void *) m_datamem , params.pitch[0]);
imshow("data" , data);
Mat dataU = cv::Mat(params.height[1] ,params.width[1], 8UC1, (void *) m_datamem + params.offset[1], params.pitch[1]);
imshow("dataU" , dataU);
Mat dataV = cv::Mat(params.height[2] ,params.width[2], 8UC1, (void *) m_datamem + params.offset[2], params.pitch[2]);
imshow("dataV" , dataV);
NvBufferDestroy(fd);
}
The code for separate buffers is as follows :
char *m_datamem ;
char *m_datamemU;
char *m_datamemV;
while (true)
{
// Acquire a Frame.
UniqueObj<Frame> frame(iFrameConsumer->acquireFrame());
cout<<"frame instantiated"<<endl;
IFrame *iFrame = interface_cast<IFrame>(frame);
cout<<"iFrame instantiated : "<<iFrame<< endl;
if (!iFrame)
break;
// Get the Frame's Image.
Image *image = iFrame->getImage();
EGLStream::NV::IImageNativeBuffer *iImageNativeBuffer
= interface_cast<EGLStream::NV::IImageNativeBuffer>(image);
TEST_ERROR_RETURN(!iImageNativeBuffer, "Failed to create an IImageNativeBuffer");
fd = iImageNativeBuffer->createNvBuffer(Argus::Size {m_framesize.width, m_framesize.height},
NvBufferColorFormat_YUV420, NvBufferLayout_Pitch, &status);
if (status != STATUS_OK)
TEST_ERROR_RETURN(status != STATUS_OK, "Failed to create a native buffer");
NvBufferParams params;
NvBufferGetParams(fd, ¶ms);
int fsize = params.pitch[0] * params.height[0] ;
int fsizeU = params.pitch[1]*params.height[1];
int fsizeV = params.pitch[2]*params.height[2];
m_datamem = (char *)mmap(NULL, fsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, params.offset[0]);
m_datamemU = (char *)mmap(NULL, fsizeU, PROT_READ | PROT_WRITE, MAP_SHARED, fd, params.offset[1]);
m_datamemV = (char *)mmap(NULL, fsizeV, PROT_READ | PROT_WRITE, MAP_SHARED, fd, params.offset[2]);
Mat data = cv::Mat(params.height[0] ,params.width[0], 8UC1, (void *) m_datamem , params.pitch[0]);
imshow("data" , data);
Mat dataU = cv::Mat(params.height[1] ,params.width[1], 8UC1, (void *)m_datamemU, params.pitch[1]);
imshow("dataU" , dataU);
Mat dataV = cv::Mat(params.height[2] ,params.width[2], 8UC1, (void *) m_datamemV, params.pitch[2]);
imshow("dataV" , dataV);
NvBufferDestroy(fd);
}
When I try to imshow the buffers, the buffers are corrupted using single buffer code (offset added to base pointer). When I try to use separate buffers, there is no corruption. Kindly let me know what is wrong with single buffer access.
Thanks.