Ignore:
Timestamp:
Mar 5, 2006 11:50:53 AM (18 years ago)
Author:
bennylp
Message:

Fixed serious flaw in GSM where encoder and decoder shared the same state!

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c

    r205 r281  
    9898 
    9999/* GSM codec private data. */ 
    100 struct gsm_private 
    101 { 
    102     int dummy; 
     100struct gsm_data 
     101{ 
     102    void    *encoder; 
     103    void    *decoder; 
    103104}; 
    104105 
     
    267268{ 
    268269    pjmedia_codec *codec; 
     270    struct gsm_data *gsm_data; 
    269271 
    270272    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL); 
     
    284286        codec->op = &gsm_op; 
    285287        codec->factory = factory; 
     288 
     289        gsm_data = pj_pool_zalloc(gsm_codec_factory.pool,  
     290                                  sizeof(struct gsm_data)); 
     291        codec->codec_data = gsm_data; 
    286292    } 
    287293 
    288294    pj_mutex_unlock(gsm_codec_factory.mutex); 
    289  
    290     pj_assert(codec->codec_data == NULL); 
    291295 
    292296    *p_codec = codec; 
     
    300304                                      pjmedia_codec *codec ) 
    301305{ 
     306    struct gsm_data *gsm_data; 
     307 
    302308    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL); 
    303309    PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL); 
    304310 
     311    gsm_data = codec->codec_data; 
     312 
    305313    /* Close codec, if it's not closed. */ 
    306     if (codec->codec_data != NULL) { 
    307         gsm_destroy(codec->codec_data); 
    308         codec->codec_data = NULL; 
    309     } 
     314    gsm_codec_close(codec); 
    310315 
    311316    /* Put in the free list. */ 
     
    343348                                   pjmedia_codec_param *attr ) 
    344349{ 
    345     pj_assert(codec->codec_data == NULL); 
     350    struct gsm_data *gsm_data = codec->codec_data; 
     351 
     352    pj_assert(gsm_data != NULL); 
     353    pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL); 
    346354 
    347355    PJ_UNUSED_ARG(attr); 
    348356 
    349     codec->codec_data = gsm_create(); 
    350     if (!codec->codec_data) 
     357    gsm_data->encoder = gsm_create(); 
     358    if (!gsm_data->encoder) 
    351359        return PJMEDIA_CODEC_EFAILED; 
    352360 
     361    gsm_data->decoder = gsm_create(); 
     362    if (!gsm_data->decoder) 
     363        return PJMEDIA_CODEC_EFAILED; 
     364 
    353365    return PJ_SUCCESS; 
    354366} 
     
    359371static pj_status_t gsm_codec_close( pjmedia_codec *codec ) 
    360372{ 
    361     pj_assert(codec->codec_data != NULL); 
    362  
    363     if (codec->codec_data) { 
    364         gsm_destroy(codec->codec_data); 
    365         codec->codec_data = NULL; 
     373    struct gsm_data *gsm_data = codec->codec_data; 
     374 
     375    pj_assert(gsm_data != NULL); 
     376 
     377    if (gsm_data->encoder) { 
     378        gsm_destroy(gsm_data->encoder); 
     379        gsm_data->encoder = NULL; 
     380    } 
     381    if (gsm_data->decoder) { 
     382        gsm_destroy(gsm_data->decoder); 
     383        gsm_data->decoder = NULL; 
    366384    } 
    367385 
     
    408426                                     struct pjmedia_frame *output) 
    409427{ 
    410     PJ_ASSERT_RETURN(codec && codec->codec_data && input && output, 
    411                      PJ_EINVAL); 
     428    struct gsm_data *gsm_data = codec->codec_data; 
     429 
     430    pj_assert(gsm_data != NULL); 
     431    PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 
    412432 
    413433    if (output_buf_len < 33) 
     
    417437        return PJMEDIA_CODEC_EPCMTOOSHORT; 
    418438 
    419     gsm_encode(codec->codec_data, (short*)input->buf,  
     439    gsm_encode(gsm_data->encoder, (short*)input->buf,  
    420440               (unsigned char*)output->buf); 
    421441 
     
    434454                                     struct pjmedia_frame *output) 
    435455{ 
    436     PJ_ASSERT_RETURN(codec && codec->codec_data && input && output, 
    437                      PJ_EINVAL); 
     456    struct gsm_data *gsm_data = codec->codec_data; 
     457 
     458    pj_assert(gsm_data != NULL); 
     459    PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 
    438460 
    439461    if (output_buf_len < 320) 
     
    443465        return PJMEDIA_CODEC_EFRMTOOSHORT; 
    444466 
    445     gsm_decode(codec->codec_data,  
     467    gsm_decode(gsm_data->decoder,  
    446468               (unsigned char*)input->buf,  
    447469               (short*)output->buf); 
Note: See TracChangeset for help on using the changeset viewer.