Added Null port, and changed conference so that it does not call port get_frame() when there is no listener on the port

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@318 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2006-03-15 19:32:41 +00:00
parent 7f09ad7f18
commit de38058342
7 changed files with 198 additions and 11 deletions

View File

@ -120,6 +120,10 @@ SOURCE=..\src\pjmedia\jbuf.c
# End Source File
# Begin Source File
SOURCE=..\src\pjmedia\null_port.c
# End Source File
# Begin Source File
SOURCE=..\src\pjmedia\nullsound.c
# PROP Exclude_From_Build 1
# End Source File
@ -209,6 +213,10 @@ SOURCE=..\include\pjmedia\jbuf.h
# End Source File
# Begin Source File
SOURCE=..\include\pjmedia\null_port.h
# End Source File
# Begin Source File
SOURCE=..\include\pjmedia.h
# End Source File
# Begin Source File

View File

@ -32,6 +32,7 @@
#include <pjmedia/file_port.h>
#include <pjmedia/g711.h>
#include <pjmedia/jbuf.h>
#include <pjmedia/null_port.h>
#include <pjmedia/port.h>
#include <pjmedia/rtcp.h>
#include <pjmedia/rtp.h>

View File

@ -0,0 +1,53 @@
/* $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_NULL_PORT_H__
#define __PJMEDIA_NULL_PORT_H__
/**
* @file null_port.h
* @brief Null media port.
*/
#include <pjmedia/port.h>
PJ_BEGIN_DECL
/**
* Create Null port.
*
* @param sampling_rate Sampling rate of the port.
* @param samples_per_frame Number of samples per frame.
* @param bits_per_sample Number of bits per sample.
* @param p_port Pointer to receive the port instance.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
unsigned sampling_rate,
unsigned samples_per_frame,
unsigned bits_per_sample,
pjmedia_port **p_port );
PJ_END_DECL
#endif /* __PJMEDIA_NULL_PORT_H__ */

View File

@ -491,8 +491,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
unsigned index;
pj_status_t status;
PJ_ASSERT_RETURN(conf && pool && strm_port && port_name && p_port,
PJ_EINVAL);
PJ_ASSERT_RETURN(conf && pool && strm_port && port_name, PJ_EINVAL);
pj_mutex_lock(conf->mutex);
@ -522,7 +521,9 @@ PJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
conf->port_cnt++;
/* Done. */
*p_port = index;
if (p_port) {
*p_port = index;
}
pj_mutex_unlock(conf->mutex);
@ -1052,6 +1053,10 @@ static pj_status_t play_cb( /* in */ void *user_data,
continue;
}
/* Also skip if this port doesn't have listeners. */
if (conf_port->listener_cnt == 0)
continue;
/* Get frame from this port.
* For port zero (sound port), get the frame from the rx_buffer
* instead.
@ -1101,10 +1106,6 @@ static pj_status_t play_cb( /* in */ void *user_data,
}
}
/* Also skip if this port doesn't have listeners. */
if (conf_port->listener_cnt == 0)
continue;
/* Get the signal level. */
level = pjmedia_calc_avg_signal(output, conf->samples_per_frame);

View File

