Commit fb113617 authored by smorlat's avatar smorlat

support for large video formats

bugfixing in SDL video output



git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@120 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 94f6bf42
......@@ -1460,7 +1460,7 @@ void linphone_core_stop_media_streams(LinphoneCore *lc){
}
if (linphone_core_video_preview_enabled(lc)){
if (lc->previewstream==NULL){
lc->previewstream=video_preview_start(lc->video_conf.device);
lc->previewstream=video_preview_start(lc->video_conf.device, lc->video_conf.vsize);
}
}
#endif
......@@ -1940,7 +1940,8 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
if (lc->videostream==NULL){
if (val){
if (lc->previewstream==NULL){
lc->previewstream=video_preview_start(lc->video_conf.device);
lc->previewstream=video_preview_start(lc->video_conf.device,
lc->video_conf.vsize);
}
}else{
if (lc->previewstream!=NULL){
......@@ -2045,8 +2046,14 @@ static bool_t video_size_supported(MSVideoSize vsize){
void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize){
if (video_size_supported(vsize))
if (video_size_supported(vsize)){
MSVideoSize oldvsize=lc->video_conf.vsize;
lc->video_conf.vsize=vsize;
if (!ms_video_size_equal(oldvsize,vsize) && lc->previewstream!=NULL){
toggle_video_preview(lc,FALSE);
toggle_video_preview(lc,TRUE);
}
}
}
void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name){
......
This diff is collapsed.
......@@ -33,6 +33,23 @@ static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices,
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
}
void linphone_gtk_fill_video_sizes(GtkWidget *combo){
const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
int i,active=0;
char vsize_def[256];
MSVideoSize cur=linphone_core_get_preferred_video_size(linphone_gtk_get_core());
/* glade creates a combo box without list model and text renderer,
unless we fill it with a dummy text.
This dummy text needs to be removed first*/
gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0);
for(i=0;def->name!=NULL;++def,++i){
snprintf(vsize_def,sizeof(vsize_def),"%s (%ix%i)",def->name,def->vsize.width,def->vsize.height);
gtk_combo_box_append_text(GTK_COMBO_BOX(combo),vsize_def);
if (cur.width==def->vsize.width && cur.height==def->vsize.height) active=i;
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
}
void linphone_gtk_parameters_closed(GtkWidget *button){
GtkWidget *pb=gtk_widget_get_toplevel(button);
gtk_widget_destroy(pb);
......@@ -153,6 +170,14 @@ void linphone_gtk_cam_changed(GtkWidget *w){
g_free(sel);
}
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;
linphone_core_set_preferred_video_size(linphone_gtk_get_core(),
defs[sel].vsize);
}
void linphone_gtk_ring_file_set(GtkWidget *w){
gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w));
linphone_core_set_ring(linphone_gtk_get_core(),file);
......@@ -623,6 +648,7 @@ void linphone_gtk_show_parameters(void){
linphone_core_get_capture_device(lc));
linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc),
linphone_core_get_video_device(lc));
linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")),
linphone_core_echo_cancelation_enabled(lc));
......
......@@ -101,17 +101,24 @@ AC_DEFUN([MS_CHECK_VIDEO],[
PKG_CHECK_MODULES(SWSCALE, [libswscale >= 0.5.0 ], [echo "We have libswscale"],
[echo "We don't have libswscale, let's hope its symbols are in libavcodec"] )
MS_CHECK_DEP([SDL],[SDL],[${libsdldir}/include],[${libsdldir}/lib],[SDL/SDL.h],[SDL],[SDL_Init])
if test "$SDL_found" = "no" ; then
AC_MSG_ERROR([Could not find libsdl headers and library. This is mandatory for video support])
if test "$libsdldir" != "none" ; then
MS_CHECK_DEP([SDL],[SDL],[${libsdldir}/include],[${libsdldir}/lib],[SDL/SDL.h],[SDL],[SDL_Init])
if test "$SDL_found" = "no" ; then
AC_MSG_ERROR([Could not find libsdl headers and library. This is mandatory for video support])
fi
fi
PKG_CHECK_MODULES(THEORA, [theora >= 1.0alpha7 ], [have_theora=yes],
[have_theora=no])
AC_CHECK_HEADERS(X11/Xlib.h)
VIDEO_CFLAGS=" $FFMPEG_CFLAGS $SDL_CFLAGS -DVIDEO_ENABLED "
VIDEO_LIBS=" $FFMPEG_LIBS $SWSCALE_LIBS $SDL_LIBS"
VIDEO_CFLAGS=" $FFMPEG_CFLAGS -DVIDEO_ENABLED"
VIDEO_LIBS=" $FFMPEG_LIBS $SWSCALE_LIBS"
if test "$SDL_found" = "yes" ; then
VIDEO_CFLAGS="$VIDEO_CFLAGS $SDL_CFLAGS -DHAVE_SDL"
VIDEO_LIBS="$VIDEO_LIBS $SDL_LIBS"
fi
if test "${ac_cv_header_X11_Xlib_h}" = "yes" ; then
VIDEO_LIBS="$VIDEO_LIBS -lX11"
......
......@@ -21,10 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MEDIASTREAM_H
#define MEDIASTREAM_H
#include "msfilter.h"
#include "msticker.h"
#include "mssndcard.h"
#include "mswebcam.h"
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/mssndcard.h"
#include "mediastreamer2/mswebcam.h"
#include "mediastreamer2/msvideo.h"
#include "ortp/ortp.h"
#include "ortp/event.h"
......@@ -119,11 +120,12 @@ struct _VideoStream
MSFilter *rtprecv;
MSFilter *rtpsend;
OrtpEvQueue *evq;
MSVideoSize sent_vsize;
bool_t adapt_bitrate;
};
typedef struct _VideoStream VideoStream;
VideoStream *video_stream_new(int locport, bool_t use_ipv6);
void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno);
int video_stream_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int rem_rtcp_port,
......@@ -133,9 +135,10 @@ void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const
/*function to call periodically to handle various events */
void video_stream_iterate(VideoStream *stream);
void video_stream_send_vfu(VideoStream *stream);
void video_stream_stop (VideoStream * stream);
void video_stream_stop(VideoStream * stream);
void video_stream_set_sent_video_size(VideoStream *stream, MSVideoSize vsize);
VideoStream * video_preview_start(MSWebCam *device);
VideoStream * video_preview_start(MSWebCam *device, MSVideoSize vsize);
void video_preview_stop(VideoStream *stream);
int video_stream_recv_only_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int payload, int jitt_comp);
......
......@@ -48,11 +48,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MS_VIDEO_SIZE_1024_W 1024
#define MS_VIDEO_SIZE_1024_H 768
#define MS_VIDEO_SIZE_800X600_W 800
#define MS_VIDEO_SIZE_800X600_H 600
#define MS_VIDEO_SIZE_MAX_W MS_VIDEO_SIZE_1024_W
#define MS_VIDEO_SIZE_MAX_H MS_VIDEO_SIZE_1024_H
typedef struct MSVideoSize{
int width,height;
int16_t width,height;
} MSVideoSize;
typedef struct MSRect{
......@@ -73,6 +76,24 @@ typedef struct MSRect{
#define MS_VIDEO_SIZE_1024 (MSVideoSize){MS_VIDEO_SIZE_1024_W, MS_VIDEO_SIZE_1024_H}
#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,
MS_YUYV,
......
......@@ -45,6 +45,7 @@ typedef struct _MSDisplayDesc{
void (*update)(struct _MSDisplay *); /*display the picture to the screen*/
void (*uninit)(struct _MSDisplay *);
bool_t (*pollevent)(struct _MSDisplay *, MSDisplayEvent *ev);
long default_window_id;
}MSDisplayDesc;
typedef struct _MSDisplay{
......@@ -76,6 +77,12 @@ extern MSDisplayDesc ms_sdl_display_desc;
extern "C"{
#endif
/*plugins can set their own display using this method:*/
void ms_display_desc_set_default(MSDisplayDesc *desc);
MSDisplayDesc * ms_display_desc_get_default(void);
void ms_display_desc_set_default_window_id(MSDisplayDesc *desc, long id);
MSVAR_DECLSPEC MSDisplayDesc ms_win_display_desc;
MSDisplay *ms_display_new(MSDisplayDesc *desc);
......@@ -85,6 +92,7 @@ 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)
#ifdef __cplusplus
}
......
......@@ -177,7 +177,10 @@ static int enc_set_br(MSFilter *f, void *arg){
EncData *d=(EncData*)f->data;
d->bitrate=*(int*)arg;
if (d->bitrate>=1024000){
if (d->bitrate>=1024000){
d->vsize=MS_VIDEO_SIZE_VGA;
d->fps=25;
}else if (d->bitrate>=512000){
d->vsize=MS_VIDEO_SIZE_VGA;
d->fps=15;
}else if (d->bitrate>=384000){
......
......@@ -63,6 +63,9 @@ int yuv_buf_init_from_mblk(YuvBuf *buf, mblk_t *m){
}else if (size==(MS_VIDEO_SIZE_1024_W*MS_VIDEO_SIZE_1024_H*3)/2){
w=MS_VIDEO_SIZE_1024_W;
h=MS_VIDEO_SIZE_1024_H;
}else if (size==(MS_VIDEO_SIZE_800X600_W*MS_VIDEO_SIZE_800X600_H*3)/2){
w=MS_VIDEO_SIZE_800X600_W;
h=MS_VIDEO_SIZE_800X600_H;
}else if (size==(160*112*3)/2){/*format used by econf*/
w=160;
h=112;
......
......@@ -153,7 +153,7 @@ static void enc_init(MSFilter *f, enum CodecID codec)
f->data=s;
ms_ffmpeg_check_init();
s->profile=0;/*always default to profile 0*/
s->comp_buf=allocb(32000,0);
s->comp_buf=NULL;
s->fps=15;
s->mtu=ms_get_payload_max_size()-2;/*-2 for the H263 payload header*/
s->maxbr=500000;
......@@ -202,7 +202,7 @@ static void prepare(EncState *s){
c->time_base.den = (int)s->fps;
c->gop_size=(int)s->fps*5; /*emit I frame every 5 seconds*/
c->pix_fmt=PIX_FMT_YUV420P;
s->comp_buf=allocb(c->bit_rate*2,0);
if (s->codec==CODEC_ID_SNOW){
c->strict_std_compliance=-2;
}
......@@ -245,7 +245,6 @@ static void prepare_mpeg4(EncState *s){
static void enc_uninit(MSFilter *f){
EncState *s=(EncState*)f->data;
if (s->comp_buf!=NULL) freemsg(s->comp_buf);
ms_free(s);
}
#if 0
......@@ -292,6 +291,10 @@ static void enc_postprocess(MSFilter *f){
avcodec_close(&s->av_context);
s->av_context.codec=NULL;
}
if (s->comp_buf!=NULL) {
freemsg(s->comp_buf);
s->comp_buf=NULL;
}
}
static void add_rfc2190_header(mblk_t **packet, AVCodecContext *context){
......
This diff is collapsed.
......@@ -143,9 +143,11 @@ static void video_steam_process_rtcp(VideoStream *stream, mblk_t *m){
}
void video_stream_iterate(VideoStream *stream){
if (stream->output!=NULL)
ms_filter_call_method_noarg(stream->output,
MS_VIDEO_OUT_HANDLE_RESIZING);
if (stream->evq){
OrtpEvent *ev=ortp_ev_queue_get(stream->evq);
if (ev!=NULL){
......@@ -170,9 +172,15 @@ VideoStream *video_stream_new(int locport, bool_t use_ipv6){
stream->evq=ortp_ev_queue_new();
stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID);
rtp_session_register_event_queue(stream->session,stream->evq);
stream->sent_vsize.width=MS_VIDEO_SIZE_CIF_W;
stream->sent_vsize.height=MS_VIDEO_SIZE_CIF_H;
return stream;
}
void video_stream_set_sent_video_size(VideoStream *stream, MSVideoSize vsize){
stream->sent_vsize=vsize;
}
void video_stream_set_relay_session_id(VideoStream *stream, const char *id){
ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id);
}
......@@ -183,16 +191,15 @@ void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno){
}
int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport,
int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam)
{
int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam){
PayloadType *pt;
RtpSession *rtps=stream->session;
MSPixFmt format;
MSVideoSize vsize;
MSVideoSize vsize,cam_vsize,disp_size;
float fps=15;
vsize.height=MS_VIDEO_SIZE_CIF_H;
vsize.width=MS_VIDEO_SIZE_CIF_W;
int tmp;
JBParameters jbp;
const int socket_buf_size=2000000;
pt=rtp_profile_get_payload(profile,payload);
if (pt==NULL){
......@@ -217,6 +224,13 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
rtp_session_set_recv_buf_size(stream->session,MAX_RTP_SIZE);
rtp_session_get_jitter_buffer_params(stream->session,&jbp);
jbp.max_packets=1000;//needed for high resolution video
rtp_session_set_jitter_buffer_params(stream->session,&jbp);
rtp_session_set_rtp_socket_recv_buffer_size(stream->session,socket_buf_size);
rtp_session_set_rtp_socket_send_buffer_size(stream->session,socket_buf_size);
/* creates two rtp filters to recv send streams (remote part) */
if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session);
......@@ -239,6 +253,8 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
}
ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
vsize=ms_video_size_min(vsize,stream->sent_vsize);
ms_filter_call_method(stream->encoder,MS_FILTER_SET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps);
ms_message("Setting vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps);
/* configure the filters */
......@@ -254,24 +270,22 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
/*set it to the pixconv */
ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);
ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&cam_vsize);
ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&cam_vsize);
}
ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
/*force the decoder to output YUV420P */
format=MS_YUV420P;
ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format);
/*ask the video display to always output CIF */
vsize.height=MS_VIDEO_SIZE_CIF_H;
vsize.width=MS_VIDEO_SIZE_CIF_W;
ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize);
disp_size.width=MS_VIDEO_SIZE_CIF_W;
disp_size.height=MS_VIDEO_SIZE_CIF_H;
tmp=1;
ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
ms_filter_call_method(stream->output,MS_VIDEO_OUT_AUTO_FIT,&tmp);
ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
if (pt->recv_fmtp!=NULL)
......@@ -331,12 +345,9 @@ void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const
VideoStream * video_preview_start(MSWebCam *device){
VideoStream * video_preview_start(MSWebCam *device, MSVideoSize vsize){
VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
MSPixFmt format;
MSVideoSize vsize;
vsize.width=MS_VIDEO_SIZE_CIF_W;
vsize.height=MS_VIDEO_SIZE_CIF_H;
/* creates the filters */
stream->source = ms_web_cam_create_reader(device);
......@@ -344,9 +355,9 @@ VideoStream * video_preview_start(MSWebCam *device){
/* configure the filters */
ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
if (format==MS_MJPEG){
stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
}else{
......
......@@ -119,8 +119,10 @@ static void parse_events(OrtpEvQueue *q){
const char *usage="mediastream --local <port> --remote <ip:port> --payload <payload type number>\n"
"[ --fmtp <fmtpline>]\n"
"[ --jitter <miliseconds>]\n";
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate);
"[ --jitter <miliseconds>]\n"
"[ --width <pixels>]\n"
"[ --height <pixels> ]\n";
static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs);
int main(int argc, char * argv[])
......@@ -131,6 +133,7 @@ int main(int argc, char * argv[])
const char *fmtp=NULL;
int jitter=50;
int bitrate=0;
MSVideoSize vs;
bool_t ec=FALSE;
/*create the rtp session */
ortp_init();
......@@ -146,6 +149,9 @@ int main(int argc, char * argv[])
rtp_profile_set_payload(&av_profile,100,&payload_type_x_snow);
rtp_profile_set_payload(&av_profile,102,&payload_type_h264);
#endif
vs.width=MS_VIDEO_SIZE_CIF_W;
vs.height=MS_VIDEO_SIZE_CIF_H;
if (argc<4) {
printf(usage);
return -1;
......@@ -173,17 +179,23 @@ int main(int argc, char * argv[])
}else if (strcmp(argv[i],"--bitrate")==0){
i++;
bitrate=atoi(argv[i]);
}else if (strcmp(argv[i],"--width")==0){
i++;
vs.width=atoi(argv[i]);
}else if (strcmp(argv[i],"--height")==0){
i++;
vs.height=atoi(argv[i]);
}else if (strcmp(argv[i],"--ec")==0){
ec=TRUE;
}
}
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate);
run_media_streams(localport,ip,remoteport,payload,fmtp,jitter,ec,bitrate,vs);
return 0;
}
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate)
void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs)
{
AudioStream *audio=NULL;
#ifdef VIDEO_ENABLED
......@@ -212,7 +224,7 @@ void run_media_streams(int localport, const char *remote_ip, int remoteport, in
#ifdef VIDEO_ENABLED
printf("Starting video stream.\n");
video=video_stream_new(localport, ms_is_ipv6(remote_ip));
video_stream_set_sent_video_size(video,vs);
video_stream_start(video,profile,
remote_ip,
remoteport,remoteport+1,
......
......@@ -24,7 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
int main(int argc, char *argv[]){
VideoStream *vs;
MSWebCam *cam;
MSVideoSize vsize;
int i;
vsize.width=MS_VIDEO_SIZE_CIF_W;
vsize.height=MS_VIDEO_SIZE_CIF_H;
ortp_init();
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
ms_init();
......@@ -32,7 +37,7 @@ int main(int argc, char *argv[]){
/* this is to test the sequence start/stop */
for(i=0;i<1;++i){
int n;
vs=video_preview_start(cam);
vs=video_preview_start(cam,vsize);
for(n=0;n<1000;++n){
#ifdef WIN32
......
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