codecs API: Added description of API usage

Added API description clarifies when bytes/samples are used. New variable names
proposed and all existing codecs are adapted to it. Change is just renaming...

Change-Id: I75dba64a49eb3f4369ec7160cb793dda4b44c810
Reviewed-on: https://code.wireshark.org/review/35576
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Pascal Quantin <pascal@wireshark.org>
This commit is contained in:
Jirka Novak 2019-12-28 19:58:28 +01:00 committed by Pascal Quantin
parent cff06caa1e
commit 8a3572997f
7 changed files with 114 additions and 53 deletions

View File

@ -110,24 +110,24 @@ codec_g711u_get_frequency(void *ctx _U_)
}
static size_t
codec_g711u_decode(void *ctx _U_, const void *input, size_t inputSizeBytes, void *output,
size_t *outputSizeBytes)
codec_g711u_decode(void *ctx _U_, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
const guint8 *dataIn = (const guint8 *) input;
gint16 *dataOut = (gint16 *) output;
const guint8 *dataIn = (const guint8 *) inputBytes;
gint16 *dataOut = (gint16 *) outputSamples;
size_t i;
if (!output || !outputSizeBytes) {
return inputSizeBytes * 2;
if (!outputSamples || !outputSamplesSize) {
return inputBytesSize * 2;
}
for (i = 0; i < inputSizeBytes; i++)
for (i = 0; i < inputBytesSize; i++)
{
dataOut[i] = ulaw_exp_table[dataIn[i]];
}
*outputSizeBytes = inputSizeBytes * 2;
return inputSizeBytes * 2;
*outputSamplesSize = inputBytesSize * 2;
return inputBytesSize * 2;
}
static void *
@ -155,24 +155,24 @@ codec_g711a_get_frequency(void *ctx _U_)
}
static size_t
codec_g711a_decode(void *ctx _U_, const void *input, size_t inputSizeBytes, void *output,
size_t *outputSizeBytes)
codec_g711a_decode(void *ctx _U_, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
const guint8 *dataIn = (const guint8 *) input;
gint16 *dataOut = (gint16 *) output;
const guint8 *dataIn = (const guint8 *) inputBytes;
gint16 *dataOut = (gint16 *) outputSamples;
size_t i;
if (!output || !outputSizeBytes) {
return inputSizeBytes * 2;
if (!outputSamples || !outputSamplesSize) {
return inputBytesSize * 2;
}
for (i = 0; i < inputSizeBytes; i++)
for (i = 0; i < inputBytesSize; i++)
{
dataOut[i] = alaw_exp_table[dataIn[i]];
}
*outputSizeBytes = inputSizeBytes * 2;
return inputSizeBytes * 2;
*outputSamplesSize = inputBytesSize * 2;
return inputBytesSize * 2;
}
void

View File

@ -57,8 +57,8 @@ codec_g722_get_frequency(void *ctx _U_)
}
static size_t
codec_g722_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
size_t *outputSizeBytes)
codec_g722_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
g722_decode_state_t *state = (g722_decode_state_t *)ctx;
@ -66,13 +66,14 @@ codec_g722_decode(void *ctx, const void *input, size_t inputSizeBytes, void *out
return 0; /* out-of-memory; */
}
if (!output || !outputSizeBytes) {
return 4 * inputSizeBytes;
if (!outputSamples || !outputSamplesSize) {
return 4 * inputBytesSize;
}
/* g722_decode returns the number of 16-bit samples. */
*outputSizeBytes = 2 * g722_decode(state, (int16_t *)output, (const uint8_t *)input, (int)inputSizeBytes);
return *outputSizeBytes;
*outputSamplesSize = 2 * g722_decode(state, (int16_t *)outputSamples,
(const uint8_t *)inputBytes, (int)inputBytesSize);
return *outputSamplesSize;
}
void

View File

