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  }