From 6b110e3449d1094f1c6e26ed784d6a9e46a28995 Mon Sep 17 00:00:00 2001 From: smorlat Date: Wed, 22 Oct 2008 09:16:50 +0000 Subject: [PATCH] - workaround a v4l2 driver bug - support for large video resolutions in progress. git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@112 3f6dc0c8-ddfe-455d-9043-3cd528dc4637 --- linphone/coreapi/linphonecore.c | 59 ++++ linphone/coreapi/linphonecore.h | 27 +- linphone/gtk-glade/parameters.glade | 486 ++++++++++++++------------- linphone/mediastreamer2/src/msv4l2.c | 26 +- 4 files changed, 358 insertions(+), 240 deletions(-) diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c index 406a1e318..794ffaaa2 100644 --- a/linphone/coreapi/linphonecore.c +++ b/linphone/coreapi/linphonecore.c @@ -557,6 +557,9 @@ void video_config_read(LinphoneCore *lc) if (str && str[0]==0) str=NULL; linphone_core_set_video_device(lc,str); + linphone_core_set_preferred_video_size_by_name(lc, + lp_config_get_string(lc->config,"video","size","cif")); + enabled=lp_config_get_int(lc->config,"video","enabled",1); capture=lp_config_get_int(lc->config,"video","capture",enabled); display=lp_config_get_int(lc->config,"video","display",enabled); @@ -2001,6 +2004,61 @@ const char *linphone_core_get_video_device(const LinphoneCore *lc){ return NULL; } +static MSVideoSizeDef supported_resolutions[]={ + { MS_VIDEO_SIZE_4CIF , "4cif" }, + { MS_VIDEO_SIZE_VGA , "vga" }, + { MS_VIDEO_SIZE_CIF , "cif" }, + { MS_VIDEO_SIZE_QCIF , "qcif" }, + { {0,0} , NULL } +}; + +const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc){ + return supported_resolutions; +} + +static MSVideoSize video_size_get_by_name(const char *name){ + MSVideoSizeDef *pdef=supported_resolutions; + for(;pdef->name!=NULL;pdef++){ + if (strcasecmp(name,pdef->name)==0){ + return pdef->vsize; + } + } + ms_warning("Video resolution %s is not supported in linphone.",name); + return (MSVideoSize){0,0}; +} + +const char *video_size_get_name(MSVideoSize vsize){ + MSVideoSizeDef *pdef=supported_resolutions; + for(;pdef->name!=NULL;pdef++){ + if (pdef->vsize.width==vsize.width && pdef->vsize.height==vsize.height){ + return pdef->name; + } + } + return NULL; +} + +static bool_t video_size_supported(MSVideoSize vsize){ + if (video_size_get_name(vsize)) return TRUE; + ms_warning("Video resolution %ix%i is not supported in linphone.",vsize.width,vsize.height); + return FALSE; +} + + +void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize){ + if (video_size_supported(vsize)) + lc->video_conf.vsize=vsize; +} + +void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name){ + MSVideoSize vsize=video_size_get_by_name(name); + if (vsize.width!=0) linphone_core_set_preferred_video_size(lc,vsize); + else linphone_core_set_preferred_video_size(lc,MS_VIDEO_SIZE_CIF); +} + +MSVideoSize linphone_core_get_preferred_video_size(LinphoneCore *lc){ + return lc->video_conf.vsize; +} + void linphone_core_use_files(LinphoneCore *lc, bool_t yesno){ lc->use_files=yesno; } @@ -2152,6 +2210,7 @@ void video_config_uninit(LinphoneCore *lc) 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); + lp_config_set_string(lc->config,"video","size",video_size_get_name(config->vsize)); } void codecs_config_uninit(LinphoneCore *lc) diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h index 2ced6a2f8..df71afbaf 100644 --- a/linphone/coreapi/linphonecore.h +++ b/linphone/coreapi/linphonecore.h @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ortp/ortp.h" #include "ortp/payloadtype.h" #include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msvideo.h" #define LINPHONE_IPADDR_SIZE 64 #define LINPHONE_HOSTNAME_SIZE 128 @@ -111,6 +112,7 @@ typedef struct codecs_config typedef struct video_config{ struct _MSWebCam *device; const char **cams; + MSVideoSize vsize; bool_t capture; bool_t show_local; bool_t display; @@ -673,12 +675,15 @@ MSList * linphone_core_get_call_logs(LinphoneCore *lc); 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*/ -void linphone_core_use_files(LinphoneCore *lc, bool_t yesno); -void linphone_core_set_play_file(LinphoneCore *lc, const char *file); -void linphone_core_set_record_file(LinphoneCore *lc, const char *file); - - +typedef struct MSVideoSizeDef{ + MSVideoSize vsize; + const char *name; +}MSVideoSizeDef; +/* returns a zero terminated table of MSVideoSizeDef*/ +const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc); +void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize); +MSVideoSize linphone_core_get_preferred_video_size(LinphoneCore *lc); +void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name); void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val); bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc); @@ -690,6 +695,16 @@ const char** linphone_core_get_video_devices(const LinphoneCore *lc); int linphone_core_set_video_device(LinphoneCore *lc, const char *id); const char *linphone_core_get_video_device(const LinphoneCore *lc); + + + +/*play/record support: use files instead of soundcard*/ +void linphone_core_use_files(LinphoneCore *lc, bool_t yesno); +void linphone_core_set_play_file(LinphoneCore *lc, const char *file); +void linphone_core_set_record_file(LinphoneCore *lc, const char *file); + + + int linphone_core_get_mtu(const LinphoneCore *lc); void linphone_core_set_mtu(LinphoneCore *lc, int mtu); diff --git a/linphone/gtk-glade/parameters.glade b/linphone/gtk-glade/parameters.glade index 78476ce16..d8a63ace3 100644 --- a/linphone/gtk-glade/parameters.glade +++ b/linphone/gtk-glade/parameters.glade @@ -1,6 +1,6 @@ - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -118,18 +118,48 @@ 3 2 - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP (UDP): + GTK_JUSTIFY_RIGHT + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio RTP/UDP: + GTK_JUSTIFY_RIGHT + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Video RTP/UDP: + GTK_JUSTIFY_RIGHT + + + 2 + 3 + + + + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 1 65535 1 10 10 - + 1 2 - 2 - 3 @@ -148,50 +178,20 @@ - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 1 65535 1 10 10 - + 1 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Video RTP/UDP: - GTK_JUSTIFY_RIGHT - - 2 3 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Audio RTP/UDP: - GTK_JUSTIFY_RIGHT - - - 1 - 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - SIP (UDP): - GTK_JUSTIFY_RIGHT - - @@ -397,6 +397,145 @@ + + + True + True + Enable echo cancellation + 0 + True + + + + 1 + 2 + 5 + 6 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + a sound card + + + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Playback device: + GTK_JUSTIFY_RIGHT + + + GTK_FILL + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring device: + GTK_JUSTIFY_RIGHT + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Capture device: + GTK_JUSTIFY_RIGHT + + + 2 + 3 + GTK_FILL + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + ALSA special device (optional): + GTK_JUSTIFY_RIGHT + + + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + default soundcard + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + default soundcard + + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring sound: + GTK_JUSTIFY_RIGHT + + + 4 + 5 + GTK_FILL + + True @@ -432,145 +571,6 @@ GTK_FILL - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Ring sound: - GTK_JUSTIFY_RIGHT - - - 4 - 5 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - 1 - 2 - 3 - 4 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - default soundcard - - - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - default soundcard - - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - ALSA special device (optional): - GTK_JUSTIFY_RIGHT - - - 3 - 4 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Capture device: - GTK_JUSTIFY_RIGHT - - - 2 - 3 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Ring device: - GTK_JUSTIFY_RIGHT - - - 1 - 2 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Playback device: - GTK_JUSTIFY_RIGHT - - - GTK_FILL - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - a sound card - - - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - True - Enable echo cancellation - 0 - True - - - - 1 - 2 - 5 - 6 - - @@ -599,16 +599,28 @@ True - 1 + 2 2 - + True - Video input device: - GTK_JUSTIFY_RIGHT + - GTK_EXPAND + 1 + 2 + 1 + 2 + + + + + True + Prefered video resolution: + + + 1 + 2 @@ -623,6 +635,16 @@ GTK_EXPAND + + + True + Video input device: + GTK_JUSTIFY_RIGHT + + + GTK_EXPAND + + @@ -698,42 +720,15 @@ 3 2 - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your display name (eg: John Doe): - - - - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + False 1 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your username: - - - 1 - 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your resulting SIP address: - - 2 3 @@ -753,19 +748,46 @@ - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your resulting SIP address: + + + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your username: + + + 1 + 2 + + + + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False + 1 2 - 2 - 3 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your display name (eg: John Doe): + + @@ -1284,17 +1306,21 @@ Video codecs 2 2 - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 stands for "unlimited" - 0 -1 100000 1 10 10 - + Download speed limit in Kbit/sec: + GTK_JUSTIFY_RIGHT + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Upload speed limit in Kbit/sec: + GTK_JUSTIFY_RIGHT - 1 - 2 1 2 @@ -1314,25 +1340,21 @@ Video codecs - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Upload speed limit in Kbit/sec: - GTK_JUSTIFY_RIGHT + 0 stands for "unlimited" + 0 -1 100000 1 10 10 + + 1 + 2 1 2 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Download speed limit in Kbit/sec: - GTK_JUSTIFY_RIGHT - - diff --git a/linphone/mediastreamer2/src/msv4l2.c b/linphone/mediastreamer2/src/msv4l2.c index 3b8f1bf1f..2a25d125b 100644 --- a/linphone/mediastreamer2/src/msv4l2.c +++ b/linphone/mediastreamer2/src/msv4l2.c @@ -47,6 +47,7 @@ typedef struct V4l2State{ MSVideoSize got_vsize; int pix_fmt; int int_pix_fmt; /*internal pixel format */ + int picture_size; mblk_t *frames[VIDEO_MAX_FRAME]; int frame_ind; int frame_max; @@ -92,6 +93,23 @@ static bool_t v4lv2_try_format(V4l2State *s, int fmtid){ return TRUE; } +static int get_picture_buffer_size(MSPixFmt pix_fmt, int w, int h){ + switch(pix_fmt){ + case MS_YUV420P: + return (w*h*3)/2; + break; + case MS_RGB24: + return w*h*3; + break; + case MS_YUYV: + return w*h*2; + break; + default: + return 0; + } + return 0; +} + static int v4l2_configure(V4l2State *s){ struct v4l2_capability cap; struct v4l2_format fmt; @@ -144,7 +162,7 @@ static int v4l2_configure(V4l2State *s){ }else{ ms_message("Size of picture is %ix%i",fmt.fmt.pix.width,fmt.fmt.pix.height); } - + s->picture_size=get_picture_buffer_size(s->pix_fmt,fmt.fmt.pix.width,fmt.fmt.pix.height); return 0; } @@ -270,7 +288,11 @@ static mblk_t * v4lv2_grab_image(V4l2State *s){ ms_warning("Ignoring empty buffer..."); return NULL; } - ret->b_wptr=ret->b_rptr+buf.bytesused; + /*normally buf.bytesused should contain the right buffer size; however we have found a buggy + driver that puts a random value inside */ + if (s->picture_size!=0) + ret->b_wptr=ret->b_rptr+s->picture_size; + else ret->b_wptr=ret->b_rptr+buf.bytesused; } } }