Changeset 1844 for pjproject/trunk/pjmedia/src/pjmedia/splitcomb.c
- Timestamp:
- Mar 4, 2008 3:37:45 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/splitcomb.c
r1840 r1844 49 49 #define OP_GET (-1) 50 50 51 /* Media flow directions */ 51 52 /* 53 * Media flow directions: 54 * 55 * put_frame() +-----+ 56 * UPSTREAM ------------>|split|<--> DOWNSTREAM 57 * <------------|comb | 58 * get_frame() +-----+ 59 * 60 */ 52 61 enum sc_dir 53 62 { 54 /* This is the direction from the splitcomb to the downstream 55 * port(s), or when put_frame() is called to the splitcomb. 63 /* This is the media direction from the splitcomb to the 64 * downstream port(s), which happens when: 65 * - put_frame() is called to the splitcomb 66 * - get_frame() is called to the reverse channel port. 56 67 */ 57 68 DIR_DOWNSTREAM, 58 69 59 /* This is the direction from the downstream port to the splitcomb, 60 * or when get_frame() is called to the splitcomb. 70 /* This is the media direction from the downstream port to 71 * the splitcomb, which happens when: 72 * - get_frame() is called to the splitcomb 73 * - put_frame() is called to the reverse channel port. 61 74 */ 62 75 DIR_UPSTREAM 63 76 }; 64 77 65 66 67 #if 068 # define TRACE_UP_(x) PJ_LOG(5,x)69 # define TRACE_DN_(x) PJ_LOG(5,x)70 #else71 # define TRACE_UP_(x)72 # define TRACE_DN_(x)73 #endif74 78 75 79 … … 107 111 unsigned ch_num; 108 112 109 /* Maximum burst before media flow is suspended */ 113 /* Maximum burst before media flow is suspended. 114 * With reverse port, it's possible that either end of the 115 * port doesn't actually process the media flow (meaning, it 116 * stops calling get_frame()/put_frame()). When this happens, 117 * the other end will encounter excessive underflow or overflow, 118 * depending on which direction is not actively processed by 119 * the stopping end. 120 * 121 * To avoid excessive underflow/overflow, the media flow will 122 * be suspended once underflow/overflow goes over this max_burst 123 * limit. 124 */ 110 125 int max_burst; 111 126 112 /* Maximum NULL frames received before media flow is suspended. */ 127 /* When the media interface port of the splitcomb or the reverse 128 * channel port is registered to conference bridge, the bridge 129 * will transmit NULL frames to the media port when the media 130 * port is not receiving any audio from other slots (for example, 131 * when no other slots are connected to the media port). 132 * 133 * When this happens, we will generate zero frame to our buffer, 134 * to avoid underflow/overflow. But after too many NULL frames 135 * are received, we will pause the media flow instead, to save 136 * some processing. 137 * 138 * This value controls how many NULL frames can be received 139 * before we suspend media flow for a particular direction. 140 */ 113 141 unsigned max_null_frames; 114 142 115 /* A reverse port need a temporary buffer to store frame 143 /* A reverse port need a temporary buffer to store frames 116 144 * (because of the different phase, see splitcomb.h for details). 117 145 * Since we can not expect get_frame() and put_frame() to be … … 314 342 port->on_destroy = &rport_on_destroy; 315 343 316 344 /* Buffer settings */ 317 345 buf_cnt = options & 0xFF; 318 346 if (buf_cnt == 0) … … 323 351 324 352 /* Create downstream/put buffers */ 325 status = pjmedia_delay_buf_create(pool, "scomb -down",353 status = pjmedia_delay_buf_create(pool, "scombdb-dn", 326 354 port->info.clock_rate, 327 355 port->info.samples_per_frame, … … 333 361 334 362 /* Create upstream/get buffers */ 335 status = pjmedia_delay_buf_create(pool, "scomb -up",363 status = pjmedia_delay_buf_create(pool, "scombdb-up", 336 364 port->info.clock_rate, 337 365 port->info.samples_per_frame, … … 446 474 447 475 /* 448 * "Write" a multichannel frame. This would split the multichannel frame 449 * into individual mono channel, and write it to the appropriate port. 476 * "Write" a multichannel frame downstream. This would split 477 * the multichannel frame into individual mono channel, and write 478 * it to the appropriate port. 450 479 */ 451 480 static pj_status_t put_frame(pjmedia_port *this_port, … … 466 495 } else { 467 496 struct reverse_port *rport = (struct reverse_port*)port; 468 469 /* Write zero port to delaybuf so that it doesn't underflow.470 * If we don't do this, get_frame() on this direction will471 * cause delaybuf to generate missing frame and the last472 * frame transmitted to delaybuf will be replayed multiple473 * times, which doesn't sound good.474 */475 497 476 498 /* Update the number of NULL frames received. Once we have too … … 490 512 } 491 513 514 /* Write zero port to delaybuf so that it doesn't underflow. 515 * If we don't do this, get_frame() on this direction will 516 * cause delaybuf to generate missing frame and the last 517 * frame transmitted to delaybuf will be replayed multiple 518 * times, which doesn't sound good. 519 */ 520 492 521 /* Update rport state. */ 493 522 op_update(rport, DIR_DOWNSTREAM, OP_PUT); … … 498 527 499 528 /* Generate zero frame. */ 500 pjmedia_zero_samples( rport->tmp_up_buf,529 pjmedia_zero_samples(sc->put_buf, 501 530 this_port->info.samples_per_frame); 502 531 503 532 /* Put frame to delay buffer */ 504 533 pjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf, 505 rport->tmp_up_buf);534 sc->put_buf); 506 535 507 536 } … … 566 595 567 596 /* 568 * Get a multichannel frame .597 * Get a multichannel frame upstream. 569 598 * This will get mono channel frame from each port and put the 570 599 * mono frame into the multichannel frame. … … 617 646 } else { 618 647 pjmedia_zero_samples(sc->get_buf, 619 rport->base.info.samples_per_frame);648 port->info.samples_per_frame); 620 649 } 621 650 … … 628 657 this_port->info.channel_count, 629 658 this_port->info.samples_per_frame); 630 631 632 659 633 660 has_frame = PJ_TRUE; … … 647 674 static pj_status_t on_destroy(pjmedia_port *this_port) 648 675 { 649 /* Nothing to do */ 676 /* Nothing to do for the splitcomb 677 * Reverse ports must be destroyed separately. 678 */ 650 679 PJ_UNUSED_ARG(this_port); 651 680 … … 655 684 656 685 /* 657 * Get a mono frame from a reversed phase channel. 686 * Put a frame in the reverse port (upstream direction). This frame 687 * will be picked up by get_frame() above. 658 688 */ 659 689 static pj_status_t rport_put_frame(pjmedia_port *this_port, … … 666 696 /* Handle NULL frame */ 667 697 if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) { 668 TRACE_UP_((THIS_FILE, "Upstream write %d null samples at buf pos %d",669 this_port->info.samples_per_frame, rport->up_write_pos));670 671 /* Write zero port to delaybuf so that it doesn't underflow.672 * If we don't do this, get_frame() on this direction will673 * cause delaybuf to generate missing frame and the last674 * frame transmitted to delaybuf will be replayed multiple675 * times, which doesn't sound good.676 */677 678 698 /* Update the number of NULL frames received. Once we have too 679 699 * many of this, we'll stop calling op_update() to let the … … 688 708 } 689 709 710 /* Write zero port to delaybuf so that it doesn't underflow. 711 * If we don't do this, get_frame() on this direction will 712 * cause delaybuf to generate missing frame and the last 713 * frame transmitted to delaybuf will be replayed multiple 714 * times, which doesn't sound good. 715 */ 716 690 717 /* Update rport state. */ 691 718 op_update(rport, DIR_UPSTREAM, OP_PUT); … … 730 757 731 758 732 /* 733 * Get a mono frame from a reversed phase channel.759 /* Get a mono frame from a reversed phase channel (downstream direction). 760 * The frame is put by put_frame() call to the splitcomb. 734 761 */ 735 762 static pj_status_t rport_get_frame(pjmedia_port *this_port,
Note: See TracChangeset
for help on using the changeset viewer.