Commit a2f12e7f authored by smorlat's avatar smorlat
Browse files

- resizing of capture

- updated for lastest mingw w32api
- use swscale 



git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@142 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent ec96cbfd
......@@ -222,7 +222,7 @@ Libs=../oRTP/build/win32native;../mediastreamer2/build/win32native;../../linphon
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-Wall -Werror_@@_-D_WIN32_WINNT=0x501_@@_-D_WORKAROUND_MINGW32_BUGS_@@_-DINET6_@@_-DORTP_INET6_@@_-DORTP_STATIC_@@_-DVIDEO_ENABLED_@@_-ggdb_@@_-DOSIP_MT_@@_
Compiler=-Wall -Werror_@@_-D_WIN32_WINNT=0x501_@@_-DINET6_@@_-DORTP_INET6_@@_-DORTP_STATIC_@@_-DVIDEO_ENABLED_@@_-ggdb_@@_-DOSIP_MT_@@_
CppCompiler=
Linker=
PreprocDefines=
......
......@@ -37,6 +37,7 @@ Source: "..\..\linphone-deps\bin\libogg.dll"; DestDir: "{app}"; Flags: ignorever
;;Source: "..\..\linphone-deps\bin\speex.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\linphone-deps\bin\avcodec.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\linphone-deps\bin\avutil.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\linphone-deps\bin\swscale.dll"; DestDir: "{app}"; Flags: ignoreversion
;;Source: "..\..\linphone-deps\bin\libspeex-1.dll"; DestDir: "{app}"; Flags: ignoreversion
;;Source: "..\..\linphone-deps\bin\libspeexdsp-1.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\mediastreamer2\build\win32native\mediastreamer2.dll"; DestDir: "{app}"; Flags: ignoreversion
......
......@@ -173,7 +173,7 @@ void linphone_gtk_cam_changed(GtkWidget *w){
void linphone_gtk_video_size_changed(GtkWidget *w){
int sel=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
const MSVideoSizeDef *defs=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());
if (defs<0) return;
if (sel<0) return;
linphone_core_set_preferred_video_size(linphone_gtk_get_core(),
defs[sel].vsize);
}
......
......@@ -51,7 +51,7 @@ Libs=../../../oRTP/build/win32native;../../../../linphone-deps/lib
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-DINET6 _@@_-DORTP_INET6 _@@_-DORTP_STATIC_@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DDISABLE_RESAMPLE_@@_-DVIDEO_ENABLED_@@_-Wall -Werror_@@_-g_@@_
Compiler=-DINET6 _@@_-DORTP_INET6 _@@_-DORTP_STATIC_@@_-D_WIN32_WINNT=0x0501 _@@_-DDISABLE_RESAMPLE_@@_-DVIDEO_ENABLED_@@_-Wall -Werror_@@_-g_@@_
CppCompiler=
Linker=libmediastreamer2.a_@@_-lortp_@@_-lgsm_@@_-lspeex_@@_-lws2_32_@@_-liphlpapi_@@_-lwinmm_@@_-lavcodec_@@_-lavutil_@@_-ltheora_@@_-logg_@@_-lvfw32_@@__@@_
PreprocDefines=
......
......@@ -512,9 +512,9 @@ Libs=../../../../linphone-deps/lib;../../../oRTP/build/win32native
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-ggdb_@@_-DINET6 _@@_-DORTP_INET6 _@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DNOSDL_@@_-DVIDEO_ENABLED_@@_-DNORESAMPLE_@@_-Wall _@@_-DHAVE_LIBAVCODEC_AVCODEC_H_@@_-D_TRUE_TIME_@@_
Compiler=-ggdb_@@_-DINET6 _@@_-DORTP_INET6 _@@_-D_WIN32_WINNT=0x0501 _@@_-DNOSDL_@@_-DVIDEO_ENABLED_@@_-DNORESAMPLE_@@_-Wall _@@_-DHAVE_LIBAVCODEC_AVCODEC_H_@@_-D_TRUE_TIME_@@_
CppCompiler=
Linker=-lortp_@@_-lavcodec_@@_-lavutil_@@_-ltheora_@@_-lspeex_@@_-lspeexdsp_@@_-lgsm_@@_-lws2_32_@@_-lwinmm_@@_-lvfw32_@@_-logg_@@__@@_
Linker=-lortp_@@_-lswscale_@@_-lavcodec_@@_-lavutil_@@_-ltheora_@@_-lspeex_@@_-lspeexdsp_@@_-lgsm_@@_-lws2_32_@@_-lwinmm_@@_-lvfw32_@@_-logg_@@__@@_
PreprocDefines=
CompilerSettings=0000000000010000000000
Icon=
......@@ -609,5 +609,5 @@ Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd= $(CC) -c winvideo2.c -o "Default Profile/winvideo2.o" $(CFLAGS)
BuildCmd=$(CC) -c winvideo2.c -o "Default Profile/winvideo2.o" $(CFLAGS)
......@@ -54,8 +54,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MS_VIDEO_SIZE_MAX_W MS_VIDEO_SIZE_1024_W
#define MS_VIDEO_SIZE_MAX_H MS_VIDEO_SIZE_1024_H
/* those structs are part of the ABI: don't change their size otherwise binary plugins will be broken*/
typedef struct MSVideoSize{
int16_t width,height;
int width,height;
} MSVideoSize;
typedef struct MSRect{
......@@ -78,21 +80,6 @@ typedef struct MSRect{
#define MS_VIDEO_SIZE_800X600 (MSVideoSize){MS_VIDEO_SIZE_800X600_W, MS_VIDEO_SIZE_800X600_H}
static inline bool_t ms_video_size_greater_than(MSVideoSize vs1, MSVideoSize vs2){
return (vs1.width>=vs2.width) && (vs1.height>=vs2.height);
}
static inline MSVideoSize ms_video_size_max(MSVideoSize vs1, MSVideoSize vs2){
return ms_video_size_greater_than(vs1,vs2) ? vs1 : vs2;
}
static inline MSVideoSize ms_video_size_min(MSVideoSize vs1, MSVideoSize vs2){
return ms_video_size_greater_than(vs1,vs2) ? vs2 : vs1;
}
static inline bool_t ms_video_size_equal(MSVideoSize vs1, MSVideoSize vs2){
return vs1.width==vs2.width && vs1.height==vs2.height;
}
typedef enum{
MS_YUV420P,
......@@ -130,6 +117,25 @@ void yuv_buf_mirror(YuvBuf *buf);
void rgb24_revert(uint8_t *buf, int w, int h, int linesize);
void rgb24_copy_revert(uint8_t *dstbuf, int dstlsz,
const uint8_t *srcbuf, int srclsz, MSVideoSize roi);
static inline bool_t ms_video_size_greater_than(MSVideoSize vs1, MSVideoSize vs2){
return (vs1.width>=vs2.width) && (vs1.height>=vs2.height);
}
static inline MSVideoSize ms_video_size_max(MSVideoSize vs1, MSVideoSize vs2){
return ms_video_size_greater_than(vs1,vs2) ? vs1 : vs2;
}
static inline MSVideoSize ms_video_size_min(MSVideoSize vs1, MSVideoSize vs2){
return ms_video_size_greater_than(vs1,vs2) ? vs2 : vs1;
}
static inline bool_t ms_video_size_equal(MSVideoSize vs1, MSVideoSize vs2){
return vs1.width==vs2.width && vs1.height==vs2.height;
}
MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs);
#ifdef __cplusplus
}
#endif
......
......@@ -224,6 +224,12 @@ static int enc_get_vsize(MSFilter *f, void *arg){
return 0;
}
static int enc_set_vsize(MSFilter *f, void *arg){
EncData *d=(EncData*)f->data;
d->vsize=*(MSVideoSize*)arg;
return 0;
}
static int enc_add_fmtp(MSFilter *f, void *arg){
EncData *d=(EncData*)f->data;
const char *fmtp=(const char *)arg;
......@@ -247,6 +253,7 @@ static MSFilterMethod enc_methods[]={
{ MS_FILTER_SET_BITRATE , enc_set_br },
{ MS_FILTER_GET_FPS , enc_get_fps },
{ MS_FILTER_GET_VIDEO_SIZE, enc_get_vsize },
{ MS_FILTER_SET_VIDEO_SIZE, enc_set_vsize },
{ MS_FILTER_ADD_FMTP , enc_add_fmtp },
{ MS_FILTER_REQ_VFU , enc_req_vfu },
{ 0 , NULL }
......
......@@ -189,3 +189,26 @@ void rgb24_copy_revert(uint8_t *dstbuf, int dstlsz,
psrc+=srclsz;
}
}
static MSVideoSize _ordered_vsizes[]={
MS_VIDEO_SIZE_QCIF,
MS_VIDEO_SIZE_QVGA,
MS_VIDEO_SIZE_CIF,
MS_VIDEO_SIZE_VGA,
MS_VIDEO_SIZE_4CIF,
MS_VIDEO_SIZE_720P,
{0,0}
};
MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs){
MSVideoSize *p;
MSVideoSize ret;
ret.width=0;
ret.height=0;
for(p=_ordered_vsizes;p->width!=0;++p){
if (ms_video_size_greater_than(vs,*p) && !ms_video_size_equal(vs,*p)){
ret=*p;
}else return ret;
}
return ret;
};
......@@ -349,8 +349,9 @@ void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const
VideoStream * video_preview_start(MSWebCam *device, MSVideoSize vsize){
VideoStream * video_preview_start(MSWebCam *device, MSVideoSize disp_size){
VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
MSVideoSize vsize=disp_size;
MSPixFmt format;
/* creates the filters */
......@@ -372,7 +373,7 @@ VideoStream * video_preview_start(MSWebCam *device, MSVideoSize vsize){
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,&vsize);
ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
/* and then connect all */
ms_filter_link(stream->source,0, stream->pixconv,0);
......
......@@ -27,8 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "nowebcam.h"
#include "mediastreamer2/mswebcam.h"
#ifndef _MSC_VER
#include "vfw-missing.h"
#ifndef AVSTREAMMASTER_NONE
#define AVSTREAMMASTER_NONE 1
#endif
#define AMD_HACK2
......
......@@ -26,8 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mswebcam.h"
#ifndef _MSC_VER
#include "vfw-missing.h"
#ifndef AVSTREAMMASTER_NONE
#define AVSTREAMMASTER_NONE 1
#endif
typedef void (*queue_msg_t)(void *, mblk_t *);
......@@ -42,6 +42,7 @@ typedef struct VfwEngine{
queue_msg_t cb;
void *cb_data;
bool_t started;
bool_t configured;
bool_t thread_running;
}VfwEngine;
......@@ -50,31 +51,38 @@ typedef struct VfwEngine{
static VfwEngine *engines[VFW_ENGINE_MAX_INSTANCES]={0};
static bool_t try_format(VfwEngine *s, BITMAPINFO *videoformat, MSPixFmt pixfmt){
MSVideoSize tried_size=s->vsize;
bool_t ret;
capGetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO));
videoformat->bmiHeader.biSizeImage = 0;
videoformat->bmiHeader.biWidth = s->vsize.width;
videoformat->bmiHeader.biHeight = s->vsize.height;
switch(pixfmt){
case MS_YUV420P:
videoformat->bmiHeader.biBitCount = 12;
videoformat->bmiHeader.biCompression=MAKEFOURCC('I','4','2','0');
break;
case MS_YUY2:
videoformat->bmiHeader.biBitCount = 16;
videoformat->bmiHeader.biCompression=MAKEFOURCC('Y','U','Y','2');
break;
case MS_RGB24:
videoformat->bmiHeader.biBitCount = 24;
videoformat->bmiHeader.biCompression=BI_RGB;
break;
default:
return FALSE;
}
ret=capSetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO));
do{
capGetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO));
videoformat->bmiHeader.biSizeImage = 0;
videoformat->bmiHeader.biWidth = tried_size.width;
videoformat->bmiHeader.biHeight = tried_size.height;
switch(pixfmt){
case MS_YUV420P:
videoformat->bmiHeader.biBitCount = 12;
videoformat->bmiHeader.biCompression=MAKEFOURCC('I','4','2','0');
break;
case MS_YUY2:
videoformat->bmiHeader.biBitCount = 16;
videoformat->bmiHeader.biCompression=MAKEFOURCC('Y','U','Y','2');
break;
case MS_RGB24:
videoformat->bmiHeader.biBitCount = 24;
videoformat->bmiHeader.biCompression=BI_RGB;
break;
default:
return FALSE;
}
ms_message("Trying video size %ix%i",tried_size.width,tried_size.height);
ret=capSetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO));
tried_size=ms_video_size_get_just_lower_than(tried_size);
}while(ret==FALSE && tried_size.width!=0);
if (ret) {
/*recheck video format */
capGetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO));
s->vsize.width=videoformat->bmiHeader.biWidth;
s->vsize.height=videoformat->bmiHeader.biHeight;
}
return ret;
}
......@@ -87,7 +95,8 @@ static int _vfw_engine_select_format(VfwEngine *obj){
capGetVideoFormat(obj->capvideo, &videoformat, sizeof(BITMAPINFO));
memcpy(compname,&videoformat.bmiHeader.biCompression,4);
compname[4]='\0';
ms_message("vfw: camera's current format is %s", compname);
ms_message("vfw: camera's current format is '%s' at %ix%i", compname,
videoformat.bmiHeader.biWidth,videoformat.bmiHeader.biHeight);
driver_last=ms_fourcc_to_pix_fmt(videoformat.bmiHeader.biCompression);
if (driver_last!=MS_PIX_FMT_UNKNOWN && try_format(obj,&videoformat,driver_last)){
ms_message("Using driver last setting");
......@@ -144,26 +153,38 @@ vfw_engine_thread(void *arg)
while(s->thread_running)
{
BOOL fGotMessage;
if((fGotMessage = PeekMessage(&msg, (HWND) s->capvideo, 0, 0, PM_REMOVE)) != 0)
while((fGotMessage = PeekMessage(&msg, (HWND) s->capvideo, 0, 0, PM_REMOVE)) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Sleep(10);
Sleep(10);
}
ms_thread_exit(NULL);
return NULL;
}
static void vfw_engine_destroy(VfwEngine *obj){
static void _vfw_engine_unconfigure(VfwEngine *obj){
if (!capCaptureStop(obj->capvideo)){
ms_error("vfw: fail to stop capture !");
}
obj->thread_running=FALSE;
ms_thread_join(obj->thread,NULL);
obj->configured=FALSE;
}
static void _vfw_engine_disconnect(VfwEngine *obj){
capDriverDisconnect(obj->capvideo);
DestroyWindow(obj->capvideo);
obj->capvideo=NULL;
}
static void vfw_engine_destroy(VfwEngine *obj){
if (obj->configured){
_vfw_engine_unconfigure(obj);
}
_vfw_engine_disconnect(obj);
ms_free(obj);
}
static int _vfw_engine_setup(VfwEngine *obj){
......@@ -188,50 +209,60 @@ static int _vfw_engine_setup(VfwEngine *obj){
return 0;
}
static int _vfw_engine_connect(VfwEngine *obj){
MSVideoSize sz;
sz.width=MS_VIDEO_SIZE_CIF_W;
sz.height=MS_VIDEO_SIZE_CIF_H;
HWND hwnd=capCreateCaptureWindow("Capture Window",WS_CHILD /* WS_OVERLAPPED */
,0,0,sz.width,sz.height,HWND_MESSAGE, 0) ;
if (hwnd==NULL) return -1;
if(!capDriverConnect(hwnd,obj->devidx)){
ms_warning("vfw: could not connect to capture driver, no webcam connected.");
DestroyWindow(hwnd);
return -1;
}
obj->capvideo=hwnd;
obj->vsize=sz;
return 0;
}
static VfwEngine * vfw_engine_new(int i){
char dev[512];
char ver[512];
VfwEngine *obj=(VfwEngine*)ms_new0(VfwEngine,1);
if (capGetDriverDescription(i, dev, sizeof (dev),
ver, sizeof (ver))){
MSVideoSize sz;
sz.width=MS_VIDEO_SIZE_CIF_W;
sz.height=MS_VIDEO_SIZE_CIF_H;
HWND hwnd=capCreateCaptureWindow("Capture Window",WS_CHILD /* WS_OVERLAPPED */
,0,0,sz.width,sz.height,HWND_MESSAGE, 0) ;
if (hwnd==NULL) return NULL;
if(!capDriverConnect(hwnd,i)){
ms_warning("vfw: could not connect to capture driver, no webcam connected.");
DestroyWindow(hwnd);
return NULL;
}
strcpy(obj->dev,dev);
obj->devidx=i;
obj->capvideo=hwnd;
obj->vsize=sz;
if (_vfw_engine_setup(obj)==-1){
vfw_engine_destroy(obj);
if (_vfw_engine_connect(obj)==-1){
ms_free(obj);
return NULL;
}
if (_vfw_engine_select_format(obj)==-1){
vfw_engine_destroy(obj);
return NULL;
}
capSetCallbackOnVideoStream(obj->capvideo, vfw_engine_stream_callback);
if (!capCaptureSequenceNoFile(obj->capvideo)){
ms_error("vfw: fail to start capture !");
}
ms_thread_create(&obj->thread,NULL,vfw_engine_thread,obj);
strcpy(obj->dev,dev);
engines[i]=obj;
return obj;
}
return NULL;
}
static void _vfw_engine_configure(VfwEngine *obj){
if (_vfw_engine_setup(obj)==-1){
return;
}
if (_vfw_engine_select_format(obj)==-1){
return ;
}
capSetCallbackOnVideoStream(obj->capvideo, vfw_engine_stream_callback);
if (!capCaptureSequenceNoFile(obj->capvideo)){
ms_error("vfw: fail to start capture !");
}
ms_thread_create(&obj->thread,NULL,vfw_engine_thread,obj);
obj->configured=TRUE;
}
static MSPixFmt vfw_engine_get_pix_fmt(VfwEngine *obj){
if (!obj->configured)
_vfw_engine_configure(obj);
return obj->pix_fmt;
}
......@@ -239,12 +270,25 @@ static MSVideoSize vfw_engine_get_video_size(VfwEngine *obj){
return obj->vsize;
}
static void vfw_engine_set_video_size(VfwEngine *obj, MSVideoSize vsize){
if (!obj->configured)
obj->vsize=vsize;
else if (ms_video_size_greater_than(vsize,obj->vsize) && !ms_video_size_equal(vsize,obj->vsize) ){
_vfw_engine_unconfigure(obj);
_vfw_engine_disconnect(obj);
_vfw_engine_connect(obj);
obj->vsize=vsize;
_vfw_engine_configure(obj);
}
}
static void vfw_engine_set_callback(VfwEngine* obj, queue_msg_t cb, void *cb_data){
obj->cb=cb;
obj->cb_data=cb_data;
}
static void vfw_engine_start_capture(VfwEngine *obj){
if (!obj->configured) _vfw_engine_configure(obj);
obj->started=TRUE;
}
......@@ -326,7 +370,6 @@ static void vfw_process(MSFilter * obj){
s->frame_count=0;
}
cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0);
if (cur_frame>s->frame_count){
mblk_t *om=NULL;
......@@ -366,6 +409,7 @@ static int vfw_get_pix_fmt(MSFilter *f,void *arg){
static int vfw_set_vsize(MSFilter *f, void *arg){
VfwState *s=(VfwState*)f->data;
s->vsize=*((MSVideoSize*)arg);
vfw_engine_set_video_size(s->eng,s->vsize);
return 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