diff options
76 files changed, 652 insertions, 420 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index a9b75d45f5..214e63ca08 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -3253,7 +3253,10 @@ msgctxt "#728" msgid "FTP server" msgstr "" -#empty string with id 729 +#: system/settings/settings.xml +msgctxt "#729" +msgid "Enable SSL" +msgstr "" #: system/settings/settings.xml msgctxt "#730" @@ -20370,25 +20373,25 @@ msgctxt "#36622" msgid "Set the maximum SMB protocol version to negotiate when making connections. Forcing SMBv2 or SMBv1 compatibility may be required with older NAS and Windows shares." msgstr "" -#. Values for setting with label #36621 "Maximum protocol version" - none means "no protocol version is forced" +#. Values for setting with label #36621 and #36628 "Minimum/Maximum protocol version" - none means "no protocol version is forced" #: system/settings/settings.xml msgctxt "#36623" msgid "None" msgstr "" -#. Values for setting with label #36621 "Maximum protocol version" +#. Values for setting with label #36621 and #36628 "Minimum/Maximum protocol version" #: system/settings/settings.xml msgctxt "#36624" msgid "SMBv1" msgstr "" -#. Values for setting with label #36621 "Maximum protocol version" +#. Values for setting with label #36621 and #36628 "Minimum/Maximum protocol version" #: system/settings/settings.xml msgctxt "#36625" msgid "SMBv2" msgstr "" -#. Values for setting with label #36621 "Maximum protocol version" +#. Values for setting with label #36621 and #36628 "Minimum/Maximum protocol version" #: system/settings/settings.xml msgctxt "#36626" msgid "SMBv3" @@ -20400,7 +20403,37 @@ msgctxt "#36627" msgid "Client" msgstr "" -#empty strings from id 36628 to 36899 +#. Label of a setting, allow the minimum smbclient protocol to be configured +#: system/settings/settings.xml +msgctxt "#36628" +msgid "Minimum protocol version" +msgstr "" + +#. Description of setting with label #36628 "Minimum protocol version" +#: system/settings/settings.xml +msgctxt "#36629" +msgid "Set the minimum SMB protocol version to negotiate when making connections. Forcing SMBv2 may be required to prevent SMBv1 use on some OS." +msgstr "" + +#. Label of a setting, sets additional config required for some proprietary SMBv1 implementations (mostly routers) +#: system/settings/settings.xml +msgctxt "#36630" +msgid "Use legacy security" +msgstr "" + +#. Description of setting with label #36630 "Use legacy security" +#: system/settings/settings.xml +msgctxt "#36631" +msgid "Force weak SMBv1 security for compatibility with the USB sharing features on some WiFi routers and NAS devices." +msgstr "" + +#empty strings from id 36632 to 36898 + +#. Description of setting with label #729 "Enable SSL" +#: system/settings/settings.xml +msgctxt "#36899" +msgid "Enables SSL encryption in the webserver. Certificate special://userdata/server.key and Key special://userdata/server.pem must be created manually" +msgstr "" #: xbmc/media/MediaType.cpp msgctxt "#36900" diff --git a/addons/skin.estuary/xml/DialogButtonMenu.xml b/addons/skin.estuary/xml/DialogButtonMenu.xml index 9d29e01a5c..90839ff75b 100644 --- a/addons/skin.estuary/xml/DialogButtonMenu.xml +++ b/addons/skin.estuary/xml/DialogButtonMenu.xml @@ -61,9 +61,7 @@ <visible>System.Loggedon</visible> </item> <item> - <label>$LOCALIZE[20046]</label> - <altlabel>$LOCALIZE[20045]</altlabel> - <usealttexture>!System.IsMaster</usealttexture> + <label>$VAR[MasterModeLabel]</label> <onclick>mastermode</onclick> <visible>System.HasLocks</visible> </item> diff --git a/addons/skin.estuary/xml/DialogPVRInfo.xml b/addons/skin.estuary/xml/DialogPVRInfo.xml index eb06d6f17e..a8903e96cb 100644 --- a/addons/skin.estuary/xml/DialogPVRInfo.xml +++ b/addons/skin.estuary/xml/DialogPVRInfo.xml @@ -119,7 +119,7 @@ </control> <include content="InfoDialogTopBarInfo"> <param name="main_label" value="$INFO[ListItem.Title]" /> - <param name="sub_label" value="$VAR[SeasonEpisodeLabel]" /> + <param name="sub_label" value="[COLOR grey]$VAR[SeasonEpisodeLabel][/COLOR]$INFO[ListItem.EpisodeName,[COLOR white][B],[/B][/COLOR]]" /> <param name="posy" value="40" /> </include> </control> diff --git a/addons/skin.estuary/xml/Includes_PVR.xml b/addons/skin.estuary/xml/Includes_PVR.xml index b85dea2a37..c67df54581 100644 --- a/addons/skin.estuary/xml/Includes_PVR.xml +++ b/addons/skin.estuary/xml/Includes_PVR.xml @@ -167,7 +167,7 @@ <top>435</top> <width>830</width> <height>70</height> - <label>[I]$INFO[ListItem.EpisodeName][/I]</label> + <label>[I]$VAR[SeasonEpisodeLabel]$INFO[ListItem.EpisodeName][/I]</label> </control> <control type="textbox"> <top>490</top> diff --git a/addons/skin.estuary/xml/MyPVRGuide.xml b/addons/skin.estuary/xml/MyPVRGuide.xml index 7e22beab15..08a7471253 100644 --- a/addons/skin.estuary/xml/MyPVRGuide.xml +++ b/addons/skin.estuary/xml/MyPVRGuide.xml @@ -64,11 +64,18 @@ <left>300</left> <right>60</right> <height>30</height> - <label>[COLOR button_focus]$INFO[ListItem.StartTime][/COLOR]$INFO[ListItem.EndTime,[COLOR button_focus] - ,[/COLOR]] $INFO[ListItem.EpgEventTitle]$INFO[ListItem.EpisodeName, (,)]$INFO[ListItem.Genre, [COLOR grey]$LOCALIZE[515]:[/COLOR] ]</label> + <label>[COLOR button_focus]$INFO[ListItem.StartTime][/COLOR]$INFO[ListItem.EndTime,[COLOR button_focus] - ,[/COLOR]] $INFO[ListItem.EpgEventTitle]$INFO[ListItem.Genre, [COLOR grey]$LOCALIZE[515]:[/COLOR] ]</label> + </control> + <control type="label"> + <top>29</top> + <left>300</left> + <right>60</right> + <height>30</height> + <label>[COLOR grey]$VAR[SeasonEpisodeLabel][/COLOR]$INFO[ListItem.EpisodeName,[COLOR white],[/COLOR]]</label> </control> <control type="textbox"> <left>300</left> - <top>38</top> + <top>67</top> <right>60</right> <height>173</height> <label>$INFO[ListItem.Plot]</label> diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml index f59f13f5d5..dd62e8c1c4 100644 --- a/addons/skin.estuary/xml/Variables.xml +++ b/addons/skin.estuary/xml/Variables.xml @@ -409,9 +409,8 @@ <value condition="ListItem.HasTimer">icons/pvr/PVR-HasTimer.png</value> </variable> <variable name="SeasonEpisodeLabel"> - <value condition="String.IsEmpty(ListItem.Season) + String.IsEmpty(ListItem.Episode)">$INFO[ListItem.EpisodeName,[B],[/B]]</value> - <value condition="String.IsEmpty(ListItem.EpisodeName)">$INFO[ListItem.Season,[COLOR grey]S,[/COLOR]]$INFO[ListItem.Episode,[COLOR grey]E,[/COLOR]]</value> - <value>$INFO[ListItem.Season,[COLOR grey]S,[/COLOR]]$INFO[ListItem.Episode,[COLOR grey]E,[/COLOR]]: [B]$INFO[ListItem.EpisodeName][/B]</value> + <value condition="String.IsEmpty(ListItem.EpisodeName)">$INFO[ListItem.Season,S]$INFO[ListItem.Episode,E]</value> + <value>$INFO[ListItem.Season,S]$INFO[ListItem.Episode,E,: ]</value> </variable> <variable name="ExpirationDateTimeLabel"> <value condition="!String.IsEmpty(ListItem.ExpirationDate)">[COLOR grey]$LOCALIZE[19299]:[/COLOR] $INFO[ListItem.ExpirationDate] $INFO[ListItem.ExpirationTime][CR]</value> @@ -431,4 +430,8 @@ <value condition="String.IsEqual(Skin.String(background_overlay),0)">$LOCALIZE[231]</value> <value>$INFO[Skin.String(background_overlay),$LOCALIZE[467] ]</value> </variable> + <variable name="MasterModeLabel"> + <value condition="!System.IsMaster">$LOCALIZE[20045]</value> + <value>$LOCALIZE[20046]</value> + </variable> </includes> diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 0c65d8406b..7859f8f513 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -1758,6 +1758,15 @@ <hidden>true</hidden> </control> </setting> + <setting id="services.webserverssl" type="boolean" parent="services.webserver" label="729" help="36899"> + <requirement>WEBSERVER_HAS_SSL</requirement> + <level>1</level> + <default>false</default> + <dependencies> + <dependency type="enable" setting="services.webserver">true</dependency> + </dependencies> + <control type="toggle" /> + </setting> <setting id="services.webskin" type="addon" label="199" help="36332"> <level>1</level> <default>webinterface.default</default> @@ -1979,6 +1988,19 @@ <default>0.0.0.0</default> <control type="edit" format="ip" /> </setting> + <setting id="smb.minprotocol" type="integer" label="36628" help="36629"> + <level>2</level> + <default>0</default> + <constraints> + <options> + <option label="36623">0</option> + <option label="36624">1</option> + <option label="36625">2</option> + <option label="36626">3</option> + </options> + </constraints> + <control type="list" format="integer" /> + </setting> <setting id="smb.maxprotocol" type="integer" label="36621" help="36622"> <level>2</level> <default>3</default> @@ -1992,6 +2014,16 @@ </constraints> <control type="list" format="integer" /> </setting> + <setting id="smb.legacysecurity" type="boolean" label="36630" help="36631"> + <level>2</level> + <default>false</default> + <control type="toggle" /> + <dependencies> + <dependency type="enable"> + <condition setting="smb.maxprotocol" operator="is">1</condition> + </dependency> + </dependencies> + </setting> </group> </category> <category id="weather" label="8" help="36316"> diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION index 95725cbd60..9fcfc4f386 100644 --- a/tools/depends/target/ffmpeg/FFMPEG-VERSION +++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION @@ -1,5 +1,5 @@ LIBNAME=ffmpeg BASE_URL=https://github.com/xbmc/FFmpeg -VERSION=3.4-Leia-Alpha-1 +VERSION=3.4.1-Leia-Alpha-1 ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz GNUTLS_VER=3.4.14 diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 67864cd7d5..d36107521e 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2972,7 +2972,7 @@ bool CApplication::PlayMedia(const CFileItem& item, const std::string &player, i { CLog::Log(LOGWARNING, "CApplication::PlayMedia called to play a playlist %s but no idea which playlist to use, playing first item", item.GetPath().c_str()); if(pPlayList->size()) - return PlayFile(*(*pPlayList)[0], "", false) == PLAYBACK_OK; + return PlayFile(*(*pPlayList)[0], "", false); } } } @@ -2988,12 +2988,12 @@ bool CApplication::PlayMedia(const CFileItem& item, const std::string &player, i if (CServiceBroker::GetAddonMgr().GetAddon(path.GetHostName(), addon, ADDON_GAMEDLL)) { CFileItem addonItem(addon); - return PlayFile(addonItem, player, false) == PLAYBACK_OK; + return PlayFile(addonItem, player, false); } } //nothing special just play - return PlayFile(item, player, false) == PLAYBACK_OK; + return PlayFile(item, player, false); } // PlayStack() @@ -3003,21 +3003,20 @@ bool CApplication::PlayMedia(const CFileItem& item, const std::string &player, i // A faster calculation of video time would improve this // substantially. // return value: same with PlayFile() -PlayBackRet CApplication::PlayStack(const CFileItem& item, bool bRestart) +bool CApplication::PlayStack(const CFileItem& item, bool bRestart) { if (!m_stackHelper.InitializeStack(item)) - return PLAYBACK_FAIL; + return false; int startoffset = m_stackHelper.InitializeStackStartPartAndOffset(item); - m_itemCurrentFile.reset(new CFileItem(item)); CFileItem selectedStackPart = m_stackHelper.GetCurrentStackPartFileItem(); selectedStackPart.m_lStartOffset = startoffset; return PlayFile(selectedStackPart, "", true); } -PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bool bRestart) +bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRestart) { // Ensure the MIME type has been retrieved for http:// and shout:// streams if (item.GetMimeType().empty()) @@ -3028,8 +3027,6 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo // bRestart will be true when called from PlayStack(), skipping this block m_appPlayer.SetPlaySpeed(1); - m_itemCurrentFile.reset(new CFileItem(item)); - m_nextPlaylistItem = -1; m_stackHelper.Clear(); @@ -3046,17 +3043,17 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo if (CGUIDialogPlayEject::ShowAndGetInput(item)) // PlayDiscAskResume takes path to disc. No parameter means default DVD drive. // Can't do better as CGUIDialogPlayEject calls CMediaManager::IsDiscInDrive, which assumes default DVD drive anyway - return MEDIA_DETECT::CAutorun::PlayDiscAskResume() ? PLAYBACK_OK : PLAYBACK_FAIL; + return MEDIA_DETECT::CAutorun::PlayDiscAskResume(); } else #endif HELPERS::ShowOKDialogText(CVariant{435}, CVariant{436}); - return PLAYBACK_OK; + return true; } if (item.IsPlayList()) - return PLAYBACK_FAIL; + return false; if (item.IsPlugin()) { // we modify the item so that it becomes a real URL @@ -3064,7 +3061,7 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo CFileItem item_new(item); if (XFILE::CPluginDirectory::GetPluginResult(item.GetPath(), item_new, resume)) return PlayFile(std::move(item_new), player, false); - return PLAYBACK_FAIL; + return false; } #ifdef HAS_UPNP @@ -3073,7 +3070,7 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo CFileItem item_new(item); if (XFILE::CUPnPDirectory::GetResource(item.GetURL(), item_new)) return PlayFile(std::move(item_new), player, false); - return PLAYBACK_FAIL; + return false; } #endif @@ -3100,8 +3097,6 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo // have to be set here due to playstack using this for starting the file if (item.HasVideoInfoTag()) options.state = item.GetVideoInfoTag()->GetResumePoint().playerState; - if (m_stackHelper.IsPlayingRegularStack() && m_itemCurrentFile->m_lStartOffset != 0) - m_itemCurrentFile->m_lStartOffset = STARTOFFSET_RESUME; // to force fullscreen switching } if (!bRestart || m_stackHelper.IsPlayingISOStack()) { @@ -3173,7 +3168,7 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo { //check if we must show the simplified bd menu if (!CGUIDialogSimpleMenu::ShowPlaySelection(const_cast<CFileItem&>(item))) - return PLAYBACK_CANCELED; + return false; } // this really aught to be inside !bRestart, but since PlayStack @@ -3187,12 +3182,10 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo else if(m_stackHelper.IsPlayingRegularStack()) { //! @todo - this will fail if user seeks back to first file in stack - if(m_stackHelper.GetCurrentPartNumber() == 0 || m_itemCurrentFile->m_lStartOffset == STARTOFFSET_RESUME) + if(m_stackHelper.GetCurrentPartNumber() == 0 || m_stackHelper.GetRegisteredStack(item)->m_lStartOffset != 0) options.fullscreen = g_advancedSettings.m_fullScreenOnMovieStart && !CMediaSettings::GetInstance().DoesVideoStartWindowed(); else options.fullscreen = false; - // reset this so we don't think we are resuming on seek - m_itemCurrentFile->m_lStartOffset = 0; } else options.fullscreen = g_advancedSettings.m_fullScreenOnMovieStart && !CMediaSettings::GetInstance().DoesVideoStartWindowed(); @@ -3221,83 +3214,18 @@ PlayBackRet CApplication::PlayFile(CFileItem item, const std::string& player, bo CLog::LogF(LOGDEBUG,"Ignored %d playback thread messages", dMsgCount); } - std::string newPlayer; - if (!player.empty()) - newPlayer = player; - else if (bRestart && !m_appPlayer.GetCurrentPlayer().empty()) - newPlayer = m_appPlayer.GetCurrentPlayer(); - else - newPlayer = CPlayerCoreFactory::GetInstance().GetDefaultPlayer(item); - - // We should restart the player, unless the previous and next tracks are using - // one of the players that allows gapless playback (paplayer, VideoPlayer) - // DVD playback does not support gapless - if (item.IsDiscImage() || item.IsDVDFile()) - m_appPlayer.ClosePlayer(); - else - m_appPlayer.ClosePlayerGapless(newPlayer); - - m_appPlayer.CreatePlayer(newPlayer, *this); - - PlayBackRet iResult; - if (m_appPlayer.HasPlayer()) - { - /* When playing video pause any low priority jobs, they will be unpaused when playback stops. - * This should speed up player startup for files on internet filesystems (eg. webdav) and - * increase performance on low powered systems (Atom/ARM). - */ - if (item.IsVideo() || item.IsGame()) - { - CJobManager::GetInstance().PauseJobs(); - } - - // don't hold graphicscontext here since player - // may wait on another thread, that requires gfx - CSingleExit ex(g_graphicsContext); - - iResult = m_appPlayer.OpenFile(item, options); - } - else - { - CLog::Log(LOGERROR, "Error creating player for item %s (File doesn't exist?)", item.GetPath().c_str()); - iResult = PLAYBACK_FAIL; - } - - if (iResult == PLAYBACK_OK) - { - m_appPlayer.SetVolume(m_volumeLevel); - m_appPlayer.SetMute(m_muted); - - if(m_appPlayer.IsPlayingAudio()) - { - if (g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO) - g_windowManager.ActivateWindow(WINDOW_VISUALISATION); - } - else if(m_appPlayer.IsPlayingVideo()) - { - // if player didn't manage to switch to fullscreen by itself do it here - if (options.fullscreen && m_appPlayer.IsRenderingVideo() && - g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO && - g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_GAME) - SwitchToFullScreen(true); - } - else - { - if (g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION || - g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO || - g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_GAME) - g_windowManager.PreviousWindow(); - } + m_appPlayer.SetVolume(m_volumeLevel); + m_appPlayer.SetMute(m_muted); + m_appPlayer.OpenFile(item, options, player, *this); #if !defined(TARGET_POSIX) - g_audioManager.Enable(false); + g_audioManager.Enable(false); #endif - if (item.HasPVRChannelInfoTag()) - CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_NONE); - } + if (item.HasPVRChannelInfoTag()) + CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_NONE); - return iResult; + return true; } void CApplication::OnPlayBackEnded() @@ -3330,6 +3258,20 @@ void CApplication::OnPlayBackStarted(const CFileItem &file) g_pythonParser.OnPlayBackStarted(file); #endif + if (m_stackHelper.IsPlayingISOStack() || m_stackHelper.IsPlayingRegularStack()) + m_itemCurrentFile.reset(new CFileItem(*m_stackHelper.GetRegisteredStack(file))); + else + m_itemCurrentFile.reset(new CFileItem(file)); + + /* When playing video pause any low priority jobs, they will be unpaused when playback stops. + * This should speed up player startup for files on internet filesystems (eg. webdav) and + * increase performance on low powered systems (Atom/ARM). + */ + if (file.IsVideo() || file.IsGame()) + { + CJobManager::GetInstance().PauseJobs(); + } + CServiceBroker::GetPVRManager().OnPlaybackStarted(m_itemCurrentFile); m_stackHelper.OnPlayBackStarted(file); @@ -4054,7 +3996,6 @@ bool CApplication::OnMessage(CGUIMessage& message) // reset the current playing file m_itemCurrentFile->Reset(); g_infoManager.ResetCurrentItem(); - m_stackHelper.Clear(); if (message.GetMessage() == GUI_MSG_PLAYBACK_ENDED) { @@ -4065,6 +4006,7 @@ bool CApplication::OnMessage(CGUIMessage& message) if (!m_appPlayer.IsPlaying()) { g_audioManager.Enable(true); + m_appPlayer.OpenNext(); } if (!m_appPlayer.IsPlayingVideo()) @@ -4097,6 +4039,12 @@ bool CApplication::OnMessage(CGUIMessage& message) g_windowManager.PreviousWindow(); } + if (!m_appPlayer.IsPlaying()) + { + m_itemCurrentFile.reset(new CFileItem()); + m_stackHelper.Clear(); + } + if (IsEnableTestMode()) CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT); return true; @@ -4384,10 +4332,10 @@ void CApplication::Restart(bool bSamePosition) // and which means we gotta close & reopen the current playing file // first check if we're playing a file - if ( !m_appPlayer.IsPlayingVideo() && !m_appPlayer.IsPlayingAudio()) + if (!m_appPlayer.IsPlayingVideo() && !m_appPlayer.IsPlayingAudio()) return ; - if( !m_appPlayer.HasPlayer() ) + if (!m_appPlayer.HasPlayer()) return ; // do we want to return to the current position in the file @@ -4408,7 +4356,7 @@ void CApplication::Restart(bool bSamePosition) m_itemCurrentFile->m_lStartOffset = (long)(time * 75.0); // reopen the file - if ( PlayFile(*m_itemCurrentFile, "", true) == PLAYBACK_OK ) + if (PlayFile(*m_itemCurrentFile, "", true)) m_appPlayer.SetPlayerState(state); } diff --git a/xbmc/Application.h b/xbmc/Application.h index 36b1138068..2cfcc311cc 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -186,7 +186,7 @@ public: bool PlayMedia(const CFileItem& item, const std::string &player, int iPlaylist); bool ProcessAndStartPlaylist(const std::string& strPlayList, PLAYLIST::CPlayList& playlist, int iPlaylist, int track=0); - PlayBackRet PlayFile(CFileItem item, const std::string& player, bool bRestart = false); + bool PlayFile(CFileItem item, const std::string& player, bool bRestart = false); void StopPlaying(); void Restart(bool bSamePosition = true); void DelayedPlayerRestart(); @@ -473,7 +473,7 @@ protected: void VolumeChanged(); - PlayBackRet PlayStack(const CFileItem& item, bool bRestart); + bool PlayStack(const CFileItem& item, bool bRestart); float NavigationIdleTime(); bool InitDirectoriesLinux(); diff --git a/xbmc/ApplicationPlayer.cpp b/xbmc/ApplicationPlayer.cpp index fef61ebeda..81371a5d62 100644 --- a/xbmc/ApplicationPlayer.cpp +++ b/xbmc/ApplicationPlayer.cpp @@ -31,7 +31,7 @@ CApplicationPlayer::CApplicationPlayer() { - m_iPlayerOPSeq = 0; + } std::shared_ptr<IPlayer> CApplicationPlayer::GetInternal() const @@ -42,6 +42,7 @@ std::shared_ptr<IPlayer> CApplicationPlayer::GetInternal() const void CApplicationPlayer::ClosePlayer() { + m_nextItem.pItem.reset(); std::shared_ptr<IPlayer> player = GetInternal(); if (player) { @@ -57,37 +58,10 @@ void CApplicationPlayer::CloseFile(bool reopen) std::shared_ptr<IPlayer> player = GetInternal(); if (player) { - ++m_iPlayerOPSeq; player->CloseFile(reopen); } } -void CApplicationPlayer::ClosePlayerGapless(std::string &playername) -{ - std::shared_ptr<IPlayer> player = GetInternal(); - if (!player) - return; - - bool gaplessSupported = player->m_type == "music" || player->m_type == "video"; - gaplessSupported = gaplessSupported && (playername == player->m_name); - if (!gaplessSupported) - { - ClosePlayer(); - } - else - { - if (player->m_type != "video") - { - // XXX: we had to stop the previous playing item, it was done in VideoPlayer::OpenFile. - // but in paplayer::OpenFile, it sometimes just fade in without call CloseFile. - // but if we do not stop it, we can not distinguish callbacks from previous - // item and current item, it will confused us then we can not make correct delay - // callback after the starting state. - CloseFile(true); - } - } -} - void CApplicationPlayer::CreatePlayer(const std::string &player, IPlayerCallback& callback) { CSingleLock lock(m_playerLock); @@ -108,26 +82,72 @@ std::string CApplicationPlayer::GetCurrentPlayer() return ""; } -PlayBackRet CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& options) +bool CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& options, + const std::string &playerName, IPlayerCallback& callback) { + // get player type + std::string newPlayer; + if (!playerName.empty()) + newPlayer = playerName; + else + newPlayer = CPlayerCoreFactory::GetInstance().GetDefaultPlayer(item); + + // check if we need to close current player + // VideoPlayer can open a new file while playing std::shared_ptr<IPlayer> player = GetInternal(); - PlayBackRet iResult = PLAYBACK_FAIL; - if (player) + if (player && player->IsPlaying()) + { + bool needToClose = false; + + if (item.IsDiscImage() || item.IsDVDFile()) + needToClose = true; + + if (player->m_name != newPlayer) + needToClose = true; + + if (player->m_type != "video") + needToClose = true; + + if (needToClose) + { + m_nextItem.pItem = std::make_shared<CFileItem>(item); + m_nextItem.options = options; + m_nextItem.playerName = newPlayer; + m_nextItem.callback = &callback; + + CloseFile(); + return true; + } + } + + if (!player) + { + CreatePlayer(newPlayer, callback); + player = GetInternal(); + if (!player) + return false; + } + + bool ret = player->OpenFile(item, options); + + m_nextItem.pItem.reset(); + + // reset caching timers + m_audioStreamUpdate.SetExpired(); + m_videoStreamUpdate.SetExpired(); + m_subtitleStreamUpdate.SetExpired(); + + return ret; +} + +void CApplicationPlayer::OpenNext() +{ + if (m_nextItem.pItem) { - // op seq for detect cancel (CloseFile be called or OpenFile be called again) during OpenFile. - unsigned int startingSeq = ++m_iPlayerOPSeq; - - iResult = player->OpenFile(item, options) ? PLAYBACK_OK : PLAYBACK_FAIL; - // check whether the OpenFile was canceled by either CloseFile or another OpenFile. - if (m_iPlayerOPSeq != startingSeq) - iResult = PLAYBACK_CANCELED; - - // reset caching timers - m_audioStreamUpdate.SetExpired(); - m_videoStreamUpdate.SetExpired(); - m_subtitleStreamUpdate.SetExpired(); + OpenFile(*m_nextItem.pItem, m_nextItem.options, + m_nextItem.playerName, *m_nextItem.callback); + m_nextItem.pItem.reset(); } - return iResult; } bool CApplicationPlayer::HasPlayer() const diff --git a/xbmc/ApplicationPlayer.h b/xbmc/ApplicationPlayer.h index 7a179fef0b..22a084862e 100644 --- a/xbmc/ApplicationPlayer.h +++ b/xbmc/ApplicationPlayer.h @@ -30,13 +30,6 @@ #include "cores/IPlayer.h" #include "SeekHandler.h" -typedef enum -{ - PLAYBACK_CANCELED = -1, - PLAYBACK_FAIL = 0, - PLAYBACK_OK = 1, -} PlayBackRet; - class CAction; class CPlayerOptions; class CStreamDetails; @@ -52,15 +45,14 @@ public: CApplicationPlayer(); // player management - void CloseFile(bool reopen = false); void ClosePlayer(); - void ClosePlayerGapless(std::string &playername); - void CreatePlayer(const std::string &player, IPlayerCallback& callback); std::string GetCurrentPlayer(); float GetPlaySpeed(); float GetPlayTempo(); bool HasPlayer() const; - PlayBackRet OpenFile(const CFileItem& item, const CPlayerOptions& options); + bool OpenFile(const CFileItem& item, const CPlayerOptions& options, + const std::string &playerName, IPlayerCallback& callback); + void OpenNext(); void SetPlaySpeed(float speed); void SetTempo(float tempo); void FrameAdvance(int frames); @@ -165,12 +157,13 @@ public: void SetVideoSettings(CVideoSettings& settings); CSeekHandler& GetSeekHandler(); + protected: std::shared_ptr<IPlayer> GetInternal() const; + void CreatePlayer(const std::string &player, IPlayerCallback& callback); + void CloseFile(bool reopen = false); -private: std::shared_ptr<IPlayer> m_pPlayer; - unsigned int m_iPlayerOPSeq; // used to detect whether an OpenFile request on player is canceled by us. CCriticalSection m_playerLock; CSeekHandler m_seekHandler; @@ -181,4 +174,12 @@ private: int m_iVideoStream; XbmcThreads::EndTime m_subtitleStreamUpdate; int m_iSubtitleStream; + + struct SNextItem + { + std::shared_ptr<CFileItem> pItem; + CPlayerOptions options = {}; + std::string playerName; + IPlayerCallback *callback = nullptr; + } m_nextItem; }; diff --git a/xbmc/ApplicationStackHelper.cpp b/xbmc/ApplicationStackHelper.cpp index a71b12d515..c4a3f7911c 100644 --- a/xbmc/ApplicationStackHelper.cpp +++ b/xbmc/ApplicationStackHelper.cpp @@ -175,7 +175,7 @@ int CApplicationStackHelper::InitializeStackStartPartAndOffset(const CFileItem& if (!CDVDFileInfo::GetFileDuration(GetStackPartFileItem(i).GetPath(), duration)) { m_currentStack->Clear(); - return PLAYBACK_FAIL; + return false; } totalTimeMs += duration; // set end time in every part diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index db5d31c431..3745d679ed 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -9872,30 +9872,25 @@ std::string CGUIInfoManager::GetItemLabel(const CFileItem *item, int info, std:: if (item->HasPVRChannelInfoTag()) { CPVREpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) + if (tag && tag->EpisodeNumber() > 0) { - if (tag->SeriesNumber() > 0) - iSeason = tag->SeriesNumber(); - if (tag->EpisodeNumber() > 0) - iEpisode = tag->EpisodeNumber(); + iEpisode = tag->EpisodeNumber(); + iSeason = tag->SeriesNumber(); } } - else if (item->HasEPGInfoTag()) + else if (item->HasEPGInfoTag() && + item->GetEPGInfoTag()->EpisodeNumber() > 0) { - if (item->GetEPGInfoTag()->SeriesNumber() > 0) - iSeason = item->GetEPGInfoTag()->SeriesNumber(); - if (item->GetEPGInfoTag()->EpisodeNumber() > 0) - iEpisode = item->GetEPGInfoTag()->EpisodeNumber(); + iSeason = item->GetEPGInfoTag()->SeriesNumber(); + iEpisode = item->GetEPGInfoTag()->EpisodeNumber(); } else if (item->HasPVRTimerInfoTag()) { const CPVREpgInfoTagPtr tag(item->GetPVRTimerInfoTag()->GetEpgInfoTag()); - if (tag) + if (tag && tag->EpisodeNumber() > 0) { - if (tag->SeriesNumber() > 0) - iSeason = tag->SeriesNumber(); - if (tag->EpisodeNumber() > 0) - iEpisode = tag->EpisodeNumber(); + iSeason = tag->SeriesNumber(); + iEpisode = tag->EpisodeNumber(); } } else if (item->HasVideoInfoTag() && diff --git a/xbmc/LangInfo.cpp b/xbmc/LangInfo.cpp index 0cd0642a6c..47a36edc4e 100644 --- a/xbmc/LangInfo.cpp +++ b/xbmc/LangInfo.cpp @@ -992,8 +992,10 @@ void CLangInfo::SetTemperatureUnit(CTemperature::Unit temperatureUnit) m_temperatureUnit = temperatureUnit; - // need to reset our weather as temperatures need re-translating - CServiceBroker::GetWeatherManager().Refresh(); + // refresh weather manager as temperatures need re-translating + // NOTE: this could be called before our service manager is up + if (CServiceBroker::IsServiceManagerUp()) + CServiceBroker::GetWeatherManager().Refresh(); } void CLangInfo::SetTemperatureUnit(const std::string& temperatureUnit) @@ -1034,8 +1036,10 @@ void CLangInfo::SetSpeedUnit(CSpeed::Unit speedUnit) m_speedUnit = speedUnit; - // need to reset our weather as speeds need re-translating - CServiceBroker::GetWeatherManager().Refresh(); + // refresh weather manager as speeds need re-translating + // NOTE: this could be called before our service manager is up + if (CServiceBroker::IsServiceManagerUp()) + CServiceBroker::GetWeatherManager().Refresh(); } void CLangInfo::SetSpeedUnit(const std::string& speedUnit) diff --git a/xbmc/PlayListPlayer.cpp b/xbmc/PlayListPlayer.cpp index d5fcc126ca..ccf8cc558f 100644 --- a/xbmc/PlayListPlayer.cpp +++ b/xbmc/PlayListPlayer.cpp @@ -314,10 +314,8 @@ bool CPlayListPlayer::Play(int iSong, std::string player, bool bAutoPlay /* = fa m_bPlaybackStarted = false; unsigned int playAttempt = XbmcThreads::SystemClockMillis(); - PlayBackRet ret = g_application.PlayFile(*item, player, bAutoPlay); - if (ret == PLAYBACK_CANCELED) - return false; - if (ret == PLAYBACK_FAIL) + bool ret = g_application.PlayFile(*item, player, bAutoPlay); + if (ret == false) { CLog::Log(LOGERROR,"Playlist Player: skipping unplayable item: %i, path [%s]", m_iCurrentSong, CURL::GetRedacted(item->GetPath()).c_str()); playlist.SetUnPlayable(m_iCurrentSong); diff --git a/xbmc/ServiceBroker.cpp b/xbmc/ServiceBroker.cpp index 69adefdc25..e25a1b6413 100644 --- a/xbmc/ServiceBroker.cpp +++ b/xbmc/ServiceBroker.cpp @@ -142,6 +142,11 @@ bool CServiceBroker::IsBinaryAddonCacheUp() return g_application.m_ServiceManager->init_level > 1; } +bool CServiceBroker::IsServiceManagerUp() +{ + return g_application.m_ServiceManager->init_level == 3; +} + CWinSystemBase& CServiceBroker::GetWinSystem() { return g_application.m_ServiceManager->GetWinSystem(); diff --git a/xbmc/ServiceBroker.h b/xbmc/ServiceBroker.h index d0dcd30999..168ebccfc5 100644 --- a/xbmc/ServiceBroker.h +++ b/xbmc/ServiceBroker.h @@ -106,6 +106,7 @@ public: static CInputManager& GetInputManager(); static CFileExtensionProvider &GetFileExtensionProvider(); static bool IsBinaryAddonCacheUp(); + static bool IsServiceManagerUp(); static CNetwork& GetNetwork(); static CWinSystemBase& GetWinSystem(); static CRenderSystemBase& GetRenderSystem(); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp index e30cc7caf6..6c5e2afccf 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp @@ -108,7 +108,7 @@ bool CActiveAESink::HasPassthroughDevice() for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2) { CAEDeviceInfo& info = *itt2; - if (info.m_deviceType != AE_DEVTYPE_PCM) + if (info.m_deviceType != AE_DEVTYPE_PCM && !info.m_streamTypes.empty()) return true; } } diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp index 6214871813..8eb5dfc287 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp @@ -37,6 +37,7 @@ #include "settings/Settings.h" #include "utils/Log.h" #include "utils/StringUtils.h" +#include "utils/SystemInfo.h" #include "rendering/dx/DeviceResources.h" #include "rendering/dx/RenderContext.h" @@ -850,8 +851,32 @@ static bool HasATIMP2Bug(AVCodecContext *avctx) && avctx->color_trc == AVCOL_TRC_GAMMA28; } +// UHD HEVC Main10 causes crash on Xbox One S/X +static bool HasXbox4kHevcMain10Bug(AVCodecContext *avctx) +{ + if (CSysInfo::GetWindowsDeviceFamily() != CSysInfo::Xbox) + return false; + + if (avctx->codec_id != AV_CODEC_ID_HEVC) + return false; + + if (avctx->profile != FF_PROFILE_HEVC_MAIN_10) + return false; + + if (avctx->height <= 1080 || avctx->width <= 1920) + return false; + + return true; +} + static bool CheckCompatibility(AVCodecContext *avctx) { + if (HasXbox4kHevcMain10Bug(avctx)) + { + CLog::LogFunction(LOGWARNING, "DXVA", "UHD hevc main10 is not supported on Xbox One S/X. DXVA will not be used."); + return false; + } + if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && HasATIMP2Bug(avctx)) return false; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.cpp index 49c1e4cede..0a0595c608 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.cpp @@ -50,7 +50,7 @@ CDVDDemuxBXA::~CDVDDemuxBXA() Dispose(); } -bool CDVDDemuxBXA::Open(CDVDInputStream* pInput) +bool CDVDDemuxBXA::Open(std::shared_ptr<CDVDInputStream> pInput) { Abort(); @@ -99,7 +99,7 @@ void CDVDDemuxBXA::Dispose() bool CDVDDemuxBXA::Reset() { - CDVDInputStream* pInputStream = m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = m_pInput; Dispose(); return Open(pInputStream); } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.h index 80aa8e8be7..31c938f4a6 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxBXA.h @@ -54,7 +54,7 @@ public: CDVDDemuxBXA(); ~CDVDDemuxBXA() override; - bool Open(CDVDInputStream* pInput); + bool Open(std::shared_ptr<CDVDInputStream> pInput); void Dispose(); bool Reset() override; void Abort() override; @@ -70,7 +70,7 @@ public: protected: friend class CDemuxStreamAudioBXA; - CDVDInputStream* m_pInput; + std::shared_ptr<CDVDInputStream> m_pInput; int64_t m_bytes; CDemuxStreamAudioBXA *m_stream; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.cpp index 8ebc2eac95..930cfba383 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.cpp @@ -42,7 +42,7 @@ CDVDDemuxCDDA::~CDVDDemuxCDDA() Dispose(); } -bool CDVDDemuxCDDA::Open(CDVDInputStream* pInput) +bool CDVDDemuxCDDA::Open(std::shared_ptr<CDVDInputStream> pInput) { Abort(); @@ -79,7 +79,7 @@ void CDVDDemuxCDDA::Dispose() bool CDVDDemuxCDDA::Reset() { - CDVDInputStream* pInputStream = m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = m_pInput; Dispose(); return Open(pInputStream); } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.h index eefc545dd6..f712dcc0a9 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxCDDA.h @@ -35,7 +35,7 @@ public: CDVDDemuxCDDA(); ~CDVDDemuxCDDA() override; - bool Open(CDVDInputStream* pInput); + bool Open(std::shared_ptr<CDVDInputStream> pInput); void Dispose(); bool Reset() override; void Abort() override; @@ -51,7 +51,7 @@ public: protected: friend class CDemuxStreamAudioCDDA; - CDVDInputStream* m_pInput; + std::shared_ptr<CDVDInputStream> m_pInput; int64_t m_bytes; CDemuxStreamAudioCDDA *m_stream; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index b96f353887..472646595b 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -79,12 +79,12 @@ CDVDDemuxClient::~CDVDDemuxClient() Dispose(); } -bool CDVDDemuxClient::Open(CDVDInputStream* pInput) +bool CDVDDemuxClient::Open(std::shared_ptr<CDVDInputStream> pInput) { Abort(); m_pInput = pInput; - m_IDemux = dynamic_cast<CDVDInputStream::IDemux*>(m_pInput); + m_IDemux = std::dynamic_pointer_cast<CDVDInputStream::IDemux>(m_pInput); if (!m_IDemux) return false; @@ -113,7 +113,7 @@ void CDVDDemuxClient::DisposeStreams() bool CDVDDemuxClient::Reset() { - CDVDInputStream* pInputStream = m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = m_pInput; Dispose(); return Open(pInputStream); } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h index 230a43bd22..b3dc1bccdc 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h @@ -35,7 +35,7 @@ public: CDVDDemuxClient(); ~CDVDDemuxClient() override; - bool Open(CDVDInputStream* pInput); + bool Open(std::shared_ptr<CDVDInputStream> pInput); void Dispose(); bool Reset() override; void Abort() override; @@ -59,8 +59,8 @@ protected: void DisposeStreams(); std::shared_ptr<CDemuxStream> GetStreamInternal(int iStreamId); - CDVDInputStream* m_pInput; - CDVDInputStream::IDemux *m_IDemux; + std::shared_ptr<CDVDInputStream> m_pInput; + std::shared_ptr<CDVDInputStream::IDemux> m_IDemux; std::map<int, std::shared_ptr<CDemuxStream>> m_streams; int m_displayTime; double m_dtsAtDisplayTime; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 3f4b3646e4..31e62ad702 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -145,7 +145,7 @@ static int dvd_file_read(void *h, uint8_t* buf, int size) if(interrupt_cb(h)) return AVERROR_EXIT; - CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput; return pInputStream->Read(buf, size); } /* @@ -159,7 +159,7 @@ static int64_t dvd_file_seek(void *h, int64_t pos, int whence) if(interrupt_cb(h)) return AVERROR_EXIT; - CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput; if(whence == AVSEEK_SIZE) return pInputStream->GetLength(); else @@ -198,14 +198,14 @@ bool CDVDDemuxFFmpeg::Aborted() if(m_timeout.IsTimePast()) return true; - CDVDInputStreamFFmpeg * input = dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput); + std::shared_ptr<CDVDInputStreamFFmpeg> input = std::dynamic_pointer_cast<CDVDInputStreamFFmpeg>(m_pInput); if(input && input->Aborted()) return true; return false; } -bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo, bool fileinfo) +bool CDVDDemuxFFmpeg::Open(std::shared_ptr<CDVDInputStream> pInput, bool streaminfo, bool fileinfo) { AVInputFormat* iformat = NULL; std::string strFile; @@ -610,7 +610,7 @@ void CDVDDemuxFFmpeg::Dispose() bool CDVDDemuxFFmpeg::Reset() { - CDVDInputStream* pInputStream = m_pInput; + std::shared_ptr<CDVDInputStream> pInputStream = m_pInput; Dispose(); return Open(pInputStream, m_streaminfo); } @@ -680,8 +680,8 @@ void CDVDDemuxFFmpeg::SetSpeed(int iSpeed) AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromInput() { - const CDVDInputStreamFFmpeg *const input = - dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput); + const std::shared_ptr<CDVDInputStreamFFmpeg> input = + std::dynamic_pointer_cast<CDVDInputStreamFFmpeg>(m_pInput); CURL url = m_pInput->GetURL(); AVDictionary *options = nullptr; @@ -863,7 +863,7 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) double timestamp = (double)pts * num / den; double starttime = 0.0f; - CDVDInputStream::IMenus* menu = dynamic_cast<CDVDInputStream::IMenus*>(m_pInput); + std::shared_ptr<CDVDInputStream::IMenus> menu = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInput); if (!menu && m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE) starttime = (double)m_pFormatContext->start_time / AV_TIME_BASE; @@ -1632,7 +1632,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) #ifdef HAVE_LIBBLURAY if (m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY)) { - static_cast<CDVDInputStreamBluray*>(m_pInput)->GetStreamInfo(pStream->id, stream->language); + std::static_pointer_cast<CDVDInputStreamBluray>(m_pInput)->GetStreamInfo(pStream->id, stream->language); stream->dvdNavId = pStream->id; } #endif @@ -1706,7 +1706,7 @@ std::string CDVDDemuxFFmpeg::GetFileName() int CDVDDemuxFFmpeg::GetChapterCount() { - CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput); + std::shared_ptr<CDVDInputStream::IChapter> ich = std::dynamic_pointer_cast<CDVDInputStream::IChapter>(m_pInput); if(ich) return ich->GetChapterCount(); @@ -1718,7 +1718,7 @@ int CDVDDemuxFFmpeg::GetChapterCount() int CDVDDemuxFFmpeg::GetChapter() { - CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput); + std::shared_ptr<CDVDInputStream::IChapter> ich = std::dynamic_pointer_cast<CDVDInputStream::IChapter>(m_pInput); if(ich) return ich->GetChapter(); @@ -1741,7 +1741,7 @@ void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName, int chapterIdx { if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) chapterIdx = GetChapter(); - CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput); + std::shared_ptr<CDVDInputStream::IChapter> ich = std::dynamic_pointer_cast<CDVDInputStream::IChapter>(m_pInput); if(ich) ich->GetChapterName(strChapterName, chapterIdx); else @@ -1763,7 +1763,7 @@ int64_t CDVDDemuxFFmpeg::GetChapterPos(int chapterIdx) if(chapterIdx <= 0) return 0; - CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput); + std::shared_ptr<CDVDInputStream::IChapter> ich = std::dynamic_pointer_cast<CDVDInputStream::IChapter>(m_pInput); if(ich) return ich->GetChapterPos(chapterIdx); @@ -1775,7 +1775,7 @@ bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts) if(chapter < 1) chapter = 1; - CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput); + std::shared_ptr<CDVDInputStream::IChapter> ich = std::dynamic_pointer_cast<CDVDInputStream::IChapter>(m_pInput); if(ich) { CLog::Log(LOGDEBUG, "%s - chapter seeking using input stream", __FUNCTION__); diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.h index 81cb18505e..246bc5a79c 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.h @@ -88,7 +88,7 @@ public: CDVDDemuxFFmpeg(); ~CDVDDemuxFFmpeg() override; - bool Open(CDVDInputStream* pInput, bool streaminfo = true, bool fileinfo = false); + bool Open(std::shared_ptr<CDVDInputStream> pInput, bool streaminfo = true, bool fileinfo = false); void Dispose(); bool Reset() override ; void Flush() override; @@ -117,7 +117,7 @@ public: bool Aborted(); AVFormatContext* m_pFormatContext; - CDVDInputStream* m_pInput; + std::shared_ptr<CDVDInputStream> m_pInput; protected: friend class CDemuxStreamAudioFFmpeg; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp index ab2f98cfb5..a91fefbb27 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp @@ -71,12 +71,12 @@ bool CDVDDemuxVobsub::Open(const std::string& filename, int source, const std::s CFileItem item(vobsub, false); item.SetMimeType("video/x-vobsub"); item.SetContentLookup(false); - m_Input.reset(CDVDFactoryInputStream::CreateInputStream(NULL, item)); + m_Input = CDVDFactoryInputStream::CreateInputStream(NULL, item); if(!m_Input.get() || !m_Input->Open()) return false; m_Demuxer.reset(new CDVDDemuxFFmpeg()); - if(!m_Demuxer->Open(m_Input.get())) + if(!m_Demuxer->Open(m_Input)) return false; CDVDStreamInfo hints; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h index 748cd3e078..cc558fbce2 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h @@ -69,7 +69,7 @@ private: } STimestamp; std::string m_Filename; - std::unique_ptr<CDVDInputStream> m_Input; + std::shared_ptr<CDVDInputStream> m_Input; std::unique_ptr<CDVDDemuxFFmpeg> m_Demuxer; std::vector<STimestamp> m_Timestamps; std::vector<STimestamp>::iterator m_Timestamp; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.cpp index 4cb381e21e..3f49781940 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.cpp @@ -35,7 +35,7 @@ using namespace PVR; -CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo) +CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(std::shared_ptr<CDVDInputStream> pInputStream, bool fileinfo) { if (!pInputStream) return NULL; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.h index 8281d28f63..54391471b2 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDFactoryDemuxer.h @@ -20,11 +20,13 @@ * */ +#include <memory> + class CDVDDemux; class CDVDInputStream; class CDVDFactoryDemuxer { public: - static CDVDDemux* CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo = false); + static CDVDDemux* CreateDemuxer(std::shared_ptr<CDVDInputStream> pInputStream, bool fileinfo = false); }; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.cpp index 0d680a0508..96327dd719 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.cpp @@ -125,12 +125,12 @@ int CDemuxMultiSource::GetStreamLength() return length; } -bool CDemuxMultiSource::Open(CDVDInputStream* pInput) +bool CDemuxMultiSource::Open(std::shared_ptr<CDVDInputStream> pInput) { if (!pInput) return false; - m_pInput = dynamic_cast<InputStreamMultiStreams*>(pInput); + m_pInput = std::dynamic_pointer_cast<InputStreamMultiStreams>(pInput); if (!m_pInput) return false; @@ -138,7 +138,7 @@ bool CDemuxMultiSource::Open(CDVDInputStream* pInput) auto iter = m_pInput->m_InputStreams.begin(); while (iter != m_pInput->m_InputStreams.end()) { - DemuxPtr demuxer = DemuxPtr(CDVDFactoryDemuxer::CreateDemuxer(iter->get())); + DemuxPtr demuxer = DemuxPtr(CDVDFactoryDemuxer::CreateDemuxer((*iter))); if (!demuxer) { iter = m_pInput->m_InputStreams.erase(iter); diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.h index 1b2d56c2e1..0856a5cdf4 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DemuxMultiSource.h @@ -46,7 +46,7 @@ public: CDemuxMultiSource(); ~CDemuxMultiSource() override; - bool Open(CDVDInputStream* pInput); + bool Open(std::shared_ptr<CDVDInputStream> pInput); // implementation of CDVDDemux void Abort() override; @@ -68,7 +68,7 @@ private: void Dispose(); void SetMissingStreamDetails(DemuxPtr demuxer); - InputStreamMultiStreams* m_pInput = NULL; + std::shared_ptr<InputStreamMultiStreams> m_pInput = NULL; std::map<DemuxPtr, InputStreamPtr> m_DemuxerToInputStreamMap; DemuxQueue m_demuxerQueue; std::map<int64_t, DemuxPtr> m_demuxerMap; diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp index 3a6d8202a8..a25deadf6e 100644 --- a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp +++ b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp @@ -62,18 +62,17 @@ extern "C" { bool CDVDFileInfo::GetFileDuration(const std::string &path, int& duration) { - std::unique_ptr<CDVDInputStream> input; std::unique_ptr<CDVDDemux> demux; CFileItem item(path, false); - input.reset(CDVDFactoryInputStream::CreateInputStream(NULL, item)); - if (!input.get()) + auto input = CDVDFactoryInputStream::CreateInputStream(NULL, item); + if (!input) return false; if (!input->Open()) return false; - demux.reset(CDVDFactoryDemuxer::CreateDemuxer(input.get(), true)); + demux.reset(CDVDFactoryDemuxer::CreateDemuxer(input, true)); if (!demux.get()) return false; @@ -108,7 +107,7 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, CFileItem item(strPath, false); item.SetMimeTypeForInternetFile(); - CDVDInputStream *pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, item); + auto pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, item); if (!pInputStream) { CLog::Log(LOGERROR, "InputStream: Error creating stream for %s", redactPath.c_str()); @@ -118,8 +117,6 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, if (!pInputStream->Open()) { CLog::Log(LOGERROR, "InputStream: Error opening, %s", redactPath.c_str()); - if (pInputStream) - delete pInputStream; return false; } @@ -130,7 +127,6 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, pDemuxer = CDVDFactoryDemuxer::CreateDemuxer(pInputStream, true); if(!pDemuxer) { - delete pInputStream; CLog::Log(LOGERROR, "%s - Error creating demuxer", __FUNCTION__); return false; } @@ -140,12 +136,13 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, CLog::Log(LOGERROR, "%s - Exception thrown when opening demuxer", __FUNCTION__); if (pDemuxer) delete pDemuxer; - delete pInputStream; + return false; } if (pStreamDetails) { + DemuxerToStreamDetails(pInputStream, pDemuxer, *pStreamDetails, strPath); //extern subtitles @@ -304,8 +301,6 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, if (pDemuxer) delete pDemuxer; - delete pInputStream; - if(!bOk) { XFILE::CFile file; @@ -340,19 +335,17 @@ bool CDVDFileInfo::GetFileStreamDetails(CFileItem *pItem) CFileItem item(playablePath, false); item.SetMimeTypeForInternetFile(); - CDVDInputStream *pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, item); + auto pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, item); if (!pInputStream) return false; if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) { - delete pInputStream; return false; } if (pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) || !pInputStream->Open()) { - delete pInputStream; return false; } @@ -361,17 +354,15 @@ bool CDVDFileInfo::GetFileStreamDetails(CFileItem *pItem) { bool retVal = DemuxerToStreamDetails(pInputStream, pDemuxer, pItem->GetVideoInfoTag()->m_streamDetails, strFileNameAndPath); delete pDemuxer; - delete pInputStream; return retVal; } else { - delete pInputStream; return false; } } -bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDemux *pDemuxer, const std::vector<CStreamDetailSubtitle> &subs, CStreamDetails &details) +bool CDVDFileInfo::DemuxerToStreamDetails(std::shared_ptr<CDVDInputStream> pInputStream, CDVDDemux *pDemuxer, const std::vector<CStreamDetailSubtitle> &subs, CStreamDetails &details) { bool result = DemuxerToStreamDetails(pInputStream, pDemuxer, details); for (unsigned int i = 0; i < subs.size(); i++) @@ -385,7 +376,7 @@ bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDem } /* returns true if details have been added */ -bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDemux *pDemux, CStreamDetails &details, const std::string &path) +bool CDVDFileInfo::DemuxerToStreamDetails(std::shared_ptr<CDVDInputStream> pInputStream, CDVDDemux *pDemux, CStreamDetails &details, const std::string &path) { bool retVal = false; details.Reset(); @@ -455,12 +446,12 @@ bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDem // correct bluray runtime. we need the duration from the input stream, not the demuxer. if (pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY)) { - if (static_cast<CDVDInputStreamBluray*>(pInputStream)->GetTotalTime() > 0) + if (std::static_pointer_cast<CDVDInputStreamBluray>(pInputStream)->GetTotalTime() > 0) { const CStreamDetailVideo* dVideo = static_cast<const CStreamDetailVideo*>(details.GetNthStream(CStreamDetail::VIDEO, 0)); CStreamDetailVideo* detailVideo = const_cast<CStreamDetailVideo*>(dVideo); if (detailVideo) - detailVideo->m_iDuration = static_cast<CDVDInputStreamBluray*>(pInputStream)->GetTotalTime() / 1000; + detailVideo->m_iDuration = std::static_pointer_cast<CDVDInputStreamBluray>(pInputStream)->GetTotalTime() / 1000; } } #endif diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.h b/xbmc/cores/VideoPlayer/DVDFileInfo.h index 8771d73b08..c6fffdd80a 100644 --- a/xbmc/cores/VideoPlayer/DVDFileInfo.h +++ b/xbmc/cores/VideoPlayer/DVDFileInfo.h @@ -20,6 +20,7 @@ #pragma once +#include <memory> #include <string> #include <vector> @@ -40,12 +41,12 @@ public: // Probe the files streams and store the info in the VideoInfoTag static bool GetFileStreamDetails(CFileItem *pItem); - static bool DemuxerToStreamDetails(CDVDInputStream* pInputStream, CDVDDemux *pDemux, CStreamDetails &details, const std::string &path = ""); + static bool DemuxerToStreamDetails(std::shared_ptr<CDVDInputStream> pInputStream, CDVDDemux *pDemux, CStreamDetails &details, const std::string &path = ""); /** \brief Probe the file's internal and external streams and store the info in the StreamDetails parameter. * \param[out] details The file's StreamDetails consisting of internal streams and external subtitle streams. */ - static bool DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDemux *pDemuxer, const std::vector<CStreamDetailSubtitle> &subs, CStreamDetails &details); + static bool DemuxerToStreamDetails(std::shared_ptr<CDVDInputStream> pInputStream, CDVDDemux *pDemuxer, const std::vector<CStreamDetailSubtitle> &subs, CStreamDetails &details); static bool GetFileDuration(const std::string &path, int &duration); diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp index 20378f6fa2..dac1ee5cf2 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp @@ -44,7 +44,7 @@ #include "Util.h" -CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio) +std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio) { using namespace ADDON; @@ -67,7 +67,7 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer for (auto addonInfo : addonInfos) { if (CInputStreamAddon::Supports(addonInfo, fileitem)) - return new CInputStreamAddon(addonInfo, pPlayer, fileitem); + return std::shared_ptr<CInputStreamAddon>(new CInputStreamAddon(addonInfo, pPlayer, fileitem)); } if (fileitem.IsDiscImage()) @@ -77,10 +77,10 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer url.SetHostName(file); url.SetFileName("BDMV/index.bdmv"); if(XFILE::CFile::Exists(url.Get())) - return new CDVDInputStreamBluray(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamBluray>(new CDVDInputStreamBluray(pPlayer, fileitem)); #endif - return new CDVDInputStreamNavigator(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamNavigator>(new CDVDInputStreamNavigator(pPlayer, fileitem)); } #ifdef HAS_DVD_DRIVE @@ -88,20 +88,20 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer { #ifdef HAVE_LIBBLURAY if(XFILE::CFile::Exists(URIUtils::AddFileToFolder(file, "BDMV", "index.bdmv"))) - return new CDVDInputStreamBluray(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamBluray>(new CDVDInputStreamBluray(pPlayer, fileitem)); #endif - return new CDVDInputStreamNavigator(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamNavigator>(new CDVDInputStreamNavigator(pPlayer, fileitem)); } #endif if (fileitem.IsDVDFile(false, true)) - return (new CDVDInputStreamNavigator(pPlayer, fileitem)); + return std::shared_ptr<CDVDInputStreamNavigator>(new CDVDInputStreamNavigator(pPlayer, fileitem)); else if(file.substr(0, 6) == "pvr://") - return new CDVDInputStreamPVRManager(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamPVRManager>(new CDVDInputStreamPVRManager(pPlayer, fileitem)); #ifdef HAVE_LIBBLURAY else if (fileitem.IsType(".bdmv") || fileitem.IsType(".mpls") || file.substr(0, 7) == "bluray:") - return new CDVDInputStreamBluray(pPlayer, fileitem); + return std::shared_ptr<CDVDInputStreamBluray>(new CDVDInputStreamBluray(pPlayer, fileitem)); #endif else if(file.substr(0, 6) == "rtp://" || file.substr(0, 7) == "rtsp://" @@ -111,17 +111,17 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer || file.substr(0, 6) == "mms://" || file.substr(0, 7) == "mmst://" || file.substr(0, 7) == "mmsh://") - return new CDVDInputStreamFFmpeg(fileitem); + return std::shared_ptr<CDVDInputStreamFFmpeg>(new CDVDInputStreamFFmpeg(fileitem)); #ifdef ENABLE_DVDINPUTSTREAM_STACK else if(file.substr(0, 8) == "stack://") - return new CDVDInputStreamStack(fileitem); + return std::shared_ptr<CDVDInputStreamStack>(new CDVDInputStreamStack(fileitem)); #endif else if(file.substr(0, 7) == "rtmp://" || file.substr(0, 8) == "rtmpt://" || file.substr(0, 8) == "rtmpe://" || file.substr(0, 9) == "rtmpte://" || file.substr(0, 8) == "rtmps://") - return new CDVDInputStreamFFmpeg(fileitem); + return std::shared_ptr<CDVDInputStreamFFmpeg>(new CDVDInputStreamFFmpeg(fileitem)); CFileItem finalFileitem(fileitem); @@ -155,20 +155,20 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer } if (finalFileitem.IsType(".m3u8")) - return new CDVDInputStreamFFmpeg(finalFileitem); + return std::shared_ptr<CDVDInputStreamFFmpeg>(new CDVDInputStreamFFmpeg(finalFileitem)); if (finalFileitem.GetMimeType() == "application/vnd.apple.mpegurl") - return new CDVDInputStreamFFmpeg(finalFileitem); + return std::shared_ptr<CDVDInputStreamFFmpeg>(new CDVDInputStreamFFmpeg(finalFileitem)); if (URIUtils::IsProtocol(finalFileitem.GetPath(), "udp")) - return new CDVDInputStreamFFmpeg(finalFileitem); + return std::shared_ptr<CDVDInputStreamFFmpeg>(new CDVDInputStreamFFmpeg(finalFileitem)); } // our file interface handles all these types of streams - return (new CDVDInputStreamFile(finalFileitem)); + return std::shared_ptr<CDVDInputStreamFile>(new CDVDInputStreamFile(finalFileitem)); } -CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, const std::vector<std::string>& filenames) +std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, const std::vector<std::string>& filenames) { - return (new CInputStreamMultiSource(pPlayer, fileitem, filenames)); + return std::shared_ptr<CInputStreamMultiSource>(new CInputStreamMultiSource(pPlayer, fileitem, filenames)); } diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.h index 65e57e7664..e9ee6a94e9 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.h @@ -20,6 +20,7 @@ * */ +#include <memory> #include <string> #include <vector> @@ -31,6 +32,6 @@ class IVideoPlayer; class CDVDFactoryInputStream { public: - static CDVDInputStream* CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio = false); - static CDVDInputStream* CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, const std::vector<std::string>& filenames); + static std::shared_ptr<CDVDInputStream> CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio = false); + static std::shared_ptr<CDVDInputStream> CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, const std::vector<std::string>& filenames); }; diff --git a/xbmc/cores/VideoPlayer/DVDOverlayContainer.cpp b/xbmc/cores/VideoPlayer/DVDOverlayContainer.cpp index 3b6a94dcfc..7270d902e1 100644 --- a/xbmc/cores/VideoPlayer/DVDOverlayContainer.cpp +++ b/xbmc/cores/VideoPlayer/DVDOverlayContainer.cpp @@ -154,7 +154,7 @@ bool CDVDOverlayContainer::ContainsOverlayType(DVDOverlayType type) /* * iAction should be LIBDVDNAV_BUTTON_NORMAL or LIBDVDNAV_BUTTON_CLICKED */ -void CDVDOverlayContainer::UpdateOverlayInfo(CDVDInputStreamNavigator* pStream, CDVDDemuxSPU *pSpu, int iAction) +void CDVDOverlayContainer::UpdateOverlayInfo(std::shared_ptr<CDVDInputStreamNavigator> pStream, CDVDDemuxSPU *pSpu, int iAction) { CSingleLock lock(*this); diff --git a/xbmc/cores/VideoPlayer/DVDOverlayContainer.h b/xbmc/cores/VideoPlayer/DVDOverlayContainer.h index 9d453aedc9..46d0611705 100644 --- a/xbmc/cores/VideoPlayer/DVDOverlayContainer.h +++ b/xbmc/cores/VideoPlayer/DVDOverlayContainer.h @@ -20,6 +20,8 @@ * */ +#include <memory> + #include "DVDCodecs/Overlay/DVDOverlay.h" #include "threads/CriticalSection.h" @@ -41,7 +43,7 @@ public: void CleanUp(double pts); // validates all overlays against current pts int GetSize(); - void UpdateOverlayInfo(CDVDInputStreamNavigator* pStream, CDVDDemuxSPU *pSpu, int iAction); + void UpdateOverlayInfo(std::shared_ptr<CDVDInputStreamNavigator> pStream, CDVDDemuxSPU *pSpu, int iAction); private: VecOverlaysIter Remove(VecOverlaysIter itOverlay); // removes a specific overlay diff --git a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.cpp b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.cpp index 7b2e6f3a12..363e97bd1d 100644 --- a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.cpp +++ b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleStream.cpp @@ -40,7 +40,7 @@ bool CDVDSubtitleStream::Open(const std::string& strFile) { CFileItem item(strFile, false); item.SetContentLookup(false); - std::unique_ptr<CDVDInputStream> pInputStream(CDVDFactoryInputStream::CreateInputStream(NULL, item)); + std::shared_ptr<CDVDInputStream> pInputStream(CDVDFactoryInputStream::CreateInputStream(NULL, item)); if (pInputStream && pInputStream->Open()) { // prepare buffer diff --git a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.cpp b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.cpp index 3a9da0578a..77010407b5 100644 --- a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.cpp +++ b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitleTagSami.cpp @@ -233,11 +233,11 @@ void CDVDSubtitleTagSami::LoadHead(CDVDSubtitleStream* samiStream) std::string line = cLine; StringUtils::Trim(line); - if (!StringUtils::CompareNoCase(line, "<BODY>")) + if (StringUtils::EqualsNoCase(line, "<BODY>")) break; if (inSTYLE) { - if (!StringUtils::CompareNoCase(line, "</STYLE>")) + if (StringUtils::EqualsNoCase(line, "</STYLE>")) break; else { @@ -257,7 +257,7 @@ void CDVDSubtitleTagSami::LoadHead(CDVDSubtitleStream* samiStream) } else { - if (!StringUtils::CompareNoCase(line, "<STYLE TYPE=\"text/css\">")) + if (StringUtils::EqualsNoCase(line, "<STYLE TYPE=\"text/css\">")) inSTYLE = true; } } diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp index d4a96691e1..84fa00df7d 100644 --- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp +++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp @@ -20,6 +20,7 @@ #include "ProcessInfo.h" #include "cores/DataCacheCore.h" +#include "settings/AdvancedSettings.h" #include "threads/SingleLock.h" CCriticalSection createSection; @@ -528,9 +529,20 @@ float CProcessInfo::GetNewTempo() return m_newTempo; } +float CProcessInfo::MinTempoPlatform() +{ + return 0.75f; +} + +float CProcessInfo::MaxTempoPlatform() +{ + return 1.55f; +} + bool CProcessInfo::IsTempoAllowed(float tempo) { - if (tempo > 0.75 && tempo < 1.55) + if (tempo > MinTempoPlatform() && + (tempo < MaxTempoPlatform() || tempo < g_advancedSettings.m_maxTempo)) return true; return false; diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h index a718d3d50e..0c18021176 100644 --- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h +++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h @@ -98,7 +98,9 @@ public: void SetTempo(float tempo); void SetNewTempo(float tempo); float GetNewTempo(); - virtual bool IsTempoAllowed(float tempo); + bool IsTempoAllowed(float tempo); + virtual float MinTempoPlatform(); + virtual float MaxTempoPlatform(); void SetLevelVQ(int level); int GetLevelVQ(); void SetGuiRender(bool gui); diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index d1ba6a4126..a3019a1fc7 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -423,11 +423,11 @@ void CSelectionStreams::Update(SelectionStream& s) } } -void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer, std::string filename2) +void CSelectionStreams::Update(std::shared_ptr<CDVDInputStream> input, CDVDDemux* demuxer, std::string filename2) { if(input && input->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* nav = static_cast<CDVDInputStreamNavigator*>(input); + std::shared_ptr<CDVDInputStreamNavigator> nav = std::static_pointer_cast<CDVDInputStreamNavigator>(input); std::string filename = nav->GetFileName(); int source = Source(STREAM_SOURCE_NAV, filename); @@ -544,7 +544,7 @@ void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer, std:: CServiceBroker::GetDataCacheCore().SignalVideoInfoChange(); } -void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer) +void CSelectionStreams::Update(std::shared_ptr<CDVDInputStream> input, CDVDDemux* demuxer) { Update(input, demuxer, ""); } @@ -775,8 +775,9 @@ void CVideoPlayer::OnStartup() bool CVideoPlayer::OpenInputStream() { - if(m_pInputStream) - SAFE_DELETE(m_pInputStream); + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); CLog::Log(LOGNOTICE, "Creating InputStream"); @@ -980,7 +981,7 @@ void CVideoPlayer::OpenDefaultStreams(bool reset) if(!valid) CloseStream(m_CurrentSubtitle, false); - if (!dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream) || m_playerOptions.state.empty()) + if (!std::dynamic_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream) || m_playerOptions.state.empty()) SetSubtitleVisibleInternal(visible); // only set subtitle visibility if state not stored by dvd navigator, because navigator will restore it (if visible) // open teletext stream @@ -1252,15 +1253,15 @@ void CVideoPlayer::Prepare() return; } - if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream)) + if (std::shared_ptr<CDVDInputStream::IMenus> ptr = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream)) { CLog::Log(LOGNOTICE, "VideoPlayer: playing a file with menu's"); - if(dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream)) + if(std::dynamic_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream)) m_playerOptions.starttime = 0; if (!m_playerOptions.state.empty()) ptr->SetState(m_playerOptions.state); - else if(CDVDInputStreamNavigator* nav = dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream)) + else if(std::shared_ptr<CDVDInputStreamNavigator> nav = std::dynamic_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream)) nav->EnableSubtitleStream(m_processInfo->GetVideoSettings().m_SubtitleOn); } @@ -1471,7 +1472,7 @@ void CVideoPlayer::Process() continue; // check for a still frame state - if (CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream)) + if (std::shared_ptr<CDVDInputStream::IMenus> pStream = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream)) { // stills will be skipped if(m_dvd.state == DVDSTATE_STILL) @@ -1609,7 +1610,7 @@ void CVideoPlayer::Process() if (IsInMenuInternal()) { - if (CDVDInputStream::IMenus* menu = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream)) + if (std::shared_ptr<CDVDInputStream::IMenus> menu = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream)) { double correction = menu->GetTimeStampCorrection(); if (pPacket->dts != DVD_NOPTS_VALUE && pPacket->dts > correction) @@ -1751,7 +1752,7 @@ void CVideoPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket) m_VideoPlayerSubtitle->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop)); if(m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) - m_VideoPlayerSubtitle->UpdateOverlayInfo(static_cast<CDVDInputStreamNavigator*>(m_pInputStream), LIBDVDNAV_BUTTON_NORMAL); + m_VideoPlayerSubtitle->UpdateOverlayInfo(std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream), LIBDVDNAV_BUTTON_NORMAL); } void CVideoPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket) @@ -2467,7 +2468,9 @@ void CVideoPlayer::OnExit() SAFE_DELETE(m_pDemuxer); SAFE_DELETE(m_pSubtitleDemuxer); SAFE_DELETE(m_pCCDemuxer); - SAFE_DELETE(m_pInputStream); + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); // clean up all selection streams m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NONE); @@ -2535,7 +2538,9 @@ void CVideoPlayer::HandleMessages() SAFE_DELETE(m_pDemuxer); SAFE_DELETE(m_pSubtitleDemuxer); SAFE_DELETE(m_pCCDemuxer); - SAFE_DELETE(m_pInputStream); + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NONE); @@ -2679,7 +2684,7 @@ void CVideoPlayer::HandleMessages() { if(st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamNavigator> pStream = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream); if(pStream->SetActiveAudioStream(st.id)) { m_dvd.iSelectedAudioStream = -1; @@ -2718,7 +2723,7 @@ void CVideoPlayer::HandleMessages() { if (st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamNavigator> pStream = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream); if (pStream->SetAngle(st.id)) { m_dvd.iSelectedVideoStream = st.id; @@ -2755,7 +2760,7 @@ void CVideoPlayer::HandleMessages() { if(st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamNavigator> pStream = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream); if(pStream->SetActiveSubtitleStream(st.id)) { m_dvd.iSelectedSPUStream = -1; @@ -2790,7 +2795,7 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSetState* pMsgPlayerSetState = static_cast<CDVDMsgPlayerSetState*>(pMsg); - if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream)) + if (std::shared_ptr<CDVDInputStream::IMenus> ptr = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream)) { if(ptr->SetState(pMsgPlayerSetState->GetState())) { @@ -2833,7 +2838,7 @@ void CVideoPlayer::HandleMessages() if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) && speed != m_playSpeed) { - CDVDInputStreamPVRManager* pvrinputstream = static_cast<CDVDInputStreamPVRManager*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamPVRManager> pvrinputstream = std::static_pointer_cast<CDVDInputStreamPVRManager>(m_pInputStream); pvrinputstream->Pause( speed == 0 ); } @@ -3290,7 +3295,7 @@ bool CVideoPlayer::GetSubtitleVisible() { if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamNavigator> pStream = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream); return pStream->IsSubtitleStreamEnabled(); } @@ -3308,7 +3313,7 @@ void CVideoPlayer::SetSubtitleVisibleInternal(bool bVisible) m_VideoPlayerVideo->EnableSubtitle(bVisible); if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) - static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(bVisible); + std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream)->EnableSubtitleStream(bVisible); } TextCacheStruct_t* CVideoPlayer::GetTeletextCache() @@ -3608,7 +3613,7 @@ bool CVideoPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { /* set aspect ratio as requested by navigator for dvd's */ - float aspect = static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->GetVideoAspectRatio(); + float aspect = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream)->GetVideoAspectRatio(); if (aspect != 0.0) { hint.aspect = aspect; @@ -3635,7 +3640,7 @@ bool CVideoPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) } } - CDVDInputStream::IMenus* pMenus = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream); + std::shared_ptr<CDVDInputStream::IMenus> pMenus = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream); if(pMenus && pMenus->IsInMenu()) hint.stills = true; @@ -3969,7 +3974,7 @@ int CVideoPlayer::OnDiscNavResult(void* pData, int iMessage) if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { - CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream); + std::shared_ptr<CDVDInputStreamNavigator> pStream = std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream); switch (iMessage) { @@ -4050,7 +4055,7 @@ int CVideoPlayer::OnDiscNavResult(void* pData, int iMessage) //dvdnav_highlight_event_t* pInfo = (dvdnav_highlight_event_t*)pData; int iButton = pStream->GetCurrentButton(); CLog::Log(LOGDEBUG, "DVDNAV_HIGHLIGHT: Highlight button %d\n", iButton); - m_VideoPlayerSubtitle->UpdateOverlayInfo(static_cast<CDVDInputStreamNavigator*>(m_pInputStream), LIBDVDNAV_BUTTON_NORMAL); + m_VideoPlayerSubtitle->UpdateOverlayInfo(std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream), LIBDVDNAV_BUTTON_NORMAL); } break; case DVDNAV_VTS_CHANGE: @@ -4147,7 +4152,7 @@ bool CVideoPlayer::OnAction(const CAction &action) } \ } while(false) - CDVDInputStream::IMenus* pMenus = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream); + std::shared_ptr<CDVDInputStream::IMenus> pMenus = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream); if (pMenus) { if (m_dvd.state == DVDSTATE_STILL && m_dvd.iDVDStillTime != 0 && pMenus->GetTotalButtons() == 0) @@ -4297,7 +4302,7 @@ bool CVideoPlayer::OnAction(const CAction &action) CLog::Log(LOGDEBUG, " - button select"); // show button pushed overlay if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) - m_VideoPlayerSubtitle->UpdateOverlayInfo(static_cast<CDVDInputStreamNavigator*>(m_pInputStream), LIBDVDNAV_BUTTON_CLICKED); + m_VideoPlayerSubtitle->UpdateOverlayInfo(std::static_pointer_cast<CDVDInputStreamNavigator>(m_pInputStream), LIBDVDNAV_BUTTON_CLICKED); pMenus->ActivateButton(); } @@ -4376,7 +4381,7 @@ bool CVideoPlayer::OnAction(const CAction &action) bool CVideoPlayer::IsInMenuInternal() const { - CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream); + std::shared_ptr<CDVDInputStream::IMenus> pStream = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream); if (pStream) { if (m_dvd.state == DVDSTATE_STILL) @@ -4609,7 +4614,7 @@ void CVideoPlayer::UpdatePlayState(double timeout) state.time = (m_clock.GetClock(false) - times.ptsStart) * 1000 / DVD_TIME_BASE; state.timeMax = (times.ptsEnd - times.ptsStart) * 1000 / DVD_TIME_BASE; state.timeMin = (times.ptsBegin - times.ptsStart) * 1000 / DVD_TIME_BASE; - state.time_offset = 0; + state.time_offset = -times.ptsStart; } else if (pDisplayTime && pDisplayTime->GetTotalTime() > 0) { @@ -4631,7 +4636,7 @@ void CVideoPlayer::UpdatePlayState(double timeout) state.time_offset = 0; } - if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream)) + if (std::shared_ptr<CDVDInputStream::IMenus> ptr = std::dynamic_pointer_cast<CDVDInputStream::IMenus>(m_pInputStream)) { if (!ptr->GetState(state.player_state)) state.player_state = ""; diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h index 58a0295432..1bd8c916f1 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.h +++ b/xbmc/cores/VideoPlayer/VideoPlayer.h @@ -261,8 +261,8 @@ public: void Clear(StreamType type, StreamSource source); int Source(StreamSource source, std::string filename); void Update(SelectionStream& s); - void Update(CDVDInputStream* input, CDVDDemux* demuxer); - void Update(CDVDInputStream* input, CDVDDemux* demuxer, std::string filename2); + void Update(std::shared_ptr<CDVDInputStream> input, CDVDDemux* demuxer); + void Update(std::shared_ptr<CDVDInputStream> input, CDVDDemux* demuxer, std::string filename2); std::vector<SelectionStream> Get(StreamType type); template<typename Compare> std::vector<SelectionStream> Get(StreamType type, Compare compare) @@ -543,7 +543,7 @@ protected: CDVDClock m_clock; // master clock CDVDOverlayContainer m_overlayContainer; - CDVDInputStream* m_pInputStream; // input stream for current playing file + std::shared_ptr<CDVDInputStream> m_pInputStream; // input stream for current playing file CDVDDemux* m_pDemuxer; // demuxer for current playing file CDVDDemux* m_pSubtitleDemuxer; CDVDDemuxCC* m_pCCDemuxer; diff --git a/xbmc/cores/VideoPlayer/VideoPlayerSubtitle.h b/xbmc/cores/VideoPlayer/VideoPlayerSubtitle.h index f1f28899bf..7882e09f8d 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayerSubtitle.h +++ b/xbmc/cores/VideoPlayer/VideoPlayerSubtitle.h @@ -44,7 +44,7 @@ public: void FindSubtitles(const char* strFilename); int GetSubtitleCount(); - void UpdateOverlayInfo(CDVDInputStreamNavigator* pStream, int iAction) { m_pOverlayContainer->UpdateOverlayInfo(pStream, &m_dvdspus, iAction); } + void UpdateOverlayInfo(std::shared_ptr<CDVDInputStreamNavigator> pStream, int iAction) { m_pOverlayContainer->UpdateOverlayInfo(pStream, &m_dvdspus, iAction); } bool AcceptsData() const override; void SendMessage(CDVDMsg* pMsg, int priority = 0) override; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp index 255c5ffb41..2912ced554 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp @@ -2491,33 +2491,15 @@ void CLinuxRendererGL::SetTextureFilter(GLenum method) bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) { - if(feature == RENDERFEATURE_BRIGHTNESS) - { - return (m_renderMethod & RENDER_GLSL); - } - - if(feature == RENDERFEATURE_CONTRAST) - { - return (m_renderMethod & RENDER_GLSL); - } - - if(feature == RENDERFEATURE_GAMMA) - return false; - - if(feature == RENDERFEATURE_NOISE) - return false; - - if(feature == RENDERFEATURE_SHARPNESS) - { - return false; - } - - if (feature == RENDERFEATURE_STRETCH || - feature == RENDERFEATURE_ZOOM || - feature == RENDERFEATURE_VERTICAL_SHIFT || - feature == RENDERFEATURE_PIXEL_RATIO || - feature == RENDERFEATURE_POSTPROCESS || - feature == RENDERFEATURE_ROTATION) + if (feature == RENDERFEATURE_STRETCH || + feature == RENDERFEATURE_NONLINSTRETCH || + feature == RENDERFEATURE_ZOOM || + feature == RENDERFEATURE_VERTICAL_SHIFT || + feature == RENDERFEATURE_PIXEL_RATIO || + feature == RENDERFEATURE_POSTPROCESS || + feature == RENDERFEATURE_ROTATION || + feature == RENDERFEATURE_BRIGHTNESS || + feature == RENDERFEATURE_CONTRAST) return true; return false; diff --git a/xbmc/cores/omxplayer/OMXHelper.cpp b/xbmc/cores/omxplayer/OMXHelper.cpp index 38a4046e5d..b202a36a09 100644 --- a/xbmc/cores/omxplayer/OMXHelper.cpp +++ b/xbmc/cores/omxplayer/OMXHelper.cpp @@ -35,7 +35,7 @@ return (lh) > (rh); \ } while(0) -bool OMXPlayerUnsuitable(bool m_HasVideo, bool m_HasAudio, CDVDDemux* m_pDemuxer, CDVDInputStream* m_pInputStream, CSelectionStreams &m_SelectionStreams) +bool OMXPlayerUnsuitable(bool m_HasVideo, bool m_HasAudio, CDVDDemux* m_pDemuxer, std::shared_ptr<CDVDInputStream> m_pInputStream, CSelectionStreams &m_SelectionStreams) { // if no OMXPlayer acceleration then it is not suitable if (!CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_USEOMXPLAYER)) diff --git a/xbmc/cores/omxplayer/OMXHelper.h b/xbmc/cores/omxplayer/OMXHelper.h index de6525bf19..78a5901e6c 100644 --- a/xbmc/cores/omxplayer/OMXHelper.h +++ b/xbmc/cores/omxplayer/OMXHelper.h @@ -22,7 +22,9 @@ #include "system.h" -bool OMXPlayerUnsuitable(bool m_HasVideo, bool m_HasAudio, CDVDDemux* m_pDemuxer, CDVDInputStream* m_pInputStream, CSelectionStreams &m_SelectionStreams); +#include <memory> + +bool OMXPlayerUnsuitable(bool m_HasVideo, bool m_HasAudio, CDVDDemux* m_pDemuxer, std::shared_ptr<CDVDInputStream> m_pInputStream, CSelectionStreams &m_SelectionStreams); bool OMXDoProcessing(struct SOmxPlayerState &m_OmxPlayerState, int m_playSpeed, IDVDStreamPlayerVideo *m_VideoPlayerVideo, IDVDStreamPlayerAudio *m_VideoPlayerAudio, CCurrentStream m_CurrentAudio, CCurrentStream m_CurrentVideo, bool m_HasVideo, bool m_HasAudio, CProcessInfo &processInfo); bool OMXStillPlaying(bool waitVideo, bool waitAudio, bool eosVideo, bool eosAudio); diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp index 819c7991f4..c178c7c195 100644 --- a/xbmc/cores/paplayer/PAPlayer.cpp +++ b/xbmc/cores/paplayer/PAPlayer.cpp @@ -582,6 +582,7 @@ void PAPlayer::Process() GetTimeInternal(); //update for GUI } + m_isPlaying = false; } inline void PAPlayer::ProcessStreams(double &freeBufferTime) diff --git a/xbmc/cores/paplayer/VideoPlayerCodec.cpp b/xbmc/cores/paplayer/VideoPlayerCodec.cpp index 8b4015317b..0d483e4969 100644 --- a/xbmc/cores/paplayer/VideoPlayerCodec.cpp +++ b/xbmc/cores/paplayer/VideoPlayerCodec.cpp @@ -114,9 +114,9 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache) if (!m_pInputStream->Open()) { CLog::Log(LOGERROR, "%s: Error opening file %s", __FUNCTION__, strFileToOpen.c_str()); - if (m_pInputStream) - delete m_pInputStream; - m_pInputStream = NULL; + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); return false; } @@ -127,8 +127,9 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache) m_pDemuxer = CDVDFactoryDemuxer::CreateDemuxer(m_pInputStream); if (!m_pDemuxer) { - delete m_pInputStream; - m_pInputStream = NULL; + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); CLog::Log(LOGERROR, "%s: Error creating demuxer", __FUNCTION__); return false; } @@ -141,8 +142,6 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache) delete m_pDemuxer; m_pDemuxer = NULL; } - delete m_pInputStream; - m_pInputStream = NULL; return false; } @@ -165,8 +164,9 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache) CLog::Log(LOGERROR, "%s: Could not find audio stream", __FUNCTION__); delete m_pDemuxer; m_pDemuxer = NULL; - delete m_pInputStream; - m_pInputStream = NULL; + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); return false; } @@ -179,8 +179,9 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache) CLog::Log(LOGERROR, "%s: Could not create audio codec", __FUNCTION__); delete m_pDemuxer; m_pDemuxer = NULL; - delete m_pInputStream; - m_pInputStream = NULL; + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); return false; } @@ -298,11 +299,9 @@ void VideoPlayerCodec::DeInit() m_pDemuxer = NULL; } - if (m_pInputStream != NULL) - { - delete m_pInputStream; - m_pInputStream = NULL; - } + if (m_pInputStream.use_count() > 1) + throw std::runtime_error("m_pInputStream reference count is greater than 1"); + m_pInputStream.reset(); if (m_pAudioCodec != NULL) { diff --git a/xbmc/cores/paplayer/VideoPlayerCodec.h b/xbmc/cores/paplayer/VideoPlayerCodec.h index 4cea55315e..7ecffd5ee9 100644 --- a/xbmc/cores/paplayer/VideoPlayerCodec.h +++ b/xbmc/cores/paplayer/VideoPlayerCodec.h @@ -56,7 +56,7 @@ private: CAEStreamInfo::DataType GetPassthroughStreamType(AVCodecID codecId, int samplerate); CDVDDemux* m_pDemuxer; - CDVDInputStream* m_pInputStream; + std::shared_ptr<CDVDInputStream> m_pInputStream; CDVDAudioCodec* m_pAudioCodec; std::string m_strContentType; diff --git a/xbmc/filesystem/IDirectory.cpp b/xbmc/filesystem/IDirectory.cpp index 0a54e2670c..866bfab3f3 100644 --- a/xbmc/filesystem/IDirectory.cpp +++ b/xbmc/filesystem/IDirectory.cpp @@ -72,22 +72,18 @@ bool IDirectory::IsAllowed(const CURL& url) const std::string folder = URIUtils::GetDirectory(fileName); URIUtils::RemoveSlashAtEnd(folder); folder = URIUtils::GetFileName(folder); - if (folder.size() <= 3) // cannot be a vcd variant - return true; - - if (!StringUtils::CompareNoCase(folder, "vcd") && - !StringUtils::CompareNoCase(folder, "MPEGAV") && - !StringUtils::CompareNoCase(folder, "CDDA")) - return true; - - // Allow filenames of the form AVSEQ##(#).DAT, ITEM###(#).DAT - // and MUSIC##(#).DAT - return (fileName.length() == 11 || fileName.length() == 12) && - (StringUtils::StartsWithNoCase(fileName, "AVSEQ") || - StringUtils::StartsWithNoCase(fileName, "MUSIC") || - StringUtils::StartsWithNoCase(fileName, "ITEM")); + if (StringUtils::EqualsNoCase(folder, "vcd") || + StringUtils::EqualsNoCase(folder, "mpegav") || + StringUtils::EqualsNoCase(folder, "cdda")) + { + // Allow filenames of the form AVSEQ##(#).DAT, ITEM###(#).DAT + // and MUSIC##(#).DAT + return (fileName.length() == 11 || fileName.length() == 12) && + (StringUtils::StartsWithNoCase(fileName, "AVSEQ") || + StringUtils::StartsWithNoCase(fileName, "MUSIC") || + StringUtils::StartsWithNoCase(fileName, "ITEM")); + } } - return true; } diff --git a/xbmc/filesystem/SMBFile.cpp b/xbmc/filesystem/SMBFile.cpp index a7c7cbbbc4..328c676239 100644 --- a/xbmc/filesystem/SMBFile.cpp +++ b/xbmc/filesystem/SMBFile.cpp @@ -118,6 +118,15 @@ void CSMB::Init() fprintf(f, "\tlock directory = %s/.smb/\n", home.c_str()); + // set minimum smbclient protocol version + if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MINPROTOCOL) > 0) + { + if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MINPROTOCOL) == 1) + fprintf(f, "\tclient min protocol = NT1\n"); + else + fprintf(f, "\tclient min protocol = SMB%d\n", CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MINPROTOCOL)); + } + // set maximum smbclient protocol version if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MAXPROTOCOL) > 0) { @@ -127,6 +136,13 @@ void CSMB::Init() fprintf(f, "\tclient max protocol = SMB%d\n", CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MAXPROTOCOL)); } + // set legacy security options + if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_SMB_LEGACYSECURITY) && (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_SMB_MAXPROTOCOL) == 1)) + { + fprintf(f, "\tclient NTLMv2 auth = no\n"); + fprintf(f, "\tclient use spnego = no\n"); + } + // set wins server if there's one. name resolve order defaults to 'lmhosts host wins bcast'. // if no WINS server has been specified the wins method will be ignored. if (CServiceBroker::GetSettings().GetString(CSettings::SETTING_SMB_WINSSERVER).length() > 0 && !StringUtils::EqualsNoCase(CServiceBroker::GetSettings().GetString(CSettings::SETTING_SMB_WINSSERVER), "0.0.0.0") ) diff --git a/xbmc/games/windows/GUIWindowGames.cpp b/xbmc/games/windows/GUIWindowGames.cpp index d5ff3b85a6..c4fcc7c5de 100644 --- a/xbmc/games/windows/GUIWindowGames.cpp +++ b/xbmc/games/windows/GUIWindowGames.cpp @@ -335,5 +335,5 @@ void CGUIWindowGames::OnItemInfo(int itemNumber) bool CGUIWindowGames::PlayGame(const CFileItem &item) { - return g_application.PlayFile(item, "") == PLAYBACK_OK; + return g_application.PlayFile(item, ""); } diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp index 9ad0bfede0..cfbf60bfc0 100644 --- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp +++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp @@ -652,7 +652,7 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye bool match = false; for (auto entry : possiblePlayers) { - if (StringUtils::CompareNoCase(entry, playername)) + if (StringUtils::EqualsNoCase(entry, playername)) { match = true; break; diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp index 2bb584b40f..a3fc07e437 100644 --- a/xbmc/interfaces/python/XBPython.cpp +++ b/xbmc/interfaces/python/XBPython.cpp @@ -35,6 +35,7 @@ #include "Util.h" #ifdef TARGET_WINDOWS #include "utils/Environment.h" +#include "utils/SystemInfo.h" #endif #include "settings/AdvancedSettings.h" @@ -603,6 +604,10 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker) CEnvironment::putenv(buf); buf = "OS=win32"; CEnvironment::putenv(buf); +#ifdef _DEBUG + if (CSysInfo::GetWindowsDeviceFamily() == CSysInfo::Xbox) + CEnvironment::putenv("PYTHONCASEOK=1"); +#endif #endif if (PyEval_ThreadsInitialized()) diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp index 4285f1ad6c..116e8e81a6 100644 --- a/xbmc/network/AirTunesServer.cpp +++ b/xbmc/network/AirTunesServer.cpp @@ -429,7 +429,7 @@ void CAirTunesServer::SetupRemoteControl() std::vector<CZeroconfBrowser::ZeroconfService> services = CZeroconfBrowser::GetInstance()->GetFoundServices(); for (auto service : services ) { - if (StringUtils::CompareNoCase(service.GetType(), std::string(ZEROCONF_DACP_SERVICE) + ".") == 0) + if (StringUtils::EqualsNoCase(service.GetType(), std::string(ZEROCONF_DACP_SERVICE) + ".")) { #define DACP_NAME_PREFIX "iTunes_Ctrl_" // name has the form "iTunes_Ctrl_56B29BB6CB904862" diff --git a/xbmc/network/NetworkServices.cpp b/xbmc/network/NetworkServices.cpp index 90ed446d7b..cbf916184b 100644 --- a/xbmc/network/NetworkServices.cpp +++ b/xbmc/network/NetworkServices.cpp @@ -160,7 +160,8 @@ bool CNetworkServices::OnSettingChanging(std::shared_ptr<const CSetting> setting const std::string &settingId = setting->GetId(); #ifdef HAS_WEB_SERVER if (settingId == CSettings::SETTING_SERVICES_WEBSERVER || - settingId == CSettings::SETTING_SERVICES_WEBSERVERPORT) + settingId == CSettings::SETTING_SERVICES_WEBSERVERPORT || + settingId == CSettings::SETTING_SERVICES_WEBSERVERSSL) { if (IsWebserverRunning() && !StopWebserver()) return false; @@ -423,7 +424,9 @@ void CNetworkServices::OnSettingChanged(std::shared_ptr<const CSetting> setting) #endif // HAS_WEB_SERVER if (settingId == CSettings::SETTING_SMB_WINSSERVER || settingId == CSettings::SETTING_SMB_WORKGROUP || - settingId == CSettings::SETTING_SMB_MAXPROTOCOL) + settingId == CSettings::SETTING_SMB_MINPROTOCOL || + settingId == CSettings::SETTING_SMB_MAXPROTOCOL || + settingId == CSettings::SETTING_SMB_LEGACYSECURITY) { // okey we really don't need to restart, only deinit samba, but that could be damn hard if something is playing //! @todo - General way of handling setting changes that require restart diff --git a/xbmc/network/WebServer.cpp b/xbmc/network/WebServer.cpp index 685b81ea12..19be1e56f2 100644 --- a/xbmc/network/WebServer.cpp +++ b/xbmc/network/WebServer.cpp @@ -35,6 +35,7 @@ #include "network/httprequesthandler/IHTTPRequestHandler.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" +#include "ServiceBroker.h" #include "threads/SingleLock.h" #include "URL.h" #include "Util.h" @@ -83,7 +84,9 @@ CWebServer::CWebServer() m_thread_stacksize(0), m_authenticationRequired(false), m_authenticationUsername("kodi"), - m_authenticationPassword("") + m_authenticationPassword(""), + m_key(), + m_cert() { #if defined(TARGET_DARWIN) void *stack_addr; @@ -1110,14 +1113,96 @@ static void logFromMHD(void* unused, const char* fmt, va_list ap) } } +bool CWebServer::LoadCert(std::string &skey, std::string &scert) +{ + XFILE::CFile file; + XFILE::auto_buffer buf; + const char* keyFile = "special://userdata/server.key"; + const char* certFile = "special://userdata/server.pem"; + + if (!file.Exists(keyFile) || !file.Exists(certFile)) + return false; + + if (file.LoadFile(keyFile, buf) > 0) + { + skey.resize(buf.length()); + skey.assign(buf.get()); + file.Close(); + } + else + CLog::Log(LOGDEBUG, "WebServer %s: Error loading: %s", __FUNCTION__, keyFile); + + if (file.LoadFile(certFile, buf) > 0) + { + scert.resize(buf.length()); + scert.assign(buf.get()); + file.Close(); + } + else + CLog::Log(LOGDEBUG, "WebServer %s: Error loading: %s", __FUNCTION__, certFile); + + if (!skey.empty() && !scert.empty()) + { + CLog::Log(LOGERROR, "WebServer %s: found server key: %s, certificate: %s, HTTPS support enabled", __FUNCTION__, keyFile, certFile); + return true; + } + return false; +} + struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port) { unsigned int timeout = 60 * 60 * 24; + const char* ciphers = "NORMAL:-VERS-TLS1.0"; #if MHD_VERSION >= 0x00040500 MHD_set_panic_func(&panicHandlerForMHD, nullptr); #endif + if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_SERVICES_WEBSERVERSSL) && + MHD_is_feature_supported(MHD_FEATURE_SSL) == MHD_YES && + LoadCert(m_key, m_cert)) + // SSL enabled + return MHD_start_daemon(flags | +#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) + // use main thread for each connection, can only handle one request at a + // time [unless you set the thread pool size] + MHD_USE_SELECT_INTERNALLY +#else + // one thread per connection + // WARNING: set MHD_OPTION_CONNECTION_TIMEOUT to something higher than 1 + // otherwise on libmicrohttpd 0.4.4-1 it spins a busy loop + MHD_USE_THREAD_PER_CONNECTION +#endif +#if (MHD_VERSION >= 0x00095207) + | MHD_USE_INTERNAL_POLLING_THREAD /* MHD_USE_THREAD_PER_CONNECTION must be used only with MHD_USE_INTERNAL_POLLING_THREAD since 0.9.54 */ +#endif +#if (MHD_VERSION >= 0x00040001) + | MHD_USE_DEBUG /* Print MHD error messages to log */ +#endif + | MHD_USE_SSL + , + port, + 0, + 0, + &CWebServer::AnswerToConnection, + this, + +#if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) + MHD_OPTION_THREAD_POOL_SIZE, 4, +#endif + MHD_OPTION_CONNECTION_LIMIT, 512, + MHD_OPTION_CONNECTION_TIMEOUT, timeout, + MHD_OPTION_URI_LOG_CALLBACK, &CWebServer::UriRequestLogger, this, +#if (MHD_VERSION >= 0x00040001) + MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, 0, +#endif // MHD_VERSION >= 0x00040001 + MHD_OPTION_THREAD_STACK_SIZE, m_thread_stacksize, + MHD_OPTION_HTTPS_MEM_KEY, m_key.c_str(), + MHD_OPTION_HTTPS_MEM_CERT, m_cert.c_str(), + MHD_OPTION_HTTPS_PRIORITIES, ciphers, + MHD_OPTION_END); + + // No SSL return MHD_start_daemon(flags | #if (MHD_VERSION >= 0x00040002) && (MHD_VERSION < 0x00090B01) // use main thread for each connection, can only handle one request at a @@ -1134,11 +1219,11 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port) #endif #if (MHD_VERSION >= 0x00040001) | MHD_USE_DEBUG /* Print MHD error messages to log */ -#endif +#endif , port, - NULL, - NULL, + 0, + 0, &CWebServer::AnswerToConnection, this, @@ -1149,7 +1234,7 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port) MHD_OPTION_CONNECTION_TIMEOUT, timeout, MHD_OPTION_URI_LOG_CALLBACK, &CWebServer::UriRequestLogger, this, #if (MHD_VERSION >= 0x00040001) - MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, NULL, + MHD_OPTION_EXTERNAL_LOGGER, &logFromMHD, 0, #endif // MHD_VERSION >= 0x00040001 MHD_OPTION_THREAD_STACK_SIZE, m_thread_stacksize, MHD_OPTION_END); @@ -1166,7 +1251,6 @@ bool CWebServer::Start(uint16_t port, const std::string &username, const std::st closesocket(v6testSock); m_daemon_ip6 = StartMHD(MHD_USE_IPv6, port); } - m_daemon_ip4 = StartMHD(0, port); m_running = (m_daemon_ip6 != nullptr) || (m_daemon_ip4 != nullptr); @@ -1205,6 +1289,11 @@ bool CWebServer::IsStarted() return m_running; } +bool CWebServer::WebServerSupportsSSL() +{ + return MHD_is_feature_supported(MHD_FEATURE_SSL) == MHD_YES; +} + void CWebServer::SetCredentials(const std::string &username, const std::string &password) { CSingleLock lock(m_critSection); diff --git a/xbmc/network/WebServer.h b/xbmc/network/WebServer.h index c03ecb9711..f71ae98e53 100644 --- a/xbmc/network/WebServer.h +++ b/xbmc/network/WebServer.h @@ -44,6 +44,7 @@ public: bool Start(uint16_t port, const std::string &username, const std::string &password); bool Stop(); bool IsStarted(); + static bool WebServerSupportsSSL(); void SetCredentials(const std::string &username, const std::string &password); void RegisterRequestHandler(IHTTPRequestHandler *handler); @@ -139,6 +140,8 @@ private: unsigned int size); #endif + bool LoadCert(std::string &skey, std::string &scert); + uint16_t m_port; struct MHD_Daemon *m_daemon_ip6; struct MHD_Daemon *m_daemon_ip4; @@ -147,6 +150,8 @@ private: bool m_authenticationRequired; std::string m_authenticationUsername; std::string m_authenticationPassword; + std::string m_key; + std::string m_cert; CCriticalSection m_critSection; std::vector<IHTTPRequestHandler *> m_requestHandlers; }; diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp index 3651501ef3..031edaca4d 100644 --- a/xbmc/pictures/GUIWindowSlideShow.cpp +++ b/xbmc/pictures/GUIWindowSlideShow.cpp @@ -556,7 +556,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re else if (m_Image[1 - m_iCurrentPic].IsLoaded()) { if (g_application.GetAppPlayer().IsPlayingVideo()) - g_application.GetAppPlayer().CloseFile(); + g_application.GetAppPlayer().ClosePlayer(); m_bPlayingVideo = false; m_iVideoSlide = -1; @@ -770,7 +770,7 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action) if (m_slides.size()) AnnouncePlayerStop(m_slides.at(m_iCurrentSlide)); if (g_application.GetAppPlayer().IsPlayingVideo()) - g_application.GetAppPlayer().CloseFile(); + g_application.GetAppPlayer().ClosePlayer(); Close(); break; @@ -1099,16 +1099,14 @@ bool CGUIWindowSlideShow::PlayVideo() CLog::Log(LOGDEBUG, "Playing current video slide %s", item->GetPath().c_str()); m_bPlayingVideo = true; m_iVideoSlide = m_iCurrentSlide; - PlayBackRet ret = g_application.PlayFile(*item, ""); - if (ret == PLAYBACK_OK) + bool ret = g_application.PlayFile(*item, ""); + if (ret == true) return true; - if (ret == PLAYBACK_FAIL) + else { CLog::Log(LOGINFO, "set video %s unplayable", item->GetPath().c_str()); item->SetProperty("unplayable", true); } - else if (ret == PLAYBACK_CANCELED) - m_bPause = true; m_bPlayingVideo = false; m_iVideoSlide = -1; return false; diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index 3e86520604..34c7063c90 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -284,7 +284,17 @@ void CPVRGUIInfo::UpdateTimeshift(void) m_iStartTime = iStartTime; m_iTimeshiftStartTime = iStartTime + iMinTime; m_iTimeshiftEndTime = iStartTime + iMaxTime; - m_iTimeshiftPlayTime = iStartTime + iPlayTime; + + if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) + { + // getstreamtimes api + m_iTimeshiftPlayTime = iStartTime + iPlayTime; + } + else + { + // legacy api + m_iTimeshiftPlayTime = std::time(nullptr); + } CDateTime tmp; tmp.SetFromUTCDateTime(m_iTimeshiftStartTime); @@ -551,7 +561,7 @@ int CPVRGUIInfo::TranslateIntInfo(DWORD dwInfo) const CSingleLock lock(m_critSection); if (dwInfo == PVR_EPG_EVENT_PROGRESS) - iReturn = (int) ((float) GetStartTime() / m_iDuration * 100); + iReturn = (int) ((float) GetPlayingTime() / m_iDuration * 100); else if (dwInfo == PVR_ACTUAL_STREAM_SIG_PROGR) iReturn = (int) ((float) m_qualityInfo.iSignal / 0xFFFF * 100); else if (dwInfo == PVR_ACTUAL_STREAM_SNR_PROGR) @@ -865,18 +875,18 @@ void CPVRGUIInfo::CharInfoTimeshiftPlayTime(std::string &strValue) const void CPVRGUIInfo::CharInfoEpgEventElapsedTime(std::string &strValue) const { - strValue = StringUtils::SecondsToTimeString(GetStartTime() / 1000, TIME_FORMAT_GUESS).c_str(); + strValue = StringUtils::SecondsToTimeString(GetPlayingTime() / 1000, TIME_FORMAT_GUESS).c_str(); } void CPVRGUIInfo::CharInfoEpgEventRemainingTime(std::string &strValue) const { - strValue = StringUtils::SecondsToTimeString((m_iDuration - GetStartTime()) / 1000, TIME_FORMAT_GUESS).c_str(); + strValue = StringUtils::SecondsToTimeString((m_iDuration - GetPlayingTime()) / 1000, TIME_FORMAT_GUESS).c_str(); } void CPVRGUIInfo::CharInfoEpgEventFinishTime(std::string &strValue) const { CDateTime finishTime = CDateTime::GetCurrentDateTime(); - finishTime += CDateTimeSpan(0, 0, 0, (m_iDuration - GetStartTime()) / 1000); + finishTime += CDateTimeSpan(0, 0, 0, (m_iDuration - GetPlayingTime()) / 1000); strValue = finishTime.GetAsLocalizedTime("", false); } @@ -1125,13 +1135,28 @@ void CPVRGUIInfo::UpdateNextTimer(void) int CPVRGUIInfo::GetDuration(void) const { + if (!m_bHasTimeshiftData) + { + // fetch data + const_cast<CPVRGUIInfo*>(this)->UpdateTimeshift(); + const_cast<CPVRGUIInfo*>(this)->UpdatePlayingTag(); + } + CSingleLock lock(m_critSection); return m_iDuration; } -int CPVRGUIInfo::GetStartTime(void) const +int CPVRGUIInfo::GetPlayingTime(void) const { CSingleLock lock(m_critSection); + + if (!m_bHasTimeshiftData) + { + // fetch data + const_cast<CPVRGUIInfo*>(this)->UpdateTimeshift(); + const_cast<CPVRGUIInfo*>(this)->UpdatePlayingTag(); + } + if (m_playingEpgTag || m_iTimeshiftStartTime) { /* Calculate here the position we have of the running live TV event. diff --git a/xbmc/pvr/PVRGUIInfo.h b/xbmc/pvr/PVRGUIInfo.h index 2a04e5f071..bef9ca308b 100644 --- a/xbmc/pvr/PVRGUIInfo.h +++ b/xbmc/pvr/PVRGUIInfo.h @@ -68,7 +68,7 @@ namespace PVR * @brief Get the current position in milliseconds since the start of a LiveTV item. * @return The position in milliseconds or NULL if no channel is playing. */ - int GetStartTime(void) const; + int GetPlayingTime(void) const; /*! * @brief Clear the playing EPG tag. diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 4b1ff9019e..3c34217d03 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -809,7 +809,7 @@ int CPVRManager::GetTotalTime(void) const int CPVRManager::GetStartTime(void) const { - return IsStarted() && m_guiInfo ? m_guiInfo->GetStartTime() : 0; + return IsStarted() && m_guiInfo ? m_guiInfo->GetPlayingTime() : 0; } bool CPVRManager::TranslateBoolInfo(DWORD dwInfo) const diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 8f58833c96..8be3b8cd02 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -156,6 +156,7 @@ void CAdvancedSettings::Initialize() m_DXVAForceProcessorRenderer = true; m_DXVAAllowHqScaling = true; m_videoFpsDetect = 1; + m_maxTempo = 1.55f; m_mediacodecForceSoftwareRendering = false; @@ -678,6 +679,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) XMLUtils::GetBoolean(pElement, "usedisplaycontrolhwstereo", m_useDisplayControlHWStereo); //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2); + XMLUtils::GetFloat(pElement, "maxtempo", m_maxTempo, 1.5, 2.1); // Store global display latency settings TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency"); diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index 6883023e73..900d9f8d91 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -191,6 +191,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler bool m_DXVAAllowHqScaling; int m_videoFpsDetect; bool m_mediacodecForceSoftwareRendering; + float m_maxTempo; std::string m_videoDefaultPlayer; float m_videoPlayCountMinimumPercent; diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp index f5d5e33e13..309e12a2ee 100644 --- a/xbmc/settings/SettingConditions.cpp +++ b/xbmc/settings/SettingConditions.cpp @@ -35,6 +35,7 @@ #include "cores/AudioEngine/Interfaces/AE.h" #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h" #include "guilib/LocalizeStrings.h" +#include "network/WebServer.h" #include "peripherals/Peripherals.h" #include "profiles/ProfilesManager.h" #include "pvr/PVRGUIActions.h" @@ -346,6 +347,11 @@ void CSettingConditions::Initialize() m_simpleConditions.insert("has_ae_quality_levels"); +#ifdef HAS_WEB_SERVER + if(CWebServer::WebServerSupportsSSL()) + m_simpleConditions.insert("webserver_has_ssl"); +#endif + // add complex conditions m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("addonhassettings", AddonHasSettings)); m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("checkmasterlock", CheckMasterLock)); diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index b5add4c8ef..87fd54c1b1 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -81,7 +81,6 @@ #include "SeekHandler.h" #include "utils/Variant.h" #include "view/ViewStateSettings.h" -#include "weather/WeatherManager.h" #include "ServiceBroker.h" #include "DiscSettings.h" @@ -325,6 +324,7 @@ const std::string CSettings::SETTING_SERVICES_WEBSERVER = "services.webserver"; const std::string CSettings::SETTING_SERVICES_WEBSERVERPORT = "services.webserverport"; const std::string CSettings::SETTING_SERVICES_WEBSERVERUSERNAME = "services.webserverusername"; const std::string CSettings::SETTING_SERVICES_WEBSERVERPASSWORD = "services.webserverpassword"; +const std::string CSettings::SETTING_SERVICES_WEBSERVERSSL = "services.webserverssl"; const std::string CSettings::SETTING_SERVICES_WEBSKIN = "services.webskin"; const std::string CSettings::SETTING_SERVICES_ESENABLED = "services.esenabled"; const std::string CSettings::SETTING_SERVICES_ESPORT = "services.esport"; @@ -341,7 +341,9 @@ const std::string CSettings::SETTING_SERVICES_AIRPLAYPASSWORD = "services.airpla const std::string CSettings::SETTING_SERVICES_AIRPLAYVIDEOSUPPORT = "services.airplayvideosupport"; const std::string CSettings::SETTING_SMB_WINSSERVER = "smb.winsserver"; const std::string CSettings::SETTING_SMB_WORKGROUP = "smb.workgroup"; +const std::string CSettings::SETTING_SMB_MINPROTOCOL = "smb.minprotocol"; const std::string CSettings::SETTING_SMB_MAXPROTOCOL = "smb.maxprotocol"; +const std::string CSettings::SETTING_SMB_LEGACYSECURITY = "smb.legacysecurity"; const std::string CSettings::SETTING_VIDEOSCREEN_MONITOR = "videoscreen.monitor"; const std::string CSettings::SETTING_VIDEOSCREEN_SCREEN = "videoscreen.screen"; const std::string CSettings::SETTING_VIDEOSCREEN_RESOLUTION = "videoscreen.resolution"; @@ -826,7 +828,6 @@ void CSettings::UninitializeISettingsHandlers() #if defined(TARGET_LINUX) GetSettingsManager()->UnregisterCallback(&g_timezone); #endif // defined(TARGET_LINUX) - GetSettingsManager()->UnregisterCallback(&CServiceBroker::GetWeatherManager()); #if defined(TARGET_DARWIN_OSX) GetSettingsManager()->UnregisterCallback(&XBMCHelper::GetInstance()); #endif @@ -976,6 +977,7 @@ void CSettings::InitializeISettingCallbacks() settingSet.insert(CSettings::SETTING_SERVICES_WEBSERVERPORT); settingSet.insert(CSettings::SETTING_SERVICES_WEBSERVERUSERNAME); settingSet.insert(CSettings::SETTING_SERVICES_WEBSERVERPASSWORD); + settingSet.insert(CSettings::SETTING_SERVICES_WEBSERVERSSL); settingSet.insert(CSettings::SETTING_SERVICES_ZEROCONF); settingSet.insert(CSettings::SETTING_SERVICES_AIRPLAY); settingSet.insert(CSettings::SETTING_SERVICES_AIRPLAYVOLUMECONTROL); @@ -993,7 +995,9 @@ void CSettings::InitializeISettingCallbacks() settingSet.insert(CSettings::SETTING_SERVICES_ESCONTINUOUSDELAY); settingSet.insert(CSettings::SETTING_SMB_WINSSERVER); settingSet.insert(CSettings::SETTING_SMB_WORKGROUP); + settingSet.insert(CSettings::SETTING_SMB_MINPROTOCOL); settingSet.insert(CSettings::SETTING_SMB_MAXPROTOCOL); + settingSet.insert(CSettings::SETTING_SMB_LEGACYSECURITY); GetSettingsManager()->RegisterCallback(&CNetworkServices::GetInstance(), settingSet); settingSet.clear(); @@ -1011,11 +1015,6 @@ void CSettings::InitializeISettingCallbacks() GetSettingsManager()->RegisterCallback(&g_timezone, settingSet); #endif - settingSet.clear(); - settingSet.insert(CSettings::SETTING_WEATHER_ADDON); - settingSet.insert(CSettings::SETTING_WEATHER_ADDONSETTINGS); - GetSettingsManager()->RegisterCallback(&CServiceBroker::GetWeatherManager(), settingSet); - #if defined(TARGET_DARWIN_OSX) settingSet.clear(); settingSet.insert(CSettings::SETTING_INPUT_APPLEREMOTEMODE); @@ -1073,7 +1072,6 @@ void CSettings::UninitializeISettingCallbacks() #if defined(TARGET_LINUX) GetSettingsManager()->UnregisterCallback(&g_timezone); #endif // defined(TARGET_LINUX) - GetSettingsManager()->UnregisterCallback(&CServiceBroker::GetWeatherManager()); #if defined(TARGET_DARWIN_OSX) GetSettingsManager()->UnregisterCallback(&XBMCHelper::GetInstance()); #endif diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index 6f05379cc3..26bc0991a1 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -272,6 +272,7 @@ public: static const std::string SETTING_SERVICES_WEBSERVERPORT; static const std::string SETTING_SERVICES_WEBSERVERUSERNAME; static const std::string SETTING_SERVICES_WEBSERVERPASSWORD; + static const std::string SETTING_SERVICES_WEBSERVERSSL; static const std::string SETTING_SERVICES_WEBSKIN; static const std::string SETTING_SERVICES_ESENABLED; static const std::string SETTING_SERVICES_ESPORT; @@ -288,7 +289,9 @@ public: static const std::string SETTING_SERVICES_AIRPLAYVIDEOSUPPORT; static const std::string SETTING_SMB_WINSSERVER; static const std::string SETTING_SMB_WORKGROUP; + static const std::string SETTING_SMB_MINPROTOCOL; static const std::string SETTING_SMB_MAXPROTOCOL; + static const std::string SETTING_SMB_LEGACYSECURITY; static const std::string SETTING_VIDEOSCREEN_MONITOR; static const std::string SETTING_VIDEOSCREEN_SCREEN; static const std::string SETTING_VIDEOSCREEN_RESOLUTION; diff --git a/xbmc/storage/android/AndroidStorageProvider.cpp b/xbmc/storage/android/AndroidStorageProvider.cpp index aa352ee4ff..dd6f66d5ef 100644 --- a/xbmc/storage/android/AndroidStorageProvider.cpp +++ b/xbmc/storage/android/AndroidStorageProvider.cpp @@ -182,7 +182,7 @@ void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives) break; } StringUtils::Trim(share.strName); - if (share.strName.empty() || share.strName == "?" || StringUtils::CompareNoCase(share.strName, "null") == 0) + if (share.strName.empty() || share.strName == "?" || StringUtils::EqualsNoCase(share.strName, "null")) share.strName = URIUtils::GetFileName(share.strPath); share.m_ignore = true; droidDrives.push_back(share); diff --git a/xbmc/utils/ScraperUrl.cpp b/xbmc/utils/ScraperUrl.cpp index 594d470d52..a48304b5d6 100644 --- a/xbmc/utils/ScraperUrl.cpp +++ b/xbmc/utils/ScraperUrl.cpp @@ -274,7 +274,7 @@ bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCur strHTML = converted; } } - else if (ftype == CMime::FileTypePlainText || StringUtils::CompareNoCase(mimeType.substr(0, 5), "text/") == 0) + else if (ftype == CMime::FileTypePlainText || StringUtils::EqualsNoCase(mimeType.substr(0, 5), "text/")) { std::string realTextCharset, converted; CCharsetDetection::ConvertPlainTextToUtf8(strHTML, converted, reportedCharset, realTextCharset); diff --git a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp index c244d5ec5d..028a3fbe20 100644 --- a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp +++ b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp @@ -222,6 +222,12 @@ CInfoScanner::INFO_TYPE CVideoTagLoaderFFmpeg::LoadMP4(CVideoInfoTag& tag, tag.SetPlotOutline(avtag->value); else if (strcmp(avtag->key, "synopsis") == 0) tag.SetPlot(avtag->value); + else if (strcmp(avtag->key, "track") == 0) + tag.m_iTrack = std::stoi(avtag->value); + else if (strcmp(avtag->key, "album") == 0) + tag.SetAlbum(avtag->value); + else if (strcmp(avtag->key, "artist") == 0) + tag.SetArtist(StringUtils::Split(avtag->value, " / ")); } for (size_t i = 0; i < m_fctx->nb_streams; ++i) diff --git a/xbmc/weather/WeatherManager.cpp b/xbmc/weather/WeatherManager.cpp index 7261d5a4b9..91a7b4ea5f 100644 --- a/xbmc/weather/WeatherManager.cpp +++ b/xbmc/weather/WeatherManager.cpp @@ -27,6 +27,7 @@ #include "LangInfo.h" #include "ServiceBroker.h" #include "settings/lib/Setting.h" +#include "settings/lib/SettingsManager.h" #include "settings/Settings.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" @@ -38,10 +39,18 @@ using namespace ADDON; CWeatherManager::CWeatherManager(void) : CInfoLoader(30 * 60 * 1000) // 30 minutes { + CServiceBroker::GetSettings().GetSettingsManager()->RegisterCallback(this, { + CSettings::SETTING_WEATHER_ADDON, + CSettings::SETTING_WEATHER_ADDONSETTINGS + }); + Reset(); } -CWeatherManager::~CWeatherManager(void) = default; +CWeatherManager::~CWeatherManager(void) +{ + CServiceBroker::GetSettings().GetSettingsManager()->UnregisterCallback(this); +} std::string CWeatherManager::BusyInfo(int info) const { diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp index 44d5a84b8a..b56555fa2b 100644 --- a/xbmc/windows/GUIMediaWindow.cpp +++ b/xbmc/windows/GUIMediaWindow.cpp @@ -1408,7 +1408,7 @@ bool CGUIMediaWindow::OnPlayMedia(int iItem, const std::string &player) if (pItem->IsInternetStream() || pItem->IsPlayList()) bResult = g_application.PlayMedia(*pItem, player, m_guiState->GetPlaylist()); else - bResult = g_application.PlayFile(*pItem, player) == PLAYBACK_OK; + bResult = g_application.PlayFile(*pItem, player); if (pItem->m_lStartOffset == STARTOFFSET_RESUME) pItem->m_lStartOffset = 0; |