Segmentation fault when NvMediaImageGetBits

Hi
I try to get raw data from NvMediaImage with function NvMediaImageGetBits.But I got a Segmentation fault when run the code.
I add my codo into sample application img_cc.I add function NvMediaImageGetBits in save.c
Here is the code

static NvU32
_SaveThreadFunc(void *data)
{
    SaveThreadCtx *threadCtx = (SaveThreadCtx *)data;
    NvMediaImage *image = NULL;
[b]    NvU8 *pSrcBuff = NULL;
    NvU32 srcPitch = 2;
    NvMediaImageSurfaceMap surfaceMap;[/b]
    NvMediaImage *convertedImage = NULL;
    NvMediaStatus status;
    NvU32 totalSavedFrames=0;
    char outputFileName[MAX_STRING_SIZE];
    char buf[MAX_STRING_SIZE] = {0};
    char *calSettings = NULL;

    NVM_SURF_FMT_DEFINE_ATTR(attr);

    while (!(*threadCtx->quit)) {
        image=NULL;
        /* Wait for captured frames */
        while (NvQueueGet(threadCtx->inputQueue, &image, SAVE_DEQUEUE_TIMEOUT) !=
           NVMEDIA_STATUS_OK) {
            LOG_DBG("%s: saveThread input queue %d is empty\n",
                     __func__, threadCtx->virtualGroupIndex);
            if (*threadCtx->quit)
                goto loop_done;
        }

        if (threadCtx->saveEnabled) {
            if (*threadCtx->numRtSettings) {
                calSettings = threadCtx->rtSettings[_GetSettingNum(threadCtx->rtSettings,
                                                                  *threadCtx->numRtSettings,
                                                                  totalSavedFrames)
                                                  ].outputFileName;
            } else if (threadCtx->sensorInfo) {
                memset(buf, 0 , MAX_STRING_SIZE);
                status = threadCtx->sensorInfo->AppendOutputFilename(buf,
                                                                     threadCtx->sensorProperties);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: Failed to append output filename\n", __func__);
                    *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }
                calSettings = buf;
            } else {
                calSettings = NULL;
            }

            /* Save image to file */
            _CreateOutputFileName(threadCtx->saveFilePrefix,
                                  calSettings,
                                  threadCtx->virtualGroupIndex,
                                  totalSavedFrames,
                                  threadCtx->useNvRawFormat,
                                  outputFileName);

            LOG_INFO("%s: Write image. res [%u:%u] (file: %s)\n",
                        __func__, image->width, image->height,
                        outputFileName);
            if (threadCtx->useNvRawFormat) {

                status = NvMediaSurfaceFormatGetAttrs(threadCtx->surfType,
                                                      attr,
                                                      NVM_SURF_FMT_ATTR_MAX);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s:NvMediaSurfaceFormatGetAttrs failed\n", __func__);
                   *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }

                if (threadCtx->sensorInfo && (attr[NVM_SURF_ATTR_SURF_TYPE].value == NVM_SURF_ATTR_SURF_TYPE_RAW)) {
                    threadCtx->sensorInfo->WriteNvRawImage(&threadCtx->settingsCommands,
                                                           threadCtx->calParams,
                                                           image,
                                                           totalSavedFrames,
                                                           outputFileName);
                } else {
                    LOG_ERR("%s: NvRawFormat applicable only for RAW captured image \n", __func__);
                    *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }
            } else {
                WriteImage(outputFileName,
                           image,
                           NVMEDIA_TRUE,
                           NVMEDIA_FALSE,
                           threadCtx->rawBytesPerPixel);

               [b] if (NvMediaImageLock(image, NVMEDIA_IMAGE_ACCESS_WRITE, &surfaceMap) !=
                    NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: NvMediaImageLock failed\n", __func__);
                    return NVMEDIA_STATUS_ERROR;
                }



                if (!(pSrcBuff = malloc(surfaceMap.height*surfaceMap.width*srcPitch))) {
                    LOG_ERR("%s: Out of memory\n", __func__);
                    return NVMEDIA_STATUS_OUT_OF_MEMORY;
                }

                status = NvMediaImageGetBits(image, NULL, (void **)&pSrcBuff, &srcPitch);
                NvMediaImageUnlock(image);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: NvMediaImageGetBits() failed\n", __func__);

                }[/b]
            }
        }

        totalSavedFrames++;

        if (threadCtx->displayEnabled) {

            status = NvMediaSurfaceFormatGetAttrs(threadCtx->surfType,
                                                  attr,
                                                  NVM_SURF_FMT_ATTR_MAX);
            if (status != NVMEDIA_STATUS_OK) {
                LOG_ERR("%s:NvMediaSurfaceFormatGetAttrs failed\n", __func__);
               *threadCtx->quit = NVMEDIA_TRUE;
                goto loop_done;
            }

            if (attr[NVM_SURF_ATTR_SURF_TYPE].value == NVM_SURF_ATTR_SURF_TYPE_RAW) {
                /* Acquire image for storing converting images */
                while (NvQueueGet(threadCtx->conversionQueue,
                                  (void *)&convertedImage,
                                  SAVE_DEQUEUE_TIMEOUT) != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: conversionQueue is empty\n", __func__);
                    if (*threadCtx->quit)
                        goto loop_done;
                }

                status = _ConvRawToRgba(image,
                                        convertedImage,
                                        threadCtx->rawBytesPerPixel,
                                        threadCtx->pixelOrder);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: convRawToRgba failed for image %d in saveThread %d\n",
                            __func__, totalSavedFrames, threadCtx->virtualGroupIndex);
                    *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }

                while (NvQueuePut(threadCtx->outputQueue,
                                  &convertedImage,
                                  SAVE_ENQUEUE_TIMEOUT) != NVMEDIA_STATUS_OK) {
                    LOG_DBG("%s: savethread output queue %d is full\n",
                             __func__, threadCtx->virtualGroupIndex);
                    if (*threadCtx->quit)
                        goto loop_done;
                }
                convertedImage = NULL;
            } else {
                while (NvQueuePut(threadCtx->outputQueue,
                                  &image,
                                  SAVE_ENQUEUE_TIMEOUT) != NVMEDIA_STATUS_OK) {
                    LOG_DBG("%s: savethread output queue %d is full\n",
                             __func__, threadCtx->virtualGroupIndex);
                    if (*threadCtx->quit)
                        goto loop_done;
                }
                image=NULL;
            }
        }

        if (threadCtx->numFramesToSave &&
           (totalSavedFrames == threadCtx->numFramesToSave)) {
            *threadCtx->quit = NVMEDIA_TRUE;
            goto loop_done;
        }
    loop_done:
        if (image) {
            if (NvQueuePut((NvQueue *)image->tag,
                           (void *)&image,
                           0) != NVMEDIA_STATUS_OK) {
                LOG_ERR("%s: Failed to put image back in queue\n", __func__);
                *threadCtx->quit = NVMEDIA_TRUE;
            };
            image = NULL;
        }
        if (convertedImage) {
            if (NvQueuePut((NvQueue *)convertedImage->tag,
                           (void *)&convertedImage,
                           0) != NVMEDIA_STATUS_OK) {
                LOG_ERR("%s: Failed to put image back in conversionQueue\n", __func__);
                *threadCtx->quit = NVMEDIA_TRUE;
            }
            convertedImage = NULL;
        }
    }
    LOG_INFO("%s: Save thread exited\n", __func__);
    threadCtx->exitedFlag = NVMEDIA_TRUE;
    return NVMEDIA_STATUS_OK;
}

