: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);
{
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);
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
m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_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);
if (m_use_streaminfo)
return m_streaminfo.getPTS(offset, pts);
- if (!m_file.valid() < 0)
+ if (!m_file.valid())
return -1;
offset -= offset % 188;
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;
+}