From 9dd94101b1bf3383b7daa34fb335bca2fc74db15 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sun, 25 Sep 2011 20:25:07 +0200 Subject: [PATCH] Re-write re-sync code --- src/input/r_mpeg_ts.cpp | 89 +++++++++++++++++++++++++---------------- src/input/r_mpeg_ts.h | 4 +- tests/results.txt | 2 +- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/src/input/r_mpeg_ts.cpp b/src/input/r_mpeg_ts.cpp index 52b885047..5b9388ef1 100644 --- a/src/input/r_mpeg_ts.cpp +++ b/src/input/r_mpeg_ts.cpp @@ -43,6 +43,7 @@ namespace bfs = boost::filesystem; #define TS_PROBE_SIZE (2 * TS_CONSECUTIVE_PACKETS * 204) #define TS_PIDS_DETECT_SIZE 10 * 1024 * 1024 #define TS_PACKET_SIZE 188 +#define TS_MAX_PACKET_SIZE 204 #define GET_PID(p) (((static_cast(p->pid_msb) << 8) | p->pid_lsb) & 0x1FFF) #define CONTINUITY_COUNTER(p) (static_cast(p->continuity_counter) & 0x0F) @@ -393,6 +394,7 @@ mpeg_ts_reader_c::mpeg_ts_reader_c(track_info_c &_ti) , file_done(false) , m_packet_sent_to_packetizer(false) , m_dont_use_audio_pts(debugging_requested("mpeg_ts_dont_use_audio_pts")) + , m_debug_resync(debugging_requested("mpeg_ts_resync")) , m_detected_packet_size(0) { mm_io_cptr temp_io; @@ -421,28 +423,22 @@ mpeg_ts_reader_c::mpeg_ts_reader_c(track_info_c &_ti) PAT->type = PAT_TYPE; tracks.push_back(PAT); - unsigned char buf[205]; // maximum TS packet size + 1 - buf[0] = m_io->read_uint8(); + unsigned char buf[TS_MAX_PACKET_SIZE]; // maximum TS packet size + 1 bool done = m_io->eof(); while (!done) { + if (m_io->read(buf, m_detected_packet_size) != static_cast(m_detected_packet_size)) + break; - if (buf[0] == 0x47) { - m_io->read(buf + 1, m_detected_packet_size); - if (buf[m_detected_packet_size] != 0x47) { - m_io->skip(0 - m_detected_packet_size); - buf[0] = m_io->read_uint8(); + if (buf[0] != 0x47) { + if (resync(m_io->getFilePointer() - m_detected_packet_size)) continue; - } - parse_packet(buf); - done = PAT_found && PMT_found && (0 == es_to_process); - done |= m_io->eof() || (m_io->getFilePointer() >= TS_PIDS_DETECT_SIZE); - m_io->skip(-1); - - } else { - buf[0] = m_io->read_uint8(); // advance byte per byte to find a new sync - done |= m_io->eof() || (m_io->getFilePointer() >= TS_PIDS_DETECT_SIZE); + break; } + + parse_packet(buf); + done = PAT_found && PMT_found && (0 == es_to_process); + done |= m_io->eof() || (m_io->getFilePointer() >= TS_PIDS_DETECT_SIZE); } } catch (...) { } @@ -1153,31 +1149,21 @@ mpeg_ts_reader_c::read(generic_packetizer_c *requested_ptzr, return FILE_STATUS_HOLDING; } - unsigned char buf[205]; + unsigned char buf[TS_MAX_PACKET_SIZE + 1]; track_buffer_ready = -1; if (file_done) return flush_packetizers(); - buf[0] = m_io->read_uint8(); - while (true) { - if (m_io->eof()) + if (m_io->read(buf, m_detected_packet_size) != static_cast(m_detected_packet_size)) return finish(); if (buf[0] != 0x47) { - buf[0] = m_io->read_uint8(); // advance byte per byte to find a new sync - continue; - } - - if ((m_io->read(buf + 1, m_detected_packet_size) != (unsigned int)m_detected_packet_size) || m_io->eof()) + if (resync(m_io->getFilePointer() - m_detected_packet_size)) + continue; return finish(); - - if (buf[m_detected_packet_size] != 0x47) { - m_io->skip(0 - m_detected_packet_size); - buf[0] = m_io->read_uint8(); - continue; } parse_packet(buf); @@ -1187,11 +1173,8 @@ mpeg_ts_reader_c::read(generic_packetizer_c *requested_ptzr, track_buffer_ready = -1; } - if (!m_packet_sent_to_packetizer) - continue; - - m_io->skip(-1); - return FILE_STATUS_MOREDATA; + if (m_packet_sent_to_packetizer) + return FILE_STATUS_MOREDATA; } } @@ -1261,3 +1244,39 @@ mpeg_ts_reader_c::parse_clip_info_file() { } } } + +bool +mpeg_ts_reader_c::resync(int64_t start_at) { + try { + mxdebug_if(m_debug_resync, boost::format("Start resync for data from %1%\n") % start_at); + m_io->setFilePointer(start_at); + + unsigned char buf[TS_MAX_PACKET_SIZE + 1]; + + while (!m_io->eof()) { + int64_t curr_pos = m_io->getFilePointer(); + buf[0] = m_io->read_uint8(); + + if (0x47 != buf[0]) + continue; + + if (m_io->read(&buf[1], m_detected_packet_size) != static_cast(m_detected_packet_size)) + return false; + + if (0x47 != buf[m_detected_packet_size]) { + m_io->setFilePointer(curr_pos + 1); + continue; + } + + mxdebug_if(m_debug_resync, boost::format("Re-established at %1%\n") % curr_pos); + + m_io->setFilePointer(curr_pos); + return true; + } + + } catch (...) { + return false; + } + + return false; +} diff --git a/src/input/r_mpeg_ts.h b/src/input/r_mpeg_ts.h index 9ae50a9d7..7d49af91f 100644 --- a/src/input/r_mpeg_ts.h +++ b/src/input/r_mpeg_ts.h @@ -267,7 +267,7 @@ protected: std::vector tracks; std::map m_ptzr_to_track_map; - bool m_dont_use_audio_pts; + bool m_dont_use_audio_pts, m_debug_resync; int m_detected_packet_size; @@ -307,6 +307,8 @@ private: bfs::path find_clip_info_file(); void parse_clip_info_file(); + bool resync(int64_t start_at); + friend class mpeg_ts_track_c; }; diff --git a/tests/results.txt b/tests/results.txt index 96b0e8d3b..16f84a705 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -145,6 +145,6 @@ T_295vc1_rederiving_frame_types:b44ddb45845f897b986582c112e9ef1e-9864da369d9cb82 T_296video_frames_duration_0:5799836e2ff0742618d34a3e817f4c23:passed:20110709-143914:0.458765384 T_297mpeg_transport_streams:5bf7b0adead3cbcae2737b878842dd5e-68a51f8c5cdefcca641c13d7db50a853:passed:20110913-112636:10.706480253 T_298ts_language:9cdac29098316e9d9561598f55e5518e:passed:20110915-221140:10.526064317 -T_299ts_ghost_entries_in_pmt:fe936bcab0bcb678ec65a1f308c742ee:passed:20110917-004553:0.348880316 +T_299ts_ghost_entries_in_pmt:5716a012cd61366198ec92772fd216ea:passed:20110917-004553:0.348880316 T_300ts_dts_duplicate_timestamps:20dc3a1cefa6b222f637d50a8e5009b0:passed:20110918-154508:1.230918853 T_301ts_pgssub:288073767e64ed273d1c7f528c673d25:passed:20110918-154732:1.237027466