@ -73,8 +73,8 @@ codec_g726_get_frequency(void *ctx _U_)
}
static size_t
codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
size_t *outputSizeBytes)
codec_g726_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
g726_codec_ctx *state = (g726_codec_ctx *)ctx;
@ -82,7 +82,7 @@ codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *out
return 0; /* out-of-memory; */
}
if (!output || !outputSizeBytes) {
if (!outputSamples || !outputSamplesSize) {
/*
* 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,
@ -90,12 +90,12 @@ codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *out
* bitsPerSample = bitRate / sampleRate (8kHz).
* outputBytes = (inputBits / bitsPerSample) * sizeof(sample)
*/
return inputSizeBytes * 8 / (state->bit_rate / 8000) * 2;
return inputBytesSize * 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;
*outputSamplesSize = 2 * g726_decode(state->state, (int16_t *)outputSamples, (const uint8_t *) inputBytes, (int)inputBytesSize);
return *outputSamplesSize;
}
void

View File

@ -41,27 +41,27 @@ codec_g729_get_frequency(void *ctx _U_)
}
static size_t
codec_g729_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
size_t *outputSizeBytes)
codec_g729_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
bcg729DecoderChannelContextStruct *state = (bcg729DecoderChannelContextStruct *)ctx;
const guint8 *dataIn = (const guint8 *) input;
gint16 *dataOut = (gint16 *) output;
const guint8 *dataIn = (const guint8 *) inputBytes;
gint16 *dataOut = (gint16 *) outputSamples;
size_t i;
if (!ctx) {
return 0;
}
if (!output || !outputSizeBytes) {
return 80*2*(inputSizeBytes/10);
if (!outputSamples || !outputSamplesSize) {
return 80*2*(inputBytesSize/10);
}
/* The G729 algorithm encodes 10ms of voice into 80bit (10 bytes).
Based on the RTP packetization period (usually 20ms), we need to
pass to the bcg729 decoder chunks of 10ms (10 bytes)
*/
for (i = 0; i < (inputSizeBytes/10); i++) {
for (i = 0; i < (inputBytesSize/10); i++) {
/* The bcg729 decoder library fails to declare the second
argument to bcg729Decoder() to be a const pointer. If you
fix it, and some other functions, to use const, the library
@ -72,8 +72,8 @@ codec_g729_decode(void *ctx, const void *input, size_t inputSizeBytes, void *out
*/
bcg729Decoder(state, (guint8 *)dataIn + i*10, 10, 0, 0, 0, dataOut + i*80);
}
*outputSizeBytes = 80*2*(inputSizeBytes/10);
return *outputSizeBytes;
*outputSamplesSize = 80*2*(inputBytesSize/10);
return *outputSamplesSize;
}
void

View File

@ -43,25 +43,25 @@ codec_l16_get_frequency(void *ctx _U_)
}
static size_t
codec_l16_decode(void *ctx _U_, const void *input, size_t inputSizeBytes,
void *output, size_t *outputSizeBytes)
codec_l16_decode(void *ctx _U_, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
const guint16 *dataIn = (const guint16 *)input;
guint16 *dataOut = (guint16 *)output;
const guint16 *dataIn = (const guint16 *)inputBytes;
guint16 *dataOut = (guint16 *)outputSamples;
size_t i;
if (!output || !outputSizeBytes)
if (!outputSamples || !outputSamplesSize)
{
return inputSizeBytes;
return inputBytesSize;
}
for (i=0; i<inputSizeBytes/2; i++)
for (i=0; i<inputBytesSize/2; i++)
{
dataOut[i] = g_ntohs(dataIn[i]);
}
*outputSizeBytes = inputSizeBytes;
return *outputSizeBytes;
*outputSamplesSize = inputBytesSize;
return *outputSamplesSize;
}
void

View File

@ -88,7 +88,7 @@ decode_rtp_packet_payload(guint8 payload_type, const gchar *payload_type_str, gu
/****************************************************************************/
/*
* Return the number of decoded bytes
* @return Number of decoded bytes
*/
size_t

View File

@ -45,12 +45,71 @@ WS_DLL_PUBLIC void codec_get_compiled_version_info(GString *str);
struct codec_handle;
typedef struct codec_handle *codec_handle_t;
/*****************************************************************************/
/* Interface which must be implemented by a codec */
/* Codec decodes bytes to samples. Sample is 2 bytes! Codec writer must
* be careful when API refers bytes and when samples and its counts.
*/
/*****************************************************************************/
/** Initialize context of codec.
* Context can contain any information required by codec to pass between calls
* Note: There is just one codec context in runtime therefore no RTP stream
* related information should be stored in the context!
*
* @return Pointer to codec context
*/
typedef void *(*codec_init_fn)(void);
/** Destroy context of codec
*
* @param context Pointer to codec context
*/
typedef void (*codec_release_fn)(void *context);
/** Get count of channels provided by the codec
*
* @param context Pointer to codec context
*
* @return Count of channels (e.g. 1)
*/
typedef unsigned (*codec_get_channels_fn)(void *context);
/** Get frequency/rate provided by the codec
*
* @param context Pointer to codec context
*
* @return Frequency (e.g. 8000)
*/
typedef unsigned (*codec_get_frequency_fn)(void *context);
typedef size_t (*codec_decode_fn)(void *context, const void *input, size_t inputSizeBytes,
void *output, size_t *outputSizeBytes);
/** Decode one frame of payload
* Function is called twice, with different values of parameters:
* (1) To query size of required buffer in bytes for decoded samples
* pointed by inputBytes:
* outputSamples or outputSamplesSize must be set NULL
* (2) To decode samples:
* outputSamples points to allocated memory, outputSamplesSize is set to
* value returned in step (1)
*
* @param context Pointer to codec context
* @param inputBytes Pointer to input frame
* @param inputBytesSize Length of input frame in bytes
* (count of bytes to decode)
* @param outputSamples Pointer to output buffer with samples
* @param outputSamplesSize Length of output buffer in bytes (not samples!)
* Function can override this value. All codecs set it to same value as it returns in (2) when (2) is called.
*
* @return Count of reqired bytes (!not samples) to allocate in (1) or
* Count of decoded bytes (!not samples) in (2)
*/
typedef size_t (*codec_decode_fn)(void *context,
const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize);
/*****************************************************************************/
/* Codec registering interface */
/*****************************************************************************/
WS_DLL_PUBLIC gboolean register_codec(const char *name, codec_init_fn init_fn,
codec_release_fn release_fn, codec_get_channels_fn channels_fn,
@ -61,8 +120,9 @@ WS_DLL_PUBLIC void *codec_init(codec_handle_t codec);
WS_DLL_PUBLIC void codec_release(codec_handle_t codec, void *context);
WS_DLL_PUBLIC unsigned codec_get_channels(codec_handle_t codec, void *context);
WS_DLL_PUBLIC unsigned codec_get_frequency(codec_handle_t codec, void *context);
WS_DLL_PUBLIC size_t codec_decode(codec_handle_t codec, void *context, const void *input,
size_t inputSizeBytes, void *output, size_t *outputSizeBytes);
WS_DLL_PUBLIC size_t codec_decode(codec_handle_t codec, void *context,
const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize);
#ifdef __cplusplus
}