summaryrefslogtreecommitdiff
path: root/pjmedia/src
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-03-16 18:52:55 +0000
committerBenny Prijono <bennylp@teluu.com>2006-03-16 18:52:55 +0000
commita069e683724dba8caa58c8079b40999e21f64190 (patch)
tree458b6b252798e2626c971036befa7484596100ec /pjmedia/src
parentc0598144d962fbc8c20482bdc5e00e99ec62f8a9 (diff)
Added sound port (sound_port.h/c), and changed sound and RTCP names from pj_* to pjmedia_*
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@321 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r--pjmedia/src/pjmedia/conference.c18
-rw-r--r--pjmedia/src/pjmedia/endpoint.c10
-rw-r--r--pjmedia/src/pjmedia/errno.c1
-rw-r--r--pjmedia/src/pjmedia/nullsound.c28
-rw-r--r--pjmedia/src/pjmedia/pasound.c65
-rw-r--r--pjmedia/src/pjmedia/rtcp.c37
-rw-r--r--pjmedia/src/pjmedia/sound_port.c317
-rw-r--r--pjmedia/src/pjmedia/stream.c18
8 files changed, 412 insertions, 82 deletions
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index 3dbe7c5a..4c4eba6f 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -131,8 +131,8 @@ struct pjmedia_conf
unsigned max_ports; /**< Maximum ports. */
unsigned port_cnt; /**< Current number of ports. */
unsigned connect_cnt; /**< Total number of connections */
- pj_snd_stream *snd_rec; /**< Sound recorder stream. */
- pj_snd_stream *snd_player; /**< Sound player stream. */
+ pjmedia_snd_stream *snd_rec; /**< Sound recorder stream. */
+ pjmedia_snd_stream *snd_player; /**< Sound player stream. */
pj_mutex_t *mutex; /**< Conference mutex. */
struct conf_port **ports; /**< Array of ports. */
pj_uint16_t *uns_buf; /**< Buf for unsigned conversion */
@@ -382,7 +382,7 @@ static pj_status_t create_sound( pjmedia_conf *conf )
/* Open recorder only if mic is not disabled. */
if ((conf->options & PJMEDIA_CONF_NO_MIC) == 0) {
- status = pj_snd_open_recorder(-1, conf->clock_rate, 1,
+ status = pjmedia_snd_open_recorder(-1, conf->clock_rate, 1,
conf->samples_per_frame,
conf->bits_per_sample,
&rec_cb, conf, &conf->snd_rec);
@@ -393,13 +393,13 @@ static pj_status_t create_sound( pjmedia_conf *conf )
}
/* Open player */
- status = pj_snd_open_player(-1, conf->clock_rate, 1,
+ status = pjmedia_snd_open_player(-1, conf->clock_rate, 1,
conf->samples_per_frame,
conf->bits_per_sample,
&play_cb, conf, &conf->snd_player);
if (status != PJ_SUCCESS) {
if (conf->snd_rec) {
- pj_snd_stream_close(conf->snd_rec);
+ pjmedia_snd_stream_close(conf->snd_rec);
conf->snd_rec = NULL;
}
conf->snd_player = NULL;
@@ -415,11 +415,11 @@ static pj_status_t create_sound( pjmedia_conf *conf )
static pj_status_t destroy_sound( pjmedia_conf *conf )
{
if (conf->snd_rec) {
- pj_snd_stream_close(conf->snd_rec);
+ pjmedia_snd_stream_close(conf->snd_rec);
conf->snd_rec = NULL;
}
if (conf->snd_player) {
- pj_snd_stream_close(conf->snd_player);
+ pjmedia_snd_stream_close(conf->snd_player);
conf->snd_player = NULL;
}
return PJ_SUCCESS;
@@ -441,14 +441,14 @@ static pj_status_t resume_sound( pjmedia_conf *conf )
/* Start recorder. */
if (conf->snd_rec) {
- status = pj_snd_stream_start(conf->snd_rec);
+ status = pjmedia_snd_stream_start(conf->snd_rec);
if (status != PJ_SUCCESS)
goto on_error;
}
/* Start player. */
if (conf->snd_player) {
- status = pj_snd_stream_start(conf->snd_player);
+ status = pjmedia_snd_stream_start(conf->snd_player);
if (status != PJ_SUCCESS)
goto on_error;
}
diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c
index 99671017..71217b61 100644
--- a/pjmedia/src/pjmedia/endpoint.c
+++ b/pjmedia/src/pjmedia/endpoint.c
@@ -106,12 +106,12 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,
endpt->pf = pf;
/* Sound */
- pj_snd_init(pf);
+ pjmedia_snd_init(pf);
/* Init codec manager. */
status = pjmedia_codec_mgr_init(&endpt->codec_mgr);
if (status != PJ_SUCCESS) {
- pj_snd_deinit();
+ pjmedia_snd_deinit();
goto on_error;
}
@@ -122,13 +122,13 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,
status = g711_init_factory (factory, endpt->pool);
if (status != PJ_SUCCESS) {
- pj_snd_deinit();
+ pjmedia_snd_deinit();
goto on_error;
}
status = pjmedia_codec_mgr_register_factory (&endpt->codec_mgr, factory);
if (status != PJ_SUCCESS) {
- pj_snd_deinit();
+ pjmedia_snd_deinit();
goto on_error;
}
#endif
@@ -158,7 +158,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt)
endpt->pf = NULL;
- pj_snd_deinit();
+ pjmedia_snd_deinit();
pj_pool_release (endpt->pool);
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c
index b9886796..e6eeccdf 100644
--- a/pjmedia/src/pjmedia/errno.c
+++ b/pjmedia/src/pjmedia/errno.c
@@ -113,6 +113,7 @@ static const struct
{ PJMEDIA_ENCTYPE, "Media ports have incompatible media type" },
{ PJMEDIA_ENCBITS, "Media ports have incompatible bits per sample" },
{ PJMEDIA_ENCBYTES, "Media ports have incompatible bytes per frame" },
+ { PJMEDIA_ENCCHANNEL, "Media ports have incompatible number of channels" },
/* Media file errors: */
{ PJMEDIA_ENOTVALIDWAVE, "Not a valid WAVE file" },
diff --git a/pjmedia/src/pjmedia/nullsound.c b/pjmedia/src/pjmedia/nullsound.c
index ff4e92e7..9d454c08 100644
--- a/pjmedia/src/pjmedia/nullsound.c
+++ b/pjmedia/src/pjmedia/nullsound.c
@@ -21,7 +21,7 @@
#if defined(PJMEDIA_HAS_NULL_SOUND) && PJMEDIA_HAS_NULL_SOUND!=0
-static pj_snd_dev_info null_info =
+static pjmedia_snd_dev_info null_info =
{
"Null Device",
1,
@@ -30,31 +30,31 @@ static pj_snd_dev_info null_info =
};
-PJ_DEF(pj_status_t) pj_snd_init(pj_pool_factory *factory)
+PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)
{
PJ_UNUSED_ARG(factory);
return PJ_SUCCESS;
}
-PJ_DEF(int) pj_snd_get_dev_count(void)
+PJ_DEF(int) pjmedia_snd_get_dev_count(void)
{
return 1;
}
-PJ_DEF(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index)
+PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)
{
PJ_ASSERT_RETURN(index==0, NULL);
return &null_info;
}
-PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
+PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
unsigned clock_rate,
unsigned channel_count,
unsigned samples_per_frame,
unsigned bits_per_sample,
- pj_snd_rec_cb rec_cb,
+ pjmedia_snd_rec_cb rec_cb,
void *user_data,
- pj_snd_stream **p_snd_strm)
+ pjmedia_snd_stream **p_snd_strm)
{
PJ_UNUSED_ARG(index);
PJ_UNUSED_ARG(clock_rate);
@@ -69,14 +69,14 @@ PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pj_snd_open_player( int index,
+PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
unsigned clock_rate,
unsigned channel_count,
unsigned samples_per_frame,
unsigned bits_per_sample,
- pj_snd_play_cb play_cb,
+ pjmedia_snd_play_cb play_cb,
void *user_data,
- pj_snd_stream **p_snd_strm )
+ pjmedia_snd_stream **p_snd_strm )
{
PJ_UNUSED_ARG(index);
PJ_UNUSED_ARG(clock_rate);
@@ -91,25 +91,25 @@ PJ_DEF(pj_status_t) pj_snd_open_player( int index,
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pj_snd_stream_start(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)
{
PJ_UNUSED_ARG(stream);
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pj_snd_stream_stop(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream)
{
PJ_UNUSED_ARG(stream);
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pj_snd_stream_close(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
PJ_UNUSED_ARG(stream);
return PJ_SUCCESS;
}
-PJ_DEF(pj_status_t) pj_snd_deinit(void)
+PJ_DEF(pj_status_t) pjmedia_snd_deinit(void)
{
return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/pasound.c b/pjmedia/src/pjmedia/pasound.c
index 76b8d1bc..ffac434c 100644
--- a/pjmedia/src/pjmedia/pasound.c
+++ b/pjmedia/src/pjmedia/pasound.c
@@ -32,7 +32,7 @@ static struct snd_mgr
pj_pool_factory *factory;
} snd_mgr;
-struct pj_snd_stream
+struct pjmedia_snd_stream
{
pj_pool_t *pool;
pj_str_t name;
@@ -45,8 +45,8 @@ struct pj_snd_stream
pj_uint32_t underflow;
pj_uint32_t overflow;
void *user_data;
- pj_snd_rec_cb rec_cb;
- pj_snd_play_cb play_cb;
+ pjmedia_snd_rec_cb rec_cb;
+ pjmedia_snd_play_cb play_cb;
pj_bool_t quit_flag;
pj_bool_t thread_has_exited;
pj_bool_t thread_initialized;
@@ -62,7 +62,7 @@ static int PaRecorderCallback(const void *input,
PaStreamCallbackFlags statusFlags,
void *userData )
{
- pj_snd_stream *stream = userData;
+ pjmedia_snd_stream *stream = userData;
pj_status_t status;
PJ_UNUSED_ARG(output);
@@ -102,7 +102,7 @@ static int PaPlayerCallback( const void *input,
PaStreamCallbackFlags statusFlags,
void *userData )
{
- pj_snd_stream *stream = userData;
+ pjmedia_snd_stream *stream = userData;
pj_status_t status;
unsigned size = frameCount * stream->bytes_per_sample;
@@ -140,7 +140,7 @@ on_break:
/*
* Init sound library.
*/
-PJ_DEF(pj_status_t) pj_snd_init(pj_pool_factory *factory)
+PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)
{
int err;
@@ -151,16 +151,16 @@ PJ_DEF(pj_status_t) pj_snd_init(pj_pool_factory *factory)
PJ_LOG(4,(THIS_FILE, "PortAudio host api count=%d",
Pa_GetHostApiCount()));
PJ_LOG(4,(THIS_FILE, "Sound device count=%d",
- pj_snd_get_dev_count()));
+ pjmedia_snd_get_dev_count()));
- return err;
+ return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
/*
* Get device count.
*/
-PJ_DEF(int) pj_snd_get_dev_count(void)
+PJ_DEF(int) pjmedia_snd_get_dev_count(void)
{
return Pa_GetDeviceCount();
}
@@ -169,9 +169,9 @@ PJ_DEF(int) pj_snd_get_dev_count(void)
/*
* Get device info.
*/
-PJ_DEF(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index)
+PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)
{
- static pj_snd_dev_info info;
+ static pjmedia_snd_dev_info info;
const PaDeviceInfo *pa_info;
pa_info = Pa_GetDeviceInfo(index);
@@ -192,17 +192,17 @@ PJ_DEF(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index)
/*
* Open stream.
*/
-PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
+PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
unsigned clock_rate,
unsigned channel_count,
unsigned samples_per_frame,
unsigned bits_per_sample,
- pj_snd_rec_cb rec_cb,
+ pjmedia_snd_rec_cb rec_cb,
void *user_data,
- pj_snd_stream **p_snd_strm)
+ pjmedia_snd_stream **p_snd_strm)
{
pj_pool_t *pool;
- pj_snd_stream *stream;
+ pjmedia_snd_stream *stream;
PaStreamParameters inputParam;
int sampleFormat;
const PaDeviceInfo *paDevInfo = NULL;
@@ -277,17 +277,17 @@ PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
}
-PJ_DEF(pj_status_t) pj_snd_open_player( int index,
+PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
unsigned clock_rate,
unsigned channel_count,
unsigned samples_per_frame,
unsigned bits_per_sample,
- pj_snd_play_cb play_cb,
+ pjmedia_snd_play_cb play_cb,
void *user_data,
- pj_snd_stream **p_snd_strm)
+ pjmedia_snd_stream **p_snd_strm)
{
pj_pool_t *pool;
- pj_snd_stream *stream;
+ pjmedia_snd_stream *stream;
PaStreamParameters outputParam;
int sampleFormat;
const PaDeviceInfo *paDevInfo = NULL;
@@ -366,23 +366,23 @@ PJ_DEF(pj_status_t) pj_snd_open_player( int index,
/*
* Start stream.
*/
-PJ_DEF(pj_status_t) pj_snd_stream_start(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)
{
- pj_status_t status;
+ pj_status_t err;
PJ_LOG(5,(THIS_FILE, "Starting %s stream..", stream->name.ptr));
- status = Pa_StartStream(stream->stream);
+ err = Pa_StartStream(stream->stream);
- PJ_LOG(5,(THIS_FILE, "Done, status=%d", status));
+ PJ_LOG(5,(THIS_FILE, "Done, status=%d", err));
- return status;
+ return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
/*
* Stop stream.
*/
-PJ_DEF(pj_status_t) pj_snd_stream_stop(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream)
{
int i, err;
@@ -398,13 +398,13 @@ PJ_DEF(pj_status_t) pj_snd_stream_stop(pj_snd_stream *stream)
PJ_LOG(5,(THIS_FILE, "Done, status=%d", err));
- return err;
+ return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
/*
* Destroy stream.
*/
-PJ_DEF(pj_status_t) pj_snd_stream_close(pj_snd_stream *stream)
+PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
int i, err;
const PaDeviceInfo *paDevInfo;
@@ -423,17 +423,22 @@ PJ_DEF(pj_status_t) pj_snd_stream_close(pj_snd_stream *stream)
err = Pa_CloseStream(stream->stream);
pj_pool_release(stream->pool);
- return err;
+
+ return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
/*
* Deinitialize sound library.
*/
-PJ_DEF(pj_status_t) pj_snd_deinit(void)
+PJ_DEF(pj_status_t) pjmedia_snd_deinit(void)
{
+ int err;
+
PJ_LOG(4,(THIS_FILE, "PortAudio sound library shutting down.."));
- return Pa_Terminate();
+ err = Pa_Terminate();
+
+ return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/rtcp.c b/pjmedia/src/pjmedia/rtcp.c
index e43b8863..e9af1faa 100644
--- a/pjmedia/src/pjmedia/rtcp.c
+++ b/pjmedia/src/pjmedia/rtcp.c
@@ -31,7 +31,7 @@
/*
* Get NTP time.
*/
-static void rtcp_get_ntp_time(struct pj_rtcp_ntp_rec *ntp)
+static void rtcp_get_ntp_time(struct pjmedia_rtcp_ntp_rec *ntp)
{
pj_time_val tv;
@@ -44,11 +44,12 @@ static void rtcp_get_ntp_time(struct pj_rtcp_ntp_rec *ntp)
}
-PJ_DEF(void) pj_rtcp_init(pj_rtcp_session *s, pj_uint32_t ssrc)
+PJ_DEF(void) pjmedia_rtcp_init(pjmedia_rtcp_session *s,
+ pj_uint32_t ssrc)
{
- pj_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
+ pjmedia_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
- pj_memset(rtcp_pkt, 0, sizeof(pj_rtcp_pkt));
+ pj_memset(rtcp_pkt, 0, sizeof(pjmedia_rtcp_pkt));
/* Init time */
s->rtcp_lsr.hi = s->rtcp_lsr.lo = 0;
@@ -66,13 +67,13 @@ PJ_DEF(void) pj_rtcp_init(pj_rtcp_session *s, pj_uint32_t ssrc)
/* RR will be initialized on receipt of the first RTP packet. */
}
-PJ_DEF(void) pj_rtcp_fini(pj_rtcp_session *session)
+PJ_DEF(void) pjmedia_rtcp_fini(pjmedia_rtcp_session *session)
{
/* Nothing to do. */
PJ_UNUSED_ARG(session);
}
-static void rtcp_init_seq(pj_rtcp_session *s, pj_uint16_t seq)
+static void rtcp_init_seq(pjmedia_rtcp_session *s, pj_uint16_t seq)
{
s->received = 0;
s->expected_prior = 0;
@@ -83,7 +84,9 @@ static void rtcp_init_seq(pj_rtcp_session *s, pj_uint16_t seq)
pjmedia_rtp_seq_restart(&s->seq_ctrl, seq);
}
-PJ_DEF(void) pj_rtcp_rx_rtp(pj_rtcp_session *s, pj_uint16_t seq, pj_uint32_t rtp_ts)
+PJ_DEF(void) pjmedia_rtcp_rx_rtp(pjmedia_rtcp_session *s,
+ pj_uint16_t seq,
+ pj_uint32_t rtp_ts)
{
pj_uint32_t arrival;
pj_int32_t transit;
@@ -129,19 +132,21 @@ PJ_DEF(void) pj_rtcp_rx_rtp(pj_rtcp_session *s, pj_uint16_t seq, pj_uint32_t rtp
}
}
-PJ_DEF(void) pj_rtcp_tx_rtp(pj_rtcp_session *s, pj_uint16_t bytes_payload_size)
+PJ_DEF(void) pjmedia_rtcp_tx_rtp(pjmedia_rtcp_session *s,
+ pj_uint16_t bytes_payload_size)
{
- pj_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
+ pjmedia_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
rtcp_pkt->sr.sender_pcount = pj_htonl( pj_ntohl(rtcp_pkt->sr.sender_pcount) + 1);
rtcp_pkt->sr.sender_bcount = pj_htonl( pj_ntohl(rtcp_pkt->sr.sender_bcount) + bytes_payload_size );
}
-static void rtcp_build_rtcp(pj_rtcp_session *s, pj_uint32_t receiver_ssrc)
+static void rtcp_build_rtcp(pjmedia_rtcp_session *s,
+ pj_uint32_t receiver_ssrc)
{
pj_uint32_t expected;
pj_uint32_t u32;
pj_uint32_t expected_interval, received_interval, lost_interval;
- pj_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
+ pjmedia_rtcp_pkt *rtcp_pkt = &s->rtcp_pkt;
/* SSRC and last_seq */
rtcp_pkt->rr.ssrc = pj_htonl(receiver_ssrc);
@@ -175,10 +180,12 @@ static void rtcp_build_rtcp(pj_rtcp_session *s, pj_uint32_t receiver_ssrc)
}
}
-PJ_DEF(void) pj_rtcp_build_rtcp(pj_rtcp_session *session, pj_rtcp_pkt **ret_p_pkt, int *len)
+PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *session,
+ pjmedia_rtcp_pkt **ret_p_pkt,
+ int *len)
{
- pj_rtcp_pkt *rtcp_pkt = &session->rtcp_pkt;
- pj_rtcp_ntp_rec ntp;
+ pjmedia_rtcp_pkt *rtcp_pkt = &session->rtcp_pkt;
+ pjmedia_rtcp_ntp_rec ntp;
pj_time_val now;
rtcp_build_rtcp(session, session->peer_ssrc);
@@ -213,6 +220,6 @@ PJ_DEF(void) pj_rtcp_build_rtcp(pj_rtcp_session *session, pj_rtcp_pkt **ret_p_pk
/* Return pointer. */
*ret_p_pkt = rtcp_pkt;
- *len = sizeof(pj_rtcp_pkt);
+ *len = sizeof(pjmedia_rtcp_pkt);
}
diff --git a/pjmedia/src/pjmedia/sound_port.c b/pjmedia/src/pjmedia/sound_port.c
new file mode 100644
index 00000000..f3e285a2
--- /dev/null
+++ b/pjmedia/src/pjmedia/sound_port.c
@@ -0,0 +1,317 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/sound_port.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/string.h> /* pj_memset() */
+
+struct pjmedia_snd_port
+{
+ int snd_index;
+ pjmedia_snd_stream *snd_stream;
+ pjmedia_dir dir;
+ pjmedia_port *port;
+
+ unsigned clock_rate;
+ unsigned channel_count;
+ unsigned samples_per_frame;
+ unsigned bits_per_sample;
+};
+
+/*
+ * The callback called by sound player when it needs more samples to be
+ * played.
+ */
+static pj_status_t play_cb(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* out */ void *output,
+ /* out */ unsigned size)
+{
+ pjmedia_snd_port *snd_port = user_data;
+ pjmedia_port *port;
+ pjmedia_frame frame;
+ pj_status_t status;
+
+ /* We're risking accessing the port without holding any mutex.
+ * It's possible that port is disconnected then destroyed while
+ * we're trying to access it.
+ * But in the name of performance, we'll try this approach until
+ * someone complains when it crashes.
+ */
+ port = snd_port->port;
+ if (port == NULL)
+ goto no_frame;
+
+ frame.buf = output;
+ frame.size = size;
+ frame.timestamp.u32.lo = timestamp;
+
+ status = pjmedia_port_get_frame(port, &frame);
+ if (status != PJ_SUCCESS)
+ goto no_frame;
+
+ if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
+ goto no_frame;
+
+ return PJ_SUCCESS;
+
+no_frame:
+ pj_memset(output, 0, size);
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * The callback called by sound recorder when it has finished capturing a
+ * frame.
+ */
+static pj_status_t rec_cb(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* in */ const void *input,
+ /* in*/ unsigned size)
+{
+ pjmedia_snd_port *snd_port = user_data;
+ pjmedia_port *port;
+ pjmedia_frame frame;
+
+ /* We're risking accessing the port without holding any mutex.
+ * It's possible that port is disconnected then destroyed while
+ * we're trying to access it.
+ * But in the name of performance, we'll try this approach until
+ * someone complains when it crashes.
+ */
+ port = snd_port->port;
+ if (port == NULL)
+ return PJ_SUCCESS;
+
+ frame.buf = (void*)input;
+ frame.size = size;
+ frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+ frame.timestamp.u32.lo = timestamp;
+
+ pjmedia_port_put_frame(port, &frame);
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Start the sound stream.
+ * This may be called even when the sound stream has already been started.
+ */
+static pj_status_t start_sound_device( pjmedia_snd_port *snd_port )
+{
+ pj_status_t status;
+
+ /* Check if sound has been started. */
+ if (snd_port->snd_stream != NULL)
+ return PJ_SUCCESS;
+
+ /* Open sound stream. */
+ if (snd_port->dir == PJMEDIA_DIR_ENCODING) {
+ status = pjmedia_snd_open_recorder( snd_port->snd_index,
+ snd_port->clock_rate,
+ snd_port->channel_count,
+ snd_port->samples_per_frame,
+ snd_port->bits_per_sample,
+ &rec_cb,
+ snd_port,
+ &snd_port->snd_stream);
+ } else {
+ status = pjmedia_snd_open_player( snd_port->snd_index,
+ snd_port->clock_rate,
+ snd_port->channel_count,
+ snd_port->samples_per_frame,
+ snd_port->bits_per_sample,
+ &play_cb,
+ snd_port,
+ &snd_port->snd_stream);
+ }
+
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Start sound stream. */
+ status = pjmedia_snd_stream_start(snd_port->snd_stream);
+ if (status != PJ_SUCCESS) {
+ pjmedia_snd_stream_close(snd_port->snd_stream);
+ snd_port->snd_stream = NULL;
+ return status;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Stop the sound device.
+ * This may be called even when there's no sound device in the port.
+ */
+static pj_status_t stop_sound_device( pjmedia_snd_port *snd_port )
+{
+ /* Check if we have sound stream device. */
+ if (snd_port->snd_stream) {
+ pjmedia_snd_stream_stop(snd_port->snd_stream);
+ pjmedia_snd_stream_close(snd_port->snd_stream);
+ snd_port->snd_stream = NULL;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Create sound recorder port.
+ */
+PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port)
+{
+ pjmedia_snd_port *snd_port;
+
+ PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
+ PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
+
+ snd_port = pj_pool_zalloc(pool, sizeof(pjmedia_snd_port));
+ PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);
+
+ snd_port->snd_index = index;
+ snd_port->dir = PJMEDIA_DIR_ENCODING;
+ snd_port->clock_rate = clock_rate;
+ snd_port->channel_count = channel_count;
+ snd_port->samples_per_frame = samples_per_frame;
+ snd_port->bits_per_sample = bits_per_sample;
+
+ *p_port = snd_port;
+
+ /* Start sound device immediately.
+ * If there's no port connected, the sound callback will return
+ * empty signal.
+ */
+ return start_sound_device( snd_port );
+}
+
+
+/*
+ * Create sound player port.
+ */
+PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port)
+{
+ pjmedia_snd_port *snd_port;
+
+ PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
+ PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
+
+ snd_port = pj_pool_zalloc(pool, sizeof(pjmedia_snd_port));
+ PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);
+
+ snd_port->snd_index = index;
+ snd_port->dir = PJMEDIA_DIR_DECODING;
+ snd_port->clock_rate = clock_rate;
+ snd_port->channel_count = channel_count;
+ snd_port->samples_per_frame = samples_per_frame;
+ snd_port->bits_per_sample = bits_per_sample;
+
+ *p_port = snd_port;
+
+ /* Start sound device immediately.
+ * If there's no port connected, the sound callback will return
+ * empty signal.
+ */
+ return start_sound_device( snd_port );
+}
+
+
+/*
+ * Destroy port (also destroys the sound device).
+ */
+PJ_DEF(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port)
+{
+ PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);
+
+ return stop_sound_device(snd_port);
+}
+
+
+/*
+ * Connect a port.
+ */
+PJ_DEF(pj_status_t) pjmedia_snd_port_connect( pjmedia_snd_port *snd_port,
+ pjmedia_port *port)
+{
+ pjmedia_port_info *pinfo;
+
+ PJ_ASSERT_RETURN(snd_port && port, PJ_EINVAL);
+
+ /* Check that port has the same configuration as the sound device
+ * port.
+ */
+ pinfo = &port->info;
+ if (pinfo->sample_rate != snd_port->clock_rate)
+ return PJMEDIA_ENCCLOCKRATE;
+
+ if (pinfo->samples_per_frame != snd_port->samples_per_frame)
+ return PJMEDIA_ENCSAMPLESPFRAME;
+
+ if (pinfo->channel_count != snd_port->channel_count)
+ return PJMEDIA_ENCCHANNEL;
+
+ if (pinfo->bits_per_sample != snd_port->bits_per_sample)
+ return PJMEDIA_ENCBITS;
+
+ /* Port is okay. */
+ snd_port->port = port;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the connected port.
+ */
+PJ_DEF(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port)
+{
+ PJ_ASSERT_RETURN(snd_port, NULL);
+ return snd_port->port;
+}
+
+
+/*
+ * Disconnect port.
+ */
+PJ_DEF(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port)
+{
+ PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);
+
+ snd_port->port = NULL;
+
+ return PJ_SUCCESS;
+}
+
+
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index c2624b20..4c06f19f 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -99,7 +99,7 @@ struct pjmedia_stream
pj_sockaddr_in rem_src_rtp; /**< addr of src pkt from remote*/
unsigned rem_src_cnt; /**< if different, # of pkt rcv */
- pj_rtcp_session rtcp; /**< RTCP for incoming RTP. */
+ pjmedia_rtcp_session rtcp; /**< RTCP for incoming RTP. */
pj_bool_t quit_flag; /**< To signal thread exit. */
pj_thread_t *thread; /**< Jitter buffer's thread. */
@@ -520,7 +520,7 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg)
hdr->pt, pj_ntohs(hdr->seq)));
continue;
}
- pj_rtcp_rx_rtp(&stream->rtcp, pj_ntohs(hdr->seq), pj_ntohl(hdr->ts));
+ pjmedia_rtcp_rx_rtp(&stream->rtcp, pj_ntohs(hdr->seq), pj_ntohl(hdr->ts));
/* Update stat */
stream->stat.dec.pkt++;
@@ -720,7 +720,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
/* Init RTCP session: */
- pj_rtcp_init(&stream->rtcp, info->ssrc);
+ pjmedia_rtcp_init(&stream->rtcp, info->ssrc);
/* Create jitter buffer: */
@@ -789,8 +789,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
/*
if (stream->enc && stream->enc->snd_stream) {
- pj_snd_stream_stop(stream->enc->snd_stream);
- pj_snd_stream_close(stream->enc->snd_stream);
+ pjmedia_snd_stream_stop(stream->enc->snd_stream);
+ pjmedia_snd_stream_close(stream->enc->snd_stream);
stream->enc->snd_stream = NULL;
}
@@ -801,8 +801,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
/*
if (stream->dec && stream->dec->snd_stream) {
- pj_snd_stream_stop(stream->dec->snd_stream);
- pj_snd_stream_close(stream->dec->snd_stream);
+ pjmedia_snd_stream_stop(stream->dec->snd_stream);
+ pjmedia_snd_stream_close(stream->dec->snd_stream);
stream->dec->snd_stream = NULL;
}
@@ -857,7 +857,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream)
if (stream->enc && (stream->dir & PJMEDIA_DIR_ENCODING)) {
stream->enc->paused = 0;
- //pj_snd_stream_start(stream->enc->snd_stream);
+ //pjmedia_snd_stream_start(stream->enc->snd_stream);
PJ_LOG(4,(THIS_FILE, "Encoder stream started"));
} else {
PJ_LOG(4,(THIS_FILE, "Encoder stream paused"));
@@ -865,7 +865,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream)
if (stream->dec && (stream->dir & PJMEDIA_DIR_DECODING)) {
stream->dec->paused = 0;
- //pj_snd_stream_start(stream->dec->snd_stream);
+ //pjmedia_snd_stream_start(stream->dec->snd_stream);
PJ_LOG(4,(THIS_FILE, "Decoder stream started"));
} else {
PJ_LOG(4,(THIS_FILE, "Decoder stream paused"));