static void _getdns_cancel_reply(getdns_context *context, connection *conn) { struct mem_funcs *mf; if (!conn) return; if (context && context->server && _getdns_rbtree_search(&context->server->connections_set, conn) != &conn->super) return; if (conn->l->transport == GETDNS_TRANSPORT_TCP) { tcp_connection *tcp_conn = (tcp_connection *)conn; if (tcp_conn->to_answer > 0 && --tcp_conn->to_answer == 0 && tcp_conn->fd == -1) tcp_connection_destroy(tcp_conn); } else if (conn->l->transport == GETDNS_TRANSPORT_UDP && (mf = &conn->l->set->context->mf)) { listen_set *set = conn->l->set; /* Unlink this connection */ (void) _getdns_rbtree_delete( &set->connections_set, conn); DEBUG_SERVER("[connection del] count: %d\n", (int)set->connections_set.count); if ((*conn->prev_next = conn->next)) conn->next->prev_next = conn->prev_next; GETDNS_FREE(*mf, conn); free_listen_set_when_done(set); } }
static void server_onclose(tcp_connection_t* connection, void* userdata) { /* 需要使用者在on_connection()中自行将close callback修改为自己的处理函数 */ tcp_connection_destroy(connection); return; }
static void tcp_write_cb(void *userarg) { tcp_connection *conn = (tcp_connection *)userarg; struct mem_funcs *mf; getdns_eventloop *loop; tcp_to_write *to_write; ssize_t written; assert(userarg); if (!(mf = &conn->super.l->set->context->mf)) return; if (getdns_context_get_eventloop(conn->super.l->set->context, &loop)) return; /* Reset tcp_connection idle timeout */ loop->vmt->clear(loop, &conn->event); if (!conn->to_write) { conn->event.write_cb = NULL; (void) loop->vmt->schedule(loop, conn->fd, DOWNSTREAM_IDLE_TIMEOUT, &conn->event); return; } to_write = conn->to_write; if (conn->fd == -1 || (written = send(conn->fd, (const void *)&to_write->write_buf[to_write->written], to_write->write_buf_len - to_write->written, 0)) == -1) { if (conn->fd != -1) { if (_getdns_socketerror_wants_retry()) { (void) loop->vmt->schedule(loop, conn->fd, DOWNSTREAM_IDLE_TIMEOUT, &conn->event); return; } DEBUG_SERVER("I/O error from send(): %s\n", _getdns_errnostr()); } /* IO error, close connection */ tcp_connection_destroy(conn); return; } to_write->written += written; if (to_write->written == to_write->write_buf_len) { conn->to_write = to_write->next; GETDNS_FREE(*mf, to_write); } if (!conn->to_write) conn->event.write_cb = NULL; (void) loop->vmt->schedule(loop, conn->fd, DOWNSTREAM_IDLE_TIMEOUT, &conn->event); }
//////////////////////////////////////////////////////////////////////////// // MAIN //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// /// Main program. /// int main( int argc, char *argv[] ) { CvCapture *video; CvVideoWriter *writer; IplImage *frame; IplImage *hsv; char *win_name = "Source Frame"; char key = 0; tcp_connection *con; int frame_count = 0, result; int i; max_frames = 5000; unsigned char *byte_stream; // register signal handler for SIGINT und SIGPIPE // the latter occurs if the server terminates the connection /* DEBUG_PRINT( DEBUG_NOTE, "registering signal" ) if ( signal( SIGINT, sig_handler ) == SIG_ERR || signal( SIGPIPE, sig_handler ) == SIG_ERR ) { fprintf( stderr, "failed to register signal handler.\n" ); exit( 1 ); } */ parse_args( argc, argv ); // open the capture source switch ( source ) { case SOURCE_FILE: video = cvCreateFileCapture( infilename ); break; case SOURCE_CAM: video = cvCreateCameraCapture( camera ); break; default: fprintf( stderr, "strange source\n" ); exit( 1 ); } if ( !video ) { fprintf( stderr, "unable to capture source\n" ); exit( 1 ); } // connect to remote host con = tcp_connection_create( host, port ); if ( !con ) { fprintf( stderr, "unable to connect to %s, port %d\n", host, port ); exit( 1 ); } printf( "Connected to %s, port %d.\n", host, port ); frame = cvQueryFrame( video ); if ( !frame ) { fprintf( stderr, "unable to capture video.\n" ); exit( 1 ); } number_of_frames++; if ( netimage_send_header( con, frame ) <= 0 ) { fprintf( stderr, "unable to send header information.\n" ); exit( 1 ); } printf ( "Sending image stream (%d x %d, depth %u, %d channels (size: %d bytes)).\n" "Press 'q' to abort.\n", frame->width, frame->height, frame->depth, frame->nChannels, frame->imageSize ); // open capture file, if desired if ( output ) { strncat( outfilename, ".mpg", MAX_FILENAMELEN ); writer = cvCreateVideoWriter( outfilename, atofourcc( fourcc ), fps, cvSize( frame->width, frame->height ), frame->nChannels > 1 ? 1 : 0 ); if ( writer == NULL ) { fprintf( stderr, "unable to create output file '%s'\n", outfilename ); /* exit (1);*/ } else printf( "Writing to output file '%s'.\n", outfilename ); } // for fps measurement struct timeval current, last; unsigned int diff; // time difference in usecs int x0 = 0, y0 = 0, width = 0, height = 0; gettimeofday(&last, NULL); // show first frame for region selection //frame = cvQueryFrame( video ); //cvNamedWindow( win_name, 1 ); //cvShowImage( win_name, frame ); //if (output) // cvWriteFrame( writer, frame ); // get input region char* win_name2 = "First frame"; params p; CvRect* r; int x1, y1, x2, y2; int region[4]; /* use mouse callback to allow user to define object regions */ /*p.win_name = win_name2; p.orig_img = cvClone( frame ); p.cur_img = NULL; p.n = 0; cvNamedWindow( win_name2, 1 ); cvShowImage( win_name2, frame ); cvSetMouseCallback( win_name2, &mouse, &p ); printf("\nSelect Object and press [ENTER] !\n"); cvWaitKey( 0 ); cvDestroyWindow( win_name2 ); cvReleaseImage( &p.orig_img ); if( p.cur_img ) cvReleaseImage( &(p.cur_img) );*/ /* extract regions defined by user; store as an array of rectangles */ if( p.n > 0 ){ p.loc1[0].x = 0; p.loc1[0].y = 0; p.loc2[0].x = 0; p.loc2[0].y = 0; r = malloc( sizeof( CvRect ) ); x1 = MIN( p.loc1[0].x, p.loc2[0].x ); x2 = MAX( p.loc1[0].x, p.loc2[0].x ); y1 = MIN( p.loc1[0].y, p.loc2[0].y ); y2 = MAX( p.loc1[0].y, p.loc2[0].y ); width = x2 - x1; height = y2 - y1; /* ensure odd width and height */ width = ( width % 2 )? width : width+1; height = ( height % 2 )? height : height+1; r[0] = cvRect( x1, y1, width, height ); x0 = x1 + width/2; y0 = y1 + height/2; region[0] = x0; region[1] = y0; region[2] = width; region[3] = height; } //printf("\nx = %d\ny = %d\nwidth = %d\nheight = %d\n\n\n", x0, y0, width, height); // 1) convert bgr frame to hsv frame hsv = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 ); bgr2hsv(frame, hsv); result = tcp_send( con, hsv->imageData, hsv->imageSize); int counter = 1; //result = tcp_send( con, frame->imageData, frame->imageSize ); result = tcp_send( con, (char *) region, 4 * sizeof(int)); // confirm input with enter //printf("\nPress [ENTER]\n"); //cvWaitKey( 0 ); // TODO: send first frame + region data //result = tcp_send( con, frame->imageData, frame->imageSize); number_of_particles = 100; // create particles data array particles_data = (particle_data *) malloc ((number_of_particles+1) * sizeof(particle_data)); // quiet mode: no video output if (quiet){ cvDestroyWindow( win_name ); } // 1) send other frames // get video data and send/store it #ifdef STORE_VIDEO //while ( ( frame = cvQueryFrame( video ) ) && ( char ) key != 'q' && !quit && number_of_frames <= 221 ) { while ( ( frame = cvQueryFrame( video ) ) && ( char ) key != 'q' && counter < max_frames) { #else while ( ( frame = cvQueryFrame( video ) ) && ( char ) key != 'q' && counter < max_frames) { #endif // 1) convert bgr frame to hsv frame bgr2hsv(frame, hsv); result = tcp_send( con, hsv->imageData, hsv->imageSize ); //fprintf(stderr, "\n/////////////////// number of frames %d //////////////////////////////////////", number_of_frames); counter ++; //result = tcp_send( con, frame->imageData, frame->imageSize ); if ( result > 0 ) { if ( !quiet ) { cvNamedWindow( win_name, 1 ); #ifdef NO_VGA_FRAMEBUFFER #ifndef STORE_VIDEO if (number_of_frames > 2){ #else if (number_of_frames > 2 && number_of_frames % MAX_FRAMES == 0){ #endif // receive tcp package with particle data and display them in video // 1) receive tcp package with particles data //printf("\nreceive particles..."); result = tcp_receive( con, (unsigned char*)particles_data, ((number_of_particles+1) * sizeof(particle_data))); if ( result > 0 ) { // 2) draw particles data for (i=0; i<number_of_particles+1; i++){ // set OpenCV location points for bounding boxes loc1.x = ntohl(particles_data[i].x1); loc1.y = ntohl(particles_data[i].y1); loc2.x = ntohl(particles_data[i].x2); loc2.y = ntohl(particles_data[i].y2); particles_data[i].best_particle = ntohl(particles_data[i].best_particle); if (particles_data[i].best_particle > 0 ) particles_data[i].best_particle = TRUE; if (loc1.x <640 && loc2.x < 640 && loc1.y < 480 && loc2.y < 480) // draw bounding box (red for best particle, blue else) if (particles_data[i].best_particle == FALSE){ cvRectangle( frame, loc1, loc2, CV_RGB(0,0,255), 1, 8, 0 ); } else { cvRectangle( frame, loc1, loc2, CV_RGB(255,0,0), 1, 8, 0 ); } } } } #endif if (!quiet){ cvShowImage( win_name, frame ); //export_frame( frame, number_of_frames); key = cvWaitKey( 2 ); } } if ( output ) cvWriteFrame( writer, frame ); } else { printf( "connection lost.\n" ); break; } //gettimeofday(¤t, NULL); //diff = (current.tv_sec - last.tv_sec) * 1000000; //diff += (current.tv_usec - last.tv_usec); //fprintf(stderr, "FPS: %.2f\r", 1000000.0 / diff); //last.tv_sec = current.tv_sec; //last.tv_usec = current.tv_usec; number_of_frames++; } /* #ifdef STORE_VIDEO cvReleaseCapture( &video ); // 2) receive particle data and display particle data as Bounding Boxes switch ( source ) { case SOURCE_FILE: video = cvCreateFileCapture( infilename ); break; case SOURCE_CAM: fprintf( stderr, "This part is only possible if video is stored into a file\n" ); exit( 1 ); default: fprintf( stderr, "strange source\n" ); exit( 1 ); } particles_data = malloc ((number_of_particles+1) * sizeof(particle_data)); // get frames while ( ( frame = cvQueryFrame( video ) ) && ( char ) key != 'q' && !quit && number_of_frames <= 221 ) { // 1) receive tcp package with particles data // TODO result = tcp_receive( con, (char *)particles_data, ((number_of_particles+1) * sizeof(particle_data))); if ( result > 0 ) { // 2) draw particles data for (i=0; i<number_of_particles+1; i++){ // set OpenCV location points for bounding boxes loc1.x = particles_data[i].x1; loc1.y = particles_data[i].y1; loc2.x = particles_data[i].x2; loc2.y = particles_data[i].y2; // draw bounding box (red for best particle, blue else) if (particles_data[i].best_particle == TRUE){ cvRectangle( frame, loc1, loc2, CV_RGB(255,0,0), 1, 8, 0 ); } else { cvRectangle( frame, loc1, loc2, CV_RGB(0,0,255), 1, 8, 0 ); } } } // display video frame if (!quiet){ cvNamedWindow( win_name, 1 ); cvShowImage( win_name, frame ); key = cvWaitKey( 2 ); } number_of_frames++; } #endif */ // clean up if (!quiet){ cvDestroyWindow( win_name ); } cvReleaseCapture( &video ); if ( output ) cvReleaseVideoWriter( &writer ); tcp_connection_destroy( con ); return 0; } /* Mouse callback function that allows user to specify the initial object regions. Parameters are as specified in OpenCV documentation. */ void mouse( int event, int x, int y, int flags, void* param ) { params* p = (params*)param; CvPoint* loc; int n; IplImage* tmp; static int pressed = 0; /* on left button press, remember first corner of rectangle around object */ if( event == CV_EVENT_LBUTTONDOWN ) { n = p->n; if( n == 1 ) return; loc = p->loc1; loc[n].x = x; loc[n].y = y; pressed = 1; } /* on left button up, finalize the rectangle and draw it in black */ else if( event == CV_EVENT_LBUTTONUP ) { n = p->n; if( n == 1 ) return; loc = p->loc2; loc[n].x = x; loc[n].y = y; cvReleaseImage( &(p->cur_img) ); p->cur_img = NULL; cvRectangle( p->orig_img, p->loc1[n], loc[n], CV_RGB(0,0,0), 1, 8, 0 ); cvShowImage( p->win_name, p->orig_img ); pressed = 0; p->n++; } /* on mouse move with left button down, draw rectangle as defined in white */ else if( event == CV_EVENT_MOUSEMOVE && flags & CV_EVENT_FLAG_LBUTTON ) { n = p->n; if( n == 1 ) return; tmp = cvClone( p->orig_img ); loc = p->loc1; cvRectangle( tmp, loc[n], cvPoint(x, y), CV_RGB(255,255,255), 1, 8, 0 ); cvShowImage( p->win_name, tmp ); if( p->cur_img ) cvReleaseImage( &(p->cur_img) ); p->cur_img = tmp; } }
getdns_return_t getdns_reply(getdns_context *context, const getdns_dict *reply, getdns_transaction_t request_id) { /* TODO: Check request_id at context->outbound_requests */ connection *conn = (connection *)(intptr_t)request_id; struct mem_funcs *mf; getdns_eventloop *loop; uint8_t buf[65536]; size_t len; getdns_return_t r; if (!conn) return GETDNS_RETURN_INVALID_PARAMETER; if (!context || !context->server) { if (!context) context = conn->l->set->context; } else if (_getdns_rbtree_search(&context->server->connections_set, conn) != &conn->super) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; if (!reply) { _getdns_cancel_reply(context, conn); return GETDNS_RETURN_GOOD; } if (!(mf = &conn->l->set->context->mf)) return GETDNS_RETURN_GENERIC_ERROR;; if ((r = getdns_context_get_eventloop(conn->l->set->context, &loop))) return r; len = sizeof(buf); if ((r = getdns_msg_dict2wire_buf(reply, buf, &len))) return r; else if (conn->l->transport == GETDNS_TRANSPORT_UDP) { listener *l = conn->l; if (conn->l->fd >= 0 && sendto(conn->l->fd, (void *)buf, len, 0, (struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) { /* TODO: handle _getdns_socketerror_wants_retry() */ /* IO error, never cleanup a listener because of I/O error */ DEBUG_SERVER("I/O error from sendto(): %s\n", _getdns_errnostr()); } /* Unlink this connection */ (void) _getdns_rbtree_delete( &l->set->connections_set, conn); DEBUG_SERVER("[connection del] count: %d\n", (int)l->set->connections_set.count); if ((*conn->prev_next = conn->next)) conn->next->prev_next = conn->prev_next; GETDNS_FREE(*mf, conn); if (l->fd < 0) free_listen_set_when_done(l->set); } else if (conn->l->transport == GETDNS_TRANSPORT_TCP) { tcp_connection *conn = (tcp_connection *)(intptr_t)request_id; tcp_to_write **to_write_p; tcp_to_write *to_write; if (conn->fd == -1) { if (conn->to_answer > 0) --conn->to_answer; tcp_connection_destroy(conn); return GETDNS_RETURN_GOOD; } if (!(to_write = (tcp_to_write *)GETDNS_XMALLOC( *mf, uint8_t, sizeof(tcp_to_write) + len + 2))) { tcp_connection_destroy(conn); return GETDNS_RETURN_MEMORY_ERROR; } to_write->write_buf_len = len + 2; to_write->write_buf[0] = (len >> 8) & 0xFF; to_write->write_buf[1] = len & 0xFF; to_write->written = 0; to_write->next = NULL; (void) memcpy(to_write->write_buf + 2, buf, len); /* Append to_write to conn->to_write list */ for ( to_write_p = &conn->to_write ; *to_write_p ; to_write_p = &(*to_write_p)->next) ; /* pass */ *to_write_p = to_write; if (conn->to_answer > 0) conn->to_answer--; /* When event is scheduled, and doesn't have tcp_write_cb: * reschedule. */ if (conn->event.write_cb == NULL) { if (conn->event.ev) loop->vmt->clear(loop, &conn->event); conn->event.write_cb = tcp_write_cb; (void) loop->vmt->schedule(loop, conn->fd, DOWNSTREAM_IDLE_TIMEOUT, &conn->event); } }
//////////////////////////////////////////////////////////////////////////// // MAIN //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// /// Main program. /// int main( int argc, char *argv[] ) { CvCapture *video; CvVideoWriter *writer; IplImage *frame; char *win_name = "Source Frame"; char key = 0; tcp_connection *con; int frame_count = 0, result; // register signal handler for SIGINT und SIGPIPE // the latter occurs if the server terminates the connection /* DEBUG_PRINT( DEBUG_NOTE, "registering signal" ) if ( signal( SIGINT, sig_handler ) == SIG_ERR || signal( SIGPIPE, sig_handler ) == SIG_ERR ) { fprintf( stderr, "failed to register signal handler.\n" ); exit( 1 ); } */ parse_args( argc, argv ); // open the capture source switch ( source ) { case SOURCE_FILE: video = cvCreateFileCapture( infilename ); break; case SOURCE_CAM: video = cvCreateCameraCapture( camera ); break; default: fprintf( stderr, "strange source\n" ); exit( 1 ); } if ( !video ) { fprintf( stderr, "unable to capture source\n" ); exit( 1 ); } // connect to remote host con = tcp_connection_create( host, port ); if ( !con ) { fprintf( stderr, "unable to connect to %s, port %d\n", host, port ); exit( 1 ); } printf( "Connected to %s, port %d.\n", host, port ); frame = cvQueryFrame( video ); if ( !frame ) { fprintf( stderr, "unable to capture video.\n" ); exit( 1 ); } if ( netimage_send_header( con, frame ) <= 0 ) { fprintf( stderr, "unable to send header information.\n" ); exit( 1 ); } printf ( "Sending image stream (%d x %d, depth %u, %d channels (size: %d bytes)).\n" "Press 'q' to abort.\n", frame->width, frame->height, frame->depth, frame->nChannels, frame->imageSize ); // open capture file, if desired if ( output ) { strncat( outfilename, ".mpg", MAX_FILENAMELEN ); writer = cvCreateVideoWriter( outfilename, atofourcc( fourcc ), fps, cvSize( frame->width, frame->height ), frame->nChannels > 1 ? 1 : 0 ); if ( writer == NULL ) { fprintf( stderr, "unable to create output file '%s'\n", outfilename ); /* exit (1);*/ } else printf( "Writing to output file '%s'.\n", outfilename ); } // for fps measurement struct timeval current, last; unsigned int diff; // time difference in usecs gettimeofday(&last, NULL); // get video data and send/store it while ( ( frame = cvQueryFrame( video ) ) && ( char ) key != 'q' && !quit ) { result = tcp_send( con, frame->imageData, frame->imageSize ); if ( result > 0 ) { if ( !quiet ) { cvNamedWindow( win_name, 1 ); cvShowImage( win_name, frame ); key = cvWaitKey( 5 ); } if ( output ) cvWriteFrame( writer, frame ); } else { printf( "connection lost.\n" ); break; } gettimeofday(¤t, NULL); diff = (current.tv_sec - last.tv_sec) * 1000000; diff += (current.tv_usec - last.tv_usec); fprintf(stderr, "FPS: %.2f\r", 1000000.0 / diff); last.tv_sec = current.tv_sec; last.tv_usec = current.tv_usec; } // clean up cvDestroyWindow( win_name ); cvReleaseCapture( &video ); if ( output ) cvReleaseVideoWriter( &writer ); tcp_connection_destroy( con ); return 0; }