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.

No Empty Buffer Done callback with VFDC component

Hi All,

I have written an omx application using SDK 5.02 for the DM8168 that is designed to display 1024x1024 frames of video on the HDMI output. The app is loosly based on the decode_display sample code.

The app uses the Scalar and Display OMX components. YUV420SP video is provided to the Scalar via one of the SATA interfaces. The scalar converts this video to YUV422 format. I have verified that this is working. The scalar provides this video to the display component. The application has a display processing thread that calls OMX_EmptyThisBuffer on the display input port when frames are available on the scalar output port. However, the Empty Buffer Done callback function is never called. I have tried many experiments but I cannot determine why the callback function is not being called. I wonder if anyone has had this issue or if any debugging suggestions?

The source code is attached.

7485.video_display.tar.gz

The program output is as follows:

OMX initialized
Enter Video_Display_Example
OMX.TI.VPSSM3.VFPC.INDTXSCWB component created
Got Event! Enable/Disable Event
Got Event! Enable/Disable Event
Scaler ports enabled
OMX.TI.VPSSM3.VFDC component created
OMX.TI.VPSSM3.CTRL.DC component created
Got Event! Enable/Disable Event
Display component input port enabled
Got Event! State changed to: OMX_StateIdle
Scaler state -> IDLE
Got Event! State changed to: OMX_StateIdle
Display control state -> IDLE
Got Event! State changed to: OMX_StateIdle
Display state -> IDLE
Got Event! State changed to: OMX_StateExecuting
Display Control state -> EXECUTE
Got Event! State changed to: OMX_StateExecuting
Display state -> EXECUTE
Got Event! State changed to: OMX_StateExecuting
Scaler state -> EXECUTE
DISPLAYING VIDEO.
Starting DisplayInputThread
Starting ScalerOutputThread
ScalerOutputThread: Calling OMX_FillThisBuffer for buffer 0x12e2e0
Starting ScalerInputThread
Starting LiveThread
ScalerOutputThread: Calling OMX_FillThisBuffer for buffer 0x12e340
ScalerOutputThread: Calling OMX_FillThisBuffer for buffer 0x12e3a0
ScalerOutputThread: Calling OMX_FillThisBuffer for buffer 0x12e400
ScalerOutputThread: Calling OMX_FillThisBuffer for buffer 0x12e460
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e160
IL_ClientCbEmptyBufferDone: scalar in buffer (0x12e160)
IL_ClientCbFillBufferDone: scaler out buffer (0x12e2e0)
DisplayInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e2e0
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e1c0
IL_ClientCbEmptyBufferDone: scalar in buffer (0x12e1c0)
IL_ClientCbFillBufferDone: scaler out buffer (0x12e340)
DisplayInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e340
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e220
IL_ClientCbEmptyBufferDone: scalar in buffer (0x12e220)
IL_ClientCbFillBufferDone: scaler out buffer (0x12e3a0)
DisplayInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e3a0
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e280
IL_ClientCbEmptyBufferDone: scalar in buffer (0x12e280)
IL_ClientCbFillBufferDone: scaler out buffer (0x12e400)
DisplayInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e400
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e160
IL_ClientCbEmptyBufferDone: scalar in buffer (0x12e160)
IL_ClientCbFillBufferDone: scaler out buffer (0x12e460)
DisplayInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e460
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e1c0
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e220
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e280
ScalerInputThread: Calling OMX_EmptyThisBuffer for buffer 0x12e160

 

  • Steve,

    OMX_VFPC_NUM_INPUT_PORTS should be used as startOutportIndex for scalar. Media controller uses this enum to identfy the port.

    Regards

    Vimal

  • Hi Vimal,

    I made that change but the behavior is still the same. Do you have any other ideas?

    Thanks, Steve

  • Hi, Its not possible to driver 1024X1024 resolution on HDMI since its not a CEA or VESA standard. Further HDMI driver currently supports only 4 standard resolutions that is 1080p30, 1080p60, 720p60 and 1080i60. We are planning to add many more CEA and VESA resolutions in next release but 1024X1024 wont be part of that as its not standard.

     

    Regards,

    Hardik Shah

  • Hardik, thanks for your help.

    I changed the resolution to 1920x1080 but I still have the same problem. I do see video on the HDMI output. It is a 1920x1080 grey image. My callback is still not being called by the display component. It is called by the scalar component. Perhaps there is something incorrect with my configuration. The two functions I use to configure the scalar and display components are shown below. It seems correct to me but perhaps you can see something that is not correct?

    NOTE: pAppData->nWidth = 1920 and pAppData->nHeight = 1080

    OMX_ERRORTYPE IL_ClientSetScalarParams( IL_Client* pAppData )
    {
      OMX_ERRORTYPE eError = OMX_ErrorNone;
      OMX_PARAM_BUFFER_MEMORYTYPE memTypeCfg;
      OMX_PARAM_PORTDEFINITIONTYPE paramPort;
      OMX_PARAM_VFPC_NUMCHANNELPERHANDLE sNumChPerHandle;
      OMX_CONFIG_ALG_ENABLE algEnable;
      OMX_CONFIG_VIDCHANNEL_RESOLUTION chResolution;

      // Setting Memory type at input port to Raw Memory
      OMX_INIT_PARAM( &memTypeCfg );
      memTypeCfg.nPortIndex = OMX_VFPC_INPUT_PORT_START_INDEX;
      memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT;
      eError = OMX_SetParameter( pAppData->pScHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamBuffMemType, &memTypeCfg );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_SetParameter->OMX_TI_IndexParamBuffMemType (input) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // Setting Memory type at output port to Raw Memory
      OMX_INIT_PARAM( &memTypeCfg );
      memTypeCfg.nPortIndex = OMX_VFPC_OUTPUT_PORT_START_INDEX;
      memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT;
      eError = OMX_SetParameter( pAppData->pScHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamBuffMemType, &memTypeCfg );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_SetParameter->OMX_TI_IndexParamBuffMemType (output) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set input height/width and color format
      OMX_INIT_PARAM( &paramPort );
      paramPort.nPortIndex = OMX_VFPC_INPUT_PORT_START_INDEX;
      eError = OMX_GetParameter( pAppData->pScHandle, OMX_IndexParamPortDefinition, &paramPort );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_GetParameter->OMX_IndexParamPortDefinition (input) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      paramPort.nPortIndex = OMX_VFPC_INPUT_PORT_START_INDEX;
      paramPort.format.video.nFrameWidth = pAppData->nWidth;
      paramPort.format.video.nFrameHeight = pAppData->nHeight;

      // Scalar will be processing YUV420 frames
      paramPort.format.video.nStride = pAppData->nWidth;
      paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
      paramPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
      paramPort.nBufferSize = paramPort.format.video.nStride * pAppData->nHeight * 3 / 2;
      paramPort.nBufferAlignment = 0;
      paramPort.bBuffersContiguous = OMX_FALSE;
      paramPort.nBufferCountActual = IL_CLIENT_SCALAR_INPUT_BUFFER_COUNT;
      eError = OMX_SetParameter( pAppData->pScHandle, OMX_IndexParamPortDefinition, &paramPort );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_SetParameter->OMX_IndexParamPortDefinition (input) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set output height/width and color format
      OMX_INIT_PARAM( &paramPort );
      paramPort.nPortIndex = OMX_VFPC_OUTPUT_PORT_START_INDEX;
      eError = OMX_GetParameter( pAppData->pScHandle, OMX_IndexParamPortDefinition, &paramPort );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_GetParameter->OMX_IndexParamPortDefinition (output) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      paramPort.nPortIndex = OMX_VFPC_OUTPUT_PORT_START_INDEX;
      paramPort.format.video.nFrameWidth = pAppData->nWidth;
      paramPort.format.video.nFrameHeight = pAppData->nHeight;
      paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
      paramPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr;
      paramPort.nBufferAlignment = 0;
      paramPort.bBuffersContiguous = OMX_FALSE;
      paramPort.nBufferCountActual = IL_CLIENT_SCALAR_OUTPUT_BUFFER_COUNT;
      paramPort.format.video.nStride = pAppData->nWidth * 2;
      paramPort.nBufferSize = paramPort.format.video.nStride * paramPort.format.video.nFrameHeight;
      eError = OMX_SetParameter( pAppData->pScHandle, OMX_IndexParamPortDefinition, &paramPort );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: OMX_SetParameter->OMX_IndexParamPortDefinition (output) failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set number of channels
      OMX_INIT_PARAM( &sNumChPerHandle );
      sNumChPerHandle.nNumChannelsPerHandle = 1;
      eError = OMX_SetParameter( pAppData->pScHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVFPCNumChPerHandle, &sNumChPerHandle );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: Failed to set number of channels. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set VFPC input and output resolution information
      OMX_INIT_PARAM( &chResolution );
      chResolution.Frm0Width = pAppData->nWidth;
      chResolution.Frm0Height = pAppData->nHeight;
      chResolution.Frm0Pitch = pAppData->nWidth;
      chResolution.Frm1Width = 0;
      chResolution.Frm1Height = 0;
      chResolution.Frm1Pitch = 0;
      chResolution.FrmStartX = 0;
      chResolution.FrmStartY = 0;
      chResolution.FrmCropWidth = 0;
      chResolution.FrmCropHeight = 0;
      chResolution.eDir = OMX_DirInput;
      chResolution.nChId = 0;
      eError = OMX_SetConfig (pAppData->pScHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigVidChResolution, &chResolution );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: Failed to set input channel resolution. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      OMX_INIT_PARAM( &chResolution);
      chResolution.Frm0Width = pAppData->nWidth;
      chResolution.Frm0Height = pAppData->nHeight;
      chResolution.Frm0Pitch = pAppData->nWidth * 2;
      chResolution.Frm1Width = 0;
      chResolution.Frm1Height = 0;
      chResolution.Frm1Pitch = 0;
      chResolution.FrmStartX = 0;
      chResolution.FrmStartY = 0;
      chResolution.FrmCropWidth = 0;
      chResolution.FrmCropHeight = 0;
      chResolution.eDir = OMX_DirOutput;
      chResolution.nChId = 0;
      eError = OMX_SetConfig( pAppData->pScHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigVidChResolution, &chResolution );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: Failed to set output channel resolution. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      /* disable algo bypass mode */
      OMX_INIT_PARAM( &algEnable );
      algEnable.nPortIndex = 0;
      algEnable.nChId = 0;
      algEnable.bAlgBypass = OMX_FALSE;
      eError = OMX_SetConfig( pAppData->pScHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgEnable, &algEnable );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetScalarParams: Failed to disable algo by pass mode. %s\n", IL_ClientErrorToStr( eError ) );
      }

      return eError;
    }

    OMX_ERRORTYPE IL_ClientSetDisplayParams( IL_Client* pAppData )
    {
      OMX_ERRORTYPE eError = OMX_ErrorNone;
      OMX_PARAM_BUFFER_MEMORYTYPE memTypeCfg;
      OMX_PARAM_PORTDEFINITIONTYPE paramPort;
      OMX_PARAM_VFDC_DRIVERINSTID driverId;
      OMX_PARAM_VFDC_CREATEMOSAICLAYOUT mosaicLayout;
      OMX_CONFIG_VFDC_MOSAICLAYOUT_PORT2WINMAP port2Winmap;

      OMX_INIT_PARAM( &paramPort );

      // set input height/width and color format
      paramPort.nPortIndex = OMX_VFDC_INPUT_PORT_START_INDEX;
      OMX_GetParameter( pAppData->pDisHandle, OMX_IndexParamPortDefinition, &paramPort );
      paramPort.nPortIndex = OMX_VFDC_INPUT_PORT_START_INDEX;
      paramPort.format.video.nFrameWidth = pAppData->nWidth;
      paramPort.format.video.nFrameHeight = pAppData->nHeight;
      paramPort.format.video.nStride = pAppData->nWidth * 2;
      paramPort.nBufferCountActual = IL_CLIENT_DISPLAY_INPUT_BUFFER_COUNT;
      paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
      paramPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr;
      paramPort.nBufferSize = paramPort.format.video.nStride * pAppData->nHeight;
      OMX_SetParameter( pAppData->pDisHandle, OMX_IndexParamPortDefinition, &paramPort );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: OMX_SetParameter->OMX_IndexParamPortDefinition failed. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set the parameter to the display component to 1080P @60 mode
      OMX_INIT_PARAM( &driverId );
      // Configured to use on-chip HDMI
      driverId.nDrvInstID = OMX_VIDEO_DISPLAY_ID_HD0;
      driverId.eDispVencMode = OMX_DC_MODE_1080P_60;

      eError = OMX_SetParameter( pAppData->pDisHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVFDCDriverInstId, &driverId );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: failed to set driver mode to 1080P@60. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set the parameter to the display controller component to 1080P @60 mode
      OMX_INIT_PARAM( &driverId );
      // Configured to use on-chip HDMI
      driverId.nDrvInstID = OMX_VIDEO_DISPLAY_ID_HD0;
      driverId.eDispVencMode = OMX_DC_MODE_1080P_60;

      eError = OMX_SetParameter( pAppData->pCtlHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVFDCDriverInstId, &driverId );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: Failed to set driver mode to 1080P@60. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // set mosaic layout info

      // Configuring the first (and only) window
      // position of window can be changed by following coordinates, keeping in center by default
      OMX_INIT_PARAM( &mosaicLayout );
      mosaicLayout.sMosaicWinFmt[0].winStartX = (HD_WIDTH - pAppData->nWidth) / 2;
      mosaicLayout.sMosaicWinFmt[0].winStartY = (HD_HEIGHT - pAppData->nHeight) / 2;
      mosaicLayout.sMosaicWinFmt[0].winWidth = pAppData->nWidth;
      mosaicLayout.sMosaicWinFmt[0].winHeight = pAppData->nHeight;
      mosaicLayout.sMosaicWinFmt[0].pitch[VFDC_YUV_INT_ADDR_IDX] = pAppData->nWidth * 2;
      mosaicLayout.sMosaicWinFmt[0].dataFormat = VFDC_DF_YUV422I_YVYU;
      mosaicLayout.sMosaicWinFmt[0].bpp = VFDC_BPP_BITS16;
      mosaicLayout.sMosaicWinFmt[0].priority = 0;
      mosaicLayout.nDisChannelNum = 0;
      mosaicLayout.nNumWindows = 1;
      eError = OMX_SetParameter( pAppData->pDisHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVFDCCreateMosaicLayout, &mosaicLayout );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: Failed to set mosaic window parameter. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // map OMX port to window
      OMX_INIT_PARAM( &port2Winmap );
      // signifies the layout id this port2win mapping refers to
      port2Winmap.nLayoutId = 0;
      // Just one window in this layout, hence setting the value to 1
      port2Winmap.numWindows = 1;
      // Only 1st input port used here
      port2Winmap.omxPortList[0] = OMX_VFDC_INPUT_PORT_START_INDEX + 0;
      eError = OMX_SetConfig( pAppData->pDisHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigVFDCMosaicPort2WinMap, &port2Winmap );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: Failed to map port to windows. %s\n", IL_ClientErrorToStr( eError ) );
       return eError;
      }

      // Setting Memory type at input port to Raw Memory
      OMX_INIT_PARAM( &memTypeCfg );
      memTypeCfg.nPortIndex = OMX_VFPC_INPUT_PORT_START_INDEX;
      memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT;
      eError = OMX_SetParameter( pAppData->pDisHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamBuffMemType, &memTypeCfg );
      if( eError != OMX_ErrorNone )
      {
       printf( "IL_ClientSetDisplayParams: Failed to set memory Type at input port. %s\n", IL_ClientErrorToStr( eError ) );
      }

      return eError;
    }

  • Hardik,

    I solved my problem. I was passing the buffer headers of the scalar output buffers to the display component instead of passing the buffer headers of the display input buffers. I fixed this and now the display is working.

    Steve