📄 thread_iso.c
字号:
/* * 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"gint IsoStartThread(camera_t* cam){ int maxspeed, port; //int channel, speed; chain_t* iso_service=NULL; isothread_info_t *info=NULL; iso_service=GetService(cam, SERVICE_ISO); if (iso_service==NULL) { // if no ISO service running... iso_service=(chain_t*)malloc(sizeof(chain_t)); iso_service->current_buffer=NULL; iso_service->next_buffer=NULL; iso_service->data=(void*)malloc(sizeof(isothread_info_t)); pthread_mutex_init(&iso_service->mutex_struct, NULL); pthread_mutex_init(&iso_service->mutex_data, NULL); info=(isothread_info_t*)iso_service->data; /* currently FORMAT_STILL_IMAGE is not supported*/ if (cam->misc_info.format == FORMAT_STILL_IMAGE) { FreeChain(iso_service); return(-1); } info->handle = NULL; // the iso receive handler gets its own raw1394 handle to free the controls port=dc1394_get_camera_port(cam->camera_info.handle); //fprintf(stderr,"port for this camera is %d\n",port); if ( (info->handle = dc1394_create_handle(port)) < 0) { FreeChain(iso_service); return(-1); } switch (cam->selfid.packetZero.phySpeed) { case 1: maxspeed=SPEED_200;break; case 2: maxspeed=SPEED_400;break; default: maxspeed=SPEED_100;break; } // copy params if we are the current camera if (cam==camera) { info->receive_method=cam->prefs.receive_method; strcpy(info->video1394_device, cam->prefs.video1394_device); info->capture.dma_device_file=info->video1394_device; info->video1394_dropframes=cam->prefs.video1394_dropframes; info->dma_buffer_size=cam->prefs.dma_buffer_size; } switch(info->receive_method) { case RECEIVE_METHOD_VIDEO1394: if (cam->misc_info.format!=FORMAT_SCALABLE_IMAGE_SIZE) if (dc1394_dma_setup_capture(cam->camera_info.handle, cam->camera_info.id, cam->misc_info.iso_channel, cam->misc_info.format, cam->misc_info.mode, maxspeed, cam->misc_info.framerate, info->dma_buffer_size, info->video1394_dropframes, info->capture.dma_device_file, &info->capture) == DC1394_SUCCESS) { info->receive_method=RECEIVE_METHOD_VIDEO1394; } else { MainError("Failed to setup DMA capture with VIDEO1394"); dc1394_destroy_handle(info->handle); FreeChain(iso_service); return(-1); } else { if (dc1394_dma_setup_format7_capture(cam->camera_info.handle, cam->camera_info.id, cam->misc_info.iso_channel, cam->misc_info.mode, maxspeed, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, info->dma_buffer_size, info->video1394_dropframes, info->capture.dma_device_file, &info->capture) == DC1394_SUCCESS) { info->receive_method=RECEIVE_METHOD_VIDEO1394; } else { MainError("Failed to setup Format_7 DMA capture with VIDEO1394"); dc1394_destroy_handle(info->handle); FreeChain(iso_service); return(-1); } } break; case RECEIVE_METHOD_RAW1394: if (cam->misc_info.format!=FORMAT_SCALABLE_IMAGE_SIZE) if (dc1394_setup_capture(cam->camera_info.handle, cam->camera_info.id, cam->misc_info.iso_channel, cam->misc_info.format, cam->misc_info.mode, maxspeed, cam->misc_info.framerate, &info->capture) == DC1394_SUCCESS) { info->receive_method=RECEIVE_METHOD_RAW1394; } else { MainError("Failed to setup capture with RAW1394"); dc1394_destroy_handle(info->handle); FreeChain(iso_service); return(-1); } else { if (dc1394_setup_format7_capture(cam->camera_info.handle, cam->camera_info.id, cam->misc_info.iso_channel, cam->misc_info.mode, maxspeed, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, QUERY_FROM_CAMERA, &info->capture) == DC1394_SUCCESS) { info->receive_method=RECEIVE_METHOD_RAW1394; } else { MainError("Failed to setup Format_7 capture with RAW1394"); dc1394_destroy_handle(info->handle); FreeChain(iso_service); return(-1); } } break; } pthread_mutex_lock(&iso_service->mutex_data); CommonChainSetup(cam, iso_service, SERVICE_ISO); // init image buffers structs info->temp=NULL; info->temp_size=0; info->temp_allocated=0; pthread_mutex_lock(&iso_service->mutex_struct); InsertChain(cam,iso_service); //iso_service->timeout_func_id=-1; if (pthread_create(&iso_service->thread, NULL, IsoThread,(void*) iso_service)) { RemoveChain(cam, iso_service); pthread_mutex_unlock(&iso_service->mutex_struct); pthread_mutex_unlock(&iso_service->mutex_data); FreeChain(iso_service); return(-1); } else { pthread_mutex_unlock(&iso_service->mutex_struct); pthread_mutex_unlock(&iso_service->mutex_data); } } return (1);}void*IsoCleanupThread(void* arg) { chain_t* iso_service; isothread_info_t *info; iso_service=(chain_t*)arg; info=(isothread_info_t*)iso_service->data; if ((info->receive_method == RECEIVE_METHOD_VIDEO1394)) { //dc1394_dma_done_with_buffer(&info->capture); // this should be done at the condition it has not been executed before or // else we get an ioctl error from libdc1394. How to do this, I don't know... //fprintf(stderr,"dma done with buffer\n"); } // clear timing info on GUI... pthread_mutex_unlock(&iso_service->mutex_data); return(NULL);} void*IsoThread(void* arg){ chain_t *iso_service; isothread_info_t *info; int dma_ok=DC1394_FAILURE; float tmp; // we should only use mutex_data in this function iso_service=(chain_t*)arg; pthread_mutex_lock(&iso_service->mutex_data); info=(isothread_info_t*)iso_service->data; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); pthread_mutex_unlock(&iso_service->mutex_data); // time inits: iso_service->prev_time = times(&iso_service->tms_buf); iso_service->fps_frames=0; iso_service->processed_frames=0; while (1) { pthread_testcancel(); pthread_cleanup_push((void*)IsoCleanupThread, (void*)iso_service); if (info->receive_method == RECEIVE_METHOD_RAW1394) dc1394_single_capture(info->handle, &info->capture); else dma_ok=dc1394_dma_single_capture(&info->capture); gettimeofday(&info->rawtime, NULL); localtime_r(&info->rawtime.tv_sec, &(iso_service->current_buffer->captime)); iso_service->current_buffer->captime_usec=info->rawtime.tv_usec; sprintf(iso_service->current_buffer->captime_string,"%04d%02d%02d-%02d%02d%02d-%03d", iso_service->current_buffer->captime.tm_year+1900, iso_service->current_buffer->captime.tm_mon+1, iso_service->current_buffer->captime.tm_mday, iso_service->current_buffer->captime.tm_hour, iso_service->current_buffer->captime.tm_min, iso_service->current_buffer->captime.tm_sec, iso_service->current_buffer->captime_usec/1000); pthread_mutex_lock(&iso_service->mutex_data); // check current buffer status IsoThreadCheckParams(iso_service); // Stereo decoding switch (iso_service->current_buffer->stereo_decoding) { case STEREO_DECODING_INTERLACED: StereoDecode((unsigned char *)info->capture.capture_buffer,info->temp, info->orig_sizex*info->orig_sizey*2); break; case STEREO_DECODING_FIELD: memcpy(info->temp,(unsigned char *)info->capture.capture_buffer,info->orig_sizex*info->orig_sizey*2); break; case NO_STEREO_DECODING: if ((iso_service->current_buffer->bayer!=NO_BAYER_DECODING)&&(info->cond16bit!=0)) { y162y((unsigned char *)info->capture.capture_buffer,info->temp, info->orig_sizex*info->orig_sizey, iso_service->current_buffer->bpp); } else { // it is necessary to put this here and not in the thread init or IsoThreadCheckParams function because // the buffer might change at every capture (typically when capture is too slow and buffering is performed) info->temp=(unsigned char*)info->capture.capture_buffer; } break; } // Bayer decoding switch (iso_service->current_buffer->bayer) { case BAYER_DECODING_NEAREST: BayerNearestNeighbor(info->temp, iso_service->current_buffer->image, iso_service->current_buffer->width, iso_service->current_buffer->height, iso_service->current_buffer->bayer_pattern); break; case BAYER_DECODING_EDGE_SENSE: BayerEdgeSense(info->temp, iso_service->current_buffer->image, iso_service->current_buffer->width, iso_service->current_buffer->height, iso_service->current_buffer->bayer_pattern); break; case BAYER_DECODING_SIMPLE: BayerSimple(info->temp, iso_service->current_buffer->image, iso_service->current_buffer->width, iso_service->current_buffer->height, iso_service->current_buffer->bayer_pattern); break; case BAYER_DECODING_DOWNSAMPLE: BayerDownsample(info->temp, iso_service->current_buffer->image, iso_service->current_buffer->width, iso_service->current_buffer->height, iso_service->current_buffer->bayer_pattern); break; case NO_BAYER_DECODING: // this is only necessary if no stereo was performed if (iso_service->current_buffer->stereo_decoding==NO_STEREO_DECODING) { memcpy(iso_service->current_buffer->image, info->temp, iso_service->current_buffer->bytes_per_frame); } break; } // FPS computation: iso_service->current_time=times(&iso_service->tms_buf); iso_service->fps_frames++; iso_service->processed_frames++; tmp=(float)(iso_service->current_time-iso_service->prev_time)/sysconf(_SC_CLK_TCK); if (tmp==0) iso_service->fps=fabs(0.0); else iso_service->fps=fabs((float)iso_service->fps_frames/tmp); if ((info->receive_method == RECEIVE_METHOD_VIDEO1394)&&(dma_ok==DC1394_SUCCESS)) dc1394_dma_done_with_buffer(&info->capture); pthread_mutex_unlock(&iso_service->mutex_data); pthread_mutex_lock(&iso_service->mutex_data); RollBuffers(iso_service); pthread_mutex_unlock(&iso_service->mutex_data); pthread_cleanup_pop(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -