/* $Id$ */
/*
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 *
 * 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/vid_port.h>
#include <pjmedia/clock.h>
#include <pjmedia/converter.h>
#include <pjmedia/errno.h>
#include <pjmedia/event.h>
#include <pjmedia/vid_codec.h>
#include <pj/log.h>
#include <pj/pool.h>


#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)


#define SIGNATURE	PJMEDIA_SIG_VID_PORT
#define THIS_FILE	"vid_port.c"

typedef struct vid_pasv_port vid_pasv_port;

enum role
{
    ROLE_NONE,
    ROLE_ACTIVE,
    ROLE_PASSIVE
};

struct pjmedia_vid_port
{
    pj_pool_t               *pool;
    pj_str_t                 dev_name;
    pjmedia_dir              dir;
//    pjmedia_rect_size        cap_size;
    pjmedia_vid_dev_stream  *strm;
    pjmedia_vid_dev_cb       strm_cb;
    void                    *strm_cb_data;
    enum role                role,
                             stream_role;
    vid_pasv_port           *pasv_port;
    pjmedia_port            *client_port;
    pj_bool_t                destroy_client_port;

    struct {
        pjmedia_converter	*conv;
        void		        *conv_buf;
        pj_size_t		 conv_buf_size;
        pjmedia_conversion_param conv_param;
        unsigned                 usec_ctr;
        unsigned                 usec_src, usec_dst;
    } conv;

    pjmedia_clock           *clock;
    pjmedia_clock_src        clocksrc;

    struct sync_clock_src_t
    {
        pjmedia_clock_src   *sync_clocksrc;
        pj_int32_t           sync_delta;
        unsigned             max_sync_ticks;
        unsigned             nsync_frame;
        unsigned             nsync_progress;
    } sync_clocksrc;

    pjmedia_frame           *frm_buf;
    pj_size_t                frm_buf_size;
    pj_mutex_t              *frm_mutex;
};

struct vid_pasv_port
{
    pjmedia_port	 base;
    pjmedia_vid_port	*vp;
};

static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,
				    void *user_data,
				    pjmedia_frame *frame);
static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,
				       void *user_data,
				       pjmedia_frame *frame);
static pj_status_t vidstream_event_cb(pjmedia_event *event,
                                      void *user_data);
static pj_status_t client_port_event_cb(pjmedia_event *event,
                                        void *user_data);

static void enc_clock_cb(const pj_timestamp *ts, void *user_data);
static void dec_clock_cb(const pj_timestamp *ts, void *user_data);

static pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,
					   pjmedia_frame *frame);

static pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,
					   pjmedia_frame *frame);


PJ_DEF(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm)
{
    pj_bzero(prm, sizeof(*prm));
    prm->active = PJ_TRUE;
}

static const char *vid_dir_name(pjmedia_dir dir)
{
    switch (dir) {
    case PJMEDIA_DIR_CAPTURE:
	return "capture";
    case PJMEDIA_DIR_RENDER:
	return "render";
    default:
	return "??";
    }
}

static pj_status_t create_converter(pjmedia_vid_port *vp)
{
    if (vp->conv.conv) {
        pjmedia_converter_destroy(vp->conv.conv);
	vp->conv.conv = NULL;
    }

    /* Instantiate converter if necessary */
    if (vp->conv.conv_param.src.id != vp->conv.conv_param.dst.id ||
	(vp->conv.conv_param.src.det.vid.size.w !=
         vp->conv.conv_param.dst.det.vid.size.w) ||
	(vp->conv.conv_param.src.det.vid.size.h !=
         vp->conv.conv_param.dst.det.vid.size.h))
    {
	pj_status_t status;

	/* Yes, we need converter */
	status = pjmedia_converter_create(NULL, vp->pool, &vp->conv.conv_param,
					  &vp->conv.conv);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(4,(THIS_FILE, status, "Error creating converter"));
	    return status;
	}
    }

    if (vp->conv.conv ||
        (vp->role==ROLE_ACTIVE && (vp->dir & PJMEDIA_DIR_ENCODING)))
    {
	pj_status_t status;
	const pjmedia_video_format_info *vfi;
	pjmedia_video_apply_fmt_param vafp;

	/* Allocate buffer for conversion */
	vfi = pjmedia_get_video_format_info(NULL, vp->conv.conv_param.dst.id);
	if (!vfi)
	    return PJMEDIA_EBADFMT;

	pj_bzero(&vafp, sizeof(vafp));
	vafp.size = vp->conv.conv_param.dst.det.vid.size;
	status = vfi->apply_fmt(vfi, &vafp);
	if (status != PJ_SUCCESS)
	    return PJMEDIA_EBADFMT;

	if (vafp.framebytes > vp->conv.conv_buf_size) {
	    vp->conv.conv_buf = pj_pool_alloc(vp->pool, vafp.framebytes);
	    vp->conv.conv_buf_size = vafp.framebytes;
	}
    }

    vp->conv.usec_ctr = 0;
    vp->conv.usec_src = PJMEDIA_PTIME(&vp->conv.conv_param.src.det.vid.fps);
    vp->conv.usec_dst = PJMEDIA_PTIME(&vp->conv.conv_param.dst.det.vid.fps);

    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
					     const pjmedia_vid_port_param *prm,
					     pjmedia_vid_port **p_vid_port)
{
    pjmedia_vid_port *vp;
    const pjmedia_video_format_detail *vfd;
    char dev_name[64];
    char fmt_name[5];
    pjmedia_vid_dev_cb vid_cb;
    pj_bool_t need_frame_buf = PJ_FALSE;
    pj_status_t status;
    unsigned ptime_usec;
    pjmedia_vid_dev_param vparam;
    pjmedia_vid_dev_info di;
    unsigned i;

    PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL);
    PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO &&
                     prm->vidparam.dir != PJMEDIA_DIR_NONE &&
                     prm->vidparam.dir != PJMEDIA_DIR_CAPTURE_RENDER,
		     PJ_EINVAL);

    /* Retrieve the video format detail */
    vfd = pjmedia_format_get_video_format_detail(&prm->vidparam.fmt, PJ_TRUE);
    if (!vfd)
	return PJ_EINVAL;

    PJ_ASSERT_RETURN(vfd->fps.num, PJ_EINVAL);

    /* Allocate videoport */
    vp = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_port);
    vp->pool = pj_pool_create(pool->factory, "video port", 500, 500, NULL);
    vp->role = prm->active ? ROLE_ACTIVE : ROLE_PASSIVE;
    vp->dir = prm->vidparam.dir;
