Fix encoder Reader usage.
Follow Reading Rules (point 5) in https://medium.com/learning-the-go-programming-language/streaming-io-in-go-d93507931185 and don't break the encoding loop when n = 0 and err = nil.
This commit is contained in:
parent
99260cfa70
commit
3977d1d823
11
encode.go
11
encode.go
|
@ -71,19 +71,22 @@ func (e *Encoder) Encode(r io.Reader) (err error) {
|
|||
var outinfo aacenc.VoAudioOutputinfo
|
||||
var input, output aacenc.VoCodecBuffer
|
||||
var n int
|
||||
var prevRead int
|
||||
loop:
|
||||
for {
|
||||
n, err = r.Read(e.inbuf)
|
||||
n, err = r.Read(e.inbuf[prevRead:])
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if n < e.insize {
|
||||
break
|
||||
prevRead += n
|
||||
if prevRead < e.insize {
|
||||
continue
|
||||
}
|
||||
n = prevRead
|
||||
prevRead = 0
|
||||
|
||||
input.Buffer = C.CBytes(e.inbuf)
|
||||
input.Length = uint64(n)
|
||||
|
|
|
@ -2,6 +2,7 @@ package aac
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -47,4 +48,89 @@ func TestEncode(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if want, got := 8192, len(buf.Bytes()); want != got {
|
||||
t.Errorf("encoded file length %d is different from expected length %d", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type testReader struct {
|
||||
bufLen int
|
||||
from io.Reader
|
||||
adjust func() int
|
||||
}
|
||||
|
||||
func (t *testReader) Read(in []byte) (int, error) {
|
||||
defer func() {
|
||||
t.bufLen = t.adjust()
|
||||
}()
|
||||
if t.bufLen > len(in) {
|
||||
t.bufLen = len(in)
|
||||
}
|
||||
if t.bufLen == 0 {
|
||||
// This is not EOF, just unavailable data at this point.
|
||||
return 0, nil
|
||||
}
|
||||
buf := make([]byte, t.bufLen)
|
||||
n, err := t.from.Read(buf)
|
||||
if n > 0 {
|
||||
copy(in, buf[:n])
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func TestEncodeVariableReadLength(t *testing.T) {
|
||||
file, err := os.Open(filepath.Join("testdata", "test.wav"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wr := wav.NewReader(file)
|
||||
f, err := wr.Format()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tr := &testReader{
|
||||
bufLen: 1,
|
||||
from: wr,
|
||||
}
|
||||
bufLenPrev := 1
|
||||
tr.adjust = func() int {
|
||||
bufLenPrev += 1
|
||||
if bufLenPrev%5 == 0 {
|
||||
return 0
|
||||
}
|
||||
return bufLenPrev
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(make([]byte, 0))
|
||||
|
||||
opts := &Options{}
|
||||
opts.SampleRate = int(f.SampleRate)
|
||||
opts.NumChannels = int(f.NumChannels)
|
||||
|
||||
enc, err := NewEncoder(buf, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = enc.Encode(tr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = enc.Close()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(os.TempDir(), "test-2.aac"), buf.Bytes(), 0644)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if want, got := 8192, len(buf.Bytes()); want != got {
|
||||
t.Errorf("encoded file length %d is different from expected length %d", got, want)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue