Re-write re-sync code

This commit is contained in:
Moritz Bunkus 2011-09-25 20:25:07 +02:00
parent 28a8829cb0
commit 9dd94101b1
3 changed files with 58 additions and 37 deletions

View File

@ -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<uint16_t>(p->pid_msb) << 8) | p->pid_lsb) & 0x1FFF)
#define CONTINUITY_COUNTER(p) (static_cast<unsigned char>(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<unsigned int>(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<unsigned int>(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<unsigned int>(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;
}

View File

@ -267,7 +267,7 @@ protected:
std::vector<mpeg_ts_track_ptr> tracks;
std::map<generic_packetizer_c *, mpeg_ts_track_ptr> 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;
};

View File

@ -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