//    vp->cap_size = vfd->size;

    vparam = prm->vidparam;
    dev_name[0] = '\0';

    /* Get device info */
    if (vp->dir & PJMEDIA_DIR_CAPTURE)
        status = pjmedia_vid_dev_get_info(prm->vidparam.cap_id, &di);
    else
        status = pjmedia_vid_dev_get_info(prm->vidparam.rend_id, &di);
    if (status != PJ_SUCCESS)
        return status;

    pj_ansi_snprintf(dev_name, sizeof(dev_name), "%s [%s]",
                     di.name, di.driver);

    for (i = 0; i < di.fmt_cnt; ++i) {
        if (prm->vidparam.fmt.id == di.fmt[i].id)
            break;
    }

    if (i == di.fmt_cnt) {
        /* The device has no no matching format. Pick one from
         * the supported formats, and later use converter to
         * convert it to the required format.
         */
        pj_assert(di.fmt_cnt != 0);
        vparam.fmt.id = di.fmt[0].id;
    }

    pj_strdup2_with_null(pool, &vp->dev_name, di.name);
    vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;

    pjmedia_fourcc_name(vparam.fmt.id, fmt_name);

    PJ_LOG(4,(THIS_FILE,
	      "Opening device %s for %s: format=%s, size=%dx%d @%d:%d fps",
	      dev_name,
	      vid_dir_name(prm->vidparam.dir), fmt_name,
	      vfd->size.w, vfd->size.h,
	      vfd->fps.num, vfd->fps.denum));

    ptime_usec = PJMEDIA_PTIME(&vfd->fps);
    pjmedia_clock_src_init(&vp->clocksrc, PJMEDIA_TYPE_VIDEO,
                           prm->vidparam.clock_rate, ptime_usec);
    vp->sync_clocksrc.max_sync_ticks = 
        PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION *
        1000 / vp->clocksrc.ptime_usec;

    /* Create the video stream */
    pj_bzero(&vid_cb, sizeof(vid_cb));
    vid_cb.capture_cb = &vidstream_cap_cb;
    vid_cb.render_cb = &vidstream_render_cb;

    status = pjmedia_vid_dev_stream_create(&vparam, &vid_cb, vp,
				           &vp->strm);
    if (status != PJ_SUCCESS)
	goto on_error;

    PJ_LOG(4,(THIS_FILE,
	      "Device %s opened: format=%s, size=%dx%d @%d:%d fps",
	      dev_name, fmt_name,
	      vparam.fmt.det.vid.size.w, vparam.fmt.det.vid.size.h,
	      vparam.fmt.det.vid.fps.num, vparam.fmt.det.vid.fps.denum));

    /* Subscribe to device's events */
    pjmedia_event_subscribe(NULL, &vidstream_event_cb,
                            vp, vp->strm);

    if (vp->dir & PJMEDIA_DIR_CAPTURE) {
	pjmedia_format_copy(&vp->conv.conv_param.src, &vparam.fmt);
	pjmedia_format_copy(&vp->conv.conv_param.dst, &prm->vidparam.fmt);
    } else {
	pjmedia_format_copy(&vp->conv.conv_param.src, &prm->vidparam.fmt);
	pjmedia_format_copy(&vp->conv.conv_param.dst, &vparam.fmt);
    }

    status = create_converter(vp);
    if (status != PJ_SUCCESS)
	goto on_error;

    if (vp->role==ROLE_ACTIVE &&
        ((vp->dir & PJMEDIA_DIR_ENCODING) || vp->stream_role==ROLE_PASSIVE))
    {
        pjmedia_clock_param param;

	/* Active role is wanted, but our device is passive, so create
	 * master clocks to run the media flow. For encoding direction,
         * we also want to create our own clock since the device's clock
         * may run at a different rate.
	 */
	need_frame_buf = PJ_TRUE;
            
        param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
        param.clock_rate = prm->vidparam.clock_rate;
        status = pjmedia_clock_create2(pool, &param,
                                       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
                                       (vp->dir & PJMEDIA_DIR_ENCODING) ?
                                       &enc_clock_cb: &dec_clock_cb,
                                       vp, &vp->clock);
        if (status != PJ_SUCCESS)
            goto on_error;

    } else if (vp->role==ROLE_PASSIVE) {
	vid_pasv_port *pp;

	/* Always need to create media port for passive role */
	vp->pasv_port = pp = PJ_POOL_ZALLOC_T(pool, vid_pasv_port);
	pp->vp = vp;
	pp->base.get_frame = &vid_pasv_port_get_frame;
	pp->base.put_frame = &vid_pasv_port_put_frame;
	pjmedia_port_info_init2(&pp->base.info, &vp->dev_name,
	                        PJMEDIA_SIG_VID_PORT,
			        prm->vidparam.dir, &prm->vidparam.fmt);

        need_frame_buf = PJ_TRUE;
    }

    if (need_frame_buf) {
	const pjmedia_video_format_info *vfi;
	pjmedia_video_apply_fmt_param vafp;

	vfi = pjmedia_get_video_format_info(NULL, vparam.fmt.id);
	if (!vfi) {
	    status = PJ_ENOTFOUND;
	    goto on_error;
	}

	pj_bzero(&vafp, sizeof(vafp));
	vafp.size = vparam.fmt.det.vid.size;
	status = vfi->apply_fmt(vfi, &vafp);
	if (status != PJ_SUCCESS)
	    goto on_error;

        vp->frm_buf = PJ_POOL_ZALLOC_T(pool, pjmedia_frame);
        vp->frm_buf_size = vafp.framebytes;
        vp->frm_buf->buf = pj_pool_alloc(pool, vafp.framebytes);
        vp->frm_buf->size = vp->frm_buf_size;
        vp->frm_buf->type = PJMEDIA_FRAME_TYPE_NONE;

        status = pj_mutex_create_simple(pool, vp->dev_name.ptr,
                                        &vp->frm_mutex);
        if (status != PJ_SUCCESS)
            goto on_error;
    }

    *p_vid_port = vp;

    return PJ_SUCCESS;

