Created
November 27, 2019 20:52
-
-
Save alfredh/90dd76b912ef86a38dee61e7252c5e71 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/mk/modules.mk b/mk/modules.mk | |
index f5487f9..026c140 100644 | |
--- a/mk/modules.mk | |
+++ b/mk/modules.mk | |
@@ -65,7 +65,7 @@ USE_L16 := 1 | |
ifneq ($(OS),win32) | |
USE_AAC := $(shell [ -f $(SYSROOT)/include/fdk-aac/FDK_audio.h ] || \ | |
- [ -f $(SYSROOT)/local/include/fdk-aac/FDK_audio.h ] || \ | |
+ [ -f $(SYSROOT_LOCAL)/include/fdk-aac/FDK_audio.h ] || \ | |
[ -f $(SYSROOT_ALT)/include/fdk-aac/FDK_audio.h ] && echo "yes") | |
USE_ALSA := $(shell [ -f $(SYSROOT)/include/alsa/asoundlib.h ] || \ | |
[ -f $(SYSROOT_ALT)/include/alsa/asoundlib.h ] && echo "yes") | |
diff --git a/modules/aac/aac.c b/modules/aac/aac.c | |
index 64a2d28..5b94430 100644 | |
--- a/modules/aac/aac.c | |
+++ b/modules/aac/aac.c | |
@@ -17,9 +17,9 @@ | |
static struct aucodec aac = { | |
- .name = "MP4A-LATM", | |
+ .name = "mpeg4-generic", | |
.srate = AAC_SRATE, | |
- .crate = 90000, | |
+ .crate = AAC_SRATE, | |
.ch = AAC_CHANNELS, | |
.pch = 1, | |
.encupdh = aac_encode_update, | |
diff --git a/modules/aac/aac.h b/modules/aac/aac.h | |
index 40996c6..bf84add 100644 | |
--- a/modules/aac/aac.h | |
+++ b/modules/aac/aac.h | |
@@ -7,7 +7,7 @@ | |
enum { | |
AAC_BITRATE = 64000, | |
- AAC_SRATE = 48000, | |
+ AAC_SRATE = 16000, | |
AAC_CHANNELS = 1, | |
}; | |
diff --git a/modules/aac/decode.c b/modules/aac/decode.c | |
index 9147186..066966f 100644 | |
--- a/modules/aac/decode.c | |
+++ b/modules/aac/decode.c | |
@@ -12,6 +12,11 @@ | |
#include "aac.h" | |
+struct hdr { | |
+ size_t bits; | |
+}; | |
+ | |
+ | |
struct audec_state { | |
HANDLE_AACDECODER dec; | |
}; | |
@@ -26,6 +31,44 @@ static void destructor(void *arg) | |
} | |
+/* todo: use sizeLength from SDP */ | |
+static int hdr_decode(struct hdr *hdr, const uint8_t *p, size_t len) | |
+{ | |
+ size_t bits; | |
+ | |
+ if (len < 4) | |
+ return EPROTO; | |
+ | |
+ if (p[0] != 0x00 || p[1] != 0x10) | |
+ return EPROTO; | |
+ | |
+ bits = ntohs(*(uint16_t *)(void *)&p[2]); | |
+ | |
+ if (bits < 1 || bits > 16384) { | |
+ warning("aac: decode: invalid bits (bits=%zu)\n", bits); | |
+ return EBADMSG; | |
+ } | |
+ | |
+ if (bits/8 > len-4) { | |
+ warning("aac: decode: short packet (%zu > %zu)\n", | |
+ bits/8, len-4); | |
+ return ENODATA; | |
+ } | |
+ | |
+ hdr->bits = bits; | |
+ | |
+ size_t left = len - 4; | |
+ | |
+ if (bits/8 != left) { | |
+ warning("multiple access units per packet\n"); | |
+ re_printf("decode: bytes = %zu\n", bits/8); | |
+ re_printf(" left = %zu\n", len-4); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+ | |
int aac_decode_update(struct audec_state **adsp, const struct aucodec *ac, | |
const char *fmtp) | |
{ | |
@@ -45,13 +88,48 @@ int aac_decode_update(struct audec_state **adsp, const struct aucodec *ac, | |
if (!ads) | |
return ENOMEM; | |
- ads->dec = aacDecoder_Open(TT_MP4_LATM_MCP1, 1); | |
+ ads->dec = aacDecoder_Open(TT_MP4_RAW, 1); | |
if (!ads->dec) { | |
warning("aac: error opening decoder\n"); | |
err = ENOMEM; | |
goto out; | |
} | |
+ info("aac: decode update: fmtp='%s'\n", fmtp); | |
+ | |
+ struct pl config; | |
+ char config_str[64]; | |
+ uint8_t config_bin[4]; | |
+ | |
+ err = re_regex(fmtp, str_len(fmtp), "config=[0-9a-f]+", &config); | |
+ if (err) | |
+ goto out; | |
+ | |
+ err = pl_strcpy(&config, config_str, sizeof(config_str)); | |
+ if (err) | |
+ goto out; | |
+ | |
+ info("aac: config string = '%s'\n", config_str); | |
+ | |
+ err = str_hex(config_bin, sizeof(config_bin), config_str); | |
+ if (err) | |
+ goto out; | |
+ | |
+ info("aac: config binary = '%w'\n", config_bin, sizeof(config_bin)); | |
+ | |
+ UCHAR *conf = config_bin; | |
+ const UINT length = (UINT)sizeof(config_bin); | |
+ | |
+ AAC_DECODER_ERROR error; | |
+ | |
+ error = aacDecoder_ConfigRaw(ads->dec, &conf, &length); | |
+ if (error != AAC_DEC_OK) { | |
+ warning("aac: decode: config error: 0x%x\n", error); | |
+ err = EPROTO; | |
+ goto out; | |
+ } | |
+ | |
+ | |
out: | |
if (err) | |
mem_deref(ads); | |
@@ -66,14 +144,18 @@ int aac_decode_frm(struct audec_state *ads, | |
int fmt, void *sampv, size_t *sampc, | |
const uint8_t *buf, size_t len) | |
{ | |
- UCHAR *pBuffer = (UCHAR *)buf; | |
- UINT bufferSize = (UINT)len; | |
- UINT valid = (UINT)len; | |
+ UCHAR *pBuffer; | |
+ UINT bufferSize; | |
+ UINT valid; | |
AAC_DECODER_ERROR error; | |
size_t nsamp = 0; | |
unsigned i; | |
int16_t *s16 = sampv; | |
int size; | |
+ struct hdr hdr; | |
+ //unsigned bits; | |
+ size_t bytes; | |
+ int err = 0; | |
if (!ads || !sampv || !sampc || !buf) | |
return EINVAL; | |
@@ -81,6 +163,20 @@ int aac_decode_frm(struct audec_state *ads, | |
if (fmt != AUFMT_S16LE) | |
return ENOTSUP; | |
+ err = hdr_decode(&hdr, buf, len); | |
+ if (err) { | |
+ warning("aac: decode: invalid header, %zu bytes (%m)\n", | |
+ len, err); | |
+ return err; | |
+ } | |
+ | |
+ //bytes = hdr.bits / 8; | |
+ bytes = len - 4; | |
+ | |
+ pBuffer = (UCHAR *)&buf[4]; | |
+ bufferSize = (UINT)bytes; | |
+ valid = (UINT)bytes; | |
+ | |
error = aacDecoder_Fill(ads->dec, &pBuffer, &bufferSize, &valid); | |
if (error != AAC_DEC_OK) { | |
warning("aac: aacDecoder_Fill() failed: 0x%x\n", error); | |
@@ -89,13 +185,15 @@ int aac_decode_frm(struct audec_state *ads, | |
size = (int)*sampc; | |
- for (i=0; i<8; i++) { | |
+ for (i=0; i<2; i++) { | |
CStreamInfo *info; | |
error = aacDecoder_DecodeFrame(ads->dec, &s16[nsamp], size, 0); | |
- if (error == AAC_DEC_NOT_ENOUGH_BITS) | |
+ if (error == AAC_DEC_NOT_ENOUGH_BITS) { | |
+ //warning("not enought bits\n"); | |
break; | |
+ } | |
if (error != AAC_DEC_OK) { | |
warning("aac: aacDecoder_DecodeFrame() failed: 0x%x\n", | |
@@ -109,11 +207,17 @@ int aac_decode_frm(struct audec_state *ads, | |
return EBADMSG; | |
} | |
+ if (info->aot != AOT_ER_AAC_ELD) { | |
+ warning("aac: decode wrong aot %d\n", info->aot); | |
+ return EPROTO; | |
+ } | |
+#if 0 | |
if (info->sampleRate != AAC_SRATE) { | |
warning("aac: decode samplerate mismatch (%d != %d)\n", | |
info->sampleRate, AAC_SRATE); | |
return EPROTO; | |
} | |
+#endif | |
if (info->numChannels != AAC_CHANNELS) { | |
warning("aac: decode channels mismatch (%d != %d)\n", | |
info->numChannels, AAC_CHANNELS); | |
diff --git a/modules/aac/encode.c b/modules/aac/encode.c | |
index 6c64b0c..7d5454a 100644 | |
--- a/modules/aac/encode.c | |
+++ b/modules/aac/encode.c | |
@@ -4,6 +4,7 @@ | |
* Copyright (C) 2010 Creytiv.com | |
*/ | |
+#include <string.h> | |
#include <re.h> | |
#include <rem.h> | |
#include <baresip.h> | |
@@ -11,9 +12,9 @@ | |
#include "aac.h" | |
-enum { | |
- FRAME_SIZE = 480 | |
-}; | |
+//enum { | |
+ //FRAME_SIZE = 480 | |
+//}; | |
struct auenc_state { | |
@@ -30,10 +31,20 @@ static void destructor(void *arg) | |
} | |
+static void hdr_encode(uint8_t *p, size_t bits) | |
+{ | |
+ p[0] = 0x00; | |
+ p[1] = 0x10; | |
+ | |
+ *(uint16_t *)(void *)&p[2] = htons(bits); | |
+} | |
+ | |
+ | |
int aac_encode_update(struct auenc_state **aesp, const struct aucodec *ac, | |
struct auenc_param *param, const char *fmtp) | |
{ | |
struct auenc_state *aes; | |
+ AACENC_InfoStruct enc_info; | |
AACENC_ERROR error; | |
int err = 0; | |
@@ -59,21 +70,35 @@ int aac_encode_update(struct auenc_state **aesp, const struct aucodec *ac, | |
goto out; | |
} | |
- error |= aacEncoder_SetParam(aes->enc, AACENC_AOT, AOT_ER_AAC_LD); | |
- error |= aacEncoder_SetParam(aes->enc, AACENC_TRANSMUX, | |
- TT_MP4_LATM_MCP1); | |
+ error |= aacEncoder_SetParam(aes->enc, AACENC_AOT, AOT_ER_AAC_ELD); | |
error |= aacEncoder_SetParam(aes->enc, AACENC_SAMPLERATE, ac->srate); | |
error |= aacEncoder_SetParam(aes->enc, AACENC_CHANNELMODE, | |
AAC_CHANNELS); | |
- error |= aacEncoder_SetParam(aes->enc, AACENC_GRANULE_LENGTH, | |
- FRAME_SIZE); | |
- error |= aacEncoder_SetParam(aes->enc, AACENC_TPSUBFRAMES, 2); | |
error |= aacEncoder_SetParam(aes->enc, AACENC_BITRATE, AAC_BITRATE); | |
+ error |= aacEncoder_SetParam(aes->enc, AACENC_TRANSMUX, | |
+ TT_MP4_RAW); | |
+ error |= aacEncoder_SetParam(aes->enc, AACENC_GRANULE_LENGTH, | |
+ 480); | |
+ if (error != AACENC_OK) { | |
+ err = EINVAL; | |
+ goto out; | |
+ } | |
+ | |
+ if (aacEncEncode(aes->enc, NULL, NULL, NULL, NULL) != AACENC_OK) { | |
+ fprintf(stderr, "Unable to initialize the encoder\n"); | |
+ return 1; | |
+ } | |
+ | |
+ error = aacEncInfo(aes->enc, &enc_info); | |
if (error != AACENC_OK) { | |
+ warning("aac: encode: could not get info (0x%x)\n", error); | |
err = EINVAL; | |
goto out; | |
} | |
+ | |
+ info("aac: encoder config: %w\n", enc_info.confBuf, enc_info.confSize); | |
+ | |
*aesp = aes; | |
out: | |
@@ -96,6 +121,7 @@ int aac_encode_frm(struct auenc_state *aes, uint8_t *buf, size_t *len, | |
const int16_t *s16 = sampv; | |
size_t total = 0; | |
size_t i; | |
+ size_t bits; | |
if (!aes || !buf || !len || !sampv) | |
return EINVAL; | |
@@ -103,9 +129,16 @@ int aac_encode_frm(struct auenc_state *aes, uint8_t *buf, size_t *len, | |
if (fmt != AUFMT_S16LE) | |
return ENOTSUP; | |
- for (i=0; i<sampc; i+=FRAME_SIZE) { | |
+#if 0 | |
+ *len = 0; | |
+ return 0; | |
+#endif | |
+ | |
+ uint8_t *payload = buf + 4; | |
+ | |
+ for (i=0; i<2; i++) { | |
- in_size = sizeof(int16_t) * FRAME_SIZE; | |
+ in_size = sizeof(int16_t) * (UINT)sampc; | |
in_buf.numBufs = 1; | |
in_buf.bufs = (void **)&s16; | |
@@ -116,12 +149,12 @@ int aac_encode_frm(struct auenc_state *aes, uint8_t *buf, size_t *len, | |
out_size = (INT)*len; | |
out_buf.numBufs = 1; | |
- out_buf.bufs = (void **)&buf; | |
+ out_buf.bufs = (void **)&(payload); | |
out_buf.bufferIdentifiers = &out_id; | |
out_buf.bufSizes = &out_size; | |
out_buf.bufElSizes = &out_elem_size; | |
- in_args.numInSamples = FRAME_SIZE; | |
+ in_args.numInSamples = (UINT)sampc; | |
in_args.numAncBytes = 0; | |
error = aacEncEncode(aes->enc, &in_buf, &out_buf, &in_args, | |
@@ -131,13 +164,30 @@ int aac_encode_frm(struct auenc_state *aes, uint8_t *buf, size_t *len, | |
return EINVAL; | |
} | |
- s16 += FRAME_SIZE; | |
+ s16 += out_args.numInSamples; | |
+ sampc -= out_args.numInSamples; | |
- buf += out_args.numOutBytes; | |
- total += out_args.numOutBytes; | |
+ payload += out_args.numOutBytes; | |
+ total += out_args.numOutBytes; | |
+ | |
+ re_printf(".... numInSamples: %d\n", out_args.numInSamples); | |
+ re_printf(" numOutBytes: %d\n", out_args.numOutBytes); | |
+ | |
+ if (sampc == 0) | |
+ break; | |
+ } | |
+ | |
+ if (total == 0) { | |
+ *len = 0; | |
+ return 0; | |
} | |
- *len = total; | |
+ bits = total * 8; | |
+ | |
+ hdr_encode(buf, bits); | |
+ | |
+ | |
+ *len = 4 + total; | |
return 0; | |
} | |
diff --git a/modules/aac/sdp.c b/modules/aac/sdp.c | |
index 60613f2..357e930 100644 | |
--- a/modules/aac/sdp.c | |
+++ b/modules/aac/sdp.c | |
@@ -10,6 +10,12 @@ | |
#include "aac.h" | |
+enum { | |
+ STREAMTYPE_AUDIO = 0x05, | |
+ PROFILE = 76, | |
+}; | |
+ | |
+ | |
static unsigned param_value(const char *fmtp, const char *name) | |
{ | |
struct pl pl, val; | |
@@ -29,6 +35,8 @@ static unsigned param_value(const char *fmtp, const char *name) | |
int aac_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt, | |
bool offer, void *arg) | |
{ | |
+ const char *config = "F8EE2000"; | |
+ | |
(void)offer; | |
(void)arg; | |
@@ -36,8 +44,14 @@ int aac_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt, | |
return 0; | |
return mbuf_printf(mb, "a=fmtp:%s " | |
- "profile-level-id=24;object=%i;bitrate=%u\r\n", | |
- fmt->id, AOT_ER_AAC_LD, AAC_BITRATE); | |
+ | |
+ "streamType=%d" | |
+ ";profile-level-id=%d" | |
+ ";config=%s" | |
+ ";mode=AAC-hbr" | |
+ | |
+ "\r\n", | |
+ fmt->id, STREAMTYPE_AUDIO, PROFILE, config); | |
} | |
@@ -46,11 +60,20 @@ bool aac_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *arg) | |
(void)lfmtp; | |
(void)arg; | |
+ info("aac: compare: %s\n", rfmtp); | |
+ | |
+#if 0 | |
if (param_value(rfmtp, "object") != AOT_ER_AAC_LD) | |
return false; | |
if (param_value(rfmtp, "bitrate") != AAC_BITRATE) | |
return false; | |
+#endif | |
return true; | |
} | |
+ | |
+ | |
+/* | |
+a=fmtp:96 config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5. | |
+ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment