18 #include <sys/socket.h>    19 #include <netinet/in.h>    20 #include <netinet/tcp.h>    30 #include <boost/archive/iterators/base64_from_binary.hpp>    31 #include <boost/archive/iterators/transform_width.hpp>    32 #include <boost/archive/iterators/ostream_iterator.hpp>    56             pthread_mutex_init (&deleteMessageMutex, NULL);
    60             json_t* result = NULL;
    61             pthread_mutex_lock(&deleteMessageMutex);
    62             if (!messageList.empty())
    64                 result = messageList.front();
    65                 messageList.pop_front();
    67             pthread_mutex_unlock(&deleteMessageMutex);
    72             struct hostent *server;
    73             server = gethostbyname(url.c_str());
    78                     fprintf(stderr,
"Could not resolve %s.\n",url.c_str());
    87             sockfd = socket(AF_INET, SOCK_STREAM, 0);
    92                     fprintf(stderr,
"Could not create socket.\n");
   101             struct sockaddr_in serv_addr;
   102             memset(&serv_addr,0, 
sizeof(serv_addr));
   103             serv_addr.sin_family = AF_INET;
   104             bcopy((
char *)server->h_addr,(
char *)&serv_addr.sin_addr.s_addr,server->h_length);
   105             serv_addr.sin_port = htons(port);
   106             if (connect(sockfd,(
struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
   111                     fprintf(stderr,
"Could not connect to %s.\n",url.c_str());
   120             pthread_create(&readThread,NULL,run_readAndSetMessages,
this);
   132                 char* content = json_dumps( *registerMessage, 0 );
   151                 sprintf(id_string,
"{\"uid\": %i",
id);
   152                 int add = send(sockfd,id_string,strlen(id_string),MSG_MORE | MSG_NOSIGNAL);
   160                 uint32_t l = strlen(content)-1; 
   162                 int amount = (l+4095)/4096;
   163                 for (
int i = 0; i < amount; i++)
   167                         int add = send(sockfd,&content[i*4096],l - i * 4096,MSG_MORE | MSG_NOSIGNAL);
   173                         int add = send(sockfd,&content[i*4096],4096,MSG_MORE | MSG_NOSIGNAL);
   181                 char finisher[] = 
"} ";
   182                 int add = send(sockfd,finisher,2,MSG_NOSIGNAL);
   191             this->registerMessage = registerMessage;
   192             char* content = json_dumps( *registerMessage, 0 );
   199             static void isaac_init_destination(j_compress_ptr cinfo)
   202             static boolean isaac_jpeg_empty_output_buffer(j_compress_ptr cinfo)
   206             static void isaac_jpeg_term_destination(j_compress_ptr cinfo)
   212             if (jpeg_quality > 100)
   214             this->jpeg_quality = jpeg_quality;
   219             uint32_t count = width*height*depth;
   221                 struct jpeg_compress_struct cinfo;
   222                 struct jpeg_error_mgr jerr;
   223                 jpeg_destination_mgr dest;
   224                 dest.init_destination = &isaac_init_destination;
   225                 dest.empty_output_buffer = &isaac_jpeg_empty_output_buffer;
   226                 dest.term_destination = &isaac_jpeg_term_destination;
   227                 cinfo.err = jpeg_std_error(&jerr);
   228                 jpeg_create_compress(&cinfo);
   230                 std::vector<char> jpeg_buffer;
   231                 jpeg_buffer.resize( count );
   232                 cinfo.dest->next_output_byte = (JOCTET*)(jpeg_buffer.data());
   233                 cinfo.dest->free_in_buffer = count;
   234                 cinfo.image_width = width;
   235                 cinfo.image_height = height;
   236                 cinfo.input_components = depth;
   237                 cinfo.in_color_space = JCS_EXT_RGBX;
   238                 jpeg_set_defaults(&cinfo);
   239                 jpeg_set_quality(&cinfo, jpeg_quality, 
false);
   240                 jpeg_start_compress(&cinfo, TRUE);
   241                 while (cinfo.next_scanline < cinfo.image_height)
   243                     JSAMPROW row_pointer[1];
   244                     row_pointer[0] = & ((JSAMPROW)ptr)[cinfo.next_scanline * width * depth];
   245                     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
   247                 jpeg_finish_compress(&cinfo);
   248                 count -= cinfo.dest->free_in_buffer;
   249                 ptr = jpeg_buffer.data();
   250                 jpeg_destroy_compress(&cinfo);
   253             using namespace boost::archive::iterators;
   254             std::stringstream payload;
   260                         const unsigned char *,
   268                 base64_text( (
char*)ptr ),
   269                 base64_text( (
char*)ptr + count),
   270                 boost::archive::iterators::ostream_iterator<char>(payload)
   274                 char header[] = 
"{\"payload\": \"data:image/jpeg;base64,";
   276                 char header[] = 
"{\"payload\": \"data:image/raw-rgba;base64,";
   278             char footer[] = 
"\"}";
   279             int hl = strlen(header);
   280             int pl = payload.str().length();
   281             int fl = strlen(footer);
   282             #if ISAAC_VALGRIND_TWEAKS == 1   287                 char* message = (
char*)malloc(hl+pl+fl+1+4);
   289                 char* message = (
char*)malloc(hl+pl+fl+1);
   291             memcpy(  message        ,header,hl);
   292             memcpy(&(message[hl   ]),payload.str().c_str(),pl);
   293             memcpy(&(message[hl+pl]),footer,fl+1); 
   306             pthread_cancel(readThread);
   307             pthread_mutex_destroy(&deleteMessageMutex);
   310         void readAndSetMessages()
   312             while (json_t * content = json_load_callback(json_load_callback_function,&sockfd,JSON_DISABLE_EOF_CHECK,NULL))
   316                 if (js = json_object_get( content, 
"fatal error"))
   318                     const char* fatal_error = json_string_value( js );
   319                     fprintf(stderr,
"Fatal error: \"%s\".\n",fatal_error);
   320                     if (strcmp(fatal_error,
"protocol mismatch") == 0)
   325                     json_decref( content );
   328                 if (js = json_object_get( content, 
"done"))
   330                     isaac_uint new_server_id = json_integer_value( js );
   331                     if (new_server_id > server_id)
   332                         server_id = new_server_id;
   333                     json_decref( content );
   337                     pthread_mutex_lock(&deleteMessageMutex);
   338                     messageList.push_back(content);
   339                     pthread_mutex_unlock(&deleteMessageMutex);
   343         static size_t json_load_callback_function (
void *buffer, 
size_t buflen, 
void *data)
   345             return recv(*((
isaac_int*)data),buffer,1,0);
   347         static void* run_readAndSetMessages(
void* communicator)
   358         std::list<json_t*> messageList;
   359         pthread_mutex_t deleteMessageMutex;
   360         pthread_t readThread;
   361         json_t** registerMessage;
 IsaacCommunicator(const std::string url, const isaac_uint port)
 
isaac_int serverSend(char *content, bool starting=true, bool finishing=false)
 
json_t * getLastMessage()
 
#define ISAAC_MAX_DIFFERENCE
 
void setJpegQuality(isaac_uint jpeg_quality)
 
void serverSendFrame(void *ptr, const isaac_uint width, const isaac_uint height, const isaac_uint depth)
 
isaac_int serverSendRegister(json_t **registerMessage)
 
#define ISAAC_HANDLE_EPIPE(add, n, sockfd, readThread)
 
isaac_int serverConnect(CommunicatorSetting setting)