Ignore:
Timestamp:
May 13, 2006 10:46:23 PM (18 years ago)
Author:
bennylp
Message:

Another major modifications in PJMEDIA:

  • handle multiple frames in one packet
  • split stream creation into two steps to allow customization
  • PLC framework and implementation with G.711 and speex
  • stream returns NO_FRAME correctly.
  • added ptime argument in pjsua
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/g711.c

    r429 r438  
    2424#include <pjmedia/errno.h> 
    2525#include <pjmedia/port.h> 
     26#include <pjmedia/plc.h> 
    2627#include <pj/pool.h> 
    2728#include <pj/string.h> 
     
    3132 
    3233 
    33 #define G711_BPS        64000 
    34 #define G711_CODEC_CNT  0       /* number of codec to preallocate in memory */ 
    35 #define PTIME           20 
    36 #define FRAME_SIZE      (8000 * PTIME / 1000) 
     34#define G711_BPS            64000 
     35#define G711_CODEC_CNT      0   /* number of codec to preallocate in memory */ 
     36#define PTIME               10  /* basic frame size is 10 msec      */ 
     37#define FRAME_SIZE          (8000 * PTIME / 1000)   /* 80 bytes     */ 
     38#define SAMPLES_PER_FRAME   (8000 * PTIME / 1000)   /* 80 samples   */ 
    3739 
    3840/* These are the only public functions exported to applications */ 
    39 PJ_DECL(pj_status_t) g711_init_factory (pjmedia_codec_factory *factory, pj_pool_t *pool); 
     41PJ_DECL(pj_status_t) g711_init_factory (pjmedia_codec_factory *factory,  
     42                                        pj_pool_t *pool); 
    4043 
    4144/* Algorithm prototypes. */ 
    42 unsigned char linear2alaw(int           pcm_val);   /* 2's complement (16-bit range) */ 
     45unsigned char linear2alaw(int           pcm_val); 
    4346int           alaw2linear(unsigned char a_val); 
    4447unsigned char linear2ulaw(int           pcm_val); 
     
    6669                               pjmedia_codec_param *attr ); 
    6770static pj_status_t  g711_close( pjmedia_codec *codec ); 
    68 static pj_status_t  g711_get_frames(pjmedia_codec *codec, 
    69                                     void *pkt, 
    70                                     pj_size_t pkt_size, 
    71                                     unsigned *frame_cnt, 
    72                                     pjmedia_frame frames[]); 
     71static pj_status_t  g711_parse(pjmedia_codec *codec, 
     72                               void *pkt, 
     73                               pj_size_t pkt_size, 
     74                               const pj_timestamp *timestamp, 
     75                               unsigned *frame_cnt, 
     76                               pjmedia_frame frames[]); 
    7377static pj_status_t  g711_encode( pjmedia_codec *codec,  
    7478                                 const struct pjmedia_frame *input, 
     
    7983                                 unsigned output_buf_len,  
    8084                                 struct pjmedia_frame *output); 
     85static pj_status_t  g711_recover( pjmedia_codec *codec, 
     86                                  unsigned output_buf_len, 
     87                                  struct pjmedia_frame *output); 
    8188 
    8289/* Definition for G711 codec operations. */ 
     
    8693    &g711_open, 
    8794    &g711_close, 
    88     &g711_get_frames, 
     95    &g711_parse, 
    8996    &g711_encode, 
    90     &g711_decode 
     97    &g711_decode, 
     98    &g711_recover 
    9199}; 
    92100 
     
    114122struct g711_private 
    115123{ 
    116     unsigned pt; 
     124    unsigned        pt; 
     125    pj_bool_t       plc_enabled; 
     126    pjmedia_plc    *plc; 
    117127}; 
    118128 
     
    218228 
    219229    /* It's sufficient to check payload type only. */ 
    220     return (id->pt==PJMEDIA_RTP_PT_PCMU || id->pt==PJMEDIA_RTP_PT_PCMA) ? 0 : -1; 
     230    return (id->pt==PJMEDIA_RTP_PT_PCMU || id->pt==PJMEDIA_RTP_PT_PCMA)? 0:-1; 
    221231} 
    222232 
     
    228238 
    229239    pj_memset(attr, 0, sizeof(pjmedia_codec_param)); 
    230     attr->clock_rate = 8000; 
    231     attr->channel_cnt = 1; 
    232     attr->avg_bps = G711_BPS; 
    233     attr->pcm_bits_per_sample = 16; 
    234     attr->ptime = PTIME; 
    235     attr->pt = id->pt; 
     240    attr->info.clock_rate = 8000; 
     241    attr->info.channel_cnt = 1; 
     242    attr->info.avg_bps = G711_BPS; 
     243    attr->info.pcm_bits_per_sample = 16; 
     244    attr->info.frm_ptime = PTIME; 
     245    attr->info.pt = (pj_uint8_t)id->pt; 
     246 
     247    /* Set default frames per packet to 2 (or 20ms) */ 
     248    attr->setting.frm_per_pkt = 2; 
     249 
     250    /* Enable plc by default. */ 
     251    attr->setting.plc = 1; 
    236252 
    237253    /* Default all flag bits disabled. */ 
     
    275291{ 
    276292    pjmedia_codec *codec = NULL; 
     293    pj_status_t status; 
    277294 
    278295    PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL); 
     
    293310        } 
    294311 
     312        /* Set the payload type */ 
    295313        codec_priv->pt = id->pt; 
     314 
     315        /* Create PLC, always with 10ms ptime */ 
     316        status = pjmedia_plc_create(g711_factory.pool, 8000, 80, 
     317                                    0, &codec_priv->plc); 
     318        if (status != PJ_SUCCESS) { 
     319            pj_mutex_unlock(g711_factory.mutex); 
     320            return status; 
     321        } 
    296322 
    297323        codec->factory = factory; 
     
    351377{ 
    352378    struct g711_private *priv = codec->codec_data; 
    353     priv->pt = attr->pt; 
     379    priv->pt = attr->info.pt; 
     380    priv->plc_enabled = (attr->setting.plc != 0); 
    354381    return PJ_SUCCESS; 
    355382} 
     
    362389} 
    363390 
    364 static pj_status_t  g711_get_frames(pjmedia_codec *codec, 
    365                                     void *pkt, 
    366                                     pj_size_t pkt_size, 
    367                                     unsigned *frame_cnt, 
    368                                     pjmedia_frame frames[]) 
     391static pj_status_t  g711_parse( pjmedia_codec *codec, 
     392                                void *pkt, 
     393                                pj_size_t pkt_size, 
     394                                const pj_timestamp *ts, 
     395                                unsigned *frame_cnt, 
     396                                pjmedia_frame frames[]) 
    369397{ 
    370398    unsigned count = 0; 
    371399 
    372400    PJ_UNUSED_ARG(codec); 
    373     PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL); 
     401 
     402    PJ_ASSERT_RETURN(ts && frame_cnt && frames, PJ_EINVAL); 
    374403 
    375404    while (pkt_size >= FRAME_SIZE && count < *frame_cnt) { 
    376         frames[0].type = PJMEDIA_FRAME_TYPE_AUDIO; 
    377         frames[0].buf = pkt; 
    378         frames[0].size = FRAME_SIZE; 
     405        frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 
     406        frames[count].buf = pkt; 
     407        frames[count].size = FRAME_SIZE; 
     408        frames[count].timestamp.u64 = ts->u64 + SAMPLES_PER_FRAME * count; 
    379409 
    380410        pkt = ((char*)pkt) + FRAME_SIZE; 
     
    434464 
    435465    /* Check output buffer length */ 
    436     if (output_buf_len < input->size * 2) 
    437         return PJMEDIA_CODEC_EPCMTOOSHORT; 
     466    PJ_ASSERT_RETURN(output_buf_len >= input->size * 2, 
     467                     PJMEDIA_CODEC_EPCMTOOSHORT); 
     468 
     469    /* Input buffer MUST have exactly 80 bytes long */ 
     470    PJ_ASSERT_RETURN(input->size == FRAME_SIZE,  
     471                     PJMEDIA_CODEC_EFRMINLEN); 
    438472 
    439473    /* Decode */ 
     
    462496    output->size = input->size * 2; 
    463497 
    464     return PJ_SUCCESS; 
    465 } 
    466  
     498    if (priv->plc_enabled) 
     499        pjmedia_plc_save( priv->plc, output->buf); 
     500 
     501    return PJ_SUCCESS; 
     502} 
     503 
     504static pj_status_t  g711_recover( pjmedia_codec *codec, 
     505                                  unsigned output_buf_len, 
     506                                  struct pjmedia_frame *output) 
     507{ 
     508    struct g711_private *priv = codec->codec_data; 
     509 
     510    if (!priv->plc_enabled) 
     511        return PJ_EINVALIDOP; 
     512 
     513    PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2,  
     514                     PJMEDIA_CODEC_EPCMTOOSHORT); 
     515 
     516    pjmedia_plc_generate(priv->plc, output->buf); 
     517    output->size = SAMPLES_PER_FRAME * 2; 
     518 
     519    return PJ_SUCCESS; 
     520} 
    467521 
    468522#endif  /* PJMEDIA_HAS_G711_CODEC */ 
Note: See TracChangeset for help on using the changeset viewer.