/*
 * 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
 */
#ifndef __PJMEDIA_VIDEO_DEV_H__
#define __PJMEDIA_VIDEO_DEV_H__

/**
 * @file videodev.h
 * @brief Video device API.
 */
#include <pjmedia-videodev/config.h>
#include <pjmedia-videodev/errno.h>
#include <pjmedia/frame.h>
#include <pjmedia/format.h>
#include <pj/pool.h>


PJ_BEGIN_DECL

/**
 * @defgroup video_device_reference Video Device API Reference
 * @ingroup video_device_api
 * @brief API Reference
 * @{
 */
 
/**
 * Type for device index.
 */
typedef pj_int32_t pjmedia_vid_dev_index;

/**
 * Enumeration of window handle type.
 */
typedef enum pjmedia_vid_dev_hwnd_type
{
    /**
     * Type none.
     */
    PJMEDIA_VID_DEV_HWND_TYPE_NONE,

    /**
     * Native window handle on Windows.
     */
    PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,

    /**
     * Native view on iOS.
     */
    PJMEDIA_VID_DEV_HWND_TYPE_IOS,

    /**
     * Native window handle on Android.
     */
    PJMEDIA_VID_DEV_HWND_TYPE_ANDROID

} pjmedia_vid_dev_hwnd_type;

/**
 * Type for window handle.
 */
typedef struct pjmedia_vid_dev_hwnd
{
    /**
     * The window handle type.
     */
    pjmedia_vid_dev_hwnd_type type;

    /**
     * The window handle.
     */
    union
    {
        struct {
            void    *hwnd;      /**< HWND       */
        } win;
        struct {
            void    *window;    /**< Window     */
            void    *display;   /**< Display    */
        } x11;
        struct {
            void    *window;    /**< Window     */
        } cocoa;
        struct {
            void    *window;    /**< Window     */
        } ios;
        struct {
            void    *window;    /**< Native window */
        } android;
        void        *window;
    } info;

} pjmedia_vid_dev_hwnd;

/**
 * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.
 * Initialize this with pjmedia_vid_dev_switch_param_default()
 */
typedef struct pjmedia_vid_dev_switch_param
{
    /**
     * Target device ID to switch to. Once the switching is successful, the
     * video stream will use this device and the old device will be closed.
     */
    pjmedia_vid_dev_index target_id;

} pjmedia_vid_dev_switch_param;


/**
 * Enumeration of window flags.
 */
typedef enum pjmedia_vid_dev_wnd_flag
{
    /**
     * Window with border.
     */
    PJMEDIA_VID_DEV_WND_BORDER = 1,

    /**
     * Window can be resized.
     */
    PJMEDIA_VID_DEV_WND_RESIZABLE = 2

} pjmedia_vid_dev_wnd_flag;


/**
 * Device index constants.
 */
enum pjmedia_vid_dev_std_index
{
    /**
     * Constant to denote default capture device
     */
    PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,

    /**
     * Constant to denote default render device
     */
    PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,

    /**
     * Constant to denote invalid device index.
     */
    PJMEDIA_VID_INVALID_DEV = -3
};


/**
 * Enumeration of window fullscreen flags.
 */
typedef enum pjmedia_vid_dev_fullscreen_flag
{
    /**
     * Windowed or disable fullscreen.
     */
    PJMEDIA_VID_DEV_WINDOWED = 0,

    /**
     * Fullscreen enabled, video mode may be changed.
     */
    PJMEDIA_VID_DEV_FULLSCREEN = 1,

    /**
     * Fullscreen enabled by resizing video frame to match to the desktop,
     * video mode will not be changed.
     */
    PJMEDIA_VID_DEV_FULLSCREEN_DESKTOP = 2

} pjmedia_vid_dev_fullscreen_flag;


/**
 * This enumeration identifies various video device capabilities. These video
 * capabilities indicates what features are supported by the underlying
 * video device implementation.
 *
 * Applications get these capabilities in the #pjmedia_vid_dev_info structure.
 *
 * Application can also set the specific features/capabilities when opening
 * the video stream by setting the \a flags member of #pjmedia_vid_dev_param
 * structure.
 *
 * Once video stream is running, application can also retrieve or set some
 * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and
 * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The
 * value of the capability is specified as pointer, and application needs to
 * supply the pointer with the correct value, according to the documentation
 * of each of the capability.
 */
