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