⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread_display.c

📁 Coriander is a GUI for controlling a Digital Camera (in the sense of the IIDC specs issued by the 1
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2000-2004 Damien Douxchamps  <ddouxchamps@users.sf.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "coriander.h"gintDisplayStartThread(camera_t* cam){  chain_t *display_service=NULL;  displaythread_info_t *info=NULL;  display_service=GetService(camera,SERVICE_DISPLAY);  if (display_service==NULL) {// if no display service running...    display_service=(chain_t*)malloc(sizeof(chain_t));    display_service->current_buffer=NULL;    display_service->next_buffer=NULL;    display_service->data=(void*)malloc(sizeof(displaythread_info_t));    info=(displaythread_info_t*)display_service->data;    pthread_mutex_init(&display_service->mutex_struct, NULL);    pthread_mutex_init(&display_service->mutex_data, NULL);    pthread_mutex_init(&info->mutex_cancel, NULL);        pthread_mutex_lock(&info->mutex_cancel);    info->cancel_req=0;    pthread_mutex_unlock(&info->mutex_cancel);        pthread_mutex_lock(&display_service->mutex_data);    info->period=cam->prefs.display_period;    CommonChainSetup(cam, display_service,SERVICE_DISPLAY);        pthread_mutex_lock(&display_service->mutex_struct);    InsertChain(cam, display_service);        if (pthread_create(&display_service->thread, NULL, DisplayThread, (void*)display_service)) {      RemoveChain(cam, display_service);      pthread_mutex_unlock(&display_service->mutex_struct);      pthread_mutex_unlock(&display_service->mutex_data);      FreeChain(display_service);      return(-1);    }    pthread_mutex_unlock(&display_service->mutex_struct);    pthread_mutex_unlock(&display_service->mutex_data);      }  return (1);}void*DisplayCleanupThread(void* arg){  chain_t* display_service;  displaythread_info_t *info;  display_service=(chain_t*)arg;  info=(displaythread_info_t*)display_service->data;  pthread_mutex_unlock(&display_service->mutex_data);  return(NULL);}void*DisplayThread(void* arg){  chain_t* display_service=NULL;  displaythread_info_t *info=NULL;  long int skip_counter;  float tmp;  // we should only use mutex_data in this function  display_service=(chain_t*)arg;  pthread_mutex_lock(&display_service->mutex_data);  info=(displaythread_info_t*)display_service->data;  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);  pthread_mutex_unlock(&display_service->mutex_data);  skip_counter=0;  // time inits:  display_service->prev_time = times(&display_service->tms_buf);  display_service->fps_frames=0;  display_service->processed_frames=0;  while (1) {    pthread_mutex_lock(&info->mutex_cancel);        if (info->cancel_req>0) {      break;    }    else {      pthread_mutex_unlock(&info->mutex_cancel);      pthread_mutex_lock(&display_service->mutex_data);      if(RollBuffers(display_service)) { // have buffers been rolled?#ifdef HAVE_SDLLIB	// check params	DisplayThreadCheckParams(display_service);#endif	if (display_service->current_buffer->width!=-1) {	  if (skip_counter>=(info->period-1)) {	    skip_counter=0;#ifdef HAVE_SDLLIB	    if (info->sdloverlay!=NULL) {	      if (SDL_LockYUVOverlay(info->sdloverlay) == 0) {		convert_to_yuv_for_SDL(display_service->current_buffer, info->sdloverlay, preferences.overlay_byte_order);				// informative overlays		SDLDisplayArea(display_service);		SDLDisplayPattern(display_service);				SDL_UnlockYUVOverlay(info->sdloverlay);		SDL_DisplayYUVOverlay(info->sdloverlay, &info->sdlvideorect);				info->redraw_prev_time=times(&info->redraw_tms_buf);	      }	    }#endif	    display_service->fps_frames++;	    display_service->processed_frames++;	  }	  else { //	    if (display_service->camera->prefs.display_redraw==DISPLAY_REDRAW_ON) {	      ConditionalTimeoutRedraw(display_service);	    }	    skip_counter++;	  }	  // FPS display:	  display_service->current_time=times(&display_service->tms_buf);	  tmp=(float)(display_service->current_time-display_service->prev_time)/sysconf(_SC_CLK_TCK);	  if (tmp==0)	    display_service->fps=fabs(0.0);	  else	    display_service->fps=fabs((float)display_service->fps_frames/tmp);	}	pthread_mutex_unlock(&display_service->mutex_data);      }      else { //	if (display_service->camera->prefs.display_redraw==DISPLAY_REDRAW_ON) {	  ConditionalTimeoutRedraw(display_service);	}	pthread_mutex_unlock(&display_service->mutex_data);      }    }    usleep(0);  }    pthread_mutex_unlock(&info->mutex_cancel);  return ((void*)1);}// the goal of the following function is to redraw the SDL display twice a second so that the image follows the screen// during window movement or if another window comes momentarily on top of the display while no images are coming. voidConditionalTimeoutRedraw(chain_t* service){  displaythread_info_t *info=NULL;  float interval;  info=(displaythread_info_t*)service->data;  if (service->current_buffer->width!=-1) {    info->redraw_current_time=times(&info->redraw_tms_buf);    interval=fabs((float)(info->redraw_current_time-info->redraw_prev_time)/sysconf(_SC_CLK_TCK));    if (interval>(1.0/service->camera->prefs.display_redraw_rate)) { // redraw e.g. 4 times per second#ifdef HAVE_SDLLIB      if (SDL_LockYUVOverlay(info->sdloverlay) == 0) {	//MainStatus("Conditional display redraw");	convert_to_yuv_for_SDL(service->current_buffer, info->sdloverlay, preferences.overlay_byte_order);	SDLDisplayArea(service);	SDL_UnlockYUVOverlay(info->sdloverlay);	SDL_DisplayYUVOverlay(info->sdloverlay, &info->sdlvideorect);      }#endif      info->redraw_prev_time=times(&info->redraw_tms_buf);    }  }}gintDisplayStopThread(camera_t* cam){  displaythread_info_t *info;  chain_t *display_service;  display_service=GetService(cam,SERVICE_DISPLAY);    if (display_service!=NULL) { // if display service running...     info=(displaythread_info_t*)display_service->data;        // send request for cancellation:    pthread_mutex_lock(&info->mutex_cancel);    info->cancel_req=1;    pthread_mutex_unlock(&info->mutex_cancel);        // when cancellation occured, join:    pthread_join(display_service->thread, NULL);        pthread_mutex_lock(&display_service->mutex_data);    pthread_mutex_lock(&display_service->mutex_struct);    RemoveChain(cam,display_service);#ifdef HAVE_SDLLIB    SDLQuit(display_service);#endif        pthread_mutex_unlock(&display_service->mutex_struct);    pthread_mutex_unlock(&display_service->mutex_data);    FreeChain(display_service);  }  return (1);}#ifdef HAVE_SDLLIBintSDLInit(chain_t *display_service){  displaythread_info_t *info;  const SDL_VideoInfo *sdl_videoinfo;  SDL_Rect** modes;  info=(displaythread_info_t*)display_service->data;  //SDL_Surface *icon_surface;  info->sdlbpp=16;  info->sdlflags=SDL_ANYFORMAT | SDL_RESIZABLE;  // Initialize the SDL library (video subsystem)  if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) == -1) {    fprintf(stderr,"Couldn't initialize SDL video subsystem\n");    return(0);  }    sdl_videoinfo = SDL_GetVideoInfo();    if ((xvinfo.max_width!=-1)&&(xvinfo.max_height!=-1)) {    // if the XV area is too small, we use software accelleration    if ((xvinfo.max_width<display_service->current_buffer->width)||	(xvinfo.max_height<display_service->current_buffer->height)) {      //fprintf(stderr,"Using SW surface\n");      info->sdlflags|= SDL_SWSURFACE;      info->sdlflags&= ~SDL_HWSURFACE;      info->sdlflags&= ~SDL_HWACCEL;    }    else {      //fprintf(stderr,"Using HW surface\n");      info->sdlflags|= SDL_HWSURFACE;      info->sdlflags|= SDL_HWACCEL;      info->sdlflags&= ~SDL_SWSURFACE;    }  }  else {    // try HW accel and pray...    info->sdlflags|= SDL_SWSURFACE;    info->sdlflags&= ~SDL_HWSURFACE;    info->sdlflags&= ~SDL_HWACCEL;  }  modes=SDL_ListModes(NULL,info->sdlflags);  if (modes!=(SDL_Rect**)-1) {    // not all resolutions are OK for this video card. For safety we switch to software accel    fprintf(stderr,"No SDL mode available with hardware accel. Trying without HWSURFACE\n");    info->sdlflags&= ~SDL_HWSURFACE;    info->sdlflags&= ~SDL_HWACCEL;    modes=SDL_ListModes(NULL,info->sdlflags);    if (modes!=(SDL_Rect**)-1) {      fprintf(stderr,"Still no modes available. Can't start SDL!\n");      SDL_Quit();      return(0);    }  }  /*  // set coriander icon  icon_surface=SDL_CreateRGBSurfaceFrom((void*)coriander_logo_xpm)  SDL_WM_SetIcon(icon_surface,NULL);  */  info->sdlvideorect.x=0;  info->sdlvideorect.y=0;  info->sdlvideorect.w=display_service->current_buffer->width;  info->sdlvideorect.h=display_service->current_buffer->height;  // maximize display size to XV size if necessary  if ((xvinfo.max_width!=-1)&&(xvinfo.max_height!=-1)) {    if (info->sdlvideorect.w>xvinfo.max_width) {      info->sdlvideorect.w=xvinfo.max_width;    }    if (info->sdlvideorect.h>xvinfo.max_height) {      info->sdlvideorect.h=xvinfo.max_height;    }  }  // Set requested video mode  info->sdlbpp = SDL_VideoModeOK(info->sdlvideorect.w, info->sdlvideorect.h, info->sdlbpp, info->sdlflags);  info->sdlvideo = SDL_SetVideoMode(info->sdlvideorect.w, info->sdlvideorect.h, info->sdlbpp, info->sdlflags);  if (info->sdlvideo == NULL) {    MainError(SDL_GetError());    SDL_Quit();    return(0);  }  if (SDL_SetColorKey( info->sdlvideo, SDL_SRCCOLORKEY, 0x0) < 0 ) {    MainError(SDL_GetError());  }    // Show cursor  SDL_ShowCursor(1);    // set window title:  SDL_WM_SetCaption(camera->prefs.name,camera->prefs.name);  // this line broke everything for unknown reasons so I just remove it.  //info->sdlvideo->format->BytesPerPixel=2;  // Create YUV Overlay  switch(preferences.overlay_byte_order) {  case OVERLAY_BYTE_ORDER_YUYV:    info->sdloverlay = SDL_CreateYUVOverlay(display_service->current_buffer->width,					    display_service->current_buffer->height,					    SDL_YUY2_OVERLAY,info->sdlvideo);    break;  case OVERLAY_BYTE_ORDER_UYVY:    info->sdloverlay = SDL_CreateYUVOverlay(display_service->current_buffer->width,					    display_service->current_buffer->height,					    SDL_UYVY_OVERLAY,info->sdlvideo);    break;  default:    fprintf(stderr,"Invalid overlay byte order\n");    break;  }    if (info->sdloverlay==NULL) {    MainError(SDL_GetError());    SDL_Quit();    return(0);  }  SDLEventStartThread(display_service);  return(1);}// we should optimize this for RGB too: RGB modes could use RGB-SDL instead of YUV overlayvoidconvert_to_yuv_for_SDL(buffer_t *buffer, SDL_Overlay *sdloverlay, int overlay_byte_order){  unsigned char *dest=sdloverlay->pixels[0];  switch(buffer->buffer_color_mode) {  case COLOR_FORMAT7_MONO8:    y2uyvy(buffer->image, dest, buffer->width, buffer->height, 	   sdloverlay->pitches[0], overlay_byte_order);    break;  case COLOR_FORMAT7_YUV411:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -