/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 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/splitcomb.h>
#include <pjmedia/delaybuf.h>
#include <pjmedia/errno.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/pool.h>


#define SIGNATURE	    PJMEDIA_SIG_PORT_SPLIT_COMB
#define SIGNATURE_PORT	    PJMEDIA_SIG_PORT_SPLIT_COMB_P
#define THIS_FILE	    "splitcomb.c"
#define TMP_SAMP_TYPE	    pj_int16_t

/* Maximum number of channels. */
#define MAX_CHANNELS	    16

/* Maximum number of buffers to be accommodated by delaybuf */
#define MAX_BUF_CNT	    PJMEDIA_SOUND_BUFFER_COUNT

/* Maximum number of burst before we pause the media flow */
#define MAX_BURST	    (buf_cnt + 6)

/* Maximum number of NULL frames received before we pause the
 * media flow.
 */
#define MAX_NULL_FRAMES	    (rport->max_burst)


/* Operations */
#define OP_PUT		    (1)
#define OP_GET		    (-1)


/* 
 * Media flow directions:
 *
 *             put_frame() +-----+
 *  UPSTREAM  ------------>|split|<--> DOWNSTREAM
 *            <------------|comb |
 *             get_frame() +-----+
 *
 */
enum sc_dir
{
    /* This is the media direction from the splitcomb to the 
     * downstream port(s), which happens when:
     *  - put_frame() is called to the splitcomb
     *  - get_frame() is called to the reverse channel port.
     */
    DIR_DOWNSTREAM,

    /* This is the media direction from the downstream port to 
     * the splitcomb, which happens when:
     *  - get_frame() is called to the splitcomb
     *  - put_frame() is called to the reverse channel port.
     */
    DIR_UPSTREAM
};



/*
 * This structure describes the splitter/combiner.
 */
struct splitcomb
{
    pjmedia_port      base;

    unsigned	      options;

    /* Array of ports, one for each channel */
    struct {
	pjmedia_port *port;
	pj_bool_t     reversed;
    } port_desc[MAX_CHANNELS];

    /* Temporary buffers needed to extract mono frame from
     * multichannel frame. We could use stack for this, but this
     * way it should be safer for devices with small stack size.
     */
    TMP_SAMP_TYPE    *get_buf;
    TMP_SAMP_TYPE    *put_buf;
};


/*
 * This structure describes reverse port.
 */
struct reverse_port
{
    pjmedia_port     base;
    struct splitcomb*parent;
    unsigned	     ch_num;

    /* Maximum burst before media flow is suspended.
     * With reverse port, it's possible that either end of the 
     * port doesn't actually process the media flow (meaning, it
     * stops calling get_frame()/put_frame()). When this happens,
     * the other end will encounter excessive underflow or overflow,
     * depending on which direction is not actively processed by
     * the stopping end.
     *
     * To avoid excessive underflow/overflow, the media flow will
     * be suspended once underflow/overflow goes over this max_burst
     * limit.
     */
    int		     max_burst;

    /* When the media interface port of the splitcomb or the reverse
     * channel port is registered to conference bridge, the bridge
     * will transmit NULL frames to the media port when the media
     * port is not receiving any audio from other slots (for example,
     * when no other slots are connected to the media port).
     *
     * When this happens, we will generate zero frame to our buffer,
     * to avoid underflow/overflow. But after too many NULL frames
     * are received, we will pause the media flow instead, to save
     * some processing.
     *
     * This value controls how many NULL frames can be received
     * before we suspend media flow for a particular direction.
     */
    unsigned	     max_null_frames;

    /* A reverse port need a temporary buffer to store frames
     * (because of the different phase, see splitcomb.h for details). 
     * Since we can not expect get_frame() and put_frame() to be
     * called evenly one after another, we use delay buffers to
     * accomodate the burst.
     *
     * We maintain state for each direction, hence the array. The
     * array is indexed by direction (sc_dir).
     */
    struct {

	/* The delay buffer where frames will be stored */
	pjmedia_delay_buf   *dbuf;

	/* Flag to indicate that audio flow on this direction
	 * is currently being suspended (perhaps because nothing
	 * is processing the frame on the other end).
	 */
	pj_bool_t	paused;

