Hi,
We have a problem with the h264 decoder in 1080p with the DM8148 EVM + Video conference daughter board. The last 24 lines of the video image are clipped. We use "capture_encode" example (OMX, EZSDK 5.03.01.15) to create the h264 video file (Modified version to capture from the hdmi receiver Sii9135): root@dm814x-evm:/usr/share/ti/ti-omx# ./capture_encode_a8host_debug.xv5T -o test.h264 -m 1080p -f 60 -b 15000000 -n 600 -d 0 and then "decode_display" example to play back the video: root@dm814x-evm:/usr/share/ti/ti-omx# ./decode_display_a8host_debug.xv5T -i test.h264 -w 1920 -h 1080 -f 60 -c h264 -g 0 -d 0 The video image is 1920x1056 instead of 1920x1080. No problems with a software h264 decoder (ex: VLC on Ubuntu) to decode the same video file (test.h264). No problems in 720p.
Thanks
Stephane Rousseau
Can you see if this is display or decoder issue by displaying known images on display alone?
Thanks,
brijesh jadav
Please mark this post as answered via the Verify Answer button below if you think it answers your question. Thanks!
The display is ok when I run "capture_encode". So, I assume it is ok when we run "decode_display". Also, the monitor info indicates 1920x1080. So, I presume the 1920x1056 frame is stretched to 1920x1080 before to be displayed.
Edit: I think the problem could also be in the scaler (OMX.TI.VPSSM3.VFPC.INDTXSCWB).
I found a patch to fix the bug. It is in the file "${EZSDK}/component-sources/omx-ti81xx-src_05_02_00_30/src/ti/omx/comp/vfpc/src/omx_vfpc_IndTxSC_if.c" (overlay sdk). In the beginning of the function "_OMX_VFPCIndTxSCWb_SetFVIDFrameInfo", the frame width and the frame height of the buffer are respectively clipped to 1920 and 1080. But, the buffer size is 1952x1104 and the video frame size is 1920x1080 with the origin at x = 32 and y = 24 (1920+32=1952 and 1080+24=1104). This result with a video frame of 1948x1056 with the origin at x = 32 and y = 24. Note that not only 24 bottom lines was clipped but also 32 rightmost columns of pixel.
By removing the code that does the clipping to 1920x1080, the displayed frame is effectively 1920x1080 but...
But now I'm facing a new problem: The 24 bottom lines are ok but the 32 rightmost columns of pixel are corrupted.
Stephane,
Decoder produce o/p for 1920x1080 video in a buffer of size 2048x1176 due to alignement and padding requirement. effective video in this o/p buffer is at x =32 and y=24 pixel offset. So in SC video is cropped to get the proper o/p. Now since VPSS handles max line width of 1920, it ends up cropping rightmost 32 pixel and cropped video is 1888 x 1080, which is scaled to 1920x1080.
We have not tried, but you can modify the pointers given to SC5 and get the correct o/p. Note OMX buffer pointer and buffer headers are tied, you will have to do bookkeeping of pointers given to SC and returned pointer will need to be modifed to original pointer
Regards
Vimal
Hi Vimal,
Thank you for answering. In the function "_OMX_VFPCIndTxSCWb_SetFVIDFrameInfo" (see my previous post), I offset the buffer pointer to startX + startY * pitch then reset startX and startY to zero and then set width and height to 1920 and 1080 respectively. This result in full garbage to the screen. But, if I offset only to startY * pitch, this is ok (but the 32 rightmost columns of pixel are still corrupted). I think that adding 32 to the address of the buffer no longer respects the alignment constraint.
You are using EZSDK 5.03 ? I assume you are using non tunneled mode of OMX. Do you have CCS connected on your board. If yes, you could check the image for one frame itself. Chroma pointer is calculated properly ? Alignment of 32 should have been sufficient. (You can also experiment with 128). Is the pitch set properly, if not you should see garbage as checkerd pattern and almost same throughout the screen.
Vimal,
I found the problem with the full corrupted frame: some parameters of the scaler are not set correctly (probably the pitch) when the application set the config with "OMX_TI_IndexConfigVidChResolution" in "_OMX_VFPCIndTxSCWbConfig" function even if the dynamic config parameters are set correctly ("drvState->ScWbDynamicCfg[...]"). So, when the function "_OMX_VFPCIndTxSCWb_SetFVIDFrameInfo" is called, all the dynamic config parameters are identical to the new ones computed from the buffer header. The parameter update is then skipped and the frame is totally corrupted. If we force an update of the parameters, everything works fine. Also, in the application (decode_display), If we set any parameter of the structure "OMX_CONFIG_VIDCHANNEL_RESOLUTION" with any value except the good one (ex: Frm0Pitch = 0) , everything works fine because this will force an update of the parameters (in the function "_OMX_VFPCIndTxSCWb_SetFVIDFrameInfo").
To sum up, there is a bug with "OMX_TI_IndexConfigVidChResolution". When we workaround this bug, we can solve the other bugs (24x32 trimming and 32 columns of corruption) by offsetting the buffer address.
Now, the question is: Are all these bugs will be fixed in the next release of OMX?
Thanks for root causing the issue..Pitch should be fine, as this does not change based on offset. May be offsets are not set correctly. For summary and in order to take the changes, could you please list all the changes you did. Also are you using 5.3.15 non tunneled mode OMX version ? I will try to take the changes and try out in our set-up.
I have rectified this, and will be available in next release.
Thanks..
FYI modified code:
_OMX_VFPCIndTxSCWb_SetFVIDFrameInfo
...
.....
if ( OMX_DirInput == eDir ) { chParams = &drvState->scConfig.chParams[chNum]; pitch = pOmxBufHdr->nFramePitch; if ( pOmxBufHdr->nFrameWidth >= 1920 ) { width = 1920; //pOmxBufHdr->nFrameWidth; } else { width = pOmxBufHdr->nFrameWidth; } if ( pOmxBufHdr->nFrameHeight >= 1080 ) { height = 1080; } else { height = pOmxBufHdr->nFrameHeight; } startX = 0; startY = 0; if ( pOmxBufHdr->nFrameWidth >= 1920 ) { cropWidth = width - startX; } else { cropWidth = pOmxBufHdr->nCropWidth; } if ( pOmxBufHdr->nFrameHeight >= 1080 ) { cropHeight = height - startY; } else { cropHeight = pOmxBufHdr->nCropHeight; } OMX_BASE_ASSERT (cropWidth + startX <= width, OMX_ErrorUndefined); OMX_BASE_ASSERT (cropHeight + startY <= height, OMX_ErrorUndefined); /** Check for any dynamic video frame parameter change and enable the * rtparam upadte in that case */ if ( ( pitch != drvState->ScWbDynamicCfg[chNum].nInPitch ) || (chParams->inFmt.pitch[FVID2_YUV_INT_ADDR_IDX] != pitch) ){ drvState->ScWbDynamicCfg[chNum].nInPitch = pitch; if (VPS_VPDMA_MT_TILEDMEM == drvState->scConfig.chParams[chNum].inMemType) { drvState->ScWbDynamicCfg[chNum].nInPitch = VPSUTILS_TILER_CNT_8BIT_PITCH; } chParams->inFmt.pitch[FVID2_YUV_INT_ADDR_IDX] = drvState->ScWbDynamicCfg[chNum].nInPitch; rtParamUpdate = TRUE; } if ( width != drvState->ScWbDynamicCfg[chNum].nInWidth ) { drvState->ScWbDynamicCfg[chNum].nInWidth = width; chParams->inFmt.width = drvState->ScWbDynamicCfg[chNum].nInWidth; rtParamUpdate = TRUE; } if ( height != drvState->ScWbDynamicCfg[chNum].nInHeight ) { drvState->ScWbDynamicCfg[chNum].nInHeight = height; chParams->inFmt.height = drvState->ScWbDynamicCfg[chNum].nInHeight; rtParamUpdate = TRUE; } if ( startX != drvState->ScWbDynamicCfg[chNum].nFrmStartX ) { drvState->ScWbDynamicCfg[chNum].nFrmStartX = startX; chParams->srcCropCfg->cropStartX = drvState->ScWbDynamicCfg[chNum].nFrmStartX; rtParamUpdate = TRUE; } if ( startY != drvState->ScWbDynamicCfg[chNum].nFrmStartY ) { drvState->ScWbDynamicCfg[chNum].nFrmStartY = startY; chParams->srcCropCfg->cropStartY = drvState->ScWbDynamicCfg[chNum].nFrmStartY; rtParamUpdate = TRUE; } if ( cropWidth != drvState->ScWbDynamicCfg[chNum].nFrmCropWidth ) { drvState->ScWbDynamicCfg[chNum].nFrmCropWidth = cropWidth; chParams->srcCropCfg->cropWidth = drvState->ScWbDynamicCfg[chNum].nFrmCropWidth; rtParamUpdate = TRUE; } if ( cropHeight != drvState->ScWbDynamicCfg[chNum].nFrmCropHeight ) { drvState->ScWbDynamicCfg[chNum].nFrmCropHeight = cropHeight; chParams->srcCropCfg->cropHeight = drvState->ScWbDynamicCfg[chNum].nFrmCropHeight; rtParamUpdate = TRUE; } pFrame->addr[FVID2_FRAME_ADDR_IDX] [FVID2_YUV_SP_Y_ADDR_IDX] = pOmxBufHdr->pBuffer + pOmxBufHdr->nVerOffset* pitch + pOmxBufHdr->nHorOffset; if (pOmxBufHdr->pBuffer) { pFrame->addr[FVID2_FRAME_ADDR_IDX] [FVID2_YUV_SP_CBCR_ADDR_IDX] = pOmxBufHdr->nCBufPtr + (pOmxBufHdr->nVerOffset / 2) * pitch + pOmxBufHdr->nHorOffset; } else { pFrame->addr[FVID2_FRAME_ADDR_IDX] [FVID2_YUV_SP_CBCR_ADDR_IDX] = NULL; }
Thanks Vimal,
your fix works fine in 1920x1080 but could be problematic in smaller resolutions (ex: 1280x720) where cropWidth/cropHeight will be smaller than width/height. This will crash when the scaler is bypassed (bAlgBypass = 1) because the source region will be larger than the destination region. Here is the fix I suggest:
if ( OMX_DirInput == eDir ) { chParams = &drvState->scConfig.chParams[chNum]
pitch = pOmxBufHdr->nFramePitch;
width = pOmxBufHdr->nFrameWidth - pOmxBufHdr->nHorOffset; height = pOmxBufHdr->nFrameHeight - pOmxBufHdr->nVerOffset; cropWidth = pOmxBufHdr->nCropWidth; cropHeight = pOmxBufHdr->nCropHeight; startX = 0; startY = 0;
#if 0 if ( pOmxBufHdr->nFrameWidth >= 1920 ) { width = 1920; //pOmxBufHdr->nFrameWidth; } else { width = pOmxBufHdr->nFrameWidth; } if ( pOmxBufHdr->nFrameHeight >= 1080 ) { height = 1080; } else { height = pOmxBufHdr->nFrameHeight; } startX = drvState->ScWbDynamicCfg[chNum].nFrmStartX; startY = drvState->ScWbDynamicCfg[chNum].nFrmStartY; if ( pOmxBufHdr->nHorOffset != startX ) { /* If application programmed startX is not equal to what buffer supplier is specifying, reset it to what the buffer supplier says*/ startX = pOmxBufHdr->nHorOffset; } if ( pOmxBufHdr->nVerOffset != startY ) { /* If application programmed startY is not equal to what buffer supplier is specifying, reset it to what the buffer supplier says*/ startY = pOmxBufHdr->nVerOffset; } if ( pOmxBufHdr->nFrameWidth >= 1920 ) { cropWidth = width - startX; } else { cropWidth = pOmxBufHdr->nCropWidth; } if ( pOmxBufHdr->nFrameHeight >= 1080 ) { cropHeight = height - startY; } else { cropHeight = pOmxBufHdr->nCropHeight; }
#endif
// Same modifications for the remaining code
....
Modified code was tested for 5 different resolution streams inclding 720p. Also crop height / width is always smaller than width /height. Could you please clarify issue you observe ?
(On a sidenote though, we know cropping will not work if horizontal/vertical offsets are zero; Which we are looking into for taking from SC config)
I observe a crash in 1280x720 when the scaler is programmed in bypass mode. Here is how the bypass mode is enabled into the OMX example "decode_display" in the file "ilclient_utils.c":
OMX_ERRORTYPE IL_ClientSetScalarParams (IL_Client *pAppData)
{
OMX_CONFIG_ALG_ENABLE algEnable;
/* disable algo bypass mode */
OMX_INIT_PARAM (&algEnable); algEnable.nPortIndex = 0; algEnable.nChId = 0; // algEnable.bAlgBypass = 0; algEnable.bAlgBypass = 1; eError = OMX_SetConfig (pAppData->pScHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgEnable, &algEnable);
}
For algBypass input width/height should be same as output width/height, which is not true for the decoder o/p buffer format ( as in the code it was done as cropping). Most likely you see assertion from driver for width/height not matching. Please see OMX_DIO_NonTunnel_FillCustomHeader in the omxbase code, where width , height was set as added with offsets. You can remove the offsets in width, height calculation. Since NOW offsets are added in address. width, height can be same as crop height /width in buffer header. So in effect no cropping is done for decoder o/p. for 1920 because of clipping in the code, it works without this change. I have tested both bypass / no bypass mode with the change and it works for different resolutions.
btw, your intention for bypass is disabling 1:1 scaling ?
my intention is to disable the filtering when the scaling is 1:1 because it is very important for us to have a sharp image.
thanks
I and my colleagues are working DM8148 video interfaces. We experiencing some problems similar to the ones you described in your posts.
I'd like to ask you some questions:
1) you mentioned a "Video conference daughter board". I googled around to find more information about it but I could not find anything. Could you tell me where you purchased it?
2) In the "overlay sdk" we did not find sources of the firmware of the Cortex-M3 managing HDVICP2 codec. Did you? We'd like to put the hands on this firmware in order to verify how the codec parameters - set at IL client level - are passed to the HDVICP2 hardware module. We suspect that several parameters are ignored. For more details please see http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/181568.aspx
Thanks in advance and regards.