void CCreatePATPacket::CreatePAT() { this->PSISize = 0; SAFE_DELETE_ARRAY(this->PSI); //まずPSI作成 //pointer_field + last_section_numberまで+PID+CRCのサイズ this->PSISize = 1 + 8 + (int)this->PIDMap.size()*4 + 4; this->PSI = new BYTE[this->PSISize]; memset( this->PSI, 0xFF, this->PSISize ); this->PSI[0] = 0; this->PSI[1] = 0; this->PSI[2] = (BYTE)(((this->PSISize-4)&0x00000F00)>>8); this->PSI[2] |= 0xB0; this->PSI[3] = (BYTE)((this->PSISize-4)&0x000000FF); this->PSI[4] = (BYTE)((this->TSID&0xFF00)>>8); this->PSI[5] = (BYTE)(this->TSID&0x00FF); this->PSI[6] = this->version<<1; this->PSI[6] |= 0xC1; this->PSI[7] = 0; this->PSI[8] = 0; DWORD dwCreateSize = 0; map<WORD, PROGRAM_PID_INFO>::iterator itr; for( itr = this->PIDMap.begin(); itr != this->PIDMap.end(); itr++ ){ this->PSI[9+dwCreateSize] = (BYTE)((itr->second.SID&0xFF00)>>8); this->PSI[9+dwCreateSize+1] = (BYTE)(itr->second.SID&0x00FF); this->PSI[9+dwCreateSize+2] = (BYTE)((itr->second.PMTPID&0xFF00)>>8); this->PSI[9+dwCreateSize+3] = (BYTE)(itr->second.PMTPID&0x00FF); dwCreateSize+=4; } unsigned long ulCrc = _Crc32(8+dwCreateSize,this->PSI+1); this->PSI[this->PSISize-4] = (BYTE)((ulCrc&0xFF000000)>>24); this->PSI[this->PSISize-3] = (BYTE)((ulCrc&0x00FF0000)>>16); this->PSI[this->PSISize-2] = (BYTE)((ulCrc&0x0000FF00)>>8); this->PSI[this->PSISize-1] = (BYTE)(ulCrc&0x000000FF); CreatePacket(); }
BOOL CSITTable::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"++CSITTable:: section_syntax err" ); return FALSE; } if( table_id != 0x7F ){ //table_idがおかしい _OutputDebugString( L"++CSITTable:: table_id err 0x7F != 0x%02X", table_id ); return FALSE; } if( readSize+section_length > dataSize && section_length > 3){ //サイズ異常 _OutputDebugString( L"++CSITTable:: 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"++CSITTable:: CRC err" ); return FALSE; } if( section_length > 8 ){ 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]; transmission_info_loop_length = ((WORD)data[readSize+5]&0x0F)<<8 | data[readSize+6]; readSize += 7; if( readSize+transmission_info_loop_length <= (DWORD)section_length+3-4 && transmission_info_loop_length > 0){ CDescriptor descriptor; if( descriptor.Decode( data+readSize, transmission_info_loop_length, &descriptorList, NULL ) == FALSE ){ _OutputDebugString( L"++CSITTable:: descriptor err" ); return FALSE; } readSize+=transmission_info_loop_length; } while( readSize < (DWORD)section_length+3-4 ){ SERVICE_LOOP_DATA* item = new SERVICE_LOOP_DATA; item->service_id = ((WORD)data[readSize])<<8 | data[readSize+1]; item->running_status = (data[readSize+2]&0x70)>>4; item->service_loop_length = ((WORD)data[readSize+2]&0x0F)<<8 | data[readSize+3]; readSize += 4; if( readSize+item->service_loop_length <= (DWORD)section_length+3-4 && item->service_loop_length > 0){ CDescriptor descriptor; if( descriptor.Decode( data+readSize, item->service_loop_length, &(item->descriptorList), NULL ) == FALSE ){ _OutputDebugString( L"++CSITTable:: descriptor2 err" ); return FALSE; } } readSize+=item->service_loop_length; serviceLoopList.push_back(item); } }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; }
DWORD CCreatePMTPacket::DecodePMT(BYTE* data, DWORD dataSize) { if( data == NULL ){ return ERR_FALSE; } if( dataSize < 7 ){ return ERR_FALSE; } BYTE table_id; BYTE section_syntax_indicator; WORD section_length; WORD program_number; BYTE version_number; BYTE current_next_indicator; BYTE section_number; BYTE last_section_number; WORD PCR_PID; WORD program_info_length; DWORD crc32; 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"CCreatePMTPacket::section_syntax_indicator Err"); return ERR_FALSE; } if( table_id != 0x02 ){ //table_idがおかしい _OutputDebugString(L"CCreatePMTPacket::table_id Err"); return ERR_FALSE; } if( readSize+section_length > dataSize || section_length < 4){ //サイズ異常 _OutputDebugString(L"CCreatePMTPacket::section_length Err"); return ERR_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"CCreatePMTPacket::CRC Err"); return ERR_FALSE; } if( section_length - 4 < 9 ){ _OutputDebugString(L"CCreatePMTPacket::section_length %d Err2", section_length); return ERR_FALSE; } program_number = ((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]; PCR_PID = ((WORD)data[readSize+5]&0x1F)<<8 | data[readSize+6]; program_info_length = ((WORD)data[readSize+7]&0x0F)<<8 | data[readSize+8]; readSize += 9; if( readSize + program_info_length > (DWORD)section_length+3-4 ){ _OutputDebugString(L"CCreatePMTPacket::program_info_length %d Err", program_info_length); return ERR_FALSE; } if( this->lastPcrPID == PCR_PID && this->lastPgNumber == program_number && this->lastVersion == version_number ){ //バージョン同じなのでこれ以上必要なし return ERR_NO_CHAGE; } this->lastPcrPID = PCR_PID; this->lastPgNumber = program_number; this->lastVersion = version_number; //再解析 this->emmPIDMap.clear(); SAFE_DELETE_ARRAY(this->firstDescBuff); this->firstDescBuffSize = 0; ClearSecondBuff(); //descriptor1 //バイナリ部分コピー this->firstDescBuffSize = (WORD)readSize + program_info_length; if(this->firstDescBuffSize > 0 ){ this->firstDescBuff = new BYTE[this->firstDescBuffSize]; memcpy(this->firstDescBuff, data, this->firstDescBuffSize); } //EMMあるかだけチェック WORD infoRead = 0; while(infoRead+1 < program_info_length){ BYTE descriptor_tag = data[readSize]; BYTE descriptor_length = data[readSize+1]; readSize+=2; if( descriptor_tag == 0x09 && descriptor_length >= 4 && infoRead+2+3 < program_info_length){ //CA WORD CA_PID = ((WORD)data[readSize+2]&0x1F)<<8 | (WORD)data[readSize+3]; if (CA_PID != 0x1fff) { this->emmPIDMap.insert(pair<WORD,WORD>(CA_PID, 0)); } } readSize += descriptor_length; infoRead+= 2+descriptor_length; } //descriptor2 while( readSize+4 < (DWORD)section_length+3-4 ){ WORD ES_info_length = ((WORD)data[readSize+3]&0x0F)<<8 | data[readSize+4]; if( readSize+ES_info_length+5 > (DWORD)section_length+3-4 ){ break; } SECOND_DESC_BUFF* item = new SECOND_DESC_BUFF; item->stream_type = data[readSize]; item->elementary_PID = ((WORD)data[readSize+1]&0x1F)<<8 | data[readSize+2]; item->ES_info_length = ES_info_length; item->descBuffSize = item->ES_info_length + 5; if( item->descBuffSize > 0 ){ item->descBuff = new BYTE[item->descBuffSize]; memcpy(item->descBuff, data+readSize, item->descBuffSize); } readSize += item->descBuffSize; //descriptor infoRead = 5; while(infoRead+1 < item->descBuffSize){ BYTE descriptor_tag = item->descBuff[infoRead]; BYTE descriptor_length = item->descBuff[infoRead+1]; if( descriptor_tag == 0x09 && descriptor_length >= 4 && infoRead+5 < item->descBuffSize){ //CA WORD CA_PID = ((WORD)item->descBuff[2+infoRead+2]&0x1F)<<8 | (WORD)item->descBuff[2+infoRead+3]; if (CA_PID != 0x1fff) { this->emmPIDMap.insert(pair<WORD,WORD>(CA_PID, 0)); } }else if( descriptor_tag == 0xC0 && descriptor_length >= 3 && infoRead+4 < item->descBuffSize ){ //階層伝送記述子 item->quality = item->descBuff[2+infoRead]&0x01; item->qualityPID = ((WORD)item->descBuff[2+infoRead+1]&0x1F)<<8 | item->descBuff[2+infoRead+2]; } infoRead += 2+descriptor_length; } secondDescBuff.push_back(item); } CreatePMT(); return TRUE; }
void CCreatePMTPacket::CreatePMT() { if( firstDescBuffSize == 0 || this->firstDescBuff == NULL ){ return; } SAFE_DELETE_ARRAY(this->createPSI); this->createPSISize = 0; this->needPIDList.clear(); BOOL findVHighQ = FALSE; BOOL findAHighQ = FALSE; BOOL findMPEG2V = FALSE; BOOL findAAC = FALSE; this->createVer++; if( this->createVer > 31 ){ this->createVer = 0; } //データ一覧チェック for( size_t i=0; i<secondDescBuff.size(); i++ ){ if( secondDescBuff[i]->quality == 1 ){ //高階層あり if( secondDescBuff[i]->stream_type == 0x02 ){ findVHighQ = TRUE; }else if( secondDescBuff[i]->stream_type == 0x0F ){ findAHighQ = TRUE; } } if( secondDescBuff[i]->stream_type == 0x02 ){ findMPEG2V = TRUE; } else if( secondDescBuff[i]->stream_type == 0x0F ){ findAAC = TRUE; } } //pointer_field + FirstBuff + CRC this->createPSISize = 1+this->firstDescBuffSize+4; //+ SecondBuff DWORD secondSize = 0; for( size_t i=0; i<secondDescBuff.size(); i++ ){ switch(secondDescBuff[i]->stream_type){ case 0x02: //MPEG2 VIDEO if( findVHighQ == TRUE ){ if( secondDescBuff[i]->quality == 1 ){ secondSize+=secondDescBuff[i]->descBuffSize; } }else{ secondSize+=secondDescBuff[i]->descBuffSize; } break; case 0x0F: //MPEG2 AAC if( findAHighQ == TRUE ){ if( secondDescBuff[i]->quality == 1 ){ secondSize+=secondDescBuff[i]->descBuffSize; } }else{ secondSize+=secondDescBuff[i]->descBuffSize; } break; case 0x1B: //MPEG4 VIDEO if( findMPEG2V == FALSE ){ secondSize+=secondDescBuff[i]->descBuffSize; } break; case 0x04: //MPEG2 AUDIO if( findAAC == FALSE ){ secondSize+=secondDescBuff[i]->descBuffSize; } break; case 0x06: //字幕 if( this->needCaption == TRUE ){ secondSize+=secondDescBuff[i]->descBuffSize; } break; case 0x0D: //データカルーセル if( this->needData == TRUE ){ secondSize+=secondDescBuff[i]->descBuffSize; } break; default: break; } } this->createPSISize += secondSize; this->createPSI = new BYTE[this->createPSISize]; ZeroMemory(this->createPSI, this->createPSISize); //最初のDescriptorループまでコピー memcpy( this->createPSI + 1, this->firstDescBuff, this->firstDescBuffSize ); //SectionLength this->createPSI[2] = (BYTE)(((this->createPSISize-4)&0x00000F00)>>8); this->createPSI[2] |= 0xB0; this->createPSI[3] = (BYTE)((this->createPSISize-4)&0x000000FF); //バージョン this->createPSI[6] = this->createVer<<1; this->createPSI[6] |= 0xC1; DWORD writeSize = this->firstDescBuffSize+1; for( size_t i=0; i<secondDescBuff.size(); i++ ){ switch(secondDescBuff[i]->stream_type){ case 0x02: //MPEG2 VIDEO if( findVHighQ == TRUE ){ if( secondDescBuff[i]->quality == 1 ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } }else{ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; case 0x0F: //MPEG2 AAC if( findAHighQ == TRUE ){ if( secondDescBuff[i]->quality == 1 ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } }else{ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; case 0x1B: //MPEG4 VIDEO if( findMPEG2V == FALSE ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; case 0x04: //MPEG2 AUDIO if( findAAC == FALSE ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; case 0x06: //字幕 if( this->needCaption == TRUE ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; case 0x0D: //データカルーセル if( this->needData == TRUE ){ memcpy( this->createPSI + writeSize, secondDescBuff[i]->descBuff, secondDescBuff[i]->descBuffSize ); writeSize += secondDescBuff[i]->descBuffSize; this->needPIDList.insert(pair<WORD,WORD>(secondDescBuff[i]->elementary_PID, secondDescBuff[i]->stream_type)); } break; default: break; } } unsigned long ulCrc = _Crc32(this->createPSISize-5, this->createPSI+1); this->createPSI[this->createPSISize-4] = (BYTE)((ulCrc&0xFF000000)>>24); this->createPSI[this->createPSISize-3] = (BYTE)((ulCrc&0x00FF0000)>>16); this->createPSI[this->createPSISize-2] = (BYTE)((ulCrc&0x0000FF00)>>8); this->createPSI[this->createPSISize-1] = (BYTE)(ulCrc&0x000000FF); CreatePacket(); }
BOOL CPMTUtil::DecodePMT(BYTE* data, DWORD dataSize) { Clear(); if( data == NULL ){ return FALSE; } 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"CPMTUtil::section_syntax_indicator Err"); return FALSE; } if( table_id != 0x02 ){ //table_idがおかしい _OutputDebugString(L"CPMTUtil::table_id Err"); return FALSE; } if( readSize+section_length > dataSize || section_length < 4){ //サイズ異常 _OutputDebugString(L"CPMTUtil::section_length %d Err", section_length); 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"CPMTUtil::crc32 Err"); return FALSE; } if( section_length > 12 ){ program_number = ((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]; PCR_PID = ((WORD)data[readSize+5]&0x1F)<<8 | data[readSize+6]; program_info_length = ((WORD)data[readSize+7]&0x0F)<<8 | data[readSize+8]; readSize += 9; //descriptor WORD infoRead = 0; while(readSize+1 < (DWORD)section_length+3-4 && infoRead < program_info_length){ BYTE descriptor_tag = data[readSize]; BYTE descriptor_length = data[readSize+1]; readSize+=2; if( descriptor_tag == 0x09 && descriptor_length >= 4 && readSize+3 < (DWORD)section_length+3-4 ){ //CA WORD CA_PID = ((WORD)data[readSize+2]&0x1F)<<8 | (WORD)data[readSize+3]; if (CA_PID != 0x1fff) { PIDList.insert(pair<WORD,WORD>(CA_PID, 0)); } } readSize += descriptor_length; infoRead+= 2+descriptor_length; } while( readSize+4 < (DWORD)section_length+3-4 ){ ES_INFO_DATA* item = new ES_INFO_DATA; item->stream_type = data[readSize]; item->elementary_PID = ((WORD)data[readSize+1]&0x1F)<<8 | data[readSize+2]; item->ES_info_length = ((WORD)data[readSize+3]&0x0F)<<8 | data[readSize+4]; readSize += 5; PIDList.insert(pair<WORD,WORD>(item->elementary_PID, item->stream_type)); //descriptor infoRead = 0; while(readSize+1 < (DWORD)section_length+3-4 && infoRead < item->ES_info_length){ BYTE descriptor_tag = data[readSize]; BYTE descriptor_length = data[readSize+1]; readSize+=2; if( descriptor_tag == 0x09 && descriptor_length >= 4 && readSize+3 < (DWORD)section_length+3-4 ){ //CA WORD CA_PID = ((WORD)data[readSize+2]&0x1F)<<8 | (WORD)data[readSize+3]; if (CA_PID != 0x1fff) { PIDList.insert(pair<WORD,WORD>(CA_PID, 0)); } } readSize += descriptor_length; infoRead+= 2+descriptor_length; } // readSize+=item->ES_info_length; ESInfoList.push_back(item); } }
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 CNITTable::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"++CNITTable:: section_syntax err" ); return FALSE; } if( table_id != 0x40 && table_id != 0x41 ){ //table_idがおかしい _OutputDebugString( L"++CNITTable:: table_id err 0x%02X", table_id ); return FALSE; } if( readSize+section_length > dataSize && section_length > 3){ //サイズ異常 _OutputDebugString( L"++CNITTable:: 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"++CNITTable:: CRC err" ); return FALSE; } if( section_length > 8 ){ network_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]; network_descriptors_length = ((WORD)data[readSize+5]&0x0F)<<8 | data[readSize+6]; readSize += 7; if( readSize+network_descriptors_length <= (DWORD)section_length+3-4 && network_descriptors_length > 0){ if( network_id == 0x0001 || network_id == 0x0003 ){ SDDecode( data+readSize, network_descriptors_length, &descriptorList, NULL ); }else{ CDescriptor descriptor; if( descriptor.Decode( data+readSize, network_descriptors_length, &descriptorList, NULL ) == FALSE ){ _OutputDebugString( L"++CNITTable:: descriptor err" ); return FALSE; } } readSize+=network_descriptors_length; } transport_stream_loop_length = ((WORD)data[readSize]&0x0F)<<8 | data[readSize+1]; readSize += 2; WORD tsLoopReadSize = 0; while( readSize < (DWORD)section_length+3-4 && tsLoopReadSize < transport_stream_loop_length){ TS_INFO_DATA* item = new TS_INFO_DATA; item->transport_stream_id = ((WORD)data[readSize])<<8 | data[readSize+1]; item->original_network_id = ((WORD)data[readSize+2])<<8 | data[readSize+3]; item->transport_descriptors_length = ((WORD)data[readSize+4]&0x0F)<<8 | data[readSize+5]; readSize += 6; if( readSize+item->transport_descriptors_length <= (DWORD)section_length+3-4 && item->transport_descriptors_length > 0){ CDescriptor descriptor; if( descriptor.Decode( data+readSize, item->transport_descriptors_length, &(item->descriptorList), NULL ) == FALSE ){ _OutputDebugString( L"++CNITTable:: descriptor2 err" ); return FALSE; } } readSize+=item->transport_descriptors_length; tsLoopReadSize += 6 + item->transport_descriptors_length; TSInfoList.push_back(item); } }else{
BOOL CPATTable::Decode( BYTE* data, DWORD dataSize, DWORD* decodeReadSize ) { if( data == NULL ){ return FALSE; } pmtMap.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 || (data[1]&0x40) != 0 ){ //固定値がおかしい _OutputDebugString( L"++CPATTable:: section_syntax err" ); return FALSE; } if( table_id != 0x00 ){ //table_idがおかしい _OutputDebugString( L"++CPATTable:: table_id err 0x00 != 0x%02X", table_id ); return FALSE; } if( readSize+section_length > dataSize && section_length > 3){ //サイズ異常 _OutputDebugString( L"++CPATTable:: 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"++CPATTable:: CRC err" ); return FALSE; } if( section_length > 4 ){ transport_stream_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]; readSize += 5; while( readSize < (DWORD)section_length+3-4 ){ PMT_DATA item; item.program_number = ((WORD)data[readSize])<<8 | data[readSize+1]; item.PID = ((WORD)data[readSize+2]&0x1F)<<8 | data[readSize+3]; pmtMap.insert(pair<WORD, PMT_DATA>(item.program_number, item)); readSize+=4; } }else{