When exec the NvMediaImageGetBits function,it will Segmentation fault.
the gdb dump

[Thread 0x7fb57e3200 (LWP 4496) exited]

Thread 4 "nvmimg_cc" received signal SIGSEGV, Segmentation fault.
0x0000007fb7f75f84 in ?? () from /usr/lib/libnvmedia.so

Could you kindly tell me how to solve this problem?

Dear Calmcar,
I assume when you comment NvMediaImageGetBits, the application is not crashing. If so, Can you please double check the srcPitch value in NvMediaImageGetBits?

Hi SivaRamaKrishna

My camera module output format is YUV422,so what value do srcPitch should be?
I set it to 2 in my code.

Dear Calmcar,
I notice there is a usage of NvMediaImageGetbits in _ConvRawToRgba in the same file. Can you check with similar values? Similarly, Please check the size of pSrcBuff also.

Hi SivaRamaKrishna
I set srcPitch to 1 and it works.And because my camera output pixel format is yuv422.I set pSrcBuff size to widthheight2.
Here’s the code

if (threadCtx->useNvRawFormat) {

                status = NvMediaSurfaceFormatGetAttrs(threadCtx->surfType,
                                                      attr,
                                                      NVM_SURF_FMT_ATTR_MAX);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s:NvMediaSurfaceFormatGetAttrs failed\n", __func__);
                   *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }

                if (threadCtx->sensorInfo && (attr[NVM_SURF_ATTR_SURF_TYPE].value == NVM_SURF_ATTR_SURF_TYPE_RAW)) {
                    threadCtx->sensorInfo->WriteNvRawImage(&threadCtx->settingsCommands,
                                                           threadCtx->calParams,
                                                           image,
                                                           totalSavedFrames,
                                                           outputFileName);
                } else {
                    LOG_ERR("%s: NvRawFormat applicable only for RAW captured image \n", __func__);
                    *threadCtx->quit = NVMEDIA_TRUE;
                    goto loop_done;
                }
            } else {
                WriteImage(outputFileName,
                           image,
                           NVMEDIA_TRUE,
                           NVMEDIA_FALSE,
                           threadCtx->rawBytesPerPixel);

                if (NvMediaImageLock(image, NVMEDIA_IMAGE_ACCESS_WRITE, &surfaceMap) !=
                    NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: NvMediaImageLock failed\n", __func__);
                    return NVMEDIA_STATUS_ERROR;
                }

                NvU32 srcPitch = 1;

                if (!(pSrcBuff = malloc(surfaceMap.height*surfaceMap.width*srcPitch*2))) {
                    LOG_ERR("%s: Out of memory\n", __func__);
                    return NVMEDIA_STATUS_OUT_OF_MEMORY;
                }

                status = NvMediaImageGetBits(image, NULL, (void **)&pSrcBuff, &srcPitch);
                NvMediaImageUnlock(image);
                if (status != NVMEDIA_STATUS_OK) {
                    LOG_ERR("%s: NvMediaImageGetBits() failed\n", __func__);

                }
                char write_name[]="test0";
                write_name[4]+=i;
		int fd = open(write_name, O_RDWR | O_CREAT, 0666);
		write(fd,pSrcBuff,surfaceMap.height*surfaceMap.width*srcPitch*2);
	        close(fd);
		i++;
		if(pSrcBuff!=NULL){
			free(pSrcBuff);
			pSrcBuff=NULL;
			}
            }

I save the data to verify the pointer and it works.
But if I comment the SDK save function WriteImage.After that,I cannot save complete data(only several rows).
Could you kindly tell me how to get complete data pointer without WriteImage?

I check the _ConvRawToRgba function,the correct srcPitch value should be widthrawBytesPerPixel.My resolution is 1280720 yuv422_8bit,so srcPitch is 1280*2.But this value will cause Segmentation fault.

I try to get rawBytesPerPixel from threadCtx->rawBytesPerPixel.It’s 0,so srcPitch is 0.And then I got all zero data

I also try other value like 12802,2,12801…But all of them will cause Segmentation fault

Does the funtion support YUV pixel format?

Dear calmcar,
I will make changes in img_cc sample similar to yours. What is the setup to reproduce this on my end?

Hi SivaRamaKrishna

Please try this parameter

surfaceMap.height=720
surfaceMap.width=1280
rawBytesPerPixel=2
srcPitch=rawBytesPerPixel*surfaceMap.width

I try to transmit data as raw8 format.And I get the data successfully.It seems it cannot support yuv format.