void* processing_routine(void* args) { //decoded video frame that will be pulled from the queue jakopter_video_frame_t frame; //wait for frames to be decoded, and then process them. pthread_mutex_lock(&mutex_stopped); while(!stopped) { pthread_mutex_unlock(&mutex_stopped); if(video_queue_pull_frame(&frame) < 0) { fprintf(stderr, "[Video Processing] Error retrieving frame !\n"); video_set_stopped(); } //a 0-sized frame means we're about to quit. else if(frame.size != 0) if(frame_processing_callback(frame.pixels, frame.w, frame.h, frame.size) < 0) { fprintf(stderr, "[Video Processing] Error processing frame !\n"); video_set_stopped(); } pthread_mutex_lock(&mutex_stopped); } pthread_mutex_unlock(&mutex_stopped); //free the resources of the processing module if(frame_processing_clean != NULL) frame_processing_clean(); pthread_exit(NULL); }
//cette fonction est un thread, ne pas l'appeler ! void* video_routine(void* args) { ssize_t pack_size = 0; int nb_img = 0; pthread_mutex_lock(&mutex_stopped); while(!stopped) { pthread_mutex_unlock(&mutex_stopped); //Wait for the drone to send data on the video socket if (select(sock_video+1, &vid_fd_set, NULL, NULL, &video_timeout) < 0) { perror("Error select()"); video_set_stopped(); } else if(FD_ISSET(sock_video, &vid_fd_set)) { /*receive the video data from the drone. Only BASE_SIZE, since TCP_SIZE may be larger on purpose.*/ pack_size = recv(sock_video, tcp_buf, BASE_VIDEO_BUF_SIZE, 0); if(pack_size == 0) { printf("Stream ended by server. Ending the video thread.\n"); video_set_stopped(); } else if(pack_size < 0) perror("Error recv()"); else { //we actually got some data, send it for decoding ! nb_img = video_decode_packet(tcp_buf, pack_size); if(nb_img < 0) { fprintf(stderr, "Error processing frame !\n"); video_set_stopped(); } } } else { printf("Video : data reception has timed out. Ending the video thread now.\n"); video_set_stopped(); } //reset the timeout and the FDSET entry video_timeout.tv_sec = VIDEO_TIMEOUT; FD_ZERO(&vid_fd_set); FD_SET(sock_video, &vid_fd_set); pthread_mutex_lock(&mutex_stopped); } pthread_mutex_unlock(&mutex_stopped); //there's no reason to keep stuff that's needed for our video thread once it's ended, so clean it now. video_clean(); pthread_mutex_lock(&mutex_terminated); terminated = 1; printf("Video thread terminated.\n"); pthread_mutex_unlock(&mutex_terminated); pthread_exit(NULL); }
/* End the video thread and clean the required structures */ int jakopter_stop_video() { if(video_set_stopped()) { fprintf(stderr, "Video thread is already shut down.\n"); return -1; } else return 0; }
/* * Ask the thread to stop with set_stopped, then * call join_thread, print a message if the thread has already ended. * \return -1 on error, 0 otherwise. */ int jakopter_stop_video() { video_set_stopped(); int exit_status = video_join_thread(); if(exit_status == 1) fprintf(stderr, "Video thread is already shut down.\n"); else if(exit_status < 0) return -1; return 0; }
void* video_routine(void* args) { //TCP segment of encoded video received from the drone static uint8_t tcp_buf[TCP_VIDEO_BUF_SIZE]; //size of this segment in bytes ssize_t pack_size = 0; //set to 1 by the decoding function if a decoded video frame is available int got_frame = 0; //structure that will hold our latest decoded video frame jakopter_video_frame_t decoded_frame; pthread_mutex_lock(&mutex_stopped); while(!stopped) { pthread_mutex_unlock(&mutex_stopped); //Wait for the drone to send data on the video socket if (select(sock_video+1, &vid_fd_set, NULL, NULL, &video_timeout) < 0) { perror("Error select()"); video_set_stopped(); } else if(FD_ISSET(sock_video, &vid_fd_set)) { /*receive the video data from the drone. Only BASE_SIZE, since TCP_SIZE may be larger on purpose.*/ pack_size = recv(sock_video, tcp_buf, BASE_VIDEO_BUF_SIZE, 0); if(pack_size == 0) { printf("Stream ended by server. Ending the video thread.\n"); video_set_stopped(); } else if(pack_size < 0) perror("Error recv()"); else { //we actually got some data, send it for decoding ! got_frame = video_decode_packet(tcp_buf, pack_size, &decoded_frame); if(got_frame < 0) { fprintf(stderr, "Error decoding video !\n"); video_set_stopped(); } //if we have a complete decoded frame, push it onto the queue for decoding else if(got_frame == 1) video_queue_push_frame(&decoded_frame); } } else { printf("Video : data reception has timed out. Ending the video thread now.\n"); video_set_stopped(); } //reset the timeout and the FDSET entry video_timeout.tv_sec = VIDEO_TIMEOUT; FD_ZERO(&vid_fd_set); FD_SET(sock_video, &vid_fd_set); pthread_mutex_lock(&mutex_stopped); } pthread_mutex_unlock(&mutex_stopped); /*push an empty frame on the queue so the processing thread knows it has to stop*/ video_queue_push_frame(&VIDEO_QUEUE_END); pthread_join(processing_thread, NULL); //there's no reason to keep stuff that's needed for our video thread once it's ended, so clean it now. video_clean(); pthread_exit(NULL); }