on_error:
    pjmedia_vid_port_destroy(vp);
    return status;
}

PJ_DEF(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,
				     const pjmedia_vid_dev_cb *cb,
                                     void *user_data)
{
    pj_assert(vid_port && cb);
    pj_memcpy(&vid_port->strm_cb, cb, sizeof(*cb));
    vid_port->strm_cb_data = user_data;
}

PJ_DEF(pjmedia_vid_dev_stream*)
pjmedia_vid_port_get_stream(pjmedia_vid_port *vp)
{
    PJ_ASSERT_RETURN(vp, NULL);
    return vp->strm;
}


PJ_DEF(pjmedia_port*)
pjmedia_vid_port_get_passive_port(pjmedia_vid_port *vp)
{
    PJ_ASSERT_RETURN(vp && vp->role==ROLE_PASSIVE, NULL);
    return &vp->pasv_port->base;
}


PJ_DEF(pjmedia_clock_src *)
pjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port )
{
    PJ_ASSERT_RETURN(vid_port, NULL);
    return &vid_port->clocksrc;
}

PJ_DECL(pj_status_t)
pjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,
                                pjmedia_clock_src *clocksrc)
{
    PJ_ASSERT_RETURN(vid_port && clocksrc, PJ_EINVAL);

    vid_port->sync_clocksrc.sync_clocksrc = clocksrc;
    vid_port->sync_clocksrc.sync_delta =
        pjmedia_clock_src_get_time_msec(&vid_port->clocksrc) -
        pjmedia_clock_src_get_time_msec(clocksrc);

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vp,
					      pjmedia_port *port,
					      pj_bool_t destroy)
{
    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);
    vp->destroy_client_port = destroy;
    vp->client_port = port;

    /* Subscribe to client port's events */
    pjmedia_event_subscribe(NULL, &client_port_event_cb, vp,
                            vp->client_port);

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vp)
{
    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);

    pjmedia_event_unsubscribe(NULL, &client_port_event_cb, vp,
                              vp->client_port);
    vp->client_port = NULL;

    return PJ_SUCCESS;
}


