/* $Id$ */
/* 
 * Copyright (C) 2008-2010 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-videodev/videodev_imp.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/string.h>

#define THIS_FILE   "videodev.c"

#define DEFINE_CAP(name, info)	{name, info}

/* Capability names */
static struct cap_info
{
    const char *name;
    const char *info;
} cap_infos[] = 
{
    DEFINE_CAP("format",        "Video format"),
    DEFINE_CAP("scale",         "Input dimension"),
    DEFINE_CAP("window",        "Renderer window"),
};


/*
 * The device index seen by application and driver is different. 
 *
 * At application level, device index is index to global list of device.
 * At driver level, device index is index to device list on that particular
 * factory only.
 */
#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
#define GET_FID(dev_id)		   ((dev_id) >> 16)
#define DEFAULT_DEV_ID		    0


/* extern functions to create factories */
#if PJMEDIA_VIDEO_DEV_HAS_NULL_VIDEO
pjmedia_vid_dev_factory* pjmedia_null_video_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
pjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
pjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_SDL
pjmedia_vid_dev_factory* pjmedia_sdl_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
pjmedia_vid_dev_factory* pjmedia_ffmpeg_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_V4L2
pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_QT
pjmedia_vid_dev_factory* pjmedia_qt_factory(pj_pool_factory *pf);
#endif

#if PJMEDIA_VIDEO_DEV_HAS_IOS
pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf);
#endif

#define MAX_DRIVERS	16
#define MAX_DEVS	64


/* driver structure */
struct driver
{
    /* Creation function */
    pjmedia_vid_dev_factory_create_func_ptr create;
    /* Factory instance */
    pjmedia_vid_dev_factory *f;
    char		     name[32];	    /* Driver name		    */
    unsigned		     dev_cnt;	    /* Number of devices	    */
    unsigned		     start_idx;	    /* Start index in global list   */
    int			     cap_dev_idx;   /* Default capture device.	    */
    int			     rend_dev_idx;  /* Default render device	    */
};

/* The video subsystem */
static struct vid_subsys
{
    unsigned	     init_count;	/* How many times init() is called  */
    pj_pool_factory *pf;		/* The pool factory.		    */

    unsigned	     drv_cnt;		/* Number of drivers.		    */
    struct driver    drv[MAX_DRIVERS];	/* Array of drivers.		    */

    unsigned	     dev_cnt;		/* Total number of devices.	    */
    pj_uint32_t	     dev_list[MAX_DEVS];/* Array of device IDs.		    */

} vid_subsys;

/* API: get capability name/info */
PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
					     const char **p_desc)
{
    const char *desc;
    unsigned i;

    if (p_desc==NULL) p_desc = &desc;

    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
	if ((1 << i)==cap)
	    break;
    }

    if (i==32) {
	*p_desc = "??";
	return "??";
    }

    *p_desc = cap_infos[i].info;
    return cap_infos[i].name;
}

static pj_status_t get_cap_pointer(const pjmedia_vid_param *param,
				   pjmedia_vid_dev_cap cap,
				   void **ptr,
				   unsigned *size)
{
#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
			    *size = sizeof(param->name)

    switch (cap) {
    case PJMEDIA_VID_DEV_CAP_FORMAT:
	FIELD_INFO(fmt);
	break;
    case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:
	FIELD_INFO(disp_size);
	break;
    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
	FIELD_INFO(window);
	break;
    default:
	return PJMEDIA_EVID_INVCAP;
    }

#undef FIELD_INFO

    return PJ_SUCCESS;
}

/* API: set cap value to param */
PJ_DEF(pj_status_t) pjmedia_vid_param_set_cap( pjmedia_vid_param *param,
					       pjmedia_vid_dev_cap cap,
					       const void *pval)
{
    void *cap_ptr;
    unsigned cap_size;
    pj_status_t status;

    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
    if (status != PJ_SUCCESS)
	return status;

    pj_memcpy(cap_ptr, pval, cap_size);
    param->flags |= cap;

    return PJ_SUCCESS;
}

/* API: get cap value from param */
PJ_DEF(pj_status_t) pjmedia_vid_param_get_cap( const pjmedia_vid_param *param,
					       pjmedia_vid_dev_cap cap,
					       void *pval)
{
    void *cap_ptr;
    unsigned cap_size;
    pj_status_t status;

    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
    if (status != PJ_SUCCESS)
	return status;

    if ((param->flags & cap) == 0) {
	pj_bzero(cap_ptr, cap_size);
	return PJMEDIA_EVID_INVCAP;
    }

    pj_memcpy(pval, cap_ptr, cap_size);
    return PJ_SUCCESS;
}

