/***************************************************************************** * section_demux.c: Prints sections from a TS file ***************************************************************************** *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include /***************************************************************************** * Local declarations *****************************************************************************/ #define MAX_PIDS 8192 #define READ_ONCE 7 typedef struct ts_pid_t { int i_psi_refcount; int8_t i_last_cc; /* biTStream PSI section gathering */ uint8_t *p_psi_buffer; uint16_t i_psi_buffer_used; } ts_pid_t; static ts_pid_t p_pids[MAX_PIDS]; static uint8_t i_want_table_id = 0; static uint16_t i_want_pid = 0; /***************************************************************************** * handle_section *****************************************************************************/ static void handle_section(uint16_t i_pid, uint8_t *p_section) { uint8_t i_table_id = psi_get_tableid(p_section); if (!psi_validate(p_section)) { printf("invalid section on PID %hu\n", i_pid); free(p_section); return; } // if(i_table_id == i_want_table_id){ // printf("Wanted section: T<%02x>P<%04x> -> %02x %02x %02x %02x\n", i_table_id, i_pid, p_section[0], p_section[1], // p_section[2], p_section[3]); // } if (i_pid == i_want_pid && i_table_id == i_want_table_id) { // This is the section I want; printf("Wanted section: T<%02x>P<%04x> -> %02x %02x %02x %02x\n", i_table_id, i_pid, p_section[0], p_section[1], p_section[2], p_section[3]); // Call SW_S32 Minitor_DataRevc(SW_U8 *data_p, SW_S8 slot,SW_U32 markid) here !!! } else { // printf("Ignored section: T<%02x>P<%04x> -> %02x %02x %02x %02x\n", i_table_id, i_pid, p_section[0], p_section[1], // p_section[2], p_section[3]); } } /***************************************************************************** * 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; // printf("handle_psi_packet:> %02x %02x %02x %02x\n",p_ts[0],p_ts[1],p_ts[2],p_ts[3]); 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); } } /***************************************************************************** * Main loop *****************************************************************************/ static void usage(const char *psz) { fprintf(stderr, "usage: %s < [> ]\n", psz); exit(EXIT_FAILURE); } int main(int i_argc, char **ppsz_argv) { int i, c; // Set wanted tableId and pId // SW_ERROR Minitor_SendDataReq(SW_U32 mustsend,SW_U32 pid,SW_U32 table,SW_U32 prog, SW_U32 trick) i_want_pid = 0x0021; i_want_table_id = 0xfe; static const struct option long_options[] = { {"table_id", required_argument, NULL, 't'}, {"pid", required_argument, NULL, 'p'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0} }; while ((c = getopt_long(i_argc, ppsz_argv, "t:hVp:", long_options, NULL)) != -1) { switch (c) { case 't': //TODO: Get wanted tableId via args... break; case 'p': //TODO: Get wanted pId via args... break; case 'V': fprintf(stderr, "biTStream %d.%d.%d\n", BITSTREAM_VERSION_MAJOR, BITSTREAM_VERSION_MINOR, BITSTREAM_VERSION_REVISION); exit(0); break; case 'h': default: usage(ppsz_argv[0]); } } if (optind < i_argc) usage(ppsz_argv[0]); setvbuf(stdout, NULL, _IOLBF, 0); memset(p_pids, 0, sizeof(p_pids)); 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); } bool b_is_last_invalid = false; while (!feof(stdin) && !ferror(stdin)) { uint8_t p_ts[TS_SIZE]; size_t i_ret = fread(p_ts, sizeof(p_ts), 1, stdin); if (i_ret != 1) continue; if (!ts_validate(p_ts)) { if (!b_is_last_invalid) { printf("invalid TS packet\n"); b_is_last_invalid = true; } int i; for (i = 1; i < TS_SIZE; i++) { if (ts_validate(p_ts + i)) { memmove(p_ts, p_ts + i, TS_SIZE - i); i_ret = fread(p_ts + TS_SIZE - i, i, 1, stdin); if (i_ret != 1) continue; break; } } if (i == TS_SIZE) continue; } uint16_t i_pid = ts_get_pid(p_ts); ts_pid_t *p_pid = &p_pids[i_pid]; // if (p_pid->i_psi_refcount) handle_psi_packet(p_ts); p_pid->i_last_cc = ts_get_cc(p_ts); b_is_last_invalid = false; } return EXIT_SUCCESS; }