PJ_DEF(pjmedia_port*)
pjmedia_vid_port_get_connected_port(pjmedia_vid_port *vp)
{
    PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, NULL);
    return vp->client_port;
}

PJ_DEF(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vp)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(vp, PJ_EINVAL);

    status = pjmedia_vid_dev_stream_start(vp->strm);
    if (status != PJ_SUCCESS)
	goto on_error;

    if (vp->clock) {
	status = pjmedia_clock_start(vp->clock);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    return PJ_SUCCESS;

on_error:
    pjmedia_vid_port_stop(vp);
    return status;
}

PJ_DEF(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vp)
{
    return pjmedia_vid_dev_stream_is_running(vp->strm);
}

PJ_DEF(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vp)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(vp, PJ_EINVAL);

    if (vp->clock) {
	status = pjmedia_clock_stop(vp->clock);
    }

    status = pjmedia_vid_dev_stream_stop(vp->strm);

    return status;
}

PJ_DEF(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vp)
{
    PJ_ASSERT_ON_FAIL(vp, return);

    PJ_LOG(4,(THIS_FILE, "Closing %s..", vp->dev_name.ptr));

    if (vp->clock) {
	pjmedia_clock_destroy(vp->clock);
	vp->clock = NULL;
    }
    if (vp->strm) {
        pjmedia_event_unsubscribe(NULL, &vidstream_event_cb, vp, vp->strm);
	pjmedia_vid_dev_stream_destroy(vp->strm);
	vp->strm = NULL;
    }
    if (vp->client_port) {
        pjmedia_event_unsubscribe(NULL, &client_port_event_cb, vp,
                                  vp->client_port);
	if (vp->destroy_client_port)
	    pjmedia_port_destroy(vp->client_port);
	vp->client_port = NULL;
    }
    if (vp->frm_mutex) {
	pj_mutex_destroy(vp->frm_mutex);
	vp->frm_mutex = NULL;
    }
    if (vp->conv.conv) {
        pjmedia_converter_destroy(vp->conv.conv);
        vp->conv.conv = NULL;
    }
    pj_pool_release(vp->pool);
}

