chansrv: sound, add aac
This commit is contained in:
parent
8ac35d7ed1
commit
bf0d56c314
@ -401,6 +401,7 @@
|
||||
#define WAVE_FORMAT_MULAW 0x0007
|
||||
#define WAVE_FORMAT_MPEGLAYER3 0x0055
|
||||
#define WAVE_FORMAT_OPUS 0x0069
|
||||
#define WAVE_FORMAT_AAC_MS 0xA106
|
||||
|
||||
/* Virtual channel options */
|
||||
#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
|
||||
|
11
configure.ac
11
configure.ac
@ -116,6 +116,10 @@ AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr],
|
||||
[Build xrdpvr module (default: no)]),
|
||||
[], [enable_xrdpvr=no])
|
||||
AM_CONDITIONAL(XRDP_XRDPVR, [test x$enable_xrdpvr = xyes])
|
||||
AC_ARG_ENABLE(fdkaac, AS_HELP_STRING([--enable-fdkaac],
|
||||
[Build aac(audio codec) (default: no)]),
|
||||
[], [enable_fdkaac=no])
|
||||
AM_CONDITIONAL(XRDP_FDK_AAC, [test x$enable_fdkaac = xyes])
|
||||
AC_ARG_ENABLE(opus, AS_HELP_STRING([--enable-opus],
|
||||
[Build opus(audio codec) (default: no)]),
|
||||
[], [enable_opus=no])
|
||||
@ -230,6 +234,13 @@ then
|
||||
[AC_MSG_ERROR([please install libfuse-dev or fuse-devel])])
|
||||
fi
|
||||
|
||||
# checking for fdk aac
|
||||
if test "x$enable_fdkaac" = "xyes"
|
||||
then
|
||||
AC_CHECK_HEADER([fdk-aac/aacenc_lib.h], [],
|
||||
[AC_MSG_ERROR([please install libfdk-aac-dev or dontknow-devel])])
|
||||
fi
|
||||
|
||||
# checking for opus
|
||||
if test "x$enable_opus" = "xyes"
|
||||
then
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user