6/02/2012

Android (7x27, 8x50) - Green (Gray) images are shown for first few frames during live streaming

Sometimes, if you try to play live streaming link, you can see green or gray frame for first few frames.

This phenomenon is reproduced when video frame from server is not started with I frame (SYNC frame).



To resolve this issue, you can drop frames (do not display) till I frame is fed to devices following below code change.



- Changes in opencore side

(ref CAF link: https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/opencore.git;a=commit;h=45efd3e4cab108a30ba71e54b717c1448b992c6b)



- Apply code changes to in external/opencore/nodes/pvomxbasedecnode/include/pvmf_omx_basedec_node.h

< Changes in class PVMFOMXBaseDecNode>

class PVMFOMXBaseDecNode
. .. ..
// PMEM Allocator usage
PVMFPMemBufferAlloc * ipPMemBufferAlloc;

////////////////////////// Add below codes /////////////////////////
OMX_BOOL first_iframe_received;
////////////////////////////// End ////////////////////////////////////////

};

- Apply code changes to funtions in external/opencore/nodes/pvomxbasedecnode/src/pvmf_omx_basedec_node.cpp



< Changes in OSCL_EXPORT_REF PVMFOMXBaseDecNode::PVMFOMXBaseDecNode()>

OSCL_EXPORT_REF PVMFOMXBaseDecNode::PVMFOMXBaseDecNode(int32 aPriority, const ch
iStopInResetMsgSent(false),
iCompactFSISettingSucceeded(false),
bHWAccelerated(accelerated? OMX_TRUE: OMX_FALSE),
////////////////////////// Changed from ////////////////////////////

ipPMemBufferAlloc(NULL)

//////////////////////////////// To //////////////////////////////////////
ipPMemBufferAlloc(NULL),
first_iframe_received(OMX_FALSE)

////////////////////////////// End //////////////////////////////////////
{
iThreadSafeHandlerEventHandler = NULL;
iThreadSafeHandlerEmptyBufferDone = NULL;

. .. .

< Changes in OMX_ERRORTYPE PVMFOMXBaseDecNode::FillBufferDoneProcessing()>

OMX_ERRORTYPE PVMFOMXBaseDecNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYP
. .. ..
}
////////////////////////// Add below codes /////////////////////////
if(aBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) {
first_iframe_received = OMX_TRUE;
iDoNotSendOutputBuffersDownstreamFlag = false;
} else if(first_iframe_received != OMX_TRUE) {
iDoNotSendOutputBuffersDownstreamFlag = true;
}

////////////////////////////// End ////////////////////////////////////////
// if a buffer is empty, or if it should not be sent downstream (say, due to state change)
// release the buffer back to the pool
if ((aBuffer->nFilledLen == 0) || (iDoNotSendOutputBuffersDownstreamFlag == true))
. .. ..



- For 8x50, due to decoder operation, you need to apply changes in openmax side as well.

(ref CAF link: https://www.codeaurora.org/gitweb/quic/la/?p=platform/vendor/qcom-opensource/omx/mm-video.git;a=commit;h=4f043fac28db01cd1f483ea4a47bde2fbe832c4d)



- Apply code changes to funtions in vendor\qcom-opensource\omx\mm-video\8k\vdec\src\omx_vdec.h

< Changes in class omx_vdec:public qc_omx_component, public omx_vdec_inpbuf>

class omx_vdec:public qc_omx_component, public omx_vdec_inpbuf {
// wait for resource, (buffer done from Q6 to free buffers)
bool m_bWaitForResource;
////////////////////////// Add below codes /////////////////////////
bool m_first_sync_frame_rcvd;
////////////////////////////// End ////////////////////////////////////////
use_buffer_map m_use_buf_hdrs;

H264_Utils *m_h264_utils;

. .. ..

- Apply code changes to funtions in vendor\qcom-opensource\omx\mm-video\8k\vdec\src\omx_vdec.cpp

< Changes in omx_vdec::omx_vdec()>

omx_vdec::omx_vdec():m_state(OMX_StateInvalid),

. .. ..
////////////////////////// Add below codes /////////////////////////
m_first_sync_frame_rcvd(false);
////////////////////////////// End ////////////////////////////////////////
{

/* Assumption is that , to begin with , we have all the frames with client */
memset(m_out_flags, 0x00, (OMX_CORE_NUM_OUTPUT_BUFFERS + 7) / 8);

. .. ..

< Changes in void omx_vdec::fill_extradata(()>

void omx_vdec::fill_extradata(OMX_INOUT OMX_BUFFERHEADERTYPE * pBufHdr,

. .. ..
pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *) pExtraData->data;
pBufHdr->nFlags &= (~OMX_BUFFERFLAG_SYNCFRAME);
if (frameDetails->ePicType[0] == VDEC_PICTURE_TYPE_I) {

////////////////////////////////// Changed from ///////////////////////////////////
pBufHdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;

////////////////////////////////////////// To ///////////////////////////////////////////
if((false == m_first_sync_frame_rcvd)
&& (strncmp(m_vdec_cfg.kind, "OMX.qcom.video.decoder.avc", 26) == 0)
&& (100 == frameDetails->nPercentConcealedMacroblocks)) {
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,"First I frame with 100% concealment.");
} else {
pBufHdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED,"First I frame received.");
m_first_sync_frame_rcvd = true;
}

///////////////////////////////////////// End //////////////////////////////////////////
}
if (frameDetails->ePicFormat == VDEC_PROGRESSIVE_FRAME)
pExtraFrameInfo->interlaceType =

. .. ..

No comments:

Post a Comment