fixed memory leaks
+ new interface
This commit is contained in:
parent
fdf99cc485
commit
99260cfa70
|
@ -1,7 +1,9 @@
|
|||
// Package aacenc implements cgo bindings for [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library.
|
||||
package aacenc
|
||||
|
||||
// Package aacenc implements cgo bindings for [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library.
|
||||
|
||||
//#include "voAAC.h"
|
||||
// VO_U32 encode(VO_HANDLE hCodec,void *pcm, int pcmlen, void *aac, int aacBufferSize, VO_U32 *err);
|
||||
import "C"
|
||||
|
||||
import (
|
||||
|
@ -208,7 +210,9 @@ type AacencParam struct {
|
|||
|
||||
// Encoder Thread-safe
|
||||
type Encoder struct {
|
||||
handle C.VO_HANDLE
|
||||
handle C.VO_HANDLE
|
||||
outbuff [20480]byte
|
||||
blockSize int // size of block for encoding
|
||||
}
|
||||
|
||||
// Errors.
|
||||
|
@ -322,3 +326,35 @@ func (e *Encoder) Uninit() uint {
|
|||
v := (uint)(ret)
|
||||
return v
|
||||
}
|
||||
|
||||
// EncodePcmBlock - Encodes single interleaved block 1024 * numchannels
|
||||
// if buffer size is wrong returns VoErrInvalidArg
|
||||
func (e *Encoder) EncodePcmBlock(inPcm []int16) (aac []byte, err uint) {
|
||||
if len(inPcm) != e.blockSize {
|
||||
return nil, VoErrInvalidArg
|
||||
}
|
||||
var ret _Ctype_VO_U32
|
||||
len := C.encode(e.handle,
|
||||
unsafe.Pointer(&inPcm[0]),
|
||||
_Ctype_int(len(inPcm)*2), // int16
|
||||
unsafe.Pointer(&e.outbuff[0]),
|
||||
_Ctype_int(len(e.outbuff)),
|
||||
&ret)
|
||||
err = uint(ret)
|
||||
if err != VoErrNone { // error
|
||||
return nil, err
|
||||
}
|
||||
return e.outbuff[:len], err
|
||||
}
|
||||
|
||||
// SetParamAac set Samplerate & numchannels for AAC encoding
|
||||
func (e *Encoder) SetParamAac(aacSamplerate, nChannels int) (err uint) {
|
||||
e.blockSize = 1024 * nChannels
|
||||
setParametersBlock := C.AACENC_PARAM{
|
||||
sampleRate: _Ctype_int(aacSamplerate), /*! audio file sample rate */
|
||||
bitRate: 64000, /*! encoder bit rate in bits/sec */
|
||||
nChannels: _Ctype_short(nChannels), /*! number of channels on input (1,2) */
|
||||
adtsUsed: 1, /*! whether write adts header */
|
||||
}
|
||||
return uint(C.voAACEncSetParam(e.handle, VoPidAacEncparam, _Ctype_VO_PTR(&setParametersBlock)))
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ package aacenc
|
|||
#include "external/aacenc/src/stat_bits.c"
|
||||
#include "external/aacenc/src/tns.c"
|
||||
#include "external/aacenc/src/transform.c"
|
||||
// #include "bridge.c"
|
||||
|
||||
#cgo CFLAGS: -std=gnu99 -Iexternal/aacenc/include -DUSE_DEFAULT_MEM
|
||||
*/
|
||||
|
|
24
aacenc/bridge.c
Normal file
24
aacenc/bridge.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
// #include <stdint.h>
|
||||
// #include <stdio.h>
|
||||
#include "voAAC.h"
|
||||
|
||||
// function hooks "panic: runtime error: cgo argument has Go pointer to Go pointer"
|
||||
VO_U32 encode(VO_HANDLE hCodec,void *pcm, int pcmlen, void *aac, int aacBufferSize, VO_U32 *err){
|
||||
VO_CODECBUFFER input,output;
|
||||
VO_AUDIO_OUTPUTINFO outInfo;
|
||||
input.Buffer=pcm;
|
||||
input.Length=pcmlen;
|
||||
VO_U32 ret=voAACEncSetInputData(hCodec, &input);
|
||||
if (ret!=VO_ERR_NONE){
|
||||
*err=ret;
|
||||
return 0;
|
||||
}
|
||||
output.Buffer=aac;
|
||||
output.Length=aacBufferSize;
|
||||
ret=voAACEncGetOutputData(hCodec,&output,&outInfo);
|
||||
if (ret!=VO_ERR_NONE){
|
||||
*err=ret;
|
||||
return 0;
|
||||
}
|
||||
return output.Length;
|
||||
}
|
29
aacenc/encode_test.go
Normal file
29
aacenc/encode_test.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package aacenc
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBridge(t *testing.T) {
|
||||
channels := 2
|
||||
properLen := 1024 * channels
|
||||
m := make([]int16, properLen, properLen)
|
||||
aacEnc := New()
|
||||
aacEnc.Init(VoAudioCodingAac)
|
||||
ret := aacEnc.SetParamAac(44100, channels)
|
||||
if ret != VoErrNone {
|
||||
t.Error("SetParamAac failed")
|
||||
}
|
||||
|
||||
b, errn := aacEnc.EncodePcmBlock(m)
|
||||
if errn != VoErrNone {
|
||||
t.Error("EncodePcmBlock failed on proper len", ErrorFromResult(errn))
|
||||
}
|
||||
log.Print("Encoded: ", len(b))
|
||||
b, errn = aacEnc.EncodePcmBlock(m[1:])
|
||||
if errn == VoErrNone {
|
||||
t.Error("EncodePcmBlock failed on wrong len", ErrorFromResult(errn))
|
||||
}
|
||||
|
||||
}
|
27
encode.go
27
encode.go
|
@ -1,6 +1,7 @@
|
|||
// Package aac provides AAC codec encoder based on [VisualOn AAC encoder](https://github.com/mstorsjo/vo-aacenc) library.
|
||||
package aac
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
|
@ -67,8 +68,12 @@ func NewEncoder(w io.Writer, opts *Options) (e *Encoder, err error) {
|
|||
|
||||
// Encode encodes data from reader.
|
||||
func (e *Encoder) Encode(r io.Reader) (err error) {
|
||||
var outinfo aacenc.VoAudioOutputinfo
|
||||
var input, output aacenc.VoCodecBuffer
|
||||
var n int
|
||||
loop:
|
||||
for {
|
||||
n, err := r.Read(e.inbuf)
|
||||
n, err = r.Read(e.inbuf)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
return err
|
||||
|
@ -80,16 +85,13 @@ func (e *Encoder) Encode(r io.Reader) (err error) {
|
|||
break
|
||||
}
|
||||
|
||||
var outinfo aacenc.VoAudioOutputinfo
|
||||
var input, output aacenc.VoCodecBuffer
|
||||
|
||||
input.Buffer = C.CBytes(e.inbuf)
|
||||
input.Length = uint64(n)
|
||||
|
||||
ret := e.aacEnc.SetInputData(&input)
|
||||
err = aacenc.ErrorFromResult(ret)
|
||||
if err != nil {
|
||||
return err
|
||||
break loop
|
||||
}
|
||||
|
||||
output.Buffer = C.CBytes(e.outbuf)
|
||||
|
@ -98,13 +100,24 @@ func (e *Encoder) Encode(r io.Reader) (err error) {
|
|||
ret = e.aacEnc.GetOutputData(&output, &outinfo)
|
||||
err = aacenc.ErrorFromResult(ret)
|
||||
if err != nil {
|
||||
return err
|
||||
break loop
|
||||
}
|
||||
|
||||
_, err = e.w.Write(C.GoBytes(output.Buffer, C.int(output.Length)))
|
||||
if err != nil {
|
||||
return err
|
||||
break loop
|
||||
}
|
||||
C.free(input.Buffer)
|
||||
input.Buffer = nil
|
||||
C.free(output.Buffer)
|
||||
output.Buffer = nil
|
||||
}
|
||||
|
||||
if input.Buffer != nil {
|
||||
C.free(input.Buffer)
|
||||
}
|
||||
if output.Buffer != nil {
|
||||
C.free(output.Buffer)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -5,8 +5,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/gen2brain/aac-go"
|
||||
"github.com/youpy/go-wav"
|
||||
aac "github.com/aam335/aac-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
Loading…
Reference in a new issue