typedef enum pjmedia_vid_dev_cap
{
    /**
     * Support for video formats. The value of this capability
     * is represented by #pjmedia_format structure.
     */
    PJMEDIA_VID_DEV_CAP_FORMAT = 1,

    /**
     * Support for video input scaling
     */
    PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,

    /**
     * Support for returning the native window handle of the video window.
     * For renderer, this means the window handle of the renderer window,
     * while for capture, this means the window handle of the native preview,
     * only if the device supports  PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW
     * capability.
     *
     * The value of this capability is pointer to pjmedia_vid_dev_hwnd
     * structure.
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,

    /**
     * Support for resizing video output. This capability SHOULD be 
     * implemented by renderer, to alter the video output dimension on the fly.
     * Value is pjmedia_rect_size. 
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,

    /**
     * Support for setting the video window's position.
     * Value is pjmedia_coord specifying the window's new coordinate.
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,

    /**
     * Support for setting the video output's visibility.
     * The value of this capability is a pj_bool_t containing boolean
     * PJ_TRUE or PJ_FALSE.
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,

    /**
     * Support for native preview capability in capture devices. Value is
     * pj_bool_t. With native preview, capture device can be instructed to
     * show or hide a preview window showing video directly from the camera
     * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview
     * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW
     * capability to query the video window.
     *
     * The value of this capability is a pj_bool_t containing boolean
     * PJ_TRUE or PJ_FALSE.
     */
    PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64,

    /**
     * Support for changing video orientation. For a renderer device,
     * changing video orientation in will potentially affect the size of
     * render window, i.e: width and height swap. For a capture device,
     * the video will be rotated but the size of the video frame
     * will stay the same, so the video may be resized or stretched.
     *
     * The value of this capability is pjmedia_orient.
     */
    PJMEDIA_VID_DEV_CAP_ORIENTATION = 128,

    /**
     * Support for fast switching to another device. A video stream with this
     * capability allows replacing of its underlying device with another
     * device, saving the user from opening a new video stream and gets a much
     * faster and smoother switching action.
     *
     * Note that even when this capability is supported by a device, it may
     * not be able to switch to arbitrary device. Application must always
     * check the return value of the operation to verify that switching has
     * occurred.
     *
     * This capability is currently write-only (i.e. set-only).
     *
     * The value of this capability is pointer to pjmedia_vid_dev_switch_param
     * structure.
     */
    PJMEDIA_VID_DEV_CAP_SWITCH = 256,

    /**
     * Support for setting the output video window's flags.
     * The value of this capability is a bitmask combination of
     * #pjmedia_vid_dev_wnd_flag.
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512,

    /**
     * Support for setting the output video window full screen.
     */
    PJMEDIA_VID_DEV_CAP_OUTPUT_FULLSCREEN = 1024,

    /**
     * End of standard capability
     */
    PJMEDIA_VID_DEV_CAP_MAX = 16384

} pjmedia_vid_dev_cap;

/**
 * Device information structure returned by #pjmedia_vid_dev_get_info().
 */
typedef struct pjmedia_vid_dev_info
{
    /** The device ID */
    pjmedia_vid_dev_index id;

    /** The device name */
    char name[64];

    /** The underlying driver name */
    char driver[32];

    /** 
     * The supported direction of the video device, i.e. whether it supports 
     * capture only, render only, or both.
     */
    pjmedia_dir dir;

    /**
     * Specify whether the device supports callback. Devices that implement
     * "active interface" will actively call the callbacks to give or ask for
     * video frames. If the device doesn't support callback, application
     * must actively request or give video frames from/to the device by using
     * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame().
     */
    pj_bool_t has_callback;

    /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */
    unsigned caps;

    /** Number of video formats supported by this device */
    unsigned fmt_cnt;

    /** 
     * Array of supported video formats. Some fields in each supported video
     * format may be set to zero or of "unknown" value, to indicate that the
     * value is unknown or should be ignored. When these value are not set
     * to zero, it indicates that the exact format combination is being used. 
     */
    pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];

} pjmedia_vid_dev_info;