	/* Operation level. When the level exceeds a maximum value,
	 * the media flow on this direction will be paused.
	 */
	int		level;

	/* Timestamp. */
	pj_timestamp	ts;

	/* Number of NULL frames transmitted to this port so far.
	 * NULL frame indicate that nothing is transmitted, and 
	 * once we get too many of this, we should pause the media
	 * flow to reduce processing.
	 */
	unsigned	null_cnt;

    } buf[2];

    /* Must have temporary put buffer for the delay buf,
     * unfortunately.
     */
    pj_int16_t	      *tmp_up_buf;
};


/*
 * Prototypes.
 */
static pj_status_t put_frame(pjmedia_port *this_port, 
			     pjmedia_frame *frame);
static pj_status_t get_frame(pjmedia_port *this_port, 
			     pjmedia_frame *frame);
static pj_status_t on_destroy(pjmedia_port *this_port);

static pj_status_t rport_put_frame(pjmedia_port *this_port, 
				   pjmedia_frame *frame);
static pj_status_t rport_get_frame(pjmedia_port *this_port, 
				   pjmedia_frame *frame);
static pj_status_t rport_on_destroy(pjmedia_port *this_port);


/*
 * Create the splitter/combiner.
 */
PJ_DEF(pj_status_t) pjmedia_splitcomb_create( pj_pool_t *pool,
					      unsigned clock_rate,
					      unsigned channel_count,
					      unsigned samples_per_frame,
					      unsigned bits_per_sample,
					      unsigned options,
					      pjmedia_port **p_splitcomb)
{
    const pj_str_t name = pj_str("splitcomb");
    struct splitcomb *sc;

    /* Sanity check */
    PJ_ASSERT_RETURN(pool && clock_rate && channel_count &&
		     samples_per_frame && bits_per_sample &&
		     p_splitcomb, PJ_EINVAL);

    /* Only supports 16 bits per sample */
    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);

    *p_splitcomb = NULL;

    /* Create the splitter/combiner structure */
    sc = PJ_POOL_ZALLOC_T(pool, struct splitcomb);
    PJ_ASSERT_RETURN(sc != NULL, PJ_ENOMEM);

    /* Create temporary buffers */
    sc->get_buf = (TMP_SAMP_TYPE*)
		  pj_pool_alloc(pool, samples_per_frame * 
				      sizeof(TMP_SAMP_TYPE) /
				      channel_count);
    PJ_ASSERT_RETURN(sc->get_buf, PJ_ENOMEM);

    sc->put_buf = (TMP_SAMP_TYPE*)
		  pj_pool_alloc(pool, samples_per_frame * 
				      sizeof(TMP_SAMP_TYPE) /
				      channel_count);
    PJ_ASSERT_RETURN(sc->put_buf, PJ_ENOMEM);


    /* Save options */
    sc->options = options;

    /* Initialize port */
    pjmedia_port_info_init(&sc->base.info, &name, SIGNATURE, clock_rate,
			   channel_count, bits_per_sample, samples_per_frame);

    sc->base.put_frame = &put_frame;
    sc->base.get_frame = &get_frame;
    sc->base.on_destroy = &on_destroy;

    /* Init ports array */
    /*
    sc->port_desc = pj_pool_zalloc(pool, channel_count*sizeof(*sc->port_desc));
    */
    pj_bzero(sc->port_desc, sizeof(sc->port_desc));

    /* Done for now */
    *p_splitcomb = &sc->base;

    return PJ_SUCCESS;
}


/*
 * Attach media port with the same phase as the splitter/combiner.
 */
PJ_DEF(pj_status_t) pjmedia_splitcomb_set_channel( pjmedia_port *splitcomb,
						   unsigned ch_num,
						   unsigned options,
						   pjmedia_port *port)
{
    struct splitcomb *sc = (struct splitcomb*) splitcomb;

    /* Sanity check */
    PJ_ASSERT_RETURN(splitcomb && port, PJ_EINVAL);

    /* Make sure this is really a splitcomb port */
    PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);

    /* Check the channel number */
    PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);

    /* options is unused for now */
    PJ_UNUSED_ARG(options);

    sc->port_desc[ch_num].port = port;
    sc->port_desc[ch_num].reversed = PJ_FALSE;

    return PJ_SUCCESS;
}


