#ifndef STREAMINGINPUT_H
#define STREAMINGINPUT_H
/* BeginDocumentation
* Name: StreamingInput
*
* Description: Special retina module in charge of obtaining the retina input images from a
* video streaming through a network connection.
* In particular it creates a TCP socket listening for a incoming connection through which the
* input images are received in PNG format sequentialy.
* This class uses the method load_PNG from CImg, so it requires libpng-dev (and zlib). upng
* library could be adapted to load CImg images and thus remove these dependences.
*
* Author: Pablo Martinez CaƱada. University of Granada. CITIC-UGR. Spain.
* <pablomc@ugr.es>
* Author: Richard R. Carrillo. University of Granada. CITIC-UGR. Spain.
*
* SeeAlso: module
*/
#include <fstream>
#include <vector>
#include <string>
#include <stdio.h> // For FILE*
#include <pthread.h>
#include "module.h"
using namespace cimg_library;
using namespace std;
// Parameter of frame receiver thread
struct receiver_params {
FILE *accept_socket_fh; // File stream associated to accept_socket_fd
CImg<double> *buffer_img; // Buffer used to temporally store the image being received
bool exit_reception; // Reception threads exits when this var is set to true by a the caller
pthread_mutex_t buffer_mutex; // This var is locked when the buffer is started to be copied to the output and unlocked when it can be copied agin (new frame received)
pthread_mutex_t reception_mutex; // This var is locked when the thread starts receiving and unlocked the when can receive again (buffer copied to output)
};
// Thread function in charge of receiving frames through socket (int)new_socket_fd and
// storing them in bufferImage.
// After soreing a frame it signals the completion and waits until the signal is cleared
// to sore the next one.
void *image_receiver_thread(struct receiver_params *params);
class StreamingInput: public module{
protected:
// Internal variables
CImg<double> *outputImage; // Buffer where Update() stores the received image for getOutput()
int socket_fd; // Connection socket file descriptor or -1 if socket has not been creted
int accept_socket_fd; // Socket fd created when a connection is accepted
string connection_url; // URL of the connection. It must be 'tcp://localhost:port', where port
pthread_t Receiver_thread_id; // ID of the thread created to receive images
struct receiver_params receiver_vars; // Variables shared between the class object and the thread
double NextFrameTime; // Time at which the next frame must be received
bool endOfInput; // Indicates that the end of input has been reached (connection closed by other end), sext module output should be NULL
// StreamingInput operation parameters
int SkipNInitFrames; // Number of of frames to skip just at the beginning of the stream
bool RepeatLastFrame; // If this parameteris true, the last input frame received is repeated until the end of simulation time
double InputFramePeriod; // Number of simulation milliseconds that must elapse before a new frame is used. This is an alternative way to specify the FPS of the input.
public:
// Constructor, copy, destructor.
StreamingInput(int x=1, int y=1, double temporal_step=1.0, string conn_url="");
StreamingInput(const StreamingInput& copy);
~StreamingInput(void);
// Allocate values and set protected parameters
virtual bool allocateValues();
// These functions are mainly used by setParameters() to set object parameter properties after the object is created
bool set_SkipNInitFrames(int n_frames);
bool set_RepeatLastFrame(bool repeat_flag);
bool set_InputFramePeriod(double sim_time_period);
// Only used to update the object simulation time
virtual void feedInput(double sim_time, const CImg<double> &new_input, bool isCurrent, int port);
// Wait until a new frame is available and update output image buffer
void get_new_frame();
// update output image according to current sim. time, waiting for a new frame if needed
virtual void update();
// set Parameters
virtual bool setParameters(vector<double> params, vector<string> paramID);
// This method creates a socket (used for streaming) and bind it to a local port
bool openConnetion();
// This method waits for an incomming connection and creates a thread which
// continuously receives images
bool receiveStream();
// This method stops the thread in charge of receving the images
bool stopStreamReception();
// This method closes the streaming connection
bool closeConnection();
// Get image (y(k))
virtual CImg<double>* getOutput();
// Returns false to indicate that this class performs computation
virtual bool isDummy();
};
#endif // STREAMINGINPUT_H