/** Forward declaration for pjmedia_vid_dev_stream */
typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;

typedef struct pjmedia_vid_dev_cb
{
    /**
    * This callback is called by capturer stream when it has captured the
    * whole packet worth of video samples.
    *
    * @param stream        The video stream.
    * @param user_data     User data associated with the stream.
    * @param frame         Captured frame.
    *
    * @return              Returning non-PJ_SUCCESS will cause the video
    *                      stream to stop
    */
    pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,
                              void *user_data,
                              pjmedia_frame *frame);

    /**
    * This callback is called by renderer stream when it needs additional
    * data to be rendered by the device. Application must fill in the whole
    * of output buffer with video samples.
    *
    * The frame argument contains the following values:
    *  - timestamp         Rendering timestamp, in samples.
    *  - buf               Buffer to be filled out by application.
    *  - size              The size requested in bytes, which will be equal
    *                      to the size of one whole packet.
    *
    * @param stream        The video stream.
    * @param user_data     User data associated with the stream.
    * @param frame         Video frame, which buffer is to be filled in by
    *                      the application.
    *
    * @return              Returning non-PJ_SUCCESS will cause the video 
    *                      stream to stop
    */
    pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,
                             void *user_data,
                             pjmedia_frame *frame);

} pjmedia_vid_dev_cb;


/**
 * This structure specifies the parameters to open the video stream.
 */
typedef struct pjmedia_vid_dev_param
{
    /**
     * The video direction. This setting is mandatory.
     */
    pjmedia_dir dir;

    /**
     * The video capture device ID. This setting is mandatory if the video
     * direction includes input/capture direction.
     */
    pjmedia_vid_dev_index cap_id;

    /**
     * The video render device ID. This setting is mandatory if the video
     * direction includes output/render direction.
     */
    pjmedia_vid_dev_index rend_id;

    /** 
     * Video clock rate. This setting is mandatory if the video
     * direction includes input/capture direction
     */
    unsigned clock_rate;

    /**
     * Video frame rate. This setting is mandatory if the video
     * direction includes input/capture direction
     */
//    pjmedia_ratio frame_rate;

    /**
     * This flags specifies which of the optional settings are valid in this
     * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.
     */
    unsigned flags;

    /**
     * Set the video format. This setting is mandatory.
     */
    pjmedia_format fmt;

    /**
     * Window for the renderer to display the video. This setting is optional,
     * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in 
     * the flags.
     */
    pjmedia_vid_dev_hwnd window;

    /**
     * Video display size. This setting is optional, and will only be used 
     * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.
     */
    pjmedia_rect_size disp_size;

    /**
     * Video window position. This setting is optional, and will only be used
     * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.
     */
    pjmedia_coord window_pos;

    /**
     * Video window's visibility. This setting is optional, and will only be
     * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.
     */
    pj_bool_t window_hide;

    /**
     * Enable built-in preview. This setting is optional and is only used
     * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and
     * set in the flags.
     */
    pj_bool_t native_preview;

    /**
     * Video orientation. This setting is optional and is only used if
     * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is
     * set in the flags.
     */
    pjmedia_orient orient;

    /**
     * Video window flags. This setting is optional, and will only be used
     * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags.
     */
    unsigned window_flags;

    /**
     * Video window's fullscreen status. This setting is optional, and will
     * only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_FULLSCREEN is set in the
     * flags.
     */
    pjmedia_vid_dev_fullscreen_flag window_fullscreen;

} pjmedia_vid_dev_param;


/** Forward declaration for video device factory */
typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;

/* typedef for factory creation function */
typedef pjmedia_vid_dev_factory*
(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);