/*
 * Create reverse phase port for the specified channel.
 */
PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
				      pjmedia_port *splitcomb,
				      unsigned ch_num,
				      unsigned options,
				      pjmedia_port **p_chport)
{
    const pj_str_t name = pj_str("scomb-rev");
    struct splitcomb *sc = (struct splitcomb*) splitcomb;
    struct reverse_port *rport;
    unsigned buf_cnt;
    const pjmedia_audio_format_detail *sc_afd, *p_afd;
    pjmedia_port *port;
    pj_status_t status;

    /* Sanity check */
    PJ_ASSERT_RETURN(pool && splitcomb, PJ_EINVAL);

    /* Make sure this is really a splitcomb port */
    PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);

    /* Check the channel number */
    PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);

    /* options is unused for now */
    PJ_UNUSED_ARG(options);

    sc_afd = pjmedia_format_get_audio_format_detail(&splitcomb->info.fmt, 1);

    /* Create the port */
    rport = PJ_POOL_ZALLOC_T(pool, struct reverse_port);
    rport->parent = sc;
    rport->ch_num = ch_num;

    /* Initialize port info... */
    port = &rport->base;
    pjmedia_port_info_init(&port->info, &name, SIGNATURE_PORT, 
			   sc_afd->clock_rate, 1,
			   sc_afd->bits_per_sample,
			   PJMEDIA_PIA_SPF(&splitcomb->info) /
				   sc_afd->channel_count);

    p_afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);

    /* ... and the callbacks */
    port->put_frame = &rport_put_frame;
    port->get_frame = &rport_get_frame;
    port->on_destroy = &rport_on_destroy;

    /* Buffer settings */
    buf_cnt = options & 0xFF;
    if (buf_cnt == 0)
	buf_cnt = MAX_BUF_CNT;

    rport->max_burst = MAX_BURST;
    rport->max_null_frames = MAX_NULL_FRAMES;

    /* Create downstream/put buffers */
    status = pjmedia_delay_buf_create(pool, "scombdb-dn",
				      p_afd->clock_rate,
				      PJMEDIA_PIA_SPF(&port->info),
				      p_afd->channel_count,
				      buf_cnt * p_afd->frame_time_usec / 1000,
				      0, &rport->buf[DIR_DOWNSTREAM].dbuf);
    if (status != PJ_SUCCESS) {
	return status;
    }

    /* Create upstream/get buffers */
    status = pjmedia_delay_buf_create(pool, "scombdb-up",
				      p_afd->clock_rate,
				      PJMEDIA_PIA_SPF(&port->info),
				      p_afd->channel_count,
				      buf_cnt * p_afd->frame_time_usec / 1000,
				      0, &rport->buf[DIR_UPSTREAM].dbuf);
    if (status != PJ_SUCCESS) {
	pjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);
	return status;
    }

    /* And temporary upstream/get buffer */
    rport->tmp_up_buf = (pj_int16_t*)
	                pj_pool_alloc(pool,
				      PJMEDIA_PIA_AVG_FSZ(&port->info));

    /* Save port in the splitcomb */
    sc->port_desc[ch_num].port = &rport->base;
    sc->port_desc[ch_num].reversed = PJ_TRUE;


    /* Done */
    *p_chport = port;
    return status;
}


/* 
 * Extract one mono frame from a multichannel frame. 
 */
static void extract_mono_frame( const pj_int16_t *in,
			        pj_int16_t *out,
				unsigned ch,
				unsigned ch_cnt,
				unsigned samples_count)
{
    unsigned i;

    in += ch;
    for (i=0; i<samples_count; ++i) {
	*out++ = *in;
	in += ch_cnt;
    }
}


/* 
 * Put one mono frame into a multichannel frame 
 */
static void store_mono_frame( const pj_int16_t *in,
			      pj_int16_t *out,
			      unsigned ch,
			      unsigned ch_cnt,
			      unsigned samples_count)
{
    unsigned i;

    out += ch;
    for (i=0; i<samples_count; ++i) {
	*out = *in++;
	out += ch_cnt;
    }
}

