summaryrefslogtreecommitdiff
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
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
-rw-r--r--pjmedia/build/pjmedia.dsp8
-rw-r--r--pjmedia/include/pjmedia/errno.h5
-rw-r--r--pjmedia/include/pjmedia/port.h1
-rw-r--r--pjmedia/include/pjmedia/rtcp.h69
-rw-r--r--pjmedia/include/pjmedia/sound.h87
-rw-r--r--pjmedia/include/pjmedia/sound_port.h165
-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
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c5
15 files changed, 678 insertions, 156 deletions
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
index a4bbbbb5..a84395a0 100644
--- a/pjmedia/build/pjmedia.dsp
+++ b/pjmedia/build/pjmedia.dsp
@@ -168,6 +168,10 @@ SOURCE=..\src\pjmedia\silencedet.c
# End Source File
# Begin Source File
+SOURCE=..\src\pjmedia\sound_port.c
+# End Source File
+# Begin Source File
+
SOURCE=..\src\pjmedia\stream.c
# End Source File
# End Group
@@ -256,6 +260,10 @@ SOURCE=..\include\pjmedia\sound.h
# End Source File
# Begin Source File
+SOURCE=..\include\pjmedia\sound_port.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\pjmedia\stream.h
# End Source File
# Begin Source File
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index 7537744a..3d95c44a 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -415,6 +415,11 @@ PJ_BEGIN_DECL
* Incompatible bytes per frame
*/
#define PJMEDIA_ENCBYTES (PJMEDIA_ERRNO_START+165) /* 220165 */
+/**
+ * @hideinitializer
+ * Incompatible number of channels
+ */
+#define PJMEDIA_ENCCHANNEL (PJMEDIA_ERRNO_START+166) /* 220166 */
/************************************************************
diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h
index 5437061a..196e7139 100644
--- a/pjmedia/include/pjmedia/port.h
+++ b/pjmedia/include/pjmedia/port.h
@@ -78,6 +78,7 @@ struct pjmedia_port_info
unsigned pt; /**< Payload type (can be dynamic). */
pj_str_t encoding_name; /**< Encoding name. */
unsigned sample_rate; /**< Sampling rate. */
+ unsigned channel_count; /**< Number of channels. */
unsigned bits_per_sample; /**< Bits/sample */
unsigned samples_per_frame; /**< No of samples per frame. */
unsigned bytes_per_frame; /**< No of samples per frame. */
diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h
index d0873e72..f39c7800 100644
--- a/pjmedia/include/pjmedia/rtcp.h
+++ b/pjmedia/include/pjmedia/rtcp.h
@@ -39,7 +39,7 @@ PJ_BEGIN_DECL
/**
* RTCP sender report.
*/
-struct pj_rtcp_sr
+struct pjmedia_rtcp_sr
{
pj_uint32_t ssrc; /**< SSRC identification. */
pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
@@ -50,14 +50,14 @@ struct pj_rtcp_sr
};
/**
- * @see pj_rtcp_sr
+ * @see pjmedia_rtcp_sr
*/
-typedef struct pj_rtcp_sr pj_rtcp_sr;
+typedef struct pjmedia_rtcp_sr pjmedia_rtcp_sr;
/**
* RTCP receiver report.
*/
-struct pj_rtcp_rr
+struct pjmedia_rtcp_rr
{
pj_uint32_t ssrc; /**< SSRC identification. */
#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
@@ -78,15 +78,15 @@ struct pj_rtcp_rr
};
/**
- * @see pj_rtcp_rr
+ * @see pjmedia_rtcp_rr
*/
-typedef struct pj_rtcp_rr pj_rtcp_rr;
+typedef struct pjmedia_rtcp_rr pjmedia_rtcp_rr;
/**
* RTCP common header.
*/
-struct pj_rtcp_common
+struct pjmedia_rtcp_common
{
#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
unsigned version:2; /**< packet type */
@@ -103,48 +103,48 @@ struct pj_rtcp_common
};
/**
- * @see pj_rtcp_common
+ * @see pjmedia_rtcp_common
*/
-typedef struct pj_rtcp_common pj_rtcp_common;
+typedef struct pjmedia_rtcp_common pjmedia_rtcp_common;
/**
* RTCP packet.
*/
-struct pj_rtcp_pkt
+struct pjmedia_rtcp_pkt
{
- pj_rtcp_common common; /**< Common header. */
- pj_rtcp_sr sr; /**< Sender report. */
- pj_rtcp_rr rr; /**< variable-length list */
+ pjmedia_rtcp_common common; /**< Common header. */
+ pjmedia_rtcp_sr sr; /**< Sender report. */
+ pjmedia_rtcp_rr rr; /**< variable-length list */
};
/**
- * @see pj_rtcp_pkt
+ * @see pjmedia_rtcp_pkt
*/
-typedef struct pj_rtcp_pkt pj_rtcp_pkt;
+typedef struct pjmedia_rtcp_pkt pjmedia_rtcp_pkt;
/**
* NTP time representation.
*/
-struct pj_rtcp_ntp_rec
+struct pjmedia_rtcp_ntp_rec
{
pj_uint32_t hi; /**< High order 32-bit part. */
pj_uint32_t lo; /**< Lo order 32-bit part. */
};
/**
- * @see pj_rtcp_ntp_rec
+ * @see pjmedia_rtcp_ntp_rec
*/
-typedef struct pj_rtcp_ntp_rec pj_rtcp_ntp_rec;
+typedef struct pjmedia_rtcp_ntp_rec pjmedia_rtcp_ntp_rec;
/**
* RTCP session.
*/
-struct pj_rtcp_session
+struct pjmedia_rtcp_session
{
- pj_rtcp_pkt rtcp_pkt; /**< Cached RTCP packet. */
+ pjmedia_rtcp_pkt rtcp_pkt; /**< Cached RTCP packet. */
pjmedia_rtp_seq_session seq_ctrl; /**< RTCP sequence number control. */
@@ -154,16 +154,16 @@ struct pj_rtcp_session
pj_int32_t transit; /**< Relative trans time for prev pkt */
pj_uint32_t jitter; /**< Estimated jitter */
- pj_rtcp_ntp_rec rtcp_lsr; /**< NTP ts in last SR received */
- unsigned rtcp_lsr_time; /**< Time when last SR is received. */
- pj_uint32_t peer_ssrc; /**< Peer SSRC */
+ pjmedia_rtcp_ntp_rec rtcp_lsr; /**< NTP ts in last SR received */
+ unsigned rtcp_lsr_time; /**< Time when last SR is received.*/
+ pj_uint32_t peer_ssrc; /**< Peer SSRC */
};
/**
- * @see pj_rtcp_session
+ * @see pjmedia_rtcp_session
*/
-typedef struct pj_rtcp_session pj_rtcp_session;
+typedef struct pjmedia_rtcp_session pjmedia_rtcp_session;
/**
@@ -172,7 +172,8 @@ typedef struct pj_rtcp_session pj_rtcp_session;
* @param session The session
* @param ssrc The SSRC used in to identify the session.
*/
-PJ_DECL(void) pj_rtcp_init( pj_rtcp_session *session, pj_uint32_t ssrc );
+PJ_DECL(void) pjmedia_rtcp_init( pjmedia_rtcp_session *session,
+ pj_uint32_t ssrc );
/**
@@ -180,7 +181,7 @@ PJ_DECL(void) pj_rtcp_init( pj_rtcp_session *session, pj_uint32_t ssrc );
*
* @param session The session.
*/
-PJ_DECL(void) pj_rtcp_fini( pj_rtcp_session *session);
+PJ_DECL(void) pjmedia_rtcp_fini( pjmedia_rtcp_session *session);
/**
@@ -191,8 +192,9 @@ PJ_DECL(void) pj_rtcp_fini( pj_rtcp_session *session);
* @param seq The RTP packet sequence number, in host byte order.
* @param ts The RTP packet timestamp, in host byte order.
*/
-PJ_DECL(void) pj_rtcp_rx_rtp( pj_rtcp_session *session, pj_uint16_t seq,
- pj_uint32_t ts );
+PJ_DECL(void) pjmedia_rtcp_rx_rtp( pjmedia_rtcp_session *session,
+ pj_uint16_t seq,
+ pj_uint32_t ts );
/**
@@ -203,7 +205,8 @@ PJ_DECL(void) pj_rtcp_rx_rtp( pj_rtcp_session *session, pj_uint16_t seq,
* @param ptsize The payload size of the RTP packet (ie packet minus
* RTP header) in bytes.
*/
-PJ_DECL(void) pj_rtcp_tx_rtp( pj_rtcp_session *session, pj_uint16_t ptsize );
+PJ_DECL(void) pjmedia_rtcp_tx_rtp( pjmedia_rtcp_session *session,
+ pj_uint16_t ptsize );
/**
@@ -215,9 +218,9 @@ PJ_DECL(void) pj_rtcp_tx_rtp( pj_rtcp_session *session, pj_uint16_t ptsize );
* @param len [output] Upon return, it will indicate the size of
* the RTCP packet.
*/
-PJ_DECL(void) pj_rtcp_build_rtcp( pj_rtcp_session *session,
- pj_rtcp_pkt **rtcp_pkt,
- int *len );
+PJ_DECL(void) pjmedia_rtcp_build_rtcp( pjmedia_rtcp_session *session,
+ pjmedia_rtcp_pkt **rtcp_pkt,
+ int *len );
/**
diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h
index 5719c0f9..3d0b444e 100644
--- a/pjmedia/include/pjmedia/sound.h
+++ b/pjmedia/include/pjmedia/sound.h
@@ -36,18 +36,18 @@ PJ_BEGIN_DECL
*/
/** Opaque data type for audio stream. */
-typedef struct pj_snd_stream pj_snd_stream;
+typedef struct pjmedia_snd_stream pjmedia_snd_stream;
/**
- * Device information structure returned by #pj_snd_get_dev_info.
+ * Device information structure returned by #pjmedia_snd_get_dev_info.
*/
-typedef struct pj_snd_dev_info
+typedef struct pjmedia_snd_dev_info
{
char name[64]; /**< Device name. */
unsigned input_count; /**< Max number of input channels. */
unsigned output_count; /**< Max number of output channels. */
unsigned default_samples_per_sec;/**< Default sampling rate. */
-} pj_snd_dev_info;
+} pjmedia_snd_dev_info;
/**
* This callback is called by player stream when it needs additional data
@@ -62,7 +62,7 @@ typedef struct pj_snd_dev_info
*
* @return Non-zero to stop the stream.
*/
-typedef pj_status_t (*pj_snd_play_cb)(/* in */ void *user_data,
+typedef pj_status_t (*pjmedia_snd_play_cb)(/* in */ void *user_data,
/* in */ pj_uint32_t timestamp,
/* out */ void *output,
/* out */ unsigned size);
@@ -78,7 +78,7 @@ typedef pj_status_t (*pj_snd_play_cb)(/* in */ void *user_data,
*
* @return Non-zero to stop the stream.
*/
-typedef pj_status_t (*pj_snd_rec_cb)(/* in */ void *user_data,
+typedef pj_status_t (*pjmedia_snd_rec_cb)(/* in */ void *user_data,
/* in */ pj_uint32_t timestamp,
/* in */ const void *input,
/* in*/ unsigned size);
@@ -90,7 +90,7 @@ typedef pj_status_t (*pj_snd_rec_cb)(/* in */ void *user_data,
*
* @return Zero on success.
*/
-PJ_DECL(pj_status_t) pj_snd_init(pj_pool_factory *factory);
+PJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory);
/**
@@ -98,57 +98,72 @@ PJ_DECL(pj_status_t) pj_snd_init(pj_pool_factory *factory);
*
* @return Number of devices.
*/
-PJ_DECL(int) pj_snd_get_dev_count(void);
+PJ_DECL(int) pjmedia_snd_get_dev_count(void);
/**
* Get device info.
*
* @param index The index of the device, which should be in the range
- * from zero to #pj_snd_get_dev_count - 1.
+ * from zero to #pjmedia_snd_get_dev_count - 1.
*/
-PJ_DECL(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index);
+PJ_DECL(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index);
/**
* Create a new audio stream for audio capture purpose.
*
- * @param index Device index, or -1 to let the library choose the first
- * available device, or -2 to use NULL device.
- * @param param Stream parameters.
- * @param rec_cb Callback to handle captured audio samples.
- * @param user_data User data to be associated with the stream.
- *
- * @return Audio stream, or NULL if failed.
- */
-PJ_DECL(pj_status_t) pj_snd_open_recorder( int index,
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param rec_cb Callback to handle captured audio samples.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(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);
/**
* Create a new audio stream for playing audio samples.
*
- * @param index Device index, or -1 to let the library choose the first
- * available device, or -2 to use NULL device.
- * @param param Stream parameters.
- * @param play_cb Callback to supply audio samples.
- * @param user_data User data to be associated with the stream.
- *
- * @return Audio stream, or NULL if failed.
- */
-PJ_DECL(pj_status_t) pj_snd_open_player( int index,
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param play_cb Callback to be called when the sound player needs
+ * more audio samples to play.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(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 );
/**
* Start the stream.
@@ -157,7 +172,7 @@ PJ_DECL(pj_status_t) pj_snd_open_player( int index,
*
* @return Zero on success.
*/
-PJ_DECL(pj_status_t) pj_snd_stream_start(pj_snd_stream *stream);
+PJ_DECL(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream);
/**
* Stop the stream.
@@ -166,7 +181,7 @@ PJ_DECL(pj_status_t) pj_snd_stream_start(pj_snd_stream *stream);
*
* @return Zero on success.
*/
-PJ_DECL(pj_status_t) pj_snd_stream_stop(pj_snd_stream *stream);
+PJ_DECL(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream);
/**
* Destroy the stream.
@@ -175,14 +190,14 @@ PJ_DECL(pj_status_t) pj_snd_stream_stop(pj_snd_stream *stream);
*
* @return Zero on success.
*/
-PJ_DECL(pj_status_t) pj_snd_stream_close(pj_snd_stream *stream);
+PJ_DECL(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream);
/**
* Deinitialize sound library.
*
* @return Zero on success.
*/
-PJ_DECL(pj_status_t) pj_snd_deinit(void);
+PJ_DECL(pj_status_t) pjmedia_snd_deinit(void);
diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h
new file mode 100644
index 00000000..c7d1153d
--- /dev/null
+++ b/pjmedia/include/pjmedia/sound_port.h
@@ -0,0 +1,165 @@
+/* $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
+ */
+#ifndef __PJMEDIA_SOUND_PORT_H__
+#define __PJMEDIA_SOUND_PORT_H__
+
+/**
+ * @file sound_port.h
+ * @brief Media port connection abstraction to sound device.
+ */
+#include <pjmedia/sound.h>
+#include <pjmedia/port.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_SND_PORT Media Port Connection Abstraction to Sound Device
+ * @ingroup PJMEDIA
+ * @{
+ */
+
+/**
+ * This opaque type describes sound device port connection.
+ * Sound device port is not a media port, but it is used to connect media
+ * port to the sound device.
+ */
+typedef struct pjmedia_snd_port pjmedia_snd_port;
+
+/**
+ * Create sound device port for capturing audio streams from the sound device
+ * with the specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag, currently must be zero.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(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);
+
+/**
+ * Create sound device port for playing audio streams with the specified
+ * parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag, currently must be zero.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(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);
+
+
+/**
+ * Destroy sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Connect a port to the sound device port. If the sound device port is a
+ * sound recorder device, then this will start periodic function call to
+ * the port's put_frame() function. If the sound device is a sound player
+ * device, then this will start periodic function call to the port's
+ * get_frame() function.
+ *
+ * For this version of PJMEDIA, the media port MUST have the same audio
+ * settings as the sound device port, or otherwise the connection will
+ * fail. This means the port MUST have the same clock_rate, channel count,
+ * samples per frame, and bits per sample as the sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_connect(pjmedia_snd_port *snd_port,
+ pjmedia_port *port);
+
+
+/**
+ * Retrieve the port instance currently attached to the sound port, if any.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return The port instance currently attached to the
+ * sound device port, or NULL if there is no port
+ * currently attached to the sound device port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Disconnect currently attached port from the sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SOUND_PORT_H__ */
+
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"));
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index dd71f135..85fe70f1 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -1084,11 +1084,6 @@ pj_status_t pjsua_destroy(void)
pjmedia_port_destroy(pjsua.null_port);
- /* Destroy sound framework:
- * (this should be done in pjmedia_shutdown())
- */
- pj_snd_deinit();
-
/* Shutdown all codecs: */
for (i = pjsua.codec_cnt-1; i >= 0; --i) {
(*pjsua.codec_deinit[i])();