NvSciBufObjGetPixels - is it returning a view or copying?

Please provide the following info (tick the boxes after creating this topic):
Software Version
DRIVE OS 6.0.8.1
DRIVE OS 6.0.6
DRIVE OS 6.0.5
DRIVE OS 6.0.4 (rev. 1)
DRIVE OS 6.0.4 SDK
other

Target Operating System
Linux
QNX
other

Hardware Platform
DRIVE AGX Orin Developer Kit (940-63710-0010-300)
DRIVE AGX Orin Developer Kit (940-63710-0010-200)
DRIVE AGX Orin Developer Kit (940-63710-0010-100)
DRIVE AGX Orin Developer Kit (940-63710-0010-D00)
DRIVE AGX Orin Developer Kit (940-63710-0010-C00)
DRIVE AGX Orin Developer Kit (not sure its number)
other

SDK Manager Version
1.9.3.10904
other

Host Machine Version
native Ubuntu Linux 20.04 Host installed with SDK Manager
native Ubuntu Linux 20.04 Host installed with DRIVE OS Docker Containers
native Ubuntu Linux 18.04 Host installed with DRIVE OS Docker Containers
other

It is not clear to me from the documentation if NvSciBufObjGetPixels is copying pixels or just returning a view. This snippet from sample code (CFileWriter.hpp) would imply it is doing an actual copy:

            if (m_pBuff == nullptr) {
                m_pBuff = new (std::nothrow) uint8_t[imageSize];
                if (m_pBuff == nullptr) {
                    LOG_ERR("Out of memory\n");
                    return NVSIPL_STATUS_OUT_OF_MEMORY;
                }
                std::fill(m_pBuff, m_pBuff + imageSize, 0x00);
            }

            uint8_t *buffIter = m_pBuff;
            for (uint32_t i = 0U; i < numSurfaces; i++) {
                pBuff[i] = buffIter;
                buffIter += (uint32_t)(height * yScalePtr[i] * pBuffPitches[i]);
            }

            if ((bufAttrs.needSwCacheCoherency) && (m_isRawOutput)) {
                sciErr = NvSciBufObjFlushCpuCacheRange(bufPtr, 0U, bufAttrs.planePitches[0] * height);
                CHK_NVSCISTATUS_AND_RETURN(sciErr, "NvSciBufObjFlushCpuCacheRange Failed");
            }

            sciErr = NvSciBufObjGetPixels(bufPtr, nullptr, (void **)pBuff, size, pBuffPitches); <------ copy?
            CHK_NVSCISTATUS_AND_RETURN(sciErr, "NvSciBufObjGetPixels Failed");

            for (uint32_t i = 0U; i < numSurfaces; i++) {
                if (fwrite(pBuff[i], size[i], 1U, m_pOutFile) != 1U) {
                    LOG_ERR("File write failed\n");
                    return NVSIPL_STATUS_ERROR;
                }
            }
        }

If it is copying - is there a function that just provides a view?

It performs a copy operation. What did you mean providing a view?

Maybe view was wrong terminology - it isn’t clear to me how you access pixel data in the bufPtr without the copy. Maybe this function - NvSciBufObjGetCpuPtr() - but I don’t see any examples. The copy here seems like it could be expensive for just writing out a file to disk.

1 Like

Please refer to Objects and how is used in the nvmimg_2d sample.

I have seen that as well. It also uses that call:

NvSciBufObjGetPixels(buffer, NULL, px.planePtrs, px.planeSizes, px.planePitches);

What I want to know is can we access buffer directly without having to copy. For example - we have a camera outputting 3848x2174, 12 bit raw (ends up 2 bytes per pixel) - I would expect that buffer size to be 16731104 bytes.

   auto pNvMBuffer = static_cast<INvSIPLClient::INvSIPLNvMBuffer*>(pBuffer);
​
    NvSciBufObj sciBufObj = pNvMBuffer->GetNvSciBufImage();
​
    NvSciBufAttrList bufAttrList;
​
    sciErr = NvSciBufObjGetAttrList(sciBufObj, &bufAttrList);
    checkSciStatus(sciErr, "NvSciBufObjGetAttrList failed");
    sciErr = NvSciBufAttrListGetAttrs(bufAttrList, imgAttrs, sizeof(imgAttrs) / sizeof(imgAttrs[0]));
    checkSciStatus(sciErr, "NvSciBufAttrListGetAttrs failed");
​
    auto size = *(static_cast<const uint64_t*>(imgAttrs[0].value));
    auto width = *(static_cast<const uint32_t*>(imgAttrs[3].value));
    auto height = *(static_cast<const uint32_t*>(imgAttrs[4].value));

width and height are 3848x2174 as expected, but size is coming out at 17039360.
Now, the pitch is 3904, and the top padding is 6 - 390421802 = 17021440

So - how exactly is the buffer size determined, what potential pieces am I missing, and can we access the buffer without a copy?

1 Like

Could you please provide more details on where these values were obtained from? For implementing non-copy access to the buffer, I recommend referring to the “WriteBufferToFile()” function implementation in the “SIPL Camera (nvsipl_camera)” sample application.

The sample app only shows accessing the ICP buffers, ISP0/1/2 all still use NvSciBufObjGetPixels. How can we determine the correct region of memory to read the ISP buffers?

Please create a separate topic for this query, and feel free to link it to the current discussion if necessary.