/* Update operation on the specified direction  */
static void op_update(struct reverse_port *rport, int dir, int op)
{
    char *dir_name[2] = {"downstream", "upstream"};

    rport->buf[dir].level += op;

    if (op == OP_PUT) {
	rport->buf[dir].ts.u64 += PJMEDIA_PIA_SPF(&rport->base.info);
    }

    if (rport->buf[dir].paused) {
	if (rport->buf[dir].level < -rport->max_burst) {
	    /* Prevent the level from overflowing and resets back to zero */
	    rport->buf[dir].level = -rport->max_burst;
	} else if (rport->buf[dir].level > rport->max_burst) {
	    /* Prevent the level from overflowing and resets back to zero */
	    rport->buf[dir].level = rport->max_burst;
	} else {
	    /* Level has fallen below max level, we can resume
	     * media flow.
	     */
	    PJ_LOG(5,(rport->base.info.name.ptr, 
		      "Resuming media flow on %s direction (level=%d)", 
		      dir_name[dir], rport->buf[dir].level));
	    rport->buf[dir].level = 0;
	    rport->buf[dir].paused = PJ_FALSE;

	    //This will cause disruption in audio, and it seems to be
	    //working fine without this anyway, so we disable it for now.
	    //pjmedia_delay_buf_learn(rport->buf[dir].dbuf);

	}
    } else {
	if (rport->buf[dir].level >= rport->max_burst ||
	    rport->buf[dir].level <= -rport->max_burst) 
	{
	    /* Level has reached maximum level, the other side of
	     * rport is not sending/retrieving frames. Pause the
	     * rport on this direction.
	     */
	    PJ_LOG(5,(rport->base.info.name.ptr, 
		      "Pausing media flow on %s direction (level=%d)", 
		      dir_name[dir], rport->buf[dir].level));
	    rport->buf[dir].paused = PJ_TRUE;
	}
    }
}


/*
 * "Write" a multichannel frame downstream. This would split 
 * the multichannel frame into individual mono channel, and write 
 * it to the appropriate port.
 */
static pj_status_t put_frame(pjmedia_port *this_port, 
			     pjmedia_frame *frame)
{
    struct splitcomb *sc = (struct splitcomb*) this_port;
    unsigned ch;

    /* Handle null frame */
    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {
	for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
	    pjmedia_port *port = sc->port_desc[ch].port;

	    if (!port) continue;

	    if (!sc->port_desc[ch].reversed) {
		pjmedia_port_put_frame(port, frame);
	    } else {
		struct reverse_port *rport = (struct reverse_port*)port;

		/* Update the number of NULL frames received. Once we have too
		 * many of this, we'll stop calling op_update() to let the
		 * media be suspended.
		 */

		if (++rport->buf[DIR_DOWNSTREAM].null_cnt > 
			rport->max_null_frames) 
		{
		    /* Prevent the counter from overflowing and resetting
		     * back to zero
		     */
		    rport->buf[DIR_DOWNSTREAM].null_cnt = 
			rport->max_null_frames + 1;
		    continue;
		}

		/* Write zero port to delaybuf so that it doesn't underflow. 
		 * If we don't do this, get_frame() on this direction will
		 * cause delaybuf to generate missing frame and the last
		 * frame transmitted to delaybuf will be replayed multiple
		 * times, which doesn't sound good.
		 */

		/* Update rport state. */
		op_update(rport, DIR_DOWNSTREAM, OP_PUT);

		/* Discard frame if rport is paused on this direction */
		if (rport->buf[DIR_DOWNSTREAM].paused)
		    continue;

		/* Generate zero frame. */
		pjmedia_zero_samples(sc->put_buf, 
				     PJMEDIA_PIA_SPF(&this_port->info));

		/* Put frame to delay buffer */
		pjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf,
				      sc->put_buf);

	    }
	}
	return PJ_SUCCESS;
    }

    /* Not sure how we would handle partial frame, so better reject
     * it for now.
     */
    PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),
		     PJ_EINVAL);

    /* 
     * Write mono frame into each channels 
     */
    for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
	pjmedia_port *port = sc->port_desc[ch].port;

	if (!port)
	    continue;

	/* Extract the mono frame to temporary buffer */
	extract_mono_frame((const pj_int16_t*)frame->buf, sc->put_buf, ch, 
			   PJMEDIA_PIA_CCNT(&this_port->info),
			   (unsigned)frame->size * 8 / 
			     PJMEDIA_PIA_BITS(&this_port->info) /
			     PJMEDIA_PIA_CCNT(&this_port->info));

	if (!sc->port_desc[ch].reversed) {
	    /* Write to normal port */
	    pjmedia_frame mono_frame;

	    mono_frame.buf = sc->put_buf;
	    mono_frame.size = frame->size / PJMEDIA_PIA_CCNT(&this_port->info);
	    mono_frame.type = frame->type;
	    mono_frame.timestamp.u64 = frame->timestamp.u64;

	    /* Write */
	    pjmedia_port_put_frame(port, &mono_frame);

	} else {
	    /* Write to reversed phase port */
	    struct reverse_port *rport = (struct reverse_port*)port;

	    /* Reset NULL frame counter */
	    rport->buf[DIR_DOWNSTREAM].null_cnt = 0;

	    /* Update rport state. */
	    op_update(rport, DIR_DOWNSTREAM, OP_PUT);

	    if (!rport->buf[DIR_DOWNSTREAM].paused) {
		pjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf, 
				      sc->put_buf);
	    }
	}
    }

    return PJ_SUCCESS;
}


