This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BufTab error in dm365 decode

First of all  , i'm so sorry for my poor English .

I want to decode two video streams in patrol way , which means i decode A for 10 seconds ,and then decode B for 10 seconds,and then back to decode A for 10 seconds....
My programm is given below:

myPrime:

   /* read video parameters from pipe for decode*/
        if (videoParam_fifo_get(envp->hFifoVidParam, &tempParams) != 0) {
            fprintf(stderr, "read video parameter error, error line: %d, error file: %s\n", __LINE__, __FILE__);
            cleanup(THREAD_FAILURE);
        }

        /* initialize video parameters */
        params->maxFrameRate = tempParams.frameRate;
        params->maxWidth = tempParams.width;
        params->maxHeight = tempParams.height;
        params->maxBitRate = tempParams.bitRate;

 if (colorSpace ==  ColorSpace_YUV420PSEMI) {
params->forceChromaFormat = XDM_YUV_420SP;
} else {
params->forceChromaFormat = XDM_YUV_422ILE;
}

extnParams.displayDelay = 0;
extnParams.hdvicpHandle = (void*) NULL;
extnParams.resetHDVICPeveryFrame = 0;
extnParams.disableHDVICPeveryFrame = 1;

if(strcmp(envp->videoDecoder,"h264dec") == 0)

          params->size = sizeof(IH264VDEC_Params);
   
    extnParams.viddecParams = *params;
  
    /* Create the video decoder */
    hVd2 = Vdec2_create(hEngine, envp->videoDecoder, (VIDDEC2_Params*)&extnParams, dynParams);

    if (hVd2 == NULL) {
        ERR("Failed to create video decoder: %s\n", envp->videoDecoder);
        cleanup(THREAD_FAILURE);
    }

    /* Which output buffer size does the codec require? */
    bufSize = Vdec2_getOutBufSize(hVd2);

    /* Both the codec and the display thread can own a buffer */
    gfxAttrs.bAttrs.useMask = CODEC_FREE | DISPLAY_FREE;

    /* Color space */
    gfxAttrs.colorSpace = colorSpace;

    /* Set the original dimensions of the Buffers to the max */
    gfxAttrs.dim.width = params->maxWidth;
    gfxAttrs.dim.height = params->maxHeight;
    gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(gfxAttrs.dim.width,colorSpace);

    /* Create a table of buffers for decoded data */
    hBufTab = BufTab_create(NUM_DISPLAY_BUFS, bufSize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));

    if (hBufTab == NULL) {
        ERR("Failed to create BufTab for display pipe\n");
        cleanup(THREAD_FAILURE);
    }
............


