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),
8 m_pmtVersion(-1), m_normal_decoding(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::eventChannelAllocated:
48 bool is_usb_tuner = checkUsbTuner();
49 bool fcc_state_decoding = getFCCStateDecoding();
50 int slotId = getFrontendInfo(iDVBFrontend_ENUMS::frontendNumber);
54 if (fcc_state_decoding)
56 m_normal_decoding = true;
61 eDVBServicePlay::serviceEvent(eDVBServicePMTHandler::eventTuneFailed);
62 pushbackFCCEvents(evTuneFailed);
67 case eDVBServicePMTHandler::eventNewProgramInfo:
69 if (m_fcc_flag & fcc_tune_failed)
72 eDebug("eventNewProgramInfo %d %d %d", m_timeshift_enabled, m_timeshift_active, m_normal_decoding);
73 if (m_normal_decoding)
75 eDVBServicePlay::serviceEvent(event);
79 if (m_timeshift_enabled)
80 updateTimeshiftPids();
82 if (!m_timeshift_active)
83 processNewProgramInfo();
85 if (!m_timeshift_active)
87 m_event((iPlayableService*)this, evUpdatedInfo);
88 pushbackFCCEvents(evUpdatedInfo);
93 case eDVBServicePMTHandler::eventPreStart:
94 case eDVBServicePMTHandler::eventEOF:
95 case eDVBServicePMTHandler::eventSOF:
97 eDVBServicePlay::serviceEvent(event);
100 case eDVBServicePMTHandler::eventHBBTVInfo:
102 eDVBServicePlay::serviceEvent(event);
103 pushbackFCCEvents(evHBBTVInfo);
109 RESULT eDVBServiceFCCPlay::start()
111 if (!m_is_primary) // PIP mode
113 eDVBServicePlay::start();
117 if (m_fcc_flag & fcc_start) // already started
123 m_fcc_flag |= fcc_start;
124 pushbackFCCEvents(evStart);
126 /* disable CA Interfaces on fcc_mode_preparing */
127 m_service_handler.setCaDisable(true);
128 eDVBServicePlay::start();
133 void eDVBServiceFCCPlay::pushbackFCCEvents(int event)
135 if (event == evTuneFailed)
136 m_fcc_flag |= fcc_tune_failed;
137 m_fcc_events.push_back(event);
140 void eDVBServiceFCCPlay::popFCCEvents()
142 m_fcc_events.unique(); // remove duplicate evUpdatedInfo
143 for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
145 if (*it == evUpdatedInfo)
153 m_service_handler.addCaHandler();
156 for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
159 m_event((iPlayableService*)this, event);
163 void eDVBServiceFCCPlay::changeFCCMode()
165 if (m_fcc_mode == fcc_mode_decoding)
167 eDebug("[eDVBServiceFCCPlay::changeFCCMode][%s] disable FCC decoding.", m_reference.toString().c_str());
168 m_fcc_mode = fcc_mode_preparing;
171 eDVBServicePlay::stopTimeshift();
173 /* remove CaHandler */
174 m_service_handler.removeCaHandler();
176 if (m_fcc_flag & fcc_tune_failed)
177 m_event((iPlayableService*)this, evTuneFailed);
179 else if (m_fcc_flag & fcc_failed)
180 m_event((iPlayableService*)this, evFccFailed);
186 eDebug("[eDVBServiceFCCPlay::changeFCCMode][%s] enable FCC decoding.", m_reference.toString().c_str());
187 m_fcc_mode = fcc_mode_decoding;
192 void eDVBServiceFCCPlay::processNewProgramInfo(bool toLive)
194 updateFCCDecoder(toLive);
196 if (m_fcc_flag & fcc_failed)
198 m_event((iPlayableService*)this, evFccFailed);
202 void eDVBServiceFCCPlay::updateFCCDecoder(bool sendSeekableStateChanged)
204 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder][%s]", m_reference.toString().c_str());
205 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
206 bool isProgramInfoCached = false;
207 bool pmtVersionChanged = false;
209 eDVBServicePMTHandler &h = m_service_handler;
211 eDVBServicePMTHandler::program program;
212 if (h.getProgramInfo(program))
213 eDebug("getting program info failed.");
216 eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
217 if (!program.videoStreams.empty())
219 eDebugNoNewLine(" (");
220 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
221 i(program.videoStreams.begin());
222 i != program.videoStreams.end(); ++i)
229 if (i != program.videoStreams.begin())
230 eDebugNoNewLine(", ");
231 eDebugNoNewLine("%04x", i->pid);
233 eDebugNoNewLine(")");
235 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
236 if (!program.audioStreams.empty())
238 eDebugNoNewLine(" (");
239 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
240 i(program.audioStreams.begin());
241 i != program.audioStreams.end(); ++i)
243 if (i != program.audioStreams.begin())
244 eDebugNoNewLine(", ");
245 eDebugNoNewLine("%04x", i->pid);
247 eDebugNoNewLine(")");
249 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
250 pcrpid = program.pcrPid;
251 eDebugNoNewLine(", and the text pid is %04x", program.textPid);
252 tpid = program.textPid;
253 eDebug(" %s", program.isCached ? "(Cached)":"");
254 isProgramInfoCached = program.isCached;
255 if (m_pmtVersion != program.pmtVersion)
257 if (m_pmtVersion != -1)
258 pmtVersionChanged = true;
259 m_pmtVersion = program.pmtVersion;
260 //eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] pmt version : %d", m_pmtVersion);
266 h.getDecodeDemux(m_decode_demux);
269 m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
271 m_decoder->connectVideoEvent(slot(*this, &eDVBServiceFCCPlay::video_event), m_video_event_connection);
273 m_fcc_mustplay = true;
278 if (!((m_fcc_flag & fcc_ready)||(m_fcc_flag & fcc_novideo)))
282 if (!isProgramInfoCached)
283 m_fcc_flag |= fcc_novideo;
285 else if ((vpidtype == -1) || (pcrpid== -1))
287 if (!isProgramInfoCached)
288 m_fcc_flag |= fcc_failed;
290 else if (!m_decoder->prepareFCC(m_decode_demux->getSource(), vpid, vpidtype, pcrpid))
291 m_fcc_flag |= fcc_ready;
293 m_fcc_flag |= fcc_failed;
295 else if (pmtVersionChanged)
297 m_decoder->fccUpdatePids(m_decode_demux->getSource(), vpid, vpidtype, pcrpid);
298 m_fcc_flag &=~fcc_decoding;
302 if (m_fcc_mode != fcc_mode_decoding)
305 /* fcc_mode_decoding */
306 if (!(m_fcc_flag & fcc_ready) && !(m_fcc_flag & fcc_novideo))
308 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] fcc is not ready.");
316 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
317 m_teletext_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newSubtitlePage), m_new_subtitle_page_connection);
318 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
319 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
320 if (m_timeshift_changed)
322 ePyObject subs = getCachedSubtitle();
325 int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
326 pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
327 comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
328 anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
329 if (type == 0) // dvb
330 m_subtitle_parser->start(pid, comp_page, anc_page);
331 else if (type == 1) // ttx
332 m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
339 m_timeshift_changed = 0;
343 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
347 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
348 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
349 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
353 eServiceReferenceDVB ref;
354 m_service_handler.getServiceReference(ref);
355 eServiceReferenceDVB parent = ref.getParentServiceReference();
360 ePtr<eDVBResourceManager> res_mgr;
361 if (!eDVBResourceManager::getInstance(res_mgr))
363 ePtr<iDVBChannelList> db;
364 if (!res_mgr->getChannelList(db))
366 ePtr<eDVBService> origService;
367 if (!db->getService(parent, origService))
369 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
370 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
377 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
378 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
380 m_decoder->setVideoPID(vpid, vpidtype);
383 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
384 m_decoder->setSyncPCR(pcrpid);
386 m_decoder->setSyncPCR(-1);
390 m_decoder->setTextPID(tpid);
391 m_teletext_parser->start(program.textPid);
394 if (vpid > 0 && vpid < 0x2000)
398 std::string radio_pic;
399 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
400 m_decoder->setRadioPic(radio_pic);
403 /* fcc stop and decoder start */
404 if (!(m_fcc_flag & fcc_novideo))
406 if (m_fcc_flag & fcc_decoding)
408 else if(!m_decoder->fccDecoderStart())
409 m_fcc_flag |= fcc_decoding;
414 m_fcc_mustplay = false;
422 m_decoder->setAudioChannel(achannel);
424 /* don't worry about non-existing services, nor pvr services */
427 /* (audio pid will be set in selectAudioTrack */
428 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
429 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
430 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
431 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
433 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
434 sendSeekableStateChanged = true;
436 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
438 if (sendSeekableStateChanged)
439 m_event((iPlayableService*)this, evSeekableStatusChanged);
442 void eDVBServiceFCCPlay::FCCDecoderStop()
444 eDebug("[eDVBServiceFCCPlay::FCCDecoderStop][%s]", m_reference.toString().c_str());
448 m_teletext_parser = 0;
449 m_new_subtitle_page_connection = 0;
450 m_subtitle_parser = 0;
451 m_new_dvb_subtitle_page_connection = 0;
453 if (m_fcc_flag & fcc_ready)
455 m_decoder->fccDecoderStop();
456 m_fcc_flag &=~fcc_decoding;
458 else if (m_fcc_flag & fcc_novideo)
460 m_video_event_connection = 0;
466 void eDVBServiceFCCPlay::switchToLive()
468 if (!m_timeshift_active)
471 eDebug("eDVBServiceFCCPlay::SwitchToLive");
475 m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
477 /* free the timeshift service handler, we need the resources */
478 m_service_handler_timeshift.free();
480 m_fcc_flag &=~fcc_ready;
481 m_fcc_flag &=~fcc_decoding;
482 processNewProgramInfo(true);
485 bool eDVBServiceFCCPlay::checkUsbTuner()
487 return (bool)getFrontendInfo(iDVBFrontend_ENUMS::isUsbTuner);
490 bool eDVBServiceFCCPlay::getFCCStateDecoding()
492 eFCCServiceManager *fcc_service_mgr = eFCCServiceManager::getInstance();
493 return fcc_service_mgr->isStateDecoding((iPlayableService*)this);
496 void eDVBServiceFCCPlay::setNormalDecoding()
498 eFCCServiceManager *fcc_service_mgr = eFCCServiceManager::getInstance();
499 return fcc_service_mgr->setNormalDecoding((iPlayableService*)this);
502 DEFINE_REF(eDVBServiceFCCPlay)