public override void ProcessTsPacket(TsPacketMetadata tsPacketMetadata, byte[] packetBuffer, Int64 packetOffsetInBuffer) { Result result = new Result(); //Int64 dataLeftInBit = (Int64)tsPacketMetadata.PacketSize; Int64 dataLeftInBit = (Int64)TsPacketSize.SIZE_188 * 8; //Important!!!!No matter 188 or 204 bytes, the valid data will always be 188 bytes.16 bytes are checksum that is not useful for parsing. Int64 bitOffset = packetOffsetInBuffer * 8; //Key point to set the beginning offset!!!!! if (result.Fine) { //8-bit sync_byte. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 8); } if (result.Fine) { //1-bit transport_error_indicator. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 1); } Int64 payloadUnitStartIndicator = 0; if (result.Fine) { //1-bit payload_unit_start_indicator. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 1, ref payloadUnitStartIndicator); //GetContext().WriteLog(Utility.GetValueBinaryString(fieldValue, 1) + Environment.NewLine); } if (result.Fine) { //1-bit transport_priority. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 1); } Int64 pid = 0; if (result.Fine) { //13-bit PID. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 13, ref pid); //GetContext().WriteLog(Utility.GetValueBinaryString(fieldValue, 13) + Environment.NewLine); } //To update the PID according to the request. if (result.Fine) { PidUpdate pidUpdate = null; //If this pid needs update. if (pidUpdateList.TryGetValue((UInt16)pid, out pidUpdate)) { //To update the PID. packetBuffer[packetOffsetInBuffer + 1] = (byte)((packetBuffer[packetOffsetInBuffer + 1] & (byte)0xE0) | (pidUpdate.NewPid >> 8)); //To update the high 5 bits of PID. packetBuffer[packetOffsetInBuffer + 2] = (byte)(pidUpdate.NewPid & 0xFF); //To update the low 8 bits of PID. //Write to output file now. outputFileStream.Write(packetBuffer, (int)packetOffsetInBuffer, (int)tsPacketMetadata.PacketSize); } else { //Write the original packet directly. outputFileStream.Write(packetBuffer, (int)packetOffsetInBuffer, (int)tsPacketMetadata.PacketSize); } } }
public override void ProcessTsPacket(TsPacketMetadata tsPacketMetadata, byte[] packetBuffer, Int64 packetOffsetInBuffer) { Result result = new Result(); //Int64 dataLeftInBit = (Int64)tsPacketMetadata.PacketSize; Int64 dataLeftInBit = (Int64)TsPacketSize.SIZE_188 * 8; //Important!!!!No matter 188 or 204 bytes, the valid data will always be 188 bytes.16 bytes are checksum that is not useful for parsing. Int64 bitOffset = packetOffsetInBuffer * 8; //Key point to set the beginning offset!!!!! if (result.Fine) { //8-bit sync_byte. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 8); } if (result.Fine) { //1-bit transport_error_indicator. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 1); } Int64 payloadUnitStartIndicator = 0; if (result.Fine) { //1-bit payload_unit_start_indicator. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 1, ref payloadUnitStartIndicator); //GetContext().WriteLog(Utility.GetValueBinaryString(fieldValue, 1) + Environment.NewLine); } if (result.Fine) { //1-bit transport_priority. result = Utility.ByteArraySkipBits(ref dataLeftInBit, ref bitOffset, 1); } Int64 pid = 0; if (result.Fine) { //13-bit PID. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 13, ref pid); //GetContext().WriteLog(Utility.GetValueBinaryString(fieldValue, 13) + Environment.NewLine); } Int64 scrambled = 0; if (result.Fine) { //1-bit scrambling indicator. If 1, scrambled, else clear. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 1, ref scrambled); } Int64 evenOdd = 0; if (result.Fine) { //1-bit even/odd indicator. result = Utility.ByteArrayReadBits(packetBuffer, ref dataLeftInBit, ref bitOffset, 1, ref evenOdd); } if ((totalLengthOfDataParsed - previousTotalLengthOfDataParsed) * 8 >= (muxBitrate * cwPeriod))//Need to do a CW cycle. { //To switch the CW. //Get the control word. int realControlWordId = currentControlWord; currentControlWord++; //Increase so that we can pick up next control word. realControlWordId = realControlWordId % controlWordCount; //We like to loop back if necessary. byte[] csaKey = new byte[8]; Array.Copy(controlWordSerials, realControlWordId * 8, csaKey, 0, 8);//Copy the key into a new buffer. //Set the CW. csaDescrambler.SetCW(csaKey, doEntropy); //Switch even/odd flag. evenOddFlag = (evenOddFlag + 1) % 2; //Save the new value as the previous one. previousTotalLengthOfDataParsed = totalLengthOfDataParsed; } //To process the PID according to the request. if (result.Fine) { PidUpdate pidToProcess = null; //If this pid needs to be extracted. if (pidUpdateList.TryGetValue((UInt16)pid, out pidToProcess)) { //Scramble the packet in place. csaDescrambler.EncryptTSPacket(packetBuffer, (int)packetOffsetInBuffer, (int)TsPacketSize.SIZE_188, evenOddFlag); } //Write the output no matter clear or descrambled. outputFileStream.Write(packetBuffer, (int)packetOffsetInBuffer, (int)tsPacketMetadata.PacketSize); } }