diff --git a/.drone.yml b/.drone.yml index 9c714ed..9615a2d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -19,7 +19,7 @@ steps: commands: - apk update - apk add --no-cache git gcc g++ musl-dev bash autoconf automake cmake make libtool gettext fdk-aac-dev --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community - - go test -p 1 -failfast -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... + - go test -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... --- kind: pipeline type: docker @@ -57,7 +57,7 @@ steps: commands: - apk update - apk add --no-cache git gcc musl-dev pkgconfig - - go test -p 1 -failfast -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... + - go test -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... --- kind: pipeline type: docker @@ -94,6 +94,6 @@ steps: commands: - apk update - apk add --no-cache git gcc musl-dev pkgconfig - - go test -p 1 -failfast -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... + - go test -timeout 20m -cover -race -gcflags=-d=checkptr -v ./... ... diff --git a/fdkaac/enc.go b/fdkaac/enc.go index 7a6a010..dbe9f15 100644 --- a/fdkaac/enc.go +++ b/fdkaac/enc.go @@ -25,6 +25,7 @@ package fdkaac /* #cgo pkg-config: fdk-aac #include +#include typedef struct { // the encoder handler. @@ -88,22 +89,31 @@ int aacenc_init(aacenc_t* h, int aot, int channels, int sample_rate, int bitrate case 5: mode = MODE_1_2_2; sce = 1; cpe = 2; break; case 6: mode = MODE_1_2_2_1; sce = 2; cpe = 2; break; default: - return -1; + return AACENC_INIT_ERROR; } if ((err = aacEncOpen(&h->enc, 0, channels)) != AACENC_OK) { + printf("aacEncOpen\n"); + return err; + } + + if ((err = aacEncoder_SetParam(h->enc, AACENC_GRANULE_LENGTH, 1024)) != AACENC_OK) { + printf("AACENC_GRANULE_LENGTH\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_AOT, aot)) != AACENC_OK) { + printf("AACENC_AOT\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_SAMPLERATE, sample_rate)) != AACENC_OK) { + printf("AACENC_SAMPLERATE\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_CHANNELMODE, mode)) != AACENC_OK) { + printf("AACENC_CHANNELMODE\n"); return err; } @@ -111,42 +121,51 @@ int aacenc_init(aacenc_t* h, int aot, int channels, int sample_rate, int bitrate // - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). (default) // - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR). if ((err = aacEncoder_SetParam(h->enc, AACENC_CHANNELORDER, 1)) != AACENC_OK) { + printf("AACENC_CHANNELORDER\n"); return err; } if (bitrate >= 0) { //CBR mode if ((err = aacEncoder_SetParam(h->enc, AACENC_BITRATEMODE, 0)) != AACENC_OK) { + printf("AACENC_BITRATEMODE 1\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_BITRATE, bitrate)) != AACENC_OK) { + printf("AACENC_BITRATE\n"); return err; } } else { //VBR mode if ((err = aacEncoder_SetParam(h->enc, AACENC_BITRATEMODE, -bitrate)) != AACENC_OK) { + printf("AACENC_BITRATEMODE 2\n"); return err; } } if ((err = aacEncoder_SetParam(h->enc, AACENC_TRANSMUX, trans_mux)) != AACENC_OK) { + printf("AACENC_TRANSMUX\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_SIGNALING_MODE, signaling)) != AACENC_OK) { + printf("AACENC_SIGNALING_MODE\n"); return err; } if ((err = aacEncoder_SetParam(h->enc, AACENC_AFTERBURNER, afterburner)) != AACENC_OK) { + printf("AACENC_AFTERBURNER\n"); return err; } if ((err = aacEncEncode(h->enc, NULL, NULL, NULL, NULL)) != AACENC_OK) { + printf("aacEncEncode\n"); return err; } AACENC_InfoStruct info; if ((err = aacEncInfo(h->enc, &info)) != AACENC_OK) { + printf("aacEncInfo\n"); return err; } @@ -233,6 +252,7 @@ int aacenc_max_output_buffer_size(aacenc_t* h) { */ import "C" import ( + "errors" "fmt" "unsafe" ) @@ -309,6 +329,10 @@ const ( func (v *AacEncoder) InitLc(channels, sampleRate, bitrateBps, muxingMode, afterburner int) (err error) { v.channels = channels + if !EncoderCapabilities().AAC { + return errors.New("unsupported profile") + } + r := C.aacenc_init(&v.m, C.AOT_AAC_LC, C.int(channels), C.int(sampleRate), C.int(bitrateBps), C.int(muxingMode), C.int(afterburner)) if int(r) != 0 { return NewEncoderError(int(r)) @@ -327,6 +351,10 @@ func (v *AacEncoder) InitLc(channels, sampleRate, bitrateBps, muxingMode, afterb func (v *AacEncoder) InitHEv2(channels, sampleRate, bitrateBps, muxingMode, afterburner int) (err error) { v.channels = channels + if !EncoderCapabilities().PS { + return errors.New("unsupported profile") + } + r := C.aacenc_init(&v.m, C.AOT_PS, C.int(channels), C.int(sampleRate), C.int(bitrateBps), C.int(muxingMode), C.int(afterburner)) if int(r) != 0 { return NewEncoderError(int(r)) @@ -345,6 +373,10 @@ func (v *AacEncoder) InitHEv2(channels, sampleRate, bitrateBps, muxingMode, afte func (v *AacEncoder) InitHE(channels, sampleRate, bitrateBps, muxingMode, afterburner int) (err error) { v.channels = channels + if !EncoderCapabilities().SBR { + return errors.New("unsupported profile") + } + r := C.aacenc_init(&v.m, C.AOT_SBR, C.int(channels), C.int(sampleRate), C.int(bitrateBps), C.int(muxingMode), C.int(afterburner)) if int(r) != 0 { return NewEncoderError(int(r)) diff --git a/fdkaac/enc_test.go b/fdkaac/enc_test.go index cceb13f..1182d15 100644 --- a/fdkaac/enc_test.go +++ b/fdkaac/enc_test.go @@ -202,6 +202,11 @@ func TestLcFlush(t *testing.T) { func TestHev2Init(t *testing.T) { var err error + if !fdkaac.EncoderCapabilities().PS { + t.Log("profile not supported") + return + } + e := fdkaac.NewAacEncoder() if err = e.InitHEv2(2, 44100, 48000, fdkaac.MuxingModeADTS, 1); err != nil { t.Error("Init encoder failed, err is", err) @@ -218,6 +223,11 @@ func TestHev2Init(t *testing.T) { func TestHev2Encode(t *testing.T) { var err error + if !fdkaac.EncoderCapabilities().PS { + t.Log("profile not supported") + return + } + e := fdkaac.NewAacEncoder() if err = e.InitHEv2(2, 44100, 48000, fdkaac.MuxingModeADTS, 1); err != nil { t.Error("Init encoder failed, err is", err) @@ -243,7 +253,7 @@ func TestHev2Encode(t *testing.T) { // flush got the last packets. // @remark user should flush util frame is nil. - expectedFlushSizes := []int{279, 356, 298, 279} + expectedFlushSizes := []int{279, 358, 359, 120} for { if frame, err = e.Flush(); err != nil { @@ -275,6 +285,11 @@ func TestHev2Encode(t *testing.T) { func TestHev2Flush(t *testing.T) { var err error + if !fdkaac.EncoderCapabilities().PS { + t.Log("profile not supported") + return + } + e := fdkaac.NewAacEncoder() if err = e.InitHEv2(2, 44100, 48000, fdkaac.MuxingModeADTS, 1); err != nil { t.Error("Init encoder failed, err is", err) @@ -300,7 +315,7 @@ func TestHev2Flush(t *testing.T) { // flush got the last packets. // @remark user should flush util frame is nil. - expectedFlushSizes := []int{279, 356, 298, 279} + expectedFlushSizes := []int{279, 358, 359, 120} for { if frame, err = e.Flush(); err != nil { diff --git a/fdkaac/version.go b/fdkaac/version.go index e397e7d..0f4bdf0 100644 --- a/fdkaac/version.go +++ b/fdkaac/version.go @@ -33,6 +33,8 @@ const ( ModuleNone = C.FDK_NONE ModuleFdkTools = C.FDK_TOOLS ModuleFdkAACENC = C.FDK_AACENC + ModuleFdkSBRENC = C.FDK_SBRENC + ModuleFdkMPSENC = C.FDK_MPSENC ) func GetInfoModules() []C.LIB_INFO { @@ -53,12 +55,28 @@ func GetInfoModule(module C.FDK_MODULE_ID) *C.LIB_INFO { return nil } +func EncoderCapabilities() (cap struct { + AAC bool + SBR bool + PS bool +}) { + if module := GetInfoModule(ModuleFdkAACENC); module != nil { + cap.AAC = true + } + + if module := GetInfoModule(ModuleFdkSBRENC); module != nil { + cap.SBR = (module.flags & C.CAPF_SBR_HQ) != 0 + cap.PS = (module.flags & C.CAPF_SBR_PS_MPEG) != 0 + } + + return +} + func EncoderVersion() string { return C.GoString(&GetInfoModule(ModuleFdkAACENC).versionStr[0]) } func ToolsVersion() string { - return C.GoString(&GetInfoModule(ModuleFdkTools).versionStr[0]) }