/* Video driver structure */
typedef struct pjmedia_vid_driver
{
    pjmedia_vid_dev_factory_create_func_ptr create; /* Creation function    */
    pjmedia_vid_dev_factory *f;             /* Factory instance             */
    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        */
} pjmedia_vid_driver;


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

    unsigned            drv_cnt;        /* Number of drivers.                */
    pjmedia_vid_driver  drv[PJMEDIA_VID_DEV_MAX_DRIVERS];/* Array of drivers.*/

    unsigned            dev_cnt;        /* Total number of devices.          */
    pj_uint32_t         dev_list[PJMEDIA_VID_DEV_MAX_DEVS];/* Array of devIDs*/

} pjmedia_vid_subsys;


/**
 * Get the video subsystem.
 *
 * @return              The video subsystem.
 */
PJ_DECL(pjmedia_vid_subsys*) pjmedia_get_vid_subsys(void);


/**
 * Initialize the video driver.
 *
 * @param drv_idx       The index of the video driver.
 * @param refresh       Specify non-zero to refresh the video driver.
 *
 * @return              PJ_SUCCESS on successful operation or the appropriate
 *                      error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_driver_init(unsigned drv_idx,
                                             pj_bool_t refresh);


/**
 * Deinitialize the video driver.
 *
 * @param drv_idx       The index of the video driver.
 */
PJ_DECL(void) pjmedia_vid_driver_deinit(unsigned drv_idx);


/**
 * Initialize pjmedia_vid_dev_switch_param.
 *
 * @param p         Parameter to be initialized.
 */
PJ_INLINE(void)
pjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p)
{
    pj_bzero(p, sizeof(*p));
    p->target_id = PJMEDIA_VID_INVALID_DEV;
}

/**
 * Get string info for the specified capability.
 *
 * @param cap       The capability ID.
 * @param p_desc    Optional pointer which will be filled with longer
 *                  description about the capability.
 *
 * @return          Capability name.
 */
PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
                                              const char **p_desc);


/**
 * Set a capability field value in #pjmedia_vid_dev_param structure. This will
 * also set the flags field for the specified capability in the structure.
 *
 * @param param     The structure.
 * @param cap       The video capability which value is to be set.
 * @param pval      Pointer to value. Please see the type of value to
 *                  be supplied in the pjmedia_vid_dev_cap documentation.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t)
pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,
                              pjmedia_vid_dev_cap cap,
                              const void *pval);


/**
 * Get a capability field value from #pjmedia_vid_dev_param structure. This
 * function will return PJMEDIA_EVID_INVCAP error if the flag for that
 * capability is not set in the flags field in the structure.
 *
 * @param param     The structure.
 * @param cap       The video capability which value is to be retrieved.
 * @param pval      Pointer to value. Please see the type of value to
 *                  be supplied in the pjmedia_vid_dev_cap documentation.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t)
pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,
                              pjmedia_vid_dev_cap cap,
                              void *pval);


/**
 * Refresh the list of video devices installed in the system. This function
 * will only refresh the list of videoo device so all active video streams will
 * be unaffected. After refreshing the device list, application MUST make sure
 * to update all index references to video devices (i.e. all variables of type
 * pjmedia_vid_dev_index) before calling any function that accepts video device
 * index as its parameter.
 *
 * @return              PJ_SUCCESS on successful operation or the appropriate
 *                      error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void);


/**
 * Get the number of video devices installed in the system.
 *
 * @return          The number of video devices installed in the system.
 */
PJ_DECL(unsigned) pjmedia_vid_dev_count(void);


