/***************************************************************************** * handle_psi_packet *****************************************************************************/ static void handle_psi_packet(uint8_t *p_ts) { uint16_t i_pid = ts_get_pid(p_ts); ts_pid_t *p_pid = &p_pids[i_pid]; uint8_t i_cc = ts_get_cc(p_ts); const uint8_t *p_payload; uint8_t i_length; if (ts_check_duplicate(i_cc, p_pid->i_last_cc) || !ts_has_payload(p_ts)) return; if (p_pid->i_last_cc != -1 && ts_check_discontinuity(i_cc, p_pid->i_last_cc)) psi_assemble_reset(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used); p_payload = ts_section(p_ts); i_length = p_ts + TS_SIZE - p_payload; if (!psi_assemble_empty(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used)) { uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used, &p_payload, &i_length); if (p_section != NULL) handle_section(i_pid, p_section); } p_payload = ts_next_section( p_ts ); i_length = p_ts + TS_SIZE - p_payload; while (i_length) { uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used, &p_payload, &i_length); if (p_section != NULL) handle_section(i_pid, p_section); } }
int mediainfo (char *uri) { int i; struct sockaddr_in si_other; struct ip_mreq group; int s, slen = sizeof (si_other); char *server; int port; time_t start_time; if (strncmp (uri, "udp://", 6) != 0) { exit (1); } server = uri + 6; for (i = 6; i < strlen (uri); i++) { if (*(uri + i) == ':') { *(uri + i) = '\0'; } port = atoi (uri + i + 1); } if (i == strlen (uri)) { exit (1); } setvbuf(stdout, NULL, _IOLBF, 0); memset(p_pids, 0, sizeof(p_pids)); if ((s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { exit (1); } if (is_multicast (uri) == 1) { int reuse = 1; if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0){ perror("Setting SO_REUSEADDR error"); close(s); exit(1); } } memset ((char *)&si_other, 0, sizeof (si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons (port); if (is_multicast (uri) == 1) { si_other.sin_addr.s_addr = INADDR_ANY; } else { if (inet_aton (server, &si_other.sin_addr) == 0) { exit (1); } } if (bind (s, (struct sockaddr *)&si_other, sizeof (si_other)) == -1) { exit (1); } if (is_multicast (uri) == 1) { group.imr_multiaddr.s_addr = inet_addr(server); //group.imr_interface.s_addr = inet_addr("172.16.0.10"); if(setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0){ perror("Adding multicast group error"); close(s); exit(1); } } for (i = 0; i < 8192; i++) { p_pids[i].i_last_cc = -1; psi_assemble_init(&p_pids[i].p_psi_buffer, &p_pids[i].i_psi_buffer_used); } p_pids[PAT_PID].i_psi_refcount++; p_pids[TSDT_PID].i_psi_refcount++; p_pids[NIT_PID].i_psi_refcount++; p_pids[SDT_PID].i_psi_refcount++; psi_table_init(pp_current_pat_sections); psi_table_init(pp_next_pat_sections); psi_table_init(pp_current_tsdt_sections); psi_table_init(pp_next_tsdt_sections); psi_table_init(pp_current_nit_sections); psi_table_init(pp_next_nit_sections); psi_table_init(pp_current_sdt_sections); psi_table_init(pp_next_sdt_sections); for (i = 0; i < TABLE_END; i++) pb_print_table[i] = true; printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); printf("<TS>\n"); start_time = time (NULL); while (got_pmt == 0) { uint8_t p_ts[TS_SIZE*10]; uint8_t *p; size_t i_ret = recvfrom (s, p_ts, sizeof (p_ts), MSG_CMSG_CLOEXEC | MSG_DONTWAIT, (struct sockaddr *)&si_other, &slen); if (i_ret == -1) { usleep (10000); } p = p_ts; while (p < p_ts + i_ret) { if (!ts_validate(p)) { printf("<ERROR type=\"invalid_ts\"/>\n"); } else { uint16_t i_pid = ts_get_pid(p); ts_pid_t *p_pid = &p_pids[i_pid]; if (p_pid->i_psi_refcount) handle_psi_packet(p); p_pid->i_last_cc = ts_get_cc(p); } p = p + TS_SIZE; } if (difftime (time (NULL), start_time) > 60) { printf ("Timeout\n"); break; } } printf("</TS>\n"); if (iconv_handle != (iconv_t)-1) iconv_close(iconv_handle); psi_table_free(pp_current_pat_sections); psi_table_free(pp_next_pat_sections); psi_table_free(pp_current_tsdt_sections); psi_table_free(pp_next_tsdt_sections); psi_table_free(pp_current_nit_sections); psi_table_free(pp_next_nit_sections); psi_table_free(pp_current_sdt_sections); psi_table_free(pp_next_sdt_sections); for (i = 0; i < i_nb_sids; i++) { psi_table_free(pp_sids[i]->pp_eit_sections); free(pp_sids[i]->p_current_pmt); free(pp_sids[i]); } free(pp_sids); for (i = 0; i < 8192; i++) psi_assemble_reset(&p_pids[i].p_psi_buffer, &p_pids[i].i_psi_buffer_used); close (s); return EXIT_SUCCESS; }
int main(int i_argc, char **ppsz_argv) { int c; FILE *inputfile=stdin; FILE *outputfile=stdout; int offset=12, pid=0x0426; int i_last_cc = -1; static const struct option long_options[] = { { "pid", required_argument, NULL, 'p' }, { "offset", required_argument, NULL, 's' }, { "input", required_argument, NULL, 'i' }, { "output", required_argument, NULL, 'o' }, { 0, 0, 0, 0 } }; while ((c = getopt_long(i_argc, ppsz_argv, "p:s:i:o:h", long_options, NULL)) != -1) { switch (c) { case 'p': pid=strtoul(optarg, NULL, 0); if(pid >= 8192) { ERROR("bad pid value: %d!", pid); exit(1); } break; case 's': offset=strtol(optarg, NULL, 0); if(offset >= 184 || offset <= -4) { ERROR("bad offset value: %d!", offset); exit(1); } break; case 'i': inputfile = fopen(optarg, "r"); if(!inputfile) { ERROR("cant open input file!"); exit(1); } break; case 'o': outputfile = fopen(optarg, "w"); if(!outputfile) { ERROR("cant open output file!"); exit(1); } break; case 'h': default: usage(ppsz_argv[0]); } } INFO("Using pid: 0x%04x (%d)", pid, pid); unsigned long int packets=0; while (!feof(inputfile) && !ferror(inputfile)) { uint8_t p_ts[TS_SIZE]; size_t i_ret = fread(p_ts, TS_SIZE, 1, inputfile); if (i_ret != 1) { WARN("Can't read input ts"); break; } if (ts_validate(p_ts)) { if(offset >= 0 && ts_get_pid(p_ts)==pid) { if(i_last_cc > 0 && (0x0f & (i_last_cc+1)) != ts_get_cc(p_ts)) { WARN("TS Discontinuity"); } i_last_cc = ts_get_cc(p_ts); uint8_t *payload = ts_payload(p_ts); if(offset) { payload+=offset; } if(p_ts+TS_SIZE < payload) { ERROR("payload is out of ts by %ld bytes", payload-p_ts+TS_SIZE); break; } size_t o_ret = fwrite(payload, p_ts+TS_SIZE-payload, 1, outputfile); if (o_ret != 1) { WARN("Can't write output ts"); break; } packets++; } else if(offset < 0) { uint8_t *payload = &p_ts[TS_HEADER_SIZE + offset]; if(p_ts+TS_SIZE < payload || p_ts > payload) { ERROR("payload is out of ts by %ld bytes", payload-p_ts+TS_SIZE); break; } size_t o_ret = fwrite(payload, p_ts+TS_SIZE-payload, 1, outputfile); if (o_ret != 1) { WARN("Can't write output ts"); break; } packets++; } } else { do { memmove(p_ts, &p_ts[1], TS_SIZE-1); size_t i_ret = fread(&p_ts[TS_SIZE-1], 1, 1, inputfile); if (i_ret != 1) { WARN("Can't read input ts"); break; } } while (!ts_validate(p_ts) && !feof(inputfile) && !ferror(inputfile)); } } if(packets){ INFO("Successfuly readed %ld ts-packets", packets); } //mainErr: fclose(inputfile); fclose(outputfile); return 0; }