diff options
author | Riza Sulistyo <riza@teluu.com> | 2016-08-05 07:26:18 +0000 |
---|---|---|
committer | Riza Sulistyo <riza@teluu.com> | 2016-08-05 07:26:18 +0000 |
commit | a95fd7ee553a5b1774d263e5be91c859719189da (patch) | |
tree | 403218b2176d57bc7dd2d3098d40e555dae25d16 | |
parent | 32479fea1f498f051e64570c5280cd77746b14e3 (diff) |
Re #1910: Implement option to regularly send video keyframe in the beginning of video call session.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5410 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjmedia/include/pjmedia/config.h | 19 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/vid_stream.h | 33 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/vid_stream.c | 37 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 7 | ||||
-rw-r--r-- | pjsip/include/pjsua2/account.hpp | 15 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_vid.c | 3 | ||||
-rw-r--r-- | pjsip/src/pjsua2/account.cpp | 8 |
8 files changed, 123 insertions, 0 deletions
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h index 817fba89..cbcd08fb 100644 --- a/pjmedia/include/pjmedia/config.h +++ b/pjmedia/include/pjmedia/config.h @@ -1330,6 +1330,25 @@ # define PJMEDIA_HAS_DTMF_FLASH 1 #endif +/** + * Specify the number of keyframe needed to be sent after the stream is + * created. Setting this to 0 will disable it. + * + * Default : 5 + */ +#ifndef PJMEDIA_VID_STREAM_START_KEYFRAME_CNT +# define PJMEDIA_VID_STREAM_START_KEYFRAME_CNT 5 +#endif + +/** + * Specify the interval to send keyframe after the stream is created, in msec. + * + * Default : 1000 + */ +#ifndef PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC +# define PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC 1000 +#endif + /** * @} diff --git a/pjmedia/include/pjmedia/vid_stream.h b/pjmedia/include/pjmedia/vid_stream.h index c812d37d..cd756f1e 100644 --- a/pjmedia/include/pjmedia/vid_stream.h +++ b/pjmedia/include/pjmedia/vid_stream.h @@ -117,6 +117,28 @@ typedef struct pjmedia_vid_stream_rc_config } pjmedia_vid_stream_rc_config; +/** + * Structure of configuration settings for video stream sending keyframe + * after it is created. + */ +typedef struct pjmedia_vid_stream_sk_config +{ + /** + * The number of keyframe to be sent after the stream is created. + * + * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_CNT + */ + unsigned count; + + /** + * The keyframe sending interval after the stream is created. + * + * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC + */ + unsigned interval; + +} pjmedia_vid_stream_sk_config; + /** * This structure describes video stream information. Each video stream @@ -165,6 +187,9 @@ typedef struct pjmedia_vid_stream_info pjmedia_vid_stream_rc_config rc_cfg; /**< Stream send rate control settings. */ + + pjmedia_vid_stream_sk_config sk_cfg; + /**< Stream send keyframe settings. */ } pjmedia_vid_stream_info; @@ -201,6 +226,14 @@ pjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si, PJ_DECL(void) pjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg); +/** + * Initialize the video stream send keyframe with default settings. + * + * @param cfg Video stream send keyframe structure to be initialized. + */ +PJ_DECL(void) +pjmedia_vid_stream_sk_config_default(pjmedia_vid_stream_sk_config *cfg); + /* * Opaque declaration for video stream. diff --git a/pjmedia/src/pjmedia/vid_stream.c b/pjmedia/src/pjmedia/vid_stream.c index 69891ffb..c586018f 100644 --- a/pjmedia/src/pjmedia/vid_stream.c +++ b/pjmedia/src/pjmedia/vid_stream.c @@ -154,6 +154,13 @@ struct pjmedia_vid_stream frame assembly. */ pj_bool_t force_keyframe;/**< Forced to encode keyframe? */ + unsigned num_keyframe; /**< The number of keyframe needed + to be sent, after the stream + is created. */ + pj_timestamp last_keyframe_tx; + /**< Timestamp of the last + keyframe. */ + #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 pj_bool_t use_ka; /**< Stream keep-alive with non- @@ -850,6 +857,23 @@ static pj_status_t put_frame(pjmedia_port *port, frame_out.buf = ((char*)channel->buf) + sizeof(pjmedia_rtp_hdr); frame_out.size = 0; + /* Check if need to send keyframe. */ + if (stream->num_keyframe) { + unsigned elapse_time; + pj_timestamp now; + + pj_get_timestamp(&now); + + elapse_time = pj_elapsed_msec(&stream->last_keyframe_tx, &now); + + if (elapse_time > stream->info.sk_cfg.interval) + { + stream->force_keyframe = PJ_TRUE; + if (--stream->num_keyframe) + stream->last_keyframe_tx = now; + } + } + /* Init encoding option */ pj_bzero(&enc_opt, sizeof(enc_opt)); if (stream->force_keyframe) { @@ -1459,6 +1483,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_create( #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 stream->use_ka = info->use_ka; #endif + stream->num_keyframe = info->sk_cfg.count; /* Build random RTCP CNAME. CNAME has user@host format */ stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); @@ -2009,4 +2034,16 @@ pjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg) } +/* + * Initialize the video stream send keyframe with default settings. + */ +PJ_DEF(void) +pjmedia_vid_stream_sk_config_default(pjmedia_vid_stream_sk_config *cfg) +{ + pj_bzero(cfg, sizeof(*cfg)); + cfg->count = PJMEDIA_VID_STREAM_START_KEYFRAME_CNT; + cfg->interval = PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC; +} + + #endif /* PJMEDIA_HAS_VIDEO */ diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index e75636ca..279ede7f 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -3306,6 +3306,13 @@ typedef struct pjsua_acc_config pjmedia_vid_stream_rc_config vid_stream_rc_cfg; /** + * Specify the send keyframe config for video stream. + * + * Default: see #pjmedia_vid_stream_sk_config + */ + pjmedia_vid_stream_sk_config vid_stream_sk_cfg; + + /** * Media transport config. */ pjsua_transport_config rtp_cfg; diff --git a/pjsip/include/pjsua2/account.hpp b/pjsip/include/pjsua2/account.hpp index acb78165..fedfa595 100644 --- a/pjsip/include/pjsua2/account.hpp +++ b/pjsip/include/pjsua2/account.hpp @@ -831,6 +831,21 @@ struct AccountVideoConfig : public PersistentObject */ unsigned rateControlBandwidth; + /** + * The number of keyframe to be sent after the stream is created. + * + * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_CNT + */ + unsigned startKeyframeCount; + + /** + * The keyframe sending interval after the stream is created. + * + * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC + */ + unsigned startKeyframeInterval; + + public: /** * Read this object from a container node. diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index e3bc4e9f..7725be81 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -277,6 +277,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) cfg->vid_rend_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV; #if PJMEDIA_HAS_VIDEO pjmedia_vid_stream_rc_config_default(&cfg->vid_stream_rc_cfg); + pjmedia_vid_stream_sk_config_default(&cfg->vid_stream_sk_cfg); #endif pjsua_transport_config_default(&cfg->rtp_cfg); diff --git a/pjsip/src/pjsua-lib/pjsua_vid.c b/pjsip/src/pjsua-lib/pjsua_vid.c index 42506b84..ed3e94e8 100644 --- a/pjsip/src/pjsua-lib/pjsua_vid.c +++ b/pjsip/src/pjsua-lib/pjsua_vid.c @@ -911,6 +911,9 @@ pj_status_t pjsua_vid_channel_update(pjsua_call_media *call_med, /* Set rate control config from account setting */ si->rc_cfg = acc->cfg.vid_stream_rc_cfg; + /* Set send keyframe config from account setting */ + si->sk_cfg = acc->cfg.vid_stream_sk_cfg; + #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 /* Enable/disable stream keep-alive and NAT hole punch. */ si->use_ka = pjsua_var.acc[call->acc_id].cfg.use_stream_ka; diff --git a/pjsip/src/pjsua2/account.cpp b/pjsip/src/pjsua2/account.cpp index 2160afa4..d36affeb 100644 --- a/pjsip/src/pjsua2/account.cpp +++ b/pjsip/src/pjsua2/account.cpp @@ -277,6 +277,8 @@ void AccountVideoConfig::readObject(const ContainerNode &node) throw(Error) NODE_READ_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice); NODE_READ_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod); NODE_READ_UNSIGNED( this_node, rateControlBandwidth); + NODE_READ_UNSIGNED( this_node, startKeyframeCount); + NODE_READ_UNSIGNED( this_node, startKeyframeInterval); } void AccountVideoConfig::writeObject(ContainerNode &node) const throw(Error) @@ -290,6 +292,8 @@ void AccountVideoConfig::writeObject(ContainerNode &node) const throw(Error) NODE_WRITE_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice); NODE_WRITE_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod); NODE_WRITE_UNSIGNED( this_node, rateControlBandwidth); + NODE_WRITE_UNSIGNED( this_node, startKeyframeCount); + NODE_WRITE_UNSIGNED( this_node, startKeyframeInterval); } /////////////////////////////////////////////////////////////////////////////// @@ -433,6 +437,8 @@ void AccountConfig::toPj(pjsua_acc_config &ret) const ret.vid_rend_dev = videoConfig.defaultRenderDevice; ret.vid_stream_rc_cfg.method= videoConfig.rateControlMethod; ret.vid_stream_rc_cfg.bandwidth = videoConfig.rateControlBandwidth; + ret.vid_stream_sk_cfg.count = videoConfig.startKeyframeCount; + ret.vid_stream_sk_cfg.interval = videoConfig.startKeyframeInterval; } /* Initialize from pjsip. */ @@ -598,6 +604,8 @@ void AccountConfig::fromPj(const pjsua_acc_config &prm, videoConfig.defaultRenderDevice = prm.vid_rend_dev; videoConfig.rateControlMethod = prm.vid_stream_rc_cfg.method; videoConfig.rateControlBandwidth = prm.vid_stream_rc_cfg.bandwidth; + videoConfig.startKeyframeCount = prm.vid_stream_sk_cfg.count; + videoConfig.startKeyframeInterval = prm.vid_stream_sk_cfg.interval; } void AccountConfig::readObject(const ContainerNode &node) throw(Error) |