/* Internal: init driver */
static pj_status_t init_driver(unsigned drv_idx)
{
    struct driver *drv = &vid_subsys.drv[drv_idx];
    pjmedia_vid_dev_factory *f;
    unsigned i, dev_cnt;
    pj_status_t status;

    /* Create the factory */
    f = (*drv->create)(vid_subsys.pf);
    if (!f)
	return PJ_EUNKNOWN;

    /* Call factory->init() */
    status = f->op->init(f);
    if (status != PJ_SUCCESS) {
	f->op->destroy(f);
	return status;
    }

    /* Get number of devices */
    dev_cnt = f->op->get_dev_count(f);
    if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {
	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
			      " there are too many devices",
			      vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));
	dev_cnt = MAX_DEVS - vid_subsys.dev_cnt;
    }

    /* enabling this will cause pjsua-lib initialization to fail when there
     * is no video device installed in the system, even when pjsua has been
     * run with --null-video
     *
    if (dev_cnt == 0) {
	f->op->destroy(f);
	return PJMEDIA_EVID_NODEV;
    }
    */

    /* Fill in default devices */
    drv->rend_dev_idx = drv->cap_dev_idx = -1;
    for (i=0; i<dev_cnt; ++i) {
	pjmedia_vid_dev_info info;

	status = f->op->get_dev_info(f, i, &info);
	if (status != PJ_SUCCESS) {
	    f->op->destroy(f);
	    return status;
	}

	if (drv->name[0]=='\0') {
	    /* Set driver name */
	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
	    drv->name[sizeof(drv->name)-1] = '\0';
	}

	if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {
	    /* Set default render device */
	    drv->rend_dev_idx = i;
	}
	if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {
	    /* Set default capture device */
	    drv->cap_dev_idx = i;
	}

        if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {
	    /* Done. */
	    break;
	}
    }

    /* Register the factory */
    drv->f = f;
    drv->f->sys.drv_idx = drv_idx;
    drv->start_idx = vid_subsys.dev_cnt;
    drv->dev_cnt = dev_cnt;

    /* Register devices to global list */
    for (i=0; i<dev_cnt; ++i) {
	vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
    }

    return PJ_SUCCESS;
}

/* Internal: deinit driver */
static void deinit_driver(unsigned drv_idx)
{
    struct driver *drv = &vid_subsys.drv[drv_idx];

    if (drv->f) {
	drv->f->op->destroy(drv->f);
	drv->f = NULL;
    }

    drv->dev_cnt = 0;
    drv->rend_dev_idx = drv->cap_dev_idx = -1;
}

/* API: Initialize the video subsystem. */
PJ_DEF(pj_status_t) pjmedia_vid_subsys_init(pj_pool_factory *pf)
{
    unsigned i;
    pj_status_t status = PJ_SUCCESS;

    /* Allow init() to be called multiple times as long as there is matching
     * number of shutdown().
     */
    if (vid_subsys.init_count++ != 0) {
	return PJ_SUCCESS;
    }

    /* Register error subsystem */
    pj_register_strerror(PJMEDIA_VIDEODEV_ERRNO_START, 
			 PJ_ERRNO_SPACE_SIZE, 
			 &pjmedia_videodev_strerror);

    /* Init */
    vid_subsys.pf = pf;
    vid_subsys.drv_cnt = 0;
    vid_subsys.dev_cnt = 0;

    /* Register creation functions */
#if PJMEDIA_VIDEO_DEV_HAS_V4L2
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_QT
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_qt_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_IOS
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ffmpeg_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_SDL
    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_sdl_factory;
#endif

    /* Initialize each factory and build the device ID list */
    for (i=0; i<vid_subsys.drv_cnt; ++i) {
	status = init_driver(i);
	if (status != PJ_SUCCESS) {
	    deinit_driver(i);
	    continue;
	}
    }

    return vid_subsys.dev_cnt ? PJ_SUCCESS : status;
}

/* API: register an video device factory to the video subsystem. */
PJ_DEF(pj_status_t)
pjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr adf)
{
    pj_status_t status;

    if (vid_subsys.init_count == 0)
	return PJMEDIA_EVID_INIT;

    vid_subsys.drv[vid_subsys.drv_cnt].create = adf;
    status = init_driver(vid_subsys.drv_cnt);
    if (status == PJ_SUCCESS) {
	vid_subsys.drv_cnt++;
    } else {
	deinit_driver(vid_subsys.drv_cnt);
    }

    return status;
}

