Decrease memory usage of AAC decoding, use int16 sample format
This commit is contained in:
parent
386837a4f7
commit
84c6c3b064
|
@ -131,7 +131,7 @@ func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
source := audio.NewFloat32Source(decoder.SampleRate(), decoder.NumChannels())
|
||||
source := audio.NewInt16Source(16, decoder.SampleRate(), decoder.NumChannels())
|
||||
|
||||
go func() {
|
||||
defer source.Close()
|
||||
|
@ -169,7 +169,7 @@ func (f Format) Open(r io.ReadSeekCloser) (audio.Source, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
source := audio.NewFloat32Source(decoder.SampleRate(), decoder.NumChannels())
|
||||
source := audio.NewInt16Source(16, decoder.SampleRate(), decoder.NumChannels())
|
||||
|
||||
go func() {
|
||||
defer source.Close()
|
||||
|
@ -315,6 +315,74 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
|
|||
|
||||
frameSize := encoder.FrameSize() * encoder.Channels()
|
||||
|
||||
encodeSource := func(source audio.Source, writeCallback func(frame []byte) error) error {
|
||||
buffer := make([]int16, 0, frameSize)
|
||||
for block := range source.ToInt16().GetBlocks() {
|
||||
|
||||
buffer = append(buffer, block...)
|
||||
|
||||
tempBuffer := buffer[:]
|
||||
|
||||
for len(tempBuffer) >= frameSize {
|
||||
sl := tempBuffer[:frameSize]
|
||||
frameBuffer, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&sl[0])), len(sl)*2))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(frameBuffer) > 0 {
|
||||
if err = writeCallback(frameBuffer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tempBuffer = tempBuffer[frameSize:]
|
||||
}
|
||||
|
||||
if len(tempBuffer) > 0 {
|
||||
copy(buffer, tempBuffer)
|
||||
}
|
||||
|
||||
buffer = buffer[:len(tempBuffer)]
|
||||
}
|
||||
|
||||
if len(buffer) > 0 {
|
||||
//pad
|
||||
buffer = append(buffer, make([]int16, frameSize-len(buffer))...)
|
||||
frameBuffer, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&buffer[0])), len(buffer)*2))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(frameBuffer) > 0 {
|
||||
if err = writeCallback(frameBuffer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Do flush
|
||||
for {
|
||||
frameBuffer, err := encoder.Flush()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(frameBuffer) > 0 {
|
||||
if err = writeCallback(frameBuffer); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if format == "mp4" {
|
||||
init := mp4.CreateEmptyInit()
|
||||
init.AddEmptyTrack(uint32(source.GetSampleRate()), "audio", "en")
|
||||
|
@ -392,126 +460,28 @@ func (f Format) Encode(source audio.Source, writer io.WriteCloser, options map[s
|
|||
outputBuffer = nil
|
||||
}
|
||||
|
||||
outputPacket := func(packet []byte) {
|
||||
outputBuffer = append(outputBuffer, packet)
|
||||
|
||||
if err := encodeSource(source, func(frame []byte) error {
|
||||
outputBuffer = append(outputBuffer, frame)
|
||||
if time.Duration(float64(time.Second)*(float64(frameSize*len(outputBuffer))/float64(source.GetSampleRate()))) >= segmentDuration {
|
||||
outputSegment()
|
||||
}
|
||||
}
|
||||
|
||||
var buffer []int16
|
||||
for block := range source.ToInt16().GetBlocks() {
|
||||
|
||||
buffer = append(buffer, block...)
|
||||
|
||||
for len(buffer) >= frameSize {
|
||||
sl := buffer[:frameSize]
|
||||
buf, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&sl[0])), len(sl)*2))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
outputPacket(buf)
|
||||
}
|
||||
|
||||
buffer = buffer[frameSize:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(buffer) > 0 {
|
||||
//pad
|
||||
buffer = append(buffer, make([]int16, frameSize-len(buffer))...)
|
||||
buf, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&buffer[0])), len(buffer)*2))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
outputPacket(buf)
|
||||
}
|
||||
}
|
||||
|
||||
//Do flush
|
||||
for {
|
||||
buf, err := encoder.Flush()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
outputPacket(buf)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(outputBuffer) > 0 {
|
||||
outputSegment()
|
||||
}
|
||||
} else {
|
||||
|
||||
var buffer []int16
|
||||
for block := range source.ToInt16().GetBlocks() {
|
||||
|
||||
buffer = append(buffer, block...)
|
||||
|
||||
for len(buffer) >= frameSize {
|
||||
sl := buffer[:frameSize]
|
||||
buf, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&sl[0])), len(sl)*2))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
_, err = writer.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
buffer = buffer[frameSize:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(buffer) > 0 {
|
||||
//pad
|
||||
buffer = append(buffer, make([]int16, frameSize-len(buffer))...)
|
||||
buf, err := encoder.Encode(unsafe.Slice((*byte)(unsafe.Pointer(&buffer[0])), len(buffer)*2))
|
||||
|
||||
if err := encodeSource(source, func(frame []byte) error {
|
||||
_, err := writer.Write(frame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
_, err = writer.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Do flush
|
||||
for {
|
||||
buf, err := encoder.Flush()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
_, err = writer.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue