bufferedslavexmlregionsource.cc
来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 324 行
CC
324 行
///////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveImageSource.cc defining a buffered XMLRegionSource class //// //// A XMLRegionSource which waits for external XML data blocks using //// pthread_cond_wait. The data given is buffered in a FIFO buffer and //// can be queried using get_next(). For this, it will be parsed using //// XMLRegionSource methods. The get_next() method returns a RegionSet * //// and deletes the XML buffer. //// //// Additionally, the class can fill up the FIFO buffer from a given //// NumberedFileSource, either automatically in get_next() or using our //// fill_buffer() method. //// //// XML Schema namespace "http://www.cvg.cs.reading.ac.uk/ADVISOR". //// //// Author : Nils T Siebel (nts) //// Created : Wed Feb 20 18:11:45 GMT 2002 //// Revision : 0.0 of Wed Feb 20 18:11:45 GMT 2002 //// Copyright : The University of Reading //// /////////////////////////////////////////////////////////////////////////////////// system includes...#include <string.h> // for memmove(), memset(), strlen()#include <time.h> // for tm type, mktime(), difftime()#include <sys/types.h> // for types like u_int32_t and u_int64_t// XML libraries for SAX2 API...#include <framework/MemBufInputSource.hpp> #include <sax2/SAX2XMLReader.hpp>// our own includes#include "BufferedSlaveXMLRegionSource.h"#include "RegionSet.h"#include "TrackedObjectSet.h"#include "XMLRegionHandler.h"#include "NumberedFileSource.h"#include "text_output.h" // for cerror etcnamespace ReadingPeopleTracker{static const char *BufferedSlaveXMLRegionSource_Revision = "@(#) BufferedSlaveXMLRegionSource.cc, rev 0.0 of Wed Feb 20 18:11:45 GMT 2002, Author Nils T Siebel, Copyright (c) 2002 The University of Reading";//////////////////////////////////////////////////////////////////////////// Constructor and Destructor ////////////////////////////////////////////////////////////////////////////BufferedSlaveXMLRegionSource::BufferedSlaveXMLRegionSource(unsigned int the_xdim, unsigned int the_ydim, // optionally :- NumberedFileSource *the_master_xml_data_source, unsigned int the_buffer_size){ // variable values outside of Thales Wrapper... xdim = the_xdim; ydim = the_ydim; master_xml_data_source = the_master_xml_data_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 XML data buffer buffer: an array of pointers to unsigned char * // XML data is always read first from the first pointer in this array xml_data_buffer = new unsigned char* [buffer_size]; memset((void *)xml_data_buffer, 0, buffer_size * sizeof (unsigned char*)); // zero // set up XML data buffer size buffer: an array of unsigned int xml_data_size_in_buffer = new unsigned int [buffer_size]; memset((void *)xml_data_size_in_buffer, 0, buffer_size * sizeof (unsigned int)); // zero // set up write access mutex and condition variables pthread_mutex_init(&xml_data_buffer_modification, NULL); pthread_cond_init(&new_xml_data_in_buffer, NULL); // initialise other variables buffer_entries = 0; // no XML data received yet current_region_set = NULL; // signal no valid RegionSet available yet}BufferedSlaveXMLRegionSource::~BufferedSlaveXMLRegionSource(){ // destroy write access mutex and condition variables pthread_mutex_destroy(&xml_data_buffer_modification); pthread_cond_destroy(&new_xml_data_in_buffer); if (xml_data_buffer != NULL) delete [] xml_data_buffer; // FIXME: what do we delete and what don't we? if (xml_data_size_in_buffer != NULL) delete [] xml_data_size_in_buffer; // FIXME: what do we delete and what don't we?}//////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveXMLSource::handle_new_blob_data: //// add given XML data to buffer //// //// Call this methdod to request a XML data buffer to be put into the //// buffer. The XML data will not be parsed until you call get_next() //// If the buffer is full, the method will issue an error message and //// ignore the given new data. //// ////////////////////////////////////////////////////////////////////////////////void BufferedSlaveXMLRegionSource::handle_new_blob_data(unsigned char *the_data, unsigned int the_data_size){ if (buffer_entries >= buffer_size) // no more room in buffer { cerror << " BufferedSlaveXMLSource::handle_blob_data(): " << "could not handle new XML blob data (buffer full) --- frame dropped. " << endl; return; } assert (the_data != NULL); assert (the_data_size > 0); // this requires exclusive write access to xml_data_buffer pointers // (we are competing with get_next() which could be removing an old pointer from the buffer) pthread_mutex_lock(&xml_data_buffer_modification); // xml_data_buffer[buffer_entries] = the_data; xml_data_size_in_buffer[buffer_entries] = the_data_size; buffer_entries++; // // signal ``new XML data in buffer'' to other thread in case it waits (in get_next()) pthread_cond_signal(&new_xml_data_in_buffer); // pthread_mutex_unlock(&xml_data_buffer_modification);}//////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveXMLSource::get_next: get next RegionSet from XML data //// //// Parse next XML data block in the buffer and return the resulting new //// RegionSet. If the buffer is empty, wait until the next XML data is //// put into the buffer by handle_new_blob_data(...). //// //// The RegionSet is not allocated by us; it is taken over by the caller. //// ////////////////////////////////////////////////////////////////////////////////RegionSet *BufferedSlaveXMLRegionSource::get_next(){ if (buffer_entries < 1) // no XML data buffers available: wait for one { // we might have a master_xml_data_source available where we can get the new image ourselves if (master_xml_data_source != NULL) { // get one (and only one) data block from master and place into data buffer // this requires exclusive write access to image_buffer pthread_mutex_lock(&xml_data_buffer_modification); // if (buffer_entries < 1) // check again after locking the image_buffer write access { cdebug << " BufferedSlaveXMLRegionSource::get_next(): buffer underrun"; // // get a new XML data block if available unsigned char *new_xml_data = master_xml_data_source->get_next(); size_t new_xml_data_size = master_xml_data_source->get_current_size(); // if (new_xml_data != NULL) { // place new XML data into xml_data_buffer xml_data_buffer[buffer_entries] = new_xml_data; // (buffer_entries == 0) xml_data_size_in_buffer[buffer_entries] = new_xml_data_size; buffer_entries++; // // signal ``new XML data in buffer'' just in case someone waits for it pthread_cond_signal(&new_xml_data_in_buffer); // cdebug << ", filled up from master. " << endl; } else { // unlock write access to image_buffer before returning with NULL pthread_mutex_unlock(&xml_data_buffer_modification); // signal no more XML data (probably end of sequence) assert (buffer_entries == 0); // no-one should have changed it xml_data_buffer[0] = NULL; xml_data_size_in_buffer[0] = 0; cdebug << " and no more XML data from master. " << endl; current_region_set = NULL; return current_region_set; // return "no current RegionSet" } } // pthread_mutex_unlock(&xml_data_buffer_modification); } else { // wait for a new XML data to arrive (done via handle_new_xml_data(...)) pthread_mutex_lock(&xml_data_buffer_modification); // avoid deadlocks // while (buffer_entries < 1) { pthread_cond_wait(&new_xml_data_in_buffer, &xml_data_buffer_modification); } // pthread_mutex_unlock(&xml_data_buffer_modification); } } // get first XML data block from buffer and parse it to get a new current_region_set MemBufInputSource *xml_buffer_source = new MemBufInputSource (xml_data_buffer[0], // next XML data block is first in the buffer xml_data_size_in_buffer[0], // this is the size of *(xml_data_buffer[0]) "http://www.cvg.cs.reading.ac.uk/ADVISOR/motion_detector", false); // parse XML data to get the new RegionSet with moving blobs/regions XML_parser->parse(*xml_buffer_source); // remove the XML data block from the buffer: this is done by moving the pointers up by one assert (buffer_entries > 0); // otherwise we should not have a current buffer // this requires exclusive write access to xml_data_buffer pointers // (we are competing with handle_new_xml_data(...) which could be filling up the buffer) pthread_mutex_lock(&xml_data_buffer_modification); // // de-allocate memory of current buffer so new data can be buffered // cdebug << " BufferedSlaveXMLRegionSource::get_next(): de-allocating " << "previous " << xml_data_size_in_buffer[0] << " bytes. " << endl; delete [] xml_data_buffer[0]; xml_data_size_in_buffer[0] = 0; // // move pointers up by one memmove((void *) &(xml_data_buffer[0]), (void *) &(xml_data_buffer[1]), (buffer_size - 1) * sizeof (unsigned char *)); xml_data_buffer[buffer_size - 1] = NULL; // should be useful during de-allocation // memmove((void *) &(xml_data_size_in_buffer[0]), (void *) &(xml_data_size_in_buffer[1]), (buffer_size - 1) * sizeof (unsigned int)); xml_data_size_in_buffer[buffer_size - 1] = 0; // just as a precaution // buffer_entries--; // adjust new buffer size // pthread_mutex_unlock(&xml_data_buffer_modification); // assign new current_region_set from parsed XML data current_region_set = XML_region_handler->get_current(); cdebug << " BufferedSlaveXMLRegionSource::get_next(): " << " new current_region_set has " << current_region_set->no_items << " entries." << endl; assert (current_region_set != NULL); frame_count++; return current_region_set;}frame_id_t BufferedSlaveXMLRegionSource::get_frame_id(){ if (current_region_set != NULL) // have valid RegionSet? return current_region_set->xml_frame_id; else return 0; // FIXME: in lieu of something useful}///////////////////////////////////////////////////////////////////////////////// //// BufferedSlaveXMLRegionSource::fill_buffer: fill up buffer from XML files //// //// Call this method to fill up the buffer from master_xml_data_source. //// Up to number_of_blocks_to_add XML data blocks will be read from //// master_xml_data_source using get_next(). The buffer will be filled up //// to buffer_size or until number_of_blocks_to_add have been added. //// //// Returns the number of XML files read and buffered. //// /////////////////////////////////////////////////////////////////////////////////unsigned int BufferedSlaveXMLRegionSource::fill_buffer(unsigned int number_of_blocks_to_add){ unsigned int count; // to count how many XML data blocks we are adding for (count = 0; (count < number_of_blocks_to_add); count++) { // check whether buffer is already full if (buffer_entries >= buffer_size) // no more room in buffer break; // 1 - get next XML data block and its size from master_xml_data_source unsigned char *new_xml_data = master_xml_data_source->get_next(); size_t new_xml_data_size = master_xml_data_source->get_current_size(); if (new_xml_data == NULL) break; // just break for now. We will check for end of sequence elsewhere. // 2 - simply add XML block to image_buffer // this requires exclusive write access to xml_data_buffer pointers // (we are competing with get_next() which could be removing an old pointer from the buffer) pthread_mutex_lock(&xml_data_buffer_modification); // xml_data_buffer[buffer_entries] = new_xml_data; xml_data_size_in_buffer[buffer_entries] = new_xml_data_size; buffer_entries++; // // signal ``new XML data in buffer'' to other thread in case it waits (in get_next()) pthread_cond_signal(&new_xml_data_in_buffer); // pthread_mutex_unlock(&xml_data_buffer_modification); } return count;}} // namespace ReadingPeopleTracker
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?