mirror of https://bitbucket.org/ausocean/av.git
stream/mts/psi/psi.go: added function comments and improved commenting and layout inside functions
This commit is contained in:
parent
d49a8b8c6b
commit
55bee1532e
|
@ -239,6 +239,11 @@ func asByte(b bool) byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDescriptor adds or updates a descriptor in a PSI given a descriptor tag
|
||||||
|
// and data. If the psi is not a pmt, then an error is returned. If a descriptor
|
||||||
|
// with the given tag is not found in the psi, room is made and a descriptor with
|
||||||
|
// given tag and data is created. If a descriptor with the tag is found, the
|
||||||
|
// descriptor is resized as required and the new data is copied in.
|
||||||
func (p *PSIBytes) AddDescriptor(tag int, data []byte) error {
|
func (p *PSIBytes) AddDescriptor(tag int, data []byte) error {
|
||||||
if psi.TableID(*p) != pmtID {
|
if psi.TableID(*p) != pmtID {
|
||||||
return errors.New("trying to add descriptor, but not pmt")
|
return errors.New("trying to add descriptor, but not pmt")
|
||||||
|
@ -250,27 +255,26 @@ func (p *PSIBytes) AddDescriptor(tag int, data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Old lengths
|
|
||||||
oldDescLen := desc.len()
|
oldDescLen := desc.len()
|
||||||
oldDataLen := int(desc[1])
|
oldDataLen := int(desc[1])
|
||||||
|
|
||||||
// New lengths
|
|
||||||
newDataLen := len(data)
|
newDataLen := len(data)
|
||||||
newDescLen := 2 + newDataLen
|
newDescLen := 2 + newDataLen
|
||||||
|
|
||||||
delta := newDescLen - oldDescLen
|
delta := newDescLen - oldDescLen
|
||||||
|
|
||||||
if oldDataLen > newDataLen {
|
// If the old data length is more than the new data length, we need shift data
|
||||||
|
// after descriptor up, and then trim the psi. If the oldDataLen is less than
|
||||||
|
// new data then we need reseize psi and shift data down. If data is same size
|
||||||
|
// just copy new data in.
|
||||||
|
switch {
|
||||||
|
case oldDataLen > newDataLen:
|
||||||
copy((*p)[i+newDescLen:], (*p)[i+oldDescLen:])
|
copy((*p)[i+newDescLen:], (*p)[i+oldDescLen:])
|
||||||
*p = (*p)[:len(*p)+delta]
|
*p = (*p)[:len(*p)+delta]
|
||||||
|
case oldDataLen < newDataLen:
|
||||||
} else if oldDataLen < newDataLen {
|
|
||||||
tmp := make([]byte, len(*p)+delta)
|
tmp := make([]byte, len(*p)+delta)
|
||||||
copy(tmp, *p)
|
copy(tmp, *p)
|
||||||
*p = tmp
|
*p = tmp
|
||||||
copy((*p)[i+newDescLen:], (*p)[i+oldDescLen:])
|
copy((*p)[i+newDescLen:], (*p)[i+oldDescLen:])
|
||||||
|
default:
|
||||||
} else {
|
|
||||||
copy((*p)[i+2:], data)
|
copy((*p)[i+2:], data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,20 +282,27 @@ func (p *PSIBytes) AddDescriptor(tag int, data []byte) error {
|
||||||
p.setProgInfoLen(newProgInfoLen)
|
p.setProgInfoLen(newProgInfoLen)
|
||||||
newSectionLen := int(psi.SectionLength(*p)) + delta
|
newSectionLen := int(psi.SectionLength(*p)) + delta
|
||||||
p.setSectionLen(newSectionLen)
|
p.setSectionLen(newSectionLen)
|
||||||
|
|
||||||
updateCrc((*p)[1:])
|
updateCrc((*p)[1:])
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// len returns the length of a descriptor in bytes.
|
||||||
func (d *Descriptor) len() int {
|
func (d *Descriptor) len() int {
|
||||||
return int(2 + (*d)[1])
|
return int(2 + (*d)[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProgramInfoLen returns the program info length of a PSI.
|
||||||
|
//
|
||||||
|
// TODO: check if pmt - if not return 0 ? or -1 ?
|
||||||
func (p *PSIBytes) ProgramInfoLen() int {
|
func (p *PSIBytes) ProgramInfoLen() int {
|
||||||
return int((((*p)[ProgramInfoLenIdx1] & ProgramInfoLenMask1) << 8) | (*p)[ProgramInfoLenIdx2])
|
return int((((*p)[ProgramInfoLenIdx1] & ProgramInfoLenMask1) << 8) | (*p)[ProgramInfoLenIdx2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasDescriptor checks if a descriptor of the given tag exists in a PSI. If the descriptor
|
||||||
|
// of the given tag exists, an index of this descriptor, as well as the Descriptor is returned.
|
||||||
|
// If the descriptor of the given tag cannot be found, -1 and a nil slice is returned.
|
||||||
|
//
|
||||||
|
// TODO: check if pmt, return error if not ?
|
||||||
func (p *PSIBytes) HasDescriptor(tag int) (int, Descriptor) {
|
func (p *PSIBytes) HasDescriptor(tag int) (int, Descriptor) {
|
||||||
descs := p.descriptors()
|
descs := p.descriptors()
|
||||||
if descs == nil {
|
if descs == nil {
|
||||||
|
@ -305,20 +316,21 @@ func (p *PSIBytes) HasDescriptor(tag int) (int, Descriptor) {
|
||||||
return -1, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// descriptors returns the descriptors in a psi if they exist, otherwise
|
||||||
|
// a nil slice is returned.
|
||||||
func (p *PSIBytes) descriptors() []byte {
|
func (p *PSIBytes) descriptors() []byte {
|
||||||
return (*p)[DescriptorsIdx : DescriptorsIdx+p.ProgramInfoLen()]
|
return (*p)[DescriptorsIdx : DescriptorsIdx+p.ProgramInfoLen()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createDescriptor creates a descriptor in a psi given a tag and data.
|
||||||
func (p *PSIBytes) createDescriptor(tag int, data []byte) {
|
func (p *PSIBytes) createDescriptor(tag int, data []byte) {
|
||||||
curProgLen := p.ProgramInfoLen()
|
curProgLen := p.ProgramInfoLen()
|
||||||
oldSyntaxSectionLen := SyntaxSecLenFrom(*p)
|
oldSyntaxSectionLen := SyntaxSecLenFrom(*p)
|
||||||
dataLen := len(data)
|
dataLen := len(data)
|
||||||
|
|
||||||
// Calculate the new descriptors index and length.
|
|
||||||
newDescIdx := DescriptorsIdx + curProgLen
|
newDescIdx := DescriptorsIdx + curProgLen
|
||||||
newDescLen := dataLen + 2
|
newDescLen := dataLen + 2
|
||||||
|
|
||||||
// Copy data down from newDescIdx to create room for the new descriptor.
|
// Increase size of psi and copy data down to make room for new descriptor.
|
||||||
tmp := make([]byte, len(*p)+newDescLen)
|
tmp := make([]byte, len(*p)+newDescLen)
|
||||||
copy(tmp, *p)
|
copy(tmp, *p)
|
||||||
*p = tmp
|
*p = tmp
|
||||||
|
@ -329,25 +341,23 @@ func (p *PSIBytes) createDescriptor(tag int, data []byte) {
|
||||||
(*p)[newDescIdx+1] = byte(dataLen)
|
(*p)[newDescIdx+1] = byte(dataLen)
|
||||||
copy((*p)[newDescIdx+2:newDescIdx+2+dataLen], data)
|
copy((*p)[newDescIdx+2:newDescIdx+2+dataLen], data)
|
||||||
|
|
||||||
// Update the program info length to account for the new descriptor.
|
// Set length fields and update the psi crc.
|
||||||
addedLen := dataLen + 2
|
addedLen := dataLen + 2
|
||||||
newProgInfoLen := curProgLen + addedLen
|
newProgInfoLen := curProgLen + addedLen
|
||||||
p.setProgInfoLen(newProgInfoLen)
|
p.setProgInfoLen(newProgInfoLen)
|
||||||
|
|
||||||
// set section length
|
|
||||||
newSyntaxSectionLen := int(oldSyntaxSectionLen) + addedLen
|
newSyntaxSectionLen := int(oldSyntaxSectionLen) + addedLen
|
||||||
p.setSectionLen(newSyntaxSectionLen)
|
p.setSectionLen(newSyntaxSectionLen)
|
||||||
|
|
||||||
updateCrc((*p)[1:])
|
updateCrc((*p)[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setProgInfoLen sets the program information length in a psi with a pmt.
|
||||||
func (p *PSIBytes) setProgInfoLen(l int) {
|
func (p *PSIBytes) setProgInfoLen(l int) {
|
||||||
// TODO: check if pmt first
|
|
||||||
(*p)[ProgramInfoLenIdx1] &= 0xff ^ ProgramInfoLenMask1
|
(*p)[ProgramInfoLenIdx1] &= 0xff ^ ProgramInfoLenMask1
|
||||||
(*p)[ProgramInfoLenIdx1] |= byte(l>>8) & ProgramInfoLenMask1
|
(*p)[ProgramInfoLenIdx1] |= byte(l>>8) & ProgramInfoLenMask1
|
||||||
(*p)[ProgramInfoLenIdx2] = byte(l)
|
(*p)[ProgramInfoLenIdx2] = byte(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSectionLen sets section length in a psi.
|
||||||
func (p *PSIBytes) setSectionLen(l int) {
|
func (p *PSIBytes) setSectionLen(l int) {
|
||||||
(*p)[SyntaxSecLenIdx1] &= 0xff ^ SyntaxSecLenMask1
|
(*p)[SyntaxSecLenIdx1] &= 0xff ^ SyntaxSecLenMask1
|
||||||
(*p)[SyntaxSecLenIdx1] |= byte(l>>8) & SyntaxSecLenMask1
|
(*p)[SyntaxSecLenIdx1] |= byte(l>>8) & SyntaxSecLenMask1
|
||||||
|
|
Loading…
Reference in New Issue