Skip to content

Commit

Permalink
improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Jan 15, 2024
1 parent 807b3f4 commit 5459ad8
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 19 deletions.
59 changes: 40 additions & 19 deletions internal/playback/fmp4.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package playback

import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"os"
"time"
Expand Down Expand Up @@ -33,27 +33,48 @@ func durationMp4ToGo(v uint64, timeScale uint32) time.Duration {

var errTerminated = errors.New("terminated")

func readInit(r io.ReadSeeker) ([]byte, error) {
br := bufio.NewReaderSize(r, 4096)
var out []byte
func fmp4ReadInit(r io.ReadSeeker) ([]byte, error) {
buf := make([]byte, 8)
_, err := io.ReadFull(r, buf)
if err != nil {
return nil, err
}

for {
by, err := br.ReadByte()
if err != nil {
return nil, err
}
if !bytes.Equal(buf[4:], []byte{'f', 't', 'y', 'p'}) {
return nil, fmt.Errorf("ftyp box not found")
}

out = append(out, by)
ftypSize := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3])

if len(out) >= 8 {
if bytes.Equal(out[len(out)-8:], []byte{
'm', 'o', 'o', 'f', 0x00, 0x00, 0x00, 0x10,
}) {
out = out[:len(out)-12]
return out, nil
}
}
_, err = r.Seek(int64(ftypSize), io.SeekStart)
if err != nil {
return nil, err
}

_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}

if !bytes.Equal(buf[4:], []byte{'m', 'o', 'o', 'v'}) {
return nil, fmt.Errorf("moov box not found")
}

moovSize := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3])

_, err = r.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}

buf = make([]byte, ftypSize+moovSize)

_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}

return buf, nil
}

func seekAndMuxParts(
Expand Down Expand Up @@ -377,7 +398,7 @@ func fmp4SeekAndMux(
}
defer f.Close()

init, err := readInit(f)
init, err := fmp4ReadInit(f)
if err != nil {
return 0, err
}
Expand Down
79 changes: 79 additions & 0 deletions internal/playback/fmp4_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package playback

import (
"io"
"os"
"testing"

"github.com/bluenviron/mediacommon/pkg/codecs/mpeg4audio"
"github.com/bluenviron/mediacommon/pkg/formats/fmp4"
)

func writeBenchInit(f io.WriteSeeker) {
init := fmp4.Init{
Tracks: []*fmp4.InitTrack{
{
ID: 1,
TimeScale: 90000,
Codec: &fmp4.CodecH264{
SPS: []byte{
0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02,
0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04,
0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9,
0x20,
},
PPS: []byte{0x08},
},
},
{
ID: 2,
TimeScale: 90000,
Codec: &fmp4.CodecMPEG4Audio{
Config: mpeg4audio.Config{
Type: mpeg4audio.ObjectTypeAACLC,
SampleRate: 48000,
ChannelCount: 2,
},
},
},
},
}

err := init.Marshal(f)
if err != nil {
panic(err)
}

_, err = f.Write([]byte{
'm', 'o', 'o', 'f', 0x00, 0x00, 0x00, 0x10,
})
if err != nil {
panic(err)
}
}

func BenchmarkFMP4ReadInit(b *testing.B) {
f, err := os.CreateTemp(os.TempDir(), "mediamtx-playback-fmp4-")
if err != nil {
panic(err)
}
defer os.Remove(f.Name())

writeBenchInit(f)
f.Close()

for n := 0; n < b.N; n++ {
func() {
f, err := os.Open(f.Name())
if err != nil {
panic(err)
}
defer f.Close()

_, err = fmp4ReadInit(f)
if err != nil {
panic(err)
}
}()
}
}

0 comments on commit 5459ad8

Please sign in to comment.