From 89d110df542204a384916db773acd2d19cb0542a Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 6 Mar 2006 12:13:05 +0000 Subject: [PATCH 1/1] moved PID search to proper please, simplified a bit (using the first found PMT should be ok) --- lib/dvb/pmt.cpp | 107 ++++++++++---------------------------------- lib/dvb/pmt.h | 2 + lib/dvb/tstools.cpp | 72 ++++++++++++++++++++++++++++- lib/dvb/tstools.h | 1 + 4 files changed, 97 insertions(+), 85 deletions(-) diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 4ce35394..c0670111 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -15,6 +15,7 @@ eDVBServicePMTHandler::eDVBServicePMTHandler() :m_ca_servicePtr(0), m_decode_demux_num(0xFF) { m_use_decode_demux = 0; + m_pmt_pid = -1; eDVBResourceManager::getInstance(m_resourceManager); CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready); CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready); @@ -43,7 +44,10 @@ void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel) { eDebug("ok ... now we start!!"); - m_PAT.begin(eApp, eDVBPATSpec(), m_demux); + if (m_pmt_pid == -1) + m_PAT.begin(eApp, eDVBPATSpec(), m_demux); + else + m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux); if ( m_service && !m_service->cacheEmpty() ) serviceEvent(eventNewProgramInfo); @@ -122,84 +126,6 @@ void eDVBServicePMTHandler::PATready(int) if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID()) pmtpid = (*program)->getProgramMapPid(); } - if (pmtpid == -1) - { - if ( m_reference.path.find(".ts") != std::string::npos ) // recorded ts - { - // we try to find manual the correct sid - int fd = open( m_reference.path.c_str(), O_RDONLY|O_LARGEFILE ); - if ( fd < 0 ) - eDebug("open %s failed"); - else - { - eDebug("parse ts file for find the correct pmtpid"); - unsigned char *buf = new unsigned char[256*1024]; // 256 kbyte - int rd=0; - while ( pmtpid == -1 && (rd < 1024*1024*5) ) - { -#define MAX_PIDS 64 - int pids[MAX_PIDS]; - int pididx=-1; - int r = ::read( fd, buf, 256*1024 ); - if ( r <= 0 ) - break; - rd+=r; - int cnt=0; - while(cnt < r) - { - while ( (buf[cnt] != 0x47) && ((cnt+188) < r) && (buf[cnt+188] != 0x47) ) - { -// eDebug("search sync byte %02x %02x, %d %d", buf[cnt], buf[cnt+188], cnt+188, r); - cnt++; - } - if ( buf[cnt] == 0x47 ) - { - int pid = ((buf[cnt+1]&0x3F) << 8) | buf[cnt+2]; - int idx=0; - while(idx <= pididx) // check if we already have this pid - { - if ( pids[idx] == pid ) - break; - ++idx; - } - if (idx > pididx && (pididx+1) < MAX_PIDS) - { - eDebug("found pid %04x", pid); - pids[++pididx]=pid; - } - cnt+=188; - } - else - break; - } - while(pididx > -1 && pmtpid == -1) - { - for (i = ptr->getSections().begin(); i != ptr->getSections().end() && pmtpid == -1; ++i) - { - const ProgramAssociationSection &pat = **i; - ProgramAssociationConstIterator program; - for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program) - { - int pid = (*program)->getProgramMapPid(); - if ( pid == pids[pididx]) - { - int sid = (*program)->getProgramNumber(); - pmtpid = pid; - m_reference.setServiceID(eServiceID(sid)); - eDebug("found pmt for service id %04x with pid %04x", sid, pid); - break; - } - } - } - --pididx; - } - } - delete [] buf; - close(fd); - } - } - } - if (pmtpid == -1) serviceEvent(eventNoPATEntry); else @@ -460,12 +386,25 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eDVBMetaParser parser; if (parser.parseFile(ref.path)) - eWarning("no .meta file found, trying original service ref."); - else + { + eWarning("no .meta file found, trying to find PMT pid"); + eDVBTSTools tstools; + if (tstools.openFile(ref.path.c_str())) + eWarning("failed to open file"); + else + { + int service_id, pmt_pid; + if (!tstools.findPMT(pmt_pid, service_id)) + { + eDebug("PMT pid found on pid %04x, service id %d", pmt_pid, service_id); + m_reference.setServiceID(service_id); + m_pmt_pid = pmt_pid; + } + } + + } else m_reference = parser.m_ref; - -// eDebug("try %s", m_reference.toString().c_str()); - + eDebug("alloc PVR"); /* allocate PVR */ res = m_resourceManager->allocatePVRChannel(m_pvr_channel); diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index b7115ae2..79d7917c 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -128,6 +128,8 @@ public: int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0); void free(); + + int m_pmt_pid; }; #endif diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index 34edbc9e..4dab5294 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -64,7 +64,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) if (m_use_streaminfo) return m_streaminfo.getPTS(offset, pts); - if (!m_file.valid() < 0) + if (!m_file.valid()) return -1; offset -= offset % 188; @@ -344,3 +344,73 @@ void eDVBTSTools::takeSamples() m_samples[m_pts_end] = m_offset_end; // eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); } + +int eDVBTSTools::findPMT(int &pmt_pid, int &service_id) +{ + /* FIXME: this will be factored out soon! */ + if (!m_file.valid()) + { + eDebug(" file not valid"); + return -1; + } + + if (m_file.lseek(0, SEEK_SET) < 0) + { + eDebug("seek failed"); + return -1; + } + + int left = 5*1024*1024; + + while (left >= 188) + { + unsigned char block[188]; + if (m_file.read(block, 188) != 188) + { + eDebug("read error"); + break; + } + left -= 188; + + if (block[0] != 0x47) + { + int i = 0; + while (i < 188) + { + if (block[i] == 0x47) + break; + ++i; + } + m_file.lseek(i - 188, SEEK_CUR); + continue; + } + + int pid = ((block[1] << 8) | block[2]) & 0x1FFF; + + int pusi = !!(block[1] & 0x40); + + if (!pusi) + continue; + + /* ok, now we have a PES header or section header*/ + unsigned char *sec; + + /* check for adaption field */ + if (block[3] & 0x20) + sec = block + block[4] + 4 + 1; + else + sec = block + 4; + + if (sec[0]) /* table pointer, assumed to be 0 */ + continue; + + if (sec[1] == 0x02) /* program map section */ + { + pmt_pid = pid; + service_id = (sec[4] << 8) | sec[5]; + return 0; + } + } + + return -1; +} diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h index 1aa10c70..175cef66 100644 --- a/lib/dvb/tstools.h +++ b/lib/dvb/tstools.h @@ -53,6 +53,7 @@ public: void takeSamples(); + int findPMT(int &pmt_pid, int &service_id); private: int m_pid; int m_maxrange; -- 2.30.2