diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index d094d980a..22ac94b95 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -202,6 +202,7 @@ bouquetname.hdtv HD Kanäle bouquetname.new Neue Kanäle bouquetname.other Unbekannter Provider bouquetname.removed Gelöschte Kanäle +bouquetname.webtv WebTV Kanäle buildinfo.compiled_on Build Host buildinfo.compiled_with Compiler Version buildinfo.compiler_flags Compiler Flags @@ -235,6 +236,7 @@ channellist.keep_numbers Dauerhafte Kanalnummern channellist.make_hdlist Erzeuge Bouquet mit HD-Kanälen channellist.make_newlist Erzeuge Bouquet mit neuen Kanälen channellist.make_removedlist Erzeuge Bouquet mit gelöschten Kanälen +channellist.make_webtvlist Erzeuge Bouquet mit WebTV-Kanälen channellist.new_zap_mode Quickzap in Liste channellist.new_zap_mode_active aktiv channellist.new_zap_mode_allow erlauben @@ -989,6 +991,7 @@ menu.hint_lua Plugins ausführen menu.hint_make_hdlist Bei aktiver Option wird ein Bouquet namens 'HD' erzeugt, in dem alle HD-Sender zusammengefasst sind menu.hint_make_newlist Nach einer Kanalsuche wird ein Bouquet namens 'neue Kanäle' erzeugt menu.hint_make_removedlist Nach einer Kanalsuche wird ein Bouquet namens 'gelöschte Kanäle' erzeugt +menu.hint_make_webtvlist Bei aktiver Option wird ein Bouquet namens 'WebTV' erzeugt, in dem alle WebTV-Sender zusammengefasst sind menu.hint_manage_settings Sichern, Wiederherstellen und Auslieferungszustand wiederherstellen menu.hint_mb Ihre Aufnahmen menu.hint_media Abspielen von Musik, Internetradio und Filmen; Betrachten Sie Bilder @@ -1253,6 +1256,7 @@ menu.hint_volume Wählen Sie die Anzeigeoptionen für die Lautstärke menu.hint_volume_digits Zifferndarstellung der Lautstärkeanzeige ein- oder ausschalten menu.hint_volume_pos Wählen Sie die Position der Lautstärkeanzeige aus menu.hint_volume_size Wählen Sie die Höhe der Lautstärkeanzeige +menu.hint_webtv_setup Hier konfigurierte WebTV-Kanäle finden Sie in der Kanalverwaltung. menu.hint_window_size Kanalliste, EPG-Infos und einige andere Fenster werden mit diesem Faktor skaliert menu.hint_ytplay Wiedergabe von ausgewählten Youtube Feeds menu.hint_zap_cycle Wählen Sie, ob nur innerhalb des aktiven Bouquets umgeschaltet werden kann @@ -2135,6 +2139,10 @@ videomenu.videoformat_149 14:9 videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Videosystem +webtv.head WebTV +webtv.xml WebTV-XML-Dateien +webtv.xml.add XML-Datei hinzufügen +webtv.xml.del XML-Datei entfernen window_size Fenstergröße in % wizard.initial_settings Grundeinstellungen gefunden wizard.install_settings Kanalliste für Astra 19.2°E installieren? diff --git a/data/locale/english.locale b/data/locale/english.locale index ebd7a1664..6e826836b 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -202,6 +202,7 @@ bouquetname.hdtv HD channels bouquetname.new New channels bouquetname.other Unknown provider bouquetname.removed Removed channels +bouquetname.webtv WebTV channels buildinfo.compiled_on Build Host buildinfo.compiled_with Compiler version buildinfo.compiler_flags Compiler flags @@ -235,6 +236,7 @@ channellist.keep_numbers Persistent channel numbers channellist.make_hdlist Create list of HD channels channellist.make_newlist Create list of new channels channellist.make_removedlist Create list of removed channels +channellist.make_webtvlist Create list of WebTV channels channellist.new_zap_mode Quickzap in list channellist.new_zap_mode_active active channellist.new_zap_mode_allow allow @@ -1031,6 +1033,7 @@ menu.hint_lua Run Plugins menu.hint_make_hdlist Auto-create HD channel list based on\nchannel type and name menu.hint_make_newlist Create list of recently added channels menu.hint_make_removedlist Create list of recently removed channels +menu.hint_make_webtvlist Auto-create WebTV channel list based on\nchannel type and name menu.hint_manage_settings Backup, restore, revert to defaults\nFactory box reset menu.hint_mb Your recordings menu.hint_media Play movies, audio files\nWatch pictures @@ -1300,6 +1303,7 @@ menu.hint_volume Configure Volume GUI options menu.hint_volume_digits Numeric display of the volumebar on/off menu.hint_volume_pos Select volume indicator position menu.hint_volume_size Select volume indicator height +menu.hint_webtv_setup WebTV channels configured here will be available in the standard channel lists. menu.hint_window_size Channellist, EPG-infos and some other windows are scaled by this factor menu.hint_ytplay Play selected youtube feeds menu.hint_zap_cycle When swithing channels, stay in current bouquet @@ -2188,6 +2192,10 @@ videomenu.videoformat_149 14:9 videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Digital video mode +webtv.head WebTV +webtv.xml WebTV XML files +webtv.xml.add Add XML file +webtv.xml.del Remove XML file window_size Window size in % wizard.initial_settings Initial settings found wizard.install_settings Do you want to install channels for Astra 19.2°E? diff --git a/src/daemonc/remotecontrol.cpp b/src/daemonc/remotecontrol.cpp index 37b063865..c2ecea76b 100644 --- a/src/daemonc/remotecontrol.cpp +++ b/src/daemonc/remotecontrol.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -118,6 +119,7 @@ int CRemoteControl::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data //printf("[neutrino] timeout EVT_ZAP current %llx data %llx\n", current_channel_id, *(t_channel_id *)data); if ((*(t_channel_id *)data) != current_channel_id) { g_InfoViewer->chanready = 0; + CMoviePlayerGui::getInstance().stopPlayBack(); g_Zapit->zapTo_serviceID_NOWAIT(current_channel_id ); //g_Sectionsd->setServiceChanged(current_channel_id, false); @@ -345,10 +347,12 @@ int CRemoteControl::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data else if (msg == NeutrinoMessages::EVT_TUNE_COMPLETE) { t_channel_id chid = *(t_channel_id *)data; printf("CRemoteControl::handleMsg: EVT_TUNE_COMPLETE (%016" PRIx64 ")\n", chid); - if(chid) + if(chid && !IS_WEBTV(chid)) g_Sectionsd->setServiceChanged( chid, true ); +#if 0 else g_Sectionsd->setServiceChanged( current_channel_id, true ); +#endif return messages_return::handled; } //else if (msg == NeutrinoMessages::EVT_ZAP_FAILED || msg == NeutrinoMessages::EVT_ZAP_SUB_FAILED) @@ -617,6 +621,7 @@ const std::string & CRemoteControl::setSubChannel(const int numSub, const bool f g_InfoViewer->chanready = 0; g_RCInput->killTimer(scrambled_timer); + CMoviePlayerGui::getInstance().stopPlayBack(); g_Zapit->zapTo_subServiceID_NOWAIT( current_sub_channel_id ); // Houdini: to restart reading the private EPG when switching to a new option //g_Sectionsd->setServiceChanged( current_sub_channel_id , true ); @@ -697,6 +702,7 @@ void CRemoteControl::zapTo_ChannelID(const t_channel_id channel_id, const std::s g_RCInput->killTimer(scrambled_timer); //dvbsub_pause(true); CZapit::getInstance()->Abort(); + CMoviePlayerGui::getInstance().stopPlayBack(); g_Zapit->zapTo_serviceID_NOWAIT(channel_id); zap_completion_timeout = now + ZAP_GUARD_TIME; @@ -736,5 +742,6 @@ void CRemoteControl::radioMode() void CRemoteControl::tvMode() { +printf("CRemoteControl::tvMode\n"); g_Zapit->setMode( CZapitClient::MODE_TV ); } diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index 3a5783584..f99d6ce18 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -1077,6 +1077,10 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 *msg = NeutrinoMessages::EVT_BACK_ZAP_COMPLETE; *data = (neutrino_msg_data_t) p; break; + case CZapitClient::EVT_WEBTV_ZAP_COMPLETE: + *msg = NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE; + *data = (neutrino_msg_data_t) p; + break; default: printf("[neutrino] event INITID_ZAPIT - unknown eventID 0x%x\n", emsg.eventID ); } diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 836632b71..260e6eb8e 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -937,7 +937,7 @@ bool CRecordManager::Record(const CTimerd::RecordingInfo * const eventinfo, cons printf("%s channel_id %" PRIx64 " epg: %" PRIx64 ", apidmode 0x%X\n", __func__, eventinfo->channel_id, eventinfo->epgID, eventinfo->apids); - if (g_settings.recording_type == CNeutrinoApp::RECORDING_OFF) + if (g_settings.recording_type == CNeutrinoApp::RECORDING_OFF || IS_WEBTV(eventinfo->channel_id)) return false; #if 1 // FIXME test @@ -1576,18 +1576,19 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend * /* if allocateFE was successful, full zapTo_serviceID * needed, if record frontend same as live, and its on different TP */ - bool found = (live_fe != frontend) || SAME_TRANSPONDER(live_channel_id, channel_id); + bool found = (live_fe != frontend) || IS_WEBTV(live_channel_id) || SAME_TRANSPONDER(live_channel_id, channel_id); + + /* stop all streams on that fe, if we going to change transponder */ + if (!frontend->sameTsidOnid(channel->getTransponderId())) + CStreamManager::getInstance()->StopStream(frontend); + if(found) { - /* stop stream for this channel */ - CStreamManager::getInstance()->StopStream(channel_id); ret = g_Zapit->zapTo_record(channel_id) > 0; printf("%s found same tp, zapTo_record channel_id %" PRIx64 " result %d\n", __func__, channel_id, ret); } else { printf("%s mode %d last_mode %d getLastMode %d\n", __FUNCTION__, mode, last_mode, CNeutrinoApp::getInstance()->getLastMode()); StopAutoRecord(false); - /* stop all streams */ - CStreamManager::getInstance()->StopStream(); if (mode != last_mode && (last_mode != NeutrinoMessages::mode_standby || mode != CNeutrinoApp::getInstance()->getLastMode())) { CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , mode | NeutrinoMessages::norezap ); mode_changed = true; diff --git a/src/driver/scanepg.cpp b/src/driver/scanepg.cpp index f60410aea..bca8721e2 100644 --- a/src/driver/scanepg.cpp +++ b/src/driver/scanepg.cpp @@ -85,7 +85,7 @@ void CEpgScan::AddBouquet(CChannelList * clist) { for (unsigned i = 0; i < clist->Size(); i++) { CZapitChannel * chan = clist->getChannelFromIndex(i); - if (scanned.find(chan->getTransponderId()) == scanned.end()) + if (!IS_WEBTV(chan->getChannelID()) && scanned.find(chan->getTransponderId()) == scanned.end()) scanmap.insert(eit_scanmap_pair_t(chan->getTransponderId(), chan->getChannelID())); } } @@ -179,10 +179,11 @@ void CEpgScan::AddTransponders() bool CEpgScan::CheckMode() { + bool webtv = IS_WEBTV(CZapit::getInstance()->GetCurrentChannelID()); if ((g_settings.epg_scan_mode == CEpgScan::MODE_OFF) || (standby && !(g_settings.epg_scan_mode & MODE_STANDBY)) || (!standby && !(g_settings.epg_scan_mode & MODE_LIVE)) - || (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1))) { + || (!standby && !webtv && (CFEManager::getInstance()->getEnabledCount() <= 1))) { return false; } return true; @@ -244,6 +245,11 @@ int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) scan_in_progress = true; AddTransponders(); INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); +#if 0 + t_channel_id chid = *(t_channel_id *)data; + if (IS_WEBTV(chid)) + Next(); +#endif return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { @@ -303,7 +309,7 @@ void CEpgScan::EnterStandby() void CEpgScan::Next() { - bool locked = false; + bool llocked = false, plocked = false; next_chid = 0; @@ -331,13 +337,18 @@ void CEpgScan::Next() CFrontend *pip_fe = NULL; #endif if (!standby) { - locked = true; - live_fe = CZapit::getInstance()->GetLiveFrontend(); - CFEManager::getInstance()->lockFrontend(live_fe); + bool webtv = IS_WEBTV(CZapit::getInstance()->GetCurrentChannelID()); + if (!webtv) { + llocked = true; + live_fe = CZapit::getInstance()->GetLiveFrontend(); + CFEManager::getInstance()->lockFrontend(live_fe); + } #ifdef ENABLE_PIP pip_fe = CZapit::getInstance()->GetPipFrontend(); - if (pip_fe && pip_fe != live_fe) + if (pip_fe /* && pip_fe != live_fe*/) { + plocked = true; CFEManager::getInstance()->lockFrontend(pip_fe); + } #endif } _repeat: @@ -360,13 +371,13 @@ _repeat: if (!next_chid && ((g_settings.epg_scan == SCAN_SEL) && AddSelected())) goto _repeat; - if (locked) { + if (llocked) CFEManager::getInstance()->unlockFrontend(live_fe); #ifdef ENABLE_PIP - if (pip_fe && pip_fe != live_fe) - CFEManager::getInstance()->unlockFrontend(pip_fe); + if (plocked) + CFEManager::getInstance()->unlockFrontend(pip_fe); #endif - } + CFEManager::getInstance()->Unlock(); if (next_chid) g_Zapit->zapTo_epg(next_chid, standby); diff --git a/src/driver/streamts.cpp b/src/driver/streamts.cpp index b30247b47..118d7f625 100644 --- a/src/driver/streamts.cpp +++ b/src/driver/streamts.cpp @@ -282,7 +282,7 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) t_channel_id chid = channel->getChannelID(); if (CRecordManager::getInstance()->RecordingStatus(chid)) { - printf("CStreamManager::Parse: channel %llx recorded, aborting..\n", chid); + printf("CStreamManager::FindFrontend: channel %llx recorded, aborting..\n", chid); return frontend; } @@ -294,19 +294,22 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) CFEManager::getInstance()->Lock(); - bool unlock = true; - CFEManager::getInstance()->lockFrontend(live_fe); + bool unlock = false; + if (!IS_WEBTV(live_channel_id)) { + unlock = true; + CFEManager::getInstance()->lockFrontend(live_fe); + } OpenThreads::ScopedLock m_lock(mutex); for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) - frontends.insert(it->second->frontend); + frontends.insert(it->second->frontend); for (std::set::iterator ft = frontends.begin(); ft != frontends.end(); ft++) CFEManager::getInstance()->lockFrontend(*ft); frontend = CFEManager::getInstance()->allocateFE(channel, true); - if (frontend == NULL) { + if (unlock && frontend == NULL) { unlock = false; CFEManager::getInstance()->unlockFrontend(live_fe); frontend = CFEManager::getInstance()->allocateFE(channel, true); @@ -315,7 +318,7 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) CFEManager::getInstance()->Unlock(); if (frontend) { - bool found = (live_fe != frontend) || SAME_TRANSPONDER(live_channel_id, chid); + bool found = (live_fe != frontend) || IS_WEBTV(live_channel_id) || SAME_TRANSPONDER(live_channel_id, chid); bool ret = false; if (found) ret = zapit.zapTo_record(chid) > 0; @@ -410,6 +413,8 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFro return false; printf("CStreamManager::Parse: channel_id %llx [%s]\n", chid, channel->getName().c_str()); + if (IS_WEBTV(chid)) + return false; frontend = FindFrontend(channel); if (!frontend) { @@ -436,13 +441,13 @@ void CStreamManager::AddPids(int fd, CZapitChannel *channel, stream_pids_t &pids CGenPsi psi; for (stream_pids_t::iterator it = pids.begin(); it != pids.end(); ++it) { if (*it == channel->getVideoPid()) { - printf("CStreamManager::Parse: genpsi vpid %x (%d)\n", *it, channel->type); + printf("CStreamManager::AddPids: genpsi vpid %x (%d)\n", *it, channel->type); psi.addPid(*it, channel->type == 1 ? EN_TYPE_AVC : channel->type == 2 ? EN_TYPE_HEVC : EN_TYPE_VIDEO, 0); } else { for (int i = 0; i < channel->getAudioChannelCount(); i++) { if (*it == channel->getAudioChannel(i)->pid) { CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType; - printf("CStreamManager::Parse: genpsi apid %x (%d)\n", *it, atype); + printf("CStreamManager::AddPids: genpsi apid %x (%d)\n", *it, atype); if (channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3) { psi.addPid(*it, EN_TYPE_AUDIO_EAC3, atype, channel->getAudioChannel(i)->description.c_str()); } else { @@ -622,6 +627,21 @@ bool CStreamManager::StopStream(t_channel_id channel_id) return ret; } +bool CStreamManager::StopStream(CFrontend * fe) +{ + bool ret = false; + for (streammap_iterator_t it = streams.begin(); it != streams.end(); ) { + if (it->second->frontend == fe) { + delete it->second; + streams.erase(it++); + ret = true; + } else { + ++it; + } + } + return ret; +} + bool CStreamManager::StreamStatus(t_channel_id channel_id) { bool ret; diff --git a/src/driver/streamts.h b/src/driver/streamts.h index e1a6915a1..23f74c33d 100644 --- a/src/driver/streamts.h +++ b/src/driver/streamts.h @@ -96,6 +96,7 @@ class CStreamManager : public OpenThreads::Thread bool Start(int port = 0); bool Stop(); bool StopStream(t_channel_id channel_id = 0); + bool StopStream(CFrontend * fe); bool StreamStatus(t_channel_id channel_id = 0); bool SetPort(int newport); int GetPort() { return port; } diff --git a/src/driver/vfd.cpp b/src/driver/vfd.cpp index b290cd96d..3acc7d98a 100644 --- a/src/driver/vfd.cpp +++ b/src/driver/vfd.cpp @@ -351,13 +351,13 @@ void CVFD::showRCLock(int /*duration*/) { } -void CVFD::showVolume(const char vol, const bool /*perform_update*/) +void CVFD::showVolume(const char vol, const bool force_update) { static int oldpp = 0; if(!has_lcd) return; ShowIcon(FP_ICON_MUTE, muted); - if(vol == volume) + if(!force_update && vol == volume) return; volume = vol; @@ -368,7 +368,7 @@ void CVFD::showVolume(const char vol, const bool /*perform_update*/) int pp = (int) round((double) vol * (double) 8 / (double) 100); if(pp > 8) pp = 8; - if(oldpp != pp) { + if(force_update || oldpp != pp) { printf("CVFD::showVolume: %d, bar %d\n", (int) vol, pp); int i; int j = 0x00000200; diff --git a/src/eitd/sectionsd.cpp b/src/eitd/sectionsd.cpp index d4121cb72..2fc063272 100644 --- a/src/eitd/sectionsd.cpp +++ b/src/eitd/sectionsd.cpp @@ -2684,6 +2684,9 @@ showProfiling("sectionsd_getChannelEvents start"); for (MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey::iterator e = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.begin(); e != mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end(); ++e) { uniqueNow = (*e)->get_channel_id(); + if (IS_WEBTV(uniqueNow)) + continue; + if (uniqueNow != uniqueOld) { diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 113cadcec..689902fc3 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -114,6 +114,7 @@ libneutrino_gui_a_SOURCES = \ vfd_setup.cpp \ videosettings.cpp \ volumebar.cpp \ + webtv_setup.cpp \ zapit_setup.cpp if ENABLE_TEST_MENU diff --git a/src/gui/audio_select.cpp b/src/gui/audio_select.cpp index 57109bc03..7186927dc 100644 --- a/src/gui/audio_select.cpp +++ b/src/gui/audio_select.cpp @@ -47,6 +47,7 @@ extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */ extern CAudioSetupNotifier * audioSetupNotifier; #include +#include #include #include @@ -93,6 +94,11 @@ int CAudioSelectMenuHandler::exec(CMenuTarget* parent, const std::string &action int CAudioSelectMenuHandler::doMenu () { + int mode = CNeutrinoApp::getInstance()->getMode(); + if (mode == NeutrinoMessages::mode_webtv) { + CMoviePlayerGui::getInstance().selectAudioPid(); + return menu_return::RETURN_EXIT; + } CMenuWidget AudioSelector(LOCALE_AUDIOSELECTMENUE_HEAD, NEUTRINO_ICON_AUDIO, width); CSubtitleChangeExec SubtitleChanger; diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index 1c55c85d8..e7058415b 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -85,6 +85,7 @@ extern CPictureViewer * g_PicViewer; #include #endif +#include #include extern cVideo * videoDecoder; @@ -282,15 +283,14 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey) m_frameBuffer->saveBackgroundImage(); // set zapit in lock mode - g_Zapit->lockPlayBack(); - videoDecoder->setBlank(true); + CNeutrinoApp::getInstance()->stopPlayBack(true); + videoDecoder->ShowPicture(DATADIR "/neutrino/icons/mp3.jpg"); // tell neutrino we're in audio mode + m_LastMode = CNeutrinoApp::getInstance()->getMode(); CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , NeutrinoMessages::mode_audio ); - m_LastMode=(CNeutrinoApp::getInstance()->getLastMode()); - // Stop sectionsd g_Sectionsd->setPauseScanning(true); @@ -310,7 +310,8 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey) if (my_system(AUDIOPLAYER_END_SCRIPT) != 0) perror(AUDIOPLAYER_END_SCRIPT " failed"); - g_Zapit->unlockPlayBack(); + //g_Zapit->unlockPlayBack(); + CZapit::getInstance()->EnablePlayback(true); // Start Sectionsd g_Sectionsd->setPauseScanning(false); videoDecoder->StopPicture(); diff --git a/src/gui/bedit/bouqueteditor_channels.cpp b/src/gui/bedit/bouqueteditor_channels.cpp index 6e304a261..38b63080a 100644 --- a/src/gui/bedit/bouqueteditor_channels.cpp +++ b/src/gui/bedit/bouqueteditor_channels.cpp @@ -133,6 +133,8 @@ void CBEChannelWidget::paintItem(int pos) g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x+ 20 + iconoffset, ypos + iheight - (iheight-fheight)/2, width- iconoffset- 20, (*Channels)[current]->getName(), color); if((*Channels)[current]->scrambled) frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x+width- 15 - 28, ypos, fheight); + else if (!(*Channels)[current]->getUrl().empty()) + frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x+width- 15 - 28, ypos, fheight); } } diff --git a/src/gui/bedit/bouqueteditor_chanselect.cpp b/src/gui/bedit/bouqueteditor_chanselect.cpp index eaf4da5e5..bbce973d2 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.cpp +++ b/src/gui/bedit/bouqueteditor_chanselect.cpp @@ -143,6 +143,8 @@ void CBEChannelSelectWidget::paintItem(uint32_t itemNr, int paintNr, bool pselec g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x + 20 + iconoffset, ypos + iheight - (iheight-fheight)/2, width - 20 - iconoffset, Channels[itemNr]->getName(), color); if(Channels[itemNr]->scrambled) frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x+width- 15 - 28, ypos, fheight); + else if (!Channels[itemNr]->getUrl().empty()) + frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x+width- 15 - 28, ypos, fheight); } } diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 051670ba0..c04a01d1c 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -717,7 +717,7 @@ int CChannelList::show() } #endif - if((g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) && SameTP()) { + if((g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) && SameTP() && !IS_WEBTV(chanlist[selected]->channel_id)) { printf("[neutrino channellist] start direct recording...\n"); hide(); if (!CRecordManager::getInstance()->Record(chanlist[selected]->channel_id)) { @@ -1144,7 +1144,8 @@ bool CChannelList::adjustToChannelID(const t_channel_id channel_id, bool bToo) int new_mode = old_mode; bool has_channel; first_mode_found = -1; - if(CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_tv) { + if(CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_tv + || CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_webtv) { has_channel = TVfavList->adjustToChannelID(channel_id); if (has_channel && first_mode_found < 0) first_mode_found = LIST_MODE_FAV; @@ -1639,7 +1640,7 @@ void CChannelList::paintDetails(int index) frameBuffer->paintBoxRel(x+1, y + height + 1, full_width-2, info_height - 2, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE);//round frameBuffer->paintBoxFrame(x, y + height, full_width, info_height, 2, COL_MENUCONTENT_PLUS_6, RADIUS_LARGE); - if (!p_event->description.empty()) { + if (!IS_WEBTV(chanlist[index]->channel_id) && !p_event->description.empty()) { char cNoch[50] = {0}; // UTF-8 char cSeit[50] = {0}; // UTF-8 @@ -1703,7 +1704,10 @@ void CChannelList::paintDetails(int index) g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]->RenderString(x+ full_width- 10- seit_len, y+ height+ 5+ fheight, seit_len, cSeit, colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_MENUCONTENTDARK_TEXT); g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]->RenderString(x+ full_width- 10- noch_len, y+ height+ 5+ fdescrheight+ fheight, noch_len, cNoch, colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_MENUCONTENTDARK_TEXT); } - if(g_settings.channellist_foot == 0) { + if (IS_WEBTV(chanlist[index]->channel_id)) { + g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x+ 10, y+ height+ 5+ fheight, full_width - 30, chanlist[index]->getDesc(), colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_MENUCONTENTDARK_TEXT, 0, true); + g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x+ 10, y+ height+ 5+ 2*fheight + fdescrheight, full_width - 30, chanlist[index]->getUrl(), COL_MENUCONTENTDARK_TEXT, 0, true); + } else if(g_settings.channellist_foot == 0) { transponder t; CServiceManager::getInstance()->GetTransponder(chanlist[index]->getTransponderId(), t); @@ -1853,6 +1857,8 @@ void CChannelList::paintButtonBar(bool is_current) //manage record button if (g_settings.recording_type == RECORDING_OFF) continue; + if (IS_WEBTV(chanlist[selected]->channel_id)) + continue; if (!displayNext){ if (do_record){ Button[bcnt].locale = LOCALE_MAINMENU_RECORDING_STOP; @@ -1869,7 +1875,7 @@ void CChannelList::paintButtonBar(bool is_current) if (i == 5) { //manage pip button #ifdef ENABLE_PIP - if (!is_current) + if (!is_current || IS_WEBTV(chanlist[selected]->channel_id)) #endif continue; } @@ -2001,15 +2007,17 @@ void CChannelList::paintItem(int pos, const bool firstpaint) } #endif //calculating icons + bool isWebTV = !chan->getUrl().empty(); + const char *icon = isWebTV ? NEUTRINO_ICON_STREAMING : NEUTRINO_ICON_SCRAMBLED; int icon_x = (x+width-15-2) - RADIUS_LARGE/2; int r_icon_w; int s_icon_h=0; int s_icon_w=0; - frameBuffer->getIconSize(NEUTRINO_ICON_SCRAMBLED, &s_icon_w, &s_icon_h); + frameBuffer->getIconSize(icon, &s_icon_w, &s_icon_h); r_icon_w = ChannelList_Rec; int r_icon_x = icon_x; - //paint scramble icon - if(chan->scrambled) - if (frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, icon_x - s_icon_w, ypos, fheight))//ypos + (fheight - 16)/2); + //paint icon + if(chan->scrambled || isWebTV) + if (frameBuffer->paintIcon(icon, icon_x - s_icon_w, ypos, fheight))//ypos + (fheight - 16)/2); r_icon_x = r_icon_x - s_icon_w; //paint recording icon @@ -2226,16 +2234,10 @@ bool CChannelList::SameTP(t_channel_id channel_id) { bool iscurrent = true; -#if 0 - if(CNeutrinoApp::getInstance()->recordingstatus && !autoshift) - iscurrent = (channel_id >> 16) == (rec_channel_id >> 16); -#endif if(CNeutrinoApp::getInstance()->recordingstatus) { -#if 0 - if(channel_id == 0) - channel_id = chanlist[selected]->channel_id; - iscurrent = CRecordManager::getInstance()->SameTransponder(channel_id); -#endif + if (IS_WEBTV(channel_id)) + return true; + CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(channel_id); if(channel) iscurrent = SameTP(channel); @@ -2252,10 +2254,15 @@ bool CChannelList::SameTP(CZapitChannel * channel) if(CNeutrinoApp::getInstance()->recordingstatus) { if(channel == NULL) channel = chanlist[selected]; + + if (IS_WEBTV(channel->getChannelID())) + return true; + iscurrent = CFEManager::getInstance()->canTune(channel); } return iscurrent; } + std::string CChannelList::MaxChanNr() { zapit_list_it_t chan_it; diff --git a/src/gui/components/cc_item_tvpic.cpp b/src/gui/components/cc_item_tvpic.cpp index 4dc7cd566..40ea55adf 100644 --- a/src/gui/components/cc_item_tvpic.cpp +++ b/src/gui/components/cc_item_tvpic.cpp @@ -95,7 +95,8 @@ void CComponentsPIP::paint(bool do_save_bg) if (!cc_allow_paint) return; - if(CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_tv){ + int mode = CNeutrinoApp::getInstance()->getMode(); + if(mode == NeutrinoMessages::mode_tv || mode == NeutrinoMessages::mode_webtv) { videoDecoder->Pig(pig_x, pig_y, pig_w, pig_h, screen_w, screen_h); } else{ //paint an alternate image if no tv mode available diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index a37e7d297..016c65d7a 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -710,7 +710,7 @@ void CInfoViewer::showTitle (const int ChanNum, const std::string & Channel, con int ChanNumYPos = BoxStartY + ChanHeight; if (g_settings.infobar_sat_display) { - std::string name = CServiceManager::getInstance()->GetSatelliteName(satellitePosition); + std::string name = (IS_WEBTV(channel_id))? "WebTV" : CServiceManager::getInstance()->GetSatelliteName(satellitePosition); int satNameWidth = g_SignalFont->getRenderWidth (name); std::string satname_tmp = name; if (satNameWidth > (ChanWidth - 4)) { @@ -788,6 +788,17 @@ void CInfoViewer::showTitle (const int ChanNum, const std::string & Channel, con if (fileplay) { show_Data (); + } else if (IS_WEBTV(new_channel_id)) { + CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(new_channel_id); + if (channel) { + const char *current = channel->getDesc().c_str(); + const char *next = channel->getUrl().c_str(); + if (!current) { + current = next; + next = ""; + } + display_Info(current, next, true, false, 0, NULL, NULL, NULL, NULL, true, true); + } } else { show_current_next(new_chan,epgpos); } @@ -824,6 +835,7 @@ void CInfoViewer::setInfobarTimeout(int timeout_ext) switch (mode) { case NeutrinoMessages::mode_tv: + case NeutrinoMessages::mode_webtv: timeoutEnd = CRCInput::calcTimeoutEnd (g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR] + timeout_ext); break; case NeutrinoMessages::mode_radio: @@ -1295,7 +1307,7 @@ int CInfoViewer::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) int duration = CMoviePlayerGui::getInstance().GetDuration(); snprintf(runningRest, sizeof(runningRest), "%d / %d %s", (curr_pos + 30000) / 60000, (duration - curr_pos + 30000) / 60000, unit_short_minute); display_Info(NULL, NULL, true, false, CMoviePlayerGui::getInstance().file_prozent, NULL, runningRest); - } else { + } else if (!IS_WEBTV(channel_id)) { show_Data( true ); } } @@ -1395,6 +1407,14 @@ void CInfoViewer::sendNoEpg(const t_channel_id for_channel_id) CSectionsdClient::CurrentNextInfo CInfoViewer::getEPG (const t_channel_id for_channel_id, CSectionsdClient::CurrentNextInfo &info) { + /* to clear the oldinfo for channels without epg, call getEPG() with for_channel_id = 0 */ + if (for_channel_id == 0 || IS_WEBTV(for_channel_id)) + { + oldinfo.current_uniqueKey = 0; + return info; + } + + CEitManager::getInstance()->getCurrentNextServiceKey(for_channel_id, info); //printf("CInfoViewer::getEPG: old uniqueKey %llx new %llx\n", oldinfo.current_uniqueKey, info.current_uniqueKey); diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index 39abc5e48..a0a0834f5 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -220,6 +220,7 @@ void CInfoViewerBB::getBBButtonInfo() bbButtonMaxH = 0; bbButtonMaxX = g_InfoViewer->ChanInfoX; int bbButtonMaxW = 0; + int mode; for (int i = 0; i < CInfoViewerBB::BUTTON_MAX; i++) { int w = 0, h = 0; std::string text, icon; @@ -237,7 +238,8 @@ void CInfoViewerBB::getBBButtonInfo() text = g_settings.usermenu_text[SNeutrinoSettings::BUTTON_GREEN]; if (text == g_Locale->getText(LOCALE_AUDIOSELECTMENUE_HEAD)) text = ""; - if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode() && !CMoviePlayerGui::getInstance().timeshift){ + mode = CNeutrinoApp::getInstance()->getMode(); + if ((mode == NeutrinoMessages::mode_ts || mode == NeutrinoMessages::mode_webtv) && !CMoviePlayerGui::getInstance().timeshift) { text = CMoviePlayerGui::getInstance().CurrentAudioName(); }else if (!g_RemoteControl->current_PIDs.APIDs.empty()) { int selected = g_RemoteControl->current_PIDs.PIDs.selected_apid; diff --git a/src/gui/mediaplayer_setup.cpp b/src/gui/mediaplayer_setup.cpp index f10df62d7..f75671c25 100644 --- a/src/gui/mediaplayer_setup.cpp +++ b/src/gui/mediaplayer_setup.cpp @@ -46,6 +46,7 @@ #include #include +#include #include @@ -94,6 +95,13 @@ int CMediaPlayerSetup::showMediaPlayerSetup() CAudioPlayerSetup asetup; mediaSetup->addItem(new CMenuForwarder(LOCALE_AUDIOPLAYER_NAME, true, NULL, &asetup, "", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN)); + CWebTVSetup wsetup; + CMenuForwarder *mf; + int shortcut = 1; + mf = new CMenuForwarder(LOCALE_WEBTV_HEAD, true, NULL, &wsetup, "show_menu", CRCInput::convertDigitToKey(shortcut++)); + mf->setHint(NEUTRINO_ICON_HINT_TVMODE /* FIXME */, LOCALE_MENU_HINT_WEBTV_SETUP); + mediaSetup->addItem(mf); + int res = mediaSetup->exec (NULL, ""); selected = mediaSetup->getSelected(); delete mediaSetup; diff --git a/src/gui/miscsettings_menu.cpp b/src/gui/miscsettings_menu.cpp index 36763fb4e..e21503050 100644 --- a/src/gui/miscsettings_menu.cpp +++ b/src/gui/miscsettings_menu.cpp @@ -514,11 +514,18 @@ int CMiscMenue::showMiscSettingsMenuChanlist() CMenuWidget * ms_chanlist = new CMenuWidget(LOCALE_MISCSETTINGS_HEAD, NEUTRINO_ICON_SETTINGS, width, MN_WIDGET_ID_MISCSETUP_CHANNELLIST); ms_chanlist->addIntroItems(LOCALE_MISCSETTINGS_CHANNELLIST); + bool tmp1 = g_settings.make_hd_list; + bool tmp2 = g_settings.make_webtv_list; + CMenuOptionChooser * mc; mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_MAKE_HDLIST , &g_settings.make_hd_list , OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); mc->setHint("", LOCALE_MENU_HINT_MAKE_HDLIST); ms_chanlist->addItem(mc); + mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_MAKE_WEBTVLIST , &g_settings.make_webtv_list , OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_MAKE_WEBTVLIST); + ms_chanlist->addItem(mc); + mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_MAKE_NEWLIST, &g_settings.make_new_list , OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); mc->setHint("", LOCALE_MENU_HINT_MAKE_NEWLIST); ms_chanlist->addItem(mc); @@ -544,6 +551,8 @@ int CMiscMenue::showMiscSettingsMenuChanlist() ms_chanlist->addItem(mc); int res = ms_chanlist->exec(NULL, ""); delete ms_chanlist; + if (tmp1 != g_settings.make_hd_list|| tmp2 != g_settings.make_webtv_list) + g_Zapit->reinitChannels(); return res; } diff --git a/src/gui/movieplayer.cpp b/src/gui/movieplayer.cpp index 0af132b54..75cbd856a 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -74,9 +74,12 @@ extern CInfoClock *InfoClock; #define ISO_MOUNT_POINT "/media/iso" CMoviePlayerGui* CMoviePlayerGui::instance_mp = NULL; +OpenThreads::Mutex CMoviePlayerGui::bgmutex; +OpenThreads::Condition CMoviePlayerGui::cond; CMoviePlayerGui& CMoviePlayerGui::getInstance() { + OpenThreads::ScopedLock m_lock(bgmutex); if ( !instance_mp ) { instance_mp = new CMoviePlayerGui(); @@ -92,7 +95,8 @@ CMoviePlayerGui::CMoviePlayerGui() CMoviePlayerGui::~CMoviePlayerGui() { - playback->Close(); + //playback->Close(); + stopPlayBack(); delete moviebrowser; delete filebrowser; delete bookmarkmanager; @@ -103,6 +107,7 @@ CMoviePlayerGui::~CMoviePlayerGui() void CMoviePlayerGui::Init(void) { playing = false; + stopped = true; frameBuffer = CFrameBuffer::getInstance(); @@ -152,29 +157,36 @@ void CMoviePlayerGui::Init(void) max_y = 0; ext_subs = false; iso_file = false; + bgThread = 0; } void CMoviePlayerGui::cutNeutrino() { + printf("%s: playing %d isUPNP %d\n", __func__, playing, isUPNP); if (playing) return; playing = true; /* set g_InfoViewer update timer to 1 sec, should be reset to default from restoreNeutrino->set neutrino mode */ - g_InfoViewer->setUpdateTimer(1000 * 1000); + if (!isWebTV) + g_InfoViewer->setUpdateTimer(1000 * 1000); if (isUPNP) return; g_Zapit->lockPlayBack(); - g_Sectionsd->setPauseScanning(true); + if (!isWebTV) + g_Sectionsd->setPauseScanning(true); - CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, NeutrinoMessages::mode_ts); - m_LastMode = (CNeutrinoApp::getInstance()->getLastMode() | NeutrinoMessages::norezap); + m_LastMode = (CNeutrinoApp::getInstance()->getMode() | NeutrinoMessages::norezap); +printf("%s: save mode %d\n", __func__, m_LastMode & NeutrinoMessages::mode_mask);fflush(stdout); + int new_mode = NeutrinoMessages::norezap | (isWebTV ? NeutrinoMessages::mode_webtv : NeutrinoMessages::mode_ts); + CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, new_mode); } void CMoviePlayerGui::restoreNeutrino() { + printf("%s: playing %d isUPNP %d\n", __func__, playing, isUPNP); if (!playing) return; @@ -186,7 +198,21 @@ void CMoviePlayerGui::restoreNeutrino() g_Zapit->unlockPlayBack(); g_Sectionsd->setPauseScanning(false); - CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, m_LastMode); +printf("%s: restore mode %d\n", __func__, m_LastMode & NeutrinoMessages::mode_mask);fflush(stdout); + if (m_LastMode == NeutrinoMessages::mode_tv) + g_RCInput->postMsg(NeutrinoMessages::EVT_PROGRAMLOCKSTATUS, 0x200, false); + + if (m_LastMode != NeutrinoMessages::mode_unknown) + CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, m_LastMode); + +#if 0 + if (m_LastMode == NeutrinoMessages::mode_tv) { + CZapitChannel *channel = CZapit::getInstance()->GetCurrentChannel(); + if (channel && channel->scrambled) + CZapit::getInstance()->Rezap(); + } +#endif +printf("%s: restoring done.\n", __func__);fflush(stdout); } int CMoviePlayerGui::exec(CMenuTarget * parent, const std::string & actionKey) @@ -207,6 +233,7 @@ int CMoviePlayerGui::exec(CMenuTarget * parent, const std::string & actionKey) timeshift = 0; isHTTP = false; isUPNP = false; + isWebTV = false; if (actionKey == "tsmoviebrowser") { isMovieBrowser = true; @@ -283,7 +310,7 @@ void CMoviePlayerGui::updateLcd() if (isMovieBrowser && strlen(p_movie_info->epgTitle.c_str()) && strncmp(p_movie_info->epgTitle.c_str(), "not", 3)) name = p_movie_info->epgTitle; else - name = file_name; + name = pretty_name; switch (playstate) { case CMoviePlayerGui::PAUSE: @@ -356,25 +383,26 @@ void CMoviePlayerGui::Cleanup() is_file_player = false; p_movie_info = NULL; autoshot_done = false; + currentaudioname = "Unk"; } void CMoviePlayerGui::makeFilename() { - if(file_name.empty()) { - std::string::size_type pos = full_name.find_last_of('/'); + if(pretty_name.empty()) { + std::string::size_type pos = file_name.find_last_of('/'); if(pos != std::string::npos) { - file_name = full_name.substr(pos+1); - std::replace(file_name.begin(), file_name.end(), '_', ' '); + pretty_name = file_name.substr(pos+1); + std::replace(pretty_name.begin(), pretty_name.end(), '_', ' '); } else - file_name = full_name; + pretty_name = file_name; - if(file_name.substr(0,14)=="videoplayback?"){//youtube name + if(pretty_name.substr(0,14)=="videoplayback?"){//youtube name if(!p_movie_info->epgTitle.empty()) - file_name = p_movie_info->epgTitle; + pretty_name = p_movie_info->epgTitle; else - file_name = ""; + pretty_name = ""; } - printf("CMoviePlayerGui::makeFilename: full_name [%s] file_name [%s]\n", full_name.c_str(), file_name.c_str()); + printf("CMoviePlayerGui::makeFilename: file_name [%s] pretty_name [%s]\n", file_name.c_str(), pretty_name.c_str()); } } @@ -384,8 +412,8 @@ bool CMoviePlayerGui::SelectFile() menu_ret = menu_return::RETURN_REPAINT; Cleanup(); + pretty_name = ""; file_name = ""; - full_name = ""; printf("CMoviePlayerGui::SelectFile: isBookmark %d timeshift %d isMovieBrowser %d\n", isBookmark, timeshift, isMovieBrowser); wakeup_hdd(g_settings.network_nfs_recordingdir.c_str()); @@ -393,7 +421,7 @@ bool CMoviePlayerGui::SelectFile() if (timeshift) { t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); p_movie_info = CRecordManager::getInstance()->GetMovieInfo(live_channel_id); - full_name = CRecordManager::getInstance()->GetFileName(live_channel_id) + ".ts"; + file_name = CRecordManager::getInstance()->GetFileName(live_channel_id) + ".ts"; fillPids(); ret = true; } @@ -404,7 +432,7 @@ bool CMoviePlayerGui::SelectFile() bookmarkmanager->flush(); return false; } - full_name = theBookmark->getUrl(); + file_name = theBookmark->getUrl(); sscanf(theBookmark->getTime(), "%lld", &startposition); startposition *= 1000; ret = true; @@ -419,17 +447,17 @@ bool CMoviePlayerGui::SelectFile() // get the movie info handle (to be used for e.g. bookmark handling) p_movie_info = moviebrowser->getCurrentMovieInfo(); if (moviebrowser->getMode() == MB_SHOW_RECORDS) { - full_name = file->Name; + file_name = file->Name; } else if (moviebrowser->getMode() == MB_SHOW_YT) { - full_name = file->Url; + file_name = file->Url; is_file_player = true; } fillPids(); // get the start position for the movie startposition = 1000 * moviebrowser->getCurrentStartPos(); - printf("CMoviePlayerGui::SelectFile: file %s start %d apid %X atype %d vpid %x vtype %d\n", full_name.c_str(), startposition, currentapid, currentac3, vpid, vtype); + printf("CMoviePlayerGui::SelectFile: file %s start %d apid %X atype %d vpid %x vtype %d\n", file_name.c_str(), startposition, currentapid, currentac3, vpid, vtype); ret = true; } @@ -444,7 +472,7 @@ bool CMoviePlayerGui::SelectFile() CFile *file; if ((file = filebrowser->getSelectedFile()) != NULL) { is_file_player = true; - full_name = file->Name.c_str(); + file_name = file->Name.c_str(); ret = true; if(file->getType() == CFile::FILE_PLAYLIST) parsePlaylist(file); @@ -469,8 +497,8 @@ void *CMoviePlayerGui::ShowStartHint(void *arg) set_threadname(__func__); CMoviePlayerGui *caller = (CMoviePlayerGui *)arg; CHintBox *hintbox = NULL; - if(!caller->file_name.empty()){ - hintbox = new CHintBox(LOCALE_MOVIEPLAYER_STARTING, caller->file_name.c_str(), 450, NEUTRINO_ICON_MOVIEPLAYER); + if(!caller->pretty_name.empty()){ + hintbox = new CHintBox(LOCALE_MOVIEPLAYER_STARTING, caller->pretty_name.c_str(), 450, NEUTRINO_ICON_MOVIEPLAYER); hintbox->paint(); } while (caller->showStartingHint) { @@ -478,9 +506,18 @@ void *CMoviePlayerGui::ShowStartHint(void *arg) neutrino_msg_data_t data; g_RCInput->getMsg(&msg, &data, 1); if (msg == CRCInput::RC_home || msg == CRCInput::RC_stop) { - if(caller->playback) - caller->playback->RequestAbort(); - } else if (msg != CRCInput::RC_timeout && msg > CRCInput::RC_MaxRC) { + caller->playback->RequestAbort(); + } +#if 0 + else if (caller->isWebTV) { + CNeutrinoApp::getInstance()->handleMsg(msg, data); + } +#endif + else if (caller->isWebTV && ((msg == (neutrino_msg_t) g_settings.key_quickzap_up ) || (msg == (neutrino_msg_t) g_settings.key_quickzap_down))) { + caller->playback->RequestAbort(); + g_RCInput->postMsg(msg, data); + } + else if (msg != NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE && msg != CRCInput::RC_timeout && msg > CRCInput::RC_MaxRC) { CNeutrinoApp::getInstance()->handleMsg(msg, data); } } @@ -491,34 +528,137 @@ void *CMoviePlayerGui::ShowStartHint(void *arg) return NULL; } +void* CMoviePlayerGui::bgPlayThread(void *arg) +{ + set_threadname(__func__); + CMoviePlayerGui *mp = (CMoviePlayerGui *) arg; + +#if 0 + while (mp->playback->IsPlaying()) + usleep(100000); +#endif + bgmutex.lock(); + cond.wait(&bgmutex); + bgmutex.unlock(); + printf("%s: play end...\n", __func__); + mp->PlayFileEnd(); + pthread_exit(NULL); +} + +bool CMoviePlayerGui::PlayBackgroundStart(const std::string &file, const std::string &name, t_channel_id chan) +{ + printf("%s: starting...\n", __func__); + OpenThreads::ScopedLock m_lock(mutex); + if (g_settings.parentallock_prompt != PARENTALLOCK_PROMPT_NEVER) { + int age = -1; + const char *ages[] = { "18+", "16+", "12+", "6+", "0+", NULL }; + int agen[] = { 18, 16, 12, 6, 0 }; + for (int i = 0; ages[i] && age < 0; i++) { + const char *n = name.c_str(); + char *h = (char *) n; + while ((age < 0) && (h = strstr(h, ages[i]))) + if ((h == n) || !isdigit(*(h - 1))) + age = agen[i]; + } + if (age > -1 && age >= g_settings.parentallock_lockage) { + //CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::EVT_PROGRAMLOCKSTATUS, (neutrino_msg_data_t) age); + g_RCInput->postMsg(NeutrinoMessages::EVT_PROGRAMLOCKSTATUS, age, false); + } + } + + Cleanup(); +#if 0 + isYT = false; + isNK = false; +#endif + isWebTV = true; + is_file_player = 1; + isMovieBrowser = false; + isUPNP = false; + isBookmark = false; + timeshift = TSHIFT_MODE_OFF; + isHTTP = true; + + file_name = file; + pretty_name = name; + MI_MOVIE_INFO _mi; + mi.epgTitle = name; + mi.epgChannel = file; + mi.epgId = chan; + p_movie_info = &mi; + + bool res = PlayFileStart(); + if (res) { + if (pthread_create (&bgThread, 0, CMoviePlayerGui::bgPlayThread, this)) + fprintf(stderr, "ERROR: pthread_create(%s)\n", __func__); + } else + PlayFileEnd(); + printf("%s: this %x started: res %d thread %x\n", __func__, (int) this, res, (int) CMoviePlayerGui::bgPlayThread);fflush(stdout); + return res; +} + +void CMoviePlayerGui::stopPlayBack(void) +{ + printf("%s: stopping...\n", __func__); + playback->RequestAbort(); + + if (bgThread) { + printf("%s: this %x join background thread %x\n", __func__, (int) this, (int) CMoviePlayerGui::bgPlayThread);fflush(stdout); + cond.broadcast(); + pthread_join(bgThread, NULL); + bgThread = 0; + } + printf("%s: stopped\n", __func__); +} + +void CMoviePlayerGui::Pause(bool b) +{ + if (b && (playstate == CMoviePlayerGui::PAUSE)) + b = !b; + if (b) { + playback->SetSpeed(0); + playstate = CMoviePlayerGui::PAUSE; + } else { + playback->SetSpeed(1); + playstate = CMoviePlayerGui::PLAY; + } +} + void CMoviePlayerGui::PlayFile(void) { - neutrino_msg_t msg; - neutrino_msg_data_t data; + mutex.lock(); + PlayFileStart(); + mutex.unlock(); + PlayFileLoop(); + PlayFileEnd(); +} + +bool CMoviePlayerGui::PlayFileStart(void) +{ menu_ret = menu_return::RETURN_REPAINT; - bool first_start = true; - bool time_forced = false; - bool update_lcd = true; - int eof = 0; + time_forced = false; //CTimeOSD FileTime; position = 0, duration = 0; speed = 1; + printf("%s: starting...\n", __func__); + stopPlayBack(); + playstate = CMoviePlayerGui::STOPPED; printf("Startplay at %d seconds\n", startposition/1000); handleMovieBrowser(CRCInput::RC_nokey, position); cutNeutrino(); + if (isWebTV) + videoDecoder->setBlank(true); clearSubtitle(); playback->Open(is_file_player ? PLAYMODE_FILE : PLAYMODE_TS); printf("IS FILE PLAYER: %s\n", is_file_player ? "true": "false" ); - MI_MOVIE_INFO mi; - if (p_movie_info) { if (timeshift != TSHIFT_MODE_OFF) { // p_movie_info may be invalidated by CRecordManager while we're still using it. Create and use a copy. @@ -537,7 +677,7 @@ void CMoviePlayerGui::PlayFile(void) showStartingHint = true; pthread_create(&thrStartHint, NULL, CMoviePlayerGui::ShowStartHint, this); } - bool res = playback->Start((char *) full_name.c_str(), vpid, vtype, currentapid, currentac3, duration); + bool res = playback->Start((char *) file_name.c_str(), vpid, vtype, currentapid, currentac3, duration); if (thrStartHint) { showStartingHint = false; pthread_join(thrStartHint, NULL); @@ -590,12 +730,20 @@ void CMoviePlayerGui::PlayFile(void) playback->SetSpeed(1); } } + getCurrentAudioName(is_file_player, currentaudioname); if (is_file_player) selectAutoLang(); CAudioMute::getInstance()->enableMuteIcon(true); InfoClock->enableInfoClock(true); + return res; +} +void CMoviePlayerGui::PlayFileLoop(void) +{ + bool first_start = true; + bool update_lcd = true; + int eof = 0; while (playstate >= CMoviePlayerGui::PLAY) { if (update_lcd) { @@ -607,6 +755,8 @@ void CMoviePlayerGui::PlayFile(void) first_start = false; } + neutrino_msg_t msg; + neutrino_msg_data_t data; g_RCInput->getMsg(&msg, &data, 10); // 1 secs.. if ((playstate >= CMoviePlayerGui::PLAY) && (timeshift || (playstate != CMoviePlayerGui::PAUSE))) { @@ -694,7 +844,7 @@ void CMoviePlayerGui::PlayFile(void) update_lcd = true; clearSubtitle(); } else if (msg == (neutrino_msg_t) g_settings.mpkey_audio) { - selectAudioPid(is_file_player); + selectAudioPid(); update_lcd = true; clearSubtitle(); } else if ( msg == (neutrino_msg_t) g_settings.mpkey_subtitle) { @@ -828,7 +978,11 @@ void CMoviePlayerGui::PlayFile(void) handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_stop, position); } } +} +void CMoviePlayerGui::PlayFileEnd(bool restore) +{ + printf("%s: stopping, this %x thread %x\n", __func__, (int) this, (int) CMoviePlayerGui::bgPlayThread);fflush(stdout); FileTime.kill(); clearSubtitle(); @@ -843,10 +997,13 @@ void CMoviePlayerGui::PlayFile(void) CVFD::getInstance()->ShowIcon(FP_ICON_PLAY, false); CVFD::getInstance()->ShowIcon(FP_ICON_PAUSE, false); - restoreNeutrino(); + if (restore) + restoreNeutrino(); CAudioMute::getInstance()->enableMuteIcon(false); InfoClock->enableInfoClock(false); + stopped = true; + printf("%s: stopped\n", __func__); } void CMoviePlayerGui::callInfoViewer(/*const int duration, const int curr_pos*/) @@ -858,8 +1015,6 @@ void CMoviePlayerGui::callInfoViewer(/*const int duration, const int curr_pos*/) CNeutrinoApp::getInstance()->channelList->getActiveChannel_ChannelID()); return; } - currentaudioname = "Unk"; - getCurrentAudioName( is_file_player, currentaudioname); if (isMovieBrowser && p_movie_info) { g_InfoViewer->showMovieTitle(playstate, p_movie_info->epgEpgId >>16, p_movie_info->epgChannel, p_movie_info->epgTitle, p_movie_info->epgInfo1, @@ -868,7 +1023,7 @@ void CMoviePlayerGui::callInfoViewer(/*const int duration, const int curr_pos*/) } /* not moviebrowser => use the filename as title */ - g_InfoViewer->showMovieTitle(playstate, 0, file_name, "", "", duration, position); + g_InfoViewer->showMovieTitle(playstate, 0, pretty_name, "", "", duration, position); } bool CMoviePlayerGui::getAudioName(int apid, std::string &apidtitle) @@ -957,7 +1112,7 @@ void CMoviePlayerGui::getCurrentAudioName( bool file_player, std::string &audion } } -void CMoviePlayerGui::selectAudioPid(bool file_player) +void CMoviePlayerGui::selectAudioPid() { CMenuWidget APIDSelector(LOCALE_APIDSELECTOR_HEAD, NEUTRINO_ICON_AUDIO); APIDSelector.addIntroItems(); @@ -965,7 +1120,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) int select = -1; CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); - if(file_player && !numpida){ + if(is_file_player && !numpida){ playback->FindAllPids(apids, ac3flags, &numpida, language); if(numpida) currentapid = apids[0]; @@ -976,7 +1131,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) bool defpid = currentapid ? (currentapid == apids[count]) : (count == 0); std::string apidtitle; - if(!file_player){ + if(!is_file_player){ name_ok = getAudioName(apids[count], apidtitle); } else if (!language[count].empty()){ @@ -1021,6 +1176,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) currentapid = apids[select]; currentac3 = ac3flags[select]; playback->SetAPid(currentapid, currentac3); + getCurrentAudioName(is_file_player, currentaudioname); printf("[movieplayer] apid changed to %d type %d\n", currentapid, currentac3); } } @@ -1233,7 +1389,7 @@ void CMoviePlayerGui::handleMovieBrowser(neutrino_msg_t msg, int /*position*/) sprintf(timerstring, "%lld", play_sec); std::string bookmarktime = timerstring; fprintf(stderr, "fileposition: %lld timerstring: %s bookmarktime: %s\n", play_sec, timerstring, bookmarktime.c_str()); - bookmarkmanager->createBookmark(full_name, bookmarktime); + bookmarkmanager->createBookmark(file_name, bookmarktime); } else { fprintf(stderr, "too many bookmarks\n"); DisplayErrorMessage(g_Locale->getText(LOCALE_MOVIEPLAYER_TOOMANYBOOKMARKS)); // UTF-8 @@ -1675,6 +1831,7 @@ void CMoviePlayerGui::selectAutoLang() currentapid = apids[pref_idx]; currentac3 = ac3flags[pref_idx]; playback->SetAPid(currentapid, currentac3); + getCurrentAudioName(is_file_player, currentaudioname); } } } @@ -1699,9 +1856,9 @@ void CMoviePlayerGui::parsePlaylist(CFile *file) if ( (url = strstr(cLine, "http://")) || (url = strstr(cLine, "rtmp://")) || (url = strstr(cLine, "rtsp://")) ){ if (url != NULL) { printf("name %s [%d] url: %s\n", name, dur, url); - full_name = url; + file_name = url; if(strlen(name)) - file_name = name; + pretty_name = name; } } } @@ -1714,7 +1871,7 @@ bool CMoviePlayerGui::mountIso(CFile *file) safe_mkdir(ISO_MOUNT_POINT); if (my_system(5, "mount", "-o", "loop", file->Name.c_str(), ISO_MOUNT_POINT) == 0) { makeFilename(); - full_name = "/media/iso"; + file_name = "/media/iso"; iso_file = true; return true; } @@ -1734,7 +1891,7 @@ void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover) if (!cover) snprintf(ending, sizeof(ending) - 1, "_%x.jpg", position); - std::string fname = full_name; + std::string fname = file_name; std::string::size_type pos = fname.find_last_of('.'); if (pos != std::string::npos) { fname.replace(pos, fname.length(), ending); diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index 9c65e5268..627df8f2e 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -50,6 +50,9 @@ #include #include +#include +#include + class CMoviePlayerGui : public CMenuTarget { public: @@ -68,10 +71,11 @@ class CMoviePlayerGui : public CMenuTarget CFrameBuffer * frameBuffer; int m_LastMode; - std::string full_name; std::string file_name; + std::string pretty_name; std::string currentaudioname; bool playing; + bool time_forced; CMoviePlayerGui::state playstate; int speed; int startposition; @@ -101,14 +105,17 @@ class CMoviePlayerGui : public CMenuTarget bool isMovieBrowser; bool isHTTP; bool isUPNP; + bool isWebTV; bool showStartingHint; CMovieBrowser* moviebrowser; MI_MOVIE_INFO * p_movie_info; + MI_MOVIE_INFO mi; const static short MOVIE_HINT_BOX_TIMER = 5; // time to show bookmark hints in seconds /* playback from file */ bool is_file_player; bool iso_file; + bool stopped; CFileBrowser * filebrowser; CFileFilter tsfilefilter; std::string Path_local; @@ -119,11 +126,19 @@ class CMoviePlayerGui : public CMenuTarget CBookmarkManager * bookmarkmanager; bool isBookmark; + OpenThreads::Mutex mutex; + static OpenThreads::Mutex bgmutex; + static OpenThreads::Condition cond; + pthread_t bgThread; + cPlayback *playback; static CMoviePlayerGui* instance_mp; void Init(void); void PlayFile(); + bool PlayFileStart(); + void PlayFileLoop(); + void PlayFileEnd(bool restore = true); void cutNeutrino(); void restoreNeutrino(); @@ -131,7 +146,6 @@ class CMoviePlayerGui : public CMenuTarget void callInfoViewer(/*const int duration, const int pos*/); void fillPids(); bool getAudioName(int pid, std::string &apidtitle); - void selectAudioPid(bool file_player); void getCurrentAudioName( bool file_player, std::string &audioname); void addAudioFormat(int count, std::string &apidtitle, bool& enabled ); @@ -152,6 +166,7 @@ class CMoviePlayerGui : public CMenuTarget void Cleanup(); static void *ShowStartHint(void *arg); + static void* bgPlayThread(void *arg); CMoviePlayerGui(const CMoviePlayerGui&) {}; CMoviePlayerGui(); @@ -171,7 +186,12 @@ class CMoviePlayerGui : public CMenuTarget void UpdatePosition(); int timeshift; int file_prozent; - void SetFile(std::string &name, std::string &file) { file_name = name; full_name = file; } + void SetFile(std::string &name, std::string &file) { pretty_name = name; file_name = file; } + bool PlayBackgroundStart(const std::string &file, const std::string &name, t_channel_id chan); + void stopPlayBack(void); + void setLastMode(int m) { m_LastMode = m; } + void Pause(bool b = true); + void selectAudioPid(); }; #endif diff --git a/src/gui/pictureviewer.cpp b/src/gui/pictureviewer.cpp index 366d31c3b..366bfafb2 100644 --- a/src/gui/pictureviewer.cpp +++ b/src/gui/pictureviewer.cpp @@ -72,6 +72,7 @@ #include #include +#include #include extern cVideo * videoDecoder; extern CInfoClock *InfoClock; @@ -186,14 +187,13 @@ int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & actionKey) if (parent) parent->hide(); + // remember last mode + m_LastMode = CNeutrinoApp::getInstance()->getMode(); // tell neutrino we're in pic_mode CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , NeutrinoMessages::mode_pic ); - // remember last mode - m_LastMode=(CNeutrinoApp::getInstance()->getLastMode() | NeutrinoMessages::norezap); if (!audioplayer) { // !!! why? !!! - //g_Zapit->setStandby(true); - g_Zapit->lockPlayBack(); + CNeutrinoApp::getInstance()->stopPlayBack(true); // blank background screen videoDecoder->setBlank(true); @@ -215,8 +215,8 @@ int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & actionKey) m_viewer->Cleanup(); if (!audioplayer) { // !!! why? !!! - //g_Zapit->setStandby(false); - g_Zapit->unlockPlayBack(); + //g_Zapit->unlockPlayBack(); + CZapit::getInstance()->EnablePlayback(true); // Start Sectionsd g_Sectionsd->setPauseScanning(false); diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index d20deb1cf..18b95bdea 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,7 @@ #include #include #include + extern cVideo * videoDecoder; #define NEUTRINO_SCAN_START_SCRIPT CONFIGDIR "/scan.start" @@ -197,7 +199,7 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) return menu_return::RETURN_EXIT_ALL; CRecordManager::getInstance()->StopAutoRecord(); - g_Zapit->stopPlayBack(); + CNeutrinoApp::getInstance()->stopPlayBack(); #ifdef ENABLE_PIP CZapit::getInstance()->StopPip(); #endif diff --git a/src/gui/streaminfo2.cpp b/src/gui/streaminfo2.cpp index aa3b49df0..2d0f3645e 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -471,7 +471,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) average_bitrate_offset = spaceoffset; - if(channel->getVideoPid() && !(videoDecoder->getBlank())){ + if((channel->getVideoPid() || IS_WEBTV(channel->getChannelID())) && !(videoDecoder->getBlank())){ videoDecoder->getPictureInfo(xres, yres, framerate); if (yres == 1088) yres = 1080; @@ -574,7 +574,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) g_Font[font_info]->RenderString(xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); - sprintf (buf, "%s", + sprintf (buf, "%s", IS_WEBTV(channel->getChannelID()) ? g_Locale->getText(LOCALE_WEBTV_HEAD) : CServiceManager::getInstance()->GetSatelliteName(channel->getSatellitePosition()).c_str()); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index 8209599d2..a1d92cbd4 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -1194,7 +1194,8 @@ int CTimerList::newTimer() for (int j = 0; j < (int) channels.size(); j++) { char cChannelId[3+16+1+1]; sprintf(cChannelId, "SC:" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS ",", channels[j]->channel_id); - mwtv->addItem(new CMenuForwarder(channels[j]->getName().c_str(), true, NULL, this, (std::string(cChannelId) + channels[j]->getName()).c_str(), CRCInput::RC_nokey, NULL, channels[j]->scrambled ? NEUTRINO_ICON_SCRAMBLED : NULL)); + mwtv->addItem(new CMenuForwarder(channels[j]->getName(), true, NULL, this, (std::string(cChannelId) + channels[j]->getName()).c_str(), CRCInput::RC_nokey, NULL, channels[j]->scrambled ? NEUTRINO_ICON_SCRAMBLED : (channels[j]->getUrl().empty() ? NULL : NEUTRINO_ICON_STREAMING))); + } if (!channels.empty()) mctv.addItem(new CMenuForwarder(g_bouquetManager->Bouquets[i]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) : g_bouquetManager->Bouquets[i]->Name.c_str() /*g_bouquetManager->Bouquets[i]->Name.c_str()*/, true, NULL, mwtv)); @@ -1204,7 +1205,7 @@ int CTimerList::newTimer() for (int j = 0; j < (int) channels.size(); j++) { char cChannelId[3+16+1+1]; sprintf(cChannelId, "SC:" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS ",", channels[j]->channel_id); - mwradio->addItem(new CMenuForwarder(channels[j]->getName().c_str(), true, NULL, this, (std::string(cChannelId) + channels[j]->getName()).c_str(), CRCInput::RC_nokey, NULL, channels[j]->scrambled ? NEUTRINO_ICON_SCRAMBLED : NULL)); + mwradio->addItem(new CMenuForwarder(channels[j]->getName(), true, NULL, this, (std::string(cChannelId) + channels[j]->getName()).c_str(), CRCInput::RC_nokey, NULL, channels[j]->scrambled ? NEUTRINO_ICON_SCRAMBLED : (channels[j]->getUrl().empty() ? NULL : NEUTRINO_ICON_STREAMING))); } if (!channels.empty()) mcradio.addItem(new CMenuForwarder(g_bouquetManager->Bouquets[i]->Name.c_str(), true, NULL, mwradio)); diff --git a/src/gui/upnpbrowser.cpp b/src/gui/upnpbrowser.cpp index 3a714e055..1daae1b43 100644 --- a/src/gui/upnpbrowser.cpp +++ b/src/gui/upnpbrowser.cpp @@ -97,10 +97,8 @@ int CUpnpBrowserGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/ if (parent) parent->hide(); - g_Zapit->stopPlayBack(); - //g_Zapit->lockPlayBack(); - CZapit::getInstance()->EnablePlayback(false); - + /* stop playback, disable playback start */ + CNeutrinoApp::getInstance()->stopPlayBack(true); videoDecoder->ShowPicture(DATADIR "/neutrino/icons/mp3.jpg"); // tell neutrino we're in audio mode @@ -139,14 +137,11 @@ int CUpnpBrowserGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/ if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) CAudioPlayer::getInstance()->stop(); - //g_Zapit->setStandby(false); - // Start Sectionsd g_Sectionsd->setPauseScanning(false); videoDecoder->StopPicture(); m_frameBuffer->Clear(); - //g_Zapit->unlockPlayBack(); CZapit::getInstance()->EnablePlayback(true); CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE , m_LastMode); g_RCInput->postMsg(NeutrinoMessages::SHOW_INFOBAR, 0); diff --git a/src/gui/webtv_setup.cpp b/src/gui/webtv_setup.cpp new file mode 100644 index 000000000..7aae92959 --- /dev/null +++ b/src/gui/webtv_setup.cpp @@ -0,0 +1,127 @@ +/* + WebTV Setup + + (C) 2012-2013 by martii + + + License: GPL + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __USE_FILE_OFFSET64 1 +#include "filebrowser.h" +#include +#include +#include +#include +#include +#include +#include +#include "webtv_setup.h" + +CWebTVSetup::CWebTVSetup() +{ + width = w_max (40, 10); + selected = -1; + item_offset = 0; + changed = false; +} + +#define CWebTVSetupFooterButtonCount 2 +static const struct button_label CWebTVSetupFooterButtons[CWebTVSetupFooterButtonCount] = { + { NEUTRINO_ICON_BUTTON_RED, LOCALE_WEBTV_XML_DEL }, + { NEUTRINO_ICON_BUTTON_GREEN, LOCALE_WEBTV_XML_ADD } +}; + +int CWebTVSetup::exec(CMenuTarget* parent, const std::string & actionKey) +{ + int res = menu_return::RETURN_REPAINT; + + if(actionKey == "d" /* delete */) { + selected = m->getSelected(); + if (selected >= item_offset) { + m->removeItem(selected); + m->hide(); + selected = m->getSelected(); + changed = true; + } + return res; + } + if(actionKey == "c" /* change */) { + CFileBrowser fileBrowser; + CFileFilter fileFilter; + fileFilter.addFilter("xml"); + fileBrowser.Filter = &fileFilter; + selected = m->getSelected(); + CMenuItem* item = m->getItem(selected); + CMenuForwarder *f = static_cast(item); + std::string dirname(f->getName()); + if (fileBrowser.exec(dirname.substr(0, dirname.rfind('/')).c_str())) { + f->setName(fileBrowser.getSelectedFile()->Name); + changed = true; + } + return res; + } + if(actionKey == "a" /* add */) { + CFileBrowser fileBrowser; + CFileFilter fileFilter; + fileFilter.addFilter("xml"); + fileBrowser.Filter = &fileFilter; + if (fileBrowser.exec("/") == true) { + std::string s = fileBrowser.getSelectedFile()->Name; + m->addItem(new CMenuForwarder(s, true, NULL, this, "c")); + changed = true; + } + return res; + } + + if(parent) + parent->hide(); + + Show(); + + return res; +} + +void CWebTVSetup::Show() +{ + item_offset = 0; + + m = new CMenuWidget(LOCALE_WEBTV_HEAD, NEUTRINO_ICON_MOVIEPLAYER, width); + m->addKey(CRCInput::RC_red, this, "d"); + m->addKey(CRCInput::RC_green, this, "a"); + m->setSelected(selected); + m->addIntroItems(LOCALE_EPGPLUS_OPTIONS, LOCALE_WEBTV_XML); + item_offset = m->getItemsCount(); + for (std::list::iterator it = g_settings.webtv_xml.begin(); it != g_settings.webtv_xml.end(); ++it) + m->addItem(new CMenuForwarder(*it, true, NULL, this, "c")); + m->setFooter(CWebTVSetupFooterButtons, CWebTVSetupFooterButtonCount); + m->exec(NULL, ""); + m->hide(); + if (changed) { + g_settings.webtv_xml.clear(); + for (int i = item_offset; i < m->getItemsCount(); i++) { + CMenuItem *item = m->getItem(i); + CMenuForwarder *f = static_cast(item); + g_settings.webtv_xml.push_back(f->getName()); + } + g_Zapit->reinitChannels(); + changed = false; + } + selected = m->getSelected(); + delete m; +} +// vim:ts=4 diff --git a/src/gui/webtv_setup.h b/src/gui/webtv_setup.h new file mode 100644 index 000000000..5ad1519c1 --- /dev/null +++ b/src/gui/webtv_setup.h @@ -0,0 +1,43 @@ +/* + WebTV setup menue + + Copyright (C) 2012-2013 martii + + License: GPL + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __webtv_setup_h__ +#define __webtv_setup_h__ + +#include +#include +#include + +class CWebTVSetup : public CMenuTarget +{ + private: + int width; + int selected; + int item_offset; + bool changed; + CMenuWidget *m; + public: + CWebTVSetup(); + int exec(CMenuTarget* parent, const std::string & actionKey); + void Show(); +}; +#endif diff --git a/src/gui/zapit_setup.cpp b/src/gui/zapit_setup.cpp index eb368339f..f67d8e799 100644 --- a/src/gui/zapit_setup.cpp +++ b/src/gui/zapit_setup.cpp @@ -178,7 +178,9 @@ int CSelectChannelWidget::InitZapitChannelHelper(CZapitClient::channelsMode mode char cChannelId[60] = {0}; snprintf(cChannelId, sizeof(cChannelId), "ZC%c:%d|%" PRIx64 "#", (mode==CZapitClient::MODE_TV)?'T':'R', channel->number, channel->channel_id); - CMenuForwarder * chan_item = new CMenuForwarder(channel->getName().c_str(), true, NULL, this, (std::string(cChannelId) + channel->getName()).c_str(), CRCInput::RC_nokey, NULL, channel->scrambled ?NEUTRINO_ICON_SCRAMBLED:NULL); + CMenuForwarder * chan_item = new CMenuForwarder(channel->getName(), true, NULL, this, + (std::string(cChannelId) + channel->getName()).c_str(), CRCInput::RC_nokey, NULL, + channel->scrambled ? NEUTRINO_ICON_SCRAMBLED: (channel->getUrl().empty() ? NULL : NEUTRINO_ICON_STREAMING)); chan_item->setItemButton(NEUTRINO_ICON_BUTTON_OKAY, true); mwtv->addItem(chan_item); diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 32204a41b..5bb0ff660 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -379,6 +379,7 @@ int CNeutrinoApp::loadSetup(const char * fname) #endif g_settings.make_hd_list = configfile.getInt32("make_hd_list", 1); + g_settings.make_webtv_list = configfile.getInt32("make_webtv_list", 1); g_settings.make_new_list = configfile.getInt32("make_new_list", 1); g_settings.make_removed_list = configfile.getInt32("make_removed_list", 1); g_settings.keep_channel_numbers = configfile.getInt32("keep_channel_numbers", 0); @@ -643,6 +644,21 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.plugin_hdd_dir = configfile.getString( "plugin_hdd_dir", "/media/sda1/plugins" ); g_settings.logo_hdd_dir = configfile.getString( "logo_hdd_dir", "/media/sda1/logos" ); + int webtv_count = configfile.getInt32("webtv_xml_count", 0); + if (webtv_count) { + for (int i = 0; i < webtv_count; i++) { + std::string k = "webtv_xml_" + to_string(i); + std::string webtv_xml = configfile.getString(k, ""); + if (webtv_xml.empty()) + continue; + g_settings.webtv_xml.push_back(webtv_xml); + } + } else { + std::string webtv_xml = configfile.getString("webtv_xml", WEBTV_XML); + if (!file_size(webtv_xml.c_str())) + g_settings.webtv_xml.push_back(webtv_xml); + } + loadKeys(); g_settings.timeshift_pause = configfile.getInt32( "timeshift_pause", 1 ); @@ -667,7 +683,7 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.channellist_progressbar_design = configfile.getInt32("channellist_progressbar_design", g_settings.progressbar_design); g_settings.channellist_foot = configfile.getInt32("channellist_foot" , 1);//default next Event g_settings.channellist_new_zap_mode = configfile.getInt32("channellist_new_zap_mode", 1); - g_settings.channellist_sort_mode = configfile.getInt32("channellist_sort_mode", 0);//sort mode: alpha, freq, sat + g_settings.channellist_sort_mode = configfile.getInt32("channellist_sort_mode", 0);//sort mode: alpha, freq, sat g_settings.channellist_numeric_adjust = configfile.getInt32("channellist_numeric_adjust", 0); g_settings.channellist_show_channellogo = configfile.getInt32("channellist_show_channellogo", 1); g_settings.channellist_show_numbers = configfile.getInt32("channellist_show_numbers", 1); @@ -924,6 +940,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("ci_ignore_messages", g_settings.ci_ignore_messages); configfile.setInt32( "make_hd_list", g_settings.make_hd_list); + configfile.setInt32( "make_webtv_list", g_settings.make_webtv_list); configfile.setInt32( "make_new_list", g_settings.make_new_list); configfile.setInt32( "make_removed_list", g_settings.make_removed_list); configfile.setInt32( "keep_channel_numbers", g_settings.keep_channel_numbers); @@ -1139,6 +1156,14 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setString ( "plugin_hdd_dir", g_settings.plugin_hdd_dir ); configfile.setString ( "logo_hdd_dir", g_settings.logo_hdd_dir ); + int webtv_count = 0; + for (std::list::iterator it = g_settings.webtv_xml.begin(); it != g_settings.webtv_xml.end(); ++it) { + std::string k = "webtv_xml_" + to_string(webtv_count); + configfile.setString(k, *it); + webtv_count++; + } + configfile.setInt32 ( "webtv_xml_count", g_settings.webtv_xml.size()); + saveKeys(); configfile.setInt32( "timeshift_pause", g_settings.timeshift_pause ); @@ -1429,6 +1454,24 @@ void CNeutrinoApp::channelsInit(bool bOnly) TIMER_STOP("[neutrino] sat took"); } + /* all WebTV channels */ + if (g_settings.make_webtv_list) { + if (CServiceManager::getInstance()->GetAllWebTVChannels(zapitList)) { + /* all channels */ + CBouquet* webtvBouquet = new CBouquet(0, g_Locale->getText(LOCALE_BOUQUETNAME_WEBTV), false, true); + webtvBouquet->channelList->SetChannelList(&zapitList); + TVallList->Bouquets.push_back(webtvBouquet); + /* provider */ + webtvBouquet = new CBouquet(0, g_Locale->getText(LOCALE_BOUQUETNAME_WEBTV), false, true); + webtvBouquet->channelList->SetChannelList(&zapitList); + TVbouquetList->Bouquets.push_back(webtvBouquet); + /* "satellite" */ + webtvBouquet = new CBouquet(0, g_Locale->getText(LOCALE_BOUQUETNAME_WEBTV), false, true); + webtvBouquet->channelList->SetChannelList(&zapitList); + TVsatList->Bouquets.push_back(webtvBouquet); + printf("[neutrino] got %d WebTV channels\n", (int)zapitList.size()); fflush(stdout); + } + } /* all HD channels */ if (g_settings.make_hd_list) { if (CServiceManager::getInstance()->GetAllHDChannels(zapitList)) { @@ -1719,7 +1762,7 @@ void CNeutrinoApp::InitZapper() tuxtxt_init(); t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); - if(channelList->getSize() && live_channel_id) + if(channelList->getSize() && live_channel_id && !IS_WEBTV(live_channel_id)) g_Sectionsd->setServiceChanged(live_channel_id, true ); } @@ -1760,7 +1803,7 @@ void CNeutrinoApp::InitTimerdClient() void CNeutrinoApp::InitZapitClient() { g_Zapit = new CZapitClient; -#define ZAPIT_EVENT_COUNT 28 +#define ZAPIT_EVENT_COUNT 29 const CZapitClient::events zapit_event[ZAPIT_EVENT_COUNT] = { CZapitClient::EVT_ZAP_COMPLETE, @@ -1790,7 +1833,8 @@ void CNeutrinoApp::InitZapitClient() CZapitClient::EVT_SDT_CHANGED, CZapitClient::EVT_PMT_CHANGED, CZapitClient::EVT_TUNE_COMPLETE, - CZapitClient::EVT_BACK_ZAP_COMPLETE + CZapitClient::EVT_BACK_ZAP_COMPLETE, + CZapitClient::EVT_WEBTV_ZAP_COMPLETE, }; for (int i = 0; i < ZAPIT_EVENT_COUNT; i++) @@ -1890,6 +1934,7 @@ TIMER_START(); ZapStart_arg.video_mode = g_settings.video_Mode; ZapStart_arg.ci_clock = g_settings.ci_clock; ZapStart_arg.volume = g_settings.current_volume; + ZapStart_arg.webtv_xml = &g_settings.webtv_xml; /* create decoders, read channels */ bool zapit_init = CZapit::getInstance()->Start(&ZapStart_arg); @@ -2112,7 +2157,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) while( true ) { g_RCInput->getMsg(&msg, &data, 100, ((g_settings.mode_left_right_key_tv == SNeutrinoSettings::VOLUME) && (g_RemoteControl->subChannels.size() < 1)) ? true : false); // 10 secs.. - if( ( mode == mode_tv ) || ( ( mode == mode_radio ) ) ) { + if( ( mode == mode_tv ) || ( mode == mode_radio ) || ( mode == mode_webtv ) ) { if( (msg == NeutrinoMessages::SHOW_EPG) /* || (msg == CRCInput::RC_info) */ ) { InfoClock->enableInfoClock(false); StopSubtitles(); @@ -2188,7 +2233,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) else if( msg == (neutrino_msg_t) g_settings.key_subchannel_down ) g_RemoteControl->subChannelDown(); g_InfoViewer->showSubchan(); - } + } else if ( msg == CRCInput::RC_left || msg == CRCInput::RC_right) { switch (g_settings.mode_left_right_key_tv) { @@ -2204,7 +2249,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) quickZap(msg); break; } - } + } else quickZap( msg ); } @@ -2246,7 +2291,10 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) g_PluginList->startPlugin_by_name(g_settings.onekey_plugin.c_str()); } else if(msg == (neutrino_msg_t) g_settings.key_timeshift) { - CRecordManager::getInstance()->StartTimeshift(); + if (mode == mode_webtv) { + CMoviePlayerGui::getInstance().Pause(); + } else + CRecordManager::getInstance()->StartTimeshift(); } else if (msg == (neutrino_msg_t) g_settings.key_current_transponder){ numericZap( msg ); @@ -2256,7 +2304,7 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID(); if (pip_channel_id) g_Zapit->stopPip(); - else + else StartPip(CZapit::getInstance()->GetCurrentChannelID()); } else if (msg == (neutrino_msg_t) g_settings.key_pip_setup) { @@ -2279,18 +2327,18 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) else if( msg == CRCInput::RC_page_up || msg == CRCInput::RC_page_down) { quickZap(msg == CRCInput::RC_page_up ? CRCInput::RC_right : CRCInput::RC_left); } - else if(msg == CRCInput::RC_rewind) { + else if(msg == CRCInput::RC_rewind && (mode != mode_webtv)) { if(g_RemoteControl->is_video_started) { t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); if(CRecordManager::getInstance()->RecordingStatus(live_channel_id)) CMoviePlayerGui::getInstance().exec(NULL, "rtimeshift"); } } - else if( msg == CRCInput::RC_record) { + else if( msg == CRCInput::RC_record && (mode != mode_webtv)) { if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) CRecordManager::getInstance()->exec(NULL, "Record"); } - else if( msg == CRCInput::RC_stop ) { + else if( msg == CRCInput::RC_stop) { CRecordManager::getInstance()->exec(NULL, "Stop_record"); } else if( msg == CRCInput::RC_red ) { @@ -2542,24 +2590,56 @@ void CNeutrinoApp::standbyToStandby(void) } } +void CNeutrinoApp::stopPlayBack(bool lock) +{ + CMoviePlayerGui::getInstance().stopPlayBack(); + g_Zapit->stopPlayBack(); + if (lock) + CZapit::getInstance()->EnablePlayback(false); +} + +void CNeutrinoApp::lockPlayBack(bool blank) +{ + CMoviePlayerGui::getInstance().stopPlayBack(); + g_Zapit->lockPlayBack(); + if (blank) + videoDecoder->setBlank(true); +} + int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) { int res = 0; neutrino_msg_t msg = _msg; + if(msg == NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE) { + t_channel_id chid = *(t_channel_id *) data; +printf("EVT_WEBTV_ZAP_COMPLETE: %llx\n", chid); + if (mode == mode_standby) { + delete [] (unsigned char*) data; + } else { + CZapitChannel * cc = CZapit::getInstance()->GetCurrentChannel(); + CMoviePlayerGui::getInstance().stopPlayBack(); + if (CMoviePlayerGui::getInstance().PlayBackgroundStart(cc->getUrl(), cc->getName(), cc->getChannelID())) + delete [] (unsigned char*) data; + else + g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_FAILED, data); + } + return messages_return::handled; + } if(msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { CZapit::getInstance()->GetAudioMode(g_settings.audio_AnalogMode); if(g_settings.audio_AnalogMode < 0 || g_settings.audio_AnalogMode > 2) g_settings.audio_AnalogMode = 0; g_RCInput->killTimer(scrambled_timer); + if (mode != mode_webtv) { + scrambled_timer = g_RCInput->addTimer(10*1000*1000, true); + SelectSubtitles(); + StartSubtitles(!g_InfoViewer->is_visible); - scrambled_timer = g_RCInput->addTimer(10*1000*1000, true); - SelectSubtitles(); - StartSubtitles(!g_InfoViewer->is_visible); - - /* update scan settings for manual scan to current channel */ - CScanSetup::getInstance()->updateManualSettings(); + /* update scan settings for manual scan to current channel */ + CScanSetup::getInstance()->updateManualSettings(); + } } if ((msg == NeutrinoMessages::EVT_TIMER)) { if(data == scrambled_timer) { @@ -2604,7 +2684,7 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) /* ================================== KEYS ================================================ */ if( msg == CRCInput::RC_ok || (!g_InfoViewer->virtual_zap_mode && (msg == CRCInput::RC_sat || msg == CRCInput::RC_favorites))) { - if( (mode == mode_tv) || (mode == mode_radio) || (mode == mode_ts)) { + if( (mode == mode_tv) || (mode == mode_radio) || (mode == mode_ts) || (mode == mode_webtv)) { showChannelList(msg); return messages_return::handled; } @@ -2850,8 +2930,10 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) printf("NeutrinoMessages::EVT_STREAM_START: fd %d\n", fd); wakeupFromStandby(); - if (!CStreamManager::getInstance()->AddClient(fd)) + if (!CStreamManager::getInstance()->AddClient(fd)) { close(fd); + g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_STOP, 0); + } return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_STREAM_STOP) { @@ -2878,7 +2960,7 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) if ((!isTVMode) && (mode != mode_radio)) { radioMode(true); } - else if (isTVMode && (mode != mode_tv)) { + else if (isTVMode && (mode != mode_tv) && (mode != mode_webtv)) { tvMode(true); } channelList->zapTo_ChannelID(eventinfo->channel_id); @@ -2957,9 +3039,10 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) return messages_return::handled; } else if( msg == NeutrinoMessages::RELOAD_SETUP ) { - bool tmp = g_settings.make_hd_list; + bool tmp1 = g_settings.make_hd_list; + bool tmp2 = g_settings.make_webtv_list; loadSetup(NEUTRINO_SETTINGS_FILE); - if(tmp != g_settings.make_hd_list) + if(tmp1 != g_settings.make_hd_list || tmp2 != g_settings.make_webtv_list) g_Zapit->reinitChannels(); return messages_return::handled; @@ -3049,7 +3132,7 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) return messages_return::handled; } else if( msg == NeutrinoMessages::CHANGEMODE ) { - + printf("CNeutrinoApp::handleMsg: CHANGEMODE to %d rezap %d\n", data & mode_mask, (data & norezap) != norezap); if((data & mode_mask)== mode_radio) { if( mode != mode_radio ) { radioMode((data & norezap) != norezap); @@ -3078,6 +3161,17 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) lastMode=mode; mode=mode_ts; } + if((data & mode_mask)== mode_webtv) { + lastMode=mode; + mode=mode_webtv; + if ((data & norezap) != norezap) { + CZapitChannel * cc = CZapit::getInstance()->GetCurrentChannel(); + if (cc && IS_WEBTV(cc->getChannelID())) { + CMoviePlayerGui::getInstance().stopPlayBack(); + CMoviePlayerGui::getInstance().PlayBackgroundStart(cc->getUrl(), cc->getName(), cc->getChannelID()); + } + } + } } else if( msg == NeutrinoMessages::VCR_ON ) { if( mode != mode_scart ) { @@ -3164,7 +3258,9 @@ void CNeutrinoApp::ExitRun(const bool /*write_si*/, int retcode) dprintf(DEBUG_INFO, "exit\n"); StopSubtitles(); - g_Zapit->stopPlayBack(); +printf("###################################### CNeutrinoApp::ExitRun: g_Zapit->stopPlayBack()\n");fflush(stdout); + stopPlayBack(); +printf("###################################### CNeutrinoApp::ExitRun: g_Zapit->stopPlayBack() done\n");fflush(stdout); frameBuffer->paintBackground(); videoDecoder->ShowPicture(DATADIR "/neutrino/icons/shutdown.jpg"); @@ -3333,6 +3429,7 @@ void CNeutrinoApp::tvMode( bool rezap ) } bool stopauto = (mode != mode_ts); + int oldmode = mode; mode = mode_tv; #ifdef ENABLE_PIP pipDecoder->Pig(g_settings.pip_x, g_settings.pip_y, @@ -3344,10 +3441,10 @@ void CNeutrinoApp::tvMode( bool rezap ) CRecordManager::getInstance()->StopAutoRecord(); //recordingstatus = 0; } - - frameBuffer->useBackground(false); - frameBuffer->paintBackground(); - + if (oldmode != mode_webtv) { + frameBuffer->useBackground(false); + frameBuffer->paintBackground(); + } g_RemoteControl->tvMode(); SetChannelMode(g_settings.channel_mode); if( rezap ) { @@ -3384,7 +3481,7 @@ void CNeutrinoApp::scartMode( bool bOnOff ) if( lastMode == mode_radio ) { radioMode( false ); } - else if( lastMode == mode_tv ) { + else if( lastMode == mode_tv || lastMode == mode_webtv) { tvMode( false ); } else if( lastMode == mode_standby ) { @@ -3424,8 +3521,9 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) #ifdef ENABLE_PIP g_Zapit->stopPip(); #endif + CMoviePlayerGui::getInstance().stopPlayBack(); bool stream_status = CStreamManager::getInstance()->StreamStatus(); - if((g_settings.epg_scan_mode == CEpgScan::MODE_OFF) && !fromDeepStandby && + if((g_settings.epg_scan_mode == CEpgScan::MODE_OFF) && !fromDeepStandby && !CRecordManager::getInstance()->RecordingStatus() && !stream_status) { g_Zapit->setStandby(true); } else { @@ -3506,6 +3604,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); CVFD::getInstance()->setBacklight(g_settings.backlight_tv); + CVFD::getInstance()->showVolume(g_settings.current_volume, true); CZapit::getInstance()->EnablePlayback(true); g_Zapit->setStandby(false); @@ -3548,6 +3647,11 @@ void CNeutrinoApp::radioMode( bool rezap) { //printf("radioMode: rezap %s\n", rezap ? "yes" : "no"); INFO("rezap %d current mode %d", rezap, mode); + if (mode == mode_webtv) { + CMoviePlayerGui::getInstance().setLastMode(mode_unknown); + CMoviePlayerGui::getInstance().stopPlayBack(); + CVFD::getInstance()->ShowIcon(FP_ICON_TV, false); + } if (mode == mode_tv) { CVFD::getInstance()->ShowIcon(FP_ICON_TV, false); StopSubtitles(); @@ -3592,10 +3696,10 @@ void CNeutrinoApp::switchTvRadioMode(const int prev_mode) tvMode(); else if(prev_mode == mode_radio && mode != mode_radio) radioMode(); - }else { + } else { if (mode == mode_radio ) tvMode(); - else if(mode == mode_tv) + else if(mode == mode_tv || mode == mode_webtv) radioMode(); } } @@ -3814,8 +3918,8 @@ void stop_daemons(bool stopall, bool for_flash) videoDecoder->SetCECMode((VIDEO_HDMI_CEC_MODE)0); } - delete &CMoviePlayerGui::getInstance(); CZapit::getInstance()->Stop(); + delete &CMoviePlayerGui::getInstance(); printf("zapit shutdown done\n"); if (!for_flash) { CVFD::getInstance()->Clear(); diff --git a/src/neutrino.h b/src/neutrino.h index f91a107f5..540428c90 100644 --- a/src/neutrino.h +++ b/src/neutrino.h @@ -145,6 +145,7 @@ public: mode_pic = 6, mode_ts = 7, mode_off = 8, + mode_webtv = 9, mode_mask = 0xFF, norezap = 0x100 }; @@ -216,6 +217,8 @@ public: void zapTo(t_channel_id channel_id); bool wakeupFromStandby(void); void standbyToStandby(void); + void lockPlayBack(bool blank = true); + void stopPlayBack(bool lock = false); }; #endif diff --git a/src/neutrinoMessages.h b/src/neutrinoMessages.h index aa8996d3c..0896f4032 100644 --- a/src/neutrinoMessages.h +++ b/src/neutrinoMessages.h @@ -161,7 +161,8 @@ struct NeutrinoMessages { EVT_BACK_ZAP_COMPLETE = CRCInput::RC_WithData + 25, /* data: (t_channel_id *) */ EVT_HOTPLUG = CRCInput::RC_WithData + 26, /* data: char */ - EVT_FORMAT_DRIVE = CRCInput::RC_WithData + 27 /* data: char */ + EVT_FORMAT_DRIVE = CRCInput::RC_WithData + 27, /* data: char */ + EVT_WEBTV_ZAP_COMPLETE = CRCInput::RC_WithData + 28 /* data: (t_channel_id *) */ }; enum { @@ -173,6 +174,7 @@ struct NeutrinoMessages { mode_audio = 5, mode_pic = 6, mode_ts = 7, + mode_webtv = 9, mode_mask = 0xFF, norezap = 0x100 }; diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp index 83d8f78a1..b9a09482e 100644 --- a/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,7 @@ void CNeutrinoAPI::ZapToChannelId(t_channel_id channel_id) return; } + CMoviePlayerGui::getInstance().stopPlayBack(); if (Zapit->zapTo_serviceID(channel_id) != CZapitClient::ZAP_INVALID_PARAM) Sectionsd->setServiceChanged(channel_id, false); } @@ -200,6 +202,7 @@ void CNeutrinoAPI::ZapToSubService(const char * const target) SCANF_CHANNEL_ID_TYPE, &channel_id); + CMoviePlayerGui::getInstance().stopPlayBack(); if (Zapit->zapTo_subServiceID(channel_id) != CZapitClient::ZAP_INVALID_PARAM) Sectionsd->setServiceChanged(channel_id, false); } diff --git a/src/system/locals.h b/src/system/locals.h index fbe8f1391..d4a853dff 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -229,6 +229,7 @@ typedef enum LOCALE_BOUQUETNAME_NEW, LOCALE_BOUQUETNAME_OTHER, LOCALE_BOUQUETNAME_REMOVED, + LOCALE_BOUQUETNAME_WEBTV, LOCALE_BUILDINFO_COMPILED_ON, LOCALE_BUILDINFO_COMPILED_WITH, LOCALE_BUILDINFO_COMPILER_FLAGS, @@ -262,6 +263,7 @@ typedef enum LOCALE_CHANNELLIST_MAKE_HDLIST, LOCALE_CHANNELLIST_MAKE_NEWLIST, LOCALE_CHANNELLIST_MAKE_REMOVEDLIST, + LOCALE_CHANNELLIST_MAKE_WEBTVLIST, LOCALE_CHANNELLIST_NEW_ZAP_MODE, LOCALE_CHANNELLIST_NEW_ZAP_MODE_ACTIVE, LOCALE_CHANNELLIST_NEW_ZAP_MODE_ALLOW, @@ -1058,6 +1060,7 @@ typedef enum LOCALE_MENU_HINT_MAKE_HDLIST, LOCALE_MENU_HINT_MAKE_NEWLIST, LOCALE_MENU_HINT_MAKE_REMOVEDLIST, + LOCALE_MENU_HINT_MAKE_WEBTVLIST, LOCALE_MENU_HINT_MANAGE_SETTINGS, LOCALE_MENU_HINT_MB, LOCALE_MENU_HINT_MEDIA, @@ -1327,6 +1330,7 @@ typedef enum LOCALE_MENU_HINT_VOLUME_DIGITS, LOCALE_MENU_HINT_VOLUME_POS, LOCALE_MENU_HINT_VOLUME_SIZE, + LOCALE_MENU_HINT_WEBTV_SETUP, LOCALE_MENU_HINT_WINDOW_SIZE, LOCALE_MENU_HINT_YTPLAY, LOCALE_MENU_HINT_ZAP_CYCLE, @@ -2215,6 +2219,10 @@ typedef enum LOCALE_VIDEOMENU_VIDEOFORMAT_169, LOCALE_VIDEOMENU_VIDEOFORMAT_43, LOCALE_VIDEOMENU_VIDEOMODE, + LOCALE_WEBTV_HEAD, + LOCALE_WEBTV_XML, + LOCALE_WEBTV_XML_ADD, + LOCALE_WEBTV_XML_DEL, LOCALE_WINDOW_SIZE, LOCALE_WIZARD_INITIAL_SETTINGS, LOCALE_WIZARD_INSTALL_SETTINGS, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 957a7ece4..be99fc950 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -229,6 +229,7 @@ const char * locale_real_names[] = "bouquetname.new", "bouquetname.other", "bouquetname.removed", + "bouquetname.webtv", "buildinfo.compiled_on", "buildinfo.compiled_with", "buildinfo.compiler_flags", @@ -262,6 +263,7 @@ const char * locale_real_names[] = "channellist.make_hdlist", "channellist.make_newlist", "channellist.make_removedlist", + "channellist.make_webtvlist", "channellist.new_zap_mode", "channellist.new_zap_mode_active", "channellist.new_zap_mode_allow", @@ -1058,6 +1060,7 @@ const char * locale_real_names[] = "menu.hint_make_hdlist", "menu.hint_make_newlist", "menu.hint_make_removedlist", + "menu.hint_make_webtvlist", "menu.hint_manage_settings", "menu.hint_mb", "menu.hint_media", @@ -1327,6 +1330,7 @@ const char * locale_real_names[] = "menu.hint_volume_digits", "menu.hint_volume_pos", "menu.hint_volume_size", + "menu.hint_webtv_setup", "menu.hint_window_size", "menu.hint_ytplay", "menu.hint_zap_cycle", @@ -2215,6 +2219,10 @@ const char * locale_real_names[] = "videomenu.videoformat_169", "videomenu.videoformat_43", "videomenu.videomode", + "webtv.head", + "webtv.xml", + "webtv.xml.add", + "webtv.xml.del", "window_size", "wizard.initial_settings", "wizard.install_settings", diff --git a/src/system/settings.h b/src/system/settings.h index 8f0e0123a..ca5426eef 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -125,6 +125,7 @@ struct SNeutrinoSettings int cpufreq; int standby_cpufreq; int make_hd_list; + int make_webtv_list; int make_new_list; int make_removed_list; int keep_channel_numbers; @@ -168,7 +169,9 @@ struct SNeutrinoSettings std::string network_ntprefresh; int network_ntpenable; std::string ifname; - + + std::list webtv_xml; + //personalize enum PERSONALIZE_SETTINGS //settings.h { diff --git a/src/zapit/include/zapit/channel.h b/src/zapit/include/zapit/channel.h index e3bfb5fe5..e8d1f506a 100644 --- a/src/zapit/include/zapit/channel.h +++ b/src/zapit/include/zapit/channel.h @@ -118,6 +118,10 @@ class CZapitChannel /* channel name */ std::string name; + /* WebTV */ + std::string url; + std::string desc; + /* pids of this channel */ std::vector channelSubs; std::vector audioChannels; @@ -194,6 +198,7 @@ class CZapitChannel /* constructor, desctructor */ CZapitChannel(const std::string & p_name, t_service_id p_sid, t_transport_stream_id p_tsid, t_original_network_id p_onid, unsigned char p_service_type, t_satellite_position p_satellite_position, freq_id_t freq); CZapitChannel(const std::string & p_name, t_channel_id p_channel_id, unsigned char p_service_type, t_satellite_position p_satellite_position, freq_id_t p_freq); + CZapitChannel(const char *p_name, t_channel_id p_channel_id, const char *p_url, const char *p_desc); ~CZapitChannel(void); /* get methods - read only variables */ @@ -209,6 +214,8 @@ class CZapitChannel /* get methods - read and write variables */ const std::string& getName(void) const { return name; } + const std::string& getUrl(void) const { return url; } + const std::string& getDesc(void) const { return desc; } t_satellite_position getSatellitePosition(void) const { return satellitePosition; } unsigned char getAudioChannelCount(void) { return (unsigned char) audioChannels.size(); } unsigned short getPcrPid(void) { return pcrPid; } diff --git a/src/zapit/include/zapit/client/zapitclient.h b/src/zapit/include/zapit/client/zapitclient.h index c25cdd751..59a418192 100644 --- a/src/zapit/include/zapit/client/zapitclient.h +++ b/src/zapit/include/zapit/client/zapitclient.h @@ -73,6 +73,7 @@ class CZapitClient:public CBasicClient EVT_PMT_CHANGED, EVT_TUNE_COMPLETE, EVT_BACK_ZAP_COMPLETE, + EVT_WEBTV_ZAP_COMPLETE, LAST_EVENT_MARKER // <- no actual event, needed by pzapit }; diff --git a/src/zapit/include/zapit/getservices.h b/src/zapit/include/zapit/getservices.h index 9a21b358b..c31407047 100644 --- a/src/zapit/include/zapit/getservices.h +++ b/src/zapit/include/zapit/getservices.h @@ -140,6 +140,7 @@ class CServiceManager bool GetAllRadioChannels(ZapitChannelList &list, int flags = CZapitChannel::PRESENT); bool GetAllTvChannels(ZapitChannelList &list, int flags = CZapitChannel::PRESENT); bool GetAllHDChannels(ZapitChannelList &list, int flags = CZapitChannel::PRESENT); + bool GetAllWebTVChannels(ZapitChannelList &list, int flags = CZapitChannel::PRESENT); bool GetAllSatelliteChannels(ZapitChannelList &list, t_satellite_position position, int flags = CZapitChannel::PRESENT); bool GetAllTransponderChannels(ZapitChannelList &list, transponder_id_t tpid, int flags = CZapitChannel::PRESENT); bool GetAllUnusedChannels(ZapitChannelList &list, int flags = CZapitChannel::PRESENT); diff --git a/src/zapit/include/zapit/settings.h b/src/zapit/include/zapit/settings.h index 7be89bc9f..9ec4a9990 100644 --- a/src/zapit/include/zapit/settings.h +++ b/src/zapit/include/zapit/settings.h @@ -48,6 +48,7 @@ #define CABLES_XML CONFIGDIR "/cables.xml" #define SATELLITES_XML CONFIGDIR "/satellites.xml" #define TERRESTRIAL_XML CONFIGDIR "/terrestrial.xml" +#define WEBTV_XML CONFIGDIR "/webtv_usr.xml" #define AUDIO_DEVICE "/dev/dvb/adapter0/audio0" #define DEMUX_DEVICE "/dev/dvb/adapter0/demux0" diff --git a/src/zapit/include/zapit/types.h b/src/zapit/include/zapit/types.h index 6f62866c0..77977ce04 100644 --- a/src/zapit/include/zapit/types.h +++ b/src/zapit/include/zapit/types.h @@ -43,9 +43,45 @@ typedef uint16_t t_bouquet_id; /* unique channel identification */ typedef uint64_t t_channel_id; - +#if 0 #define CREATE_CHANNEL_ID(service_id,original_network_id,transport_stream_id) ((((t_channel_id)transport_stream_id) << 32) | (((t_channel_id)original_network_id) << 16) | (t_channel_id)service_id) #define CREATE_CHANNEL_ID64 (((uint64_t)(satellitePosition+freq*4) << 48) | ((uint64_t) transport_stream_id << 32) | ((uint64_t)original_network_id << 16) | (uint64_t)service_id) +#else +extern "C" { +#include +} +#include + +static inline t_channel_id create_channel_id(t_service_id service_id, t_original_network_id original_network_id, t_transport_stream_id transport_stream_id, const char *url = NULL) +{ + if (url) { + t_channel_id cid; + unsigned char md5[16]; + md5_buffer(url, strlen(url), md5); + memcpy(&cid, md5, sizeof(cid)); + return cid | 0xFFFFFFFF00000000; + } + return (((t_channel_id)transport_stream_id) << 32) | (((t_channel_id)original_network_id) << 16) | (t_channel_id)service_id; +} +#define CREATE_CHANNEL_ID create_channel_id + +static inline t_channel_id create_channel_id64(t_service_id service_id, t_original_network_id original_network_id, t_transport_stream_id transport_stream_id, t_satellite_position satellitePosition, freq_id_t freq, const char *url = NULL) { + if (url) { + t_channel_id cid; + unsigned char md5[16]; + md5_buffer(url, strlen(url), md5); + memcpy(&cid, md5, sizeof(cid)); + return cid | 0xFFFFFFFF00000000; + } + return ((uint64_t)(satellitePosition+freq*4) << 48) | ((uint64_t) transport_stream_id << 32) | ((uint64_t)original_network_id << 16) | (uint64_t)service_id; +} +#define CREATE_CHANNEL_ID64 create_channel_id64(service_id, original_network_id, transport_stream_id, satellitePosition, freq) + +static inline bool IS_WEBTV(t_channel_id cid) +{ + return (cid & 0xFFFFFFFF00000000) == 0xFFFFFFFF00000000; +} +#endif #ifndef PRIx64 #define PRIx64 "llx" diff --git a/src/zapit/include/zapit/zapit.h b/src/zapit/include/zapit/zapit.h index 9be18fe7f..e2c45e421 100644 --- a/src/zapit/include/zapit/zapit.h +++ b/src/zapit/include/zapit/zapit.h @@ -47,6 +47,7 @@ typedef struct ZAPIT_start_arg int video_mode; int volume; int ci_clock; + std::list *webtv_xml; } Z_start_arg; typedef struct Zapit_config { @@ -121,6 +122,8 @@ class CZapit : public OpenThreads::Thread int current_volume; int volume_percent; + std::list *webtv_xml; + int currentMode; bool playbackStopForced; //diseqc_t diseqcType; @@ -135,6 +138,7 @@ class CZapit : public OpenThreads::Thread t_channel_id live_channel_id; t_channel_id pip_channel_id; t_channel_id lock_channel_id; + t_channel_id last_channel_id; /* scan params */ TP_params TP; fast_scan_type_t scant; @@ -263,5 +267,9 @@ class CZapit : public OpenThreads::Thread void Lock() { mutex.lock(); } void Unlock() { mutex.unlock(); } void EnablePlayback(bool enable) { playbackStopForced = !enable; } + void lockPlayBack(const bool sendpmt = true); + void unlockPlayBack(const bool sendpmt = true); + void Rezap(); + std::list *GetWebTVXML(void) { return webtv_xml; } }; #endif /* __zapit_h__ */ diff --git a/src/zapit/src/bouquets.cpp b/src/zapit/src/bouquets.cpp index 8eafc1cd9..e5542a828 100644 --- a/src/zapit/src/bouquets.cpp +++ b/src/zapit/src/bouquets.cpp @@ -386,6 +386,7 @@ void CBouquetManager::parseBouquetsXml(const char *fname, bool bUser) channel_node = search->xmlChildrenNode; while ((channel_node = xmlGetNextOccurence(channel_node, "S")) != NULL) { std::string name2 = xmlGetAttribute(channel_node, "n"); + char *url = xmlGetAttribute(channel_node, "u"); GET_ATTR(channel_node, "i", SCANF_SERVICE_ID_TYPE, service_id); GET_ATTR(channel_node, "on", SCANF_ORIGINAL_NETWORK_ID_TYPE, original_network_id); GET_ATTR(channel_node, "s", SCANF_SATELLITE_POSITION_TYPE, satellitePosition); @@ -395,9 +396,10 @@ void CBouquetManager::parseBouquetsXml(const char *fname, bool bUser) freq = freq/1000; CZapitChannel* chan; - t_channel_id chid = CREATE_CHANNEL_ID64; + t_channel_id chid = create_channel_id64(service_id, original_network_id, transport_stream_id, + satellitePosition, freq, url); /* FIXME to load old cable settings with new cable "positions" started from 0xF00 */ - if(bUser || CFEManager::getInstance()->cableOnly()) + if(!url && (bUser || CFEManager::getInstance()->cableOnly())) chan = CServiceManager::getInstance()->FindChannelFuzzy(chid, satellitePosition, freq); else chan = CServiceManager::getInstance()->FindChannel(chid); diff --git a/src/zapit/src/capmt.cpp b/src/zapit/src/capmt.cpp index 7f91a2fe4..9e47597ff 100644 --- a/src/zapit/src/capmt.cpp +++ b/src/zapit/src/capmt.cpp @@ -197,6 +197,9 @@ void CCamManager::StopCam(t_channel_id channel_id, CCam *cam) bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start, bool force_update) { + if (IS_WEBTV(channel_id)) + return false; + CCam * cam; int oldmask, newmask; int demux = DEMUX_SOURCE_0; diff --git a/src/zapit/src/channel.cpp b/src/zapit/src/channel.cpp index 4f86cce26..b4d38e3f2 100644 --- a/src/zapit/src/channel.cpp +++ b/src/zapit/src/channel.cpp @@ -50,6 +50,25 @@ CZapitChannel::CZapitChannel(const std::string & p_name, t_channel_id p_channel_ Init(); } +// For WebTV ... +CZapitChannel::CZapitChannel(const char *p_name, t_channel_id p_channel_id, const char *p_url, const char *p_desc) +{ + if (!p_name || !p_url) + return; + name = std::string(p_name); + url = std::string(p_url); + if (p_desc) + desc = std::string(p_desc); + channel_id = p_channel_id; + service_id = 0; + transport_stream_id = 0; + original_network_id = 0; + serviceType = ST_DIGITAL_TELEVISION_SERVICE; + satellitePosition = 0; + freq = 0; + Init(); +} + void CZapitChannel::Init() { //caPmt = NULL; @@ -329,18 +348,28 @@ void CZapitChannel::dumpBouquetXml(FILE * fd) bool write_names = 1; if(write_names) { - fprintf(fd, "\t\t\n", - getServiceId(), convert_UTF8_To_UTF8_XML(getName().c_str()).c_str(), - getTransportStreamId(), - getOriginalNetworkId(), - getSatellitePosition(), - getFreqId()); + if (url.empty()) + fprintf(fd, "\t\t\n", + getServiceId(), + convert_UTF8_To_UTF8_XML(getName().c_str()).c_str(), + getTransportStreamId(), + getOriginalNetworkId(), + getSatellitePosition(), + getFreqId()); + else + fprintf(fd, "\t\t\n", + convert_UTF8_To_UTF8_XML(getName().c_str()).c_str(), + convert_UTF8_To_UTF8_XML(url.c_str()).c_str()); } else { - fprintf(fd, "\t\t\n", - getServiceId(), - getTransportStreamId(), - getOriginalNetworkId(), - getSatellitePosition(), - getFreqId()); + if (url.empty()) + fprintf(fd, "\t\t\n", + getServiceId(), + getTransportStreamId(), + getOriginalNetworkId(), + getSatellitePosition(), + getFreqId()); + else + fprintf(fd, "\t\t\n", + convert_UTF8_To_UTF8_XML(url.c_str()).c_str()); } } diff --git a/src/zapit/src/getservices.cpp b/src/zapit/src/getservices.cpp index 9b12d05fa..db60aeaf8 100644 --- a/src/zapit/src/getservices.cpp +++ b/src/zapit/src/getservices.cpp @@ -292,6 +292,16 @@ bool CServiceManager::GetAllHDChannels(ZapitChannelList &list, int flags) return (!list.empty()); } +bool CServiceManager::GetAllWebTVChannels(ZapitChannelList &list, int flags) +{ + list.clear(); + for (channel_map_iterator_t it = allchans.begin(); it != allchans.end(); ++it) { + if ((it->second.flags & flags) && !it->second.getUrl().empty()) + list.push_back(&(it->second)); + } + return (!list.empty()); +} + bool CServiceManager::GetAllUnusedChannels(ZapitChannelList &list, int flags) { list.clear(); @@ -850,6 +860,8 @@ bool CServiceManager::LoadServices(bool only_current) printf("[zapit] Loading services, channel size %d ..\n", (int)sizeof(CZapitChannel)); //frontendType = CFEManager::getInstance()->getLiveFE()->getInfo()->type; + std::list *webtv_xml = CZapit::getInstance()->GetWebTVXML(); + if(only_current) goto do_current; @@ -916,6 +928,35 @@ bool CServiceManager::LoadServices(bool only_current) xmlFreeDoc(parser); } + if (webtv_xml) { + for (std::list::iterator it = webtv_xml->begin(); it != webtv_xml->end(); ++it) { + if (!access((*it).c_str(), R_OK)) { + INFO("Loading webtv..."); + parser = parseXmlFile((*it).c_str()); + if (parser == NULL) + continue; + + xmlNodePtr l0 = xmlDocGetRootElement(parser); + xmlNodePtr l1 = l0->xmlChildrenNode; + if (l1) { + while ((xmlGetNextOccurence(l1, "webtv"))) { + char *title = xmlGetAttribute(l1, "title"); + char *url = xmlGetAttribute(l1, "url"); + char *desc = xmlGetAttribute(l1, "description"); + if (title && url) { + t_channel_id chid = create_channel_id64(0, 0, 0, 0, 0, url); + CZapitChannel * channel = new CZapitChannel(title, chid, url, desc); + AddChannel(channel); + channel->flags = CZapitChannel::UPDATED; + } + + l1 = l1->xmlNextNode; + } + } + xmlFreeDoc(parser); + } + } + } #if 0 if (CFEManager::getInstance()->haveSat()) { LoadMotorPositions(); diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 36bc60a25..c2a23827a 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -169,6 +169,7 @@ void CZapit::SaveSettings(bool write) configfile.setInt64("lastChannelRadio", lastChannelRadio); configfile.setInt64("lastChannelTV", lastChannelTV); configfile.setInt64("lastChannel", live_channel_id); + configfile.setInt64("lastOTAChannel", last_channel_id); } configfile.setBool("writeChannelsNames", config.writeChannelsNames); @@ -290,6 +291,7 @@ void CZapit::LoadSettings() live_channel_id = configfile.getInt64("lastChannel", 0); lastChannelRadio = configfile.getInt64("lastChannelRadio", 0); lastChannelTV = configfile.getInt64("lastChannelTV", 0); + last_channel_id = configfile.getInt64("lastOTAChannel", 0); #if 0 //unused config.fastZap = configfile.getBool("fastZap", 1); @@ -485,6 +487,19 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay INFO("[zapit] zap to %s (%" PRIx64 " tp %" PRIx64 ")", newchannel->getName().c_str(), newchannel->getChannelID(), newchannel->getTransponderId()); + if (IS_WEBTV(newchannel->getChannelID()) && !newchannel->getUrl().empty()) { + if (!IS_WEBTV(live_channel_id)) + CCamManager::getInstance()->Stop(live_channel_id, CCamManager::PLAY); + + live_channel_id = newchannel->getChannelID(); + lock_channel_id = live_channel_id; + + current_channel = newchannel; + lastChannelTV = channel_id; + SendEvent(CZapitClient::EVT_WEBTV_ZAP_COMPLETE, &live_channel_id, sizeof(t_channel_id)); + return true; + } + #ifdef ENABLE_PIP /* executed async if zap NOWAIT, race possible with record lock/allocate */ CFEManager::getInstance()->Lock(); @@ -528,6 +543,7 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay live_channel_id = current_channel->getChannelID(); lock_channel_id = live_channel_id; + last_channel_id = live_channel_id; SaveSettings(false); if(!TuneChannel(live_fe, newchannel, transponder_change)) { @@ -718,18 +734,20 @@ bool CZapit::ZapForEpg(const t_channel_id channel_id, bool instandby) /* no need to lock fe in standby mode, epg scan should care to not call this if recording running */ if (!instandby) { - CFEManager::getInstance()->lockFrontend(live_fe); + if (!IS_WEBTV(live_channel_id)) + CFEManager::getInstance()->lockFrontend(live_fe); #ifdef ENABLE_PIP - if (pip_fe && pip_fe != live_fe) + if (pip_fe /* && pip_fe != live_fe */) CFEManager::getInstance()->lockFrontend(pip_fe); #endif } CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel); if (!instandby) { - CFEManager::getInstance()->unlockFrontend(live_fe); + if (!IS_WEBTV(live_channel_id)) + CFEManager::getInstance()->unlockFrontend(live_fe); #ifdef ENABLE_PIP - if (pip_fe && pip_fe != live_fe) + if (pip_fe /* && pip_fe != live_fe */) CFEManager::getInstance()->unlockFrontend(pip_fe); #endif } @@ -1009,6 +1027,40 @@ void CZapit::SendCmdReady(int connfd) CBasicServer::send_data(connfd, &response, sizeof(response)); } +void CZapit::lockPlayBack(const bool sendpmt) +{ + /* hack. if standby true, dont blank video */ + standby = true; + StopPlayBack(sendpmt); + standby = false; + playbackStopForced = true; + lock_channel_id = live_channel_id; +} + +void CZapit::unlockPlayBack(const bool /*sendpmt*/) +{ + playbackStopForced = false; + if (lock_channel_id == live_channel_id) { + StartPlayBack(current_channel); + SendPMT(); + } else { + live_fe->setTsidOnid(0); + if (!ZapIt(lock_channel_id)) + SendEvent(CZapitClient::EVT_ZAP_FAILED, &lock_channel_id, sizeof(lock_channel_id)); + lock_channel_id = 0; + } +} + +void CZapit::Rezap(void) +{ + if (currentMode & RECORD_MODE) + return; + if(config.rezapTimeout > 0) + sleep(config.rezapTimeout); + if(current_channel) + ZapIt(current_channel->getChannelID()); +} + bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd) { DBG("cmd %d (version %d) received\n", rmsg.cmd, rmsg.version); @@ -1285,12 +1337,15 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd) break; #endif case CZapitMessages::CMD_REZAP: +#if 0 if (currentMode & RECORD_MODE) break; if(config.rezapTimeout > 0) sleep(config.rezapTimeout); if(current_channel) ZapIt(current_channel->getChannelID()); +#endif + Rezap(); break; case CZapitMessages::CMD_TUNE_TP: { CBasicServer::receive_data(connfd, &TP, sizeof(TP)); @@ -1605,15 +1660,19 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd) #endif case CZapitMessages::CMD_SB_LOCK_PLAYBACK: +#if 0 /* hack. if standby true, dont blank video */ standby = true; StopPlayBack(true); standby = false; playbackStopForced = true; lock_channel_id = live_channel_id; +#endif + lockPlayBack(); SendCmdReady(connfd); break; case CZapitMessages::CMD_SB_UNLOCK_PLAYBACK: +#if 0 playbackStopForced = false; if (lock_channel_id == live_channel_id) { StartPlayBack(current_channel); @@ -1624,7 +1683,8 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd) SendEvent(CZapitClient::EVT_ZAP_FAILED, &lock_channel_id, sizeof(lock_channel_id)); lock_channel_id = 0; } - +#endif + unlockPlayBack(); SendCmdReady(connfd); break; #if 0 @@ -2022,7 +2082,13 @@ bool CZapit::StartPlayBack(CZapitChannel *thisChannel) CFEManager::getInstance()->Open(); return true; } - +#if 0 + if (IS_WEBTV(thisChannel->getChannelID())) { + INFO("WEBTV channel\n"); + SendEvent(CZapitClient::EVT_WEBTV_ZAP_COMPLETE, &live_channel_id, sizeof(t_channel_id)); + return true; + } +#endif unsigned short pcr_pid = thisChannel->getPcrPid(); unsigned short audio_pid = thisChannel->getAudioPid(); unsigned short video_pid = (currentMode & TV_MODE) ? thisChannel->getVideoPid() : 0; @@ -2083,10 +2149,16 @@ bool CZapit::StartPlayBack(CZapitChannel *thisChannel) bool CZapit::StopPlayBack(bool send_pmt) { + INFO("standby %d playing %d forced %d send_pmt %d", standby, playing, playbackStopForced, send_pmt); if(send_pmt) CCamManager::getInstance()->Stop(live_channel_id, CCamManager::PLAY); - INFO("standby %d playing %d forced %d", standby, playing, playbackStopForced); +#if 0 + if (current_channel && IS_WEBTV(current_channel->getChannelID())) { + playing = false; + return true; + } +#endif if (!playing) return true; @@ -2150,9 +2222,17 @@ void CZapit::leaveStandby(void) CFEManager::getInstance()->Open(); } standby = false; - if (current_channel) + if (current_channel) { /* tune channel, with stopped playback to not bypass the parental PIN check */ ZapIt(live_channel_id, false, false); + if (IS_WEBTV(live_channel_id)) { + CZapitChannel* newchannel = CServiceManager::getInstance()->FindChannel(last_channel_id); + CFrontend * fe = newchannel ? CFEManager::getInstance()->allocateFE(newchannel) : NULL; + bool transponder_change; + if (fe) + TuneChannel(fe, newchannel, transponder_change, false); + } + } } unsigned CZapit::ZapTo(const unsigned int bouquet, const unsigned int pchannel) @@ -2221,13 +2301,12 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg) CFEManager::getInstance()->Init(); live_fe = CFEManager::getInstance()->getFE(0); - if (live_fe == NULL) /* no frontend found? */ - return false; - /* load configuration or set defaults if no configuration file exists */ video_mode = ZapStart_arg->video_mode; current_volume = ZapStart_arg->volume; + webtv_xml = ZapStart_arg->webtv_xml; + videoDemux = new cDemux(); videoDemux->Open(DMX_VIDEO_CHANNEL); @@ -2280,6 +2359,8 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg) #endif ca = cCA::GetInstance(); + if (live_fe == NULL) /* no frontend found? */ + return false; //LoadSettings(); //LoadAudioMap();