📄 sdl_bgrab.c
字号:
unsigned long adjusted_frequency; DBMESSAGE("Setting tuner to region %i index %i\n", region, index); // frequency=bgrab_get_frequency (region, index); if (frequency>0) { adjusted_frequency=frequency*16/1000; if (ioctl (bgrab->bgrab_dev, VIDIOCSFREQ, &adjusted_frequency) == -1) { DBERROR("ioctl (VIDIOCSFREQ)"); return 0; } } return(1); }/* Self running thread that constantly grabs images */int grab_images_thread (void *data){ tSDL_bgrab *bgrab=(tSDL_bgrab *)data; int in_loop; DBMESSAGE ("Starting grabbing loop.\n"); /* Loop ... grabbing images */ in_loop=1; while (in_loop) { /* Lock buffers and state */ SDL_LockMutex(bgrab->buffer_mutex); /* Advance grab-frame number */ bgrab->current_grab_number=((bgrab->current_grab_number + 1) % 2); /* Unlock buffers and state */ SDL_UnlockMutex(bgrab->buffer_mutex); /* Wait for next image in the sequence to complete grabbing */ if (ioctl (bgrab->bgrab_dev, VIDIOCSYNC, &bgrab->vid_mmap[bgrab->current_grab_number]) == -1) { DBERROR("VIDIOCSYNC"); return(0); } /* Issue new grab command for this buffer */ if (ioctl (bgrab->bgrab_dev, VIDIOCMCAPTURE, &bgrab->vid_mmap[bgrab->current_grab_number]) == -1) { DBERROR("VIDIOCMCAPTURE"); return(0); } /* Lock buffers and state */ SDL_LockMutex(bgrab->buffer_mutex); /* Announce that a new frame is available */ bgrab->have_new_frame=1; /* Get loop state */ in_loop=bgrab->grabbing_active; /* Unlock buffers and state */ SDL_UnlockMutex(bgrab->buffer_mutex); /* Signal potentially waiting main thread */ SDL_CondSignal(bgrab->buffer_cond); } DBMESSAGE ("Done grabbing loop.\n"); return 1; }/* Initialize grabber and start grabbing-thread */int bgrabStart (tSDL_bgrab *bgrab, int width, int height, int bgra){ int i; int format, depth; /* Store variables in structure */ bgrab->width=width; bgrab->height=height; /* Always grab at 32bit RGB image */ bgrab->format=VIDEO_PALETTE_RGB32; depth=4; /* Retrieve buffer size and offsets */ if (ioctl (bgrab->bgrab_dev, VIDIOCGMBUF, &bgrab->vid_mbuf) == -1) { DBERROR("ioctl (VIDIOCGMBUF)"); return(0); } DBMESSAGE("Grabber buffer and offsets retrieved.\n"); /* Map grabber memory into user space */ bgrab->bgrab_map = mmap (0, bgrab->vid_mbuf.size, PROT_READ|PROT_WRITE,MAP_SHARED,bgrab->bgrab_dev,0); if ((unsigned char *)-1 == (unsigned char *)bgrab->bgrab_map) { DBERROR("mmap()"); return(0); } DBMESSAGE("Grabber memory mapped.\n"); /* Generate mmap records */ for (i=0; i<2; i++) { bgrab->vid_mmap[i].format = bgrab->format; bgrab->vid_mmap[i].frame = i; bgrab->vid_mmap[i].width = width; bgrab->vid_mmap[i].height = height; } #if SDL_BYTEORDER == SDL_BIG_ENDIAN DBMESSAGE ("Client is: big-endian\n"); if (bgra) { bgrab->rmask = 0x0000ff00; bgrab->gmask = 0x00ff0000; bgrab->bmask = 0xff000000; bgrab->amask = 0x000000ff; } else { bgrab->rmask = 0xff000000; bgrab->gmask = 0x00ff0000; bgrab->bmask = 0x0000ff00; bgrab->amask = 0x000000ff; } #else DBMESSAGE ("Client is: little-endian\n"); if (bgra) { bgrab->rmask = 0x00ff0000; bgrab->gmask = 0x0000ff00; bgrab->bmask = 0x000000ff; bgrab->amask = 0xff000000; } else { bgrab->rmask = 0x000000ff; bgrab->gmask = 0x0000ff00; bgrab->bmask = 0x00ff0000; bgrab->amask = 0xff000000; } #endif /* Create framebuffer */ bgrab->framebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,32, bgrab->rmask,bgrab->gmask,bgrab->bmask,0); SDL_SetAlpha(bgrab->framebuffer,0,0); if (bgrab->framebuffer==NULL) { DBERROR ("Could not create main framebuffer.\n"); return 0; } DBMESSAGE ("Main Framebuffer created.\n"); /* Create deframebuffer for deinterlacing */ bgrab->deframebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,32, bgrab->rmask,bgrab->gmask,bgrab->bmask,0); SDL_SetAlpha(bgrab->deframebuffer,0,0); if (bgrab->deframebuffer==NULL) { DBERROR ("Could not create second framebuffer.\n"); return 0; } DBMESSAGE ("Second Framebuffer created.\n"); /* Calculate framebuffer size */ bgrab->image_pixels=width*height; bgrab->image_size=bgrab->image_pixels*depth; /* Create backbuffer */ if ((bgrab->backbuffer=(unsigned char *)malloc(bgrab->image_size))==NULL) { DBERROR ("Out of memory.\n"); return 0; } /* Reset grab counter variables */ bgrab->current_grab_number=0; bgrab->totalframecount=0; bgrab->have_new_frame=0; /* Initialize mutex */ bgrab->buffer_mutex = SDL_CreateMutex(); if (bgrab->buffer_mutex==NULL) { DBERROR("Could not create mutex.\n"); return 0; } /* Initialize conditional */ bgrab->buffer_cond = SDL_CreateCond(); if (bgrab->buffer_cond==NULL) { DBERROR("Could not create conditional.\n"); return 0; } /* Initiate capture for frames */ for (i=0; i<2; i++) { /* Sync old images in the sequence to complete grabbing */ ioctl (bgrab->bgrab_dev, VIDIOCSYNC, &bgrab->vid_mmap[i]); /* Start capture */ if (ioctl (bgrab->bgrab_dev, VIDIOCMCAPTURE, &bgrab->vid_mmap[i]) == -1) { DBERROR ("VIDIOCMCAPTURE"); return 0; } } DBMESSAGE("Capture started.\n"); /* Set thread loop flag */ bgrab->grabbing_active=1; /* Start grabbing thread */ bgrab->grab_thread = SDL_CreateThread(grab_images_thread,(void *)bgrab); if (bgrab->grab_thread==NULL) { DBERROR("Could not create thread.\n"); return 0; } return 1;}/* Stop grabbing thread */int bgrabStop(tSDL_bgrab *bgrab){ /* Set flag for thread to finish */ bgrab->grabbing_active=0; /* Wait for grabbing thread to exit */ SDL_WaitThread(bgrab->grab_thread,NULL); /* Free image buffers */ if (bgrab->framebuffer) { free(bgrab->framebuffer); bgrab->framebuffer=NULL; } if (bgrab->deframebuffer) { free(bgrab->deframebuffer); bgrab->deframebuffer=NULL; } if (bgrab->backbuffer) { free(bgrab->backbuffer); bgrab->backbuffer=NULL; } /* Unmap memory */ if (munmap (bgrab->bgrab_map, bgrab->vid_mbuf.size) == -1) { DBERROR("munmap()"); return(0); } return(1);}/* Transfer last grabbed image into external buffer, lock to be processed */ int bgrabBlitFramebuffer(tSDL_bgrab *bgrab, SDL_Surface *target, int deinterlace){ /* Check if we are grabbing */ if (bgrab->grabbing_active) { /* Increase counter */ bgrab->totalframecount++; /* Lock buffers and state */ SDL_LockMutex(bgrab->buffer_mutex); /* Check if a new frame is available */ if (!bgrab->have_new_frame) { /* Wait for signal - unlocking mutex in the process */ SDL_CondWait(bgrab->buffer_cond,bgrab->buffer_mutex); } /* Copy framebuffer pixel data from other-than-grab framebuffer into current image */ memcpy (bgrab->framebuffer->pixels,&bgrab->bgrab_map[bgrab->vid_mbuf.offsets[(bgrab->current_grab_number+1) % 2]],bgrab->image_size); /* Mark frame as used */ bgrab->have_new_frame=0; /* Unlock buffers and state */ SDL_UnlockMutex(bgrab->buffer_mutex); if (deinterlace) { /* Deinterlace */ switch (deinterlace) { case 1: bgrab_deinterlace(bgrab, bgrab->framebuffer, bgrab->deframebuffer); break; case 2: bgrab_deinterlace_smart(bgrab, bgrab->framebuffer, bgrab->deframebuffer); break; case 3: bgrab_deinterlace_smooth(bgrab, bgrab->framebuffer, bgrab->deframebuffer); break; default: bgrab_deinterlace(bgrab, bgrab->framebuffer, bgrab->deframebuffer); break; } /* Blit this buffer to target */ SDL_BlitSurface(bgrab->deframebuffer, NULL, target, NULL); } else { /* Blit this buffer to target */ SDL_BlitSurface(bgrab->framebuffer, NULL, target, NULL); } /* FPS calculation */ bgrab_calc_fps(bgrab); } else { /* No grabbing */ return 0; } /* Return success */ return 1;}int bgrabOpen(tSDL_bgrab *bgrab, char *device){ /* Open the bgrab4linux device */ bgrab->bgrab_dev = open (device, O_RDWR); if (bgrab->bgrab_dev == -1) { DBERROR("open()"); return (0); } /* Reset variables */ bgrab->grabbing_active=0; bgrab->width=-1; bgrab->height=-1; bgrab->format=-1; bgrab->input=-1; bgrab->image_size=-1; bgrab->image_pixels=-1; bgrab->fps_update_interval=-1; return(1);}int bgrabClose(tSDL_bgrab *bgrab){ /* Close bgrab4linux device */ close(bgrab->bgrab_dev); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -