diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-03-16 18:52:55 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-03-16 18:52:55 +0000 |
commit | a069e683724dba8caa58c8079b40999e21f64190 (patch) | |
tree | 458b6b252798e2626c971036befa7484596100ec /pjmedia/src | |
parent | c0598144d962fbc8c20482bdc5e00e99ec62f8a9 (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.c | 18 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/endpoint.c | 10 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/errno.c | 1 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/nullsound.c | 28 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/pasound.c | 65 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/rtcp.c | 37 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/sound_port.c | 317 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/stream.c | 18 |
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")); |