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);
}
return 0;
}
-eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
+eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
{
m_is_primary = 1;
updateTimeshiftPids();
if (!m_timeshift_active)
updateDecoder();
- if (m_first_program_info && m_is_pvr)
+ if (m_first_program_info & 1 && m_is_pvr)
{
- m_first_program_info = 0;
+ m_first_program_info &= ~1;
seekTo(0);
}
- m_event((iPlayableService*)this, evUpdatedInfo);
+ if (!m_timeshift_active)
+ m_event((iPlayableService*)this, evUpdatedInfo);
break;
}
case eDVBServicePMTHandler::eventPreStart:
switch (event)
{
case eDVBServicePMTHandler::eventNewProgramInfo:
+ eDebug("eventNewProgramInfo TS");
if (m_timeshift_active)
+ {
updateDecoder();
+ if (m_first_program_info & 2)
+ {
+ if (m_slowmotion)
+ {
+ eDebug("re-apply slowmotion after timeshift file change");
+ m_decoder->setSlowMotion(m_slowmotion);
+ }
+ if (m_fastforward)
+ {
+ eDebug("re-apply skip %d, ratio %d after timeshift file change", m_skipmode, m_fastforward);
+ if (m_skipmode)
+ m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
+ if (m_fastforward != 1)
+ m_decoder->setFastForward(m_fastforward);
+ else
+ m_decoder->setTrickmode();
+ }
+ else
+ seekTo(0);
+ m_first_program_info &= ~2;
+ }
+ m_event((iPlayableService*)this, evUpdatedInfo);
+ }
break;
case eDVBServicePMTHandler::eventSOF:
- m_event((iPlayableService*)this, evSOF);
+#if 0
+ if (!m_timeshift_file_next.empty())
+ {
+ eDebug("timeshift SOF, switch to next file");
+ m_decoder->pause();
+
+ m_first_program_info |= 2;
+
+ eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
+ r.path = m_timeshift_file_next;
+
+ /* free the timeshift service handler, we need the resources */
+ m_service_handler_timeshift.free();
+ resetTimeshift(1);
+
+ if (m_skipmode < 0)
+ m_cue->seekTo(0, -1000);
+ 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);
+ }
+ else
+#endif
+ m_event((iPlayableService*)this, evSOF);
break;
case eDVBServicePMTHandler::eventEOF:
if ((!m_is_paused) && (m_skipmode >= 0))
{
- eDebug("timeshift EOF, so let's go live");
- switchToLive();
+ if (m_timeshift_file_next.empty())
+ {
+ eDebug("timeshift EOF, so let's go live");
+ switchToLive();
+ }
+ else
+ {
+ eDebug("timeshift EOF, switch to next file");
+
+ m_first_program_info |= 2;
+
+ eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
+ r.path = m_timeshift_file_next;
+
+ /* free the timeshift service handler, we need the resources */
+ m_service_handler_timeshift.free();
+ resetTimeshift(1);
+
+ 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);
+ }
}
break;
}
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)
{
if (length)
{
- int perc = play_position * 100LL / length;
-
- /* only store last play position when between 1% and 99% */
- if ((1 < perc) && (perc < 99))
- m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
+ m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
}
m_cuesheet_changed = 1;
}
{
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:
return 0;
}
-RESULT eDVBServicePlay::stopTimeshift()
+RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
{
if (!m_timeshift_enabled)
return -1;
- switchToLive();
+ if (swToLive)
+ switchToLive();
m_timeshift_enabled = 0;
}
}
+RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
+{
+ m_timeshift_file_next = f;
+ return 0;
+}
+
void eDVBServicePlay::switchToLive()
{
if (!m_timeshift_active)
return;
-
+
eDebug("SwitchToLive");
-
- m_cue = 0;
- m_decoder = 0;
- m_decode_demux = 0;
- m_teletext_parser = 0;
- m_rds_decoder = 0;
- m_subtitle_parser = 0;
- m_new_dvb_subtitle_page_connection = 0;
- m_new_subtitle_page_connection = 0;
- m_rds_decoder_event_connection = 0;
- m_video_event_connection = 0;
+
+ resetTimeshift(0);
+
m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
- /* free the timeshift service handler, we need the resources */
+ /* free the timeshift service handler, we need the resources */
m_service_handler_timeshift.free();
- m_timeshift_active = 0;
- m_timeshift_changed = 1;
updateDecoder(true);
}
-void eDVBServicePlay::switchToTimeshift()
+void eDVBServicePlay::resetTimeshift(int start)
{
- if (m_timeshift_active)
- return;
-
+ m_cue = 0;
m_decode_demux = 0;
m_decoder = 0;
m_teletext_parser = 0;
m_new_dvb_subtitle_page_connection = 0;
m_rds_decoder_event_connection = 0;
m_video_event_connection = 0;
-
- m_timeshift_active = 1;
m_timeshift_changed = 1;
+ m_timeshift_file_next.clear();
+
+ if (start)
+ {
+ m_cue = new eCueSheet();
+ m_timeshift_active = 1;
+ }
+ else
+ 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)
+ return;
+
+ resetTimeshift(1);
eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
r.path = m_timeshift_file;
- m_cue = new eCueSheet();
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();
if (!m_decoder)
{
h.getDecodeDemux(m_decode_demux);
- if (m_timeshift_changed)
- m_decoder = 0;
if (m_decode_demux)
{
m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
{
if (i == m_cue_entries.end())
{
- if (!have_any_span)
+ if (!have_any_span && !in)
break;
out = length;
} else {
{
have_any_span = 1;
m_cue->addSourceSpan(in, out);
+ in = out = 0;
}
in = length;