/*
static void save_rgb_frame(int width, int height, const pjmedia_frame *frm)
{
    static int counter;
    FILE *pFile;
    char szFilename[32];
    const pj_uint8_t *pFrame = (const pj_uint8_t*)frm->buf;
    int  y;

    if (counter > 10)
	return;

    // Open file
    sprintf(szFilename, "frame%02d.ppm", counter++);
    pFile=fopen(szFilename, "wb");
    if(pFile==NULL)
      return;

    // Write header
    fprintf(pFile, "P6\n%d %d\n255\n", width, height);

    // Write pixel data
    for(y=0; y<height; y++)
      fwrite(pFrame+y*width*3, 1, width*3, pFile);

    // Close file
    fclose(pFile);
}
*/

/* Handle event from vidstream */
static pj_status_t vidstream_event_cb(pjmedia_event *event,
                                      void *user_data)
{
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
    
    /* Just republish the event to our client */
    return pjmedia_event_publish(NULL, vp, event, 0);
}

static pj_status_t client_port_event_cb(pjmedia_event *event,
                                        void *user_data)
{
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;

    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
        const pjmedia_video_format_detail *vfd;
        pjmedia_vid_dev_param vid_param;
        pj_status_t status;
        
	pjmedia_vid_port_stop(vp);
        
        /* Retrieve the video format detail */
        vfd = pjmedia_format_get_video_format_detail(
                  &event->data.fmt_changed.new_fmt, PJ_TRUE);
        if (!vfd || !vfd->fps.num || !vfd->fps.denum)
            return PJMEDIA_EVID_BADFORMAT;
        
	/* Change the destination format to the new format */
	pjmedia_format_copy(&vp->conv.conv_param.src,
			    &event->data.fmt_changed.new_fmt);
	/* Only copy the size here */
	vp->conv.conv_param.dst.det.vid.size =
	    event->data.fmt_changed.new_fmt.det.vid.size;

	status = create_converter(vp);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(4,(THIS_FILE, status, "Error recreating converter"));
	    return status;
	}

        pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param);
        if (vid_param.fmt.id != vp->conv.conv_param.dst.id ||
            (vid_param.fmt.det.vid.size.h !=
             vp->conv.conv_param.dst.det.vid.size.h) ||
            (vid_param.fmt.det.vid.size.w !=
             vp->conv.conv_param.dst.det.vid.size.w))
        {
            status = pjmedia_vid_dev_stream_set_cap(vp->strm,
                                                    PJMEDIA_VID_DEV_CAP_FORMAT,
                                                    &vp->conv.conv_param.dst);
            if (status != PJ_SUCCESS) {
                PJ_LOG(3, (THIS_FILE, "failure in changing the format of the "
                                      "video device"));
                PJ_LOG(3, (THIS_FILE, "reverting to its original format: %s",
                                      status != PJMEDIA_EVID_ERR ? "success" :
                                      "failure"));
                return status;
            }
        }
        
        if (vp->stream_role == ROLE_PASSIVE) {
            pjmedia_clock_param clock_param;
            
            /**
             * Initially, frm_buf was allocated the biggest
             * supported size, so we do not need to re-allocate
             * the buffer here.
             */
            /* Adjust the clock */
            clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
            clock_param.clock_rate = vid_param.clock_rate;
            pjmedia_clock_modify(vp->clock, &clock_param);
        }
        
	pjmedia_vid_port_start(vp);
    }
    
    /* Republish the event, post the event to the event manager
     * to avoid deadlock if vidport is trying to stop the clock.
     */
    return pjmedia_event_publish(NULL, vp, event,
                                 PJMEDIA_EVENT_PUBLISH_POST_EVENT);
}

