개정번호개정장개정내역작성자시행일자 0.1 전체 시작강선영 Demux Part 추가 “ 개정이력 Jaram TS Reader 문서번호버전 0.1 쪽 1 작성자강선영최종수정일자 작업단계시스템 모듈
Tune Device Base EPG File Base Demux SI Parsor DB or File DB or File API Inter face API Inter face UI Jaram TS Reader 문서번호버전 0.1 쪽 2 작성자강선영최종수정일자 작업단계 시스템 전체 블록도시스템 모듈 전체 구성 + Tuner - TS File - Device - export API + Demux - Section Filter - Multi PID Extrator - Recoding AV TS Stream - export API + EPG - PSI / SI Parsor - DB - export API + Util - TS Queue
Tune Jaram TS Reader 문서번호버전 0.1 쪽 3 작성자강선영최종수정일자 작업단계시스템 모듈
UI API Interface API Interface APIs List /* Tuner Commom API List */ void TN_InitTune(); void TN_DeInitTune(); void TN_CreateTune(Handle *_tuneInfo, UInt32 _deviceType); void TN_DestroyTune(Handle _handle); int TN_GetReferenceCount(); // callback function type typedef void(*ReceiveTSCallback)(unsigned char* buf, unsigned int size); void TN_SetReceiveTSCallback(Handle _handle, ReceiveTSCallback _callback); void TN_SetFrequency(Handle _handle, UInt32 _frequency, UInt32 _bandWidth); Jaram TS Reader 문서번호버전 0.2 쪽 4 작성자강선영최종수정일자 작업단계 Tuner 블록도시스템 모듈 Demux File Base Device Base
Demux Jaram TS Reader 문서번호버전 0.1 쪽 5 작성자강선영최종수정일자 작업단계시스템 모듈
Demux Recoding AV TS Stream UI Multi PID Extrator Multi PID Extrator API Interface API Interface PES Filter PES Filter Section Filter Section Filter APIs List DMX_GetPIDList() DMX_GetPIDMultiExtrator( FileName, ExtratorInfo) /* PID */ void DMX_AddPid(int pid); void DMX_removePid(int pid); void DMX_WriteTsBuffer(unsigned char buf, int len); /* Section */ void DMX_CreateSectionFilter(); void DMX_CloseSectionFilter(); void DMX_AddSectionFilter(); void DMX_RemoveSectionFilter(); /* TS Navigation */ void DMX_StartTSNavigation() void DMX_StopTSNavigation() void DMX_SetNavigationPos(int _seekPos) /* Internal API List */ void DMXi_CheckCRC(); Jaram TS Reader 문서번호버전 0.2 쪽 6 작성자강선영최종수정일자 작업단계 Demux 블록도시스템 모듈
PID : TS 상에서 유니크 하다. 왜 아래 코드처럼 구현했을까 ? * PID = 13bit = 2^13 = 8192 갯수 8k * Data Structure - extratorPidList[MAX_PID_COUNT]; * 통상적으로 LinkList 로 구현하나, 실제 효율이나 비용면에서는 메모리를 조금 더 쓰는게 좋다. - Add 와 Remove 를 위해 Array 에 Index 만 사용 Jaram TS Reader 문서번호버전 0.2 쪽 7 작성자강선영최종수정일자 작업단계 Multi PID Extrator 시스템 모듈 Demux void DMX_AddPid(Handle _handle, int _pid) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; if ( FALSE == DMXi_VarifyHandle(_handle)) { return ; } demuxInfo->extratorPidList[_pid] = TRUE; } void DMX_AddPid(Handle _handle, int _pid) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; if ( FALSE == DMXi_VarifyHandle(_handle)) { return ; } demuxInfo->extratorPidList[_pid] = TRUE; } void DMX_RemovePid(Handle _handle, int _pid) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; if ( FALSE == DMXi_VarifyHandle(_handle)) { return ; } demuxInfo->extratorPidList[_pid] = FALSE; } void DMX_RemovePid(Handle _handle, int _pid) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; if ( FALSE == DMXi_VarifyHandle(_handle)) { return ; } demuxInfo->extratorPidList[_pid] = FALSE; } 참 쉽죵 !!!!
Demux Action Item Tuner 로 부터 TS Buffer 를 받아들여, TS Sync Byte 로 정렬하는 Function 이 필요합니다. DoDemux( unsigned char buffer, int len ) { 1. 0x47 을 찾는다 byte 을 더해서 0x47 인지를 확인한다. 3. sync byte 가 맞지 않는다면 해당 버퍼는 버린다. 4. 마지막 Byte 와 새롭게 들어올 Byte 를 연결하는 Buffer 를 만든다. } 추가 : TS 에 TS Header Information 을 Console 로 출력 해본다. Jaram TS Reader 문서번호버전 0.2 쪽 8 작성자강선영최종수정일자 작업단계 Demux Action Item. 1 ( 고상태 ) 시스템 모듈 Demux
Epg Jaram TS Reader 문서번호버전 0.1 쪽 9 작성자강선영최종수정일자 작업단계시스템 모듈
Jaram TS Reader 문서번호버전 0.2 쪽 10 작성자강선영최종수정일자 작업단계 SI Parsor 시스템 모듈 EPG SI Parsor DB or File DB or File API Inter face API Inter face UI 전체 구성 + EPG - PSI / SI Parsor * PAT ( 완료 ) * PMT * SDT * NIT * EIT * TOT 구현 초점 : 1. Section 처리에 대한 동일한 Interface 가 유지 되도록 작성 2. 예외처리에 강하도록 작성 3. 불필요한 필드 사용하지 않음
Jaram TS Reader 문서번호버전 0.2 쪽 11 작성자강선영최종수정일자 작업단계 SI - PAT 시스템 모듈
Jaram TS Reader 문서번호버전 0.2 쪽 12 작성자강선영최종수정일자 작업단계 SI - PAT 시스템 모듈 Structure /* Structure sub section of pat*/ typedef struct tagPat_subsection { struct tagPat_subsection *pNext; TUint16 program_number; TUint16 network_pid; TUint16 program_map_pid; }pat_subsection; typedef struct tagPat_section { pat_subsection *sub_table; TUint16 section_length; TUint16 transport_stream_id; TUint8 table_id; TUint8 section_syntax_indicator; TUint8 version_number; TUint8 current_next_indicator; TUint8 section_number; TUint8 last_section_number; }pat_section; Structure /* Structure sub section of pat*/ typedef struct tagPat_subsection { struct tagPat_subsection *pNext; TUint16 program_number; TUint16 network_pid; TUint16 program_map_pid; }pat_subsection; typedef struct tagPat_section { pat_subsection *sub_table; TUint16 section_length; TUint16 transport_stream_id; TUint8 table_id; TUint8 section_syntax_indicator; TUint8 version_number; TUint8 current_next_indicator; TUint8 section_number; TUint8 last_section_number; }pat_section; API List /* Structure sub section of pat*/ extern void* DecodePatSection(TUint8 *_pBuffer, TUint32 _len); extern TBool ClearPatSection(pat_section *_pSection); API List /* Structure sub section of pat*/ extern void* DecodePatSection(TUint8 *_pBuffer, TUint32 _len); extern TBool ClearPatSection(pat_section *_pSection);
Jaram TS Reader 문서번호버전 0.2 쪽 13 작성자강선영최종수정일자 작업단계 SI – PAT ( 강선영 ) 시스템 모듈 extern void *DecodePatSection(TUint8 *_pBuf, TUint32 _len) { pat_section *pPatSection = NULL; pat_subsection *pSubSection = NULL; pat_subsection *pCurSubSection = NULL; TUchar *pStartPos = NULL; TUchar *pEndPos = NULL; if (_len <= 0 || NULL == _pBuf) { return NULL; } /* check the pat syntax */ if (_pBuf != 0x00 || (_pBuf[1] & 0x80) != 0x80) { return NULL; } pPatSection = (pat_section *)malloc(sizeof(pat_section)); if (NULL == pPatSection) { return NULL; } memset(pPatSection, 0, sizeof(pat_section)); pPatSection->table_id = _pBuf[0]; pPatSection->section_syntax_indicator = _pBuf[1] >> 7; pPatSection->section_length = (_pBuf[1] & 0x0f << 8) | _pBuf[2]; /* start section length and include crc len */ pPatSection->transport_stream_id = (_pBuf[3] << 8) | _pBuf[4]; pPatSection->version_number = _pBuf[5] & 0x3e; pPatSection->current_next_indicator = _pBuf[5] & 0x01; pPatSection->section_number = _pBuf[6]; pPatSection->last_section_number = _pBuf[7]; // decoding sub section here */ if (pPatSection->section_length <= OFFSET_CRC + OFFSET_SECTION) { return NULL; } pStartPos = _pBuf + OFFSET_SUBSECTION; pEndPos = pStartPos + pPatSection->section_length - (OFFSET_SECTION + OFFSET_CRC); /* start sub section loop */ do { pCurSubSection = (pat_subsection *)malloc(sizeof(pat_subsection)); memset( pCurSubSection, 0, sizeof(pat_subsection)); /* parsing pmt pid */ pCurSubSection->program_number = pStartPos[0] << 8 | pStartPos[1]; if (pCurSubSection->program_number) { pCurSubSection->program_map_pid = ((pStartPos[2] & 0x1f) << 8) | pStartPos[3]; } else { pCurSubSection->network_pid = ((pStartPos[2] & 0x1f) << 8) | pStartPos[3]; } pStartPos += SUBSECTION_PAYLOD; if (NULL == pPatSection->sub_table) { pSubSection = pCurSubSection; pPatSection->sub_table = pSubSection; } else { pSubSection->pNext = pCurSubSection; pSubSection = pCurSubSection; } } while(pStartPos >= pEndPos); /* End sub section loop */ pSubSection->pNext = NULL; return (void*)pPatSection; }
Jaram TS Reader 문서번호버전 0.2 쪽 14 작성자강선영최종수정일자 작업단계 SI – PMT ( 고상태 ) 시스템 모듈
Jaram TS Reader 문서번호버전 0.2 쪽 15 작성자강선영최종수정일자 작업단계 SI – PMT Action Item. 2 : 고상태시스템 모듈 extern void *DecodePmtSection(TUint8 *_pBuf, TUint32 _len) { } /* if you need, fill out here */
Jaram TS Reader 문서번호버전 0.2 쪽 16 작성자강선영최종수정일자 작업단계 SI – CA ( 강선영 ) 시스템 모듈
Jaram TS Reader 문서번호버전 0.2 쪽 17 작성자강선영최종수정일자 작업단계 SI – PMT Action Item. 2 : 고상태시스템 모듈 extern void *DecodePmtSection(TUint8 *_pBuf, TUint32 _len) { } /* if you need, fill out here */
배경지식 Jaram TS Reader 문서번호버전 0.1 쪽 18 작성자강선영최종수정일자 작업단계시스템 모듈
void DMX_CreateDemux(Handle *_handle) { *_handle = (DEMUX_INFO *) malloc(sizeof(DEMUX_INFO)); } void DMX_CreateDemux(Handle *_handle) { *_handle = (DEMUX_INFO *) malloc(sizeof(DEMUX_INFO)); } Handle Base? –Struct 를 malloc or new 한 pointer address 를 저장하는 방식 – 외부에서는 Handle 로 접근하고, 해당 Module 에서는 Handle 을 원래 Struct 로 Casting 해서 사용함 Handle Create 및 Close 예제코드 - Create - Close void DMX_CloseDemux(Handle _handle) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; free(demuxInfo); } void DMX_CloseDemux(Handle _handle) { DEMUX_INFO *demuxInfo = (DEMUX_INFO *)_handle; free(demuxInfo); } Handle TestHandle = 0; UInt32 deviceType = TUNE_FILE; - create DMX_CreateDemux (&TestHandle); if (0 == TestHandle) { assert(0); } - close DMX_CloseDemux(TestHandle); Handle TestHandle = 0; UInt32 deviceType = TUNE_FILE; - create DMX_CreateDemux (&TestHandle); if (0 == TestHandle) { assert(0); } - close DMX_CloseDemux(TestHandle); Jaram TS Reader 문서번호버전 0.2 쪽 19 작성자강선영최종수정일자 작업단계 Handle Base? 시스템 모듈배경지식 공유
Reference Counter? –Module 이 생성되면서 각 Handle 을 저장하고, Count 를 증가 시킨다. – 외부에서는 Handle 로 접근시, Handle 의 유효성을 체크 할 수 있다. 예제코드 Handle 검사 TBool DMXi_VarifyHandle(Handle _handle) { TUint32 i = 0; if (NULL == DMX_GetReferenceCount()) { return FALSE; } for (i = 0; i < DEMUX_MAX; i ++) { if (_handle == g_referPoint[i]) { break; } if (DEMUX_MAX == i) { return FALSE; } return TRUE; } 사용 예 assert(DMXi_VarifyHandle(_handle)); Handle 검사 TBool DMXi_VarifyHandle(Handle _handle) { TUint32 i = 0; if (NULL == DMX_GetReferenceCount()) { return FALSE; } for (i = 0; i < DEMUX_MAX; i ++) { if (_handle == g_referPoint[i]) { break; } if (DEMUX_MAX == i) { return FALSE; } return TRUE; } 사용 예 assert(DMXi_VarifyHandle(_handle)); Jaram TS Reader 문서번호버전 0.2 쪽 20 작성자강선영최종수정일자 작업단계 Reference Counter? 시스템 모듈배경지식 공유 종료 시, 모든 핸들 삭제 void DMX_DeInitDemux() { // Check the g_referCount and free handle TUint32 i = 0; if (NULL == DMX_GetReferenceCount()) { return; } for (i = 0; i < DEMUX_MAX; i ++) { if (NULL == g_referPoint[i]) { continue; } free ((DEMUX_INFO *)g_referPoint[i]); g_referPoint[i] = 0; g_referCount--; } 종료 시, 모든 핸들 삭제 void DMX_DeInitDemux() { // Check the g_referCount and free handle TUint32 i = 0; if (NULL == DMX_GetReferenceCount()) { return; } for (i = 0; i < DEMUX_MAX; i ++) { if (NULL == g_referPoint[i]) { continue; } free ((DEMUX_INFO *)g_referPoint[i]); g_referPoint[i] = 0; g_referCount--; }