/*
 * Get a multichannel frame upstream.
 * This will get mono channel frame from each port and put the
 * mono frame into the multichannel frame.
 */
static pj_status_t get_frame(pjmedia_port *this_port, 
			     pjmedia_frame *frame)
{
    struct splitcomb *sc = (struct splitcomb*) this_port;
    unsigned ch;
    pj_bool_t has_frame = PJ_FALSE;

    /* Read frame from each port */
    for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
	pjmedia_port *port = sc->port_desc[ch].port;
	pjmedia_frame mono_frame;
	pj_status_t status;

	if (!port) {
	    pjmedia_zero_samples(sc->get_buf, 
				 PJMEDIA_PIA_SPF(&this_port->info) /
				  PJMEDIA_PIA_CCNT(&this_port->info));

	} else if (sc->port_desc[ch].reversed == PJ_FALSE) {
	    /* Read from normal port */
	    mono_frame.buf = sc->get_buf;
	    mono_frame.size = PJMEDIA_PIA_AVG_FSZ(&port->info);
	    mono_frame.timestamp.u64 = frame->timestamp.u64;

	    status = pjmedia_port_get_frame(port, &mono_frame);
	    if (status != PJ_SUCCESS || 
		mono_frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
	    {
		pjmedia_zero_samples(sc->get_buf, 
				     PJMEDIA_PIA_SPF(&port->info));
	    }

	    frame->timestamp.u64 = mono_frame.timestamp.u64;

	} else {
	    /* Read from temporary buffer for reverse port */
	    struct reverse_port *rport = (struct reverse_port*)port;

	    /* Update rport state. */
	    op_update(rport, DIR_UPSTREAM, OP_GET);

	    if (!rport->buf[DIR_UPSTREAM].paused) {
		pjmedia_delay_buf_get(rport->buf[DIR_UPSTREAM].dbuf, 
				      sc->get_buf);

	    } else {
		pjmedia_zero_samples(sc->get_buf, 
				     PJMEDIA_PIA_SPF(&port->info));
	    }

	    frame->timestamp.u64 = rport->buf[DIR_UPSTREAM].ts.u64;
	}

	/* Combine the mono frame into multichannel frame */
	store_mono_frame(sc->get_buf, 
			 (pj_int16_t*)frame->buf, ch,
			 PJMEDIA_PIA_CCNT(&this_port->info),
			 PJMEDIA_PIA_SPF(&this_port->info) /
			  PJMEDIA_PIA_CCNT(&this_port->info));

	has_frame = PJ_TRUE;
    }

    /* Return NO_FRAME is we don't get any frames from downstream ports */
    if (has_frame) {
	frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
	frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
    } else
	frame->type = PJMEDIA_FRAME_TYPE_NONE;

    return PJ_SUCCESS;
}


