Skip to content

Instantly share code, notes, and snippets.

@ofTheo
Created October 4, 2014 22:35
Show Gist options
  • Save ofTheo/25bfa61d101655bff85d to your computer and use it in GitHub Desktop.
Save ofTheo/25bfa61d101655bff85d to your computer and use it in GitHub Desktop.
UDPImageTransfer
//
// UDPImageTransfer.cpp
//
// Created by Theodore Watson on 9/16/14.
//
//
#include "UDPImageTransfer.h"
UDPImageTransfer::UDPImageTransfer(){
bConnected = false;
bNewFrame = false;
rx = tx = false;
currentPort = 0;
currentIp = "";
}
bool UDPImageTransfer::setupForSend(string ip, int port){
close();
if( udpMan.Create() && udpMan.Connect(ip.c_str(), port) ){
udpMan.SetNonBlocking(true);
currentIp = ip;
currentPort = port;
bConnected = true;
tx = true;
startThread();
}else{
ofLogError("UDPImageTransfer::setupForSend") << " unable to connect to " << ip << " " << port << endl;
}
return bConnected;
}
bool UDPImageTransfer::setupForReceive(int port){
close();
if( udpMan.Create() && udpMan.Bind(port) ){
udpMan.SetNonBlocking(true);
currentIp = "";
currentPort = port;
bConnected = true;
rx = true;
startThread();
}else{
ofLogError("UDPImageTransfer::setupForSend") << " unable to Bind to port " << port << endl;
}
return bConnected;
}
void UDPImageTransfer::sendImage(ofPixelsRef img){
if( lock() ){
outCue.push_back(img);
unlock();
}
}
int findDelim(char * data, int dataSize, string needle){
size_t s_len = needle.size();
int result = -1;
for(size_t count = 0; count < dataSize; ++count){
if (!isprint(data[count])) continue;
if( !memcmp(needle.c_str(), data + count, s_len) ){
result = count;
}
}
return result;
}
bool UDPImageTransfer::isConnected(){
return bConnected;
}
string UDPImageTransfer::getCurrentIp(){
return currentIp;
}
int UDPImageTransfer::getCurrentPort(){
return currentPort;
}
void UDPImageTransfer::threadedFunction(){
while(isThreadRunning()){
if( bConnected && tx ){
while(outCue.size()){
ofBuffer send;
string end = "[IMAGE_END]";
if(lock()){
ofPixels img = outCue.front();
ofSaveImage(img, send, OF_IMAGE_FORMAT_JPEG, OF_IMAGE_QUALITY_HIGH);
outCue.erase(outCue.begin());
unlock();
}
send.append(end);
int maxSizeToSend = 10000;
if( send.size() >= maxSizeToSend ){
int bufferCur = 0;
int buffEnd = send.size();
int buffPer = maxSizeToSend;
int steps = 0;
// cout << " bufferEnd is " << buffEnd;
while( bufferCur < buffEnd ){
int buffLeft = buffEnd-bufferCur;
if( buffLeft < buffPer ){
buffPer = buffLeft;
}
int result = udpMan.Send(&send.getBinaryBuffer()[bufferCur], buffPer);
if( result > 0 ){
bufferCur += result;
}else{
break;
}
steps++;
}
// cout << " sent - bufferCur = " << bufferCur << " with steps: " << steps << endl;
}else{
cout << " udpMan max send size is " << udpMan.GetSendBufferSize() << endl;
int result = udpMan.Send(send.getBinaryBuffer(), send.size());
cout << " sending buffer with size " << send.size() << " result is " << result << endl;
}
}
}
if( bConnected && rx ){
ofBuffer tmp;
if( udpMan.GetReceiveBufferSize() ){
tmp.allocate(udpMan.GetReceiveBufferSize());
}
int numBytes = udpMan.Receive(tmp.getBinaryBuffer(), tmp.size());
if( numBytes > 0 ){
inBuffer.append(tmp.getBinaryBuffer(), numBytes);
cout << " got this many bytes " << numBytes << endl;
string delim = "[IMAGE_END]";
if( inBuffer.size() > delim.length() ){
cout << " inBuffer size is " << inBuffer.size() << endl;
int pos = findDelim(inBuffer.getBinaryBuffer(), inBuffer.size(), delim);
if( pos >= 0 ){
cout << " found ending delim " << endl;
ofBuffer imageBuffer;
imageBuffer.set(inBuffer.getBinaryBuffer(), pos);
int end = pos + delim.length();
// cout << "pos is " << pos << " size is " << inBuffer.size() << " end is " << endl;
//inBuffer.set(&inBuffer.getBinaryBuffer()[end], inBuffer.size()-end);
inBuffer.clear();
// cout << " in buffer size is now " << inBuffer.size() << endl;
if( imageBuffer.size() ){
if( ofLoadImage(rxImg, imageBuffer) ){
cout << " image loaded with size "<< rxImg.getWidth() << " " << rxImg.getHeight() << endl;
if(lock()){
bNewFrame = true;
unlock();
}
}else{
cout << " error loading image "<< rxImg.getWidth() << " " << rxImg.getHeight() << endl;
}
}
}
}
}
}
yield();
}
}
void UDPImageTransfer::close(){
if( isThreadRunning() ){
waitForThread(true);
}
if( bConnected ){
udpMan.Close();
}
bConnected = false;
bNewFrame = false;
rx = tx = false;
currentPort = 0;
currentIp = "";
}
void UDPImageTransfer::update(){
}
bool UDPImageTransfer::isNewImage(){
return bNewFrame;
}
ofPixels UDPImageTransfer::getImage(){
if(lock()){
bNewFrame = false;
unlock();
}
return rxImg;
}
//
// UDPImageTransfer.h
//
// Created by Theodore Watson on 9/16/14.
//
//
#pragma once
#include "ofMain.h"
#include "ofxNetwork.h"
class UDPImageTransfer : public ofThread{
public:
UDPImageTransfer();
bool setupForSend(string ip, int port);
bool setupForReceive(int port);
void sendImage(ofPixelsRef img);
bool isConnected();
string getCurrentIp();
int getCurrentPort();
void close();
void update();
bool isNewImage();
ofPixels getImage();
protected:
void threadedFunction();
bool bNewFrame;
bool bConnected;
bool rx;
bool tx;
string currentIp;
int currentPort;
ofBuffer inBuffer;
ofxUDPManager udpMan;
ofPixels rxImg;
vector <ofPixels> outCue;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment