/*************************************************************************** * Copyright (c) 2002-2006, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: bdccservice.c $ * $brcm_Revision: 4 $ * $brcm_Date: 5/10/06 6:49p $ * * Module Description: * * Revision History: * * $brcm_Log: /BSEAV/lib/ccgfx/source/bdccservice.c $ * * 4 5/10/06 6:49p shyam * PR 8365 : Make it comiler warning free and ANSI C compliant * * 3 4/6/06 2:52p btosi * PR3541: adding use of the BDBG_MODULE macro for integration with the * RNG200 build * * 2 5/17/05 7:44p shyam * PR 8365 : Making it work at runtime * * 1 5/9/05 3:50p shyam * PR 8365 : Add other sub-modules of ccgfx * ***************************************************************************/ #include "bdcc_kernel.h" #include "bdccservice.h" #include "bdccpriv.h" BDBG_MODULE(bdccservice); typedef enum { BDCC_SRV_P_State_eLookingForHeader, BDCC_SRV_P_State_eLookingForExtendedHeader, BDCC_SRV_P_State_eCollectingBlock, BDCC_SRV_P_State_eSkippingBlock, BDCC_SRV_P_State_eFinishedHeader, BDCC_SRV_P_State_eFinishedBlock } BDCC_SRV_P_State ; //RLQ, tracking caption service block data received #define MAX_CS 7 /* CS 1 - 6, plus extended service */ unsigned int BDCC_SRV_CS_Count[7] = { 0, 0, 0, 0, 0, 0, 0 }; unsigned int BDCC_SRV_Get_CS_Block_Count(int cs) { if ((cs >= 1) && (cs <= 7)) return BDCC_SRV_CS_Count[cs - 1]; else return -1; } /************************************************************************** * * Function: DccService_Process * * Inputs: * pInBuf - input buffer * ServiceA - service number * ServiceB - service number, or BDCC_SRV_SERVICE_ILLEGAL * * Outputs: * pOutBufA - output buffer * pOutBufB - output buffer, or NULL * pNewActivity - activity on selectged caption service * * Returns: BDCC_Error_eSuccess or a standard BDCC_Error error code * * Description: * * This function reads the input stream and outputs complete * DTVCC service blocks, not including the header. * * The input stream format is that produced by DccPacket_Process and * contains DTVCC packets. * * This version of the function does not consume the input and generate * output for partial blocks. Only when the input contains one complete * block will the input be consumed and the output generated. The output * may contain multiple complete blocks. * **************************************************************************/ BDCC_Error BDCC_SRV_P_Process( BDCC_CBUF * pInBuf, unsigned int ServiceA, unsigned int ServiceB, BDCC_CBUF * pOutBufA, BDCC_CBUF * pOutBufB, bool * pNewActivity ) { BDCC_SRV_P_State state ; unsigned int BytesThisBlock ; BDCC_CBUF * pOutInfo ; unsigned int NumBytes ; unsigned int HeaderBytes ; unsigned int block_size = 0 ; unsigned int service_number = 0 ; unsigned int curIndex ; unsigned char curByte ; BDCC_DBG_MSG(("%s", __FUNCTION__)); *pNewActivity = false; /* * Validate Arguments */ if ( pInBuf == NULL ) { BDCC_DBG_ERR(("BDCC_SRV_P_Process: null pointer as argument\n")) ; return(BDCC_Error_eNullPointer) ; } /* * Prep output buffers. */ if ( pOutBufA ) { BDCC_CBUF_ResetPost(pOutBufA) ; pOutBufA->Error = BDCC_Error_eSuccess ; } else ServiceA = BDCC_SRV_SERVICE_ILLEGAL ; if ( pOutBufB ) { BDCC_CBUF_ResetPost(pOutBufB) ; pOutBufB->Error = BDCC_Error_eSuccess ; } else ServiceB = BDCC_SRV_SERVICE_ILLEGAL ; BDCC_CBUF_ResetPeek(pInBuf) ; state = BDCC_SRV_P_State_eLookingForHeader ; BytesThisBlock = 0 ; pOutInfo = NULL ; HeaderBytes = 0 ; NumBytes = pInBuf->NumBytes ; for ( curIndex=0 ; curIndex < NumBytes ; curIndex++ ) { curByte = BDCC_CBUF_PeekByte(pInBuf) ; switch ( state ) { case BDCC_SRV_P_State_eLookingForHeader : block_size = curByte & 0x1F ; service_number = (curByte >> 5) & 0x07 ; BytesThisBlock = 0 ; pOutInfo = NULL ; HeaderBytes = 1 ; BDCC_DBG_MSG(("%s: Service Numer = %d, block=%d", __FUNCTION__,service_number, block_size)); //RLQ if (service_number > 0) BDCC_SRV_CS_Count[service_number - 1]++; if ( service_number == 7) { state = BDCC_SRV_P_State_eLookingForExtendedHeader ; } else state = BDCC_SRV_P_State_eFinishedHeader ; break ; case BDCC_SRV_P_State_eLookingForExtendedHeader : HeaderBytes++ ; service_number = curByte & 0x3F ; state = BDCC_SRV_P_State_eFinishedHeader ; break ; case BDCC_SRV_P_State_eCollectingBlock : BDCC_DBG_MSG(("%s: CollectingBlock = %d", __FUNCTION__,service_number)); BDCC_CBUF_PostByte(pOutInfo, curByte) ; /* fall thru... */ case BDCC_SRV_P_State_eSkippingBlock : BDCC_DBG_MSG(("%s: SkippingBlock", __FUNCTION__)); BytesThisBlock++ ; if ( BytesThisBlock == block_size ) { /* done */ state = BDCC_SRV_P_State_eFinishedBlock ; } break ; default : break ; } /* switch (state) */ /* * Handle the sequential states now. */ if ( state == BDCC_SRV_P_State_eFinishedHeader ) { BDCC_DBG_MSG(("%s: FinishedHeader", __FUNCTION__)); if ( block_size == 0 || service_number == 0 ) { /* done, looking for next header */ state = BDCC_SRV_P_State_eFinishedBlock ; } else if ( service_number == ServiceA ) { pOutInfo = pOutBufA ; state = BDCC_SRV_P_State_eCollectingBlock ; } else if ( service_number == ServiceB ) { pOutInfo = pOutBufB ; state = BDCC_SRV_P_State_eCollectingBlock ; } else state = BDCC_SRV_P_State_eSkippingBlock ; } if ( state == BDCC_SRV_P_State_eFinishedBlock ) { BDCC_DBG_MSG(("%s: FinishedBlock", __FUNCTION__)); if ( pOutInfo ) BDCC_CBUF_UpdatePost(pOutInfo) ; *pNewActivity = true; BDCC_CBUF_UpdatePeek(pInBuf) ; state = BDCC_SRV_P_State_eLookingForHeader ; } } /* for (each input byte) */ /* * this final BDCC_CBUF_UpdatePeek will ensure that any partial * block at the end of the packet will get dropped and * not be incorrectly interpreted -- note that this requires * that the packet layer above stops at packet boundaries */ BDCC_CBUF_UpdatePeek(pInBuf) ; return(BDCC_Error_eSuccess) ; } /* DccService_Process */