static pj_status_t convert_frame(pjmedia_vid_port *vp,
                                 pjmedia_frame *src_frame,
                                 pjmedia_frame *dst_frame)
{
    pj_status_t status = PJ_SUCCESS;

    if (vp->conv.conv) {
        if (!dst_frame->buf || dst_frame->size < vp->conv.conv_buf_size) {
            dst_frame->buf  = vp->conv.conv_buf;
	    dst_frame->size = vp->conv.conv_buf_size;
        }
	status = pjmedia_converter_convert(vp->conv.conv,
					   src_frame, dst_frame);
    }
    
    return status;
}

/* Copy frame to buffer. */
static void copy_frame_to_buffer(pjmedia_vid_port *vp,
                                 pjmedia_frame *frame)
{
    pj_mutex_lock(vp->frm_mutex);
    pjmedia_frame_copy(vp->frm_buf, frame);
    pj_mutex_unlock(vp->frm_mutex);
}

/* Get frame from buffer and convert it if necessary. */
static pj_status_t get_frame_from_buffer(pjmedia_vid_port *vp,
                                         pjmedia_frame *frame)
{
    pj_status_t status = PJ_SUCCESS;

    pj_mutex_lock(vp->frm_mutex);
    if (vp->conv.conv)
        status = convert_frame(vp, vp->frm_buf, frame);
    else
        pjmedia_frame_copy(frame, vp->frm_buf);
    pj_mutex_unlock(vp->frm_mutex);
    
    return status;
}

static void enc_clock_cb(const pj_timestamp *ts, void *user_data)
{
    /* We are here because user wants us to be active but the stream is
     * passive. So get a frame from the stream and push it to user.
     */
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
    pjmedia_frame frame_;
    pj_status_t status = PJ_SUCCESS;

    pj_assert(vp->role==ROLE_ACTIVE);

    PJ_UNUSED_ARG(ts);

    if (!vp->client_port)
	return;

    if (vp->stream_role == ROLE_PASSIVE) {
        while (vp->conv.usec_ctr < vp->conv.usec_dst) {
            vp->frm_buf->size = vp->frm_buf_size;
            status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->frm_buf);
            vp->conv.usec_ctr += vp->conv.usec_src;
        }
        vp->conv.usec_ctr -= vp->conv.usec_dst;
        if (status != PJ_SUCCESS)
	    return;
    }

    //save_rgb_frame(vp->cap_size.w, vp->cap_size.h, vp->frm_buf);

    frame_.buf = vp->conv.conv_buf;
    frame_.size = vp->conv.conv_buf_size;
    status = get_frame_from_buffer(vp, &frame_);
    if (status != PJ_SUCCESS)
        return;

    status = pjmedia_port_put_frame(vp->client_port, &frame_);
    if (status != PJ_SUCCESS)
        return;
}

static void dec_clock_cb(const pj_timestamp *ts, void *user_data)
{
    /* We are here because user wants us to be active but the stream is
     * passive. So get a frame from the stream and push it to user.
     */
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
    pj_status_t status;
    pjmedia_frame frame;

    pj_assert(vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE);

    PJ_UNUSED_ARG(ts);

    if (!vp->client_port)
	return;

    status = vidstream_render_cb(vp->strm, vp, &frame);
    if (status != PJ_SUCCESS)
        return;
    
    if (frame.size > 0)
	status = pjmedia_vid_dev_stream_put_frame(vp->strm, &frame);
}

