1 /* iLBCdecode.c
2 * iLBC codec
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "config.h"
12
13 #include <stdio.h>
14
15 #include <glib.h>
16
17 #include "ilbc.h"
18 #include "wsutil/codecs.h"
19 #include "ws_attributes.h"
20
21 #define ILBC_20MS 20
22 #define ILBC_30MS 30
23 #define ILBC_PAYLOAD_LEN_20MS 38
24 #define ILBC_PAYLOAD_LEN_30MS 50
25 #define SAMPLE_SIZE 2
26
27 typedef struct {
28 #ifdef LIBILBC_VERSION_MAJOR
29 IlbcDecoderInstance *ilbc_ctx; /* Real iLBC context */
30 #else
31 iLBC_decinst_t *ilbc_ctx; /* Real iLBC context */
32 #endif
33 guint8 payload_len; /* Remember last payload_len */
34 } ilbc_ctx_t;
35
36 void codec_register_iLBC(void);
37
38 static void *
codec_iLBC_init(void)39 codec_iLBC_init(void)
40 {
41 ilbc_ctx_t *ctx;
42
43 ctx=(ilbc_ctx_t *)g_malloc0(sizeof(*ctx));
44 WebRtcIlbcfix_DecoderCreate(&(ctx->ilbc_ctx));
45
46 return ctx;
47 }
48
49 static void
codec_iLBC_release(void * ctx)50 codec_iLBC_release(void *ctx)
51 {
52 WebRtcIlbcfix_DecoderFree(((ilbc_ctx_t *)ctx)->ilbc_ctx);
53 g_free(ctx);
54 }
55
56 static unsigned
codec_iLBC_get_channels(void * ctx _U_)57 codec_iLBC_get_channels(void *ctx _U_)
58 {
59 return 1;
60 }
61
62 static unsigned
codec_iLBC_get_frequency(void * ctx _U_)63 codec_iLBC_get_frequency(void *ctx _U_)
64 {
65 return 8000;
66 }
67
68 static size_t
codec_iLBC_decode(void * ctx,const void * inputBytes,size_t inputBytesSize,void * outputSamples,size_t * outputSamplesSize)69 codec_iLBC_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
70 void *outputSamples, size_t *outputSamplesSize)
71 {
72 int16_t speechType; // Not used in Wireshark code
73 #ifdef LIBILBC_VERSION_MAJOR
74 int8_t *dataIn = (int8_t *)inputBytes;
75 #else
76 int16_t *dataIn = (int16_t *)inputBytes;
77 #endif
78 int16_t *dataOut = (int16_t *)outputSamples;
79 ilbc_ctx_t *dataCtx = (ilbc_ctx_t *)ctx;
80 size_t outputSamplesCount;
81
82 if (!outputSamples || !outputSamplesSize)
83 {
84 if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_20MS) {
85 /* 20ms packet size = 160 samples = 320 bytes */
86 return BLOCKL_20MS*SAMPLE_SIZE;
87 } else if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_30MS) {
88 /* 30ms packet size = 240 samples = 480 bytes */
89 return BLOCKL_30MS*SAMPLE_SIZE;
90 } else {
91 /* unknown packet size */
92 return 0;
93 }
94 }
95
96 if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_20MS) {
97 /* 20ms packet size */
98 if (dataCtx->payload_len != ILBC_20MS) {
99 WebRtcIlbcfix_DecoderInit(dataCtx->ilbc_ctx, ILBC_20MS);
100 dataCtx->payload_len = ILBC_20MS;
101 }
102 outputSamplesCount = WebRtcIlbcfix_Decode(dataCtx->ilbc_ctx, dataIn,
103 (int16_t)inputBytesSize, dataOut, &speechType);
104 } else if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_30MS) {
105 /* 30ms packet size */
106 if (dataCtx->payload_len != ILBC_30MS) {
107 WebRtcIlbcfix_DecoderInit(dataCtx->ilbc_ctx, ILBC_30MS);
108 dataCtx->payload_len = ILBC_30MS;
109 }
110 outputSamplesCount = WebRtcIlbcfix_Decode(dataCtx->ilbc_ctx, dataIn,
111 (int16_t)inputBytesSize, dataOut, &speechType);
112 } else {
113 /* unknown packet size */
114 outputSamplesCount = 0;
115 }
116
117 /* WebRtcIlbcfix_Decode returns count of samples, but we return count of bytes */
118 *outputSamplesSize = outputSamplesCount*SAMPLE_SIZE;
119 return *outputSamplesSize;
120 }
121
122 void
codec_register_iLBC(void)123 codec_register_iLBC(void)
124 {
125 register_codec("iLBC", codec_iLBC_init, codec_iLBC_release,
126 codec_iLBC_get_channels, codec_iLBC_get_frequency, codec_iLBC_decode);
127 }
128
129 /*
130 * Editor modelines - https://www.wireshark.org/tools/modelines.html
131 *
132 * Local variables:
133 * c-basic-offset: 4
134 * tab-width: 8
135 * indent-tabs-mode: nil
136 * End:
137 *
138 * vi: set shiftwidth=4 tabstop=8 expandtab:
139 * :indentSize=4:tabSize=8:noTabs=true:
140 */
141