splitcomb.c
来自「基于sip协议的网络电话源码」· C语言 代码 · 共 641 行 · 第 1/2 页
C
641 行
out += ch_cnt; }}/* * "Write" a multichannel frame. This would split the multichannel frame * into individual mono channel, and write it to the appropriate port. */static pj_status_t put_frame(pjmedia_port *this_port, const pjmedia_frame *frame){ struct splitcomb *sc = (struct splitcomb*) this_port; unsigned ch; /* Handle null frame */ if (frame->type == PJMEDIA_FRAME_TYPE_NONE) { for (ch=0; ch < this_port->info.channel_count; ++ch) { pjmedia_port *port = sc->port_desc[ch].port; if (!port) continue; pjmedia_port_put_frame(port, frame); } return PJ_SUCCESS; } /* Not sure how we would handle partial frame, so better reject * it for now. */ PJ_ASSERT_RETURN(frame->size == this_port->info.bytes_per_frame, PJ_EINVAL); /* * Write mono frame into each channels */ for (ch=0; ch < this_port->info.channel_count; ++ch) { pjmedia_port *port = sc->port_desc[ch].port; if (!port) continue; if (!sc->port_desc[ch].reversed) { /* Write to normal port */ pjmedia_frame mono_frame; /* Extract the mono frame */ extract_mono_frame(frame->buf, sc->put_buf, ch, this_port->info.channel_count, frame->size * 8 / this_port->info.bits_per_sample / this_port->info.channel_count); mono_frame.buf = sc->put_buf; mono_frame.size = frame->size / this_port->info.channel_count; mono_frame.type = frame->type; mono_frame.timestamp.u64 = frame->timestamp.u64; /* Write */ pjmedia_port_put_frame(port, &mono_frame); } else { /* Write to reversed phase port */ struct reverse_port *rport = (struct reverse_port*)port; if (rport->dn_write_pos == rport->dn_read_pos) { /* Only report overflow if the frame is constantly read * by the 'consumer' of the reverse port. * It is possible that nobody reads the buffer, so causing * overflow to happen rapidly, and writing log message this * way does not seem to be wise. */ if (rport->dn_read_pos != rport->dn_overflow_pos) { rport->dn_overflow_pos = rport->dn_read_pos; LOG_DN_((THIS_FILE, "Overflow in downstream direction")); } /* Adjust write position */ rport->dn_write_pos = (rport->dn_write_pos + rport->buf_cnt/2) % rport->buf_cnt; } /* Extract mono-frame and put it in downstream buffer */ extract_mono_frame(frame->buf, rport->dnstream_buf[rport->dn_write_pos], ch, this_port->info.channel_count, frame->size * 8 / this_port->info.bits_per_sample / this_port->info.channel_count); rport->dn_write_pos = (rport->dn_write_pos + 1) % rport->buf_cnt; } } return PJ_SUCCESS;}/* * Get a multichannel frame. * This will get mono channel frame from each port and put the * mono frame into the multichannel frame. */static pj_status_t get_frame(pjmedia_port *this_port, pjmedia_frame *frame){ struct splitcomb *sc = (struct splitcomb*) this_port; unsigned ch; pj_bool_t has_frame = PJ_FALSE; /* Clear output frame */ pjmedia_zero_samples(frame->buf, this_port->info.samples_per_frame); /* Read frame from each port */ for (ch=0; ch < this_port->info.channel_count; ++ch) { pjmedia_port *port = sc->port_desc[ch].port; pjmedia_frame mono_frame; pj_status_t status; if (!port) continue; /* Read from the port */ if (sc->port_desc[ch].reversed == PJ_FALSE) { /* Read from normal port */ mono_frame.buf = sc->get_buf; mono_frame.size = port->info.bytes_per_frame; mono_frame.timestamp.u64 = frame->timestamp.u64; status = pjmedia_port_get_frame(port, &mono_frame); if (status != PJ_SUCCESS || mono_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) { continue; } /* Combine the mono frame into multichannel frame */ store_mono_frame(mono_frame.buf, frame->buf, ch, this_port->info.channel_count, mono_frame.size * 8 / this_port->info.bits_per_sample); frame->timestamp.u64 = mono_frame.timestamp.u64; } else { /* Read from temporary buffer for reverse port */ struct reverse_port *rport = (struct reverse_port*)port; /* Check for underflows */ if (rport->up_read_pos == rport->up_write_pos) { /* Only report underflow if the buffer is constantly filled * up at the other side. * It is possible that nobody writes the buffer, so causing * underflow to happen rapidly, and writing log message this * way does not seem to be wise. */ if (rport->up_write_pos != rport->up_underflow_pos) { rport->up_underflow_pos = rport->up_write_pos; LOG_UP_((THIS_FILE, "Underflow in upstream direction")); } /* Adjust read position */ rport->up_read_pos = (rport->up_write_pos - rport->buf_cnt/2) % rport->buf_cnt; } TRACE_UP_((THIS_FILE, "Upstream read at buffer pos %d", rport->up_read_pos)); /* Combine the mono frame into multichannel frame */ store_mono_frame(rport->upstream_buf[rport->up_read_pos], frame->buf, ch, this_port->info.channel_count, port->info.samples_per_frame); rport->up_read_pos = (rport->up_read_pos + 1) % rport->buf_cnt; } has_frame = PJ_TRUE; } /* Return NO_FRAME is we don't get any frames from downstream ports */ if (has_frame) { frame->type = PJMEDIA_FRAME_TYPE_AUDIO; frame->size = this_port->info.bytes_per_frame; } else frame->type = PJMEDIA_FRAME_TYPE_NONE; return PJ_SUCCESS;}static pj_status_t on_destroy(pjmedia_port *this_port){ /* Nothing to do */ PJ_UNUSED_ARG(this_port); return PJ_SUCCESS;}/* * Get a mono frame from a reversed phase channel. */static pj_status_t rport_put_frame(pjmedia_port *this_port, const pjmedia_frame *frame){ struct reverse_port *rport = (struct reverse_port*) this_port; unsigned count; pj_assert(frame->size <= rport->base.info.bytes_per_frame); /* Check for overflows */ if (rport->up_write_pos == rport->up_read_pos) { /* Only report overflow if the frame is constantly read * at the other end of the buffer (the multichannel side). * It is possible that nobody reads the buffer, so causing * overflow to happen rapidly, and writing log message this * way does not seem to be wise. */ if (rport->up_read_pos != rport->up_overflow_pos) { rport->up_overflow_pos = rport->up_read_pos; LOG_UP_((THIS_FILE, "Overflow in upstream direction")); } /* Adjust the write position */ rport->up_write_pos = (rport->up_read_pos + rport->buf_cnt/2) % rport->buf_cnt; } /* Handle NULL frame */ if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) { TRACE_UP_((THIS_FILE, "Upstream write %d null samples at buf pos %d", this_port->info.samples_per_frame, rport->up_write_pos)); pjmedia_zero_samples(rport->upstream_buf[rport->up_write_pos], this_port->info.samples_per_frame); rport->up_write_pos = (rport->up_write_pos+1) % rport->buf_cnt; return PJ_SUCCESS; } /* Not sure how to handle partial frame, so better reject for now */ PJ_ASSERT_RETURN(frame->size == this_port->info.bytes_per_frame, PJ_EINVAL); /* Copy normal frame to curcular buffer */ count = frame->size * 8 / this_port->info.bits_per_sample; TRACE_UP_((THIS_FILE, "Upstream write %d samples at buf pos %d", count, rport->up_write_pos)); pjmedia_copy_samples(rport->upstream_buf[rport->up_write_pos], frame->buf, count); rport->up_write_pos = (rport->up_write_pos+1) % rport->buf_cnt; return PJ_SUCCESS;}/* * Get a mono frame from a reversed phase channel. */static pj_status_t rport_get_frame(pjmedia_port *this_port, pjmedia_frame *frame){ struct reverse_port *rport = (struct reverse_port*) this_port; unsigned count; count = rport->base.info.samples_per_frame; frame->size = this_port->info.bytes_per_frame; frame->type = PJMEDIA_FRAME_TYPE_AUDIO; /* Check for underflows */ if (rport->dn_read_pos == rport->dn_write_pos) { /* Only report underflow if the buffer is constantly filled * up at the other side. * It is possible that nobody writes the buffer, so causing * underflow to happen rapidly, and writing log message this * way does not seem to be wise. */ if (rport->dn_write_pos != rport->dn_underflow_pos) { rport->dn_underflow_pos = rport->dn_write_pos; LOG_DN_((THIS_FILE, "Underflow in downstream direction")); } /* Adjust read position */ rport->dn_read_pos = (rport->dn_write_pos - rport->buf_cnt/2) % rport->buf_cnt; } /* Get the samples from the circular buffer */ pjmedia_copy_samples(frame->buf, rport->dnstream_buf[rport->dn_read_pos], count); rport->dn_read_pos = (rport->dn_read_pos+1) % rport->buf_cnt; return PJ_SUCCESS;}static pj_status_t rport_on_destroy(pjmedia_port *this_port){ /* Nothing to do */ PJ_UNUSED_ARG(this_port); return PJ_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?