/**************************************************************************** * 'Copyright (c) 2004 Digital Stream Technologies Inc. All Rights Reserved. * * Module: dsthalcc.cpp * Author: Jun-ku Park, hwatk@dstreamtech.com * Description: DST HAL Closed Caption * * notes: hwatk20040602 * * TO DO LIST * ***************************************************************************/ /****************************************************************************** * Global variable declaration ******************************************************************************/ /****************************************************************************** * Imported variable declaration ******************************************************************************/ /****************************************************************************** * Imported function declaration ******************************************************************************/ /****************************************************************************** * Local definitions ******************************************************************************/ /****************************************************************************** * Local typedefs ******************************************************************************/ /****************************************************************************** * Local function prototypes ******************************************************************************/ #include #include #include #include #include #include "dsthalcommon.h" #include "dsthalcapcc.h" #include "dsthalcap.h" #include "dstddcap.h" #ifdef DMALLOC #include #endif //#include "dstddcapcc.h" //#include "dstddcap.h" DHL_RESULT Init_VBI_Thread(void); static DHL_RESULT Start_VBI_Thread(void); DHL_RESULT Stop_VBI_Thread(void); int capcc_debug = 0; extern DS_U32 gdhlCapDbgLvl; #if 0 __Public_Functions_____________________________________________________ () #endif DHL_CAP_CC_CONFIG g_CC_Config; DHL_RESULT DHL_CAP_CC_Init(void) { DHL_RESULT dhlResult = DHL_OK; dhlResult = Init_VBI_Thread(); if ( dhlResult != DHL_OK ) { printf("%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__); dhlResult = DHL_FAIL; goto done; } dhlResult = Start_VBI_Thread(); if ( dhlResult != DHL_OK ) { printf("%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__); dhlResult = DHL_FAIL; } done: return dhlResult; } DHL_RESULT DHL_CAP_CC_PresetVideoSource( DHL_CAP_CC_INPUT videoInput ) { DHL_RESULT dhlResult = DHL_OK; /* Video ÀÔ·Â ¼³Á¤ */ g_CC_Config.CCVideoSrc = videoInput; return dhlResult; } DHL_RESULT DHL_CAP_CC_ChangeVideoSource( DHL_CAP_CC_INPUT videoInput ) { DHL_RESULT dhlResult = DHL_OK; /* Video ÀÔ·Â ¼³Á¤ */ g_CC_Config.CCVideoSrc = videoInput; return dhlResult; } DHL_RESULT DHL_CAP_CC_Start(void) { DHL_RESULT dhlResult = DHL_OK; DHL_CAP_VIDEO_INPUT vi; vi = DHL_CAP_GetVideoSrc(0); if ( vi >= DHL_CAP_ATV_VIDEO_START && vi < DHL_CAP_YPBPR_VIDEO_START ) DD_CAP_ResetVBI(0); else DD_CAP_ResetVBI(1); #if 1 dhlResult = Start_VBI_Thread(); if ( dhlResult != DHL_OK ) { printf("%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__); dhlResult = DHL_FAIL; } #endif if(!DHL_ERROR(dhlResult)) DHL_DbgPrintf(gdhlCapDbgLvl,DHLDBG_CAP,"|success|\r\n"); return dhlResult; } DHL_RESULT DHL_CAP_CC_Stop(void) { DHL_RESULT dhlResult = DHL_OK; #if 1 dhlResult = Stop_VBI_Thread(); if ( dhlResult != DHL_OK ) { printf("%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__); dhlResult = DHL_FAIL; } #endif return dhlResult; } DHL_RESULT DHL_CAP_CC_Close(void) { DHL_RESULT dhlResult = DHL_OK; return dhlResult; } DHL_RESULT DHL_CAP_CC_SetCallback( P_DHL_CAP_CC_CALLBACK cbFunc, DHL_CAP_CC_INPUT videoInput ) { DHL_RESULT dhlResult = DHL_OK; g_CC_Config.cbFunc[videoInput-DHL_CAP_CC_INPUT_START] = cbFunc; return dhlResult; } static void CbCapCC(DHL_CAP_CC_INPUT ccVideoSrc, DS_U8 *pVbiBuffer, int Length) { int i, nField; for (i = 0; i < Length; i+=3) { if ( pVbiBuffer[i] & 0x01 ) nField = 1; else nField = 2; if ( g_CC_Config.cbFunc[ccVideoSrc-DHL_CAP_CC_INPUT_START] ) (g_CC_Config.cbFunc[ccVideoSrc-DHL_CAP_CC_INPUT_START])(ccVideoSrc, nField, pVbiBuffer[i+1], pVbiBuffer[i+2]); if (capcc_debug==1) { #define ASCII(x) ( ( ( (x) >= ' ' ) && ( (x) <= '~' ) ) ? (x) : '.' ) if (nField==2) /* CH2 */ printf( "\t\t\t\t\t[0x%x] [%x %x] %c%c\n", pVbiBuffer[i], pVbiBuffer[i+1], pVbiBuffer[i+2], ASCII(pVbiBuffer[i+1]), ASCII(pVbiBuffer[i+2]) ); else printf( "[0x%x] [%x %x] %c%c\n", pVbiBuffer[i], pVbiBuffer[i+1], pVbiBuffer[i+2], ASCII(pVbiBuffer[i+1]), ASCII(pVbiBuffer[i+2]) ); } } } #if 0 __Internal_Functions_____________________________________________________ () #endif static DS_BOOL bVBI_ThreadActive = _FALSE_; static DS_BOOL bVBI_ThreadActiveReq = _FALSE_; #define VBI_THREAD_DELAY 100 #define VBI_THREAD_PRIORITY 150 #define VBI_THREAD_STACKSIZE 32768 #define VBI_SIZE 1024*10 static DS_U8 vbiBuffer[VBI_SIZE]; static DS_U32 vbiThreadId = (DS_U32)0; void DHL_CAP_VBIThread(DS_U32 arg) { DHL_RESULT dhlResult; int len; DHL_CAP_VIDEO_INPUT vi; DHL_CAP_CC_INPUT capVi; while(1) { // // Start ÀÌÀüÀ̰ųª, StopÇÑ °æ¿ì ±×³É IDLE. // if ( bVBI_ThreadActiveReq == _FALSE_) { OS_mDelay(VBI_THREAD_DELAY); bVBI_ThreadActive = _FALSE_; continue; } OS_mDelay(VBI_THREAD_DELAY); bVBI_ThreadActive = _TRUE_; // // Main Path // vi = DHL_CAP_GetVideoSrc(0); if ( vi >= DHL_CAP_ATV_VIDEO_START && vi <= DHL_CAP_YPBPR_VIDEO_STOP ) { len = VBI_SIZE; if ( vi >= DHL_CAP_ATV_VIDEO_START && vi < DHL_CAP_YPBPR_VIDEO_START ) dhlResult = DD_CAP_GetVBI(0, vbiBuffer, &len); else dhlResult = DD_CAP_GetVBI(1, vbiBuffer, &len); if ( dhlResult != DHL_OK ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); continue; } if ( len > 0 ) { if ( vi >= DHL_CAP_ATV_VIDEO_START && vi <= DHL_CAP_YPBPR_VIDEO_STOP ) capVi = DHL_CAP_CC_NTSC_INPUT; else capVi = DHL_CAP_CC_YPBPR_INPUT; CbCapCC( capVi, vbiBuffer, len ); } } // // PIP Path // vi = DHL_CAP_GetVideoSrc(1); if ( vi >= DHL_CAP_ATV_VIDEO_START && vi <= DHL_CAP_YPBPR_VIDEO_STOP ) { len = VBI_SIZE; dhlResult = DD_CAP_GetVBI(1, vbiBuffer, &len); if ( dhlResult != DHL_OK ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); continue; } if ( len > 0 ) { if ( vi >= DHL_CAP_ATV_VIDEO_START && vi <= DHL_CAP_YPBPR_VIDEO_STOP ) capVi = DHL_CAP_CC_NTSC_INPUT; else capVi = DHL_CAP_CC_YPBPR_INPUT; CbCapCC( capVi, vbiBuffer, len ); } } } } DHL_RESULT Init_VBI_Thread(void) { DHL_RESULT dhlResult = DHL_OK; bVBI_ThreadActiveReq = _FALSE_; bVBI_ThreadActive = _FALSE_; vbiThreadId = OS_SpawnTask( DHL_CAP_VBIThread, "tVBIMonitor", 0, 4096, (DS_U32)0); if ( !vbiThreadId ) { printf("ERROR: Cannot create function tvVIMonitor.\n"); dhlResult = DHL_FAIL_OUT_OF_RESOURCE; } return dhlResult; } static DHL_RESULT Start_VBI_Thread(void) { DHL_RESULT dhlResult = DHL_OK; volatile DS_U32 timeout; if ( bVBI_ThreadActiveReq && bVBI_ThreadActive ) { goto done; } bVBI_ThreadActiveReq = _TRUE_; timeout = OS_GetTickCount()+50; do { if ( bVBI_ThreadActive == _TRUE_ ) break; OS_mDelay(VBI_THREAD_DELAY); } while(timeout>OS_GetTickCount()); if ( bVBI_ThreadActive != _TRUE_ && timeout>OS_GetTickCount() ) { printf("|%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__); dhlResult = DHL_FAIL; } done: return dhlResult; } DHL_RESULT Stop_VBI_Thread(void) { DHL_RESULT dhlResult = DHL_OK; volatile DS_U32 timeout; if ( !bVBI_ThreadActiveReq && !bVBI_ThreadActive ) { goto done; } // // MAIN/PIP Áß Çϳª¶óµµ ½ÃÀ۵Ǿî ÀÖÀ¸¸é, Á¤ÁöÇÏÁö ¾Ê´Â´Ù. // bVBI_ThreadActiveReq = _FALSE_; timeout = OS_GetTickCount()+50; do { if ( bVBI_ThreadActive == _FALSE_ ) break; OS_mDelay(VBI_THREAD_DELAY); } while(timeout>OS_GetTickCount()); if ( bVBI_ThreadActive != _FALSE_ && timeout>OS_GetTickCount() ) dhlResult = DHL_FAIL; done: return dhlResult; } void hcapcc_dbg(int nDbg) { capcc_debug = nDbg; }