github.com/puellanivis/breton@v0.2.16/lib/mpeg/ts/pcr/pcr.go (about) 1 package pcr 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 // PCR defines the MPEG-TS Program Clock Reference. 9 type PCR struct { 10 base uint64 11 extension uint16 12 } 13 14 func (c *PCR) String() string { 15 s := c.Duration().String() 16 17 if c.extension == 0 { 18 return s 19 } 20 21 return fmt.Sprintf("%s<%d>", s, c.extension) 22 } 23 24 const ( 25 pcrModulo = (1 << 33) - 1 26 ) 27 28 // Marshal encodes the PCR into a byte slice. 29 func (c *PCR) Marshal() ([]byte, error) { 30 //pcr := uint64(c.base & pcrModulo) << 15 | uint64(c.extension & 0x1ff) 31 32 b := make([]byte, 6) 33 b[0] = byte((c.base >> 25) & 0xff) 34 b[1] = byte((c.base >> 17) & 0xff) 35 b[2] = byte((c.base >> 9) & 0xff) 36 b[3] = byte((c.base >> 1) & 0xff) 37 38 b[4] = byte((c.base<<7)&0x80) | byte((c.extension>>8)&0x01) 39 40 b[5] = byte(c.extension & 0xff) 41 42 return b, nil 43 } 44 45 // Unmarshal decodes a byte slice into the PCR. 46 func (c *PCR) Unmarshal(b []byte) error { 47 var pcr uint64 48 for _, b := range b[0:6] { 49 pcr = (pcr << 8) | uint64(b) 50 } 51 52 c.base = pcr >> 15 53 c.extension = uint16(pcr & 0x1ff) 54 55 return nil 56 } 57 58 // Duration returns the time.Duration that corresponds to the value of the PCR. 59 func (c *PCR) Duration() time.Duration { 60 return (time.Duration(c.base&pcrModulo) * time.Microsecond) / 27 61 } 62 63 // Set overwrites the value of the PCR to match the time.Duration given. 64 func (c *PCR) Set(d time.Duration) { 65 c.base = uint64((d*27)/time.Microsecond) & pcrModulo 66 }