github.com/puellanivis/breton@v0.2.16/lib/mpeg/ts/psi/utils.go (about) 1 package psi 2 3 import ( 4 "github.com/pkg/errors" 5 ) 6 7 // CommonMarshal takes care of the common elements of encoding a PSI table. 8 func CommonMarshal(id uint8, private bool, syn *SectionSyntax, data []byte) ([]byte, error) { 9 // len(common_header) + len(data) + len(crc) 10 l := 4 + len(data) + 4 11 12 var sb []byte 13 if syn != nil { 14 var err error 15 16 sb, err = syn.Marshal() 17 if err != nil { 18 return nil, err 19 } 20 21 l += len(sb) 22 } 23 24 b := make([]byte, l) 25 26 b[1] = id 27 if private { 28 b[2] |= flagPrivate 29 } 30 31 start := 4 32 secLen := l - start 33 if secLen > 1021 { 34 return nil, errors.New("section_length may not exceed 1021") 35 } 36 b[2] |= byte((secLen>>8)&0x0F) | 0x30 37 b[3] = byte(secLen & 0xFF) 38 39 if syn != nil { 40 b[2] |= flagSectionSyntax 41 42 copy(b[start:], sb) 43 start += len(sb) 44 } 45 46 // copy in the SectionSyntax 47 copy(b[start:], data) 48 49 // TODO(puellanivis): calculate CRC32 50 copy(b[l-4:], []byte{0xde, 0xad, 0xbe, 0xef}) 51 52 return b, nil 53 } 54 55 // CommonUnmarshal takes care of the common elements of decoding a PSI table. 56 func CommonUnmarshal(b []byte) (syn *SectionSyntax, data []byte, crc uint32, err error) { 57 secLen := int(b[1]&0x0F)<<8 | int(b[2]) 58 if secLen > 1021 { 59 return nil, nil, 0, errors.New("section_length may not exceed 1021") 60 } 61 62 start := 3 63 64 if b[1]&flagSectionSyntax != 0 { 65 syn = new(SectionSyntax) 66 67 if err := syn.Unmarshal(b[3:]); err != nil { 68 return nil, nil, 0, err 69 } 70 71 start += 5 72 secLen -= 5 73 } 74 75 end := start + secLen - 4 76 if start >= len(b) { 77 return nil, nil, 0, errors.New("buffer too short") 78 } 79 if end+4 > len(b) { 80 return nil, nil, 0, errors.New("section_length overruns buffer") 81 } 82 if end < 0 { 83 return nil, nil, 0, errors.New("section_length is too short") 84 } 85 data = b[start:end] 86 87 for _, b := range b[end : end+4] { 88 crc = (crc << 8) | uint32(b) 89 } 90 91 return syn, data, crc, nil 92 }