From: cocot Date: Sun, 22 Feb 2009 05:09:48 +0000 (+0900) Subject: implement class TsPacket in Utils X-Git-Url: http://git.osdn.net/view?p=tsremuxcpp%2Fdeveloping01.git;a=commitdiff_plain;h=a49c4ec162a062651c5799cdcc77b075c6fa7e97 implement class TsPacket in Utils --- diff --git a/src/Utils.cc b/src/Utils.cc index 971e0dc..46d80e0 100644 --- a/src/Utils.cc +++ b/src/Utils.cc @@ -153,7 +153,7 @@ namespace TsRemux StreamInfo::StreamInfo(byte* data, int index)throw(std::invalid_argument) { if (NULL == data) { - throw std::invalid_argument("stream data is null"); + throw std::invalid_argument("stream data is NULL"); } if (std::strlen(data) + index < 5) { @@ -175,11 +175,11 @@ StreamInfo::StreamInfo(byte* data, int index)throw(std::invalid_argument) mData[i] = data[i + index]; } - mVideoFormat = SetVideoFormat(VideoFormat::VF_Reserved); - mAspectRatio = SetAspectRatio(AR_Reserved); - mFrameRate = SetFrameRate(FR_Reserved); - mAudioPresentationType = SetAudioPresentationType(AP_Reserved); - mSamplingFrequency = SetSamplingFrequency(SF_Reserved); + SetVideoFormat(VF_Reserved); + SetAspectRatio(AR_Reserved); + SetFrameRate(FR_Reserved); + SetAudioPresentationType(AP_Reserved); + SetSamplingFrequency(SF_Reserved); } VideoFormat StreamInfo::GetVideoFormat(void) @@ -207,7 +207,7 @@ FrameRate StreamInfo::GetFrameRate(void) return mFrameRate; } -void StreamInfo::FrameRate(FrameRate frame_rate) +void StreamInfo::SetFrameRate(FrameRate frame_rate) { mFrameRate = frame_rate; } @@ -227,7 +227,7 @@ SamplingFrequency StreamInfo::GetSamplingFrequency(void) return mSamplingFrequency; } -StreamInfo::SetSamplingFrequency(SamplingFrequency sampling_frequency) +void StreamInfo::SetSamplingFrequency(SamplingFrequency sampling_frequency) { mSamplingFrequency = sampling_frequency; } @@ -247,12 +247,12 @@ byte* StreamInfo::GetByteData(void) return mData; } -StreamType StreamInfo::GetElementaryStreamTypes(void) +ElementaryStreamTypes StreamInfo::GetElementaryStreamTypes(void) { return (ElementaryStreamTypes)mData[0]; } -void StreamInfo::SetElementaryStreamTypes(StreamType stream_type) +void StreamInfo::SetElementaryStreamTypes(ElementaryStreamTypes stream_type) { mData[0] = (byte)stream_type; } @@ -269,8 +269,8 @@ void StreamInfo::GetElementaryPID(ushort pid) byte* StreamInfo::GetElementaryDescriptors(void) { - if (std::strlen(mData) == 5) return null; - byte* descriptors = new byte[mData.Length - 5]; + if (std::strlen(mData) == 5) return NULL; + byte* descriptors = new byte[std::strlen(mData) - 5]; for (int i = 0; i < sizeof(descriptors); i++) { descriptors[i] = mData[i + 5]; @@ -279,13 +279,14 @@ byte* StreamInfo::GetElementaryDescriptors(void) } void StreamInfo::SetElementaryDescriptors(byte* value) + throw(std::invalid_argument) { - if(null == value || 0 == sizeof(value)) + if(NULL == value || 0 == sizeof(value)) { - if(mData.Length > 5) + if(std::strlen(mData) > 5) { // need to remove existing descriptors - byte[] data = new byte[5]; + byte* data = new byte[5]; data[0] = mData[0]; data[1] = mData[1]; data[2] = mData[2]; @@ -301,17 +302,17 @@ void StreamInfo::SetElementaryDescriptors(byte* value) } else { - if(sizeof(value) > 180) { - throw new ArgumentException("descriptors data too long"); + if(std::strlen(value) > 180) { + throw std::invalid_argument("descriptors data too long"); } - byte* data = new byte[5 + value.Length]; + byte* data = new byte[5 + std::strlen(value)]; data[0] = mData[0]; data[1] = mData[1]; data[2] = mData[2]; - data[3] = (byte)(0xf0 | (byte)((value.Length >> 8) & 0x0f)); - data[4] = (byte)(value.Length & 0xff); - for (int i = 0; i < value.Length; i++) + data[3] = (byte)(0xf0 | (byte)((std::strlen(value) >> 8) & 0x0f)); + data[4] = (byte)(std::strlen(value) & 0xff); + for (int i = 0; i < std::strlen(value); i++) { data[5 + i] = value[i]; } @@ -319,8 +320,180 @@ void StreamInfo::SetElementaryDescriptors(byte* value) } } +ElementaryParse::ElementaryParse(void) +{ + indicator = 0; +} + +byte ElementaryParse::GetNextBit(void) +{ + byte ret = (byte)(((mData[indicator / 8]) >> (7 - (indicator % 8))) & 1); + indicator++; + return ret; +} + +TsPacket::TsPacket(void) +{ + // initialize the packet as a NULL packet + mData = new byte[Constants::TS_SIZE]; + mData[0] = Constants::SYNC_BYTE; // sync byte + mData[1] = 0x1f; // PID = 0x1FFF + mData[2] = 0xff; // PID == 0x1FFF + mData[3] = 0x10; // no adaptation field + for (int i = 4; i < Constants::TS_SIZE; i++) { + mData[i] = 0xff; + } +} + +bool TsPacket::GetPriority(void) +{ + if ((mData[1] & 0x20) > 0) + return true; + else + return false; +} +void TsPacket::SetPriority(bool priority) +{ + if (priority) + mData[1] |= 0x20; + else + mData[1] &= 0xdf; +} +ushort TsPacket::GetPID(void) +{ + return (ushort)(((mData[1] & 0x1f) << 8) + mData[2]); +} +void TsPacket::SetPID(ushort pid) +{ + byte b = (byte)(mData[1] & 0xE0); + b += (byte)((pid >> 8) & 0x1f); + mData[1] = b; + mData[2] = (byte)(pid & 0xff); +} + +byte TsPacket::GetPointerSize(void) +{ + if ((mData[3] & 0x20) == 0) // No adaptation field present + return mData[4]; + return (byte)(mData[4] + 1 + mData[mData[4] + 5]); +} + +byte* TsPacket::GetData(void) +{ + return mData; +} + +void TsPacket::SetData(byte* data, int startIndex)throw(std::invalid_argument) +{ + if (NULL == data) + throw std::invalid_argument("NULL packet"); + else if (Constants::TS_SIZE > std::strlen(data) - startIndex) + throw std::invalid_argument("small packet"); + else if (Constants::SYNC_BYTE != data[0 + startIndex]) + throw std::invalid_argument("sync byte missing"); + for (int i = 0; i < Constants::TS_SIZE; i++) { + mData[i] = data[i + startIndex]; + } +} +bool TsPacket::HasPcr(void) +{ + if ((mData[3] & 0x20) > 0 // Adaptation field present + && (mData[4] > 0) // length > 0 + && (mData[5] & 0x10) > 0) // and a PCR + return true; + return false; +} +Int64 TsPacket::GetPcr(void)throw(std::out_of_range) +{ + if (false == this->HasPcr()) + throw std::out_of_range("PCR not present in this packet"); + Int64 mpeg2tsClock = mData[6]; + mpeg2tsClock <<= 25; + mpeg2tsClock += (mData[7] << 17); + mpeg2tsClock += (mData[8] << 9); + mpeg2tsClock += (mData[9] << 1); + mpeg2tsClock += ((mData[10] & 0x80) >> 7); + mpeg2tsClock *= 300; + mpeg2tsClock += ((mData[10] & 0x1) << 8); + mpeg2tsClock += (mData[11]); + return mpeg2tsClock; +} + +bool TsPacket::HasPesHeader(void) +{ + if ((mData[1] & 0x40) == 0) + return false; + int offset = 4; + if ((mData[3] & 0x20) > 0) + { + // adaptation field present + offset += (1 + mData[4]); + if (offset >= Constants::TS_SIZE) + return false; + } + if ((mData[3] & 0x10) > 0) + { + // payload present + int len = Constants::TS_SIZE - offset; + if (len < 10) + return false; + + if(mData[offset] == 0 + && mData[offset + 1] == 0 + && mData[offset + 2] == 1 + && len >= 9 + mData[offset + 8]) + return true; + else if(mData[offset] == 0 + && mData[offset + 1] == 0 + && mData[offset + 2] == 1) + return false; + } + return false; +} + +byte* TsPacket::Payload(void) +{ + int offset = 4; + if ((mData[3] & 0x20) > 0) + { + // adaptation field present + offset += (1 + mData[4]); + if (offset >= Constants::TS_SIZE) + return NULL; + } + if ((mData[3] & 0x10) > 0) + { + // payload present + byte* ret = new byte[Constants::TS_SIZE - offset]; + for (int i = 0; i < sizeof(ret); i++) + ret[i] = mData[i + offset]; + return ret; + } + return NULL; +} + +void TsPacket::IncrementContinuityCounter(void) +{ + if (0xf == (mData[3] & 0xf)) + mData[3] &= 0xf0; + else + mData[3]++; +} + +byte TsPacket::GetContinuityCounter(void) +{ + return (byte)(mData[3] & 0xf); +} + +void TsPacket::SetContinuityCounter(byte value)throw(std::out_of_range) +{ + if (value > 0x0f) + throw std::out_of_range("Invalid continuity counter"); + mData[3] &= 0xf0; + mData[3] |= value; +} diff --git a/src/Utils.h b/src/Utils.h index edc1b24..4d7eb41 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -103,7 +103,7 @@ struct EpElement { class StreamInfo { public: StreamInfo(byte* data, int index)throw(std::invalid_argument); - VideoFormat GetVideoFormati(void); + VideoFormat GetVideoFormat(void); void SetVideoFormat(VideoFormat videoformat); AspectRatio GetAspectRatio(void); void SetAspectRatio(AspectRatio aspectratio); @@ -111,11 +111,16 @@ class StreamInfo { void SetFrameRate(FrameRate frameRate); AudioPresentationType GetAudioPresentationType(void); void SetAudioPresentationType(AudioPresentationType audioPresentationTyp); - SamplingFrequency GetsamplingFrequency(void); + SamplingFrequency GetSamplingFrequency(void); void SetSamplingFrequency(SamplingFrequency samplingFrequency); StreamInfo(ElementaryStreamTypes streamType, ushort elementaryPid); byte* GetByteData(void); - byte* ElementaryDescriptors; + ElementaryStreamTypes GetElementaryStreamTypes(void); + void SetElementaryStreamTypes(ElementaryStreamTypes stream_type); + ushort GetElementaryPID(void); + void GetElementaryPID(ushort pid); + byte* GetElementaryDescriptors(void); + void SetElementaryDescriptors(byte* value)throw(std::invalid_argument); private: byte* mData; VideoFormat mVideoFormat; @@ -125,6 +130,7 @@ class StreamInfo { SamplingFrequency mSamplingFrequency; ElementaryStreamTypes StreamType; ushort ElementaryPID; + byte* ElementaryDescriptors; }; class BluRayOutput { @@ -267,11 +273,25 @@ class ProgramInfo { class TsPacket { public: TsPacket(void); - bool Priority; - ushort PID; - bool HasPesHeader; + bool GetPriority(void); + void SetPriority(bool priority); + ushort GetPID(void); + void SetPID(ushort pid); + byte GetPointerSize(void); + byte* GetData(void); + void SetData(byte* data, int startIndex)throw(std::invalid_argument); + bool HasPcr(void); + Int64 GetPcr(void)throw(std::out_of_range); + byte* Payload(void); + void IncrementContinuityCounter(void); + byte GetContinuityCounter(void); + void SetContinuityCounter(byte value)throw(std::out_of_range); + bool HasPesHeader(void); protected: byte* mData; + private: + bool Priority; + ushort PID; }; class PcrPacket : TsPacket {