diff -Nur linphone-1.7.1/console/linphonec.c linphone-1.7.1-new/console/linphonec.c --- linphone-1.7.1/console/linphonec.c 2007-02-14 05:31:01.000000000 +0800 +++ linphone-1.7.1-new/console/linphonec.c 2007-10-23 17:02:14.000000000 +0800 @@ -107,7 +107,8 @@ //auto answer (-a) option static bool_t auto_answer=FALSE; static bool_t answer_call=FALSE; -static bool_t video_enabled=FALSE; +static bool_t vcap_enabled=FALSE; +static bool_t display_enabled=FALSE; LPC_AUTH_STACK auth_stack; static int trace_level = 0; static char *logfile_name = NULL; @@ -356,8 +357,8 @@ */ linphone_core_init (&linphonec, &linphonec_vtable, configfile_name, NULL); - linphone_core_enable_video(&linphonec,video_enabled); - if (!video_enabled) printf("Warning: video is disabled in linphonec. Run with -V option to enable it.\n"); + linphone_core_enable_video(&linphonec,vcap_enabled,display_enabled); + if (!(vcap_enabled || display_enabled)) printf("Warning: video is disabled in linphonec.\n"); /* * Initialize readline */ @@ -495,7 +496,8 @@ -l logfile specify the log file for your SIP phone\n\ -s sipaddress specify the sip call to do at startup\n\ -a enable auto answering for incoming calls\n\ - -V enable video (disabled by default)\n\ + -C enable video capture (disabled by default)\n\ + -D enable video display (disabled by default)\n\ -v or --version display version and exits.\n"); exit(exit_status); @@ -717,9 +719,13 @@ { auto_answer = TRUE; } - else if (strncmp ("-V", argv[arg_num], 2) == 0) + else if (strncmp ("-C", argv[arg_num], 2) == 0) { - video_enabled = TRUE; + vcap_enabled = TRUE; + } + else if (strncmp ("-D", argv[arg_num], 2) == 0) + { + display_enabled = TRUE; } else if ((strncmp ("-v", argv[arg_num], 2) == 0) || diff -Nur linphone-1.7.1/console/sipomatic.c linphone-1.7.1-new/console/sipomatic.c --- linphone-1.7.1/console/sipomatic.c 2007-03-26 21:21:35.000000000 +0800 +++ linphone-1.7.1-new/console/sipomatic.c 2007-10-23 17:32:11.000000000 +0800 @@ -104,8 +104,8 @@ call_count++; #ifdef VIDEO_ENABLED if (call->video.remoteport!=0){ - call->video_stream=video_stream_send_only_start(call->profile,call->video.localport,call->video.remaddr, - call->video.remoteport,call->video.pt,"/dev/video0"); + video_stream_send_only_start(call->video_stream,call->profile, + call->video.remaddr,call->video.remoteport,call->video.pt, 60, "/dev/video0"); } #endif call->time=time(NULL); diff -Nur linphone-1.7.1/coreapi/linphonecore.c linphone-1.7.1-new/coreapi/linphonecore.c --- linphone-1.7.1/coreapi/linphonecore.c 2007-04-16 19:53:40.000000000 +0800 +++ linphone-1.7.1-new/coreapi/linphonecore.c 2007-10-24 13:09:51.000000000 +0800 @@ -445,15 +445,16 @@ void video_config_read(LinphoneCore *lc) { - int tmp; + int capture, display; const char *str; str=lp_config_get_string(lc->config,"video","device","/dev/video0"); linphone_core_set_video_device(lc,NULL,str); - tmp=lp_config_get_int(lc->config,"video","enabled",1); + capture=lp_config_get_int(lc->config,"video","capture",0); + display=lp_config_get_int(lc->config,"video","display",0); #ifdef VIDEO_ENABLED - linphone_core_enable_video(lc,tmp); + linphone_core_enable_video(lc,capture,display); #endif } @@ -1236,14 +1237,23 @@ video_preview_stop(lc->previewstream); lc->previewstream=NULL; } - if (lc->video_conf.enabled){ + if (lc->video_conf.display || lc->video_conf.capture) { StreamParams *video_params=&call->video_params; if (video_params->remoteport>0){ - - video_stream_start(lc->videostream, call->profile, - video_params->remoteaddr,video_params->remoteport, - video_params->pt,jitt_comp, lc->video_conf.device); + if (lc->video_conf.display && lc->video_conf.capture) + video_stream_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->pt, jitt_comp, lc->video_conf.device); + else if (lc->video_conf.display) + video_stream_recv_only_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->pt, jitt_comp, lc->video_conf.device); + else if (lc->video_conf.capture) + video_stream_send_only_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->pt, jitt_comp, lc->video_conf.device); + video_stream_set_rtcp_information(lc->videostream, cname,tool); } } @@ -1263,7 +1273,12 @@ } #ifdef VIDEO_ENABLED if (lc->videostream!=NULL){ - video_stream_stop(lc->videostream); + if (lc->video_conf.display && lc->video_conf.capture) + video_stream_stop(lc->videostream); + else if (lc->video_conf.display) + video_stream_recv_only_stop(lc->videostream); + else if (lc->video_conf.capture) + video_stream_send_only_stop(lc->videostream); lc->videostream=NULL; } if (linphone_core_video_preview_enabled(lc)){ @@ -1674,13 +1689,18 @@ #endif } -void linphone_core_enable_video(LinphoneCore *lc, bool_t val){ +void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled){ #ifndef VIDEO_ENABLED - if (val) + if (vcap_enabled || display_enabled) ms_warning("This version of linphone was built without video support."); #endif - lc->video_conf.enabled=val; - lc->video_conf.show_local=val; + lc->video_conf.capture=vcap_enabled; + lc->video_conf.display=display_enabled; + if (vcap_enabled && display_enabled) + lc->video_conf.show_local=1; + else + lc->video_conf.show_local=0; + /* need to re-apply network bandwidth settings*/ linphone_core_set_download_bandwidth(lc, linphone_core_get_download_bandwidth(lc)); @@ -1689,7 +1709,7 @@ } bool_t linphone_core_video_enabled(LinphoneCore *lc){ - return lc->video_conf.enabled; + return (lc->video_conf.display || lc->video_conf.capture); } @@ -1830,7 +1850,8 @@ void video_config_uninit(LinphoneCore *lc) { video_config_t *config=&lc->video_conf; - lp_config_set_int(lc->config,"video","enabled",config->enabled); + lp_config_set_int(lc->config,"video","display",config->display); + lp_config_set_int(lc->config,"video","capture",config->capture); lp_config_set_int(lc->config,"video","show_local",config->show_local); } diff -Nur linphone-1.7.1/coreapi/linphonecore.h linphone-1.7.1-new/coreapi/linphonecore.h --- linphone-1.7.1/coreapi/linphonecore.h 2007-02-14 05:31:01.000000000 +0800 +++ linphone-1.7.1-new/coreapi/linphonecore.h 2007-10-17 15:50:09.000000000 +0800 @@ -103,8 +103,9 @@ typedef struct video_config{ char *device; - bool_t enabled; + bool_t capture; bool_t show_local; + bool_t display; }video_config_t; typedef struct ui_config @@ -621,7 +622,7 @@ MSList * linphone_core_get_call_logs(LinphoneCore *lc); /* video support */ -void linphone_core_enable_video(LinphoneCore *lc, bool_t val); +void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled); bool_t linphone_core_video_enabled(LinphoneCore *lc); /*play/record support: use files instead of soundcard*/ diff -Nur linphone-1.7.1/mediastreamer2/include/mediastreamer2/mediastream.h linphone-1.7.1-new/mediastreamer2/include/mediastreamer2/mediastream.h --- linphone-1.7.1/mediastreamer2/include/mediastreamer2/mediastream.h 2007-03-27 03:43:11.000000000 +0800 +++ linphone-1.7.1-new/mediastreamer2/include/mediastreamer2/mediastream.h 2007-10-17 15:54:20.000000000 +0800 @@ -127,10 +127,12 @@ VideoStream * video_preview_start(const char *device); void video_preview_stop(VideoStream *stream); -VideoStream * video_stream_send_only_start(RtpProfile *profile, int locport, const char *remip, int remport, int payload, const char *device); - +int video_stream_recv_only_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int payload, int jitt_comp, const char *device); +int video_stream_send_only_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int payload, int jitt_comp, const char *device); +void video_stream_recv_only_stop(VideoStream *stream); void video_stream_send_only_stop(VideoStream *stream); + bool_t ms_is_ipv6(const char *address); #ifdef __cplusplus diff -Nur linphone-1.7.1/mediastreamer2/src/msfilter.c linphone-1.7.1-new/mediastreamer2/src/msfilter.c --- linphone-1.7.1/mediastreamer2/src/msfilter.c 2006-09-08 23:32:57.000000000 +0800 +++ linphone-1.7.1-new/mediastreamer2/src/msfilter.c 2007-10-25 14:30:52.000000000 +0800 @@ -124,6 +124,8 @@ int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2){ MSQueue *q; + ms_return_val_if_fail(f1, -1); + ms_return_val_if_fail(f2, -1); ms_return_val_if_fail(pin1desc->noutputs, -1); ms_return_val_if_fail(pin2desc->ninputs, -1); ms_return_val_if_fail(f1->outputs[pin1]!=NULL,-1); diff -Nur linphone-1.7.1/mediastreamer2/src/videostream.c linphone-1.7.1-new/mediastreamer2/src/videostream.c --- linphone-1.7.1/mediastreamer2/src/videostream.c 2007-03-27 03:43:11.000000000 +0800 +++ linphone-1.7.1-new/mediastreamer2/src/videostream.c 2007-10-25 17:45:09.000000000 +0800 @@ -207,7 +207,7 @@ stream->ticker = ms_ticker_new(); /* attach it the graph */ ms_ticker_attach (stream->ticker, stream->source); - return 0; + return stream; } @@ -288,47 +288,117 @@ video_stream_free(stream); } - -VideoStream * video_stream_send_only_start(RtpProfile *profile, int locport, const char *remip, int remport, int payload, const char *device) +int video_stream_recv_only_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport,int payload, int jitt_comp, const char *device) { - VideoStream *stream = video_stream_new(locport,ms_is_ipv6(remip)); - RtpSession *rtps=stream->session; PayloadType *pt; MSPixFmt format; MSVideoSize vsize=MS_VIDEO_SIZE_CIF; - float fps=7; + RtpSession *rtps=stream->session; - rtp_session_set_profile(rtps,profile); if (remport>0) rtp_session_set_remote_addr(rtps,remip,remport); rtp_session_set_payload_type(rtps,payload); - rtp_session_set_jitter_compensation(rtps,60); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + /* creates rtp filters to recv streams */ + rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE); + stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID); + ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps); + /* creates the filters */ pt=rtp_profile_get_payload(profile,payload); if (pt==NULL){ video_stream_free(stream); ms_error("videostream.c: undefined payload type."); return NULL; } - stream->encoder=ms_filter_create_encoder(pt->mime_type); - if ((stream->encoder==NULL)){ + stream->decoder=ms_filter_create_decoder(pt->mime_type); + if (stream->decoder==NULL){ /* big problem: we have not a registered codec for this payload...*/ + ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_type); video_stream_free(stream); - ms_error("videostream.c: No codecs available for payload %i.",payload); return NULL; } + + stream->sizeconv = ms_filter_new(MS_SIZE_CONV_ID); + stream->output=ms_filter_new(MS_VIDEO_OUT_ID); + + /*force the decoder to output YUV420P */ + format=MS_YUV420P; + /*ask the size-converter to always output CIF */ + vsize=MS_VIDEO_SIZE_CIF; + ms_message("Setting output vsize=%ix%i",vsize.width,vsize.height); + + ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize); + ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize); + + if (pt->recv_fmtp!=NULL) { + ms_message("pt->recv_fmtp: %s", pt->recv_fmtp); + ms_filter_call_method(stream->decoder,MS_FILTER_SET_FMTP,(void*)pt->recv_fmtp); + } + + /* and then connect all */ + ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); + ms_filter_link (stream->decoder,0 , stream->sizeconv, 0); + ms_filter_link (stream->sizeconv, 0, stream->output, 0); + + /* create the ticker */ + stream->ticker = ms_ticker_new(); + /* attach it the graph */ + ms_ticker_attach (stream->ticker, stream->rtprecv); + return stream; +} + +void +video_stream_recv_only_stop (VideoStream * stream) +{ + ms_ticker_detach(stream->ticker, stream->rtprecv); + rtp_stats_display(rtp_session_get_stats(stream->session),"Video session's RTP statistics"); + ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); + ms_filter_unlink(stream->decoder,0,stream->sizeconv,0); + ms_filter_unlink(stream->sizeconv,0,stream->output,0); + video_stream_free (stream); +} + + +int video_stream_send_only_start(VideoStream* stream, RtpProfile *profile, const char *remip, int remport, int payload, int jitt_comp, const char *device) +{ + PayloadType *pt; + MSPixFmt format; + MSVideoSize vsize=MS_VIDEO_SIZE_CIF; + RtpSession *rtps=stream->session; + float fps=15; + rtp_session_set_profile(rtps,profile); + if (remport>0) rtp_session_set_remote_addr(rtps,remip,remport); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); - /* creates two rtp filters to recv send streams (remote part) */ - rtp_session_set_recv_buf_size(stream->session,MAX_RTP_SIZE); + /* creates rtp filter to send streams (remote part) */ + rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE); stream->rtpsend =ms_filter_new(MS_RTP_SEND_ID); if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session); - /* creates the filters */ + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + video_stream_free(stream); + ms_error("videostream.c: undefined payload type."); + return NULL; + } + stream->encoder=ms_filter_create_encoder(pt->mime_type); + if ((stream->encoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + video_stream_free(stream); + ms_error("videostream.c: No codecs available for payload %i.",payload); + return NULL; + } + stream->source = ms_filter_new(MS_V4L_ID); stream->pixconv= ms_filter_new(MS_PIX_CONV_ID); - /* configure the filters */ if (pt->send_fmtp) @@ -345,8 +415,9 @@ /*set it to the pixconv */ ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format); ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize); - - /*force the decoder to output YUV420P */ + + ms_message("vsize=%ix%i, fps=%f, send format: %s, capture format: %d, bitrate: %d", + vsize.width,vsize.height,fps,pt->send_fmtp,format, pt->normal_bitrate); /* and then connect all */ ms_filter_link (stream->source, 0, stream->pixconv, 0);