<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    一江春水向東流

    做一個有思想的人,期待與每一位熱愛思考的人交流,您的關注是對我最大的支持。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      44 隨筆 :: 139 文章 :: 81 評論 :: 0 Trackbacks

    **//* $Id: directshow.c,v 1.22 2005/11/12 14:12:39 fuhuizhong Exp $ */

    #ifndef lint
    static char vcid[] = "$Id: directshow.c,v 1.22 2005/11/12 14:12:39 fuhuizhong Exp $";
    #endif /* lint */


    /**//*
    * 作者:傅惠忠
    * /modified by xiaoshao_0_0
    */
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <stdlib.h>
    #include <linux/types.h>
    #include <linux/videodev.h>
    #include "jpeglib.h"
    #include <setjmp.h>
    #include <SDL/SDL.h>
    #include <string.h>
    #include <signal.h>
    #include <errno.h>
    #define USB_VIDEO "/dev/video1"

    SDL_Surface *screen,*img;
    int cam_fd;
    int width,height;
    const int bpp = 24;
    struct video_mmap cam_mm;
    struct video_capability cam_cap;
    struct video_picture cam_pic;
    struct video_mbuf cam_mbuf;
    struct video_window win;
    char *cam_data = NULL;
    int nframe;

    void errexit(char *msg)
    ...{
    fputs(msg,stderr);
    exit(-1);
    }

    void e_sig(int signum)
    ...{
    printf(" ERROR:signal %d ",signum);
    exit(-1);
    }

    void setup_sighandler()
    ...{
    signal(SIGTERM,&e_sig);
    signal(SIGINT,&e_sig);
    signal(SIGSEGV,&e_sig);
    signal(SIGILL,&e_sig);
    signal(SIGFPE,&e_sig);
    }

    void init_video(int w,int h,int bpp); /**//* bpp == bits per pixel, 暫時無效*/
    void init_screen(int w,int h,int bpp); /**//* like above*/
    void read_video(int ,int);
    void show_img(char *pixels);
    void window_loop();
    void exchange_r_b( char * f,long size);
    void compress_to_jpeg_file( FILE *outfile, char * image_buffer,int w,int h, int quality);
    void save_snapshot();

    void free_dev()
    ...{
    printf("free device ");
    close(cam_fd);
    }

    int main(int argc,char *argv[])
    ...{
    int i;
    float scale = 1.0;
    if( argc == 2 ) ...{
    scale = atof(argv[1]);
    if(scale<0.3 || scale>1.0)
    errexit("scale out of range (0.3 ~ 1.0) ");
    }
    width = (int)(640*scale);
    height = (int)(480*scale);

    atexit( &free_dev );
    init_video(width,height,bpp);
    init_screen(width,height,bpp);
    setup_sighandler();

    window_loop();

    getchar();
    munmap(cam_data,cam_mbuf.size);

    exit(0);
    }

    void config_vid_pic()
    ...{
    char *hp = getenv("HOME");
    char cfpath[100];
    FILE *cf;
    int ret;
    sprintf( cfpath,"%s/.dshow.conf",hp );
    cf = fopen(cfpath,"r");
    /**//* The struct video_picture consists of the following fields

    brightness Picture brightness
    hue Picture hue (colour only)
    colour Picture colour (colour only)
    contrast Picture contrast
    whiteness The whiteness (greyscale only)
    depth The capture depth (may need to match the frame buffer depth)
    palette Reports the palette that should be used for this image

    The following palettes are defined

    VIDEO_PALETTE_GREY Linear intensity grey scale (255 is brightest).
    VIDEO_PALETTE_HI240 The BT848 8bit colour cube.
    VIDEO_PALETTE_RGB565 RGB565 packed into 16 bit words.
    VIDEO_PALETTE_RGB555 RGV555 packed into 16 bit words, top bit undefined.
    VIDEO_PALETTE_RGB24 RGB888 packed into 24bit words.
    VIDEO_PALETTE_RGB32 RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.
    VIDEO_PALETTE_YUV422 Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V
    VIDEO_PALETTE_YUYV Describe me
    VIDEO_PALETTE_UYVY Describe me
    VIDEO_PALETTE_YUV420 YUV420 capture
    VIDEO_PALETTE_YUV411 YUV411 capture
    VIDEO_PALETTE_RAW RAW capture (BT848)
    VIDEO_PALETTE_YUV422P YUV 4:2:2 Planar
    VIDEO_PALETTE_YUV411P YUV 4:1:1 Planar
    */
    if (ioctl(cam_fd, VIDIOCGPICT, &cam_pic) < 0) ...{
    errexit("ERROR:VIDIOCGPICT ");
    }
    //cam_pic.palette =VIDEO_PALETTE_RAW;
    cam_pic.palette =VIDEO_PALETTE_RGB24;

    if( cf==NULL ) ...{
    cam_pic.brightness = 44464;
    cam_pic.hue = 36000;
    cam_pic.colour = 0;
    cam_pic.contrast = 43312;
    cam_pic.whiteness = 13312;
    cam_pic.depth = 24;
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }
    return;
    }

    fscanf(cf,"%d",&cam_pic.brightness);
    fscanf(cf,"%d",&cam_pic.hue);
    fscanf(cf,"%d",&cam_pic.colour);
    fscanf(cf,"%d",&cam_pic.contrast);
    fscanf(cf,"%d",&cam_pic.whiteness);
    fclose( cf );
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }

    }

    void init_video(int w,int h,int bpp) /**//* bpp == bytes per pixel*/
    ...{
    int ret;

    cam_fd = open( USB_VIDEO, O_RDWR );
    if( cam_fd<0 )
    errexit("Can't open video device ");

    ret = ioctl( cam_fd,VIDIOCGCAP,&cam_cap );
    /**//* 攝像頭的基本信息
    struct video_capability cam_cap;
    name[32] Canonical name for this interface
    type Type of interface
    channels Number of radio/tv channels if appropriate
    audios Number of audio devices if appropriate
    maxwidth Maximum capture width in pixels
    maxheight Maximum capture height in pixels
    minwidth Minimum capture width in pixels
    minheight Minimum capture height in pixels
    */
    if( ret<0 ) ...{
    errexit("Can't get device information: VIDIOCGCAP ");
    }

    print_device_info();

    /**//* The struct video_window contains the following fields.

    x The X co-ordinate specified in X windows format.
    y The Y co-ordinate specified in X windows format.
    width The width of the image capture.
    height The height of the image capture.
    chromakey A host order RGB32 value for the chroma key.
    flags Additional capture flags.
    clips A list of clipping rectangles. (Set only)
    clipcount The number of clipping rectangles. (Set only)
    */
    if( ioctl(cam_fd,VIDIOCGWIN,&win)<0 ) ...{
    errexit("ERROR:VIDIOCGWIN ");
    }
    win.x = 0;
    win.y = 0;
    win.width=width;
    win.height=height;
    if (ioctl(cam_fd, VIDIOCSWIN, &win) < 0) ...{
    errexit("ERROR:VIDIOCSWIN ");
    }

    config_vid_pic();

    ret = ioctl(cam_fd,VIDIOCGMBUF,&cam_mbuf);
    /**//*
    struct video_mbuf
    {
    int size; Total memory to map
    int frames; Frames
    int offsets[VIDEO_MAX_FRAME];
    };
    */

    /**//*struct video_buffer.
    視頻緩存的信息讀取結構,設定也是一樣的結構。但是一般是X自己設定,你只要讀取就好了。
    void *base Base physical address of the buffer
    int height Height of the frame buffer
    int width Width of the frame buffer
    int depth Depth of the frame buffer
    int bytesperline Number of bytes of memory between the start of two adjacent lines*/

    if( ret<0 ) ...{
    errexit("ERROR:VIDIOCGMBUF,Can't get video_mbuf ");
    }
    printf("Frames:%d ",cam_mbuf.frames);
    nframe = cam_mbuf.frames;
    cam_data = (char*)mmap(0, cam_mbuf.size, PROT_READ|PROT_WRITE,MAP_SHARED,cam_fd,0);
    if( cam_data == MAP_FAILED ) ...{
    errexit("ERROR:mmap ");
    }
    printf("Buffer size:%d Offset:%d ",cam_mbuf.size,cam_mbuf.offsets[0]);
    }

    void print_device_info()
    ...{
    int type=cam_cap.type;
    int i;
    char type_info[14][100]=
    ...{
    "VID_TYPE_CAPTURE Can capture to memory",
    "VID_TYPE_TUNER Has a tuner of some form",
    "VID_TYPE_TELETEXT Has teletext capability",
    "VID_TYPE_OVERLAY Can overlay its image onto the frame buffer",
    "VID_TYPE_CHROMAKEY Overlay is Chromakeyed",
    "VID_TYPE_CLIPPING Overlay clipping is supported",
    "VID_TYPE_FRAMERAM Overlay overwrites frame buffer memory",
    "VID_TYPE_SCALES The hardware supports image scaling",
    "VID_TYPE_MONOCHROME Image capture is grey scale only",
    "VID_TYPE_SUBCAPTURE Capture can be of only part of the image",
    "VID_TYPE_MPEG_DECODER Can decode MPEG streams",
    "VID_TYPE_MPEG_ENCODER Can encode MPEG streams",
    "VID_TYPE_MJPEG_DECODER Can decode MJPEG streams",
    "VID_TYPE_MJPEG_ENCODER Can encode MJPEG streams",
    };
    printf("Device name:%s Width:%d ~ %d Height:%d ~ %d ",
    cam_cap.name,
    cam_cap.maxwidth, cam_cap.minwidth,
    cam_cap.maxheight, cam_cap.minheight);
    for(i=0;i<14;i++)
    ...{
    if(type&(2^i))
    ...{ printf(type_info[i]);
    printf(" ");
    }
    else
    ...{
    printf("==not supported==%s",type_info[i]);
    printf(" ");
    }
    }
    }

    void init_screen(int w,int h,int bpp) // like above
    ...{
    if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) ...{
    fprintf(stderr, "無法初始化SDL: %s ", SDL_GetError());
    exit(1);
    }
    img = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, bpp, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
    screen = SDL_SetVideoMode(width, height, bpp, SDL_SWSURFACE);
    if ( screen == NULL ) ...{
    fprintf(stderr, "無法設置視頻模式:%s ", SDL_GetError());
    exit(1);
    }
    atexit(SDL_Quit);
    }

    void read_video(int captrue_frame,int sync_frame)
    ...{
    int ret;
    //int frame=0; /*這個似乎比較關鍵*/
    //這個地方原作者弄錯了。
    cam_mm.frame=captrue_frame;
    /**//* struct video_mmap
    {
    unsigned int frame; Frame (0 - n) for double buffer
    int height,width;
    unsigned int format; should be VIDEO_PALETTE_*
    };
    */
    ret = ioctl(cam_fd,VIDIOCMCAPTURE,&cam_mm);
    if( ret<0 ) ...{
    errexit("ERROR: VIDIOCMCAPTURE ");
    }
    //cam_mm.frame=sync_frame;
    ret = ioctl(cam_fd,VIDIOCSYNC,&sync_frame);
    if( ret<0 ) ...{
    errexit("ERROR: VIDIOCSYNC ");
    }
    }

    void show_img(char *pixels)
    ...{
    int row_stride = width*3;
    char *pbuf = (char*)img->pixels;
    int row;

    /**//* for(row=0; row<height; row++) {
    memcpy(pbuf, pixels, row_stride);
    pbuf += img->pitch;
    pixels += row_stride;
    }*/
    memcpy(pbuf,pixels,row_stride*height);
    SDL_BlitSurface(img, NULL, screen, NULL);
    SDL_UpdateRect(screen,0,0,width,height);
    }

    void window_loop()
    ...{
    int ret;
    SDL_Event event;
    int keystat = 0;
    Uint32 ticks = 0;
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,1000);
    /**///////////////
    cam_mm.height = height;
    cam_mm.width = width;
    cam_mm.frame=0;
    cam_mm.format=VIDEO_PALETTE_RGB24;
    ret = ioctl(cam_fd,VIDIOCMCAPTURE,&cam_mm);

    if( ret<0 ) ...{
    errexit("ERROR: VIDIOCMCAPTURE ");
    }
    //Here just start caputer frame0,it not in the loop.
    /**///////////////
    while ( 1 ) ...{
    SDL_PollEvent(&event);
    switch (event.type) ...{
    case SDL_QUIT:
    exit(0);
    case SDL_KEYDOWN:
    if( event.key.keysym.sym == SDLK_F8 && keystat == 0 )
    save_snapshot();
    if( event.key.keysym.sym == SDLK_F9 && keystat == 0 )
    config_vid_pic();
    if( event.key.keysym.sym == SDLK_UP && keystat == 0 )
    increase_brightness();
    if( event.key.keysym.sym == SDLK_DOWN && keystat == 0 )
    decrease_birghtness();
    if( event.key.keysym.sym == SDLK_LEFT && keystat== 0 )
    increase_contrast();
    if( event.key.keysym.sym == SDLK_RIGHT && keystat==0 )
    decrease_contrast();
    keystat = 1;
    break;
    case SDL_KEYUP:
    keystat = 0;
    break;
    default:
    break;
    }
    if( (SDL_GetTicks()-ticks)<30)
    continue;
    read_video(1,0);//captrue=1,sync=0
    show_img( cam_data+cam_mbuf.offsets[0]);
    read_video(0,1);//captrue=0,sync=1
    show_img( cam_data+cam_mbuf.offsets[1]);
    ticks = SDL_GetTicks();
    }
    }
    void increase_brightness()
    ...{
    int ret=0;
    cam_pic.brightness+=1000;
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }
    }
    void decrease_birghtness()
    ...{
    int ret=0;
    cam_pic.brightness-=1000;
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }
    }
    void increase_contrast()
    ...{
    int ret=0;
    cam_pic.contrast+=1000;
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }
    }
    void decrease_contrast()
    ...{
    int ret=0;
    cam_pic.contrast-=1000;
    ret = ioctl( cam_fd, VIDIOCSPICT,&cam_pic ); /**//*設置攝像頭緩沖中voideo_picture信息*/
    if( ret<0 ) ...{
    close(cam_fd);
    errexit("ERROR: VIDIOCSPICT,Can't set video_picture format ");
    }
    }

    void compress_to_jpeg_file( FILE *outfile, char * image_buffer,int w,int h, int quality)
    ...{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1]; /**//* pointer to JSAMPLE row[s] */
    int row_stride; /**//* physical row width in image buffer */
    int image_width;
    int image_height;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, outfile);

    image_width = w;
    image_height = h;
    cinfo.image_width = image_width; /**//* image width and height, in pixels */
    cinfo.image_height = image_height;
    cinfo.input_components = 3; /**//* # of color components per pixel */
    cinfo.in_color_space = JCS_RGB; /**//* colorspace of input image */
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE /**//* limit to baseline-JPEG values */);
    jpeg_start_compress(&cinfo, TRUE);
    row_stride = image_width * 3; /**//* JSAMPLEs per row in image_buffer */
    while (cinfo.next_scanline < cinfo.image_height) ...{
    row_pointer[0] = (JSAMPROW)& image_buffer[cinfo.next_scanline * row_stride];
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);

    jpeg_destroy_compress(&cinfo);

    /**//* And we're done! */
    }
    void exchange_r_b( char * f,long size)
    ...{
    char r,b;
    long i;
    for( i = 0; i < size ; i++)
    ...{
    r = *f;
    b = *( f + 2);
    *f = b;
    *(f + 2) = r;
    f = f +3;
    }

    }

    void save_snapshot()
    ...{
    char *basepath = getenv("HOME");
    char *basename = "/snapsot";
    char *extname = ".jpg";
    char filename[100];
    int i = 0;
    FILE *fo;
    for(;;) ...{
    sprintf(filename,"%s%s%d%s",basepath,basename,i,extname);
    fo = fopen(filename,"rb");
    if( fo==NULL )
    break;
    else
    fclose(fo);
    i += 1;
    }
    printf("snapshot:%s ",filename);
    fo = fopen(filename,"wb");
    exchange_r_b( cam_data, width*height );
    compress_to_jpeg_file( fo, cam_data, width, height, 90 );
    fclose(fo);
    }

    一個比較清淅的攝像頭參數設置

    //loadVariablesNum("schlist.tx", 0);
    //fscommand("fullscrean", true);
    var my_cam = Camera.get();
    //LAN
    //Lower image quality, higher motion quality my_cam.setQuality(400000,0)
    //Higher image quality, lower motion qualitymy_cam.setQuality(0,100)
    //// 確保最低品質為 100,無論采用多大的帶寬
    my_cam.setQuality(0, 100); //
    my_cam.setKeyFrameInterval(15);
    my_cam.setLoopback(true);
    //my_cam.setMotionLevel(35, 1000);
    my_cam.setMode(320, 240, 25, true);


    // 捕獲攝像頭
    myVideo1.attachVideo(my_cam);
    myVideo1.smoothing = true;
    myVideo1._alpha = 100;
    myVideo1._rotation = 360;
    // 在舞臺上的 myVideo1 對象的邊界內顯示視頻流
    my_cam.onStatus = function(infoMsg) {
    ?if (infoMsg.code == 'Camera.Muted') {
    ??// 拒絕
    ??trace('User denies access to the camera');
    ?} else if (infoMsg.code == 'Camera.Unmuted') {
    ??// 接受
    ??trace('User allows access to the camera');
    ?}

    };
    //System.showSettings(3);
    // 顯示指定的 Flash Player"設置"面板
    stop();?

    posted on 2007-05-08 20:28 allic 閱讀(2617) 評論(0)  編輯  收藏 所屬分類: C/C++
    主站蜘蛛池模板: 毛片免费观看视频| 精品特级一级毛片免费观看| 九九热久久免费视频| 在线观看91精品国产不卡免费| 中文文字幕文字幕亚洲色| 成人免费观看一区二区| 亚洲AV一二三区成人影片| 成人AV免费网址在线观看| 国产精品亚洲午夜一区二区三区| 又黄又爽又成人免费视频| 国产成人精品亚洲日本在线| 成年女人18级毛片毛片免费 | 国产禁女女网站免费看| 亚洲精品乱码久久久久久蜜桃图片| 成人奭片免费观看| 亚洲精品无播放器在线播放| 国产免费看插插插视频| 色哟哟国产精品免费观看| 国产亚洲综合网曝门系列| 久久青草免费91线频观看站街| 亚洲精品福利网泷泽萝拉| 免费看韩国黄a片在线观看| 亚洲日韩精品无码专区| 无码专区一va亚洲v专区在线| 国产免费久久久久久无码| 国产亚洲一区二区手机在线观看| 中文字幕亚洲免费无线观看日本 | 国产精品日本亚洲777| AV在线亚洲男人的天堂| 久久国产精品2020免费m3u8 | 亚洲美女视频免费| 国内一级一级毛片a免费| 一区二区三区免费看| 91天堂素人精品系列全集亚洲| 成年人免费视频观看| 一级做a爱过程免费视| 亚洲综合一区二区精品导航| 四虎在线视频免费观看| 两个人看的www免费视频中文| 亚洲日本国产乱码va在线观看| 四虎永久免费网站免费观看|