/* Main loop */
    while (!gblGetQuit()) {
        if (ret != Dmai_EFIRSTFIELD) {
            /* Get a displayed frame from the display thread */
            fifoRet = Fifo_get(envp->hDisplayOutFifo, &hDispBuf);

            if (fifoRet != Dmai_EOK) {
                cleanup(THREAD_FAILURE);
            }

            /* Did the display thread flush the fifo? */
            if (fifoRet == Dmai_EFLUSH) {
                cleanup(THREAD_SUCCESS);
            }

            /* The display thread is no longer using the buffer */
            hDstBuf = BufTab_getBuf(hBufTab, Buffer_getId(hDispBuf));
            Buffer_freeUseMask(hDstBuf, DISPLAY_FREE);

            /* Keep track of the number of buffers sent to the display thread */
            numDisplayBufs--;

            /* Get a free buffer from the BufTab to give to the codec */
            hDstBuf = BufTab_getFreeBuf(hBufTab);

            if (hDstBuf == NULL) {
                ERR("Failed to get free buffer from BufTab\n");
                BufTab_print(hBufTab);
                cleanup(THREAD_FAILURE);
            }
        }

        /* Make sure the whole buffer is used for output */
        BufferGfx_resetDimensions(hDstBuf);


       if (getVidParamChange() & DECODE_PARAM_CHANGES) {
      clsVidParamChange(DECODE_PARAM_CHANGES);
      if (hVd2) {
                           Vdec2_delete(hVd2);
    }
           if (hBufTab)  {
                     BufTab_delete(hBufTab);
                      }
   goto myPrime;
       }

        /* Decode the video buffer */
        ret = Vdec2_process(hVd2, hInBuf, hDstBuf);

        if (ret < 0) {
            ERR("Failed to decode video buffer\n");
            cleanup(THREAD_FAILURE);
        }
.............

In main loop, before Vdec2_process , i check the video parameters to determine which stream i need to decode ,and then goto the "myPrime" to reinitialize the Params and recreate decoder and buftab again .
When i run the programm , in the beginning it can run correctly , but after several times cycles (decode A->decode B->decode A->decode B..........),the buftab returns error:

Error: Failed to get free buffer from BufTab
BufTab:
[0] @ 0x441d3000 (0x8544e000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704 (704) Height 576 (576) Pos 24x24 LineLength 768 (704)
[1] @ 0x4434d000 (0x855c8000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[2] @ 0x444c7000 (0x85742000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[3] @ 0x44641000 (0x858bc000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[4] @ 0x447bb000 (0x85a36000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[5] @ 0x44935000 (0x85bb0000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[6] @ 0x44aaf000 (0x85d2a000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[7] @ 0x44c29000 (0x85ea4000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[8] @ 0x44da3000 (0x8601e000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[9] @ 0x44f1d000 (0x86198000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[10] @ 0x45097000 (0x86312000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[11] @ 0x45211000 (0x8648c000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[12] @ 0x4538b000 (0x86606000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[13] @ 0x45505000 (0x86780000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[14] @ 0x4567f000 (0x868fa000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704, Height 576, LineLength 704
[15] @ 0x457f9000 (0x86a74000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704 (704) Height 576 (576) Pos 24x24 LineLength 768 (704)
[16] @ 0x45973000 (0x87d58000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
        Width 704 (704) Height 576 (576) Pos 24x24 LineLength 768 (704)
[17] @ 0x45c06000 (0x87a04000 phys) numBytes 718848 (718848) useMask 1 (3) ref no
        Width 704 (704) Height 576 (576) Pos 24x24 LineLength 768 (704)

I really don't known which step is wrong , and how to debug,  So i really need your help . Any advice will be appreciate.

Best regards.

Katee


 

  • Hi Katee,

    Sorry for delayed reply.  By seeing your code, I am not sure if you are flushing the codec before deleteing it. If codec is not flushed before delete, it will continue to hold some buffers and after few create-delete iterations(casued by switching decodeA->decodeB->decode A....), you may run out of buffers. 

    ------See below snippents from video.c file of the decode demo------

    /* End of clip? */

    if (Buffer_getUserPtr(hInBuf) == NULL) {

     

    /* Flush the codec for display frames */

    Vdec2_flush(hVd2);

    bufsSent = 0;

    :

    <more lines>

    :

    else {

    printf("Clip ended, exiting demo..\n");

    gblSetQuit();

    }

    } /* End of clip? */

    ------

     

    regards

    Yashwant

  • Hi,Yashwant ,

    Thanks a lot for your reply . What you said is right , in my programm ,

    if (getVidParamChange() & DECODE_PARAM_CHANGES) {
          clsVidParamChange(DECODE_PARAM_CHANGES);
          if (hVd2) 
    {
                Vdec2_delete(hVd2);
         }
          if (hBufTab)  {
              BufTab_delete(hBufTab);
          }

          goto myPrime;

    }


    Before i delete the hVd2 and hBufTab ,i should free the buffers , so i change the programm like below:

    if (getVidParamChange() & DECODE_PARAM_CHANGES) {
          clsVidParamChange(DECODE_PARAM_CHANGES);

         while( numDisplayBufs>0){

          /* Get a displayed frame from the display thread */
                fifoRet = Fifo_get(envp->hDisplayOutFifo, &hDispBuf);

                if (fifoRet != Dmai_EOK) {
                    cleanup(THREAD_FAILURE);
                }

                /* Did the display thread flush the fifo? */
                if (fifoRet == Dmai_EFLUSH) {
                    cleanup(THREAD_SUCCESS);
                }

                /* The display thread is no longer using the buffer */
                hDstBuf = BufTab_getBuf(hBufTab, Buffer_getId(hDispBuf));
                Buffer_freeUseMask(hDstBuf, DISPLAY_FREE);

                /* Keep track of the number of buffers sent to the display thread */
                numDisplayBufs--;

         }
          if (hVd2) 
    {
                Vdec2_delete(hVd2);
         }
          if (hBufTab)  {
              BufTab_delete(hBufTab);
          }

          goto myPrime;

    }

    And then the issue is been resolved .  Thanks again for your help !