github.com/puellanivis/breton@v0.2.16/lib/mpeg/ts/psi/streamdata.go (about) 1 package psi 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/pkg/errors" 8 desc "github.com/puellanivis/breton/lib/mpeg/ts/descriptor" 9 ) 10 11 // StreamData defines the Stream Data for a Program Map Table. 12 type StreamData struct { 13 Type byte 14 PID uint16 15 16 Descriptors []desc.Descriptor 17 } 18 19 func (esd *StreamData) String() string { 20 out := []string{ 21 fmt.Sprintf("Type:x%02X", esd.Type), 22 fmt.Sprintf("PID:x%04X", esd.PID), 23 } 24 25 for _, d := range esd.Descriptors { 26 out = append(out, fmt.Sprintf("Desc:%v", d)) 27 } 28 29 return fmt.Sprintf("{%s}", strings.Join(out, " ")) 30 } 31 32 func (esd *StreamData) unmarshal(b []byte) (int, error) { 33 esd.Type = b[0] 34 esd.PID = uint16(b[1]&0x1f)<<8 | uint16(b[2]) 35 36 l := int(b[3]&0x3)<<8 | int(b[4]) 37 38 start := 5 39 end := start + l 40 41 for start < end { 42 d, err := desc.Unmarshal(b[start:]) 43 if err != nil { 44 return start, err 45 } 46 47 esd.Descriptors = append(esd.Descriptors, d) 48 49 start += d.Len() 50 } 51 52 return start, nil 53 } 54 55 func (esd *StreamData) marshal() ([]byte, error) { 56 data := make([]byte, 5) 57 58 data[0] = esd.Type 59 data[1] = byte((esd.PID >> 8) & 0x1f) 60 data[2] = byte(esd.PID & 0xff) 61 62 l := len(esd.Descriptors) 63 if l > 0x3FF { 64 return nil, errors.Errorf("too many descriptors: %d > 0x3FF ", l) 65 } 66 67 data[3] = byte((l >> 8) & 0x03) 68 data[4] = byte(l & 0xFF) 69 70 for _, d := range esd.Descriptors { 71 b, err := d.Marshal() 72 if err != nil { 73 return nil, err 74 } 75 76 data = append(data, b...) 77 } 78 79 return data, nil 80 }