diff options
Diffstat (limited to 'tinyDAV/src/codecs/g729/tdav_codec_g729.c')
-rwxr-xr-x | tinyDAV/src/codecs/g729/tdav_codec_g729.c | 568 |
1 files changed, 283 insertions, 285 deletions
diff --git a/tinyDAV/src/codecs/g729/tdav_codec_g729.c b/tinyDAV/src/codecs/g729/tdav_codec_g729.c index 8981687..43b3425 100755 --- a/tinyDAV/src/codecs/g729/tdav_codec_g729.c +++ b/tinyDAV/src/codecs/g729/tdav_codec_g729.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -65,210 +65,210 @@ static void pack_SID(const int16_t ituBits[], uint8_t bitstream[]); static int tdav_codec_g729ab_open(tmedia_codec_t* self) { - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; - - // Initialize the decoder - bad_lsf = 0; - g729a->decoder.synth = (g729a->decoder.synth_buf + M); - - Init_Decod_ld8a(); - Init_Post_Filter(); - Init_Post_Process(); - /* for G.729B */ - Init_Dec_cng(); - - // Initialize the encoder - Init_Pre_Process(); - Init_Coder_ld8a(); - Set_zero(g729a->encoder.prm, PRM_SIZE + 1); - /* for G.729B */ - Init_Cod_cng(); - - - return 0; + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; + + // Initialize the decoder + bad_lsf = 0; + g729a->decoder.synth = (g729a->decoder.synth_buf + M); + + Init_Decod_ld8a(); + Init_Post_Filter(); + Init_Post_Process(); + /* for G.729B */ + Init_Dec_cng(); + + // Initialize the encoder + Init_Pre_Process(); + Init_Coder_ld8a(); + Set_zero(g729a->encoder.prm, PRM_SIZE + 1); + /* for G.729B */ + Init_Cod_cng(); + + + return 0; } static int tdav_codec_g729ab_close(tmedia_codec_t* self) { - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; + + (void)(g729a); + + /* resources will be freed by the dctor() */ - (void)(g729a); - - /* resources will be freed by the dctor() */ - - return 0; + return 0; } static tsk_size_t tdav_codec_g729ab_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size) -{ - tsk_size_t ex_size, out_size = 0; - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; - int i, frame_count = (in_size / 160); - - - if(!self || !in_data || !in_size || !out_data || (in_size % 160)){ - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } - - ex_size = (frame_count * 10); - - // allocate new buffer if needed - if(*out_max_size <ex_size){ - if(!(*out_data = tsk_realloc(*out_data, ex_size))){ - TSK_DEBUG_ERROR("Failed to allocate new buffer"); - *out_max_size = 0; - return 0; - } - *out_max_size = ex_size; - } - - for(i=0; i<frame_count; i++){ - extern int16_t *new_speech; - - if(g729a->encoder.frame == 32767){ - g729a->encoder.frame = 256; - } - else{ - g729a->encoder.frame++; - } - - memcpy(new_speech, &((uint8_t*)in_data)[i*L_FRAME*sizeof(int16_t)], sizeof(int16_t)*L_FRAME); - - Pre_Process(new_speech, L_FRAME); - Coder_ld8a(g729a->encoder.prm, g729a->encoder.frame, g729a->encoder.vad_enable); - prm2bits_ld8k(g729a->encoder.prm, g729a->encoder.serial); - - if(g729a->encoder.serial[1] == RATE_8000){ - pack_G729(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]); - out_size += 10; - } - else if(g729a->encoder.serial[1] == RATE_SID_OCTET){ - pack_SID(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]); - out_size += 2; - } - else{ // RATE_0 - //TSK_DEBUG_INFO("G729_RATE_0 - Not transmitted"); +{ + tsk_size_t ex_size, out_size = 0; + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; + int i, frame_count = (in_size / 160); + + + if(!self || !in_data || !in_size || !out_data || (in_size % 160)) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } + + ex_size = (frame_count * 10); + + // allocate new buffer if needed + if(*out_max_size <ex_size) { + if(!(*out_data = tsk_realloc(*out_data, ex_size))) { + TSK_DEBUG_ERROR("Failed to allocate new buffer"); + *out_max_size = 0; + return 0; + } + *out_max_size = ex_size; + } + + for(i=0; i<frame_count; i++) { + extern int16_t *new_speech; + + if(g729a->encoder.frame == 32767) { + g729a->encoder.frame = 256; + } + else { + g729a->encoder.frame++; + } + + memcpy(new_speech, &((uint8_t*)in_data)[i*L_FRAME*sizeof(int16_t)], sizeof(int16_t)*L_FRAME); + + Pre_Process(new_speech, L_FRAME); + Coder_ld8a(g729a->encoder.prm, g729a->encoder.frame, g729a->encoder.vad_enable); + prm2bits_ld8k(g729a->encoder.prm, g729a->encoder.serial); + + if(g729a->encoder.serial[1] == RATE_8000) { + pack_G729(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]); + out_size += 10; + } + else if(g729a->encoder.serial[1] == RATE_SID_OCTET) { + pack_SID(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]); + out_size += 2; + } + else { // RATE_0 + //TSK_DEBUG_INFO("G729_RATE_0 - Not transmitted"); if (!g729a->encoder.vad_enable) { // silence memset(&((uint8_t*)(*out_data))[out_size], 0, 10); out_size += 10; } - } - } + } + } - return out_size; + return out_size; } static tsk_size_t tdav_codec_g729ab_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr) { - tsk_size_t out_size = 0; - int i, frame_count; - const uint8_t* data_start = (const uint8_t*)in_data; - const uint8_t* data_end; - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; - - if(!self || !in_data || !in_size || !out_data || ((in_size % 10) && (in_size % 10 != 2))){ - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } - - data_end = (data_start + in_size); - - frame_count = (in_size/10) + ((in_size % 10) ? 1 : 0); - - out_size = 160*frame_count; - - /* allocate new buffer if needed */ - if(*out_max_size <out_size){ - if(!(*out_data = tsk_realloc(*out_data, out_size))){ - TSK_DEBUG_ERROR("Failed to allocate new buffer"); - *out_max_size = 0; - return 0; - } - *out_max_size = out_size; - } - - for(i=0; i<frame_count; i++){ - memset(g729a->decoder.synth_buf, 0, M); - g729a->decoder.synth = g729a->decoder.synth_buf + M; - - if((data_end - data_start) == 2){ - unpack_SID(data_start, g729a->decoder.serial); - data_start += 2; - } - else{ - unpack_G729(data_start, g729a->decoder.serial, 10); - data_start += 10; - } - - bits2prm_ld8k(&g729a->decoder.serial[1], g729a->decoder.parm); - - /* This part was modified for version V1.3 */ - /* for speech and SID frames, the hardware detects frame erasures - by checking if all bits are set to zero */ - /* for untransmitted frames, the hardware detects frame erasures - by testing serial[0] */ - - g729a->decoder.parm[0] = 0; /* No frame erasure */ - if(g729a->decoder.serial[1] != 0) { - int j; - for (j=0; j < g729a->decoder.serial[1]; j++){ - if (g729a->decoder.serial[j+2] == 0){ - g729a->decoder.parm[0] = 1; /* frame erased */ - break; - } - } - } - else if(g729a->decoder.serial[0] != SYNC_WORD){ - g729a->decoder.parm[0] = 1; - } - if(g729a->decoder.parm[1] == 1) { - /* check parity and put 1 in parm[5] if parity error */ - g729a->decoder.parm[5] = Check_Parity_Pitch(g729a->decoder.parm[4], g729a->decoder.parm[5]); - } - - Decod_ld8a(g729a->decoder.parm, g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, &g729a->decoder.Vad); - Post_Filter(g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, g729a->decoder.Vad); /* Post-filter */ - Post_Process(g729a->decoder.synth, L_FRAME); - - memcpy(&((uint8_t*)*out_data)[160*i], g729a->decoder.synth, 160); - } - - - return out_size; + tsk_size_t out_size = 0; + int i, frame_count; + const uint8_t* data_start = (const uint8_t*)in_data; + const uint8_t* data_end; + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self; + + if(!self || !in_data || !in_size || !out_data || ((in_size % 10) && (in_size % 10 != 2))) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } + + data_end = (data_start + in_size); + + frame_count = (in_size/10) + ((in_size % 10) ? 1 : 0); + + out_size = 160*frame_count; + + /* allocate new buffer if needed */ + if(*out_max_size <out_size) { + if(!(*out_data = tsk_realloc(*out_data, out_size))) { + TSK_DEBUG_ERROR("Failed to allocate new buffer"); + *out_max_size = 0; + return 0; + } + *out_max_size = out_size; + } + + for(i=0; i<frame_count; i++) { + memset(g729a->decoder.synth_buf, 0, M); + g729a->decoder.synth = g729a->decoder.synth_buf + M; + + if((data_end - data_start) == 2) { + unpack_SID(data_start, g729a->decoder.serial); + data_start += 2; + } + else { + unpack_G729(data_start, g729a->decoder.serial, 10); + data_start += 10; + } + + bits2prm_ld8k(&g729a->decoder.serial[1], g729a->decoder.parm); + + /* This part was modified for version V1.3 */ + /* for speech and SID frames, the hardware detects frame erasures + by checking if all bits are set to zero */ + /* for untransmitted frames, the hardware detects frame erasures + by testing serial[0] */ + + g729a->decoder.parm[0] = 0; /* No frame erasure */ + if(g729a->decoder.serial[1] != 0) { + int j; + for (j=0; j < g729a->decoder.serial[1]; j++) { + if (g729a->decoder.serial[j+2] == 0) { + g729a->decoder.parm[0] = 1; /* frame erased */ + break; + } + } + } + else if(g729a->decoder.serial[0] != SYNC_WORD) { + g729a->decoder.parm[0] = 1; + } + if(g729a->decoder.parm[1] == 1) { + /* check parity and put 1 in parm[5] if parity error */ + g729a->decoder.parm[5] = Check_Parity_Pitch(g729a->decoder.parm[4], g729a->decoder.parm[5]); + } + + Decod_ld8a(g729a->decoder.parm, g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, &g729a->decoder.Vad); + Post_Filter(g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, g729a->decoder.Vad); /* Post-filter */ + Post_Process(g729a->decoder.synth, L_FRAME); + + memcpy(&((uint8_t*)*out_data)[160*i], g729a->decoder.synth, 160); + } + + + return out_size; } static tsk_bool_t tdav_codec_g729ab_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) -{ - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; - - if(tsk_striequals(att_name, "fmtp")){ - tsk_params_L_t* params = tsk_null; - const char* val_str; - if((params = tsk_params_fromstring(att_value, ";", tsk_true))){ - if((val_str = tsk_params_get_param_value(params, "annexb"))){ +{ + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; + + if(tsk_striequals(att_name, "fmtp")) { + tsk_params_L_t* params = tsk_null; + const char* val_str; + if((params = tsk_params_fromstring(att_value, ";", tsk_true))) { + if((val_str = tsk_params_get_param_value(params, "annexb"))) { g729a->encoder.vad_enable &= tsk_strequals(val_str, "yes") ? 1 : 0; - } - TSK_OBJECT_SAFE_FREE(params); - } - } - return tsk_true; + } + TSK_OBJECT_SAFE_FREE(params); + } + } + return tsk_true; } static char* tdav_codec_g729ab_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { - tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; - - if(tsk_striequals(att_name, "fmtp")){ - if(g729a->encoder.vad_enable){ - return tsk_strdup("annexb=yes"); - } - else{ - return tsk_strdup("annexb=no"); - } - } - return tsk_null; + tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; + + if(tsk_striequals(att_name, "fmtp")) { + if(g729a->encoder.vad_enable) { + return tsk_strdup("annexb=yes"); + } + else { + return tsk_strdup("annexb=no"); + } + } + return tsk_null; } @@ -287,18 +287,18 @@ static char* tdav_codec_g729ab_sdp_att_get(const tmedia_codec_t* codec, const ch */ static int16_t bin2int(int16_t no_of_bits, const int16_t *bitstream) { - int16_t value, i; - int16_t bit; - - value = 0; - for(i = 0; i < no_of_bits; i++){ - value <<= 1; - bit = *bitstream++; - if (bit == BIT_1){ - value += 1; - } - } - return(value); + int16_t value, i; + int16_t bit; + + value = 0; + for(i = 0; i < no_of_bits; i++) { + value <<= 1; + bit = *bitstream++; + if (bit == BIT_1) { + value += 1; + } + } + return(value); } /*---------------------------------------------------------------------------- @@ -314,21 +314,21 @@ static int16_t bin2int(int16_t no_of_bits, const int16_t *bitstream) */ static void int2bin(int16_t value, int16_t no_of_bits, int16_t *bitstream) { - int16_t *pt_bitstream; - int16_t i, bit; - - pt_bitstream = bitstream + no_of_bits; - - for (i = 0; i < no_of_bits; i++){ - bit = value & (int16_t)0x0001; /* get lsb */ - if (bit == 0){ - *--pt_bitstream = BIT_0; - } - else{ - *--pt_bitstream = BIT_1; - } - value >>= 1; - } + int16_t *pt_bitstream; + int16_t i, bit; + + pt_bitstream = bitstream + no_of_bits; + + for (i = 0; i < no_of_bits; i++) { + bit = value & (int16_t)0x0001; /* get lsb */ + if (bit == 0) { + *--pt_bitstream = BIT_0; + } + else { + *--pt_bitstream = BIT_1; + } + value >>= 1; + } } /** @@ -337,24 +337,24 @@ static void int2bin(int16_t value, int16_t no_of_bits, int16_t *bitstream) * @param bits ITU bitstream used as destination (0 - BIT_0, 1 - BIT_1) * @param len length of the RTP bitstream */ -static void unpack_G729(const uint8_t bitstream[], int16_t bits[], int len) -{ - int16_t i; - *bits++ = SYNC_WORD; /* bit[0], at receiver this bits indicates BFI */ - switch(len){ - case 10: - *bits++ = SIZE_WORD; - break; - case 8: // RATE_6400 - case 15: //RATE_11800 - default: - TSK_DEBUG_ERROR("%d is an invalid lenght value", len); - return; - } - - for(i=0; i<len; i++){ - int2bin(bitstream[i], 8, &bits[i*8]); - } +static void unpack_G729(const uint8_t bitstream[], int16_t bits[], int len) +{ + int16_t i; + *bits++ = SYNC_WORD; /* bit[0], at receiver this bits indicates BFI */ + switch(len) { + case 10: + *bits++ = SIZE_WORD; + break; + case 8: // RATE_6400 + case 15: //RATE_11800 + default: + TSK_DEBUG_ERROR("%d is an invalid lenght value", len); + return; + } + + for(i=0; i<len; i++) { + int2bin(bitstream[i], 8, &bits[i*8]); + } } /** @@ -363,11 +363,11 @@ static void unpack_G729(const uint8_t bitstream[], int16_t bits[], int len) * @param bits ITU bitstream used as destination (0 - BIT_0, 1 - BIT_1) */ static void unpack_SID(const uint8_t bitstream[], int16_t bits[]) -{ - *bits++ = SYNC_WORD; - *bits++ = RATE_SID_OCTET; - int2bin((int16_t)bitstream[0], 8, &bits[0]); - int2bin((int16_t)bitstream[1], 8, &bits[8]); +{ + *bits++ = SYNC_WORD; + *bits++ = RATE_SID_OCTET; + int2bin((int16_t)bitstream[0], 8, &bits[0]); + int2bin((int16_t)bitstream[1], 8, &bits[8]); } /** @@ -376,9 +376,9 @@ static void unpack_SID(const uint8_t bitstream[], int16_t bits[]) * @param bitstream RTP bitstream (80 bits, 5 shorts, 10 bytes) */ static void pack_G729(const int16_t ituBits[], uint8_t bitstream[]) -{ +{ int16_t word16, i; - for(i=0; i<5; i++){ + for(i=0; i<5; i++) { word16 = bin2int(16, (int16_t*)&ituBits[i*16]); bitstream[i*2] = word16>>8, bitstream[(i*2)+1] = (word16 & 0xFF); } @@ -390,10 +390,10 @@ static void pack_G729(const int16_t ituBits[], uint8_t bitstream[]) * @param bitstream RTP bitstream (15 bits, 1 short, 2 bytes) */ static void pack_SID(const int16_t ituBits[], uint8_t bitstream[]) -{ +{ int16_t word16 = bin2int(16, ituBits); bitstream[0] = word16>>8, bitstream[1] = (word16 & 0xFF); -} +} // @@ -403,63 +403,61 @@ static void pack_SID(const int16_t ituBits[], uint8_t bitstream[]) /* constructor */ static tsk_object_t* tdav_codec_g729ab_ctor(tsk_object_t * self, va_list * app) { - tdav_codec_g729ab_t *g729a = self; - if(g729a){ - /* init base: called by tmedia_codec_create() */ - /* init self */ - g729a->encoder.vad_enable = G729_ENABLE_VAD; // AnnexB - } - return self; + tdav_codec_g729ab_t *g729a = self; + if(g729a) { + /* init base: called by tmedia_codec_create() */ + /* init self */ + g729a->encoder.vad_enable = G729_ENABLE_VAD; // AnnexB + } + return self; } /* destructor */ static tsk_object_t* tdav_codec_g729ab_dtor(tsk_object_t * self) -{ - tdav_codec_g729ab_t *g729a = self; - if(g729a){ - /* deinit base */ - tmedia_codec_audio_deinit(g729a); - /* deinit self */ - - } - - return self; +{ + tdav_codec_g729ab_t *g729a = self; + if(g729a) { + /* deinit base */ + tmedia_codec_audio_deinit(g729a); + /* deinit self */ + + } + + return self; } /* object definition */ -static const tsk_object_def_t tdav_codec_g729ab_def_s = -{ - sizeof(tdav_codec_g729ab_t), - tdav_codec_g729ab_ctor, - tdav_codec_g729ab_dtor, - tmedia_codec_cmp, +static const tsk_object_def_t tdav_codec_g729ab_def_s = { + sizeof(tdav_codec_g729ab_t), + tdav_codec_g729ab_ctor, + tdav_codec_g729ab_dtor, + tmedia_codec_cmp, }; /* plugin definition*/ -static const tmedia_codec_plugin_def_t tdav_codec_g729ab_plugin_def_s = -{ - &tdav_codec_g729ab_def_s, - - tmedia_audio, - tmedia_codec_id_g729ab, - "g729", - "g729ab Codec (libg729)", - TMEDIA_CODEC_FORMAT_G729, - tsk_false, - 8000, // rate - - { /* audio */ - 1, // channels - 0 // ptime @deprecated - }, - - /* video */ - {0}, - - tdav_codec_g729ab_set, - tdav_codec_g729ab_open, - tdav_codec_g729ab_close, - tdav_codec_g729ab_encode, - tdav_codec_g729ab_decode, - tdav_codec_g729ab_sdp_att_match, - tdav_codec_g729ab_sdp_att_get +static const tmedia_codec_plugin_def_t tdav_codec_g729ab_plugin_def_s = { + &tdav_codec_g729ab_def_s, + + tmedia_audio, + tmedia_codec_id_g729ab, + "g729", + "g729ab Codec (libg729)", + TMEDIA_CODEC_FORMAT_G729, + tsk_false, + 8000, // rate + + { /* audio */ + 1, // channels + 0 // ptime @deprecated + }, + + /* video */ + {0}, + + tdav_codec_g729ab_set, + tdav_codec_g729ab_open, + tdav_codec_g729ab_close, + tdav_codec_g729ab_encode, + tdav_codec_g729ab_decode, + tdav_codec_g729ab_sdp_att_match, + tdav_codec_g729ab_sdp_att_get }; const tmedia_codec_plugin_def_t *tdav_codec_g729ab_plugin_def_t = &tdav_codec_g729ab_plugin_def_s; |