/**
 * Get device information.
 *
 * @param id        The video device ID.
 * @param info      The device information which will be filled in by this
 *                  function once it returns successfully.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
                                              pjmedia_vid_dev_info *info);


/**
 * Lookup device index based on the driver and device name.
 *
 * @param drv_name  The driver name.
 * @param dev_name  The device name.
 * @param id        Pointer to store the returned device ID.
 *
 * @return          PJ_SUCCESS if the device can be found.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,
                                            const char *dev_name,
                                            pjmedia_vid_dev_index *id);


/**
 * Initialize the video device parameters with default values for the
 * specified device.
 *
 * @param pool      The pool.
 * @param id        The video device ID.
 * @param param     The video device parameters which will be initialized
 *                  by this function once it returns successfully.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t)
pjmedia_vid_dev_default_param(pj_pool_t *pool,
                              pjmedia_vid_dev_index id,
                              pjmedia_vid_dev_param *param);


/**
 * Open video stream object using the specified parameters. If stream is
 * created successfully, this function will return PJ_SUCCESS and the
 * stream pointer will be returned in the p_strm argument.
 *
 * The opened stream may have been opened with different size and fps
 * than the requested values in the \a param argument. Application should
 * check the actual size and fps that the stream was opened with by inspecting
 * the values in the \a param argument and see if they have changed. Also
 * if the device ID in the \a param specifies default device, it may be
 * replaced with the actual device ID upon return.
 *
 * @param param         On input, it specifies the video device parameters
 *                      to be used for the stream. On output, this will be
 *                      set to the actual video device parameters used to
 *                      open the stream.
 * @param cb            Pointer to structure containing video stream
 *                      callbacks.
 * @param user_data     Arbitrary user data, which will be given back in the
 *                      callbacks.
 * @param p_strm        Pointer to receive the video stream.
 *
 * @return              PJ_SUCCESS on successful operation or the appropriate
 *                      error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
                                            pjmedia_vid_dev_param *param,
                                            const pjmedia_vid_dev_cb *cb,
                                            void *user_data,
                                            pjmedia_vid_dev_stream **p_strm);

/**
 * Get the running parameters for the specified video stream.
 *
 * @param strm      The video stream.
 * @param param     Video stream parameters to be filled in by this
 *                  function once it returns successfully.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(
                                            pjmedia_vid_dev_stream *strm,
                                            pjmedia_vid_dev_param *param);

/**
 * Get the value of a specific capability of the video stream.
 *
 * @param strm      The video stream.
 * @param cap       The video capability which value is to be retrieved.
 * @param value     Pointer to value to be filled in by this function
 *                  once it returns successfully.  Please see the type
 *                  of value to be supplied in the pjmedia_vid_dev_cap
 *                  documentation.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(
                                            pjmedia_vid_dev_stream *strm,
                                            pjmedia_vid_dev_cap cap,
                                            void *value);

/**
 * Set the value of a specific capability of the video stream.
 *
 * @param strm      The video stream.
 * @param cap       The video capability which value is to be set.
 * @param value     Pointer to value. Please see the type of value to
 *                  be supplied in the pjmedia_vid_dev_cap documentation.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(
                                            pjmedia_vid_dev_stream *strm,
                                            pjmedia_vid_dev_cap cap,
                                            const void *value);

/**
 * Start the stream.
 *
 * @param strm      The video stream.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(
                                            pjmedia_vid_dev_stream *strm);

/**
 * Query whether the stream has been started.
 *
 * @param strm      The video stream
 *
 * @return          PJ_TRUE if the video stream has been started.
 */
PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm);


/**
 * Request one frame from the stream. Application needs to call this function
 * periodically only if the stream doesn't support "active interface", i.e.
 * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
 *
 * @param strm      The video stream.
 * @param frame     The video frame to be filled by the device.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(
                                            pjmedia_vid_dev_stream *strm,
                                            pjmedia_frame *frame);

/**
 * Put one frame to the stream. Application needs to call this function
 * periodically only if the stream doesn't support "active interface", i.e.
 * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
 *
 * @param strm      The video stream.
 * @param frame     The video frame to put to the device.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(
                                            pjmedia_vid_dev_stream *strm,
                                            const pjmedia_frame *frame);

/**
 * Stop the stream.
 *
 * @param strm      The video stream.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(
                                            pjmedia_vid_dev_stream *strm);

/**
 * Destroy the stream.
 *
 * @param strm      The video stream.
 *
 * @return          PJ_SUCCESS on successful operation or the appropriate
 *                  error code.
 */
PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(
                                            pjmedia_vid_dev_stream *strm);


/**
 * @}
 */

PJ_END_DECL


#endif    /* __PJMEDIA_VIDEO_DEV_H__ */