/* API: unregister an video device factory from the video subsystem. */
PJ_DEF(pj_status_t)
pjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr adf)
{
    unsigned i, j;

    if (vid_subsys.init_count == 0)
	return PJMEDIA_EVID_INIT;

    for (i=0; i<vid_subsys.drv_cnt; ++i) {
	struct driver *drv = &vid_subsys.drv[i];

	if (drv->create == adf) {
	    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
	    {
		vid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;
	    }

	    deinit_driver(i);
	    pj_bzero(drv, sizeof(*drv));
	    return PJ_SUCCESS;
	}
    }

    return PJMEDIA_EVID_ERR;
}

/* API: get the pool factory registered to the video subsystem. */
PJ_DEF(pj_pool_factory*) pjmedia_vid_subsys_get_pool_factory(void)
{
    return vid_subsys.pf;
}

/* API: Shutdown the video subsystem. */
PJ_DEF(pj_status_t) pjmedia_vid_subsys_shutdown(void)
{
    unsigned i;

    /* Allow shutdown() to be called multiple times as long as there is
     * matching number of init().
     */
    if (vid_subsys.init_count == 0) {
	return PJ_SUCCESS;
    }
    --vid_subsys.init_count;

    for (i=0; i<vid_subsys.drv_cnt; ++i) {
	deinit_driver(i);
    }

    vid_subsys.pf = NULL;
    return PJ_SUCCESS;
}

/* API: Get the number of video devices installed in the system. */
PJ_DEF(unsigned) pjmedia_vid_dev_count(void)
{
    return vid_subsys.dev_cnt;
}

/* Internal: convert local index to global device index */
static pj_status_t make_global_index(unsigned drv_idx, 
				     pjmedia_vid_dev_index *id)
{
    if (*id < 0) {
	return PJ_SUCCESS;
    }

    /* Check that factory still exists */
    PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);

    /* Check that device index is valid */
    PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt, 
		     PJ_EBUG);

    *id += vid_subsys.drv[drv_idx].start_idx;
    return PJ_SUCCESS;
}

/* Internal: lookup device id */
static pj_status_t lookup_dev(pjmedia_vid_dev_index id,
			      pjmedia_vid_dev_factory **p_f,
			      unsigned *p_local_index)
{
    int f_id, index;

    if (id < 0) {
	unsigned i;

	if (id == PJMEDIA_VID_INVALID_DEV)
	    return PJMEDIA_EVID_INVDEV;

	for (i=0; i<vid_subsys.drv_cnt; ++i) {
	    struct driver *drv = &vid_subsys.drv[i];
	    if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV && 
		drv->cap_dev_idx >= 0) 
	    {
		id = drv->cap_dev_idx;
		make_global_index(i, &id);
		break;
	    } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV && 
		drv->rend_dev_idx >= 0) 
	    {
		id = drv->rend_dev_idx;
		make_global_index(i, &id);
		break;
	    }
	}

	if (id < 0) {
	    return PJMEDIA_EVID_NODEFDEV;
	}
    }

    f_id = GET_FID(vid_subsys.dev_list[id]);
    index = GET_INDEX(vid_subsys.dev_list[id]);

    if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)
	return PJMEDIA_EVID_INVDEV;

    if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)
	return PJMEDIA_EVID_INVDEV;

    *p_f = vid_subsys.drv[f_id].f;
    *p_local_index = (unsigned)index;

    return PJ_SUCCESS;

}

/* API: Get device information. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
					     pjmedia_vid_dev_info *info)
{
    pjmedia_vid_dev_factory *f;
    unsigned index;
    pj_status_t status;

    PJ_ASSERT_RETURN(info && id!=PJMEDIA_VID_INVALID_DEV, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);

    status = lookup_dev(id, &f, &index);
    if (status != PJ_SUCCESS)
	return status;

    return f->op->get_dev_info(f, index, info);
}

/* API: find device */
PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
					    const char *dev_name,
					    pjmedia_vid_dev_index *id)
{
    pjmedia_vid_dev_factory *f = NULL;
    unsigned drv_idx, dev_idx;

    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);

    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
	if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
	{
	    f = vid_subsys.drv[drv_idx].f;
	    break;
	}
    }

    if (!f)
	return PJ_ENOTFOUND;

    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
    {
	pjmedia_vid_dev_info info;
	pj_status_t status;

	status = f->op->get_dev_info(f, dev_idx, &info);
	if (status != PJ_SUCCESS)
	    return status;

	if (!pj_ansi_stricmp(dev_name, info.name))
	    break;
    }

    if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
	return PJ_ENOTFOUND;

    *id = dev_idx;
    make_global_index(drv_idx, id);

    return PJ_SUCCESS;
}

