1 #include <lib/service/servicedvbfcc.h>
2 #include <lib/components/file_eraser.h>
3 #include <lib/dvb/decoder.h>
4 #include <lib/base/nconfig.h>
6 eDVBServiceFCCPlay::eDVBServiceFCCPlay(const eServiceReference &ref, eDVBService *service)
7 :eDVBServicePlay(ref, service, false), m_fcc_flag(0), m_fcc_mode(fcc_mode_preparing), m_fcc_mustplay(false),
10 CONNECT(m_service_handler.serviceEvent, eDVBServiceFCCPlay::serviceEvent);
13 eDVBServiceFCCPlay::~eDVBServiceFCCPlay()
17 void eDVBServiceFCCPlay::serviceEvent(int event)
19 if (!m_is_primary) // PIP mode
21 eDVBServicePlay::serviceEvent(event);
29 case eDVBServicePMTHandler::eventTuned:
31 eDVBServicePlay::serviceEvent(event);
32 pushbackFCCEvents(evTunedIn);
35 case eDVBServicePMTHandler::eventNoResources:
36 case eDVBServicePMTHandler::eventNoPAT:
37 case eDVBServicePMTHandler::eventNoPATEntry:
38 case eDVBServicePMTHandler::eventNoPMT:
39 case eDVBServicePMTHandler::eventTuneFailed:
40 case eDVBServicePMTHandler::eventMisconfiguration:
42 eDVBServicePlay::serviceEvent(event);
43 pushbackFCCEvents(evTuneFailed);
46 case eDVBServicePMTHandler::eventNewProgramInfo:
48 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
49 if (m_timeshift_enabled)
50 updateTimeshiftPids();
52 if (!m_timeshift_active)
53 processNewProgramInfo();
55 if (!m_timeshift_active)
57 m_event((iPlayableService*)this, evUpdatedInfo);
58 pushbackFCCEvents(evUpdatedInfo);
62 case eDVBServicePMTHandler::eventPreStart:
63 case eDVBServicePMTHandler::eventEOF:
64 case eDVBServicePMTHandler::eventSOF:
66 eDVBServicePlay::serviceEvent(event);
69 case eDVBServicePMTHandler::eventHBBTVInfo:
71 eDVBServicePlay::serviceEvent(event);
72 pushbackFCCEvents(evHBBTVInfo);
78 RESULT eDVBServiceFCCPlay::start()
80 if (!m_is_primary) // PIP mode
82 eDVBServicePlay::start();
86 if (m_fcc_flag & fcc_start) // already started
92 m_fcc_flag |= fcc_start;
93 pushbackFCCEvents(evStart);
95 /* disable CA Interfaces on fcc_mode_preparing */
96 m_service_handler.setCaDisable(true);
97 eDVBServicePlay::start();
102 void eDVBServiceFCCPlay::pushbackFCCEvents(int event)
104 if (event == evTuneFailed)
105 m_fcc_flag |= fcc_tune_failed;
106 m_fcc_events.push_back(event);
109 void eDVBServiceFCCPlay::popFCCEvents()
111 m_fcc_events.unique(); // remove duplicate evUpdatedInfo
112 for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
114 if (*it == evUpdatedInfo)
122 m_service_handler.addCaHandler();
125 for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
128 // eDebug("[eDVBServiceFCCPlay::popFCCEvents][%s] send event : %s", m_reference.toString().c_str(), eventDesc[event]);
129 m_event((iPlayableService*)this, event);
133 void eDVBServiceFCCPlay::changeFCCMode()
135 if (m_fcc_mode == fcc_mode_decoding)
137 eDebug("[eDVBServiceFCCPlay::changeFCCMode][%s] disable FCC decoding.", m_reference.toString().c_str());
138 m_fcc_mode = fcc_mode_preparing;
140 /* remove CaHandler */
141 m_service_handler.removeCaHandler();
143 if (m_fcc_flag & fcc_tune_failed)
144 m_event((iPlayableService*)this, evTuneFailed);
146 else if (m_fcc_flag & fcc_failed)
147 m_event((iPlayableService*)this, evFccFailed);
153 eDebug("[eDVBServiceFCCPlay::changeFCCMode][%s] enable FCC decoding.", m_reference.toString().c_str());
154 m_fcc_mode = fcc_mode_decoding;
159 void eDVBServiceFCCPlay::processNewProgramInfo(bool toLive)
161 updateFCCDecoder(toLive);
163 if (m_fcc_flag & fcc_failed)
165 m_event((iPlayableService*)this, evFccFailed);
169 void eDVBServiceFCCPlay::updateFCCDecoder(bool sendSeekableStateChanged)
171 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder][%s]", m_reference.toString().c_str());
172 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
173 bool isProgramInfoCached = false;
174 bool pmtVersionChanged = false;
176 eDVBServicePMTHandler &h = m_service_handler;
178 eDVBServicePMTHandler::program program;
179 if (h.getProgramInfo(program))
180 eDebug("getting program info failed.");
183 eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
184 if (!program.videoStreams.empty())
186 eDebugNoNewLine(" (");
187 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
188 i(program.videoStreams.begin());
189 i != program.videoStreams.end(); ++i)
196 if (i != program.videoStreams.begin())
197 eDebugNoNewLine(", ");
198 eDebugNoNewLine("%04x", i->pid);
200 eDebugNoNewLine(")");
202 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
203 if (!program.audioStreams.empty())
205 eDebugNoNewLine(" (");
206 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
207 i(program.audioStreams.begin());
208 i != program.audioStreams.end(); ++i)
210 if (i != program.audioStreams.begin())
211 eDebugNoNewLine(", ");
212 eDebugNoNewLine("%04x", i->pid);
214 eDebugNoNewLine(")");
216 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
217 pcrpid = program.pcrPid;
218 eDebugNoNewLine(", and the text pid is %04x", program.textPid);
219 tpid = program.textPid;
220 eDebug(" %s", program.isCached ? "(Cached)":"");
221 isProgramInfoCached = program.isCached;
222 if (m_pmtVersion != program.pmtVersion)
224 if (m_pmtVersion != -1)
225 pmtVersionChanged = true;
226 m_pmtVersion = program.pmtVersion;
227 //eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] pmt version : %d", m_pmtVersion);
233 h.getDecodeDemux(m_decode_demux);
236 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
238 m_decoder->connectVideoEvent(slot(*this, &eDVBServiceFCCPlay::video_event), m_video_event_connection);
240 m_fcc_mustplay = true;
245 if (!((m_fcc_flag & fcc_ready)||(m_fcc_flag & fcc_novideo)))
249 if (!isProgramInfoCached)
250 m_fcc_flag |= fcc_novideo;
252 else if ((vpidtype == -1) || (pcrpid== -1))
254 if (!isProgramInfoCached)
255 m_fcc_flag |= fcc_failed;
257 else if (!m_decoder->prepareFCC(m_decode_demux->getSource(), vpid, vpidtype, pcrpid))
258 m_fcc_flag |= fcc_ready;
260 m_fcc_flag |= fcc_failed;
262 else if (pmtVersionChanged)
264 m_decoder->fccUpdatePids(m_decode_demux->getSource(), vpid, vpidtype, pcrpid);
265 m_fcc_flag &=~fcc_decoding;
269 if (m_fcc_mode != fcc_mode_decoding)
272 /* fcc_mode_decoding */
273 if (!(m_fcc_flag & fcc_ready) && !(m_fcc_flag & fcc_novideo))
275 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] fcc is not ready.");
283 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
284 m_teletext_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newSubtitlePage), m_new_subtitle_page_connection);
285 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
286 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
287 if (m_timeshift_changed)
289 ePyObject subs = getCachedSubtitle();
292 int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
293 pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
294 comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
295 anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
296 if (type == 0) // dvb
297 m_subtitle_parser->start(pid, comp_page, anc_page);
298 else if (type == 1) // ttx
299 m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
306 m_timeshift_changed = 0;
310 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
314 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
315 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
316 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
320 eServiceReferenceDVB ref;
321 m_service_handler.getServiceReference(ref);
322 eServiceReferenceDVB parent = ref.getParentServiceReference();
327 ePtr<eDVBResourceManager> res_mgr;
328 if (!eDVBResourceManager::getInstance(res_mgr))
330 ePtr<iDVBChannelList> db;
331 if (!res_mgr->getChannelList(db))
333 ePtr<eDVBService> origService;
334 if (!db->getService(parent, origService))
336 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
337 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
344 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
345 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
347 m_decoder->setVideoPID(vpid, vpidtype);
350 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
351 m_decoder->setSyncPCR(pcrpid);
353 m_decoder->setSyncPCR(-1);
357 m_decoder->setTextPID(tpid);
358 m_teletext_parser->start(program.textPid);
361 if (vpid > 0 && vpid < 0x2000)
365 std::string radio_pic;
366 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
367 m_decoder->setRadioPic(radio_pic);
370 /* fcc stop and decoder start */
371 if (!(m_fcc_flag & fcc_novideo))
373 if (m_fcc_flag & fcc_decoding)
375 else if(!m_decoder->fccDecoderStart())
376 m_fcc_flag |= fcc_decoding;
381 m_fcc_mustplay = false;
389 m_decoder->setAudioChannel(achannel);
391 /* don't worry about non-existing services, nor pvr services */
394 /* (audio pid will be set in selectAudioTrack */
395 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
396 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
397 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
398 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
400 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
401 sendSeekableStateChanged = true;
403 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
405 if (sendSeekableStateChanged)
406 m_event((iPlayableService*)this, evSeekableStatusChanged);
409 void eDVBServiceFCCPlay::FCCDecoderStop()
411 eDebug("[eDVBServiceFCCPlay::FCCDecoderStop][%s]", m_reference.toString().c_str());
413 if ((m_fcc_flag & fcc_ready) && m_decoder)
415 m_teletext_parser = 0;
416 m_new_subtitle_page_connection = 0;
417 m_subtitle_parser = 0;
418 m_new_dvb_subtitle_page_connection = 0;
420 m_decoder->fccDecoderStop();
421 m_fcc_flag &=~fcc_decoding;
425 void eDVBServiceFCCPlay::switchToLive()
427 if (!m_timeshift_active)
430 eDebug("eDVBServiceFCCPlay::SwitchToLive");
434 m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
436 /* free the timeshift service handler, we need the resources */
437 m_service_handler_timeshift.free();
439 //updateDecoder(true);
440 m_fcc_flag &=~fcc_ready;
441 m_fcc_flag &=~fcc_decoding;
442 processNewProgramInfo(true);
445 DEFINE_REF(eDVBServiceFCCPlay)