/* This is the receiver thread that runs continuously to retrieve any incoming * LCM packets from the network and queues them locally. */ static void * recv_thread (void * user) { #ifdef G_OS_UNIX // Mask out all signals on this thread. sigset_t mask; sigfillset(&mask); pthread_sigmask(SIG_SETMASK, &mask, NULL); #endif lcm_udpm_t * lcm = (lcm_udpm_t *) user; while (1) { lcm_buf_t *lcmb = udp_read_packet(lcm); if (!lcmb) break; /* If necessary, notify the reading thread by writing to a pipe. We * only want one character in the pipe at a time to avoid blocking * writes, so we only do this when the queue transitions from empty to * non-empty. */ g_static_rec_mutex_lock (&lcm->mutex); if (lcm_buf_queue_is_empty (lcm->inbufs_filled)) if (lcm_internal_pipe_write(lcm->notify_pipe[1], "+", 1) < 0) perror ("write to notify"); /* Queue the packet for future retrieval by lcm_handle (). */ lcm_buf_enqueue (lcm->inbufs_filled, lcmb); g_static_rec_mutex_unlock (&lcm->mutex); } dbg (DBG_LCM, "read thread exiting\n"); return NULL; }
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; int ret, len; uint8_t buf[RTP_MAX_PACKET_LENGTH]; /* get next frames from the same RTP packet */ if (rt->cur_rtp) { ret = rtp_parse_packet(rt->cur_rtp, pkt, NULL, 0); if (ret == 0) { rt->cur_rtp = NULL; return 0; } else if (ret == 1) { return 0; } else { rt->cur_rtp = NULL; } } /* read next RTP packet */ redo: switch(rt->protocol) { default: case RTSP_PROTOCOL_RTP_TCP: len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf)); break; case RTSP_PROTOCOL_RTP_UDP: case RTSP_PROTOCOL_RTP_UDP_MULTICAST: len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf)); if (len >=0 && rtsp_st->rtp_ctx) rtp_check_and_send_back_rr(rtsp_st->rtp_ctx, len); break; } if (len < 0) return len; ret = rtp_parse_packet(rtsp_st->rtp_ctx, pkt, buf, len); if (ret < 0) goto redo; if (ret == 1) { /* more packets may follow, so we save the RTP context */ rt->cur_rtp = rtsp_st->rtp_ctx; } return 0; }