mp4: add bufio for reader, improve speed

This commit is contained in:
nareix 2016-07-28 23:38:37 +08:00
parent 87e9318f36
commit 1c1d351104
2 changed files with 33 additions and 9 deletions

View File

@ -3,22 +3,29 @@ package mp4
import ( import (
"time" "time"
"fmt" "fmt"
"github.com/nareix/pio"
"github.com/nareix/joy4/av" "github.com/nareix/joy4/av"
"github.com/nareix/joy4/codec/aacparser" "github.com/nareix/joy4/codec/aacparser"
"github.com/nareix/joy4/codec/h264parser" "github.com/nareix/joy4/codec/h264parser"
"github.com/nareix/joy4/format/mp4/mp4io" "github.com/nareix/joy4/format/mp4/mp4io"
"io" "io"
"bufio"
) )
type Demuxer struct { type Demuxer struct {
r io.ReadSeeker r io.ReadSeeker
bufr *bufio.Reader
rpos int64
streams []*Stream streams []*Stream
movieAtom *mp4io.Movie movieAtom *mp4io.Movie
} }
func NewDemuxer(r io.ReadSeeker) *Demuxer { func NewDemuxer(r io.ReadSeeker) *Demuxer {
return &Demuxer{r: r} return &Demuxer{
r: r,
bufr: bufio.NewReaderSize(r, pio.RecommendBufioSize),
}
} }
func (self *Demuxer) Streams() (streams []av.CodecData, err error) { func (self *Demuxer) Streams() (streams []av.CodecData, err error) {
@ -31,6 +38,24 @@ func (self *Demuxer) Streams() (streams []av.CodecData, err error) {
return return
} }
func (self *Demuxer) readat(pos int64, b []byte) (err error) {
if pos < self.rpos || pos > self.rpos+int64(pio.RecommendBufioSize) {
self.bufr.Reset(self.r)
if _, err = self.r.Seek(pos, 0); err != nil {
return
}
} else if pos != self.rpos {
if _, err = self.bufr.Discard(int(pos-self.rpos)); err != nil {
return
}
}
if _, err = io.ReadFull(self.bufr, b); err != nil {
return
}
self.rpos = pos+int64(len(b))
return
}
func (self *Demuxer) probe() (err error) { func (self *Demuxer) probe() (err error) {
if self.movieAtom != nil { if self.movieAtom != nil {
return return
@ -42,6 +67,10 @@ func (self *Demuxer) probe() (err error) {
if atoms, err = mp4io.ReadFileAtoms(self.r); err != nil { if atoms, err = mp4io.ReadFileAtoms(self.r); err != nil {
return return
} }
if _, err = self.r.Seek(0, 0); err != nil {
return
}
for _, atom := range atoms { for _, atom := range atoms {
if atom.Tag() == mp4io.MOOV { if atom.Tag() == mp4io.MOOV {
moov = atom.(*mp4io.Movie) moov = atom.(*mp4io.Movie)
@ -57,7 +86,7 @@ func (self *Demuxer) probe() (err error) {
for i, atrack := range moov.Tracks { for i, atrack := range moov.Tracks {
stream := &Stream{ stream := &Stream{
trackAtom: atrack, trackAtom: atrack,
r: self.r, demuxer: self,
idx: i, idx: i,
} }
if atrack.Media != nil && atrack.Media.Info != nil && atrack.Media.Info.Sample != nil { if atrack.Media != nil && atrack.Media.Info != nil && atrack.Media.Info.Sample != nil {
@ -351,12 +380,8 @@ func (self *Stream) readPacket() (pkt av.Packet, err error) {
} }
sampleOffset := int64(chunkOffset) + self.sampleOffsetInChunk sampleOffset := int64(chunkOffset) + self.sampleOffsetInChunk
if _, err = self.r.Seek(sampleOffset, 0); err != nil {
return
}
pkt.Data = make([]byte, sampleSize) pkt.Data = make([]byte, sampleSize)
if _, err = self.r.Read(pkt.Data); err != nil { if err = self.demuxer.readat(sampleOffset, pkt.Data); err != nil {
return return
} }

View File

@ -4,14 +4,12 @@ import (
"github.com/nareix/joy4/av" "github.com/nareix/joy4/av"
"github.com/nareix/joy4/format/mp4/mp4io" "github.com/nareix/joy4/format/mp4/mp4io"
"time" "time"
"io"
) )
type Stream struct { type Stream struct {
av.CodecData av.CodecData
trackAtom *mp4io.Track trackAtom *mp4io.Track
r io.ReadSeeker
idx int idx int
lastpkt *av.Packet lastpkt *av.Packet
@ -20,6 +18,7 @@ type Stream struct {
duration int64 duration int64
muxer *Muxer muxer *Muxer
demuxer *Demuxer
sample *mp4io.SampleTable sample *mp4io.SampleTable
sampleIndex int sampleIndex int