1 /****************************************************************************
2  *
3  * ITU G.722.1 wideband audio codec plugin for OpenH323/OPAL
4  *
5  * Copyright (C) 2009 Nimajin Software Consulting, All Rights Reserved
6  *
7  * Permission to copy, use, sell and distribute this file is granted
8  * provided this copyright notice appears in all copies.
9  * Permission to modify the code herein and to distribute modified code is
10  * granted provided this copyright notice appears in all copies, and a
11  * notice that the code was modified is included with the copyright notice.
12  *
13  * This software and information is provided "as is" without express or im-
14  * plied warranty, and with no claim as to its suitability for any purpose.
15  *
16  ****************************************************************************
17  *
18  * ITU-T 7/14kHz Audio Coder (G.722.1) AKA Polycom 'Siren'
19  * SDP usage described in RFC 5577
20  * H.245 capabilities defined in G.722.1 Annex A & H.245 Appendix VIII
21  * This implementation employs ITU-T G.722.1 (2005-05) fixed point reference
22  * code, release 2.1 (2008-06)
23  * This implements only standard bit rates 24000 & 32000 at 16kHz (Siren7)
24  * sampling rate, not extended modes or 32000 sampling rate (Siren14).
25  * G.722.1 does not implement any silence handling (VAD/CNG)
26  * Static variables are not used, so multiple instances can run simultaneously.
27  * G.722.1 is patented by Polycom, but is royalty-free if you follow their
28  * license terms. See:
29  * http://www.polycom.com/company/about_us/technology/siren14_g7221c/faq.html
30  *
31  * Initial development by: Ted Szoczei, Nimajin Software Consulting, 09-12-09
32  * Portions developed by: Robert Jongbloed, Vox Lucida
33  *
34  ****************************************************************************/
35 
36 #define _CRT_NONSTDC_NO_DEPRECATE 1
37 #define _CRT_SECURE_NO_WARNINGS 1
38 
39 #ifdef _WIN32
40 #include <openh323buildopts.h>
41 #if H323_STATIC_G7221
42   #define OPAL_STATIC_CODEC 1
43 #endif
44 #endif
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #ifdef _MSC_VER
50 #include <winsock2.h>
51 #else
52 #include <netinet/in.h>
53 #endif
54 
55 #ifndef PLUGIN_CODEC_DLL_EXPORTS
56 #include "plugin-config.h"
57 #endif
58 
59 #include <codec/opalplugin.h>
60 
61 #if defined(_WIN32) || defined(_WIN32_WCE)
62   #include <malloc.h>
63   #include <string.h>
64   #define STRCMPI  _strcmpi
65 #else
66   #include <semaphore.h>
67   #define STRCMPI  strcasecmp
68   #include <unistd.h>
69 #endif
70 
71 #ifdef _MSC_VER
72 extern "C" {
73 #endif
74 #include "G722-1/defs.h"
75 #ifdef _MSC_VER
76 }
77 #endif
78 
num2str(int num)79 static char * num2str(int num)
80 {
81   char buf[20];
82   sprintf(buf, "%i", num);
83   return strdup(buf);
84 }
85 
86 static struct PluginCodec_information licenseInfo =
87 {
88   1260388706,           // version timestamp = Wed Dec 09 19:58:26 2009 UTC
89 
90   "Ted Szoczei, Nimajin Software Consulting",                  // source code author
91   "1.0",                                                       // source code version
92   "ted.szoczei@nimajin.com",                                   // source code email
93   NULL,                                                        // source code URL
94   "Copyright (c) 2009 Nimajin Software Consulting",            // source code copyright
95   "None",                                                      // source code license
96   PluginCodec_License_None,                                    // source code license
97 
98   "ITU-T 7/14kHz Audio Coder (G.722.1 Annex C)",               // codec description
99   "Polycom, Inc.",                                             // codec author
100   "2.1  2008-06-26",				                           // codec version
101   NULL,                                                        // codec email
102   "http://www.itu.int/rec/T-REC-G.722.1/e",                    // codec URL
103   "(c) 2005 Polycom, Inc. All rights reserved.",               // codec copyright information
104   "ITU-T General Public License (G.191)",                      // codec license
105   PluginCodec_License_NoRoyalties                              // codec license code
106 };
107 
108 static short EndianWord = 0x1234;
109 #define LittleEndian ((*(const char *)&EndianWord) == 0x34)
110 
111 /////////////////////////////////////////////////////////////////////////////
112 
113 
114 #define FORMAT_NAME_G722_1_16_24K  "G.722.1-24k"   // text decription and mediaformat name
115 #define FORMAT_NAME_G722_1_16_32K  "G.722.1-32k"   // text decription and mediaformat name
116 #define FORMAT_NAME_G722_1c        "G.722.1c"
117 #define RTP_NAME_G722_1  "G7221"                // MIME name rfc's 3047, 5577
118 
119 #define G722_1_16K_FRAME_SAMPLES  320
120 #define G722_1_32K_FRAME_SAMPLES  640
121 
122 // required bandwidth options in bits per second
123 #define G722_1_16_24_BIT_RATE 24000
124 #define G722_1_16_32_BIT_RATE 32000
125 #define G722_1c_BIT_RATE      48000
126 
127 // required bandwidth options in bits per second
128 #define G722_1_16K_SAMPLING_RATE 16000
129 #define G722_1_32K_SAMPLING_RATE 32000
130 
131 // bits and bytes per 20 ms frame, depending on bitrate
132 // 60 bytes for 24000, 80 for 32000
133 #define G722_1_FRAME_BITS(rate) ((Word16)((rate) / 50))
134 #define G722_1_FRAME_BYTES(rate) ((rate) / 400)
135 
136 
137 /////////////////////////////////////////////////////////////////////////////
138 // Compress audio for transport
139 typedef struct
140 {
141   unsigned bitsPerSec;                  // can be changed between frames
142   unsigned sampleRate;                  // whether G.722.1 ot G.722.1c
143   Word16 history [G722_1_32K_FRAME_SAMPLES];
144   Word16 mlt_coefs [G722_1_32K_FRAME_SAMPLES];
145   Word16 mag_shift;
146 } G7221EncoderContext;
147 
148 
149 #define PLUGINCODEC_OPTION_SUPPORTMODE			"Generic Parameter 2"
150 
encoder_set_options(const struct PluginCodec_Definition * codec,void * _context,const char *,void * parm,unsigned * parmLen)151 static int encoder_set_options(
152       const struct PluginCodec_Definition * codec,
153       void * _context,
154       const char *,
155       void * parm,
156       unsigned * parmLen)
157 {
158   if (_context == NULL || parmLen == NULL || *parmLen != sizeof(const char **))
159     return 0;
160 
161   G7221EncoderContext * context = (G7221EncoderContext *)_context;
162   if (context == NULL)
163     return 0;
164 
165   unsigned bitRate = 0;
166   unsigned maxBitRate = 0;
167 
168   if (parm != NULL) {
169     const char ** options = (const char **)parm;
170     int i;
171     for (i = 0; options[i] != NULL; i += 2) {
172       if (STRCMPI(options[i], PLUGINCODEC_OPTION_MAX_BIT_RATE) == 0)
173          maxBitRate = (unsigned)(atoi(options[i+1]));
174       if (STRCMPI(options[i], PLUGINCODEC_OPTION_SUPPORTMODE) == 0)
175          bitRate = (unsigned)(atoi(options[i+1]));
176 	}
177   }
178 
179     if (context->sampleRate == 16000) {
180        maxBitRate /= 100;  // Hack as G.722.1 send act bitrate not act/100
181     } else if (bitRate > 0) {
182       switch (bitRate) {
183           case 16: maxBitRate = 48000; break;
184           case 32: maxBitRate = 32000; break;
185           case 64: maxBitRate = 16000; break;
186           default:
187                    maxBitRate = 16000; break;
188       }
189       context->bitsPerSec = maxBitRate;
190     }
191 
192     // Write back the option list the changed information
193     if (parm != NULL) {
194 	    char ** options = (char **)parm;
195         if (options == NULL) return 0;
196         for (int i = 0; options[i] != NULL; i += 2) {
197 	      if (STRCMPI(options[i], PLUGINCODEC_OPTION_MAX_BIT_RATE) == 0)
198 		     options[i+1] = num2str(maxBitRate);
199 	    }
200     }
201 
202 
203   return 1;
204 }
205 
206 
G7221EncoderCreate(const struct PluginCodec_Definition * codec)207 static void * G7221EncoderCreate (const struct PluginCodec_Definition * codec)
208 {
209   unsigned i;
210   G7221EncoderContext * Context = (G7221EncoderContext *) malloc (sizeof(G7221EncoderContext));
211   if (Context == NULL)
212     return NULL;
213 
214   Context->sampleRate = codec->sampleRate;
215   Context->bitsPerSec = codec->bitsPerSec;
216 
217   // initialize the mlt history buffer
218   for (i = 0; i < codec->parm.audio.samplesPerFrame; i++)
219     Context->history[i] = 0;
220 
221   return Context;
222 }
223 
224 
G7221EncoderDestroy(const struct PluginCodec_Definition * codec,void * context)225 static void G7221EncoderDestroy (const struct PluginCodec_Definition * codec, void * context)
226 {
227   free (context);
228 }
229 
230 
G7221Encode(const struct PluginCodec_Definition * codec,void * context,const void * fromPtr,unsigned * fromLen,void * toPtr,unsigned * toLen,unsigned int * flag)231 static int G7221Encode (const struct PluginCodec_Definition * codec,
232                                                        void * context,
233                                                  const void * fromPtr,
234                                                    unsigned * fromLen,
235                                                        void * toPtr,
236                                                    unsigned * toLen,
237                                                unsigned int * flag)
238 {
239   int i = 0;
240   G7221EncoderContext * Context = (G7221EncoderContext *) context;
241   if (Context == NULL)
242     return 0;
243 
244   if (*fromLen < codec->parm.audio.samplesPerFrame)
245     return 0;                           // Source is not a full frame
246 
247   if (*toLen < G722_1_FRAME_BYTES (Context->bitsPerSec))
248     return 0;                           // Destination buffer not big enough
249 
250   // Convert input samples to rmlt coefs
251   Context->mag_shift = samples_to_rmlt_coefs ((Word16 *) fromPtr, Context->history, Context->mlt_coefs, *fromLen/2);
252 
253   // Encode the mlt coefs
254   encoder (G722_1_FRAME_BITS (Context->bitsPerSec), NUMBER_OF_REGIONS, Context->mlt_coefs, Context->mag_shift, (Word16 *) toPtr);
255 
256  for (i = 0; i < (short)codec->parm.audio.samplesPerFrame; i++)
257      ((Word16 *) toPtr) [i] =ntohs(((Word16 *)toPtr)[i]);
258 
259  // return the number of encoded bytes to the caller
260   *fromLen = codec->parm.audio.samplesPerFrame*2;
261   *toLen = G722_1_FRAME_BYTES (Context->bitsPerSec);
262 
263   // Do some endian swapping, if needed
264   if (LittleEndian)
265 #if _WIN32
266     _swab((char *)toPtr, (char *)toPtr, *toLen);
267 #else
268     swab(toPtr, toPtr, *toLen);
269 #endif
270 
271   return 1;
272 }
273 
274 
275 /////////////////////////////////////////////////////////////////////////////
276 // Convert encoded source to audio
277 
278 
279 typedef struct
280 {
281   unsigned bitsPerSec;                  // can be changed between frames
282   unsigned sampleRate;
283   Bit_Obj bitobj;
284   Rand_Obj randobj;
285   Word16 decoder_mlt_coefs [G722_1_32K_FRAME_SAMPLES];
286   Word16 mag_shift;
287   Word16 old_samples [G722_1_32K_FRAME_SAMPLES / 2];
288   Word16 old_decoder_mlt_coefs [G722_1_32K_FRAME_SAMPLES];
289   Word16 old_mag_shift;
290   Word16 frame_error_flag;
291 } G7221DecoderContext;
292 
293 
G7221DecoderCreate(const struct PluginCodec_Definition * codec)294 static void * G7221DecoderCreate (const struct PluginCodec_Definition * codec)
295 {
296   unsigned i;
297   G7221DecoderContext * Context = (G7221DecoderContext *) malloc (sizeof(G7221DecoderContext));
298   if (Context == NULL)
299     return NULL;
300 
301   Context->sampleRate = codec->sampleRate;
302   Context->bitsPerSec = codec->bitsPerSec;
303 
304   Context->old_mag_shift = 0;
305   Context->frame_error_flag = 0;
306 
307   // initialize the coefs history
308   for (i = 0; i < codec->parm.audio.samplesPerFrame; i++)
309     Context->old_decoder_mlt_coefs[i] = 0;
310 
311   for (i = 0; i < (codec->parm.audio.samplesPerFrame >> 1); i++)
312     Context->old_samples[i] = 0;
313 
314   // initialize the random number generator
315   Context->randobj.seed0 = 1;
316   Context->randobj.seed1 = 1;
317   Context->randobj.seed2 = 1;
318   Context->randobj.seed3 = 1;
319 
320   return Context;
321 }
322 
323 
G7221DecoderDestroy(const struct PluginCodec_Definition * codec,void * context)324 static void G7221DecoderDestroy (const struct PluginCodec_Definition * codec, void * context)
325 {
326   free (context);
327 }
328 
329 
G7221Decode(const struct PluginCodec_Definition * codec,void * context,const void * fromPtr,unsigned * fromLen,void * toPtr,unsigned * toLen,unsigned int * flag)330 static int G7221Decode (const struct PluginCodec_Definition * codec,
331                                                        void * context,
332                                                  const void * fromPtr,
333                                                    unsigned * fromLen,
334                                                        void * toPtr,
335                                                    unsigned * toLen,
336                                                unsigned int * flag)
337 {
338     short i;
339     G7221DecoderContext * Context = (G7221DecoderContext *) context;
340     if (Context == NULL)
341         return 0;
342     //printf("Decode: FromLen->%i ToLen->%i\n", *fromLen, *toLen);
343 
344     if (*fromLen < G722_1_FRAME_BYTES (Context->bitsPerSec))
345         return 0;                           // Source is not a full frame
346 
347     if (*toLen < codec->parm.audio.samplesPerFrame*2)
348         return 0;                           // Destination buffer not big enough
349 
350   // Do some endian swapping, if needed
351   if (LittleEndian)
352 #ifdef _WIN32
353     _swab((char *)fromPtr, (char *)fromPtr, G722_1_FRAME_BYTES (Context->bitsPerSec));
354 #else
355     swab((void *)fromPtr, (void *)fromPtr, G722_1_FRAME_BYTES (Context->bitsPerSec));
356 #endif
357 
358   // reinit the current word to point to the start of the buffer
359   Context->bitobj.code_word_ptr = (Word16 *) fromPtr;
360   Context->bitobj.current_word = *((Word16 *) fromPtr);
361   Context->bitobj.code_bit_count = 0;
362   Context->bitobj.number_of_bits_left = G722_1_FRAME_BITS(Context->bitsPerSec);
363 
364   for (i = 0; i < (short)*fromLen/2; i++)
365       ((Word16 *) fromPtr) [i] =ntohs(((Word16 *)fromPtr)[i]);
366 
367   // process the out_words into decoder_mlt_coefs
368   decoder (&Context->bitobj, &Context->randobj, NUMBER_OF_REGIONS, \
369                 Context->decoder_mlt_coefs, &Context->mag_shift, &Context->old_mag_shift, \
370                 Context->old_decoder_mlt_coefs, Context->frame_error_flag);
371 
372   // convert the decoder_mlt_coefs to samples
373   rmlt_coefs_to_samples (Context->decoder_mlt_coefs, Context->old_samples, (Word16 *) toPtr, codec->parm.audio.samplesPerFrame, Context->mag_shift);
374 
375   //For ITU testing, off the 2 lsbs.
376   for (i = 0; i < (short)codec->parm.audio.samplesPerFrame; i++)
377     ((Word16 *) toPtr) [i] &= 0xFFFC;
378 
379     // return the number of decoded bytes to the caller
380   *fromLen = G722_1_FRAME_BYTES (Context->bitsPerSec);
381   *toLen = codec->parm.audio.samplesPerFrame*2;
382 
383   return 1;
384 }
385 
386 
387 /////////////////////////////////////////////////////////////////////////////
388 
389 // bitrate is a required SDP parameter in RFC 3047/5577
390 static const char BitRateOptionName[] = "BitRate";
391 
392 static struct PluginCodec_Option BitRateOption16_24k =
393 {
394     PluginCodec_IntegerOption,  // PluginCodec_OptionTypes
395     BitRateOptionName,          // Generic (human readable) option name
396     1,                          // Read Only flag
397     PluginCodec_EqualMerge,     // Merge mode
398     "16000",                    // Initial value
399     "bitrate",                  // SIP/SDP FMTP name
400     "0",                        // SIP/SDP FMTP default value (option not included in FMTP if have this value)
401     0,                          // H.245 Generic Capability number and scope bits
402     "24000",                    // Minimum value (enum values separated by ':')
403     "24000"                     // Maximum value
404 };
405 
406 static struct PluginCodec_Option BitRateOption16_32k =
407 {
408     PluginCodec_IntegerOption,  // PluginCodec_OptionTypes
409     BitRateOptionName,          // Generic (human readable) option name
410     1,                          // Read Only flag
411     PluginCodec_EqualMerge,     // Merge mode
412     "16000",                    // Initial value
413     "bitrate",                  // SIP/SDP FMTP name
414     "0",                        // SIP/SDP FMTP default value (option not included in FMTP if have this value)
415     0,                          // H.245 Generic Capability number and scope bits
416     "32000",                    // Minimum value (enum values separated by ':')
417     "32000"                     // Maximum value
418 };
419 
420 static struct PluginCodec_Option BitRateOption32k =
421 {
422   PluginCodec_IntegerOption,  // PluginCodec_OptionTypes
423   BitRateOptionName,          // Generic (human readable) option name
424   1,                          // Read Only flag
425   PluginCodec_EqualMerge,     // Merge mode
426   "32000",                    // Initial value
427   "bitrate",                  // SIP/SDP FMTP name
428   "0",                        // SIP/SDP FMTP default value (option not included in FMTP if have this value)
429   0,                          // H.245 Generic Capability number and scope bits
430   "240",                    // Minimum value (enum values separated by ':')
431   "480"                     // Maximum value
432 };
433 
434 static struct PluginCodec_Option * const OptionTable1624k[] =
435 {
436     &BitRateOption16_24k,
437     NULL
438 };
439 static struct PluginCodec_Option * const OptionTable1632k[] =
440 {
441     &BitRateOption16_32k,
442     NULL
443 };
444 static struct PluginCodec_Option * const OptionTable32k[] =
445 {
446   &BitRateOption32k,
447   NULL
448 };
449 
450 
get_codec_options(const struct PluginCodec_Definition * defn,void * context,const char * name,void * parm,unsigned * parmLen)451 static int get_codec_options (const struct PluginCodec_Definition * defn,
452                                                              void * context,
453                                                        const char * name,
454                                                              void * parm,
455                                                          unsigned * parmLen)
456 {
457   if (parm == NULL || parmLen == NULL || *parmLen != sizeof(struct PluginCodec_Option **))
458     return 0;
459 
460   if (defn->sampleRate == G722_1_32K_SAMPLING_RATE) {
461       *(struct PluginCodec_Option const * const * *)parm = OptionTable32k;
462   }
463   else {
464       if (defn->bitsPerSec == G722_1_16_32_BIT_RATE)
465           *(struct PluginCodec_Option const * const * *)parm = OptionTable1632k;
466       else
467           *(struct PluginCodec_Option const * const * *)parm = OptionTable1624k;
468 
469   }
470   //*(struct PluginCodec_Option const * const * *)parm = (defn->sampleRate == G722_1_16K_SAMPLING_RATE)? OptionTable1632k : OptionTable32k;
471 
472 
473   *parmLen = 0;
474 
475   return 1;
476  }
477 
478 
479 // Options are read-only, so set_codec_options not implemented
480 // get_codec_options returns pointers to statics, and toCustomized and
481 // toNormalized are not implemented, so free_codec_options is not necessary
482 
483 static struct PluginCodec_ControlDefn G7221Controls[] =
484 {
485   { PLUGINCODEC_CONTROL_GET_CODEC_OPTIONS, get_codec_options },
486   { PLUGINCODEC_CONTROL_SET_CODEC_OPTIONS, encoder_set_options },
487   { NULL }
488 };
489 
490 /////////////////////////////////////////////////////////////////////////////////////////
491 
492 // G.722.1 16k codec
493 
494 // 24k bitRate
495 static unsigned int G7221_24_FRAMES = 1;
496 static unsigned int G7221_24_MAXBITRATE = 24000;
497 
498 // 32k bitRate
499 static unsigned int G7221_32_FRAMES = 1;
500 static unsigned int G7221_32_MAXBITRATE = 32000;
501 
502 #define G7221PLUGIN_CODEC(prefix) \
503 static const struct PluginCodec_H323GenericParameterDefinition prefix##_h323params[] = \
504 { \
505    {{1,0,0,0,0},1,PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_FRAMES}}, \
506     NULL \
507 }; \
508 static struct PluginCodec_H323GenericCodecData prefix##_Cap = \
509 { \
510     OpalPluginCodec_Identifer_G7221, \
511     prefix##_MAXBITRATE, \
512     1, \
513     prefix##_h323params \
514 }; \
515 
516 G7221PLUGIN_CODEC(G7221_24);
517 G7221PLUGIN_CODEC(G7221_32);
518 
519 /////////////////////////////////////////////////////////////////////////////
520 
521 // G.722.1c 32k codec
522 static unsigned int G7221c_FRAMES = 1;
523 static unsigned int G7221c_SUPPORTMODE = 112;  //24/36/48 k
524 static unsigned int G7221c_MAXBITRATE = 480;
525 
526 #define G7221cPLUGIN_CODEC(prefix) \
527 static const struct PluginCodec_H323GenericParameterDefinition prefix##_h323params[] = \
528 { \
529    {{1,0,0,0,0},1, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_FRAMES}}, \
530    {{1,0,0,0,0},2, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_booleanArray, {prefix##_SUPPORTMODE}}, \
531     NULL \
532 }; \
533 static struct PluginCodec_H323GenericCodecData prefix##_Cap = \
534 { \
535     OpalPluginCodec_Identifer_G7221ext, \
536     prefix##_MAXBITRATE, \
537     2, \
538     prefix##_h323params \
539 };
540 
541 //G7221cPLUGIN_CODEC(G7221c);
542 
543 /////////////////////////////////////////////////////////////////////////////
544 static struct PluginCodec_Definition G7221CodecDefn[] =
545 {
546     {
547         // G.722.1 16kHz , 32kbps encoder
548         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
549         &licenseInfo,                           // license information
550         PluginCodec_MediaTypeAudio |            // audio codec
551         PluginCodec_InputTypeRaw |              // raw input data
552         PluginCodec_OutputTypeRaw |             // raw output data
553         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
554         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
555         FORMAT_NAME_G722_1_16_32K,              // text decription
556         "L16",                                  // source format
557         FORMAT_NAME_G722_1_16_32K,              // destination format
558         NULL,                                   // user data
559         G722_1_16K_SAMPLING_RATE,               // samples per second
560         G722_1_16_32_BIT_RATE,                  // raw bits per second
561         20000,                                  // microseconds per frame
562         {{
563             G722_1_16K_FRAME_SAMPLES,           // samples per frame
564             G722_1_16_32_BIT_RATE/400,          // bytes per frame
565             1,                                  // recommended number of frames per packet
566             1,                                  // maximum number of frames per packet
567         }},
568         121,                                    // IANA RTP payload code
569         RTP_NAME_G722_1,                        // RTP payload name
570         G7221EncoderCreate,                     // create codec function
571         G7221EncoderDestroy,                    // destroy codec
572         G7221Encode,                            // encode/decode
573         G7221Controls,                          // codec controls
574         PluginCodec_H323Codec_generic,          // h323CapabilityType
575         &G7221_32_Cap                           // h323CapabilityData
576     },
577     {
578         // G.722.1 16kHz, 32 kbps decoder
579         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
580         &licenseInfo,                           // license information
581         PluginCodec_MediaTypeAudio |            // audio codec
582         PluginCodec_InputTypeRaw |              // raw input data
583         PluginCodec_OutputTypeRaw |             // raw output data
584         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
585         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
586         FORMAT_NAME_G722_1_16_32K,              // text decription
587         FORMAT_NAME_G722_1_16_32K,              // source format
588         "L16",                                  // destination format
589         NULL,                                   // user data
590         G722_1_16K_SAMPLING_RATE,               // samples per second
591         G722_1_16_32_BIT_RATE,                  // raw bits per second
592         20000,                                  // microseconds per frame
593         {{
594             G722_1_16K_FRAME_SAMPLES,           // samples per frame
595             G722_1_16_32_BIT_RATE/400,          // bytes per frame
596             1,                                  // recommended number of frames per packet
597             1,                                  // maximum number of frames per packet
598         }},
599         121,                                    // IANA RTP payload code
600         RTP_NAME_G722_1,                        // RTP payload name
601         G7221DecoderCreate,                     // create codec function
602         G7221DecoderDestroy,                    // destroy codec
603         G7221Decode,                            // encode/decode
604         G7221Controls,                          // codec controls
605         PluginCodec_H323Codec_generic,          // h323CapabilityType
606         &G7221_32_Cap                           // h323CapabilityData
607     },
608     {
609         // G.722.1 16kHz , 24kbps encoder
610         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
611         &licenseInfo,                           // license information
612         PluginCodec_MediaTypeAudio |            // audio codec
613         PluginCodec_InputTypeRaw |              // raw input data
614         PluginCodec_OutputTypeRaw |             // raw output data
615         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
616         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
617         FORMAT_NAME_G722_1_16_24K,              // text decription
618         "L16",                                  // source format
619         FORMAT_NAME_G722_1_16_24K,              // destination format
620         NULL,                                   // user data
621         G722_1_16K_SAMPLING_RATE,               // samples per second
622         G722_1_16_24_BIT_RATE,                  // raw bits per second
623         20000,                                  // microseconds per frame
624         {{
625             G722_1_16K_FRAME_SAMPLES,           // samples per frame
626             G722_1_16_24_BIT_RATE/400,          // bytes per frame
627             1,                                  // recommended number of frames per packet
628             1,                                  // maximum number of frames per packet
629         }},
630         121,                                    // IANA RTP payload code
631         RTP_NAME_G722_1,                        // RTP payload name
632         G7221EncoderCreate,                     // create codec function
633         G7221EncoderDestroy,                    // destroy codec
634         G7221Encode,                            // encode/decode
635         G7221Controls,                          // codec controls
636         PluginCodec_H323Codec_generic,          // h323CapabilityType
637         &G7221_24_Cap                           // h323CapabilityData
638     },
639     {
640         // G.722.1 16kHz, 24 kbps decoder
641         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
642         &licenseInfo,                           // license information
643         PluginCodec_MediaTypeAudio |            // audio codec
644         PluginCodec_InputTypeRaw |              // raw input data
645         PluginCodec_OutputTypeRaw |             // raw output data
646         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
647         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
648         FORMAT_NAME_G722_1_16_24K,              // text decription
649         FORMAT_NAME_G722_1_16_24K,              // source format
650         "L16",                                  // destination format
651         NULL,                                   // user data
652         G722_1_16K_SAMPLING_RATE,               // samples per second
653         G722_1_16_24_BIT_RATE,                  // raw bits per second
654         20000,                                  // microseconds per frame
655         {{
656             G722_1_16K_FRAME_SAMPLES,           // samples per frame
657             G722_1_16_24_BIT_RATE/400,          // bytes per frame
658             1,                                  // recommended number of frames per packet
659             1,                                  // maximum number of frames per packet
660         }},
661         121,                                    // IANA RTP payload code
662         RTP_NAME_G722_1,                        // RTP payload name
663         G7221DecoderCreate,                     // create codec function
664         G7221DecoderDestroy,                    // destroy codec
665         G7221Decode,                            // encode/decode
666         G7221Controls,                          // codec controls
667         PluginCodec_H323Codec_generic,          // h323CapabilityType
668         &G7221_24_Cap                           // h323CapabilityData
669     },
670 #if 0
671     {
672         // G.722.1 32kHz encoder
673         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
674         &licenseInfo,                           // license information
675         PluginCodec_MediaTypeAudio |            // audio codec
676         PluginCodec_InputTypeRaw |              // raw input data
677         PluginCodec_OutputTypeRaw |             // raw output data
678         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
679         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
680         FORMAT_NAME_G722_1c,                    // text decription
681         "L16",                                  // source format
682         FORMAT_NAME_G722_1c,                    // destination format
683         NULL,                                   // user data
684         G722_1_32K_SAMPLING_RATE,               // samples per second
685         G722_1c_BIT_RATE,                       // raw bits per second
686         20000,                                  // microseconds per frame
687         {{
688             G722_1_32K_FRAME_SAMPLES,           // samples per frame
689             G722_1c_BIT_RATE/400,               // bytes per frame
690             1,                                  // recommended number of frames per packet
691             1,                                  // maximum number of frames per packet
692         }},
693         122,                                      // IANA RTP payload code
694         RTP_NAME_G722_1,                        // RTP payload name
695         G7221EncoderCreate,                     // create codec function
696         G7221EncoderDestroy,                    // destroy codec
697         G7221Encode,                            // encode/decode
698         G7221Controls,                          // codec controls
699         PluginCodec_H323Codec_generic,          // h323CapabilityType
700         &G7221c_Cap                             // h323CapabilityData
701       },
702       {
703         // G.722.1 32kHz decoder
704         PLUGIN_CODEC_VERSION_OPTIONS,           // codec API version
705         &licenseInfo,                           // license information
706         PluginCodec_MediaTypeAudio |            // audio codec
707         PluginCodec_InputTypeRaw |              // raw input data
708         PluginCodec_OutputTypeRaw |             // raw output data
709         PluginCodec_RTPTypeDynamic |            // dynamic RTP type
710         PluginCodec_RTPTypeShared,              // RTP type shared with other codecs in this definition
711         FORMAT_NAME_G722_1c,                    // text decription
712         FORMAT_NAME_G722_1c,                    // source format
713         "L16",                                  // destination format
714         NULL,                                   // user data
715         G722_1_32K_SAMPLING_RATE,               // samples per second
716         G722_1c_BIT_RATE,                       // raw bits per second
717         20000,                                  // microseconds per frame
718         {{
719             G722_1_32K_FRAME_SAMPLES,           // samples per frame
720             G722_1c_BIT_RATE/400,               // bytes per frame
721             1,                                  // recommended number of frames per packet
722             1,                                  // maximum number of frames per packet
723         }},
724         122,                                      // IANA RTP payload code
725         RTP_NAME_G722_1,                        // RTP payload name
726         G7221DecoderCreate,                     // create codec function
727         G7221DecoderDestroy,                    // destroy codec
728         G7221Decode,                            // encode/decode
729         G7221Controls,                          // codec controls
730         PluginCodec_H323Codec_generic,          // h323CapabilityType
731         &G7221c_Cap                             // h323CapabilityData
732       }
733 #endif
734 };
735 
736 extern "C" {
737 PLUGIN_CODEC_IMPLEMENT_ALL(G7221, G7221CodecDefn, PLUGIN_CODEC_VERSION_OPTIONS)
738 }
739 
740 /////////////////////////////////////////////////////////////////////////////
741