@ -0,0 +1,107 @@
/* $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/null_port.h>
#include <pjmedia/errno.h>
#include <pj/assert.h>
#include <pj/pool.h>
#include <pj/string.h>
static pj_status_t null_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t null_put_frame(pjmedia_port *this_port,
const pjmedia_frame *frame);
static pj_status_t null_on_destroy(pjmedia_port *this_port);
PJ_DEF(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
unsigned sampling_rate,
unsigned samples_per_frame,
unsigned bits_per_sample,
pjmedia_port **p_port )
{
pjmedia_port *port;
PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
port = pj_pool_zalloc(pool, sizeof(pjmedia_port));
PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
port->info.bits_per_sample = bits_per_sample;
port->info.bytes_per_frame = samples_per_frame * bits_per_sample / 8;
port->info.encoding_name = pj_str("pcm");
port->info.has_info = 1;
port->info.name = pj_str("null-port");
port->info.need_info = 0;
port->info.pt = 0xFF;
port->info.sample_rate = sampling_rate;
port->info.samples_per_frame = samples_per_frame;
port->info.signature = 0x2411;
port->info.type = PJMEDIA_TYPE_AUDIO;
port->get_frame = &null_get_frame;
port->put_frame = &null_put_frame;
port->on_destroy = &null_on_destroy;
*p_port = port;
return PJ_SUCCESS;
}
/*
* Put frame to file.
*/
static pj_status_t null_put_frame(pjmedia_port *this_port,
const pjmedia_frame *frame)
{
PJ_UNUSED_ARG(this_port);
PJ_UNUSED_ARG(frame);
return PJ_SUCCESS;
}
/*
* Get frame from file.
*/
static pj_status_t null_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame)
{
unsigned i, count;
pj_int16_t *samples = frame->buf;
count = this_port->info.samples_per_frame;
for (i=0; i<count; ++i) {
samples[i] = 0;
}
return PJ_SUCCESS;
}
/*
* Destroy port.
*/
static pj_status_t null_on_destroy(pjmedia_port *this_port)
{
PJ_UNUSED_ARG(this_port);
return PJ_SUCCESS;
}

View File

@ -64,7 +64,7 @@ PJ_BEGIN_DECL
* Aditional ports to be allocated in the conference ports for non-call
* streams.
*/
#define PJSUA_CONF_MORE_PORTS 2
#define PJSUA_CONF_MORE_PORTS 3
/**
@ -185,6 +185,8 @@ struct pjsua
pj_bool_t no_mic; /**< Disable microphone. */
char *wav_file; /**< WAV file name to play. */
unsigned wav_slot; /**< WAV player slot in bridge */
pjmedia_port *file_port; /**< WAV player port. */
pjmedia_port *null_port; /**< NULL port. */
pj_bool_t auto_play; /**< Auto play file for calls? */
pj_bool_t auto_loop; /**< Auto loop RTP stream? */
pj_bool_t auto_conf; /**< Auto put to conference? */

View File

@ -753,15 +753,22 @@ static pj_status_t init_media(void)
return status;
}
/* Add NULL port to the bridge. */
status = pjmedia_null_port_create( pjsua.pool, pjsua.clock_rate,
pjsua.clock_rate * 20 / 1000, 16,
&pjsua.null_port);
pjmedia_conf_add_port( pjsua.mconf, pjsua.pool, pjsua.null_port,
&pjsua.null_port->info.name, NULL );
/* Create WAV file player if required: */
if (pjsua.wav_file) {
pjmedia_port *port;
pj_str_t port_name;
/* Create the file player port. */
status = pjmedia_file_player_port_create( pjsua.pool, pjsua.wav_file,
0, -1, NULL, &port);
0, -1, NULL,
&pjsua.file_port);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE,
"Error playing media file",
@ -770,7 +777,8 @@ static pj_status_t init_media(void)
}
/* Add port to conference bridge: */
status = pjmedia_conf_add_port(pjsua.mconf, pjsua.pool, port,
status = pjmedia_conf_add_port(pjsua.mconf, pjsua.pool,
pjsua.file_port,
pj_cstr(&port_name, pjsua.wav_file),
&pjsua.wav_slot);
if (status != PJ_SUCCESS) {
@ -1049,6 +1057,13 @@ pj_status_t pjsua_destroy(void)
if (pjsua.mconf)
pjmedia_conf_destroy(pjsua.mconf);
/* Destroy file port */
pjmedia_port_destroy(pjsua.file_port);
/* Destroy null port. */
pjmedia_port_destroy(pjsua.null_port);
/* Destroy sound framework:
* (this should be done in pjmedia_shutdown())
*/