container/mts/mpegts.go: wrote GetPTSRange func

This func will return the first and last PTS from an MPEGTS clip by finding the first access unit, and then by moving backward from the end of the clip to find the start of the final PES packet.
This commit is contained in:
Saxon 2019-05-10 14:18:55 +09:30
parent 11ad16dbe1
commit 868d01527c
1 changed files with 44 additions and 0 deletions

View File

@ -33,6 +33,7 @@ import (
"fmt"
"github.com/Comcast/gots/packet"
"github.com/Comcast/gots/pes"
)
// General mpegts packet properties.
@ -315,3 +316,46 @@ func DiscontinuityIndicator(f bool) Option {
p[DiscontinuityIndicatorIdx] |= DiscontinuityIndicatorMask & set
}
}
// GetPTSRange retreives the first and last PTS of an MPEGTS clip.
func GetPTSRange(clip []byte) (pts [2]uint64, err error) {
// Find the first video packet.
pkt, _, err := FindPid(clip, videoPid)
if err != nil {
return [2]uint64{}, err
}
// Get the payload of the packet, which will be the start of the PES packet.
var _pkt packet.Packet
copy(_pkt[:], pkt)
payload, err := packet.Payload(&_pkt)
if err != nil {
return [2]uint64{}, err
}
// Get the the first PTS from the PES header.
_pes, err := pes.NewPESHeader(payload)
if err != nil {
return [2]uint64{}, err
}
pts[0] = _pes.PTS()
// Get the final PTS and calculate PTS immediately after.
for i := len(clip) - PacketSize; i >= 0; i -= PacketSize {
copy(_pkt[:], clip[i:i+PacketSize])
if packet.PayloadUnitStartIndicator(&_pkt) {
payload, err = packet.Payload(&_pkt)
if err != nil {
return [2]uint64{}, err
}
_pes, err = pes.NewPESHeader(payload)
if err != nil {
return [2]uint64{}, err
}
pts[1] = _pes.PTS()
return
}
}
return [2]uint64{}, errors.New("could only find one access unit in mpegts clip")
}