Commit a579563e authored by smorlat's avatar smorlat
Browse files

- workaround v4l2/uvc problems

- preview mirroring



git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@164 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 8c251647
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.3 on Tue Oct 14 00:04:09 2008 -->
<!--Generated with glade3 3.4.5 on Sat Nov 8 15:49:12 2008 -->
<glade-interface>
<widget class="GtkDialog" id="sip_account">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
......@@ -36,42 +36,49 @@
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkSpinButton" id="regperiod">
<widget class="GtkLabel" id="label38">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Your SIP identity:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
</child>
<child>
<widget class="GtkEntry" id="identity">
<property name="width_request">275</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="adjustment">3600 0 100000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label41">
<widget class="GtkLabel" id="label39">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Registration duration (sec):</property>
<property name="label" translatable="yes">SIP Proxy address:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="route">
<widget class="GtkEntry" id="proxy">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="text" translatable="yes">sip:</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
......@@ -87,50 +94,44 @@
</packing>
</child>
<child>
<widget class="GtkEntry" id="proxy">
<widget class="GtkEntry" id="route">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="text" translatable="yes">sip:</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label39">
<widget class="GtkLabel" id="label41">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">SIP Proxy address:</property>
<property name="label" translatable="yes">Registration duration (sec):</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="identity">
<widget class="GtkSpinButton" id="regperiod">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="adjustment">3600 0 100000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label38">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Your SIP identity:</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
</child>
</widget>
</child>
<child>
......
......@@ -89,10 +89,11 @@ MSDisplay *ms_display_new(MSDisplayDesc *desc);
void ms_display_set_window_id(MSDisplay *d, long window_id);
void ms_display_destroy(MSDisplay *d);
#define MS_VIDEO_OUT_SET_DISPLAY MS_FILTER_METHOD(MS_VIDEO_OUT_ID,0,MSDisplay*)
#define MS_VIDEO_OUT_HANDLE_RESIZING MS_FILTER_METHOD_NO_ARG(MS_VIDEO_OUT_ID,1)
#define MS_VIDEO_OUT_SET_CORNER MS_FILTER_METHOD(MS_VIDEO_OUT_ID,2,int*)
#define MS_VIDEO_OUT_AUTO_FIT MS_FILTER_METHOD(MS_VIDEO_OUT_ID,3,int)
#define MS_VIDEO_OUT_SET_DISPLAY MS_FILTER_METHOD(MS_VIDEO_OUT_ID,0,MSDisplay*)
#define MS_VIDEO_OUT_HANDLE_RESIZING MS_FILTER_METHOD_NO_ARG(MS_VIDEO_OUT_ID,1)
#define MS_VIDEO_OUT_SET_CORNER MS_FILTER_METHOD(MS_VIDEO_OUT_ID,2,int)
#define MS_VIDEO_OUT_AUTO_FIT MS_FILTER_METHOD(MS_VIDEO_OUT_ID,3,int)
#define MS_VIDEO_OUT_ENABLE_MIRRORING MS_FILTER_METHOD(MS_VIDEO_OUT_ID,4,int)
#ifdef __cplusplus
}
......
......@@ -44,6 +44,7 @@ typedef struct _EncData{
int mode;
uint64_t framenum;
Rfc3984Context packer;
int keyframe_int;
bool_t generate_keyframe;
}EncData;
......@@ -54,6 +55,7 @@ static void enc_init(MSFilter *f){
d->bitrate=384000;
d->vsize=MS_VIDEO_SIZE_CIF;
d->fps=30;
d->keyframe_int=10; /*10 seconds */
d->mode=0;
d->framenum=0;
d->generate_keyframe=FALSE;
......@@ -87,6 +89,11 @@ static void enc_preprocess(MSFilter *f){
params.rc.i_vbv_max_bitrate=(int) (((float)d->bitrate)*0.9/1000.0);
params.rc.i_vbv_buffer_size=params.rc.i_vbv_max_bitrate;
params.rc.f_vbv_buffer_init=0.5;
/*enable this by config ?*/
/*
params.i_keyint_max = (int)d->fps*d->keyframe_int;
params.i_keyint_min = (int)d->fps;
*/
params.b_repeat_headers=1;
params.b_cabac=0;//disable cabac to be baseline
params.i_bframe=0;/*no B frames*/
......
......@@ -81,13 +81,22 @@ static bool_t v4lv2_try_format(V4l2State *s, int fmtid){
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl (s->fd, VIDIOC_G_FMT, &fmt)<0){
ms_error("VIDIOC_G_FMT failed: %s",strerror(errno));
}
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = s->vsize.width;
fmt.fmt.pix.height = s->vsize.height;
fmt.fmt.pix.pixelformat = fmtid;
fmt.fmt.pix.field = V4L2_FIELD_ANY;
if (ioctl (s->fd, VIDIOC_S_FMT, &fmt)<0){
if (ioctl (s->fd, VIDIOC_TRY_FMT, &fmt)<0){
ms_message("VIDIOC_TRY_FMT: %s",strerror(errno));
return FALSE;
}
if (ioctl (s->fd, VIDIOC_S_FMT, &fmt)<0){
ms_message("VIDIOC_S_FMT: %s",strerror(errno));
return FALSE;
}
......@@ -114,6 +123,7 @@ static int get_picture_buffer_size(MSPixFmt pix_fmt, int w, int h){
static int v4l2_configure(V4l2State *s){
struct v4l2_capability cap;
struct v4l2_format fmt;
MSVideoSize vsize;
if (ioctl (s->fd, VIDIOC_QUERYCAP, &cap)<0) {
ms_message("Not a v4lv2 driver.");
......@@ -131,29 +141,41 @@ static int v4l2_configure(V4l2State *s){
}
ms_message("Driver is %s",cap.driver);
if (v4lv2_try_format(s,V4L2_PIX_FMT_YUV420)){
s->pix_fmt=MS_YUV420P;
s->int_pix_fmt=V4L2_PIX_FMT_YUV420;
ms_message("v4lv2: YUV420P choosen");
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_NV12)){
s->pix_fmt=MS_YUV420P;
s->int_pix_fmt=V4L2_PIX_FMT_NV12;
ms_message("v4lv2: V4L2_PIX_FMT_NV12 choosen");
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_MJPEG)){
s->pix_fmt=MS_MJPEG;
s->int_pix_fmt=V4L2_PIX_FMT_MJPEG;
ms_message("v4lv2: MJPEG choosen");
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_YUYV)){
s->pix_fmt=MS_YUYV;
s->int_pix_fmt=V4L2_PIX_FMT_YUYV;
ms_message("v4lv2: V4L2_PIX_FMT_YUYV choosen");
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_RGB24)){
s->pix_fmt=MS_RGB24;
s->int_pix_fmt=V4L2_PIX_FMT_RGB24;
ms_message("v4lv2: RGB24 choosen");
}else{
ms_error("Could not find supported pixel format.");
vsize=s->vsize;
do{
if (v4lv2_try_format(s,V4L2_PIX_FMT_YUV420)){
s->pix_fmt=MS_YUV420P;
s->int_pix_fmt=V4L2_PIX_FMT_YUV420;
ms_message("v4lv2: YUV420P choosen");
break;
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_MJPEG)){
s->pix_fmt=MS_MJPEG;
s->int_pix_fmt=V4L2_PIX_FMT_MJPEG;
ms_message("v4lv2: MJPEG choosen");
break;
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_YUYV)){
s->pix_fmt=MS_YUYV;
s->int_pix_fmt=V4L2_PIX_FMT_YUYV;
ms_message("v4lv2: V4L2_PIX_FMT_YUYV choosen");
break;
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_NV12)){
s->pix_fmt=MS_YUV420P;
s->int_pix_fmt=V4L2_PIX_FMT_NV12;
ms_message("v4lv2: V4L2_PIX_FMT_NV12 choosen");
break;
}else if (v4lv2_try_format(s,V4L2_PIX_FMT_RGB24)){
s->pix_fmt=MS_RGB24;
s->int_pix_fmt=V4L2_PIX_FMT_RGB24;
ms_message("v4lv2: RGB24 choosen");
break;
}else{
ms_error("Could not find supported pixel format for %ix%i", s->vsize.width, s->vsize.height);
}
s->vsize=ms_video_size_get_just_lower_than(s->vsize);
}while(s->vsize.width!=0);
if (s->vsize.width==0){
ms_message("Could not find any combination of resolution/pixel-format that works !");
s->vsize=vsize;
return -1;
}
memset(&fmt,0,sizeof(fmt));
......@@ -339,9 +361,8 @@ static void v4l2_uninit(MSFilter *f){
ms_free(s);
}
static void v4l2_process(MSFilter *f){
static void v4l2_preprocess(MSFilter *f){
V4l2State *s=(V4l2State*)f->data;
uint32_t elapsed;
if (s->fd==-1){
if (v4l2_open(s)==0 && v4l2_configure(s)==0 && v4l2_do_mmap(s)==0){
ms_message("V4L2 video capture started.");
......@@ -350,6 +371,12 @@ static void v4l2_process(MSFilter *f){
}
s->start_time=f->ticker->time;
}
}
static void v4l2_process(MSFilter *f){
V4l2State *s=(V4l2State*)f->data;
uint32_t elapsed;
if (s->fd!=-1){
/*see it is necessary to output a frame:*/
elapsed=f->ticker->time-s->start_time;
......@@ -429,6 +456,7 @@ MSFilterDesc ms_v4l2_desc={
.ninputs=0,
.noutputs=1,
.init=v4l2_init,
.preprocess=v4l2_preprocess,
.process=v4l2_process,
.postprocess=v4l2_postprocess,
.uninit=v4l2_uninit,
......
......@@ -526,6 +526,7 @@ typedef struct VideoOut
bool_t own_display;
bool_t ready;
bool_t autofit;
bool_t mirror;
} VideoOut;
......@@ -593,6 +594,7 @@ static void video_out_init(MSFilter *f){
obj->own_display=FALSE;
obj->ready=FALSE;
obj->autofit=FALSE;
obj->mirror=FALSE;
set_vsize(obj,&def_size);
f->data=obj;
}
......@@ -736,6 +738,7 @@ static void video_out_process(MSFilter *f){
src.h, obj->fbuf.planes, obj->fbuf.strides)<0){
ms_error("Error in sws_scale().");
}
if (obj->mirror && !mblk_get_precious_flag(inm)) yuv_buf_mirror(&obj->fbuf);
ms_display_unlock(obj->display);
}
ms_queue_flush(f->inputs[0]);
......@@ -800,12 +803,19 @@ static int video_out_set_corner(MSFilter *f,void *arg){
return 0;
}
static int video_out_enable_mirroring(MSFilter *f,void *arg){
VideoOut *s=(VideoOut*)f->data;
s->mirror=*(int*)arg;
return 0;
}
static MSFilterMethod methods[]={
{ MS_FILTER_SET_VIDEO_SIZE , video_out_set_vsize },
{ MS_VIDEO_OUT_SET_DISPLAY , video_out_set_display},
{ MS_VIDEO_OUT_SET_CORNER , video_out_set_corner},
{ MS_VIDEO_OUT_AUTO_FIT , video_out_auto_fit},
{ MS_VIDEO_OUT_HANDLE_RESIZING , video_out_handle_resizing},
{ MS_VIDEO_OUT_ENABLE_MIRRORING , video_out_enable_mirroring},
{ 0 ,NULL}
};
......
......@@ -353,6 +353,8 @@ VideoStream * video_preview_start(MSWebCam *device, MSVideoSize disp_size){
VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
MSVideoSize vsize=disp_size;
MSPixFmt format;
float fps=29.97;
int mirroring=1;
/* creates the filters */
stream->source = ms_web_cam_create_reader(device);
......@@ -361,6 +363,7 @@ VideoStream * video_preview_start(MSWebCam *device, MSVideoSize disp_size){
/* configure the filters */
ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
if (format==MS_MJPEG){
......@@ -374,6 +377,7 @@ VideoStream * video_preview_start(MSWebCam *device, MSVideoSize disp_size){
format=MS_YUV420P;
ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
ms_filter_call_method(stream->output,MS_VIDEO_OUT_ENABLE_MIRRORING,&mirroring);
/* and then connect all */
ms_filter_link(stream->source,0, stream->pixconv,0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment