bufferedslaveimagesource.cc
来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 475 行 · 第 1/2 页
CC
475 行
///////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveImageSource.cc defining a buffered ImageSource class //// //// An ImageSource which waits for external images using pthread_cond_wait. //// The images given are buffered in a FIFO buffer and can be queried. //// //// Additionally, the class can fill up the FIFO buffer from a given //// ImageSource, automatically in get_next() or using fill_buffer(). //// //// Author : Nils T Siebel (nts) //// Created : Wed Jan 23 17:52:33 GMT 2002 //// Revision : 1.0 of Thu Aug 15 13:26:33 BST 2002 //// Copyright : The University of Reading //// /////////////////////////////////////////////////////////////////////////////////#include "BufferedSlaveImageSource.h"#include <cassert>#include <cstring> // for memmove(), memset()#include <ctime> // for struct tm, mktime()#include "RGB32Image.h"#include "text_output.h" // for cerror etcnamespace ReadingPeopleTracker{static const char *BufferedSlaveImageSource_Revision = "@(#) BufferedSlaveImageSource.cc, rev 1.0 of Thu Aug 15 13:26:33 BST 2002, Author Nils T Siebel, Copyright (c) 2002 The University of Reading";BufferedSlaveImageSource::BufferedSlaveImageSource(unsigned int the_xdim, unsigned int the_ydim, ImageSource *the_master_image_source, // optional unsigned int the_buffer_size) // optional{ xdim = the_xdim; ydim = the_ydim; master_image_source = the_master_image_source; buffer_size = the_buffer_size; assert (xdim > 0); // we need valid image dimensions at this point assert (ydim > 0); // we need valid image dimensions at this point assert (buffer_size > 0); // empty buffer makes no sense (I strongly recommend > 1 --- nts) // set up the image buffer: an array of pointers to Image classes. // `current' will always be the first pointer in this array etc image_buffer = new Image*[buffer_size]; // Important: zero the *image_buffer (ie, set all pointers to NULL) memset((void *)image_buffer, 0, buffer_size * sizeof (Image*)); // set up write access mutex and condition variables pthread_mutex_init(&image_buffer_modification, NULL); pthread_cond_init(&new_image_in_buffer, NULL); // initialise other variables buffer_entries = 0; // no image received yet current = NULL; ImageSource::source_type = IST_SLAVE;}BufferedSlaveImageSource::~BufferedSlaveImageSource(){ // destroy write access mutex and condition variables pthread_mutex_destroy(&image_buffer_modification); pthread_cond_destroy(&new_image_in_buffer); // de-allocate all images in buffer, and our buffer if (image_buffer != NULL) { delete [] image_buffer; delete image_buffer; } // make sure ImageSource::~ImageSource does not try to de-allocate current current = NULL;}//////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveImageSource::handle_new_image: add given image to buffer //// //// Call this method to request a new image to be put into the buffer. //// The data will be put into a new Image. If the buffer is full, the //// method will issue an error message and ignore the image. //// //// The image data given has to be RGB32Image compatible, ie 24-bit RGB //// colour, padded to 32-bit with image addressing mode the same as //// defined by Image::image_storage_mode. //// ////////////////////////////////////////////////////////////////////////////////void BufferedSlaveImageSource::handle_new_image(unsigned char *the_data, TS_TIMESTAMP *the_timestamp){ if (buffer_entries >= buffer_size) // no more room in buffer { cerror << " BufferedSlaveImageSource::handle_new_image(): " << "could not handle new image (buffer full) --- frame dropped. " << endl; return; } assert (the_data != NULL); assert (the_timestamp != NULL); // create new time: milliseconds since the Epoch (01/01/1970) tm *f_time = new tm; f_time->tm_sec = the_timestamp->second; f_time->tm_min = the_timestamp->minute; f_time->tm_hour = the_timestamp->hour; f_time->tm_mday = the_timestamp->day; f_time->tm_mon = the_timestamp->month; f_time->tm_year = the_timestamp->year - 1900; // OK for year 3000 issue, see mktime(3) or ctime(3) if man pages still exist f_time->tm_isdst = 0; // probably not necessarily. time_t t_frame = mktime(f_time); frame_time_t the_frame_time_in_ms = ((frame_time_t) t_frame) // this is in seconds * 1000 + the_timestamp->millisecond; // make milliseconds and add delta Image *new_image = new RGB32Image(xdim, ydim, the_timestamp->frame_count, // ie the frame id the_frame_time_in_ms, the_data); new_image->set_timestamp(the_timestamp); // this requires exclusive write access to image_buffer pointers // (we are competing with get_next() which could be removing an old image from the buffer) pthread_mutex_lock(&image_buffer_modification); // image_buffer[buffer_entries] = new_image; buffer_entries++; // // signal ``new image in buffer'' to other thread in case it waits (in get_next()) pthread_cond_signal(&new_image_in_buffer); // pthread_mutex_unlock(&image_buffer_modification);}///////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveImageSource::get_next: get image from buffer or wait for it //// //// If no image is available in the buffer and we have a master_image_source //// one image will be taken from it and placed into the buffer as current. //// //// The current Image will be de-allocated by this method. //// /////////////////////////////////////////////////////////////////////////////////Image *BufferedSlaveImageSource::get_next(){ Image *old_current = NULL; if (current != NULL) { // dispose of the current Image. if (master_image_source != NULL) { // the master_image_source, if it exists, needs current during get_next() old_current = current; // remember so that we can de-allocate it later } else { // delete it#ifdef THALES_WRAPPER wrapper_release_buffer(current->get_data()); current->set_data(NULL); // so Image::~Image does not de-allocate it#endif // do not de-allocate current but re-use its memory --- for reasons of speed // this requires exclusive write access to image_buffer pointers // (we are competing with handle_new_image(...) which could be filling up the buffer) pthread_mutex_lock(&image_buffer_modification); // keep_image_memory_for_later(current); // pthread_mutex_unlock(&image_buffer_modification); current = NULL; } // remove the image from the buffer: this is done by moving the pointers one up assert (buffer_entries > 0); // otherwise we should not have a current image // this requires exclusive write access to image_buffer pointers // (we are competing with handle_new_image(...) which could be filling up the buffer) pthread_mutex_lock(&image_buffer_modification); // memmove((void *) &(image_buffer[0]), (void *) &(image_buffer[1]), (buffer_size - 1) * sizeof (Image*)); // Important: mark entry as not used (avoiding two pointers to be the same) image_buffer[buffer_size - 1] = NULL; buffer_entries--; // pthread_mutex_unlock(&image_buffer_modification); } if (buffer_entries < 1) // no images available { // we might have a master_image_source available where we can get the new image ourselves if (master_image_source != NULL) { // get one image (and only one) from master_image_source and place into image_buffer // this requires exclusive write access to image_buffer pthread_mutex_lock(&image_buffer_modification); // if (buffer_entries < 1) // check again after locking the image_buffer write access { cdebug << " BufferedSlaveImageSource::get_next(): buffer underrun"; // // query master_image_source for a new Image // set master_image_source's current Image memory to a new Image. // This is so that it does not overwrite its current Image which // might be buffered here, but might still be unused. // It is not necessary for the first frame where its current == NULL if (master_image_source->get_frame_count() > 0) { // try to get new Image memory for master_image_source Image *new_image_memory = get_new_image_memory(); if (new_image_memory == NULL) // found none { // remember the window handle (which must not be copied by copy())#ifndef NO_DISPLAY#ifdef USE_GL long int old_glwin = master_image_source->get_current()->get_glwin();#else#error Tugdual, please put the Qt equivalent or whatever here so that the window is preserved. Thanks.#endif#endif // ifndef NO_DISPLAY
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?