#include <lib/base/nconfig.h> // access to python config
#include <lib/base/httpstream.h>
+#include <lib/service/servicedvbfcc.h>
+
/* for subtitles */
#include <lib/gui/esubtitle.h>
#include <byteswap.h>
#include <netinet/in.h>
+#include <lib/dvb/fcc.h>
+
#ifndef BYTE_ORDER
#error no byte order defined!
#endif
RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
{
ePtr<eDVBService> service;
+
int r = lookupService(service, ref);
if (r)
service = 0;
// check resources...
- ptr = new eDVBServicePlay(ref, service);
+ if (eFCCServiceManager::checkAvailable(ref))
+ ptr = new eDVBServiceFCCPlay(ref, service);
+ else
+ ptr = new eDVBServicePlay(ref, service);
return 0;
}
return 0;
}
-eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
+eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service, bool connect_event):
m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
{
m_is_primary = 1;
m_is_stream = m_reference.path.substr(0, 7) == "http://";
m_is_pvr = (!m_reference.path.empty() && !m_is_stream);
-
+
m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
m_skipmode = m_fastforward = m_slowmotion = 0;
-
- CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
+
+ if (connect_event)
+ CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
+
CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
m_subtitle_sync_timer = eTimer::create(eApp);
+ m_current_video_pid_type = 0;
+
CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
}
{
eDebug("setting cue skipmode to %d", skipmode);
if (m_cue)
- m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
+ {
+ long long _skipmode = skipmode;
+ if (m_current_video_pid_type == eDVBServicePMTHandler::videoStream::vtH265_HEVC)
+ {
+ if (ratio < 0)
+ _skipmode = skipmode * 3;
+ else
+ _skipmode = skipmode * 4;
+ }
+
+ m_cue->setSkipmode(_skipmode * 90000); /* convert to 90000 per second */
+ }
}
m_skipmode = skipmode;
case sAudioPID:
if (m_dvb_service)
{
- int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
+ int apid = m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID);
if (apid != -1)
return apid;
apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
if (apid != -1)
return apid;
+ apid = m_dvb_service->getCacheEntry(eDVBService::cDDPPID);
+ if (apid != -1)
+ return apid;
+ apid = m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID);
+ if (apid != -1)
+ return apid;
+ apid = m_dvb_service->getCacheEntry(eDVBService::cAACAPID);
+ if (apid != -1)
+ return apid;
}
if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
case sPCRPID:
case the real default is not yet available.)
*/
if (m_dvb_service && ((i != -1)
- || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
+ || ((m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID) == -1)
+ && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1)
+ && (m_dvb_service->getCacheEntry(eDVBService::cDDPPID)==-1)
+ && (m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID)==-1)
+ && (m_dvb_service->getCacheEntry(eDVBService::cAACAPID)==-1))))
{
- if (apidtype == eDVBAudio::aMPEG)
- {
- m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
- m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
- }
- else if (apidtype == eDVBAudio::aAC3)
- {
- m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
- m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
- }
- else
- {
- m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
- m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
- }
+ m_dvb_service->setCacheEntry(eDVBService::cMPEGAPID, apidtype == eDVBAudio::aMPEG ? apid : -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apidtype == eDVBAudio::aAC3 ? apid : -1);
+ m_dvb_service->setCacheEntry(eDVBService::cDDPPID, apidtype == eDVBAudio::aDDP ? apid : -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAACHEAPID, apidtype == eDVBAudio::aAACHE ? apid : -1);
+ m_dvb_service->setCacheEntry(eDVBService::cAACAPID, apidtype == eDVBAudio::aAAC ? apid : -1);
}
h.resetCachedProgram();
}
m_record->setTargetFD(m_timeshift_fd);
+ m_record->setTargetFilename(m_timeshift_file.c_str());
+ m_record->enableAccessPoints(false);
m_timeshift_enabled = 1;
close(m_timeshift_fd);
eDebug("remove timeshift file");
eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
+
+ {
+ std::string timeshift_file_sc = m_timeshift_file + ".sc";
+ eBackgroundFileEraser::getInstance()->erase(timeshift_file_sc.c_str());
+ }
return 0;
}
return;
else
{
+ int timing_pid = -1;
+ int timing_pid_type = -1;
std::set<int> pids_to_record;
pids_to_record.insert(0); // PAT
if (program.pmtPid != -1)
for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
i(program.videoStreams.begin());
i != program.videoStreams.end(); ++i)
+ {
pids_to_record.insert(i->pid);
+ if (timing_pid == -1)
+ {
+ timing_pid = i->pid;
+ timing_pid_type = i->type;
+ }
+ }
+
for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
i(program.audioStreams.begin());
i != program.audioStreams.end(); ++i)
- pids_to_record.insert(i->pid);
+ {
+ pids_to_record.insert(i->pid);
+
+ if (timing_pid == -1)
+ {
+ timing_pid = i->pid;
+ timing_pid_type = -1;
+ }
+ }
for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
i(program.subtitleStreams.begin());
for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
m_record->removePID(*i);
+
+ if (timing_pid != -1)
+ m_record->setTimingPID(timing_pid, timing_pid_type);
}
}
setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
m_decoder->setVideoPID(vpid, vpidtype);
+ m_current_video_pid_type = vpidtype;
selectAudioStream();
- if (!(m_is_pvr || m_is_stream || m_timeshift_active || !m_is_primary))
+ //if (!(m_is_pvr || m_is_stream || m_timeshift_active || !m_is_primary))
+ if (!(m_is_pvr || m_is_stream || m_timeshift_active))
m_decoder->setSyncPCR(pcrpid);
else
m_decoder->setSyncPCR(-1);
{
if (m_subtitle_widget)
{
+ int subtitledelay = 0;
pts_t pos = 0;
if (m_decoder)
m_decoder->getPTS(0, pos);
+ if (m_is_pvr || m_timeshift_enabled)
+ {
+ eDebug("Subtitle in recording/timeshift");
+ subtitledelay = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_noPTSrecordingdelay", 315000);
+ }
+ else
+ {
+ /* check the setting for subtitle delay in live playback, either with pos, or without pos */
+ subtitledelay = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bad_timing_delay", 0);
+ }
+
eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
- m_subtitle_pages.push_back(page);
+ eDVBTeletextSubtitlePage tmppage = page;
+ tmppage.m_have_pts = true;
+
+ if (abs(tmppage.m_pts - pos) > 20*90000)
+ tmppage.m_pts = pos; // fix abnormal pos diffs
+
+ tmppage.m_pts += subtitledelay;
+ m_subtitle_pages.push_back(tmppage);
checkSubtitleTiming();
}
}
if (m_decoder)
m_decoder->getPTS(0, pos);
eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
- m_dvb_subtitle_pages.push_back(p);
+ if ( abs(pos-p.m_show_time)>1800000 && (m_is_pvr || m_timeshift_enabled))
+ {
+ eDebug("[eDVBServicePlay] Subtitle without PTS and recording");
+ int subtitledelay = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_noPTSrecordingdelay", 315000);
+
+ eDVBSubtitlePage tmppage;
+ tmppage = p;
+ tmppage.m_show_time = pos + subtitledelay;
+ m_dvb_subtitle_pages.push_back(tmppage);
+ }
+ else
+ {
+ int subtitledelay = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bad_timing_delay", 0);
+ if (subtitledelay != 0)
+ {
+ eDVBSubtitlePage tmppage;
+ tmppage = p;
+ tmppage.m_show_time += subtitledelay;
+ m_dvb_subtitle_pages.push_back(tmppage);
+ }
+ else
+ m_dvb_subtitle_pages.push_back(p);
+ }
checkSubtitleTiming();
}
}