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