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;
141 eDVBServicePlay::stopTimeshift();
143 /* remove CaHandler */
144 m_service_handler.removeCaHandler();
146 if (m_fcc_flag & fcc_tune_failed)
147 m_event((iPlayableService*)this, evTuneFailed);
149 else if (m_fcc_flag & fcc_failed)
150 m_event((iPlayableService*)this, evFccFailed);
156 eDebug("[eDVBServiceFCCPlay::changeFCCMode][%s] enable FCC decoding.", m_reference.toString().c_str());
157 m_fcc_mode = fcc_mode_decoding;
162 void eDVBServiceFCCPlay::processNewProgramInfo(bool toLive)
164 updateFCCDecoder(toLive);
166 if (m_fcc_flag & fcc_failed)
168 m_event((iPlayableService*)this, evFccFailed);
172 void eDVBServiceFCCPlay::updateFCCDecoder(bool sendSeekableStateChanged)
174 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder][%s]", m_reference.toString().c_str());
175 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
176 bool isProgramInfoCached = false;
177 bool pmtVersionChanged = false;
179 eDVBServicePMTHandler &h = m_service_handler;
181 eDVBServicePMTHandler::program program;
182 if (h.getProgramInfo(program))
183 eDebug("getting program info failed.");
186 eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
187 if (!program.videoStreams.empty())
189 eDebugNoNewLine(" (");
190 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
191 i(program.videoStreams.begin());
192 i != program.videoStreams.end(); ++i)
199 if (i != program.videoStreams.begin())
200 eDebugNoNewLine(", ");
201 eDebugNoNewLine("%04x", i->pid);
203 eDebugNoNewLine(")");
205 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
206 if (!program.audioStreams.empty())
208 eDebugNoNewLine(" (");
209 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
210 i(program.audioStreams.begin());
211 i != program.audioStreams.end(); ++i)
213 if (i != program.audioStreams.begin())
214 eDebugNoNewLine(", ");
215 eDebugNoNewLine("%04x", i->pid);
217 eDebugNoNewLine(")");
219 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
220 pcrpid = program.pcrPid;
221 eDebugNoNewLine(", and the text pid is %04x", program.textPid);
222 tpid = program.textPid;
223 eDebug(" %s", program.isCached ? "(Cached)":"");
224 isProgramInfoCached = program.isCached;
225 if (m_pmtVersion != program.pmtVersion)
227 if (m_pmtVersion != -1)
228 pmtVersionChanged = true;
229 m_pmtVersion = program.pmtVersion;
230 //eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] pmt version : %d", m_pmtVersion);
236 h.getDecodeDemux(m_decode_demux);
239 m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
241 m_decoder->connectVideoEvent(slot(*this, &eDVBServiceFCCPlay::video_event), m_video_event_connection);
243 m_fcc_mustplay = true;
248 if (!((m_fcc_flag & fcc_ready)||(m_fcc_flag & fcc_novideo)))
252 if (!isProgramInfoCached)
253 m_fcc_flag |= fcc_novideo;
255 else if ((vpidtype == -1) || (pcrpid== -1))
257 if (!isProgramInfoCached)
258 m_fcc_flag |= fcc_failed;
260 else if (!m_decoder->prepareFCC(m_decode_demux->getSource(), vpid, vpidtype, pcrpid))
261 m_fcc_flag |= fcc_ready;
263 m_fcc_flag |= fcc_failed;
265 else if (pmtVersionChanged)
267 m_decoder->fccUpdatePids(m_decode_demux->getSource(), vpid, vpidtype, pcrpid);
268 m_fcc_flag &=~fcc_decoding;
272 if (m_fcc_mode != fcc_mode_decoding)
275 /* fcc_mode_decoding */
276 if (!(m_fcc_flag & fcc_ready) && !(m_fcc_flag & fcc_novideo))
278 eDebug("[eDVBServiceFCCPlay::updateFCCDecoder] fcc is not ready.");
286 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
287 m_teletext_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newSubtitlePage), m_new_subtitle_page_connection);
288 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
289 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServiceFCCPlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
290 if (m_timeshift_changed)
292 ePyObject subs = getCachedSubtitle();
295 int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
296 pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
297 comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
298 anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
299 if (type == 0) // dvb
300 m_subtitle_parser->start(pid, comp_page, anc_page);
301 else if (type == 1) // ttx
302 m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
309 m_timeshift_changed = 0;
313 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
317 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
318 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
319 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
323 eServiceReferenceDVB ref;
324 m_service_handler.getServiceReference(ref);
325 eServiceReferenceDVB parent = ref.getParentServiceReference();
330 ePtr<eDVBResourceManager> res_mgr;
331 if (!eDVBResourceManager::getInstance(res_mgr))
333 ePtr<iDVBChannelList> db;
334 if (!res_mgr->getChannelList(db))
336 ePtr<eDVBService> origService;
337 if (!db->getService(parent, origService))
339 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
340 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
347 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
348 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
350 m_decoder->setVideoPID(vpid, vpidtype);
353 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
354 m_decoder->setSyncPCR(pcrpid);
356 m_decoder->setSyncPCR(-1);
360 m_decoder->setTextPID(tpid);
361 m_teletext_parser->start(program.textPid);
364 if (vpid > 0 && vpid < 0x2000)
368 std::string radio_pic;
369 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
370 m_decoder->setRadioPic(radio_pic);
373 /* fcc stop and decoder start */
374 if (!(m_fcc_flag & fcc_novideo))
376 if (m_fcc_flag & fcc_decoding)
378 else if(!m_decoder->fccDecoderStart())
379 m_fcc_flag |= fcc_decoding;
384 m_fcc_mustplay = false;
392 m_decoder->setAudioChannel(achannel);
394 /* don't worry about non-existing services, nor pvr services */
397 /* (audio pid will be set in selectAudioTrack */
398 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
399 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
400 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
401 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
403 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
404 sendSeekableStateChanged = true;
406 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
408 if (sendSeekableStateChanged)
409 m_event((iPlayableService*)this, evSeekableStatusChanged);
412 void eDVBServiceFCCPlay::FCCDecoderStop()
414 eDebug("[eDVBServiceFCCPlay::FCCDecoderStop][%s]", m_reference.toString().c_str());
418 m_teletext_parser = 0;
419 m_new_subtitle_page_connection = 0;
420 m_subtitle_parser = 0;
421 m_new_dvb_subtitle_page_connection = 0;
423 if (m_fcc_flag & fcc_ready)
425 m_decoder->fccDecoderStop();
426 m_fcc_flag &=~fcc_decoding;
428 else if (m_fcc_flag & fcc_novideo)
430 m_video_event_connection = 0;
436 void eDVBServiceFCCPlay::switchToLive()
438 if (!m_timeshift_active)
441 eDebug("eDVBServiceFCCPlay::SwitchToLive");
445 m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
447 /* free the timeshift service handler, we need the resources */
448 m_service_handler_timeshift.free();
450 //updateDecoder(true);
451 m_fcc_flag &=~fcc_ready;
452 m_fcc_flag &=~fcc_decoding;
453 processNewProgramInfo(true);
456 DEFINE_REF(eDVBServiceFCCPlay)