summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2017-07-27 22:02:04 -0700
committerjsorg71 <jay.sorg@gmail.com>2017-08-04 17:24:57 -0700
commitbf0d56c3141e3b177020ecd78d449f46555154ec (patch)
tree2aa708b94c488eae1bf5425edce09d11cf39c1e0 /sesman/chansrv
parent8ac35d7ed10dab5f194821919943eeca1e8fcb8a (diff)
downloadxrdp-proprietary-bf0d56c3141e3b177020ecd78d449f46555154ec.tar.gz
xrdp-proprietary-bf0d56c3141e3b177020ecd78d449f46555154ec.zip
chansrv: sound, add aac
Diffstat (limited to 'sesman/chansrv')
-rw-r--r--sesman/chansrv/Makefile.am5
-rw-r--r--sesman/chansrv/sound.c243
2 files changed, 246 insertions, 2 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 1df6c762..1e72b4ef 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -23,6 +23,11 @@ AM_CPPFLAGS += -DXRDP_FUSE $(FUSE_CFLAGS)
CHANSRV_EXTRA_LIBS += $(FUSE_LIBS)
endif
+if XRDP_FDK_AAC
+AM_CPPFLAGS += -DXRDP_FDK_AAC
+CHANSRV_EXTRA_LIBS += -lfdk-aac
+endif
+
if XRDP_OPUS
AM_CPPFLAGS += -DXRDP_OPUS
CHANSRV_EXTRA_LIBS += -lopus
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index e9fcb067..5a0db94b 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -35,6 +35,11 @@
#include "xrdp_sockets.h"
#include "chansrv_common.h"
+#if defined(XRDP_FDK_AAC)
+#include <fdk-aac/aacenc_lib.h>
+static HANDLE_AACENCODER g_fdk_aac_encoder = 0;
+#endif
+
#if defined(XRDP_OPUS)
#include <opus/opus.h>
static OpusEncoder *g_opus_encoder = 0;
@@ -114,6 +119,21 @@ static struct xr_wave_format_ex g_pcm_44100 =
g_pcm_44100_data /* data */
};
+#if defined(XRDP_FDK_AAC)
+static tui8 g_fdk_aac_44100_data[] = { 0 };
+static struct xr_wave_format_ex g_fdk_aac_44100 =
+{
+ WAVE_FORMAT_AAC_MS, /* wFormatTag */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 12000, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_fdk_aac_44100_data /* data */
+};
+#endif
+
#if defined(XRDP_OPUS)
static tui8 g_opus_44100_data[] = { 0 };
static struct xr_wave_format_ex g_opus_44100 =
@@ -148,6 +168,9 @@ static struct xr_wave_format_ex *g_wave_outp_formats[] =
{
&g_pcm_44100,
&g_pcm_22050,
+#if defined(XRDP_FDK_AAC)
+ &g_fdk_aac_44100,
+#endif
#if defined(XRDP_OPUS)
&g_opus_44100,
#endif
@@ -157,6 +180,9 @@ static struct xr_wave_format_ex *g_wave_outp_formats[] =
0
};
+static int g_client_does_fdk_aac = 0;
+static int g_client_fdk_aac_index = 0;
+
static int g_client_does_opus = 0;
static int g_client_opus_index = 0;
@@ -187,7 +213,7 @@ static struct xr_wave_format_ex g_pcm_inp_22050 =
static tui8 g_pcm_inp_44100_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_inp_44100 =
{
- 1, /* wFormatTag */
+ WAVE_FORMAT_PCM, /* wFormatTag */
2, /* num of channels */
44100, /* samples per sec */
176400, /* avg bytes per sec */
@@ -370,6 +396,12 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
switch(wFormatTag)
{
+ case WAVE_FORMAT_AAC_MS:
+ LOG(0, ("wFormatTag, fdk aac"));
+ g_client_does_fdk_aac = 1;
+ g_client_fdk_aac_index = aindex;
+ g_bbuf_size = 4096;
+ break;
case WAVE_FORMAT_MPEGLAYER3:
LOG(0, ("wFormatTag, mp3"));
g_client_does_mp3lame = 1;
@@ -437,6 +469,206 @@ sound_process_output_formats(struct stream *s, int size)
return 0;
}
+#if defined(XRDP_FDK_AAC)
+
+/*****************************************************************************/
+static int
+sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
+{
+ int rv;
+ int cdata_bytes;
+ char *cdata;
+
+ AACENC_ERROR error;
+ int aot;
+ int sample_rate;
+ int mode;
+ int bitrate;
+ int afterburner;
+ int channel_order;
+ AACENC_InfoStruct info = { 0 };
+ AACENC_BufDesc in_buf = { 0 };
+ AACENC_BufDesc out_buf = { 0 };
+ AACENC_InArgs in_args = { 0 };
+ AACENC_OutArgs out_args = { 0 };
+ void *in_buffer[1];
+ int in_identifier[1];
+ int in_size[1];
+ int in_elem_size[1];
+ void *out_buffer[1];
+ int out_identifier[1];
+ int out_size[1];
+ int out_elem_size[1];
+
+ rv = data_bytes;
+
+ if (g_client_does_fdk_aac == 0)
+ {
+ return rv;
+ }
+
+ if (g_fdk_aac_encoder == 0)
+ {
+ /* init fdk aac encoder */
+ LOG(0, ("sound_wave_compress_fdk_aac: using fdk aac"));
+
+ error = aacEncOpen(&g_fdk_aac_encoder, 0, 2);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncOpen() failed"));
+ return rv;
+ }
+
+ aot = 2; /* MPEG-4 AAC Low Complexity. */
+ //aot = 129; /* MPEG-2 AAC Low Complexity. */
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_AOT, aot);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_AOT failed"));
+ }
+
+ sample_rate = g_fdk_aac_44100.nSamplesPerSec;
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_SAMPLERATE,
+ sample_rate);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_SAMPLERATE failed"));
+ }
+
+ mode = MODE_2;
+ error = aacEncoder_SetParam(g_fdk_aac_encoder,
+ AACENC_CHANNELMODE, mode);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_CHANNELMODE failed"));
+ }
+
+ channel_order = 1; /* WAVE file format channel ordering */
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_CHANNELORDER,
+ channel_order);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_CHANNELORDER failed"));
+ }
+
+ /* bytes rate to bit rate */
+ bitrate = g_fdk_aac_44100.nAvgBytesPerSec * 8;
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_BITRATE,
+ bitrate);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_BITRATE failed"));
+ }
+
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_TRANSMUX, 0);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_TRANSMUX failed"));
+ }
+
+ afterburner = 1;
+ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_AFTERBURNER,
+ afterburner);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
+ "AACENC_AFTERBURNER failed"));
+ }
+
+ error = aacEncEncode(g_fdk_aac_encoder, NULL, NULL, NULL, NULL);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: Unable to initialize "
+ "the encoder"));
+ }
+
+ error = aacEncInfo(g_fdk_aac_encoder, &info);
+ if (error != AACENC_OK)
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncInfo failed"));
+ }
+
+ LOG(0, ("sound_wave_compress_fdk_aac:"));
+ LOG(0, (" AACENC_InfoStruct"));
+ LOG(0, (" maxOutBufBytes %d", info.maxOutBufBytes));
+ LOG(0, (" maxAncBytes %d", info.maxAncBytes));
+ LOG(0, (" inBufFillLevel %d", info.inBufFillLevel));
+ LOG(0, (" inputChannels %d", info.inputChannels));
+ LOG(0, (" frameLength %d", info.frameLength));
+ LOG(0, (" encoderDelay %d", info.encoderDelay));
+ LOG(0, (" confBuf"));
+ LOG(0, (" confSize %d", info.confSize));
+ }
+
+ rv = data_bytes;
+ cdata_bytes = data_bytes;
+ cdata = (char *) g_malloc(cdata_bytes, 0);
+ if (data_bytes < g_bbuf_size)
+ {
+ g_memset(data + data_bytes, 0, g_bbuf_size - data_bytes);
+ data_bytes = g_bbuf_size;
+ }
+
+ in_buffer[0] = data;
+ in_identifier[0] = IN_AUDIO_DATA;
+ in_size[0] = data_bytes;
+ in_elem_size[0] = 2;
+
+ in_args.numInSamples = data_bytes / 2;
+ in_buf.numBufs = 1;
+ in_buf.bufs = in_buffer;
+ in_buf.bufferIdentifiers = in_identifier;
+ in_buf.bufSizes = in_size;
+ in_buf.bufElSizes = in_elem_size;
+
+ out_buffer[0] = cdata;
+ out_identifier[0] = OUT_BITSTREAM_DATA;
+ out_size[0] = cdata_bytes;
+ out_elem_size[0] = 1;
+
+ out_buf.numBufs = 1;
+ out_buf.bufs = out_buffer;
+ out_buf.bufferIdentifiers = out_identifier;
+ out_buf.bufSizes = out_size;
+ out_buf.bufElSizes = out_elem_size;
+
+ error = aacEncEncode(g_fdk_aac_encoder, &in_buf, &out_buf,
+ &in_args, &out_args);
+ if (error == AACENC_OK)
+ {
+ cdata_bytes = out_args.numOutBytes;
+ LOG(10, ("sound_wave_compress_fdk_aac: aacEncEncode ok "
+ "cdata_bytes %d", cdata_bytes));
+ *format_index = g_client_fdk_aac_index;
+ g_memcpy(data, cdata, cdata_bytes);
+ rv = cdata_bytes;
+ }
+ else
+ {
+ LOG(0, ("sound_wave_compress_fdk_aac: aacEncEncode failed"));
+ }
+ g_free(cdata);
+
+ return rv;
+}
+
+#else
+
+/*****************************************************************************/
+static int
+sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
+{
+ return data_bytes;
+}
+
+#endif
+
#if defined(XRDP_OPUS)
/*****************************************************************************/
@@ -602,7 +834,11 @@ sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
static int
sound_wave_compress(char *data, int data_bytes, int *format_index)
{
- if (g_client_does_opus)
+ if (g_client_does_fdk_aac)
+ {
+ return sound_wave_compress_fdk_aac(data, data_bytes, format_index);
+ }
+ else if (g_client_does_opus)
{
return sound_wave_compress_opus(data, data_bytes, format_index);
}
@@ -982,6 +1218,9 @@ sound_init(void)
/* save data from sound_server_source */
fifo_init(&g_in_fifo, 100);
+ g_client_does_fdk_aac = 0;
+ g_client_fdk_aac_index = 0;
+
g_client_does_opus = 0;
g_client_opus_index = 0;