static pj_status_t on_destroy(pjmedia_port *this_port)
{
    /* Nothing to do for the splitcomb
     * Reverse ports must be destroyed separately.
     */
    PJ_UNUSED_ARG(this_port);

    return PJ_SUCCESS;
}


/*
 * Put a frame in the reverse port (upstream direction). This frame
 * will be picked up by get_frame() above.
 */
static pj_status_t rport_put_frame(pjmedia_port *this_port, 
				   pjmedia_frame *frame)
{
    struct reverse_port *rport = (struct reverse_port*) this_port;

    pj_assert(frame->size <= PJMEDIA_PIA_AVG_FSZ(&rport->base.info));

    /* Handle NULL frame */
    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) {
	/* Update the number of NULL frames received. Once we have too
	 * many of this, we'll stop calling op_update() to let the
	 * media be suspended.
	 */
	if (++rport->buf[DIR_UPSTREAM].null_cnt > rport->max_null_frames) {
	    /* Prevent the counter from overflowing and resetting back 
	     * to zero
	     */
	    rport->buf[DIR_UPSTREAM].null_cnt = rport->max_null_frames + 1;
	    return PJ_SUCCESS;
	}

	/* Write zero port to delaybuf so that it doesn't underflow. 
	 * If we don't do this, get_frame() on this direction will
	 * cause delaybuf to generate missing frame and the last
	 * frame transmitted to delaybuf will be replayed multiple
	 * times, which doesn't sound good.
	 */

	/* Update rport state. */
	op_update(rport, DIR_UPSTREAM, OP_PUT);

	/* Discard frame if rport is paused on this direction */
	if (rport->buf[DIR_UPSTREAM].paused)
	    return PJ_SUCCESS;

	/* Generate zero frame. */
	pjmedia_zero_samples(rport->tmp_up_buf, 
			     PJMEDIA_PIA_SPF(&this_port->info));

	/* Put frame to delay buffer */
	return pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf, 
				     rport->tmp_up_buf);
    }

    /* Not sure how to handle partial frame, so better reject for now */
    PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),
		     PJ_EINVAL);

    /* Reset NULL frame counter */
    rport->buf[DIR_UPSTREAM].null_cnt = 0;

    /* Update rport state. */
    op_update(rport, DIR_UPSTREAM, OP_PUT);

    /* Discard frame if rport is paused on this direction */
    if (rport->buf[DIR_UPSTREAM].paused)
	return PJ_SUCCESS;

    /* Unfortunately must copy to temporary buffer since delay buf
     * modifies the frame content.
     */
    pjmedia_copy_samples(rport->tmp_up_buf, (const pj_int16_t*)frame->buf,
		         PJMEDIA_PIA_SPF(&this_port->info));

    /* Put frame to delay buffer */
    return pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf, 
				 rport->tmp_up_buf);
}


/* Get a mono frame from a reversed phase channel (downstream direction).
 * The frame is put by put_frame() call to the splitcomb.
 */
static pj_status_t rport_get_frame(pjmedia_port *this_port, 
				   pjmedia_frame *frame)
{
    struct reverse_port *rport = (struct reverse_port*) this_port;

    /* Update state */
    op_update(rport, DIR_DOWNSTREAM, OP_GET);

    /* Return no frame if media flow on this direction is being
     * paused.
     */
    if (rport->buf[DIR_DOWNSTREAM].paused) {
	frame->type = PJMEDIA_FRAME_TYPE_NONE;
	return PJ_SUCCESS;
    }

    /* Get frame from delay buffer */
    frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
    frame->timestamp.u64 = rport->buf[DIR_DOWNSTREAM].ts.u64;

    return pjmedia_delay_buf_get(rport->buf[DIR_DOWNSTREAM].dbuf, 
				 (short*)frame->buf);
}


static pj_status_t rport_on_destroy(pjmedia_port *this_port)
{
    struct reverse_port *rport = (struct reverse_port*) this_port;

    pjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);
    pjmedia_delay_buf_destroy(rport->buf[DIR_UPSTREAM].dbuf);

    return PJ_SUCCESS;
}

