joy4/pktqueue/pktqueue.go
2016-06-07 19:36:06 +08:00

104 lines
1.9 KiB
Go

package pktqueue
import (
"github.com/nareix/av"
)
type timePacket struct {
time float64
av.Packet
}
type stream struct {
pkts []timePacket
lastNormalDuration float64
isVideo bool
}
func (self *stream) isDurationNormal(v float64) bool {
return v > float64(0.0) && v < float64(1.0)
}
func (self *stream) Read(flush bool) (ok bool, pkt timePacket) {
if len(self.pkts) > 1 {
ok = true
pkt = self.pkts[0]
pkt.Duration = self.pkts[1].time - self.pkts[0].time
self.pkts = self.pkts[1:]
} else if len(self.pkts) == 1 && flush {
ok = true
pkt = self.pkts[0]
pkt.Duration = self.lastNormalDuration
self.pkts = self.pkts[1:]
}
if ok {
if !self.isDurationNormal(pkt.Duration) {
pkt.Duration = self.lastNormalDuration
} else {
self.lastNormalDuration = pkt.Duration
}
}
return
}
type Queue struct {
streams []*stream
Poll func() error
err error
time float64
}
func (self *Queue) CurrentTime() float64 {
return self.time
}
func (self *Queue) Alloc(streams []av.CodecData) {
self.streams = make([]*stream, len(streams))
for i := 0; i < len(self.streams); i++ {
self.streams[i] = &stream{
isVideo: streams[i].IsVideo(),
}
}
}
func (self *Queue) Clear() {
for _, stream := range self.streams {
stream.pkts = []timePacket{}
stream.lastNormalDuration = float64(0.0)
}
self.time = 0.0
}
func (self *Queue) ReadPacket() (i int, pkt av.Packet, err error) {
for {
flush := self.err != nil
var tpkt timePacket
var ok bool
var stream *stream
for i, stream = range self.streams {
if ok, tpkt = stream.Read(flush); ok {
break
}
}
if ok {
pkt = tpkt.Packet
self.time = tpkt.time
return
} else {
if self.err == nil {
self.err = self.Poll()
} else {
err = self.err
return
}
}
}
return
}
func (self *Queue) WriteTimePacket(i int, time float64, pkt av.Packet) {
stream := self.streams[i]
stream.pkts = append(stream.pkts, timePacket{Packet: pkt, time: time})
}