X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/55c2a88ecd94a2eb6aa00f1227912fcd2659932b..2ab514e090cb4f0dc14faa061820d9d154b37647:/lib/service/servicedvb.cpp diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index dcf11d23..7f931334 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -65,16 +65,7 @@ RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std:: if (!service_center->info(parent, service_info)) { if (!service_info->getName(parent, name)) - { - // just show short name - unsigned int pos = name.find("\xc2\x86"); - if ( pos != std::string::npos ) - name.erase(0, pos+2); - pos = name.find("\xc2\x87"); - if ( pos != std::string::npos ) - name.erase(pos); - name+=" - "; - } + name=buildShortName(name) + " - "; } } } @@ -96,7 +87,7 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const { ePtr res_mgr; if ( eDVBResourceManager::getInstance( res_mgr ) ) - eDebug("isPlayble... no res manager!!"); + eDebug("isPlayable... no res manager!!"); else { eDVBChannelID chid, chid_ignore; @@ -125,7 +116,7 @@ extern void PutToDict(ePyObject &dict, const char*key, const char *value); void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm) { const char *tmp=0; - PutToDict(dict, "type", "satellite"); + PutToDict(dict, "type", "Satellite"); PutToDict(dict, "frequency", feparm.frequency); PutToDict(dict, "symbolrate", feparm.symbol_rate); PutToDict(dict, "orbital position", feparm.orbital_position); @@ -192,14 +183,14 @@ void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &fe void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm) { - PutToDict(dict, "type", "terrestrial"); + PutToDict(dict, "type", "Terrestrial"); PutToDict(dict, "frequency", feparm.frequency); const char *tmp=0; switch (feparm.bandwidth) { - case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz: tmp="8 Mhz"; break; - case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz: tmp="7 Mhz"; break; - case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz: tmp="6 Mhz"; break; + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz: tmp="8 MHz"; break; + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz: tmp="7 MHz"; break; + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz: tmp="6 MHz"; break; default: case eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto: tmp="AUTO"; break; } @@ -276,7 +267,7 @@ void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm) { const char *tmp=0; - PutToDict(dict, "type", "cable"); + PutToDict(dict, "type", "Cable"); PutToDict(dict, "frequency", feparm.frequency); PutToDict(dict, "symbolrate", feparm.symbol_rate); switch (feparm.modulation) @@ -360,7 +351,12 @@ PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r PutCableDataToDict(dict, c); break; } + default: + eDebug("unknown frontend type %d", system); + Py_DECREF(dict); + break; } + return dict; } } } @@ -725,6 +721,7 @@ RESULT eDVBServiceList::getContent(std::list &list, bool sort // S = Service Reference (as python string object .. same as ref.toString()) // C = Service Reference (as python string object .. same as ref.toCompareString()) // N = Service Name (as python string object) +// n = Short Service Name (short name brakets used) (as python string object) // when exactly one return value per service is selected in the format string, // then each value is directly a list entry // when more than one value is returned per service, then the list is a list of @@ -745,7 +742,7 @@ PyObject *eDVBServiceList::getContent(const char* format, bool sorted) ePtr sptr; eServiceCenterPtr service_center; - if (strchr(format, 'N')) + if (strchr(format, 'N') || strchr(format, 'n')) eServiceCenter::getPrivInstance(service_center); ret = PyList_New(services); @@ -777,6 +774,30 @@ PyObject *eDVBServiceList::getContent(const char* format, bool sorted) { std::string name; sptr->getName(ref, name); + + // filter short name brakets + unsigned int pos; + while((pos = name.find("\xc2\x86")) != std::string::npos) + name.erase(pos,2); + while((pos = name.find("\xc2\x87")) != std::string::npos) + name.erase(pos,2); + + if (name.length()) + tmp = PyString_FromString(name.c_str()); + } + } + if (!tmp) + tmp = PyString_FromString(""); + break; + case 'n': // short service name + if (service_center) + { + service_center->info(ref, sptr); + if (sptr) + { + std::string name; + sptr->getName(ref, name); + name = buildShortName(name); if (name.length()) tmp = PyString_FromString(name.c_str()); } @@ -1044,6 +1065,7 @@ void eDVBServicePlay::serviceEvent(int event) } break; } + case eDVBServicePMTHandler::eventNoResources: case eDVBServicePMTHandler::eventNoPAT: case eDVBServicePMTHandler::eventNoPATEntry: case eDVBServicePMTHandler::eventNoPMT: @@ -1089,7 +1111,8 @@ void eDVBServicePlay::serviceEventTimeshift(int event) m_event((iPlayableService*)this, evSOF); break; case eDVBServicePMTHandler::eventEOF: - switchToLive(); + if ((!m_is_paused) && (m_skipmode >= 0)) + switchToLive(); break; } } @@ -1102,6 +1125,8 @@ RESULT eDVBServicePlay::start() to start recording from the data demux. */ if (m_is_pvr) m_cue = new eCueSheet(); + else + m_event(this, evStart); m_first_program_info = 1; eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference; @@ -1123,10 +1148,10 @@ RESULT eDVBServicePlay::start() } if (m_is_pvr) + { loadCuesheet(); - - m_event(this, evStart); - m_event((iPlayableService*)this, evSeekableStatusChanged); + m_event(this, evStart); + } return 0; } @@ -1135,7 +1160,7 @@ RESULT eDVBServicePlay::stop() /* add bookmark for last play position */ if (m_is_pvr) { - pts_t play_position; + pts_t play_position, length; if (!getPlayPosition(play_position)) { /* remove last position */ @@ -1150,7 +1175,17 @@ RESULT eDVBServicePlay::stop() ++i; } - m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */ + if (getLength(length)) + length = 0; + + if (length) + { + int perc = play_position * 100LL / length; + + /* only store last play position when between 5% and 95% */ + if ((5 < perc) && (perc < 95)) + m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */ + } m_cuesheet_changed = 1; } } @@ -1167,7 +1202,7 @@ RESULT eDVBServicePlay::stop() if (!::stat(m_reference.path.c_str(), &s)) saveCuesheet(); } - + m_event((iPlayableService*)this, evStopped); return 0; } @@ -1242,7 +1277,7 @@ RESULT eDVBServicePlay::setFastForward(int ratio) return m_decoder->setFastForward(ffratio); } - + RESULT eDVBServicePlay::seek(ePtr &ptr) { if (m_is_pvr || m_timeshift_enabled) @@ -1449,7 +1484,7 @@ RESULT eDVBServicePlay::audioDelay(ePtr &ptr) return 0; } -RESULT eDVBServicePlay::radioText(ePtr &ptr) +RESULT eDVBServicePlay::rdsDecoder(ePtr &ptr) { ptr = this; return 0; @@ -1679,8 +1714,8 @@ int eDVBServicePlay::selectAudioStream(int i) if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type)) return -4; - if (m_radiotext_parser) - m_radiotext_parser->start(program.audioStreams[i].pid); + if (m_rds_decoder) + m_rds_decoder->start(program.audioStreams[i].pid); if (m_dvb_service && !m_is_pvr) { @@ -1717,20 +1752,81 @@ RESULT eDVBServicePlay::selectChannel(int i) return 0; } -std::string eDVBServicePlay::getRadioText(int x) +std::string eDVBServicePlay::getText(int x) { - if (m_radiotext_parser) + if (m_rds_decoder) switch(x) { - case 0: - return convertLatin1UTF8(m_radiotext_parser->getCurrentText()); + case RadioText: + return convertLatin1UTF8(m_rds_decoder->getRadioText()); + case RtpText: + return convertLatin1UTF8(m_rds_decoder->getRtpText()); } return ""; } -void eDVBServicePlay::radioTextUpdated() +void eDVBServicePlay::rdsDecoderEvent(int what) +{ + switch(what) + { + case eDVBRdsDecoder::RadioTextChanged: + m_event((iPlayableService*)this, evUpdatedRadioText); + break; + case eDVBRdsDecoder::RtpTextChanged: + m_event((iPlayableService*)this, evUpdatedRtpText); + break; + case eDVBRdsDecoder::RassInteractivePicMaskChanged: + m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask); + break; + case eDVBRdsDecoder::RecvRassSlidePic: + m_event((iPlayableService*)this, evUpdatedRassSlidePic); + break; + } +} + +void eDVBServicePlay::showRassSlidePicture() { - m_event((iPlayableService*)this, evUpdatedRadioText); + if (m_rds_decoder) + { + if (m_decoder) + { + std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture(); + if (rass_slide_pic.length()) + m_decoder->showSinglePic(rass_slide_pic.c_str()); + else + eDebug("empty filename for rass slide picture received!!"); + } + else + eDebug("no MPEG Decoder to show iframes avail"); + } + else + eDebug("showRassSlidePicture called.. but not decoder"); +} + +void eDVBServicePlay::showRassInteractivePic(int page, int subpage) +{ + if (m_rds_decoder) + { + if (m_decoder) + { + std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage); + if (rass_interactive_pic.length()) + m_decoder->showSinglePic(rass_interactive_pic.c_str()); + else + eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage); + } + else + eDebug("no MPEG Decoder to show iframes avail"); + } + else + eDebug("showRassInteractivePic called.. but not decoder"); +} + +ePyObject eDVBServicePlay::getRassInteractiveMask() +{ + if (m_rds_decoder) + return m_rds_decoder->getRassPictureMask(); + Py_RETURN_NONE; } int eDVBServiceBase::getFrontendInfo(int w) @@ -1744,19 +1840,54 @@ int eDVBServiceBase::getFrontendInfo(int w) return fe->readFrontendData(w); } -PyObject *eDVBServiceBase::getFrontendData(bool original) +PyObject *eDVBServiceBase::getFrontendData() { - ePyObject ret; + ePyObject ret = PyDict_New(); + if (ret) + { + eUsePtr channel; + if(!m_service_handler.getChannel(channel)) + { + ePtr fe; + if(!channel->getFrontend(fe)) + fe->getFrontendData(ret); + } + } + else + Py_RETURN_NONE; + return ret; +} - eUsePtr channel; - if(!m_service_handler.getChannel(channel)) +PyObject *eDVBServiceBase::getFrontendStatus() +{ + ePyObject ret = PyDict_New(); + if (ret) + { + eUsePtr channel; + if(!m_service_handler.getChannel(channel)) + { + ePtr fe; + if(!channel->getFrontend(fe)) + fe->getFrontendStatus(ret); + } + } + else + Py_RETURN_NONE; + return ret; +} + +PyObject *eDVBServiceBase::getTransponderData(bool original) +{ + ePyObject ret = PyDict_New(); + if (ret) { - ePtr fe; - if(!channel->getFrontend(fe)) + eUsePtr channel; + if(!m_service_handler.getChannel(channel)) { - ret = fe->readTransponderData(original); - if (ret) + ePtr fe; + if(!channel->getFrontend(fe)) { + fe->getTransponderData(ret, original); ePtr feparm; channel->getCurrentFrontendParameters(feparm); if (feparm) @@ -1782,11 +1913,30 @@ PyObject *eDVBServiceBase::getFrontendData(bool original) } } } - if (!ret) + else Py_RETURN_NONE; return ret; } +PyObject *eDVBServiceBase::getAll(bool original) +{ + ePyObject ret = getTransponderData(original); + if (ret != Py_None) + { + eUsePtr channel; + if(!m_service_handler.getChannel(channel)) + { + ePtr fe; + if(!channel->getFrontend(fe)) + { + fe->getFrontendData(ret); + fe->getFrontendStatus(ret); + } + } + } + return ret; +} + int eDVBServicePlay::getNumberOfSubservices() { ePtr evt; @@ -1860,7 +2010,7 @@ RESULT eDVBServicePlay::stopTimeshift() close(m_timeshift_fd); eDebug("remove timeshift file"); - remove(m_timeshift_file.c_str()); + eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str()); return 0; } @@ -1975,6 +2125,11 @@ void eDVBServicePlay::updateTimeshiftPids() i != program.audioStreams.end(); ++i) pids_to_record.insert(i->pid); + for (std::vector::const_iterator + i(program.subtitleStreams.begin()); + i != program.subtitleStreams.end(); ++i) + pids_to_record.insert(i->pid); + std::set new_pids, obsolete_pids; std::set_difference(pids_to_record.begin(), pids_to_record.end(), @@ -2004,11 +2159,12 @@ void eDVBServicePlay::switchToLive() m_decoder = 0; m_decode_demux = 0; m_teletext_parser = 0; - m_radiotext_parser = 0; + m_rds_decoder = 0; m_subtitle_parser = 0; m_new_dvb_subtitle_page_connection = 0; m_new_subtitle_page_connection = 0; - m_radiotext_updated_connection = 0; + m_rds_decoder_event_connection = 0; + m_video_event_connection = 0; /* free the timeshift service handler, we need the resources */ m_service_handler_timeshift.free(); @@ -2027,22 +2183,26 @@ void eDVBServicePlay::switchToTimeshift() m_decode_demux = 0; m_decoder = 0; m_teletext_parser = 0; - m_radiotext_parser = 0; + m_rds_decoder = 0; m_subtitle_parser = 0; m_new_subtitle_page_connection = 0; m_new_dvb_subtitle_page_connection = 0; - m_radiotext_updated_connection = 0; + m_rds_decoder_event_connection = 0; + m_video_event_connection = 0; m_timeshift_active = 1; - m_event((iPlayableService*)this, evSeekableStatusChanged); - eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference; r.path = m_timeshift_file; m_cue = new eCueSheet(); m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */ - updateDecoder(); /* mainly to switch off PCR */ + + eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now."); + pause(); + updateDecoder(); /* mainly to switch off PCR, and to set pause */ + + m_event((iPlayableService*)this, evSeekableStatusChanged); } void eDVBServicePlay::updateDecoder() @@ -2117,13 +2277,18 @@ void eDVBServicePlay::updateDecoder() m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary); if (m_decoder) m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection); + m_teletext_parser = new eDVBTeletextParser(m_decode_demux); + m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection); + m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux); + m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection); + } else + { + m_teletext_parser = 0; + m_subtitle_parser = 0; } + if (m_cue) m_cue->setDecodingDemux(m_decode_demux, m_decoder); - m_teletext_parser = new eDVBTeletextParser(m_decode_demux); - m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection); - m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux); - m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection); } if (m_decoder) @@ -2172,9 +2337,9 @@ void eDVBServicePlay::updateDecoder() ePtr data_demux; if (!h.getDataDemux(data_demux)) { - m_radiotext_parser = new eDVBRadioTextParser(data_demux); - m_radiotext_parser->connectUpdatedRadiotext(slot(*this, &eDVBServicePlay::radioTextUpdated), m_radiotext_updated_connection); - m_radiotext_parser->start(apid); + m_rds_decoder = new eDVBRdsDecoder(data_demux); + m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection); + m_rds_decoder->start(apid); } } } @@ -2188,7 +2353,10 @@ void eDVBServicePlay::updateDecoder() if (!m_is_primary) m_decoder->setTrickmode(1); - m_decoder->start(); + if (m_is_paused) + m_decoder->preroll(); + else + m_decoder->start(); if (vpid > 0 && vpid < 0x2000) ; @@ -2204,7 +2372,7 @@ void eDVBServicePlay::updateDecoder() // how we can do this better? // update cache pid when the user changed the audio track or video track // TODO handling of difference audio types.. default audio types.. - + /* don't worry about non-existing services, nor pvr services */ if (m_dvb_service && !m_is_pvr) { @@ -2695,11 +2863,51 @@ void eDVBServicePlay::setPCMDelay(int delay) void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event) { - eDebug("!!!!!!!!!! Video Event type %d, aspect %d, %dx%d", event.type, event.aspect, event.width, event.height); memcpy(&m_videoEventData, &event, sizeof(iTSMPEGDecoder::videoEvent)); m_event((iPlayableService*)this, evVideoSizeChanged); } +RESULT eDVBServicePlay::stream(ePtr &ptr) +{ + ptr = this; + return 0; +} + +PyObject *eDVBServicePlay::getStreamingData() +{ + eDVBServicePMTHandler::program program; + if (m_service_handler.getProgramInfo(program)) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject *r = program.createPythonObject(); + ePtr demux; + if (!m_service_handler.getDataDemux(demux)) + { + uint8_t demux_id; + demux->getCADemuxID(demux_id); + + PyDict_SetItemString(r, "demux", PyInt_FromLong(demux_id)); + } + + return r; +} + + DEFINE_REF(eDVBServicePlay) +PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w) +{ + switch (w) + { + case iServiceInformation::sTransponderData: + return eStaticServiceDVBInformation().getInfoObject(ref, w); + default: + break; + } + return iStaticServiceInformation::getInfoObject(ref, w); +} + eAutoInitPtr init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");