1 /* G729decode.c
2  * G.729 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 <glib.h>
14 
15 #include "bcg729/decoder.h"
16 #include "wsutil/codecs.h"
17 #include "ws_attributes.h"
18 
19 void codec_register_g729(void);
20 
21 static void *
codec_g729_init(void)22 codec_g729_init(void)
23 {
24     return initBcg729DecoderChannel();
25 }
26 
27 static void
codec_g729_release(void * ctx)28 codec_g729_release(void *ctx)
29 {
30     closeBcg729DecoderChannel((bcg729DecoderChannelContextStruct *)ctx);
31 }
32 
33 static unsigned
codec_g729_get_channels(void * ctx _U_)34 codec_g729_get_channels(void *ctx _U_)
35 {
36     return 1;
37 }
38 
39 static unsigned
codec_g729_get_frequency(void * ctx _U_)40 codec_g729_get_frequency(void *ctx _U_)
41 {
42     return 8000;
43 }
44 
45 static size_t
codec_g729_decode(void * ctx,const void * inputBytes,size_t inputBytesSize,void * outputSamples,size_t * outputSamplesSize)46 codec_g729_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
47         void *outputSamples, size_t *outputSamplesSize)
48 {
49     bcg729DecoderChannelContextStruct *state = (bcg729DecoderChannelContextStruct *)ctx;
50     const guint8 *dataIn = (const guint8 *) inputBytes;
51     gint16 *dataOut = (gint16 *) outputSamples;
52     size_t i;
53 
54     if (!ctx) {
55         return 0;
56     }
57 
58     if (!outputSamples || !outputSamplesSize) {
59         return 80*2*(inputBytesSize/10);
60     }
61 
62     /* The G729 algorithm encodes 10ms of voice into 80bit (10 bytes).
63        Based on the RTP packetization period (usually 20ms), we need to
64        pass to the bcg729 decoder chunks of 10ms (10 bytes)
65     */
66     for (i = 0; i < (inputBytesSize/10); i++) {
67         /* The bcg729 decoder library fails to declare the second
68            argument to bcg729Decoder() to be a const pointer.  If you
69            fix it, and some other functions, to use const, the library
70            compiles, so presumably it doesn't modify its input and
71            therefore can safely be passed a const pointer.  Cast away
72            the problem for now; a patch will be sent to the maintainers
73            of the library.
74         */
75         bcg729Decoder(state, (guint8 *)dataIn + i*10, 10, 0, 0, 0, dataOut + i*80);
76     }
77     *outputSamplesSize = 80*2*(inputBytesSize/10);
78     return *outputSamplesSize;
79 }
80 
81 void
codec_register_g729(void)82 codec_register_g729(void)
83 {
84     register_codec("g729", codec_g729_init, codec_g729_release,
85             codec_g729_get_channels, codec_g729_get_frequency, codec_g729_decode);
86 }
87 
88 /*
89  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
90  *
91  * Local variables:
92  * c-basic-offset: 4
93  * tab-width: 8
94  * indent-tabs-mode: nil
95  * End:
96  *
97  * vi: set shiftwidth=4 tabstop=8 expandtab:
98  * :indentSize=4:tabSize=8:noTabs=true:
99  */
100