/* API: Initialize the video device parameters with default values for the
 * specified device.
 */
PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,
                                                  pjmedia_vid_dev_index id,
						  pjmedia_vid_param *param)
{
    pjmedia_vid_dev_factory *f;
    unsigned index;
    pj_status_t status;

    PJ_ASSERT_RETURN(param && id!=PJMEDIA_VID_INVALID_DEV, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);

    status = lookup_dev(id, &f, &index);
    if (status != PJ_SUCCESS)
	return status;

    status = f->op->default_param(pool, f, index, param);
    if (status != PJ_SUCCESS)
	return status;

    /* Normalize device IDs */
    make_global_index(f->sys.drv_idx, &param->cap_id);
    make_global_index(f->sys.drv_idx, &param->rend_id);

    return PJ_SUCCESS;
}

/* API: Open video stream object using the specified parameters. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
					pjmedia_vid_param *prm,
					const pjmedia_vid_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm)
{
    pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
    pj_status_t status;

    PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
		     prm->dir==PJMEDIA_DIR_RENDER ||
		     prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,
		     PJ_EINVAL);

    /* Normalize cap_id */
    if (prm->dir & PJMEDIA_DIR_CAPTURE) {
	unsigned index;

	if (prm->cap_id < 0)
	    prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;

	status = lookup_dev(prm->cap_id, &cap_f, &index);
	if (status != PJ_SUCCESS)
	    return status;

	prm->cap_id = index;
	f = cap_f;
    }

    /* Normalize rend_id */
    if (prm->dir & PJMEDIA_DIR_RENDER) {
	unsigned index;

	if (prm->rend_id < 0)
	    prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;

	status = lookup_dev(prm->rend_id, &rend_f, &index);
	if (status != PJ_SUCCESS)
	    return status;

	prm->rend_id = index;
	f = rend_f;
    }

    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);

    /* For now, cap_id and rend_id must belong to the same factory */
    PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) ||
		     (cap_f == rend_f),
		     PJMEDIA_EVID_INVDEV);

    /* Create the stream */
    status = f->op->create_stream(f, prm, cb,
				  user_data, p_vid_strm);
    if (status != PJ_SUCCESS)
	return status;

    /* Assign factory id to the stream */
    (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;
    return PJ_SUCCESS;
}

/* API: Get the running parameters for the specified video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(
					    pjmedia_vid_dev_stream *strm,
					    pjmedia_vid_param *param)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);

    status = strm->op->get_param(strm, param);
    if (status != PJ_SUCCESS)
	return status;

    /* Normalize device id's */
    make_global_index(strm->sys.drv_idx, &param->cap_id);
    make_global_index(strm->sys.drv_idx, &param->rend_id);

    return PJ_SUCCESS;
}

/* API: Get the value of a specific capability of the video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(
					    pjmedia_vid_dev_stream *strm,
					    pjmedia_vid_dev_cap cap,
					    void *value)
{
    return strm->op->get_cap(strm, cap, value);
}

/* API: Set the value of a specific capability of the video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(
					    pjmedia_vid_dev_stream *strm,
					    pjmedia_vid_dev_cap cap,
					    const void *value)
{
    return strm->op->set_cap(strm, cap, value);
}

/* API: Start the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)
{
    return strm->op->start(strm);
}

PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(
					    pjmedia_vid_dev_stream *strm,
					    pjmedia_frame *frame)
{
    pj_assert(strm->op->get_frame);
    return strm->op->get_frame(strm, frame);
}

PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(
					    pjmedia_vid_dev_stream *strm,
                                            const pjmedia_frame *frame)
{
    pj_assert(strm->op->put_frame);
    return strm->op->put_frame(strm, frame);
}

/* API: Stop the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)
{
    return strm->op->stop(strm);
}

/* API: Destroy the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(
						pjmedia_vid_dev_stream *strm)
{
    return strm->op->destroy(strm);
}