static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,
				    void *user_data,
				    pjmedia_frame *frame)
{
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;

    /* We just store the frame in the buffer. For active role, we let
     * video port's clock to push the frame buffer to the user.
     * The decoding counterpart for passive role and active stream is
     * located in vid_pasv_port_put_frame()
     */
    copy_frame_to_buffer(vp, frame);

    /* This is tricky since the frame is still in its original unconverted
     * format, which may not be what the application expects.
     */
    if (vp->strm_cb.capture_cb)
        return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, frame);
    return PJ_SUCCESS;
}

static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,
				       void *user_data,
				       pjmedia_frame *frame)
{
    pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
    pj_status_t status = PJ_SUCCESS;
    
    pj_bzero(frame, sizeof(pjmedia_frame));
    if (vp->role==ROLE_ACTIVE) {
        unsigned frame_ts = vp->clocksrc.clock_rate / 1000 *
                            vp->clocksrc.ptime_usec / 1000;

        if (!vp->client_port)
            return status;
        
        if (vp->sync_clocksrc.sync_clocksrc) {
            pjmedia_clock_src *src = vp->sync_clocksrc.sync_clocksrc;
            pj_int32_t diff;
            unsigned nsync_frame;
            
            /* Synchronization */
            /* Calculate the time difference (in ms) with the sync source */
            diff = pjmedia_clock_src_get_time_msec(&vp->clocksrc) -
                   pjmedia_clock_src_get_time_msec(src) -
                   vp->sync_clocksrc.sync_delta;
            
            /* Check whether sync source made a large jump */
            if (diff < 0 && -diff > PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC) {
                pjmedia_clock_src_update(&vp->clocksrc, NULL);
                vp->sync_clocksrc.sync_delta = 
                    pjmedia_clock_src_get_time_msec(src) -
                    pjmedia_clock_src_get_time_msec(&vp->clocksrc);
                vp->sync_clocksrc.nsync_frame = 0;
                return status;
            }
            
            /* Calculate the difference (in frames) with the sync source */
            nsync_frame = abs(diff) * 1000 / vp->clocksrc.ptime_usec;
            if (nsync_frame == 0) {
                /* Nothing to sync */
                vp->sync_clocksrc.nsync_frame = 0;
            } else {
                pj_int32_t init_sync_frame = nsync_frame;
                
                /* Check whether it's a new sync or whether we need to reset
                 * the sync
                 */
                if (vp->sync_clocksrc.nsync_frame == 0 ||
                    (vp->sync_clocksrc.nsync_frame > 0 &&
                     nsync_frame > vp->sync_clocksrc.nsync_frame))
                {
                    vp->sync_clocksrc.nsync_frame = nsync_frame;
                    vp->sync_clocksrc.nsync_progress = 0;
                } else {
                    init_sync_frame = vp->sync_clocksrc.nsync_frame;
                }
                
                if (diff >= 0) {
                    unsigned skip_mod;
                    
                    /* We are too fast */
                    if (vp->sync_clocksrc.max_sync_ticks > 0) {
                        skip_mod = init_sync_frame / 
                        vp->sync_clocksrc.max_sync_ticks + 2;
                    } else
                        skip_mod = init_sync_frame + 2;
                    
                    PJ_LOG(5, (THIS_FILE, "synchronization: early by %d ms",
                               diff));
                    /* We'll play a frame every skip_mod-th tick instead of
                     * a complete pause
                     */
                    if (++vp->sync_clocksrc.nsync_progress % skip_mod > 0) {
                        pjmedia_clock_src_update(&vp->clocksrc, NULL);
                        return status;
                    }
                } else {
                    unsigned i, ndrop = init_sync_frame;
                    
                    /* We are too late, drop the frame */
                    if (vp->sync_clocksrc.max_sync_ticks > 0) {
                        ndrop /= vp->sync_clocksrc.max_sync_ticks;
                        ndrop++;
                    }
                    PJ_LOG(5, (THIS_FILE, "synchronization: late, "
                               "dropping %d frame(s)", ndrop));
                    
                    if (ndrop >= nsync_frame) {
                        vp->sync_clocksrc.nsync_frame = 0;
                        ndrop = nsync_frame;
                    } else
                        vp->sync_clocksrc.nsync_progress += ndrop;
                    
                    for (i = 0; i < ndrop; i++) {
                        vp->frm_buf->size = vp->frm_buf_size;
                        status = pjmedia_port_get_frame(vp->client_port,
                                                        vp->frm_buf);
                        if (status != PJ_SUCCESS) {
                            pjmedia_clock_src_update(&vp->clocksrc, NULL);
                            return status;
                        }
                        
                        pj_add_timestamp32(&vp->clocksrc.timestamp,
                                           frame_ts);
                    }
                }
            }
        }
        
        vp->frm_buf->size = vp->frm_buf_size;
        status = pjmedia_port_get_frame(vp->client_port, vp->frm_buf);
        if (status != PJ_SUCCESS) {
            pjmedia_clock_src_update(&vp->clocksrc, NULL);
            return status;
        }
        pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts);
        pjmedia_clock_src_update(&vp->clocksrc, NULL);

        status = convert_frame(vp, vp->frm_buf, frame);
	if (status != PJ_SUCCESS)
            return status;

	if (!vp->conv.conv)
	    pj_memcpy(frame, vp->frm_buf, sizeof(*frame));
    } else {
        /* The stream is active while we are passive so we need to get the
         * frame from the buffer.
         * The encoding counterpart is located in vid_pasv_port_get_frame()
         */
        get_frame_from_buffer(vp, frame);
    }
    if (vp->strm_cb.render_cb)
        return (*vp->strm_cb.render_cb)(stream, vp->strm_cb_data, frame);
    return PJ_SUCCESS;
}

static pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,
					   pjmedia_frame *frame)
{
    struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;
    pjmedia_vid_port *vp = vpp->vp;

    if (vp->stream_role==ROLE_PASSIVE) {
        /* We are passive and the stream is passive.
         * The encoding counterpart is in vid_pasv_port_get_frame().
         */
        pj_status_t status;
        pjmedia_frame frame_;
        
        pj_bzero(&frame_, sizeof(frame_));
        status = convert_frame(vp, frame, &frame_);
        if (status != PJ_SUCCESS)
            return status;

	return pjmedia_vid_dev_stream_put_frame(vp->strm, (vp->conv.conv?
                                                           &frame_: frame));
    } else {
        /* We are passive while the stream is active so we just store the
         * frame in the buffer.
         * The encoding counterpart is located in vidstream_cap_cb()
         */
        copy_frame_to_buffer(vp, frame);
    }

    return PJ_SUCCESS;
}

static pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,
					   pjmedia_frame *frame)
{
    struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;
    pjmedia_vid_port *vp = vpp->vp;
    pj_status_t status = PJ_SUCCESS;

    if (vp->stream_role==ROLE_PASSIVE) {
        /* We are passive and the stream is passive.
         * The decoding counterpart is in vid_pasv_port_put_frame().
         */
	status = pjmedia_vid_dev_stream_get_frame(vp->strm, (vp->conv.conv?
                                                  vp->frm_buf: frame));
	if (status != PJ_SUCCESS)
	    return status;

        status = convert_frame(vp, vp->frm_buf, frame);
    } else {
        /* The stream is active while we are passive so we need to get the
         * frame from the buffer.
         * The decoding counterpart is located in vidstream_rend_cb()
         */
        get_frame_from_buffer(vp, frame);
    }

    return status;
}


#endif /* PJMEDIA_HAS_VIDEO */
