diff --git a/include/baresip.h b/include/baresip.h index 37e85d0e7a..d7f91816a8 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -1430,6 +1430,7 @@ typedef void (video_err_h)(int err, const char *str, void *arg); int video_alloc(struct video **vp, struct list *streaml, const struct stream_param *stream_prm, const struct config *cfg, + const struct account *acc, struct sdp_session *sdp_sess, const struct mnat *mnat, struct mnat_sess *mnat_sess, const struct menc *menc, struct menc_sess *menc_sess, diff --git a/modules/account/account.c b/modules/account/account.c index 6ba59eddef..6262881a93 100644 --- a/modules/account/account.c +++ b/modules/account/account.c @@ -84,6 +84,8 @@ static int account_write_template(const char *file) "# ;stunserver=stun:[user:pass]@host[:port]\n" "# ;inreq_allowed={yes, no} # default: yes\n" "# ;video_codecs=h264,vp8,...\n" + "# ;video_source=v4l2,/dev/video0\n" + "# ;video_display=x11,nil\n" "#\n" "# Examples:\n" "#\n" diff --git a/src/account.c b/src/account.c index 9e804d558e..50f3088de4 100644 --- a/src/account.c +++ b/src/account.c @@ -40,6 +40,10 @@ static void destructor(void *arg) mem_deref(acc->ausrc_dev); mem_deref(acc->auplay_mod); mem_deref(acc->auplay_dev); + mem_deref(acc->vidsrc_mod); + mem_deref(acc->vidsrc_dev); + mem_deref(acc->viddisp_mod); + mem_deref(acc->viddisp_dev); mem_deref(acc->cert); mem_deref(acc->extra); mem_deref(acc->uas_user); @@ -630,7 +634,16 @@ int account_alloc(struct account **accp, const char *sipaddr) err |= decode_pair(&acc->auplay_mod, &acc->auplay_dev, &acc->laddr.params, "audio_player"); if (err) { - warning("account: audio_source/player parse error\n"); + warning("account: audio_source/audio_player parse error\n"); + goto out; + } + + err = decode_pair(&acc->vidsrc_mod, &acc->vidsrc_dev, + &acc->laddr.params, "video_source"); + err |= decode_pair(&acc->viddisp_mod, &acc->viddisp_dev, + &acc->laddr.params, "video_display"); + if (err) { + warning("account: video_source/video_display parse error\n"); goto out; } diff --git a/src/call.c b/src/call.c index e042b223a6..77cee843c8 100644 --- a/src/call.c +++ b/src/call.c @@ -753,7 +753,7 @@ int call_streams_alloc(struct call *call) /* Video stream */ if (call->use_video) { err = video_alloc(&call->video, &call->streaml, &strm_prm, - call->cfg, call->sdp, + call->cfg, acc, call->sdp, acc->mnat, call->mnats, acc->menc, call->mencs, "main", diff --git a/src/core.h b/src/core.h index abf38200ac..6f285e3ef6 100644 --- a/src/core.h +++ b/src/core.h @@ -88,6 +88,10 @@ struct account { char *ausrc_dev; char *auplay_mod; char *auplay_dev; + char *vidsrc_mod; + char *vidsrc_dev; + char *viddisp_mod; + char *viddisp_dev; uint32_t autelev_pt; /**< Payload type for telephone-events */ char *extra; /**< Extra parameters */ char *uas_user; /**< UAS authentication username */ diff --git a/src/peerconn.c b/src/peerconn.c index 41b2b60b42..10ca5f9ed4 100644 --- a/src/peerconn.c +++ b/src/peerconn.c @@ -367,8 +367,8 @@ int peerconnection_add_video_track(struct peer_connection *pc, mediatrack_close_handler, pc); err = video_alloc(&media->u.vid, &pc->streaml, &pc->stream_prm, cfg, - pc->sdp, pc->mnat, pc->mnats, pc->menc, pc->mencs, - NULL, vidcodecl, NULL, offerer, + NULL, pc->sdp, pc->mnat, pc->mnats, pc->menc, + pc->mencs, NULL, vidcodecl, NULL, offerer, video_error_handler, media); if (err) { warning("peerconnection: video alloc failed (%m)\n", err); diff --git a/src/video.c b/src/video.c index ddeb639025..60e4f13ce5 100644 --- a/src/video.c +++ b/src/video.c @@ -93,6 +93,7 @@ struct vtx { unsigned skipc; /**< Number of frames skipped */ struct list filtl; /**< Filters in encoding order */ enum vidfmt fmt; /**< Outgoing pixel format */ + char module[128]; /**< Source module name */ char device[128]; /**< Source device name */ uint32_t ts_offset; /**< Random timestamp offset */ bool picup; /**< Send picture update */ @@ -140,6 +141,7 @@ struct vrx { struct vidsz size; /**< Incoming video resolution */ enum vidfmt fmt; /**< Incoming pixel format */ enum vidorient orient; /**< Display orientation */ + char module[128]; /**< Display module name */ char device[128]; /**< Display device name */ int pt_rx; /**< Incoming RTP payload type */ int frames; /**< Number of frames received */ @@ -616,6 +618,7 @@ static int vtx_alloc(struct vtx *vtx, struct video *video) /* The initial value of the timestamp SHOULD be random */ vtx->ts_offset = rand_u16(); + str_ncpy(vtx->module, video->cfg.src_mod, sizeof(vtx->module)); str_ncpy(vtx->device, video->cfg.src_dev, sizeof(vtx->device)); vtx->fmt = (enum vidfmt)-1; @@ -636,6 +639,7 @@ static int vrx_alloc(struct vrx *vrx, struct video *video) vrx->pt_rx = -1; vrx->orient = VIDORIENT_PORTRAIT; + str_ncpy(vrx->module, video->cfg.disp_mod, sizeof(vrx->module)); str_ncpy(vrx->device, video->cfg.disp_dev, sizeof(vrx->device)); vrx->fmt = (enum vidfmt)-1; @@ -1050,6 +1054,7 @@ static int vrx_print_pipeline(struct re_printf *pf, const struct vrx *vrx) * @param streaml List of streams * @param stream_prm Stream parameters * @param cfg Global configuration + * @param acc Account (optional) * @param sdp_sess SDP Session * @param mnat Media NAT (optional) * @param mnat_sess Media NAT session (optional) @@ -1067,6 +1072,7 @@ static int vrx_print_pipeline(struct re_printf *pf, const struct vrx *vrx) int video_alloc(struct video **vp, struct list *streaml, const struct stream_param *stream_prm, const struct config *cfg, + const struct account *acc, struct sdp_session *sdp_sess, const struct mnat *mnat, struct mnat_sess *mnat_sess, const struct menc *menc, struct menc_sess *menc_sess, @@ -1095,6 +1101,26 @@ int video_alloc(struct video **vp, struct list *streaml, if (err) goto out; + if (acc && acc->vidsrc_mod) { + str_ncpy(v->vtx.module, acc->vidsrc_mod, + sizeof(v->vtx.module)); + str_ncpy(v->vtx.device, acc->vidsrc_dev, + sizeof(v->vtx.device)); + + info("video: using account specific source: (%s,%s)\n", + acc->vidsrc_mod, acc->vidsrc_dev); + } + + if (acc && acc->viddisp_mod) { + str_ncpy(v->vrx.module, acc->viddisp_mod, + sizeof(v->vrx.module)); + str_ncpy(v->vrx.device, acc->viddisp_dev, + sizeof(v->vrx.device)); + + info("video: using account specific display: (%s,%s)\n", + acc->viddisp_mod, acc->viddisp_dev); + } + mem_destructor(v, video_destructor); tmr_init(&v->tmr); @@ -1208,7 +1234,7 @@ static int set_vidisp(struct vrx *vrx) vrx->vidisp_prm.fullscreen = vrx->video->cfg.fullscreen; vd = (struct vidisp *)vidisp_find(baresip_vidispl(), - vrx->video->cfg.disp_mod); + vrx->module); if (!vd) return ENOENT; diff --git a/test/account.c b/test/account.c index dc3ff63eec..0194c88677 100644 --- a/test/account.c +++ b/test/account.c @@ -30,6 +30,7 @@ static const char str[] = ";mwi=no" ";call_transfer=no" ";audio_source=null,null" + ";video_source=null,null" ;