m_event((iPlayableService*)this, evUpdatedInfo);
break;
}
+ case eDVBServicePMTHandler::eventPreStart:
+ loadCuesheet();
+ break;
case eDVBServicePMTHandler::eventEOF:
m_event((iPlayableService*)this, evEOF);
break;
m_event_handler.inject(event, 0);
m_event_handler.inject(empty, 1);
}
- loadCuesheet();
m_event(this, evStart);
}
return 0;
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;
}
RESULT eDVBServicePlay::isCurrentlySeekable()
{
- return m_is_pvr || m_timeshift_active;
+ int ret = 0;
+ if (m_decoder)
+ {
+ ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
+ if (m_decoder->getVideoProgressive() == -1)
+ ret &= ~2;
+ }
+ return ret;
}
RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
return 0;
}
-RESULT eDVBServicePlay::stopTimeshift()
+RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
{
if (!m_timeshift_enabled)
return -1;
- switchToLive();
+ if (swToLive)
+ switchToLive();
m_timeshift_enabled = 0;
m_timeshift_active = 0;
m_timeshift_changed = 1;
- m_event((iPlayableService*)this, evSeekableStatusChanged);
-
- updateDecoder();
+ updateDecoder(true);
}
void eDVBServicePlay::switchToTimeshift()
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 */
eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
pause();
- updateDecoder(); /* mainly to switch off PCR, and to set pause */
-
- m_event((iPlayableService*)this, evSeekableStatusChanged);
+ updateDecoder(true); /* mainly to switch off PCR, and to set pause */
}
-void eDVBServicePlay::updateDecoder()
+void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
{
int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
+ bool mustPlay = false;
eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
Py_DECREF(subs);
}
}
- m_decoder->play(); /* pids will be set later */
}
if (m_cue)
m_cue->setDecodingDemux(m_decode_demux, m_decoder);
- m_decoder->play(); /* pids will be set later. */
+ mustPlay = true;
}
m_timeshift_changed = 0;
if (m_decoder)
{
+ bool wasSeekable = m_decoder->getVideoProgressive() != -1;
if (m_dvb_service)
{
achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
}
}
- std::string config_delay;
- int config_delay_int = 0;
- if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
- config_delay_int = atoi(config_delay.c_str());
- m_decoder->setAC3Delay(ac3_delay == -1 ? config_delay_int : ac3_delay + config_delay_int);
-
- if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
- config_delay_int = atoi(config_delay.c_str());
- else
- config_delay_int = 0;
- m_decoder->setPCMDelay(pcm_delay == -1 ? config_delay_int : pcm_delay + config_delay_int);
+ setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
+ setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
m_decoder->setVideoPID(vpid, vpidtype);
selectAudioStream();
m_decoder->setRadioPic(radio_pic);
}
- m_decoder->set();
+ if (mustPlay)
+ m_decoder->play();
+ else
+ m_decoder->set();
+
m_decoder->setAudioChannel(achannel);
/* don't worry about non-existing services, nor pvr services */
m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
}
+ if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
+ sendSeekableStateChanged = true;
}
m_have_video_pid = (vpid > 0 && vpid < 0x2000);
+
+ if (sendSeekableStateChanged)
+ m_event((iPlayableService*)this, evSeekableStatusChanged);
}
void eDVBServicePlay::loadCuesheet()
{
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;
{
if (m_dvb_service)
m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
- if (m_decoder)
- m_decoder->setAC3Delay(delay);
+ if (m_decoder) {
+ std::string config_delay;
+ int config_delay_int = 0;
+ if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
+ config_delay_int = atoi(config_delay.c_str());
+ m_decoder->setAC3Delay(delay + config_delay_int);
+ }
}
void eDVBServicePlay::setPCMDelay(int delay)
{
if (m_dvb_service)
m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
- if (m_decoder)
- m_decoder->setPCMDelay(delay);
+ if (m_decoder) {
+ std::string config_delay;
+ int config_delay_int = 0;
+ if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
+ config_delay_int = atoi(config_delay.c_str());
+ else
+ config_delay_int = 0;
+ m_decoder->setPCMDelay(delay + config_delay_int);
+ }
}
void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)