//ストリーム内の現在の時間情報を取得する //引数: // time [OUT]ストリーム内の現在の時間 BOOL CDecodeUtil::GetNowTime( SYSTEMTIME* time ) { if( this->totInfo != NULL ){ *time = this->totInfo->jst_time; return TRUE; }else if( this->tdtInfo != NULL ){ *time = this->tdtInfo->jst_time; return TRUE; }else{ if( this->sitInfo != NULL ){ for( size_t i=0; i<this->sitInfo->descriptorList.size(); i++ ){ if( this->sitInfo->descriptorList[i]->GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::partialTS_time_descriptor ){ if( this->sitInfo->descriptorList[i]->GetNumber(AribDescriptor::jst_time_flag) == 1 ){ DWORD timeBytesSize; const BYTE* timeBytes = this->sitInfo->descriptorList[i]->GetBinary(AribDescriptor::jst_time, &timeBytesSize); if( timeBytes != NULL && timeBytesSize >= 5 ){ DWORD mjd = timeBytes[0] << 8 | timeBytes[1]; _MJDtoSYSTEMTIME(mjd, time); BYTE b = timeBytes[2]; time->wHour = (WORD)_BCDtoDWORD(&b, 1, 2); b = timeBytes[3]; time->wMinute = (WORD)_BCDtoDWORD(&b, 1, 2); b = timeBytes[4]; time->wSecond = (WORD)_BCDtoDWORD(&b, 1, 2); return TRUE; } } } } } return FALSE; } }
BOOL CTDTTable::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( data == NULL ){ return FALSE; } ////////////////////////////////////////////////////// //サイズのチェック //最低限table_idとsection_length+CRCのサイズは必須 if( dataSize < 7 ){ return FALSE; } //->サイズのチェック DWORD readSize = 0; ////////////////////////////////////////////////////// //解析処理 table_id = data[0]; section_syntax_indicator = (data[1]&0x80)>>7; section_length = ((WORD)data[1]&0x0F)<<8 | data[2]; readSize+=3; if( section_syntax_indicator != 0 ){ //固定値がおかしい _OutputDebugString( L"++CTDTTable:: section_syntax err" ); return FALSE; } if( table_id != 0x70 ){ //table_idがおかしい _OutputDebugString( L"++CTDTTable:: table_id err 0x%02X", table_id ); return FALSE; } if( section_length != 0x0005){ //サイズ異常 _OutputDebugString( L"++CTDTTable:: size err %d > %d", readSize+section_length, dataSize ); return FALSE; } if( section_length > 4 ){ DWORD mjd = ((DWORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &jst_time); jst_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); jst_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); jst_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize += 5; }else{ return FALSE; } //->解析処理 if( decodeReadSize != NULL ){ *decodeReadSize = 3+section_length; } return TRUE; }
BOOL CDecodeUtil::CheckSIT(WORD PID, CSITTable* sit) { if( sit == NULL ){ return FALSE; } //時間計算 if( this->totTime.dwHighDateTime == 0 && this->tdtTime.dwHighDateTime == 0 ){ for( size_t i=0; i<sit->descriptorList.size(); i++ ){ if( sit->descriptorList[i]->GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::partialTS_time_descriptor ){ if( sit->descriptorList[i]->GetNumber(AribDescriptor::jst_time_flag) == 1 ){ DWORD timeBytesSize; const BYTE* timeBytes = sit->descriptorList[i]->GetBinary(AribDescriptor::jst_time, &timeBytesSize); if( timeBytes != NULL && timeBytesSize >= 5 ){ DWORD mjd = timeBytes[0] << 8 | timeBytes[1]; SYSTEMTIME time; _MJDtoSYSTEMTIME(mjd, &time); BYTE b = timeBytes[2]; time.wHour = (WORD)_BCDtoDWORD(&b, 1, 2); b = timeBytes[3]; time.wMinute = (WORD)_BCDtoDWORD(&b, 1, 2); b = timeBytes[4]; time.wSecond = (WORD)_BCDtoDWORD(&b, 1, 2); if( SystemTimeToFileTime(&time, &this->sitTime) == FALSE ){ this->sitTime.dwHighDateTime = 0; } this->sitTimeTick = GetTickCount(); } } } } } if( epgDBUtil != NULL ){ if( this->patInfo != NULL ){ epgDBUtil->AddServiceList(this->patInfo->transport_stream_id, sit); } } if( this->sitInfo == NULL ){ //初回 this->sitInfo = sit; }else{ if( this->sitInfo->version_number != sit->version_number ){ //バージョン変わった SAFE_DELETE(this->sitInfo); this->sitInfo = sit; }else{ //変化なし return FALSE; } } return TRUE; }
BOOL CEITTable_SD2::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( InitDecode(data, dataSize, decodeReadSize, TRUE) == FALSE ) { return FALSE; } Clear(); if( section_syntax_indicator != 1 ) { //固定値がおかしい _OutputDebugString( L"++CEITTable_SD2:: section_syntax err" ); return FALSE; } if( table_id != 0xA3 && table_id != 0xA2 ) { //table_idがおかしい _OutputDebugString( L"++CEITTable_SD2:: table_id err 0x%02X", table_id ); return FALSE; } if( section_length - 4 > 18 ) { service_id = ((WORD)data[readSize])<<8 | data[readSize+1]; version_number = (data[readSize+2]&0x3E)>>1; current_next_indicator = data[readSize+2]&0x01; section_number = data[readSize+3]; last_section_number = data[readSize+4]; service_id2 = ((WORD)data[readSize+5])<<8 | data[readSize+6]; original_network_id = ((WORD)data[readSize+7])<<8 | data[readSize+8]; readSize += 9; DWORD mjd = ((DWORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &start_time); start_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); start_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); start_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize += 5; mjd = ((DWORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &end_time); end_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); end_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); end_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize += 5; while( readSize+3 < (DWORD)section_length+3-4 ) { EVENT_MAP_INFO* item = new EVENT_MAP_INFO; item->descriptor_length = ((WORD)data[readSize]&0x03)<<8 | data[readSize+1]; mjd = ((DWORD)data[readSize+2])<<8 | data[readSize+3]; _MJDtoSYSTEMTIME(mjd, &item->start_day); DWORD readDesc = 4; DWORD max = item->descriptor_length; max+=2; while( readSize+readDesc+6 < (DWORD)section_length+3-4 && readDesc < max ) { EVENT_MAP_DATA dataInfo; dataInfo.event_id = ((WORD)data[readSize+readDesc])<<8 | data[readSize+readDesc+1]; dataInfo.hour = data[readSize+readDesc+2]>>3; dataInfo.minute = (data[readSize+readDesc+2]&0x07)*10; dataInfo.minute += data[readSize+readDesc+3]>>4; BYTE length = data[readSize+readDesc+3]&0x0F; dataInfo.a4table_eventID = ((WORD)data[readSize+readDesc+5])<<8 | data[readSize+readDesc+6]; if( readSize+readDesc+10 < (DWORD)section_length+3-4 && length == 7 ) { dataInfo.duration = _BCDtoDWORD(data+readSize+readDesc+8, 1, 2)*60*60; dataInfo.duration += _BCDtoDWORD(data+readSize+readDesc+9, 1, 2)*60; dataInfo.duration += _BCDtoDWORD(data+readSize+readDesc+10, 1, 2); } else { dataInfo.duration = 0; } readDesc+=4+length; item->eventList.push_back(dataInfo); } eventMapList.push_back(item); readSize+=item->descriptor_length+2; } } else {
BOOL CTOTTable::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( data == NULL ){ return FALSE; } Clear(); ////////////////////////////////////////////////////// //サイズのチェック //最低限table_idとsection_length+CRCのサイズは必須 if( dataSize < 7 ){ return FALSE; } //->サイズのチェック DWORD readSize = 0; ////////////////////////////////////////////////////// //解析処理 table_id = data[0]; section_syntax_indicator = (data[1]&0x80)>>7; section_length = ((WORD)data[1]&0x0F)<<8 | data[2]; readSize+=3; if( section_syntax_indicator != 0 ){ //固定値がおかしい _OutputDebugString( L"++CTOTTable:: section_syntax err" ); return FALSE; } if( table_id != 0x73 ){ //table_idがおかしい _OutputDebugString( L"++CTOTTable:: table_id err 0x%02X", table_id ); return FALSE; } if( readSize+section_length > dataSize && section_length > 3){ //サイズ異常 _OutputDebugString( L"++CTOTTable:: size err %d > %d", readSize+section_length, dataSize ); return FALSE; } //CRCチェック crc32 = ((DWORD)data[3+section_length-4])<<24 | ((DWORD)data[3+section_length-3])<<16 | ((DWORD)data[3+section_length-2])<<8 | data[3+section_length-1]; if( crc32 != _Crc32(3+section_length-4, data) ){ _OutputDebugString( L"++CTOTTable:: CRC err" ); return FALSE; } if( section_length > 4 ){ DWORD mjd = ((DWORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &jst_time); jst_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); jst_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); jst_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize += 5; descriptors_loop_length = ((WORD)data[readSize]&0x0F)<<8 | data[readSize+1]; readSize += 2; if( readSize+descriptors_loop_length <= (DWORD)section_length+3-4 && descriptors_loop_length > 0){ CDescriptor descriptor; if( descriptor.Decode( data+readSize, descriptors_loop_length, &descriptorList, NULL ) == FALSE ){ _OutputDebugString( L"++CTOTTable:: descriptor2 err" ); return FALSE; } } readSize+=descriptors_loop_length; }else{ return FALSE; } //->解析処理 if( decodeReadSize != NULL ){ *decodeReadSize = 3+section_length; } return TRUE; }
BOOL CEITTable_SD::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( data == NULL ){ return FALSE; } Clear(); ////////////////////////////////////////////////////// //サイズのチェック //最低限table_idとsection_length+CRCのサイズは必須 if( dataSize < 7 ){ return FALSE; } //->サイズのチェック DWORD readSize = 0; ////////////////////////////////////////////////////// //解析処理 table_id = data[0]; section_syntax_indicator = (data[1]&0x80)>>7; section_length = ((WORD)data[1]&0x0F)<<8 | data[2]; readSize+=3; if( section_syntax_indicator != 1 ){ //固定値がおかしい _OutputDebugString( L"++CEITTable_SD:: section_syntax err" ); return FALSE; } if( table_id != 0xA4 && table_id != 0xA7 ){ //table_idがおかしい _OutputDebugString( L"++CEITTable_SD:: table_id err 0x%02X", table_id ); return FALSE; } if( readSize+section_length > dataSize && section_length > 3){ //サイズ異常 _OutputDebugString( L"++CEITTable_SD:: size err %d > %d", readSize+section_length, dataSize ); return FALSE; } //CRCチェック crc32 = ((DWORD)data[3+section_length-4])<<24 | ((DWORD)data[3+section_length-3])<<16 | ((DWORD)data[3+section_length-2])<<8 | data[3+section_length-1]; if( crc32 != _Crc32(3+section_length-4, data) ){ _OutputDebugString( L"++CEITTable_SD:: CRC err" ); return FALSE; } if( section_length > 4 ){ service_id = ((WORD)data[readSize])<<8 | data[readSize+1]; version_number = (data[readSize+2]&0x3E)>>1; current_next_indicator = data[readSize+2]&0x01; section_number = data[readSize+3]; last_section_number = data[readSize+4]; transport_stream_id = ((WORD)data[readSize+5])<<8 | data[readSize+6]; original_network_id = ((WORD)data[readSize+7])<<8 | data[readSize+8]; readSize += 9; while( readSize < (DWORD)section_length+3-4 ){ EVENT_INFO_DATA* item = new EVENT_INFO_DATA; item->event_id = ((WORD)data[readSize])<<8 | data[readSize+1]; if( data[readSize+2] == 0xFF && data[readSize+3] == 0xFF && data[readSize+4] == 0xFF && data[readSize+5] == 0xFF && data[readSize+6] == 0xFF ) { item->StartTimeFlag = FALSE; }else{ item->StartTimeFlag = TRUE; DWORD mjd = ((DWORD)data[readSize+2])<<8 | data[readSize+3]; _MJDtoSYSTEMTIME(mjd, &(item->start_time)); item->start_time.wHour = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); item->start_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+5, 1, 2); item->start_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+6, 1, 2); } readSize+=7; if( data[readSize] == 0xFF && data[readSize+1] == 0xFF && data[readSize+2] == 0xFF) { item->DurationFlag = FALSE; }else{ item->DurationFlag = TRUE; item->durationHH = (WORD)_BCDtoDWORD(data+readSize, 1, 2); item->durationMM = (WORD)_BCDtoDWORD(data+readSize+1, 1, 2); item->durationSS = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); } readSize+=3; item->running_status = (data[readSize]&0xE0)>>5; item->free_CA_mode = (data[readSize]&0x10)>>4; item->descriptors_loop_length = ((WORD)data[readSize]&0x0F)<<8 | data[readSize+1]; readSize += 2; if( readSize+item->descriptors_loop_length <= (DWORD)section_length+3-4 && item->descriptors_loop_length > 0){ if( original_network_id == 0x0001 || original_network_id == 0x0003 ){ SDDecode( data+readSize, item->descriptors_loop_length, &(item->descriptorList), NULL ); }else{ CDescriptor descriptor; if( descriptor.Decode( data+readSize, item->descriptors_loop_length, &(item->descriptorList), NULL ) == FALSE ){ _OutputDebugString( L"++CEITTable_SD:: descriptor2 err" ); return FALSE; } } } readSize+=item->descriptors_loop_length; eventInfoList.push_back(item); } }else{
BOOL CPartialTSTimeDesc::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( data == NULL ){ return FALSE; } ////////////////////////////////////////////////////// //サイズのチェック //最低限descriptor_tagとdescriptor_lengthのサイズは必須 if( dataSize < 2 ){ return FALSE; } //->サイズのチェック DWORD readSize = 0; ////////////////////////////////////////////////////// //解析処理 descriptor_tag = data[0]; descriptor_length = data[1]; readSize += 2; if( descriptor_tag != 0xC3 ){ //タグ値がおかしい _OutputDebugString( L"++++CPartialTSTimeDesc:: descriptor_tag err 0xC3 != 0x%02X", descriptor_tag ); return FALSE; } if( readSize+descriptor_length > dataSize ){ //サイズ異常 _OutputDebugString( L"++++CPartialTSTimeDesc:: size err %d > %d", readSize+descriptor_length, dataSize ); return FALSE; } if( descriptor_length > 0 ){ event_version_number = data[readSize]; readSize++; DWORD mjd = ((WORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &event_start_time); event_start_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); event_start_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); event_start_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize+=5; duration_HH = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); duration_MM = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); duration_SS = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize+=3; offset_HH = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); offset_MM = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); offset_SS = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize+=3; offset_flag = (data[readSize]&0x04)>>2; other_descriptor_status = (data[readSize]&0x02)>>1; jst_time_flag = data[readSize]&0x01; readSize++; if( jst_time_flag == 1 ){ mjd = ((WORD)data[readSize])<<8 | data[readSize+1]; _MJDtoSYSTEMTIME(mjd, &jst_time); jst_time.wHour = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); jst_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+3, 1, 2); jst_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); readSize+=5; } }else{
BOOL CEITTable::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( InitDecode(data, dataSize, decodeReadSize, TRUE) == FALSE ){ return FALSE; } Clear(); if( section_syntax_indicator != 1 ){ //固定値がおかしい _OutputDebugString( L"++CEITTable:: section_syntax err" ); return FALSE; } if( table_id < 0x4E || table_id > 0x6F ){ //table_idがおかしい _OutputDebugString( L"++CEITTable:: table_id err 0x%02X", table_id ); return FALSE; } if( section_length - 4 > 10 ){ service_id = ((WORD)data[readSize])<<8 | data[readSize+1]; version_number = (data[readSize+2]&0x3E)>>1; current_next_indicator = data[readSize+2]&0x01; section_number = data[readSize+3]; last_section_number = data[readSize+4]; transport_stream_id = ((WORD)data[readSize+5])<<8 | data[readSize+6]; original_network_id = ((WORD)data[readSize+7])<<8 | data[readSize+8]; segment_last_section_number = data[readSize+9]; last_table_id = data[readSize+10]; readSize += 11; while( readSize+11 < (DWORD)section_length+3-4 ){ EVENT_INFO_DATA* item = new EVENT_INFO_DATA; item->event_id = ((WORD)data[readSize])<<8 | data[readSize+1]; if( data[readSize+2] == 0xFF && data[readSize+3] == 0xFF && data[readSize+4] == 0xFF && data[readSize+5] == 0xFF && data[readSize+6] == 0xFF ) { item->StartTimeFlag = FALSE; }else{ item->StartTimeFlag = TRUE; DWORD mjd = ((DWORD)data[readSize+2])<<8 | data[readSize+3]; _MJDtoSYSTEMTIME(mjd, &(item->start_time)); item->start_time.wHour = (WORD)_BCDtoDWORD(data+readSize+4, 1, 2); item->start_time.wMinute = (WORD)_BCDtoDWORD(data+readSize+5, 1, 2); item->start_time.wSecond = (WORD)_BCDtoDWORD(data+readSize+6, 1, 2); } readSize+=7; if( data[readSize] == 0xFF && data[readSize+1] == 0xFF && data[readSize+2] == 0xFF) { item->DurationFlag = FALSE; }else{ item->DurationFlag = TRUE; item->durationHH = (WORD)_BCDtoDWORD(data+readSize, 1, 2); item->durationMM = (WORD)_BCDtoDWORD(data+readSize+1, 1, 2); item->durationSS = (WORD)_BCDtoDWORD(data+readSize+2, 1, 2); } readSize+=3; item->running_status = (data[readSize]&0xE0)>>5; item->free_CA_mode = (data[readSize]&0x10)>>4; item->descriptors_loop_length = ((WORD)data[readSize]&0x0F)<<8 | data[readSize+1]; readSize += 2; if( readSize+item->descriptors_loop_length <= (DWORD)section_length+3-4 && item->descriptors_loop_length > 0){ if( original_network_id == 0x0001 || original_network_id == 0x0003 ){ SDDecode( data+readSize, item->descriptors_loop_length, &(item->descriptorList), NULL ); }else{ if( AribDescriptor::CreateDescriptors( data+readSize, item->descriptors_loop_length, &(item->descriptorList), NULL ) == FALSE ){ _OutputDebugString( L"++CEITTable:: descriptor2 err" ); SAFE_DELETE(item); return FALSE; } } } readSize+=item->descriptors_loop_length; eventInfoList.push_back(item); } }else{