static THREAD_FUNC_PREFIX hdhomerun_dhcp_thread_execute(void *arg) { struct hdhomerun_dhcp_t *dhcp = (struct hdhomerun_dhcp_t *)arg; struct hdhomerun_pkt_t pkt_inst; while (1) { if (dhcp->terminate) { return NULL; } struct hdhomerun_pkt_t *pkt = &pkt_inst; hdhomerun_pkt_reset(pkt); int rx_length = recv(dhcp->sock, (char *)pkt->end, (int)(pkt->limit - pkt->end), 0); if (rx_length <= 0) { if (!sock_getlasterror_socktimeout) { sleep(1); } continue; } pkt->end += rx_length; hdhomerun_dhcp_recv(dhcp, pkt); } }
struct hdhomerun_pkt_t *hdhomerun_pkt_create(void) { struct hdhomerun_pkt_t *pkt = (struct hdhomerun_pkt_t *)calloc(1, sizeof(struct hdhomerun_pkt_t)); if (!pkt) { return NULL; } hdhomerun_pkt_reset(pkt); return pkt; }
static THREAD_FUNC_PREFIX hdhomerun_video_thread_execute(void *arg) { struct hdhomerun_video_sock_t *vs = (struct hdhomerun_video_sock_t *)arg; struct hdhomerun_pkt_t pkt_inst; while (!vs->terminate) { struct hdhomerun_pkt_t *pkt = &pkt_inst; hdhomerun_pkt_reset(pkt); /* Receive. */ int length = recv(vs->sock, (char *)pkt->end, VIDEO_RTP_DATA_PACKET_SIZE, 0); pkt->end += length; if (length == VIDEO_RTP_DATA_PACKET_SIZE) { hdhomerun_video_parse_rtp(vs, pkt); length = (int)(pkt->end - pkt->pos); } if (length != VIDEO_DATA_PACKET_SIZE) { if (length > 0) { /* Data received but not valid - ignore. */ continue; } if (sock_getlasterror_socktimeout) { /* Wait for more data. */ continue; } vs->terminate = TRUE; return NULL; } pthread_mutex_lock(&vs->lock); /* Store in ring buffer. */ size_t head = vs->head; uint8_t *ptr = vs->buffer + head; memcpy(ptr, pkt->pos, length); /* Stats. */ vs->packet_count++; hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 0); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 1); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 2); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 3); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 4); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 5); hdhomerun_video_stats_ts_pkt(vs, ptr + TS_PACKET_SIZE * 6); /* Calculate new head. */ head += length; if (head >= vs->buffer_size) { head -= vs->buffer_size; } /* Check for buffer overflow. */ if (head == vs->tail) { vs->overflow_error_count++; pthread_mutex_unlock(&vs->lock); continue; } /* Atomic update. */ vs->head = head; pthread_mutex_unlock(&vs->lock); } return NULL; }