www.pudn.com > ReadingPeopleTracker-1.28.rar > BufferedSlaveImageSource.h


///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  BufferedSlaveImageSource.h  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  : 0.0 of Wed Jan 23 17:52:33 GMT 2002                          //
//  Copyright : The University of Reading                                    //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#ifndef __BUFFERED_SLAVE_IMAGE_SOURCE_H__
#define __BUFFERED_SLAVE_IMAGE_SOURCE_H__

#include 
#include      // for IEEE POSIX 1003.1c --- 1995 threads
#include        // for UINT_MAX

#include "ImageSource.h"
#include "timestamp_c.h"
#include "tracker_defines_types_and_helpers.h"  // for frame_id_t, frame_time_t, ImageType

namespace ReadingPeopleTracker
{

// number of images to buffer before refusing external requests to
//   handle_new_image(...).  Equals to maximum number of images used and
//   provided by this ImageSource at any one time.
#define BSS_DEFAULT_BUFFER_SIZE 10

class BufferedSlaveImageSource : public ImageSource
{
private:
    unsigned int buffer_entries;  // actual number of images in buffer, including current
    unsigned int buffer_size;     // maximum of the above, the buffer size

    // dimensions of image --- must be specified upon instantiation!  It will be queried.
    unsigned int xdim;
    unsigned int ydim;
    
    // the image buffer: an array [0..buffer_size-1] of Image * allocated during intstantiation
    Image **image_buffer;
    
    // our master image source, if given: to fill up the buffer, either
    //   using our fill_buffer method or automatically in get_next()
    ImageSource *master_image_source;

    //////////////////////////////////////////////////////////////////////////
    //   Pthread data: mutex and condition variables for image_buffer       //
    //////////////////////////////////////////////////////////////////////////

    pthread_mutex_t image_buffer_modification;  // write access to image_buffer
    pthread_cond_t new_image_in_buffer;         // whether new image has arrived in buffer    

public:
    // constructor, desctructor
    BufferedSlaveImageSource(unsigned int the_xdim, unsigned int the_ydim,
			     ImageSource *the_master_image_source = NULL,
			     unsigned int the_buffer_size = BSS_DEFAULT_BUFFER_SIZE);
    ~BufferedSlaveImageSource();
    
    // method to call when a new image arrives.  It will be buffered or ignored.
    void handle_new_image(unsigned char *the_data, TS_TIMESTAMP *the_timestamp);

    // fill image_buffer with up to number_of_images_to_add images, from master_image_source
    unsigned int fill_buffer(unsigned int number_of_images_to_add = UINT_MAX);
    
    // return number of entries currently in buffer
    inline unsigned int get_buffer_entries() const
	{
	    return buffer_entries;
	}
    
    // return maximum number of entries in buffer --- the buffer size
    inline unsigned int get_buffer_size() const
	{
	    return buffer_size;
	}
    
    
    //////////////////////////////////////////////////////////////////////////
    //   Redefinition of ImageSource methods                                //
    //////////////////////////////////////////////////////////////////////////

    virtual Image *get_next();

    virtual unsigned int get_xdim() const
	{
	    return xdim;
	}
    
    virtual unsigned int get_ydim() const
	{
	    return ydim;
	}


    virtual ImageType get_image_type() const
	{
	    if (master_image_source != NULL)
		return master_image_source->get_image_type();  // simply return master's ImageType
	    
	    bool we_no_what_images_we_will_get = false;
	    assert(we_no_what_images_we_will_get == true);  // how should we know?

	    return RGB32;  // possibly...
	}


private:
    // private helpers

    // reserve the Image memory for later re-use
    void keep_image_memory_for_later (Image *&old_image);

    // get back Image memory reserved by keep_image_memory_for_later (or NULL if none available)
    Image *get_new_image_memory();


    // prevent people from using the default (or in fact, any) copy contructor 
    //   or operator= for BufferedSlaveImageSource --- nothing good could come from it
    
protected:
    BufferedSlaveImageSource &operator= (const BufferedSlaveImageSource &original)
	{
	    // do not use !
	    bool this_is_recommended = false;
	    assert (this_is_recommended == true);  // do not use BufferedSlaveImageSource &operator=
	    return *this;
	}
    
    BufferedSlaveImageSource (const BufferedSlaveImageSource &original)
	{
	    // do not use !
	    bool this_is_recommended = false;
	    assert (this_is_recommended == true);  // do not use BufferedSlaveImageSource's copy constructor
	}
};

} // namespace ReadingPeopleTracker

#endif