Changeset 438 for pjproject/trunk/pjmedia/src/pjmedia/g711.c
- Timestamp:
- May 13, 2006 10:46:23 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/g711.c
r429 r438 24 24 #include <pjmedia/errno.h> 25 25 #include <pjmedia/port.h> 26 #include <pjmedia/plc.h> 26 27 #include <pj/pool.h> 27 28 #include <pj/string.h> … … 31 32 32 33 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 */ 37 39 38 40 /* 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); 41 PJ_DECL(pj_status_t) g711_init_factory (pjmedia_codec_factory *factory, 42 pj_pool_t *pool); 40 43 41 44 /* Algorithm prototypes. */ 42 unsigned char linear2alaw(int pcm_val); /* 2's complement (16-bit range) */45 unsigned char linear2alaw(int pcm_val); 43 46 int alaw2linear(unsigned char a_val); 44 47 unsigned char linear2ulaw(int pcm_val); … … 66 69 pjmedia_codec_param *attr ); 67 70 static 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[]); 71 static 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[]); 73 77 static pj_status_t g711_encode( pjmedia_codec *codec, 74 78 const struct pjmedia_frame *input, … … 79 83 unsigned output_buf_len, 80 84 struct pjmedia_frame *output); 85 static pj_status_t g711_recover( pjmedia_codec *codec, 86 unsigned output_buf_len, 87 struct pjmedia_frame *output); 81 88 82 89 /* Definition for G711 codec operations. */ … … 86 93 &g711_open, 87 94 &g711_close, 88 &g711_ get_frames,95 &g711_parse, 89 96 &g711_encode, 90 &g711_decode 97 &g711_decode, 98 &g711_recover 91 99 }; 92 100 … … 114 122 struct g711_private 115 123 { 116 unsigned pt; 124 unsigned pt; 125 pj_bool_t plc_enabled; 126 pjmedia_plc *plc; 117 127 }; 118 128 … … 218 228 219 229 /* 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; 221 231 } 222 232 … … 228 238 229 239 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; 236 252 237 253 /* Default all flag bits disabled. */ … … 275 291 { 276 292 pjmedia_codec *codec = NULL; 293 pj_status_t status; 277 294 278 295 PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL); … … 293 310 } 294 311 312 /* Set the payload type */ 295 313 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 } 296 322 297 323 codec->factory = factory; … … 351 377 { 352 378 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); 354 381 return PJ_SUCCESS; 355 382 } … … 362 389 } 363 390 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[]) 391 static 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[]) 369 397 { 370 398 unsigned count = 0; 371 399 372 400 PJ_UNUSED_ARG(codec); 373 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL); 401 402 PJ_ASSERT_RETURN(ts && frame_cnt && frames, PJ_EINVAL); 374 403 375 404 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; 379 409 380 410 pkt = ((char*)pkt) + FRAME_SIZE; … … 434 464 435 465 /* 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); 438 472 439 473 /* Decode */ … … 462 496 output->size = input->size * 2; 463 497 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 504 static 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 } 467 521 468 522 #endif /* PJMEDIA_HAS_G711_CODEC */
Note: See TracChangeset
for help on using the changeset viewer.