diff --git a/stream/mts/psi/crc.go b/stream/mts/psi/crc.go index a361307d..cd9a1199 100644 --- a/stream/mts/psi/crc.go +++ b/stream/mts/psi/crc.go @@ -37,13 +37,13 @@ import ( func addCrc(out []byte) []byte { t := make([]byte, len(out)+4) copy(t, out) - updateCrc(t) + updateCrc(t[1:]) return t } // updateCrc updates the crc of bytes slice, writing the checksum into the last four bytes. func updateCrc(b []byte) { - crc32 := crc32_Update(0xffffffff, crc32_MakeTable(bits.Reverse32(crc32.IEEE)), b[1:len(b)-4]) + crc32 := crc32_Update(0xffffffff, crc32_MakeTable(bits.Reverse32(crc32.IEEE)), b[:len(b)-4]) binary.BigEndian.PutUint32(b[len(b)-4:], crc32) } diff --git a/stream/mts/psi/helpers.go b/stream/mts/psi/helpers.go index 82d7ce72..174b289b 100644 --- a/stream/mts/psi/helpers.go +++ b/stream/mts/psi/helpers.go @@ -64,15 +64,14 @@ func UpdateTime(dst []byte, t uint64) error { for i := range dst[TimeDataIndx : TimeDataIndx+TimeDataSize] { dst[i+TimeDataIndx] = ts[i] } - updateCrc(dst) + updateCrc(dst[1:]) return nil } // SyntaxSecLenFrom takes a byte slice representation of a psi and extracts // it's syntax section length -func SyntaxSecLenFrom(p []byte) (l uint8) { - l = uint8(p[syntaxSecLenIndx]) - crcSize - return +func SyntaxSecLenFrom(p []byte) int { + return int(((p[SyntaxSecLenIdx1] & SyntaxSecLenMask1) << 8) | p[SyntaxSecLenIdx2]) } // TimeFrom takes a byte slice representation of a psi-pmt and extracts it's @@ -112,7 +111,7 @@ func UpdateLocation(d []byte, s string) error { for i := range loc { loc[i] = 0 } - updateCrc(d) + updateCrc(d[1:]) return nil } diff --git a/stream/mts/psi/psi.go b/stream/mts/psi/psi.go index c2e30f9e..6a4a9103 100644 --- a/stream/mts/psi/psi.go +++ b/stream/mts/psi/psi.go @@ -70,8 +70,10 @@ const ( // Other misc consts const ( - syntaxSecLenIndx = 3 - crcSize = 4 + SyntaxSecLenIdx1 = 2 + SyntaxSecLenIdx2 = 3 + SyntaxSecLenMask1 = 0x03 + crcSize = 4 ) const ( @@ -275,24 +277,40 @@ func (p *PSIBytes) descriptors() []byte { func (p *PSIBytes) createDescriptor(tag int, data []byte) { curProgLen := p.ProgramInfoLen() + oldSyntaxSectionLen := SyntaxSecLenFrom(*p) dataLen := len(data) // Calculate the new descriptors index and length. newDescIdx := DescriptorsIdx + curProgLen newDescLen := dataLen + 2 - // Copy data down from newDescIdx to create room for the new descriptor. - copy((*p)[newDescIdx+newDescLen:], (*p)[newDescIdx:dataLen-newDescLen]) - + copy((*p)[newDescIdx+newDescLen:], (*p)[newDescIdx:newDescIdx+newDescLen]) // Set the tag, data len and data of the new desriptor. (*p)[newDescIdx] = byte(tag) (*p)[newDescIdx+1] = byte(dataLen) copy((*p)[newDescIdx+2:newDescIdx+2+dataLen], data) // Update the program info length to account for the new descriptor. - newProgInfoLen := curProgLen + dataLen - (*p)[ProgramInfoLenIdx1] = byte(newProgInfoLen >> 8) + // TODO: put this in function set program info length + addedLen := dataLen + 2 + newProgInfoLen := curProgLen + addedLen + (*p)[ProgramInfoLenIdx1] &= 0xff ^ ProgramInfoLenMask1 + (*p)[ProgramInfoLenIdx1] |= byte(newProgInfoLen>>8) & ProgramInfoLenMask1 (*p)[ProgramInfoLenIdx2] = byte(newProgInfoLen) + + // set section length + // TODO: put this in func set program info length + newSyntaxSectionLen := int(oldSyntaxSectionLen) + addedLen + (*p)[SyntaxSecLenIdx1] &= 0xff ^ SyntaxSecLenMask1 + (*p)[SyntaxSecLenIdx1] |= byte(newSyntaxSectionLen>>8) & SyntaxSecLenMask1 + (*p)[SyntaxSecLenIdx2] = byte(newSyntaxSectionLen) +} + +func (p *PSIBytes) trimPadding() []byte { + sectionLength := SyntaxSecLenFrom(*p) + paddingIdx := (4 + sectionLength) + o := (*p)[:paddingIdx] + return o } func (d *Descriptor) update(data []byte) {