diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-11-24 00:27:14 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2016-12-06 17:51:47 +0000 |
commit | f5e22a14877922aa7b907d2e434958c86efd6875 (patch) | |
tree | 33439d1a8cd3322faa9ce8b0f6b12a08427d47fb /codecs/G726/G726decode.c | |
parent | d8cdb550445a1bc86626bd9d45da1ce958d1592b (diff) |
codecs: Add support for G.722 and G.726
Integrate the Spandsp library for G.722 and G.726 support. Adds support
for G.722 and all eight variants of G.726.
Note: this also fixes a crash in Qt (buffer overrun, reading too much
data) caused by confusion of the larger output buffer (resample_buff)
with the smaller input buffer (decode_buff). It was not triggered before
because the sample rate was always 8k, but with the addition of the new
codecs, a different sample rate became possible (16k).
Fix also a crash which occurs when the RTP_STREAM_DEBUG macro is enabled
and the VOIP Calls dialog is opened (the begin frame, start_fd, is not
yet known and therfore a NULL dereference could occur).
Passes testing (plays normally without bad RTP timing errors) with
SampleCaptures files: sip-rtp-g722.pcap and sip-rtp-g726.pcap. Tested
with cmake (Qt), autotools (Qt and GTK+) with ASAN enabled.
Bug: 5619
Change-Id: I5661908d193927bba50901079119eeff0c04991f
Reviewed-on: https://code.wireshark.org/review/18939
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'codecs/G726/G726decode.c')
-rw-r--r-- | codecs/G726/G726decode.c | 86 |
1 files changed, 61 insertions, 25 deletions
diff --git a/codecs/G726/G726decode.c b/codecs/G726/G726decode.c index e454be5ac8..cb157d6c46 100644 --- a/codecs/G726/G726decode.c +++ b/codecs/G726/G726decode.c @@ -24,53 +24,89 @@ #include <glib.h> #ifdef HAVE_SPANDSP -#include "telephony.h" -#include "bitstream.h" -#include "g726.h" +#include "spandsp.h" #include "G726decode.h" -/* this isn't reentrant. Making it might involve quite a few changes to be able to pass a g726 state - * variable to the various functions involved in G.726 decoding. - */ -static g726_state_t state; +typedef struct _g726_codec_ctx { + g726_state_t *state; + int bit_rate; +} g726_codec_ctx; -/* Currently, only G.726-32, linear encoding, left packed is supported */ -void * -codec_g726_init(void) +static inline void * +codec_g726_init(int bit_rate, int packing) { - memset (&state, 0, sizeof (state)); - g726_init(&state, 32000, 0, 1); + g726_state_t *decoder = g726_init(NULL, bit_rate, G726_ENCODING_LINEAR, packing); + + if (!decoder) { + return NULL; /* out-of-memory; */ + } + + g726_codec_ctx *state = g_new(g726_codec_ctx, 1); + state->state = decoder; + state->bit_rate = bit_rate; - return NULL; + return state; } +void *codec_g726_16_init(void) { return codec_g726_init(16000, G726_PACKING_RIGHT); } +void *codec_g726_24_init(void) { return codec_g726_init(24000, G726_PACKING_RIGHT); } +void *codec_g726_32_init(void) { return codec_g726_init(32000, G726_PACKING_RIGHT); } +void *codec_g726_40_init(void) { return codec_g726_init(40000, G726_PACKING_RIGHT); } +void *codec_aal2_g726_16_init(void) { return codec_g726_init(16000, G726_PACKING_LEFT); } +void *codec_aal2_g726_24_init(void) { return codec_g726_init(24000, G726_PACKING_LEFT); } +void *codec_aal2_g726_32_init(void) { return codec_g726_init(32000, G726_PACKING_LEFT); } +void *codec_aal2_g726_40_init(void) { return codec_g726_init(40000, G726_PACKING_LEFT); } + void -codec_g726_release(void *ctx _U_) +codec_g726_release(void *ctx) { + g726_codec_ctx *state = (g726_codec_ctx *)ctx; + + if (!state) { + return; /* out-of-memory; */ + } + /* Note: replaces g726_release since spandsp 20090211 */ + g726_free(state->state); + g_free(state); } -int +unsigned codec_g726_get_channels(void *ctx _U_) { return 1; } -int +unsigned codec_g726_get_frequency(void *ctx _U_) { - return 32000; + return 8000; } -/* Packing should be user defined (via the decode dialog) since due to historical reasons two diverging - * de facto standards are in use today (see RFC3551). - */ -int -codec_g726_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output, - int *outputSizeBytes) +size_t +codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output, + size_t *outputSizeBytes) { - *outputSizeBytes = 2 * g726_decode(&state, output, (void*) input, inputSizeBytes); - return 0; + g726_codec_ctx *state = (g726_codec_ctx *)ctx; + + if (!state) { + return 0; /* out-of-memory; */ + } + + if (!output || !outputSizeBytes) { + /* + * sample rate 8kHz, for bitrate 16kHz we have 16/8 = 2 bits/sample, so + * 1 input byte (8 bits) will expand to four 16-bit samples. Likewise, + * for bitrate 40kHz we have 40/8 = 5 bits/sample. Alternatively: + * bitsPerSample = bitRate / sampleRate (8kHz). + * outputBytes = (inputBits / bitsPerSample) * sizeof(sample) + */ + return inputSizeBytes * 8 / (state->bit_rate / 8000) * 2; + } + + /* g726_decode returns the number of 16-bit samples. */ + *outputSizeBytes = 2 * g726_decode(state->state, (int16_t *)output, (const uint8_t *) input, (int)inputSizeBytes); + return *outputSizeBytes; } #endif |