serviceEvent(eventNoPAT);
}
- PyObject *eDVBServicePMTHandler::getCaIds()
+ PyObject *eDVBServicePMTHandler::getCaIds(bool pair)
{
ePyObject ret;
if ( !getProgramInfo(prog) )
{
- int cnt=prog.caids.size();
- if (cnt)
+ if (pair)
{
+ int cnt=prog.caids.size();
+ if (cnt)
+ {
+ ret=PyList_New(cnt);
+ std::list<program::capid_pair>::iterator it(prog.caids.begin());
+ while(cnt--)
+ {
+ ePyObject tuple = PyTuple_New(2);
+ PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(it->caid));
+ PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((it++)->capid));
+ PyList_SET_ITEM(ret, cnt, tuple);
+ }
+ }
+ }
+ else
+ {
+ std::set<program::capid_pair> set(prog.caids.begin(), prog.caids.end());
+ std::set<program::capid_pair>::iterator it(set.begin());
+ int cnt=set.size();
ret=PyList_New(cnt);
- std::set<uint16_t>::iterator it(prog.caids.begin());
while(cnt--)
- PyList_SET_ITEM(ret, cnt, PyInt_FromLong(*it++));
+ PyList_SET_ITEM(ret, cnt, PyInt_FromLong((it++)->caid));
}
}
return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
}
- int eDVBServicePMTHandler::getProgramInfo(struct program &program)
+ int eDVBServicePMTHandler::getProgramInfo(program &program)
{
ePtr<eTable<ProgramMapSection> > ptr;
int cached_apid_ac3 = -1;
case CA_DESCRIPTOR:
{
CaDescriptor *descr = (CaDescriptor*)(*desc);
- program.caids.insert(descr->getCaSystemId());
+ program::capid_pair pair;
+ pair.caid = descr->getCaSystemId();
+ pair.capid = descr->getCaPid();
+ program.caids.push_back(pair);
break;
}
default:
if ((*desc)->getTag() == CA_DESCRIPTOR)
{
CaDescriptor *descr = (CaDescriptor*)(*desc);
- program.caids.insert(descr->getCaSystemId());
+ program::capid_pair pair;
+ pair.caid = descr->getCaSystemId();
+ pair.capid = descr->getCaPid();
+ program.caids.push_back(pair);
}
}
}
program.textPid = cached_tpid;
}
CAID_LIST &caids = m_service->m_ca;
- for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it)
- program.caids.insert(*it);
+ for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it) {
+ program::capid_pair pair;
+ pair.caid = *it;
+ pair.capid = -1; // not known yet
+ program.caids.push_back(pair);
+ }
if ( cnt )
ret = 0;
}
int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate, eDVBService *service)
{
+ ePtr<iTsSource> s;
+ return tuneExt(ref, use_decode_demux, s, NULL, cue, simulate, service);
+}
+
+int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr<iTsSource> &source, const char *streaminfo_file, eCueSheet *cue, bool simulate, eDVBService *service)
+{
RESULT res=0;
m_reference = ref;
{
eWarning("no .meta file found, trying to find PMT pid");
eDVBTSTools tstools;
- if (tstools.openFile(ref.path.c_str()))
+ if (source)
+ tstools.setSource(source, streaminfo_file ? streaminfo_file : ref.path.c_str());
+ else if (tstools.openFile(ref.path.c_str()))
eWarning("failed to open file");
else
{
if (m_pvr_channel)
{
m_pvr_channel->setCueSheet(cue);
- m_pvr_channel->playFile(ref.path.c_str());
+ if (source)
+ m_pvr_channel->playSource(source, streaminfo_file);
+ else
+ m_pvr_channel->playFile(ref.path.c_str());
}
}
struct program
{
+ struct capid_pair
+ {
+ uint16_t caid;
+ int capid;
+ bool operator< (const struct capid_pair &t) { return t.caid < caid; }
+ };
std::vector<videoStream> videoStreams;
std::vector<audioStream> audioStreams;
int defaultAudioStream;
std::vector<subtitleStream> subtitleStreams;
- std::set<uint16_t> caids;
+ std::list<capid_pair> caids;
int pcrPid;
int pmtPid;
int textPid;
PyObject *createPythonObject();
};
- int getProgramInfo(struct program &program);
+ int getProgramInfo(program &program);
int getDataDemux(ePtr<iDVBDemux> &demux);
int getDecodeDemux(ePtr<iDVBDemux> &demux);
- PyObject *getCaIds();
+ PyObject *getCaIds(bool pair=false); // caid / ecmpid pair
int getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel);
int getServiceReference(eServiceReferenceDVB &service) { service = m_reference; return 0; }
int getChannel(eUsePtr<iDVBChannel> &channel);
void resetCachedProgram() { m_have_cached_program = false; }
+ /* deprecated interface */
int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false, eDVBService *service = 0);
+
+ /* new interface */
+ int tuneExt(eServiceReferenceDVB &ref, int use_decode_demux, ePtr<iTsSource> &, const char *streaminfo_file, eCueSheet *sg=0, bool simulate=false, eDVBService *service = 0);
+
void free();
private:
bool m_have_cached_program;
RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
{
ASSERT(ref == m_ref);
- if (m_parser.m_name.size())
+ if (!ref.name.empty())
+ name = ref.name;
+ else if (!m_parser.m_name.empty())
name = m_parser.m_name;
else
{
int err = f.open(m_ref.path.c_str(), 0);
if (err < 0)
return -1;
-
+
+ off_t offset = 0;
off_t length = f.length();
unsigned char buffer[188*256*4];
while (1)
{
- off_t offset = f.lseek(0, SEEK_CUR);
eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
- int r = f.read(buffer, sizeof(buffer));
+ int r = f.read(offset, buffer, sizeof(buffer));
if (!r)
break;
if (r < 0)
return r;
+ offset += r;
parser.parseData(offset, buffer, r);
}
if (m_skipmode < 0)
m_cue->seekTo(0, -1000);
- m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+ ePtr<iTsSource> source = createTsSource(r);
+ m_service_handler_timeshift.tuneExt(r, 1, source, r.path.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
m_event((iPlayableService*)this, evUser+1);
}
m_service_handler_timeshift.free();
resetTimeshift(1);
- m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+ ePtr<iTsSource> source = createTsSource(r);
+ m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
m_event((iPlayableService*)this, evUser+1);
}
m_event(this, evStart);
m_first_program_info = 1;
- m_service_handler.tune(service, m_is_pvr, m_cue, false, m_dvb_service);
+ ePtr<iTsSource> source = createTsSource(service);
+ m_service_handler.tuneExt(service, m_is_pvr, source, service.path.c_str(), m_cue, false, m_dvb_service);
if (m_is_pvr)
{
{
eDVBServicePMTHandler::program program;
- if (w == sCAIDs)
+ if (w == sCAIDs || w == sCAIDPIDs)
return resIsPyObject;
eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
{
case sCAIDs:
return m_service_handler.getCaIds();
+ case sCAIDPIDs:
+ return m_service_handler.getCaIds(true);
case sTransponderData:
return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
default:
m_timeshift_active = 0;
}
+ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref)
+{
+ eRawFile *f = new eRawFile();
+ f->open(ref.path.c_str());
+ return ePtr<iTsSource>(f);
+}
+
void eDVBServicePlay::switchToTimeshift()
{
if (m_timeshift_active)
r.path = m_timeshift_file;
m_cue->seekTo(0, -1000);
- m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+
+ ePtr<iTsSource> source = createTsSource(r);
+ m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
pause();