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 + -
显示快捷键?