: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);
{
if (m_channel)
if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
- eDebug("Allocating a demux for now tuned-in channel failed.");
+ eDebug("Allocating %s-decoding a demux for now tuned-in channel failed.", m_use_decode_demux ? "" : "non-");
serviceEvent(eventTuned);
{
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);
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
program.pmtPid = -1;
program.textPid = -1;
- if (!m_PMT.getCurrent(ptr))
+ if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
{
int cached_apid_ac3 = -1;
int cached_apid_mpeg = -1;
demux = m_demux;
return ret;
}
+
+ ASSERT(m_channel); /* calling without a previous ::tune is certainly bad. */
ret = m_channel->getDemux(demux, iDVBChannel::capDecode);
if (!ret)
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);
eDebug("allocatePVRChannel failed!\n");
m_channel = m_pvr_channel;
}
-
+
+ ePtr<iDVBChannelList> db;
+ if (!m_resourceManager->getChannelList(db))
+ db->getService((eServiceReferenceDVB&)m_reference, m_service);
+
if (m_channel)
{
m_channel->connectStateChange(
m_pvr_channel->playFile(ref.path.c_str());
}
- ePtr<iDVBChannelList> db;
- if (!m_resourceManager->getChannelList(db))
- db->getService((eServiceReferenceDVB&)m_reference, m_service);
-
return res;
}