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

99 lines
1.6 KiB
Go

package pktreorder
import (
"github.com/nareix/av"
"io"
)
type stream struct {
isVideo bool
pkts []av.Packet
pos float64
}
type Queue struct {
streams []*stream
pktnr int
err error
}
func (self *Queue) Alloc(streams []av.CodecData) {
self.streams = []*stream{}
self.pktnr = 0
for _, s := range streams {
self.streams = append(self.streams, &stream{isVideo: s.IsVideo()})
}
}
func (self *Queue) chooseStream() (chosen int) {
flush := self.err != nil
minpos := float64(-1)
chosen = -1
for i, stream := range self.streams {
if (minpos < 0 || stream.pos < minpos || stream.pos == minpos && stream.isVideo) &&
(!flush || flush && len(stream.pkts) > 0) {
minpos = stream.pos
chosen = i
}
}
return
}
func (self *Queue) ReadPacket() (i int, pkt av.Packet, err error) {
if self.pktnr == 0 {
if self.err != nil {
err = self.err
} else {
err = io.EOF
}
return
}
chosen := self.chooseStream()
if chosen < 0 {
err = io.EOF
return
}
stream := self.streams[chosen]
if len(stream.pkts) == 0 {
err = io.EOF
return
}
i = chosen
pkt = stream.pkts[0]
stream.pkts = stream.pkts[1:]
stream.pos += pkt.Duration
self.pktnr--
return
}
func (self *Queue) WritePacket(i int, pkt av.Packet) (err error) {
stream := self.streams[i]
stream.pkts = append(stream.pkts, pkt)
self.pktnr++
return
}
func (self *Queue) CanReadPacket() bool {
chosen := self.chooseStream()
if chosen < 0 {
return false
}
if len(self.streams[chosen].pkts) == 0 {
return false
}
return true
}
func (self *Queue) EndWritePacket(err error) {
if err == nil {
err = io.EOF
}
self.err = err
}