From 69509cc9aa38121b97c4ee6f9d51739e1a8d2e74 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Thu, 30 Jul 2015 13:42:51 +0000 Subject: [PATCH] Re #1863: Add missing video Device API. - refresh device list, lookup dev, cap name, set/get capabilities git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5139 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua2/media.hpp | 184 ++++++++++++++++++++++++++++++++- pjsip/src/pjsua2/endpoint.cpp | 8 ++ pjsip/src/pjsua2/media.cpp | 161 ++++++++++++++++++++++++++++- 3 files changed, 351 insertions(+), 2 deletions(-) diff --git a/pjsip/include/pjsua2/media.hpp b/pjsip/include/pjsua2/media.hpp index 1f45e54ed..82909165b 100644 --- a/pjsip/include/pjsua2/media.hpp +++ b/pjsip/include/pjsua2/media.hpp @@ -1354,7 +1354,7 @@ struct MediaCoordinate */ struct MediaSize { - unsigned w; /**< The width. */ + unsigned w; /**< The width. */ unsigned h; /**< The height. */ }; @@ -1602,6 +1602,11 @@ private: */ struct VideoDevInfo { + /** + * The device ID + */ + pjmedia_vid_dev_index id; + /** * The device name */ @@ -1645,11 +1650,33 @@ struct VideoDevInfo /** Array of video device info */ typedef std::vector VideoDevInfoVector; +/** + * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability. + */ +struct VideoSwitchParam +{ + /** + * 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; +}; + /** * Video device manager. */ class VidDevManager { public: + /** + * Refresh the list of video devices installed in the system. This function + * will only refresh the list of video 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. + */ + void refreshDevs() throw(Error); + /** * Get the number of video devices installed in the system. * @@ -1673,6 +1700,161 @@ public: */ const VideoDevInfoVector &enumDev() throw(Error); + /** + * Lookup device index based on the driver and device name. + * + * @param drv_name The driver name. + * @param dev_name The device name. + * + * @return The device ID. If the device is not found, + * Error will be thrown. + */ + int lookupDev(const string &drv_name, + const string &dev_name) const throw(Error); + + /** + * Get string info for the specified capability. + * + * @param cap The capability ID. + * + * @return Capability name. + */ + string capName(pjmedia_vid_dev_cap cap) const; + + /** + * This will configure video format capability to the video device. + * If video device is currently active, the method will forward the setting + * to the video device instance to be applied immediately, if it + * supports it. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags, + * otherwise Error will be thrown. + * + * Note that in case the setting is kept for future use, it will be applied + * to any devices, even when application has changed the video device to be + * used. + * + * @param dev_id The video device id. + * @param format The video format. + * @param keep Specify whether the setting is to be kept for + * future use. + */ + void setFormat(int dev_id, + const MediaFormatVideo &format, + bool keep) throw(Error); + + /** + * Get the video format capability to the video device. + * If video device is currently active, the method will forward the request + * to the video device. If video device is currently inactive, and if + * application had previously set the setting and mark the setting as kept, + * then that setting will be returned. Otherwise, this method will + * raise error. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags, + * otherwise Error will be thrown. + * + * @param dev_id The video device id. + * @return keep The video format. + */ + MediaFormatVideo getFormat(int dev_id) const throw(Error); + + /** + * This will configure video format capability to the video device. + * If video device is currently active, the method will forward the setting + * to the video device instance to be applied immediately, if it + * supports it. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_INPUT_SCALE capability in VideoDevInfo.caps flags, + * otherwise Error will be thrown. + * + * Note that in case the setting is kept for future use, it will be applied + * to any devices, even when application has changed the video device to be + * used. + * + * @param dev_id The video device id. + * @param scale The video scale. + * @param keep Specify whether the setting is to be kept for + * future use. + */ + void setInputScale(int dev_id, + const MediaSize &scale, + bool keep) throw(Error); + + /** + * Get the video input scale capability to the video device. + * If video device is currently active, the method will forward the request + * to the video device. If video device is currently inactive, and if + * application had previously set the setting and mark the setting as kept, + * then that setting will be returned. Otherwise, this method will + * raise error. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags, + * otherwise Error will be thrown. + * + * @param dev_id The video device id. + * @return keep The video format. + */ + MediaSize getInputScale(int dev_id) const throw(Error); + + /** + * This will configure fast switching to another video device. + * If video device is currently active, the method will forward the setting + * to the video device instance to be applied immediately, if it + * supports it. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS capability in VideoDevInfo.caps + * flags, otherwise Error will be thrown. + * + * Note that in case the setting is kept for future use, it will be applied + * to any devices, even when application has changed the video device to be + * used. + * + * @param dev_id The video device id. + * @param flags The video window flag. + * @param keep Specify whether the setting is to be kept for + * future use. + */ + void setOutputWindowFlags(int dev_id, int flags, bool keep) throw(Error); + + /** + * Get the window output flags capability to the video device. + * If video device is currently active, the method will forward the request + * to the video device. If video device is currently inactive, and if + * application had previously set the setting and mark the setting as kept, + * then that setting will be returned. Otherwise, this method will + * raise error. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS capability in VideoDevInfo.caps + * flags, otherwise Error will be thrown. + * + * @param dev_id The video device id. + * @return keep The video format. + */ + int getOutputWindowFlags(int dev_id) throw(Error); + + /** + * This will configure fast switching to another video device. + * If video device is currently active, the method will forward the setting + * to the video device instance to be applied immediately, if it + * supports it. + * + * This method is only valid if the device has + * PJMEDIA_VID_DEV_CAP_SWITCH capability in VideoDevInfo.caps flags, + * otherwise Error will be thrown. + * + * @param dev_id The video device id. + * @param param The video switch param. + */ + void switchDev(int dev_id, + const VideoSwitchParam ¶m) throw(Error); + /** * Check whether the video capture device is currently active, i.e. if * a video preview has been started or there is a video call using diff --git a/pjsip/src/pjsua2/endpoint.cpp b/pjsip/src/pjsua2/endpoint.cpp index a522c6790..7eed81387 100644 --- a/pjsip/src/pjsua2/endpoint.cpp +++ b/pjsip/src/pjsua2/endpoint.cpp @@ -1707,6 +1707,9 @@ void Endpoint::videoCodecSetPriority(const string &codec_id, #if PJSUA_HAS_VIDEO pj_str_t codec_str = str2Pj(codec_id); PJSUA2_CHECK_EXPR(pjsua_vid_codec_set_priority(&codec_str, priority)); +#else + PJ_UNUSED_ARG(codec_id); + PJ_UNUSED_ARG(priority); #endif } @@ -1718,6 +1721,8 @@ CodecParam Endpoint::videoCodecGetParam(const string &codec_id) const pj_str_t codec_str = str2Pj(codec_id); PJSUA2_CHECK_EXPR(pjsua_vid_codec_get_param(&codec_str, pj_param)); +#else + PJ_UNUSED_ARG(codec_id); #endif return pj_param; } @@ -1730,6 +1735,9 @@ void Endpoint::videoCodecSetParam(const string &codec_id, pjmedia_vid_codec_param *pj_param = (pjmedia_vid_codec_param*)param; PJSUA2_CHECK_EXPR(pjsua_vid_codec_set_param(&codec_str, pj_param)); +#else + PJ_UNUSED_ARG(codec_id); + PJ_UNUSED_ARG(param); #endif } diff --git a/pjsip/src/pjsua2/media.cpp b/pjsip/src/pjsua2/media.cpp index 6c8dbf0e2..a53fcb107 100644 --- a/pjsip/src/pjsua2/media.cpp +++ b/pjsip/src/pjsua2/media.cpp @@ -1019,6 +1019,7 @@ VideoWindow::VideoWindow(pjsua_vid_win_id win_id) VideoWindowInfo VideoWindow::getInfo() const throw(Error) { VideoWindowInfo vwi; + pj_bzero(&vwi, sizeof(vwi)); #if PJSUA_HAS_VIDEO pjsua_vid_win_info pj_vwi; @@ -1122,6 +1123,7 @@ void VideoPreviewOpParam::fromPj(const pjsua_vid_preview_param &prm) pjsua_vid_preview_param VideoPreviewOpParam::toPj() const { pjsua_vid_preview_param param; + pj_bzero(¶m, sizeof(param)); #if PJSUA_HAS_VIDEO param.rend_id = this->rendId; param.show = this->show; @@ -1197,6 +1199,7 @@ void MediaFormatVideo::fromPj(const pjmedia_format &format) avgBps = format.det.vid.avg_bps; maxBps = format.det.vid.max_bps; #else + PJ_UNUSED_ARG(format); type = PJMEDIA_TYPE_UNKNOWN; #endif } @@ -1226,6 +1229,7 @@ pjmedia_format MediaFormatVideo::toPj() const void VideoDevInfo::fromPj(const pjmedia_vid_dev_info &dev_info) { #if PJSUA_HAS_VIDEO + id = dev_info.id; name = dev_info.name; driver = dev_info.driver; dir = dev_info.dir; @@ -1254,6 +1258,13 @@ VideoDevInfo::~VideoDevInfo() } /////////////////////////////////////////////////////////////////////////////// +void VidDevManager::refreshDevs() throw(Error) +{ +#if PJSUA_HAS_VIDEO + PJSUA2_CHECK_EXPR(pjmedia_vid_dev_refresh()); +#endif +} + unsigned VidDevManager::getDevCount() { #if PJSUA_HAS_VIDEO @@ -1272,6 +1283,8 @@ VideoDevInfo VidDevManager::getDevInfo(int dev_id) const throw(Error) PJSUA2_CHECK_EXPR(pjsua_vid_dev_get_info(dev_id, &pj_info)); dev_info.fromPj(pj_info); +#else + PJ_UNUSED_ARG(dev_id); #endif return dev_info; } @@ -1296,6 +1309,149 @@ const VideoDevInfoVector &VidDevManager::enumDev() throw(Error) return videoDevList; } +int VidDevManager::lookupDev(const string &drv_name, + const string &dev_name) const throw(Error) +{ + pjmedia_vid_dev_index pj_idx = 0; +#if PJSUA_HAS_VIDEO + PJSUA2_CHECK_EXPR(pjmedia_vid_dev_lookup(drv_name.c_str(), + dev_name.c_str(), + &pj_idx)); +#else + PJ_UNUSED_ARG(drv_name); + PJ_UNUSED_ARG(dev_name); +#endif + return pj_idx; +} + +string VidDevManager::capName(pjmedia_vid_dev_cap cap) const +{ + string cap_name; +#if PJSUA_HAS_VIDEO + cap_name = pjmedia_vid_dev_cap_name(cap, NULL); +#else + PJ_UNUSED_ARG(cap); +#endif + return cap_name; +} + +void VidDevManager::setFormat(int dev_id, + const MediaFormatVideo &format, + bool keep) throw(Error) +{ +#if PJSUA_HAS_VIDEO + pjmedia_format pj_format = format.toPj(); + + PJSUA2_CHECK_EXPR(pjsua_vid_dev_set_setting(dev_id, + PJMEDIA_VID_DEV_CAP_FORMAT, + &pj_format, + keep)); +#else + PJ_UNUSED_ARG(dev_id); + PJ_UNUSED_ARG(format); + PJ_UNUSED_ARG(keep); +#endif +} + +MediaFormatVideo VidDevManager::getFormat(int dev_id) const throw(Error) +{ + MediaFormatVideo vid_format; + pj_bzero(&vid_format, sizeof(vid_format)); +#if PJSUA_HAS_VIDEO + pjmedia_format pj_format; + PJSUA2_CHECK_EXPR(pjsua_vid_dev_get_setting(dev_id, + PJMEDIA_VID_DEV_CAP_FORMAT, + &pj_format)); + vid_format.fromPj(pj_format); +#else + PJ_UNUSED_ARG(dev_id); +#endif + return vid_format; +} + +void VidDevManager::setInputScale(int dev_id, + const MediaSize &scale, + bool keep) throw(Error) +{ +#if PJSUA_HAS_VIDEO + pjmedia_rect_size pj_size; + pj_size.w = scale.w; + pj_size.h = scale.h; + PJSUA2_CHECK_EXPR(pjsua_vid_dev_set_setting(dev_id, + PJMEDIA_VID_DEV_CAP_INPUT_SCALE, + &pj_size, + keep)); +#else + PJ_UNUSED_ARG(dev_id); + PJ_UNUSED_ARG(scale); + PJ_UNUSED_ARG(keep); +#endif +} + +MediaSize VidDevManager::getInputScale(int dev_id) const throw(Error) +{ + MediaSize scale; + pj_bzero(&scale, sizeof(scale)); +#if PJSUA_HAS_VIDEO + pjmedia_rect_size pj_size; + PJSUA2_CHECK_EXPR(pjsua_vid_dev_get_setting(dev_id, + PJMEDIA_VID_DEV_CAP_INPUT_SCALE, + &pj_size)); + + scale.w = pj_size.w; + scale.h = pj_size.h; +#else + PJ_UNUSED_ARG(dev_id); +#endif + return scale; +} + +void VidDevManager::setOutputWindowFlags(int dev_id, + int flags, + bool keep) throw(Error) +{ +#if PJSUA_HAS_VIDEO + PJSUA2_CHECK_EXPR(pjsua_vid_dev_set_setting(dev_id, + PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS, + &flags, + keep)); +#else + PJ_UNUSED_ARG(dev_id); + PJ_UNUSED_ARG(flags); + PJ_UNUSED_ARG(keep); +#endif +} + +int VidDevManager::getOutputWindowFlags(int dev_id) throw(Error) +{ + int flags = 0; + +#if PJSUA_HAS_VIDEO + PJSUA2_CHECK_EXPR(pjsua_vid_dev_get_setting(dev_id, + PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS, + &flags)); +#else + PJ_UNUSED_ARG(dev_id); +#endif + return flags; +} + +void VidDevManager::switchDev(int dev_id, + const VideoSwitchParam ¶m) throw(Error) +{ +#if PJSUA_HAS_VIDEO + pjmedia_vid_dev_switch_param pj_param; + pj_param.target_id = param.target_id; + PJSUA2_CHECK_EXPR(pjsua_vid_dev_set_setting(dev_id, + PJMEDIA_VID_DEV_CAP_SWITCH, + &pj_param, + PJ_FALSE)); +#else + PJ_UNUSED_ARG(dev_id); + PJ_UNUSED_ARG(param); +#endif +} + void VidDevManager::clearVideoDevList() { #if PJSUA_HAS_VIDEO @@ -1324,10 +1480,13 @@ void VidDevManager::setCaptureOrient(pjmedia_vid_dev_index dev_id, #if PJSUA_HAS_VIDEO PJSUA2_CHECK_EXPR(pjsua_vid_dev_set_setting(dev_id, PJMEDIA_VID_DEV_CAP_ORIENTATION, &orient, keep)); +#else + PJ_UNUSED_ARG(dev_id); + PJ_UNUSED_ARG(orient); + PJ_UNUSED_ARG(keep); #endif } - VidDevManager::VidDevManager() { }