diff --git a/src/lib_ccx/ccx_demuxer.c b/src/lib_ccx/ccx_demuxer.c index 25d192a1..a6c79b63 100644 --- a/src/lib_ccx/ccx_demuxer.c +++ b/src/lib_ccx/ccx_demuxer.c @@ -8,9 +8,11 @@ static void ccx_demuxer_reset(struct ccx_demuxer *ctx) { ctx->startbytes_pos=0; ctx->startbytes_avail=0; + ctx->num_of_PIDs = 0; + memset(ctx->have_PIDs, -1, (MAX_PSI_PID + 1) * sizeof(int)); memset (ctx->PIDs_seen, 0, 65536*sizeof (int)); - memset(ctx->min_pts, UINT64_MAX, MAX_PID * sizeof(uint64_t)); - memset(ctx->stream_id_of_each_pid, 0, MAX_PID * sizeof(uint8_t)); + memset(ctx->min_pts, UINT64_MAX, (MAX_PSI_PID + 1) * sizeof(uint64_t)); + memset(ctx->stream_id_of_each_pid, 0, (MAX_PSI_PID + 1) * sizeof(uint8_t)); memset (ctx->PIDs_programs, 0, 65536*sizeof (struct PMT_entry *)); } diff --git a/src/lib_ccx/ccx_demuxer.h b/src/lib_ccx/ccx_demuxer.h index 90804866..9acfe234 100644 --- a/src/lib_ccx/ccx_demuxer.h +++ b/src/lib_ccx/ccx_demuxer.h @@ -46,6 +46,7 @@ struct program_info */ int16_t pcr_pid; uint64_t got_important_streams_min_pts[COUNT]; + int has_all_min_pts; }; struct cap_info @@ -123,8 +124,10 @@ struct ccx_demuxer (stream ids range from 0xbd to 0xef so 0xef - 0xbd + 1 = 51)*/ //uint8_t found_stream_ids[MAX_NUM_OF_STREAMIDS]; - uint8_t stream_id_of_each_pid[MAX_PID]; - uint64_t min_pts[MAX_PID]; + uint8_t stream_id_of_each_pid[MAX_PSI_PID + 1]; + uint64_t min_pts[MAX_PSI_PID + 1]; + int have_PIDs[MAX_PSI_PID + 1]; + int num_of_PIDs; struct PMT_entry *PIDs_programs[MAX_PID]; struct ccx_demux_report freport; diff --git a/src/lib_ccx/ts_functions.c b/src/lib_ccx/ts_functions.c index 2c0d2829..c5959350 100644 --- a/src/lib_ccx/ts_functions.c +++ b/src/lib_ccx/ts_functions.c @@ -810,28 +810,6 @@ long ts_readstream(struct ccx_demuxer *ctx, struct demuxer_data **data) continue; } - //PTS calculation - if (payload.pesstart) //if there is PES Header data in the payload and we didn't get the first pts of that stream - { - if (ctx->min_pts[payload.pid] == UINT64_MAX) //check if we don't have the min_pts of that packet's pid - { - // Packetized Elementary Stream (PES) 32-bit start code - uint64_t pes_prefix = (payload.start[0] << 16) | (payload.start[1] << 8) | payload.start[2]; - uint8_t pes_stream_id = payload.start[3]; - - uint64_t pts = 0; - - // check for PES header - if (pes_prefix == 0x000001) - { - pts = get_pts(payload.start); - //keep in mind we already checked if we have this stream id - ctx->stream_id_of_each_pid[payload.pid] = pes_stream_id; - ctx->min_pts[payload.pid] = pts; //and add its packet pts - } - } - } - switch (ctx->PIDs_seen[payload.pid]) { case 0: // First time we see this PID @@ -847,6 +825,8 @@ long ts_readstream(struct ccx_demuxer *ctx, struct demuxer_data **data) dbg_print(CCX_DMT_PARSE, "\nNew PID found: %u, program number still unknown\n", payload.pid); ctx->PIDs_seen[payload.pid]=1; } + ctx->have_PIDs[ctx->num_of_PIDs] = payload.pid; + ctx->num_of_PIDs++; break; case 1: // Saw it before but we didn't know what program it belonged to. Luckier now? if (ctx->PIDs_programs[payload.pid]) @@ -864,6 +844,31 @@ long ts_readstream(struct ccx_demuxer *ctx, struct demuxer_data **data) break; } + //PTS calculation + if (payload.pesstart) //if there is PES Header data in the payload and we didn't get the first pts of that stream + { + // Packetized Elementary Stream (PES) 32-bit start code + uint64_t pes_prefix = (payload.start[0] << 16) | (payload.start[1] << 8) | payload.start[2]; + uint8_t pes_stream_id = payload.start[3]; + + uint64_t pts = 0; + + // check for PES header + if (pes_prefix == 0x000001) + { + pts = get_pts(payload.start); + //keep in mind we already checked if we have this stream id + //we find the index of the packet PID in the have_PIDs array + int pid_index; + for (int i = 0; i < ctx->num_of_PIDs; i++) + if (payload.pid == ctx->have_PIDs[i]) + pid_index = i; + ctx->stream_id_of_each_pid[pid_index] = pes_stream_id; + if (pts < ctx->min_pts[pid_index]) + ctx->min_pts[pid_index] = pts; //and add its packet pts + } + } + if (payload.pid==1003 && !ctx->hauppauge_warning_shown && !ccx_options.hauppauge_mode) { // TODO: Change this very weak test for something more decent such as size. @@ -984,23 +989,30 @@ long ts_readstream(struct ccx_demuxer *ctx, struct demuxer_data **data) for (int i = 0; i < ctx->nb_program; i++) { pinfo = &ctx->pinfo[i]; - for (int j = 0; j < MAX_PID; j++) + if (!pinfo->has_all_min_pts) { - if (ctx->PIDs_programs[j]) + for (int j = 0; j < ctx->num_of_PIDs; j++) { - if (ctx->PIDs_programs[j]->program_number == pinfo->program_number) + if (ctx->PIDs_programs[ctx->have_PIDs[j]]) { - if (ctx->min_pts[j] != UINT64_MAX) + if (ctx->PIDs_programs[ctx->have_PIDs[j]]->program_number == pinfo->program_number) { - if (ctx->stream_id_of_each_pid[j] == 0xbd) - if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[PRIVATE_STREAM_1]) - pinfo->got_important_streams_min_pts[PRIVATE_STREAM_1] = ctx->min_pts[j]; - if (ctx->stream_id_of_each_pid[j] >= 0xc0 && ctx->stream_id_of_each_pid[j] <= 0xdf) - if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[AUDIO]) - pinfo->got_important_streams_min_pts[AUDIO] = ctx->min_pts[j]; - if (ctx->stream_id_of_each_pid[j] >= 0xe0 && ctx->stream_id_of_each_pid[j] <= 0xef) - if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[VIDEO]) - pinfo->got_important_streams_min_pts[VIDEO] = ctx->min_pts[j]; + if (ctx->min_pts[j] != UINT64_MAX) + { + if (ctx->stream_id_of_each_pid[j] == 0xbd) + if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[PRIVATE_STREAM_1]) + pinfo->got_important_streams_min_pts[PRIVATE_STREAM_1] = ctx->min_pts[j]; + if (ctx->stream_id_of_each_pid[j] >= 0xc0 && ctx->stream_id_of_each_pid[j] <= 0xdf) + if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[AUDIO]) + pinfo->got_important_streams_min_pts[AUDIO] = ctx->min_pts[j]; + if (ctx->stream_id_of_each_pid[j] >= 0xe0 && ctx->stream_id_of_each_pid[j] <= 0xef) + if (ctx->min_pts[j] < pinfo->got_important_streams_min_pts[VIDEO]) + pinfo->got_important_streams_min_pts[VIDEO] = ctx->min_pts[j]; + if (pinfo->got_important_streams_min_pts[PRIVATE_STREAM_1] != UINT64_MAX && + pinfo->got_important_streams_min_pts[AUDIO] != UINT64_MAX && + pinfo->got_important_streams_min_pts[VIDEO] != UINT64_MAX) + pinfo->has_all_min_pts = 1; + } } } } diff --git a/src/lib_ccx/ts_tables.c b/src/lib_ccx/ts_tables.c index 1bd83cd0..3639bed4 100644 --- a/src/lib_ccx/ts_tables.c +++ b/src/lib_ccx/ts_tables.c @@ -74,7 +74,8 @@ int update_pinfo(struct ccx_demuxer *ctx, int pid, int program_number) ctx->pinfo[ctx->nb_program].analysed_PMT_once = CCX_FALSE; ctx->pinfo[ctx->nb_program].name[0] = '\0'; ctx->pinfo[ctx->nb_program].pcr_pid = -1; - memset(ctx->pinfo[ctx->nb_program].got_important_streams_min_pts, UINT64_MAX, 3 * sizeof(uint64_t)); + ctx->pinfo[ctx->nb_program].has_all_min_pts = 0; + memset(ctx->pinfo[ctx->nb_program].got_important_streams_min_pts, UINT64_MAX, COUNT * sizeof(uint64_t)); ctx->nb_program++; return CCX_OK;