github.com/puellanivis/breton@v0.2.16/lib/mpeg/ts/dvb/descriptor.go (about) 1 package dvb 2 3 import ( 4 "fmt" 5 6 "github.com/pkg/errors" 7 desc "github.com/puellanivis/breton/lib/mpeg/ts/descriptor" 8 ) 9 10 // ServiceType is an enum encoding DVB standards indicating service types for MPEG-TS. 11 type ServiceType uint8 12 13 // SesrviceType enum values. 14 const ( 15 ServiceTypeTV ServiceType = iota + 1 16 ServiceTypeRadio 17 ServiceTypeTeletext 18 ServiceTypeHDTV = 0x11 19 ServiceTypeH264SDTV = 0x16 20 ServiceTypeH264HDTV = 0x19 21 ServiceTypeHEVCTV = 0x1F 22 ) 23 24 var dvbServiceTypeNames = map[ServiceType]string{ 25 ServiceTypeTV: "TV", 26 ServiceTypeRadio: "Radio", 27 ServiceTypeTeletext: "Teletext", 28 ServiceTypeHDTV: "HDTV", 29 ServiceTypeH264SDTV: "H.264-SDTV", 30 ServiceTypeH264HDTV: "H.264-HDTV", 31 ServiceTypeHEVCTV: "HEVC-TV", 32 } 33 34 func (t ServiceType) String() string { 35 if s, ok := dvbServiceTypeNames[t]; ok { 36 return s 37 } 38 39 return fmt.Sprintf("x%02X", uint8(t)) 40 } 41 42 // ServiceDescriptor defines a DVB Service Descriptor for the MPEG-TS standard. 43 type ServiceDescriptor struct { 44 Type ServiceType 45 46 Provider string 47 Name string 48 } 49 50 func (d *ServiceDescriptor) String() string { 51 return fmt.Sprintf("{DVB:ServiceDesc %v P:%q N:%q}", d.Type, d.Provider, d.Name) 52 } 53 54 const ( 55 tagDVBService uint8 = 0x48 56 ) 57 58 func init() { 59 desc.Register(tagDVBService, func() desc.Descriptor { return new(ServiceDescriptor) }) 60 } 61 62 // Tag implements mpeg/ts/descriptor.Descriptor. 63 func (d *ServiceDescriptor) Tag() uint8 { 64 return tagDVBService 65 } 66 67 // Len returns the length in bytes that the ServiceDescriptor would encode into, and implements mpeg/ts/descriptor.Descriptor. 68 func (d *ServiceDescriptor) Len() int { 69 return 5 + len(d.Provider) + len(d.Name) 70 } 71 72 // Unmarshal decodes a byte slice into the ServiceDescriptor. 73 func (d *ServiceDescriptor) Unmarshal(b []byte) error { 74 if b[0] != tagDVBService { 75 return errors.Errorf("descriptor_tag mismatch: x%02X != x%02X", b[0], tagDVBService) 76 } 77 78 l := int(b[1]) 79 80 b = b[2:] 81 if len(b) < l { 82 return errors.Errorf("unexpected end of byte-slice: %d < %d", len(b), l) 83 } 84 85 d.Type = ServiceType(b[0]) 86 b = b[1:] 87 88 n := int(b[0]) 89 d.Provider = string(b[1 : 1+n]) 90 91 b = b[1+n:] 92 93 n = int(b[0]) 94 d.Name = string(b[1 : 1+n]) 95 96 return nil 97 } 98 99 // Marshal encodes the ServiceDescriptor into a byte slice. 100 func (d *ServiceDescriptor) Marshal() ([]byte, error) { 101 l := 3 + len(d.Provider) + len(d.Name) 102 if l > 0xFF { 103 return nil, errors.Errorf("descriptor data field too large: %d", l) 104 } 105 106 b := make([]byte, d.Len()) 107 108 b[0] = tagDVBService 109 b[1] = byte(l) 110 b[2] = byte(d.Type) 111 112 b[3] = byte(len(d.Provider)) 113 n := copy(b[4:], d.Provider) 114 115 b[4+n] = byte(len(d.Name)) 116 copy(b[5+n:], d.Name) 117 118 return b, nil 119 }