/* Returns: 0 = synced ok 1 = not synced, reconnect */ int mpeg_sync(INPUT *r, channel_source source_proto) { time_t sync_start = time(NULL); unsigned int sync_packets = 0; unsigned int read_bytes = 0; char syncframe[188]; int _timeout = TCP_READ_TIMEOUT; int _retries = TCP_READ_RETRIES; if (source_proto == udp_sock) { _timeout = UDP_READ_TIMEOUT; _retries = UDP_READ_RETRIES; } do { if (r->dienow) return 1; resync: if (fdread_ex(r->sock, syncframe, 1, _timeout, _retries, 1) != 1) { proxy_log(r, "mpeg_sync fdread() timeoutA"); return 1; // reconnect } // LOGf("DEBUG: Read 0x%02x Offset %u Sync: %u\n", (uint8_t)syncframe[0], read_bytes, sync_packets); read_bytes++; if (syncframe[0] == 0x47) { ssize_t rdsz = fdread_ex(r->sock, syncframe, 188-1, _timeout, _retries, 1); if (rdsz != 188-1) { proxy_log(r, "mpeg_sync fdread() timeoutB"); return 1; // reconnect } read_bytes += 188-1; if (++sync_packets == 7) // sync 7 packets break; goto resync; } else { sync_packets = 0; } if (read_bytes > FRAME_PACKET_SIZE) { // Can't sync in 1316 bytes proxy_log(r, "mpeg_sync can't sync after 1316 bytes"); return 1; // reconnect } if (sync_start+2 <= time(NULL)) { // Do not sync in two seconds proxy_log(r, "mpeg_sync can't sync in 2 seconds"); return 1; // reconnect } } while (1); if (read_bytes-FRAME_PACKET_SIZE != 0) LOGf("INPUT : [%-12s] TS synced after %u bytes\n", r->channel->id, read_bytes-FRAME_PACKET_SIZE); return 0; }
static int read_device_command_stream(struct videohub_data *d) { int ret, ncommands = 0; char buf[8192 + 1]; if (test_data) return 0; memset(buf, 0, sizeof(buf)); while ((ret = fdread_ex(d->dev_fd, buf, sizeof(buf) - 1, 5, 0, 1)) >= 0) { ncommands += parse_text_buffer(d, buf); memset(buf, 0, sizeof(buf)); } return ncommands; }
int main(int argc, char **argv) { ssize_t readen; int have_data = 1; int ntimeouts = 0; time_t timeout_start = time(NULL); int rtp_hdr_pos = 0, num_packets = 0; struct rlimit rl; if (getrlimit(RLIMIT_STACK, &rl) == 0) { if (rl.rlim_cur > THREAD_STACK_SIZE) { rl.rlim_cur = THREAD_STACK_SIZE; setrlimit(RLIMIT_STACK, &rl); } } memset(rtp_hdr[0], 0, RTP_HDR_SZ); memset(rtp_hdr[1], 0, RTP_HDR_SZ); data_init(&ts); ts_set_log_func(LOG_func); parse_options(&ts, argc, argv); if (ts.pidfile) daemonize(ts.pidfile); if (ts.syslog_active) { if (ts.syslog_remote) { log_init(ts.ident, 1, 1, ts.syslog_host, ts.syslog_port); remote_syslog = 1; } else { openlog(ts.ident, LOG_NDELAY | LOG_PID, LOG_USER); local_syslog = 1; } } ts.notify = notify_alloc(&ts); ts_LOGf("Start %s\n", program_id); notify(&ts, "START", "Starting %s", program_id); if (ts.input.type == NET_IO && udp_connect_input(&ts.input) < 1) goto EXIT; if (ts.output.type == NET_IO && udp_connect_output(&ts.output) < 1) goto EXIT; signal(SIGCHLD, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGINT , signal_quit); signal(SIGTERM, signal_quit); if (ts.threaded) { pthread_create(&ts.decode_thread, &ts.thread_attr, &decode_thread, &ts); pthread_create(&ts.write_thread , &ts.thread_attr, &write_thread , &ts); } ts.emm_last_report = time(NULL) + FIRST_REPORT_SEC; ts.ecm_last_report = time(NULL) + FIRST_REPORT_SEC; camd_start(&ts); if (packet_from_file) { uint8_t tmp[2048]; ts_hex_dump_buf((char *)tmp, sizeof(tmp), packet_buf, packet_buflen, 16); ts_LOGf("%s | Processing packet with CAID 0x%04x\n", packet_type == ECM_MSG ? "ECM" : "EMM", ts.forced_caid); ts_LOGf("%s | Packet dump:\n%s\n", packet_type == ECM_MSG ? "ECM" : "EMM", tmp); camd_process_packet(&ts, camd_msg_alloc(packet_type, ts.forced_caid, ts.forced_service_id, packet_buf, packet_buflen)); goto EXIT; } do { if (!ts.camd.constant_codeword) do_reports(&ts); if (ts.input.type == NET_IO) { set_log_io_errors(0); if (!ts.rtp_input) { readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE, 250, 4, 1); } else { readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE + RTP_HDR_SZ, 250, 4, 1); if (readen > RTP_HDR_SZ) { memcpy(rtp_hdr[rtp_hdr_pos], ts_packet, RTP_HDR_SZ); memmove(ts_packet, ts_packet + RTP_HDR_SZ, FRAME_SIZE); readen -= RTP_HDR_SZ; uint16_t ssrc = (rtp_hdr[rtp_hdr_pos][2] << 8) | rtp_hdr[rtp_hdr_pos][3]; uint16_t pssrc = (rtp_hdr[!rtp_hdr_pos][2] << 8) | rtp_hdr[!rtp_hdr_pos][3]; rtp_hdr_pos = !rtp_hdr_pos; if (pssrc + 1 != ssrc && (ssrc != 0 && pssrc != 0xffff) && num_packets > 2) if (ts.ts_discont) ts_LOGf("--- | RTP discontinuity last_ssrc %5d, curr_ssrc %5d, lost %d packet\n", pssrc, ssrc, ((ssrc - pssrc)-1) & 0xffff); num_packets++; } } set_log_io_errors(1); if (!keep_running) break; if (readen < 0) { ts_LOGf("--- | Input read timeout.\n"); if (!ntimeouts) { timeout_start = time(NULL); notify(&ts, "INPUT_TIMEOUT", "Read timeout on input %s://%s:%s/", ts.rtp_input ? "rtp" : "udp", ts.input.hostname, ts.input.service); } ts.no_input = 1; ntimeouts++; } else { if (ntimeouts && readen > 0) { time_t now = time(NULL); ts_LOGf("+++ | Input OK after %ld sec timeout.\n", (now - timeout_start) + 2); notify(&ts, "INPUT_OK", "Data is available on input %s://%s:%s/ after %ld seconds timeout.", ts.rtp_input ? "rtp" : "udp", ts.input.hostname, ts.input.service, (now - timeout_start) + 2); // Timeout is detected when ~2 seconds there is no incoming data ts.no_input = 0; ntimeouts = 0; } } } else { readen = read(ts.input.fd, ts_packet, FRAME_SIZE); have_data = !(readen <= 0); } if (readen > 0) { if (ts.input_dump_file) fwrite(ts_packet, readen, 1, ts.input_dump_file); process_packets(&ts, ts_packet, readen); } } while (have_data && keep_running); EXIT: camd_stop(&ts); // If pthread_join failes make sure we exit... signal(SIGINT , SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGALRM, signal_alarm); alarm(2); if (ts.threaded) { ts.decode_stop = 1; ts.write_stop = 1; if (ts.decode_thread) pthread_join(ts.decode_thread, NULL); if (ts.write_thread) pthread_join(ts.write_thread, NULL); } show_pid_report(&ts); notify_sync(&ts, "STOP", "Stopping %s", program_id); ts_LOGf("Stop %s\n", program_id); if (ts.syslog_active) { if (ts.syslog_remote) log_close(); else closelog(); } if (ts.input_dump_file) fclose(ts.input_dump_file); if (ts.pidfile) unlink(ts.pidfile); if (log_file) fclose(log_file); notify_free(&ts.notify); data_free(&ts); exit(EXIT_SUCCESS); }
ssize_t fdread_nowaitfull(int fd, char *buf, size_t buf_size) { return fdread_ex(fd, buf, buf_size, FDREAD_TIMEOUT, FDREAD_RETRIES, 0); }
ssize_t fdread(int fd, char *buf, size_t buf_size) { return fdread_ex(fd, buf, buf_size, FDREAD_TIMEOUT, FDREAD_RETRIES, 1); }