github.com/puellanivis/breton@v0.2.16/lib/mpeg/ts/pes/packet.go (about) 1 package pes 2 3 import ( 4 "bytes" 5 6 "github.com/pkg/errors" 7 ) 8 9 type packet struct { 10 stream *Stream 11 12 payload []byte 13 } 14 15 var startCodePrefix = []byte{0, 0, 1} 16 17 func (p *packet) preUnmarshal(b []byte) (int, error) { 18 if !bytes.HasPrefix(b, startCodePrefix) { 19 return 0, errors.Errorf("bad start prefix [% 2X]", b[:3]) 20 } 21 22 if p.stream == nil { 23 p.stream = new(Stream) 24 } 25 26 p.stream.ID = b[3] 27 return (int(b[4]) << 8) | int(b[5]), nil 28 } 29 30 func (p *packet) unmarshal(b []byte) error { 31 switch p.stream.ID { 32 case idPaddingStream, idPrivateStream2: 33 // Optional PES Header not present for these streams. 34 35 default: 36 hlen, err := p.stream.unmarshalHeader(b) 37 if err != nil { 38 return err 39 } 40 41 b = b[hlen:] 42 } 43 44 p.payload = append([]byte{}, b...) 45 46 return nil 47 } 48 49 func (p *packet) Unmarshal(b []byte) error { 50 l, err := p.preUnmarshal(b) 51 if err != nil { 52 return err 53 } 54 55 // trim mandatory header (already consumed by preMarshal) 56 b = b[mandatoryHeaderLength:] 57 58 return p.unmarshal(b[:l]) // enforce length with slice boundaries. 59 } 60 61 func (p *packet) Marshal() ([]byte, error) { 62 var h []byte 63 64 switch p.stream.ID { 65 case idPaddingStream, idPrivateStream2: 66 // Optional PES Header not present for these streams. 67 68 default: 69 var err error 70 71 h, err = p.stream.marshalHeader() 72 if err != nil { 73 return nil, err 74 } 75 } 76 77 l := len(h) + len(p.payload) 78 79 if l > 0xffff { 80 return nil, errors.Errorf("packet size too big: header:%d payload:%d", len(h), len(p.payload)) 81 } 82 83 out := make([]byte, mandatoryHeaderLength+l) 84 85 copy(out, startCodePrefix) 86 87 out[3] = p.stream.ID 88 out[4] = byte((l >> 8) & 0xff) 89 out[5] = byte(l & 0xff) 90 91 start := mandatoryHeaderLength 92 start += copy(out[start:], h) 93 94 copy(out[start:], p.payload) 95 96 return out, nil 97 }