diff options
45 files changed, 1140 insertions, 613 deletions
diff --git a/addons/screensaver.xbmc.builtin.dim/addon.xml b/addons/screensaver.xbmc.builtin.dim/addon.xml index 97b4b2c053..fd93c8975f 100644 --- a/addons/screensaver.xbmc.builtin.dim/addon.xml +++ b/addons/screensaver.xbmc.builtin.dim/addon.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <addon id="screensaver.xbmc.builtin.dim" name="Dim" - version="1.0.43" + version="1.0.44" provider-name="Team Kodi"> <extension point="xbmc.ui.screensaver" library=""/> <extension point="xbmc.addon.metadata"> diff --git a/addons/skin.estouchy/addon.xml b/addons/skin.estouchy/addon.xml index 9ebb2c7bf0..9a3ee31a1c 100644 --- a/addons/skin.estouchy/addon.xml +++ b/addons/skin.estouchy/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="skin.estouchy" version="2.0.15" name="Estouchy" provider-name="Team Kodi"> +<addon id="skin.estouchy" version="2.0.16" name="Estouchy" provider-name="Team Kodi"> <requires> <import addon="xbmc.gui" version="5.13.0"/> </requires> @@ -14,6 +14,7 @@ <summary lang="bg_BG">Облик за устройства със сензорен екран</summary> <summary lang="ca_ES">Aparença per als dispositius amb pantalla tàctil</summary> <summary lang="cs_CZ">Vzhled pro zařízení s dotykovou obrazovkou</summary> + <summary lang="da_DK">Skin for touchscreen enheder</summary> <summary lang="de_DE">Skin für Touchscreen-Geräte</summary> <summary lang="el_GR">Κέλυφος για συσκευές με οθόνη αφής</summary> <summary lang="en_GB">Skin for touchscreen devices</summary> @@ -58,6 +59,7 @@ <description lang="bg_BG">Обликът е разработен за ползване на устройства със сензорен екран, като таблети и телефони.</description> <description lang="ca_ES">Aparença dissenyada perquè s'utilitzi en dispositius amb pantalla tàctil com taules i telèfons intel·ligents</description> <description lang="cs_CZ">Vzhled navržený pro použití na zařízeních s dotykovou obrazovkou, jako jsou tablety a chytré telefony</description> + <description lang="da_DK">Skins som er designet til brug på touchscreen enheder som tablets og smartphones</description> <description lang="de_DE">Dieses Skin wurde für die Benutzung mit Touchscreen-Geräten wie Tablets und Handys entworfen</description> <description lang="el_GR">Κέλυφος σχεδιασμένο για να χρησιμοποιηθεί σε συσκευές με οθόνη αφής όπως ταμπλέτες και έξυπνα κινητά.</description> <description lang="en_GB">Skin designed to be used on touchscreen devices like tablets and smartphones</description> diff --git a/addons/skin.estouchy/language/resource.language.da_dk/strings.po b/addons/skin.estouchy/language/resource.language.da_dk/strings.po index 4b9446996a..f89b2f986a 100644 --- a/addons/skin.estouchy/language/resource.language.da_dk/strings.po +++ b/addons/skin.estouchy/language/resource.language.da_dk/strings.po @@ -44,6 +44,10 @@ msgctxt "#31009" msgid "Working..." msgstr "Arbejder..." +msgctxt "#31011" +msgid "Recent" +msgstr "Nyligt" + msgctxt "#31013" msgid "Movies" msgstr "Film" @@ -64,6 +68,10 @@ msgctxt "#31018" msgid "Player process info" msgstr "Procesinformation for afspilning" +msgctxt "#31019" +msgid "Video decoder" +msgstr "Videodekoder" + msgctxt "#31020" msgid "Pixel format" msgstr "Pixelformat" @@ -227,3 +235,11 @@ msgstr "Omdøb Gruppe" msgctxt "#31563" msgid "Delete Group" msgstr "Slet Gruppe" + +msgctxt "#31564" +msgid "Show hidden" +msgstr "Vis skjulte" + +msgctxt "#31565" +msgid "Show deleted" +msgstr "Vis slettede" diff --git a/addons/skin.estuary/addon.xml b/addons/skin.estuary/addon.xml index d01576929f..4444aa9272 100644 --- a/addons/skin.estuary/addon.xml +++ b/addons/skin.estuary/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="skin.estuary" version="2.0.11" name="Estuary" provider-name="phil65, Ichabod Fletchman"> +<addon id="skin.estuary" version="2.0.12" name="Estuary" provider-name="phil65, Ichabod Fletchman"> <requires> <import addon="xbmc.gui" version="5.13.0"/> </requires> diff --git a/addons/skin.estuary/language/resource.language.af_za/strings.po b/addons/skin.estuary/language/resource.language.af_za/strings.po index 4f24955033..c7ca6c0220 100644 --- a/addons/skin.estuary/language/resource.language.af_za/strings.po +++ b/addons/skin.estuary/language/resource.language.af_za/strings.po @@ -48,6 +48,10 @@ msgctxt "#31007" msgid "Unwatched movies" msgstr "Ongekykte flieks" +msgctxt "#31008" +msgid "Enable category widgets" +msgstr "Stel kategorie widget in staat" + msgctxt "#31009" msgid "Download icons" msgstr "Aflaai ikone" @@ -108,6 +112,10 @@ msgctxt "#31023" msgid "Viewtype" msgstr "Aansigtipe" +msgctxt "#31024" +msgid "Choose rating to display for media items" +msgstr "Kies gradering om vir media items te vertoon" + msgctxt "#31025" msgid "No favourites found. You can add any item from media views to this list by using the context menu." msgstr "Geen gunstelinge gevind. Jy kan enige item vanaf media aansigte byvoeg by hierdie lys deur die konteks kieslys te gebruik." @@ -436,6 +444,14 @@ msgctxt "#31131" msgid "Choose skin fanart pack" msgstr "Kies oortreksel ondersteunerkuns pak" +msgctxt "#31132" +msgid "Select Program" +msgstr "Selekteer program" + +msgctxt "#31133" +msgid "Select Resolution" +msgstr "Selekteer resolusie" + msgctxt "#31134" msgid "Remaining" msgstr "Oorblywend" @@ -536,6 +552,22 @@ msgctxt "#31161" msgid "Numeric pad" msgstr "Nommer blok" +msgctxt "#31162" +msgid "Play your personal games or download one of the many game add-ons from the official repository." +msgstr "Speel jou persoonlike speletjies of laai een van die baie speletjie byvoegsels af vanaf die offisiële stoorplek." + +msgctxt "#31163" +msgid "Show Fanart background" +msgstr "Wys Ondersteunerkuns agtergrond" + +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Kies tipe profiel identifikasie" + msgctxt "#31165" msgid "Profile name" msgstr "Profiel naam" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Profiel avatar" diff --git a/addons/skin.estuary/language/resource.language.cs_cz/strings.po b/addons/skin.estuary/language/resource.language.cs_cz/strings.po index d3429ac68d..7748b76d2a 100644 --- a/addons/skin.estuary/language/resource.language.cs_cz/strings.po +++ b/addons/skin.estuary/language/resource.language.cs_cz/strings.po @@ -458,7 +458,7 @@ msgstr "Zbývá" msgctxt "#31136" msgid "Click here to see latest changes..." -msgstr "Klikněte sem pro zobrazení posledních změn..." +msgstr "Klikněte sem pro zobrazení posledních změn…" msgctxt "#31137" msgid "PVR info" diff --git a/addons/skin.estuary/language/resource.language.da_dk/strings.po b/addons/skin.estuary/language/resource.language.da_dk/strings.po index 44769fac00..b92456773a 100644 --- a/addons/skin.estuary/language/resource.language.da_dk/strings.po +++ b/addons/skin.estuary/language/resource.language.da_dk/strings.po @@ -148,6 +148,18 @@ msgctxt "#31033" msgid "Your rating" msgstr "Din vurdering" +msgctxt "#31034" +msgid "Extended info" +msgstr "Udvidet info" + +msgctxt "#31035" +msgid "Pages" +msgstr "Sider" + +msgctxt "#31036" +msgid "items" +msgstr "emner" + msgctxt "#31038" msgid "Rewind" msgstr "Spol Tilbage" @@ -156,6 +168,10 @@ msgctxt "#31039" msgid "Fast forward" msgstr "Spol Frem" +msgctxt "#31041" +msgid "Camera manufacturer" +msgstr "Kameraproducent" + msgctxt "#31042" msgid "Playlist options" msgstr "Playlisteindstillinger" @@ -188,10 +204,22 @@ msgctxt "#31056" msgid "Go to playlist" msgstr "Gå til playliste" +msgctxt "#31057" +msgid "Show login screen on startup" +msgstr "Vis login under opstart" + msgctxt "#31058" msgid "Automatic Login on startup" msgstr "Automatisk login ved opstart" +msgctxt "#31061" +msgid "Main menu items" +msgstr "Hovedmenu emner" + +msgctxt "#31062" +msgid "Choose weather fanart pack" +msgstr "Vælg vejr fanart pakke" + msgctxt "#31063" msgid "Sections" msgstr "Sektioner" @@ -220,10 +248,26 @@ msgctxt "#31072" msgid "Power Options" msgstr "Strømstyring" +msgctxt "#31075" +msgid "Movie sets" +msgstr "Filmsæt" + +msgctxt "#31080" +msgid "Ends at" +msgstr "Slutter" + msgctxt "#31082" msgid "Lyrics add-on" msgstr "Add-on til Sangtekster" +msgctxt "#31083" +msgid "Lyrics add-on settings" +msgstr "Indstillinger for sangtekst" + +msgctxt "#31084" +msgid "Visualisation settings" +msgstr "Visualisering indstillinger" + msgctxt "#31089" msgid "Available groups" msgstr "Tilgængelig grupper" @@ -276,6 +320,10 @@ msgctxt "#31106" msgid "Teletext" msgstr "Tekst-tv" +msgctxt "#31112" +msgid "Toggle audio stream" +msgstr "Lydspor" + msgctxt "#31113" msgid "Search local library" msgstr "Søg i lokalt bibliotek" @@ -332,6 +380,10 @@ msgctxt "#31134" msgid "Remaining" msgstr "Tilbage" +msgctxt "#31136" +msgid "Click here to see latest changes..." +msgstr "Klik for at se seneste ændringer..." + msgctxt "#31137" msgid "PVR info" msgstr "PVR-information" @@ -340,6 +392,10 @@ msgctxt "#31138" msgid "Player process info" msgstr "Procesinformation for afspilning" +msgctxt "#31139" +msgid "Video decoder" +msgstr "Videodekoder" + msgctxt "#31140" msgid "Pixel format" msgstr "Pixelformat" @@ -364,6 +420,10 @@ msgctxt "#31149" msgid "Select genre fanart pack" msgstr "Vælg fankunst genrepakke" +msgctxt "#31150" +msgid "Repository" +msgstr "Fjernlager" + msgctxt "#31151" msgid "Unwatched music videos" msgstr "Usete musikvideoer" @@ -392,6 +452,10 @@ msgctxt "#31158" msgid "Touch mode" msgstr "Touchtilstand" +msgctxt "#31159" +msgid "Artwork" +msgstr "Grafik" + msgctxt "#31160" msgid "Show media flags" msgstr "Vis medieflag" @@ -400,6 +464,14 @@ msgctxt "#31161" msgid "Numeric pad" msgstr "Numerisk tastetur" +msgctxt "#31163" +msgid "Show Fanart background" +msgstr "Vis fanart baggrund" + msgctxt "#31165" msgid "Profile name" msgstr "Profilnavn" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Profilavatar" diff --git a/addons/skin.estuary/language/resource.language.is_is/strings.po b/addons/skin.estuary/language/resource.language.is_is/strings.po index b905477ea3..cd076c4b7a 100644 --- a/addons/skin.estuary/language/resource.language.is_is/strings.po +++ b/addons/skin.estuary/language/resource.language.is_is/strings.po @@ -448,6 +448,10 @@ msgctxt "#31132" msgid "Select Program" msgstr "Veldu forrit" +msgctxt "#31133" +msgid "Select Resolution" +msgstr "Veldu upplausn" + msgctxt "#31134" msgid "Remaining" msgstr "Eftir" diff --git a/addons/skin.estuary/language/resource.language.it_it/strings.po b/addons/skin.estuary/language/resource.language.it_it/strings.po index 90ca5d86f1..e3cb7ace1e 100644 --- a/addons/skin.estuary/language/resource.language.it_it/strings.po +++ b/addons/skin.estuary/language/resource.language.it_it/strings.po @@ -556,6 +556,10 @@ msgctxt "#31163" msgid "Show Fanart background" msgstr "Mostra sfondo Fanart" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Scegli il tipo di indentificazione del profilo" + msgctxt "#31165" msgid "Profile name" msgstr "Nome profilo" diff --git a/addons/skin.estuary/language/resource.language.ms_my/strings.po b/addons/skin.estuary/language/resource.language.ms_my/strings.po index e9cc7ba6f2..beec68369a 100644 --- a/addons/skin.estuary/language/resource.language.ms_my/strings.po +++ b/addons/skin.estuary/language/resource.language.ms_my/strings.po @@ -560,6 +560,14 @@ msgctxt "#31163" msgid "Show Fanart background" msgstr "Menunjuk latar balakang seni peminat" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Pilih jenis pengenalpastian profil" + msgctxt "#31165" msgid "Profile name" msgstr "Nama profil" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Avatar profil" diff --git a/addons/skin.estuary/language/resource.language.nl_nl/strings.po b/addons/skin.estuary/language/resource.language.nl_nl/strings.po index c2bc2690e8..8bda468b58 100644 --- a/addons/skin.estuary/language/resource.language.nl_nl/strings.po +++ b/addons/skin.estuary/language/resource.language.nl_nl/strings.po @@ -448,6 +448,10 @@ msgctxt "#31132" msgid "Select Program" msgstr "Selecteer programma" +msgctxt "#31133" +msgid "Select Resolution" +msgstr "Kies resolutie" + msgctxt "#31134" msgid "Remaining" msgstr "Resterend" @@ -556,6 +560,14 @@ msgctxt "#31163" msgid "Show Fanart background" msgstr "Toon fanartachtergrond" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Kies het type profielidentificatie" + msgctxt "#31165" msgid "Profile name" msgstr "Profielnaam" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Profielafbeelding" diff --git a/addons/skin.estuary/language/resource.language.pt_br/strings.po b/addons/skin.estuary/language/resource.language.pt_br/strings.po index 4db8910427..5789213118 100644 --- a/addons/skin.estuary/language/resource.language.pt_br/strings.po +++ b/addons/skin.estuary/language/resource.language.pt_br/strings.po @@ -510,11 +510,11 @@ msgstr "Repositório" msgctxt "#31151" msgid "Unwatched music videos" -msgstr "Concertos por assistir" +msgstr "Videoclipes a assistir" msgctxt "#31152" msgid "Random music videos" -msgstr "Concertos randômicos" +msgstr "Videoclipes aleatórios" msgctxt "#31153" msgid "You do not have any add-ons of this type installed. Enter the add-on browser to download add-ons created by our community." diff --git a/addons/skin.estuary/language/resource.language.sv_se/strings.po b/addons/skin.estuary/language/resource.language.sv_se/strings.po index de4fecdbba..6cf645fa36 100644 --- a/addons/skin.estuary/language/resource.language.sv_se/strings.po +++ b/addons/skin.estuary/language/resource.language.sv_se/strings.po @@ -560,6 +560,14 @@ msgctxt "#31163" msgid "Show Fanart background" msgstr "Visa Fanart-bakgrund" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "Välj typ av profilidentifiering" + msgctxt "#31165" msgid "Profile name" msgstr "Profilnamn" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "Profil avatar" diff --git a/addons/skin.estuary/language/resource.language.zh_cn/strings.po b/addons/skin.estuary/language/resource.language.zh_cn/strings.po index c8f05d9d73..cbded7a926 100644 --- a/addons/skin.estuary/language/resource.language.zh_cn/strings.po +++ b/addons/skin.estuary/language/resource.language.zh_cn/strings.po @@ -448,6 +448,10 @@ msgctxt "#31132" msgid "Select Program" msgstr "选择程序" +msgctxt "#31133" +msgid "Select Resolution" +msgstr "选择分辨率" + msgctxt "#31134" msgid "Remaining" msgstr "剩余" @@ -556,6 +560,14 @@ msgctxt "#31163" msgid "Show Fanart background" msgstr "显示同人画背景" +msgctxt "#31164" +msgid "Choose kind of profile identification" +msgstr "选择个人配置标识种类" + msgctxt "#31165" msgid "Profile name" msgstr "用户配置名称" + +msgctxt "#31166" +msgid "Profile avatar" +msgstr "用户配置头像" diff --git a/addons/skin.estuary/xml/DialogPlayerProcessInfo.xml b/addons/skin.estuary/xml/DialogPlayerProcessInfo.xml index 53c4567c60..5dbbaf8361 100644 --- a/addons/skin.estuary/xml/DialogPlayerProcessInfo.xml +++ b/addons/skin.estuary/xml/DialogPlayerProcessInfo.xml @@ -8,7 +8,7 @@ <control type="group"> <bottom>0</bottom> <height>250</height> - <animation effect="slide" end="0,-80" time="150" condition="PVR.IsTimeShift">conditional</animation> + <animation effect="slide" end="0,-20" time="150" condition="VideoPlayer.Content(LiveTV)">conditional</animation> <control type="image"> <left>10</left> <top>-240</top> diff --git a/addons/skin.estuary/xml/DialogSeekBar.xml b/addons/skin.estuary/xml/DialogSeekBar.xml index a307f28ce0..b4b4d6de91 100644 --- a/addons/skin.estuary/xml/DialogSeekBar.xml +++ b/addons/skin.estuary/xml/DialogSeekBar.xml @@ -143,107 +143,83 @@ <label>$VAR[SeekLabel]</label> <shadowcolor>black</shadowcolor> </control> - <control type="group" id="6000"> - <top>-5</top> - <visible>PVR.IsTimeShift + !Player.ChannelPreviewActive</visible> - <animation effect="fade" time="300">VisibleChange</animation> - <control type="label"> - <top>0</top> - <right>20</right> - <width>400</width> - <height>50</height> - <align>right</align> - <aligny>center</aligny> - <font>font30</font> - <label>$INFO[PVR.TimeShiftEnd]</label> + <control type="group"> + <visible>VideoPlayer.Content(LiveTV)</visible> + <control type="group"> + <visible>Player.SeekEnabled + VideoPlayer.HasEPG</visible> + <include content="PVRProgress"> + <param name="ts_bar_top" value="70"/> + <param name="epg_bar_top" value="78"/> + <param name="ts_bar_height" value="8"/> + <param name="epg_bar_height" value="8"/> + </include> </control> - <control type="label"> - <top>0</top> - <left>20</left> - <width>400</width> - <height>50</height> - <align>left</align> - <aligny>center</aligny> - <font>font30</font> - <label>$INFO[PVR.TimeShiftStart]</label> + <control type="group"> + <visible>Player.SeekEnabled + !VideoPlayer.HasEPG</visible> + <include content="PVRProgress"> + <param name="ts_bar_top" value="70"/> + <param name="ts_bar_height" value="16"/> + </include> </control> - <control type="label"> - <top>0</top> - <left>20</left> - <right>20</right> - <height>50</height> - <align>center</align> - <aligny>center</aligny> - <font>font30</font> - <label>[B]$LOCALIZE[31026][/B] $INFO[PVR.TimeshiftCur] (-$INFO[PVR.TimeshiftOffset])</label> + <control type="group"> + <visible>!Player.SeekEnabled + VideoPlayer.HasEPG</visible> + <include content="PVRProgress"> + <param name="epg_bar_top" value="70"/> + <param name="epg_bar_height" value="16"/> + </include> + </control> + <control type="group"> + <visible>!Player.SeekEnabled + !VideoPlayer.HasEPG</visible> + <include content="PVRProgress"/> + </control> + <control type="slider" id="403"> + <left>0</left> + <top>65</top> + <width>100%</width> + <height>26</height> + <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> + <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> + <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> + <visible>Player.SeekEnabled + !Player.ChannelPreviewActive</visible> </control> + </control> + <control type="group"> + <visible>!VideoPlayer.Content(LiveTV)</visible> <control type="progress"> <left>0</left> - <top>50</top> + <top>70</top> <width>100%</width> - <height>15</height> - <info>PVR.timeshiftprogress</info> - <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> + <height>16</height> + <info>Player.ProgressCache</info> + <texturebg border="3" colordiffuse="00FFFFFF">colors/white50.png</texturebg> <midtexture>colors/white50.png</midtexture> - <visible>VideoPlayer.Content(livetv)</visible> </control> - </control> - <control type="progress"> - <left>0</left> - <top>70</top> - <width>100%</width> - <height>15</height> - <info>PVR.EpgEventProgress</info> - <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> - <midtexture colordiffuse="button_focus">colors/white.png</midtexture> - <visible>VideoPlayer.HasEpg</visible> - </control> - <control type="progress"> - <left>0</left> - <top>70</top> - <width>100%</width> - <height>15</height> - <info>Player.ProgressCache</info> - <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> - <midtexture>colors/white50.png</midtexture> - <visible>!VideoPlayer.Content(livetv)</visible> - </control> - <control type="progress"> - <left>0</left> - <top>70</top> - <width>100%</width> - <height>15</height> - <info>Player.Progress</info> - <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> - <midtexture colordiffuse="button_focus">colors/white.png</midtexture> - <visible>!VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> - </control> - <control type="slider" id="401"> - <left>5</left> - <top>65</top> - <width>100%</width> - <height>25</height> - <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> - <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> - <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> - <visible>Player.SeekEnabled + !VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> - </control> - <control type="slider" id="402"> - <left>5</left> - <top>65</top> - <width>100%</width> - <height>25</height> - <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> - <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> - <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> - <visible>Player.SeekEnabled + VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> + <control type="progress"> + <left>0</left> + <top>70</top> + <width>100%</width> + <height>16</height> + <info>Player.Progress</info> + <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> + <midtexture colordiffuse="button_focus">colors/white.png</midtexture> + </control> + <control type="slider" id="401"> + <left>0</left> + <top>65</top> + <width>100%</width> + <height>26</height> + <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> + <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> + <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> + <visible>Player.SeekEnabled</visible> + </control> </control> </control> <control type="group"> <visible>!Window.IsVisible(playerprocessinfo)</visible> <visible>Player.ShowInfo + VideoPlayer.Content(LiveTV)</visible> <animation effect="fade" time="400">VisibleChange</animation> - <animation effect="slide" end="0,-80" time="150" condition="Control.IsVisible(6000)">conditional</animation> + <animation effect="slide" end="0,-20" time="150" condition="VideoPlayer.Content(LiveTV)">conditional</animation> <bottom>0</bottom> <height>380</height> <control type="label"> @@ -295,7 +271,6 @@ <visible>Player.ShowInfo + !VideoPlayer.Content(LiveTV) + Window.IsActive(fullscreenvideo)</visible> <animation effect="fade" time="200">VisibleChange</animation> <control type="group"> - <animation effect="slide" end="0,-80" time="150" condition="PVR.IsTimeShift">conditional</animation> <control type="image"> <depth>DepthOSD+</depth> <left>10</left> diff --git a/addons/skin.estuary/xml/Includes_PVR.xml b/addons/skin.estuary/xml/Includes_PVR.xml index 938eb63dad..8ec061bee3 100644 --- a/addons/skin.estuary/xml/Includes_PVR.xml +++ b/addons/skin.estuary/xml/Includes_PVR.xml @@ -101,6 +101,93 @@ <orientation>vertical</orientation> </control> </include> + <include name="PVRProgress"> + <control type="group"> + <animation effect="fade" time="400">VisibleChange</animation> + <visible>!Player.ChannelPreviewActive</visible> + <control type="group"> + <visible>Player.SeekEnabled | VideoPlayer.HasEPG</visible> + <control type="label"> + <top>22</top> + <right>20</right> + <width>400</width> + <height>50</height> + <align>right</align> + <aligny>center</aligny> + <font>font30</font> + <label>$INFO[PVR.TimeshiftProgressEndTime]</label> + </control> + <control type="label"> + <top>22</top> + <left>20</left> + <width>400</width> + <height>50</height> + <align>left</align> + <aligny>center</aligny> + <font>font30</font> + <label>$INFO[PVR.TimeshiftProgressStartTime]</label> + </control> + <control type="label"> + <top>22</top> + <left>20</left> + <right>20</right> + <height>50</height> + <align>center</align> + <aligny>center</aligny> + <font>font30</font> + <label>[B]$LOCALIZE[31026][/B] $INFO[PVR.TimeshiftCur] (-$INFO[PVR.TimeshiftOffset])</label> + <visible>PVR.IsTimeShift</visible> + </control> + </control> + <control type="group"> + <visible>VideoPlayer.HasEPG</visible> + <control type="progress"> + <left>0</left> + <top>$PARAM[epg_bar_top]</top> + <width>100%</width> + <height>$PARAM[epg_bar_height]</height> + <info2>PVR.TimeshiftProgressEpgStart</info2> + <info>PVR.TimeshiftProgressPlayPos</info> + <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> + <midtexture colordiffuse="button_focus">colors/white.png</midtexture> + </control> + <control type="progress"> + <left>0</left> + <top>$PARAM[epg_bar_top]</top> + <width>100%</width> + <height>$PARAM[epg_bar_height]</height> + <info2>PVR.TimeshiftProgressPlayPos</info2> + <info>PVR.TimeshiftProgressEpgEnd</info> + <texturebg border="3" colordiffuse="00FFFFFF">colors/white50.png</texturebg> + <midtexture>colors/white50.png</midtexture> + </control> + </control> + <control type="progress"> + <left>0</left> + <top>$PARAM[ts_bar_top]</top> + <width>100%</width> + <height>$PARAM[ts_bar_height]</height> + <info2>PVR.TimeshiftProgressBufferStart</info2> + <info>PVR.TimeshiftProgressBufferEnd</info> + <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> + <midtexture>colors/white70.png</midtexture> + <visible>Player.SeekEnabled</visible> + </control> + </control> + <control type="group"> + <animation effect="fade" time="400">VisibleChange</animation> + <visible>Player.ChannelPreviewActive</visible> + <control type="progress"> + <left>0</left> + <top>70</top> + <width>100%</width> + <height>16</height> + <info>PVR.EpgEventProgress</info> + <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> + <midtexture colordiffuse="button_focus">colors/white.png</midtexture> + </control> + </control> + </include> <include name="PVRInfoPanel"> <control type="group"> <visible>!ListItem.IsFolder</visible> diff --git a/addons/skin.estuary/xml/MusicOSD.xml b/addons/skin.estuary/xml/MusicOSD.xml index 0ce7dc5025..6097c0729b 100644 --- a/addons/skin.estuary/xml/MusicOSD.xml +++ b/addons/skin.estuary/xml/MusicOSD.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <window> + <onload condition="!Player.PauseEnabled">SetFocus(603)</onload> <defaultcontrol always="true">602</defaultcontrol> <depth>DepthOSD</depth> <controls> @@ -62,6 +63,7 @@ <radioposy>0</radioposy> <selected>Player.Paused</selected> <onclick>PlayerControl(Play)</onclick> + <visible>Player.PauseEnabled</visible> </control> <control type="radiobutton" id="603"> <include content="OSDButton"> @@ -183,13 +185,13 @@ </control> </control> <control type="label"> - <right>30</right> + <animation effect="slide" end="0,-20" time="150" condition="MusicPlayer.Content(LiveTV)">conditional</animation> + <right>20</right> <top>-60</top> - <textoffsetx>20</textoffsetx> <aligny>center</aligny> <align>right</align> - <width>1858</width> - <height>60</height> + <width>1000</width> + <height>50</height> <label>$VAR[MusicOSDHelpTextVar]</label> </control> </control> @@ -213,55 +215,55 @@ <left>0</left> <top>-5</top> <width>100%</width> - <height>25</height> + <height>26</height> <onup>8010</onup> <ondown>650</ondown> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib>osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> <info>Player.Progress</info> - <visible>Player.SeekEnabled + !Control.HasFocus(87) + !VideoPlayer.HasEpg</visible> + <visible>Player.SeekEnabled + !Control.HasFocus(87) + !MusicPlayer.Content(LiveTV)</visible> <action>seek</action> </control> <control type="slider"> <left>0</left> <top>-5</top> <width>100%</width> - <height>25</height> + <height>26</height> <onup>8010</onup> <ondown>650</ondown> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> <info>Player.Progress</info> - <visible>Player.SeekEnabled + Control.HasFocus(87) + !VideoPlayer.HasEpg</visible> + <visible>Player.SeekEnabled + Control.HasFocus(87) + !MusicPlayer.Content(LiveTV)</visible> <action>seek</action> </control> <control type="slider"> <left>0</left> <top>-5</top> <width>100%</width> - <height>25</height> + <height>26</height> <onup>8010</onup> <ondown>650</ondown> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib>osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> - <info>PVR.EpgEventProgress</info> - <visible>Player.SeekEnabled + !Control.HasFocus(87) + VideoPlayer.HasEpg</visible> + <info>PVR.TimeshiftProgressPlayPos</info> + <visible>Player.SeekEnabled + !Control.HasFocus(87) + MusicPlayer.Content(LiveTV)</visible> </control> <control type="slider"> <left>0</left> <top>-5</top> <width>100%</width> - <height>25</height> + <height>26</height> <onup>8010</onup> <ondown>650</ondown> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> - <info>PVR.EpgEventProgress</info> - <visible>Player.SeekEnabled + Control.HasFocus(87) + VideoPlayer.HasEpg</visible> + <info>PVR.TimeshiftProgressPlayPos</info> + <visible>Player.SeekEnabled + Control.HasFocus(87) + MusicPlayer.Content(LiveTV)</visible> </control> </control> </controls> diff --git a/addons/skin.estuary/xml/VideoOSD.xml b/addons/skin.estuary/xml/VideoOSD.xml index 7c33235890..5aeaff5bb9 100644 --- a/addons/skin.estuary/xml/VideoOSD.xml +++ b/addons/skin.estuary/xml/VideoOSD.xml @@ -21,15 +21,15 @@ <visible>![Window.IsVisible(SliderDialog) | Window.IsVisible(osdaudiosettings) | Window.IsVisible(osdvideosettings) | Window.IsVisible(VideoBookmarks) | Window.IsVisible(playerprocessinfo) | Window.IsVisible(osdcmssettings) | Window.IsVisible(PVROSDChannels) | Window.IsVisible(pvrchannelguide)]</visible> <animation effect="fade" time="200">VisibleChange</animation> <control type="label"> - <right>30</right> + <animation effect="slide" end="0,-20" time="150" condition="VideoPlayer.Content(LiveTV)">conditional</animation> + <right>20</right> <top>0</top> <align>right</align> - <textoffsetx>20</textoffsetx> <aligny>center</aligny> <width>1000</width> - <height>60</height> + <height>50</height> <label>$VAR[VideoOSDHelpTextVar]</label> - <visible>!Player.ShowInfo + !PVR.IsTimeShift</visible> + <visible>!Player.ShowInfo</visible> </control> <control type="group" id="200"> <control type="grouplist" id="201"> @@ -49,7 +49,7 @@ <param name="texture" value="osd/fullscreen/buttons/previous.png"/> </include> <onclick>PlayerControl(Previous)</onclick> - <visible>!VideoPlayer.Content(livetv)</visible> + <visible>!VideoPlayer.Content(livetv) + [Player.ChapterCount | Integer.IsGreater(Playlist.Length(video),1) | Player.SeekEnabled]</visible> </control> <control type="radiobutton" id="602"> <textureradioonfocus colordiffuse="white">osd/fullscreen/buttons/play.png</textureradioonfocus> @@ -140,7 +140,7 @@ </include> <onclick>Dialog.Close(VideoOSD)</onclick> <onclick>ActivateWindow(pvrchannelguide)</onclick> - <visible>VideoPlayer.Content(livetv)</visible> + <visible>VideoPlayer.Content(livetv) + VideoPlayer.HasEPG</visible> </control> <control type="radiobutton" id="700"> <include content="OSDButton"> @@ -199,47 +199,47 @@ <top>-5</top> <left>0</left> <width>100%</width> - <height>25</height> + <height>26</height> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib>osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> <info>Player.Progress</info> <action>seek</action> - <visible>!Control.HasFocus(87) + !VideoPlayer.HasEpg</visible> + <visible>!Control.HasFocus(87) + !VideoPlayer.Content(LiveTV)</visible> </control> <control type="slider"> <top>-5</top> <left>0</left> <width>100%</width> - <height>25</height> + <height>26</height> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> <info>Player.Progress</info> <action>seek</action> - <visible>Control.HasFocus(87) + !VideoPlayer.HasEpg</visible> + <visible>Control.HasFocus(87) + !VideoPlayer.Content(LiveTV)</visible> </control> <control type="slider"> <top>-5</top> <left>0</left> <width>100%</width> - <height>25</height> + <height>26</height> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib>osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> - <info>PVR.EpgEventProgress</info> - <visible>!Control.HasFocus(87) + VideoPlayer.HasEpg</visible> + <info>PVR.TimeshiftProgressPlayPos</info> + <visible>!Control.HasFocus(87) + VideoPlayer.Content(LiveTV)</visible> </control> <control type="slider"> <top>-5</top> <left>0</left> <width>100%</width> - <height>25</height> + <height>26</height> <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_leftright.png</texturesliderbar> <textureslidernib colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">osd/progress/nub_leftright.png</textureslidernibfocus> - <info>PVR.EpgEventProgress</info> - <visible>Control.HasFocus(87) + VideoPlayer.HasEpg</visible> + <info>PVR.TimeshiftProgressPlayPos</info> + <visible>Control.HasFocus(87) + VideoPlayer.Content(LiveTV)</visible> </control> </control> </control> diff --git a/system/settings/darwin_ios.xml b/system/settings/darwin_ios.xml index 329a9c9a5f..d86a3122a7 100644 --- a/system/settings/darwin_ios.xml +++ b/system/settings/darwin_ios.xml @@ -22,6 +22,9 @@ <section id="system"> <category id="display"> <group id="1"> + <setting id="videoscreen.resolution"> + <default>17</default> <!-- RES_CUSTOM --> + </setting> <setting id="videoscreen.fakefullscreen"> <visible>false</visible> </setting> diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index df477d7325..f39a94e967 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -3177,7 +3177,9 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes else options.fullscreen = g_advancedSettings.m_fullScreenOnMovieStart && !CMediaSettings::GetInstance().DoesVideoStartWindowed(); - options.preferStereo = CServiceBroker::GetActiveAE()->HasStereoAudioChannelCount(); + // stereo streams may have lower quality, i.e. 32bit vs 16 bit + options.preferStereo = g_advancedSettings.m_videoPreferStereoStream && + CServiceBroker::GetActiveAE()->HasStereoAudioChannelCount(); // reset VideoStartWindowed as it's a temp setting CMediaSettings::GetInstance().SetVideoStartWindowed(false); diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index 381082a4d3..95677356a7 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -4558,6 +4558,31 @@ const infomap playlist[] = {{ "length", PLAYLIST_LENGTH }, /// _boolean_, /// Returns true if PVR is currently playing a channel and if this channel is currently recorded. /// } +/// \table_row3{ <b>`PVR.TimeshiftProgressPlayPos`</b>, +/// \anchor PVR_TimeshiftProgressPlayPos +/// _integer_, +/// Returns the percentage of the current play position within the PVR timeshift progress. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEpgStart`</b>, +/// \anchor PVR_TimeshiftProgressEpgStart +/// _integer_, +/// Returns the percentage of the start of the currently playing epg event within the PVR timeshift progress. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEpgEnd`</b>, +/// \anchor PVR_TimeshiftProgressEpgEnd +/// _integer_, +/// Returns the percentage of the end of the currently playing epg event within the PVR timeshift progress. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressBufferStart`</b>, +/// \anchor PVR_TimeshiftProgressBufferStart +/// _integer_, +/// Returns the percentage of the start of the timeshift buffer within the PVR timeshift progress. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressBufferEnd`</b>, +/// \anchor PVR_TimeshiftProgressBufferEnd +/// _integer_, +/// Returns the percentage of the end of the timeshift buffer within the PVR timeshift progress. +/// } /// \table_end /// /// ----------------------------------------------------------------------------- @@ -4632,7 +4657,12 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING { "hasnonrecordingradiotimer", PVR_HAS_NONRECORDING_RADIO_TIMER }, { "channelnumberinput", PVR_CHANNEL_NUMBER_INPUT }, { "canrecordplayingchannel", PVR_CAN_RECORD_PLAYING_CHANNEL }, - { "isrecordingplayingchannel", PVR_IS_RECORDING_PLAYING_CHANNEL }}; + { "isrecordingplayingchannel", PVR_IS_RECORDING_PLAYING_CHANNEL }, + { "timeshiftprogressplaypos", PVR_TIMESHIFT_PROGRESS_PLAY_POS }, + { "timeshiftprogressepgstart", PVR_TIMESHIFT_PROGRESS_EPG_START }, + { "timeshiftprogressepgend", PVR_TIMESHIFT_PROGRESS_EPG_END }, + { "timeshiftprogressbufferstart", PVR_TIMESHIFT_PROGRESS_BUFFER_START }, + { "timeshiftprogressbufferend", PVR_TIMESHIFT_PROGRESS_BUFFER_END }}; /// \page modules__General__List_of_gui_access /// \section modules__General__List_of_gui_access_PvrTimes PvrTimes @@ -4774,6 +4804,51 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING /// Added with Leia: (secs)\, (mins)\, (hours) for total time values and (m). /// Example: 3661 seconds => h=1\, hh=01\, m=1\, mm=01\, ss=01\, hours=1\, mins=61\, secs=3661 /// } +/// \table_row3{ <b>`PVR.TimeshiftProgressDuration`</b>, +/// \anchor PVR_TimeshiftProgressDuration +/// _string_, +/// Returns the duration of the PVR timeshift progress in the +/// format hh:mm:ss. hh: will be omitted if hours value is zero. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressDuration(format)`</b>, +/// \anchor PVR_TimeshiftProgressDuration_format +/// _string_, +/// Returns the duration of the PVR timeshift progress in different formats: +/// Hours (hh)\, minutes (mm) or seconds (ss). +/// Also supported: (hh:mm)\, (mm:ss)\, (hh:mm:ss)\, (h:mm:ss). +/// Added with Leia: (secs)\, (mins)\, (hours) for total time values and (m). +/// Example: 3661 seconds => h=1\, hh=01\, m=1\, mm=01\, ss=01\, hours=1\, mins=61\, secs=3661 +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressStartTime`</b>, +/// \anchor PVR_TimeshiftProgressStartTime +/// _string_, +/// Returns the start time of the PVR timeshift progress in the +/// format hh:mm:ss. hh: will be omitted if hours value is zero. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressStartTime(format)`</b>, +/// \anchor PVR_TimeshiftProgressStartTime_format +/// _string_, +/// Returns the start time of the PVR timeshift progress in different formats: +/// Hours (hh)\, minutes (mm) or seconds (ss). +/// Also supported: (hh:mm)\, (mm:ss)\, (hh:mm:ss)\, (h:mm:ss). +/// Added with Leia: (secs)\, (mins)\, (hours) for total time values and (m). +/// Example: 3661 seconds => h=1\, hh=01\, m=1\, mm=01\, ss=01\, hours=1\, mins=61\, secs=3661 +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEndTime`</b>, +/// \anchor PVR_TimeshiftProgressEndTime +/// _string_, +/// Returns the end time of the PVR timeshift progress in the +/// format hh:mm:ss. hh: will be omitted if hours value is zero. +/// } +/// \table_row3{ <b>`PVR.TimeshiftProgressEndTime(format)`</b>, +/// \anchor PVR_TimeshiftProgressEndTime_format +/// _string_, +/// Returns the end time of the PVR timeshift progress in different formats: +/// Hours (hh)\, minutes (mm) or seconds (ss). +/// Also supported: (hh:mm)\, (mm:ss)\, (hh:mm:ss)\, (h:mm:ss). +/// Added with Leia: (secs)\, (mins)\, (hours) for total time values and (m). +/// Example: 3661 seconds => h=1\, hh=01\, m=1\, mm=01\, ss=01\, hours=1\, mins=61\, secs=3661 +/// } /// \table_end /// /// ----------------------------------------------------------------------------- @@ -4786,7 +4861,10 @@ const infomap pvr_times[] = {{ "epgeventduration", PVR_EPG_EVENT_DURA { "timeshiftstart", PVR_TIMESHIFT_START_TIME }, { "timeshiftend", PVR_TIMESHIFT_END_TIME }, { "timeshiftcur", PVR_TIMESHIFT_PLAY_TIME }, - { "timeshiftoffset", PVR_TIMESHIFT_OFFSET }}; + { "timeshiftoffset", PVR_TIMESHIFT_OFFSET }, + { "timeshiftprogressduration", PVR_TIMESHIFT_PROGRESS_DURATION }, + { "timeshiftprogressstarttime", PVR_TIMESHIFT_PROGRESS_START_TIME }, + { "timeshiftprogressendtime", PVR_TIMESHIFT_PROGRESS_END_TIME }}; /// \page modules__General__List_of_gui_access /// \section modules__General__List_of_gui_access_RDS Radio RDS diff --git a/xbmc/addons/PVRClient.cpp b/xbmc/addons/PVRClient.cpp index 4805ccc9d6..b7a64e07d1 100644 --- a/xbmc/addons/PVRClient.cpp +++ b/xbmc/addons/PVRClient.cpp @@ -1339,15 +1339,6 @@ PVR_ERROR CPVRClient::CanSeekStream(bool &bCanSeek) const }); } -PVR_ERROR CPVRClient::IsTimeshifting(bool &bTimeshifting) const -{ - bTimeshifting = false; - return DoAddonCall(__FUNCTION__, [&bTimeshifting](const AddonInstance* addon) { - bTimeshifting = addon->IsTimeshifting(); - return PVR_ERROR_NO_ERROR; - }); -} - PVR_ERROR CPVRClient::GetStreamTimes(PVR_STREAM_TIMES *times) { return DoAddonCall(__FUNCTION__, [×](const AddonInstance* addon) { diff --git a/xbmc/addons/PVRClient.h b/xbmc/addons/PVRClient.h index a25304bcca..ced1d95858 100644 --- a/xbmc/addons/PVRClient.h +++ b/xbmc/addons/PVRClient.h @@ -799,13 +799,6 @@ namespace PVR static const char *ToString(const PVR_ERROR error); /*! - * @brief Check whether timeshifting is active for the currently playing stream, if any. - * @param bTimeshifting True, if timeshifting is active, false otherwise. - * @return PVR_ERROR_NO_ERROR on success, respective error code otherwise. - */ - PVR_ERROR IsTimeshifting(bool &bTimeshifting) const; - - /*! * @brief Check whether the currently playing stream, if any, is a real-time stream. * @param bRealTime True if real-time, false otherwise. * @return PVR_ERROR_NO_ERROR on success, respective error code otherwise. diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index 9c924ffb73..7385c023f3 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -373,23 +373,18 @@ bool CSelectionStreams::Get(StreamType type, StreamFlags flag, SelectionStream& return false; } -int CSelectionStreams::IndexOf(StreamType type, int source, int64_t demuxerId, int id) const +int CSelectionStreams::TypeIndexOf(StreamType type, int source, int64_t demuxerId, int id) const { - int count = -1; - for(size_t i=0;i<m_Streams.size();i++) - { - if(type && m_Streams[i].type != type) - continue; - count++; - if(source && m_Streams[i].source != source) - continue; - if(id < 0) - continue; - if(m_Streams[i].id == id && m_Streams[i].demuxerId == demuxerId) - return count; - } - if(id < 0) - return count; + if (id < 0) + return -1; + + auto it = std::find_if(m_Streams.begin(), m_Streams.end(), + [&](const SelectionStream& stream) {return stream.type == type + && stream.source == source && stream.id == id + && stream.demuxerId == demuxerId;}); + + if (it != m_Streams.end()) + return it->type_index; else return -1; } @@ -414,7 +409,7 @@ int CSelectionStreams::Source(StreamSource source, std::string filename) void CSelectionStreams::Update(SelectionStream& s) { - int index = IndexOf(s.type, s.source, s.demuxerId, s.id); + int index = TypeIndexOf(s.type, s.source, s.demuxerId, s.id); if(index >= 0) { SelectionStream& o = Get(s.type, index); @@ -423,7 +418,7 @@ void CSelectionStreams::Update(SelectionStream& s) } else { - s.type_index = Count(s.type); + s.type_index = CountType(s.type); m_Streams.push_back(s); } } @@ -554,23 +549,16 @@ void CSelectionStreams::Update(std::shared_ptr<CDVDInputStream> input, CDVDDemux Update(input, demuxer, ""); } -int CSelectionStreams::CountSource(StreamType type, StreamSource source) const +int CSelectionStreams::CountTypeOfSource(StreamType type, StreamSource source) const { - int count = 0; - for(size_t i=0;i<m_Streams.size();i++) - { - if(type && m_Streams[i].type != type) - continue; - if (source && m_Streams[i].source != source) - continue; - count++; - } - return count; + return std::count_if(m_Streams.begin(), m_Streams.end(), + [&](const SelectionStream& stream) {return (stream.type == type) && (stream.source == source);}); } -int CSelectionStreams::Count(StreamType type) const +int CSelectionStreams::CountType(StreamType type) const { - return IndexOf(type, STREAM_SOURCE_NONE, -1, -1) + 1; + return std::count_if(m_Streams.begin(), m_Streams.end(), + [&](const SelectionStream& stream) {return stream.type == type;}); } //------------------------------------------------------------------------------ @@ -1612,7 +1600,7 @@ void CVideoPlayer::Process() break; first = false; - if (m_pCCDemuxer->GetNrOfStreams() != m_SelectionStreams.CountSource(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX)) + if (m_pCCDemuxer->GetNrOfStreams() != m_SelectionStreams.CountTypeOfSource(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX)) { m_SelectionStreams.Clear(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX); m_SelectionStreams.Update(NULL, m_pCCDemuxer, ""); @@ -3535,7 +3523,7 @@ bool CVideoPlayer::OpenStream(CCurrentStream& current, int64_t demuxerId, int iS if(STREAM_SOURCE_MASK(source) == STREAM_SOURCE_DEMUX_SUB) { - int index = m_SelectionStreams.IndexOf(current.type, source, demuxerId, iStream); + int index = m_SelectionStreams.TypeIndexOf(current.type, source, demuxerId, iStream); if(index < 0) return false; SelectionStream st = m_SelectionStreams.Get(current.type, index); @@ -3568,7 +3556,7 @@ bool CVideoPlayer::OpenStream(CCurrentStream& current, int64_t demuxerId, int iS } else if(STREAM_SOURCE_MASK(source) == STREAM_SOURCE_TEXT) { - int index = m_SelectionStreams.IndexOf(current.type, source, demuxerId, iStream); + int index = m_SelectionStreams.TypeIndexOf(current.type, source, demuxerId, iStream); if(index < 0) return false; @@ -4596,7 +4584,7 @@ int CVideoPlayer::AddSubtitleFile(const std::string& filename, const std::string if (sub->type != STREAM_SUBTITLE) continue; - int index = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, + int index = m_SelectionStreams.TypeIndexOf(STREAM_SUBTITLE, m_SelectionStreams.Source(STREAM_SOURCE_DEMUX_SUB, filename), sub->demuxerId, sub->uniqueId); SelectionStream& stream = m_SelectionStreams.Get(STREAM_SUBTITLE, index); @@ -4611,7 +4599,7 @@ int CVideoPlayer::AddSubtitleFile(const std::string& filename, const std::string stream.flags = static_cast<StreamFlags>(info.flag); } - return m_SelectionStreams.IndexOf(STREAM_SUBTITLE, + return m_SelectionStreams.TypeIndexOf(STREAM_SUBTITLE, m_SelectionStreams.Source(STREAM_SOURCE_DEMUX_SUB, filename), -1, 0); } if(ext == ".sub") @@ -4634,7 +4622,7 @@ int CVideoPlayer::AddSubtitleFile(const std::string& filename, const std::string m_SelectionStreams.Update(s); UpdateContent(); - return m_SelectionStreams.IndexOf(STREAM_SUBTITLE, s.source, s.demuxerId, s.id); + return m_SelectionStreams.TypeIndexOf(STREAM_SUBTITLE, s.source, s.demuxerId, s.id); } void CVideoPlayer::UpdatePlayState(double timeout) @@ -5020,11 +5008,11 @@ void CVideoPlayer::UpdateContent() void CVideoPlayer::UpdateContentState() { CSingleLock lock(m_content.m_section); - m_content.m_videoIndex = m_SelectionStreams.IndexOf(STREAM_VIDEO, m_CurrentVideo.source, + m_content.m_videoIndex = m_SelectionStreams.TypeIndexOf(STREAM_VIDEO, m_CurrentVideo.source, m_CurrentVideo.demuxerId, m_CurrentVideo.id); - m_content.m_audioIndex = m_SelectionStreams.IndexOf(STREAM_AUDIO, m_CurrentAudio.source, + m_content.m_audioIndex = m_SelectionStreams.TypeIndexOf(STREAM_AUDIO, m_CurrentAudio.source, m_CurrentAudio.demuxerId, m_CurrentAudio.id); - m_content.m_subtitleIndex = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, m_CurrentSubtitle.source, + m_content.m_subtitleIndex = m_SelectionStreams.TypeIndexOf(STREAM_SUBTITLE, m_CurrentSubtitle.source, m_CurrentSubtitle.demuxerId, m_CurrentSubtitle.id); } @@ -5063,7 +5051,7 @@ void CVideoPlayer::GetVideoStreamInfo(int streamId, VideoStreamInfo &info) int CVideoPlayer::GetVideoStreamCount() const { CSingleLock lock(m_content.m_section); - return m_content.m_selectionStreams.Count(STREAM_VIDEO); + return m_content.m_selectionStreams.CountType(STREAM_VIDEO); } int CVideoPlayer::GetVideoStream() const @@ -5112,7 +5100,7 @@ void CVideoPlayer::GetAudioStreamInfo(int index, AudioStreamInfo &info) int CVideoPlayer::GetAudioStreamCount() { CSingleLock lock(m_content.m_section); - return m_content.m_selectionStreams.Count(STREAM_AUDIO); + return m_content.m_selectionStreams.CountType(STREAM_AUDIO); } int CVideoPlayer::GetAudioStream() @@ -5155,7 +5143,7 @@ void CVideoPlayer::SetSubtitle(int iStream) int CVideoPlayer::GetSubtitleCount() { CSingleLock lock(m_content.m_section); - return m_content.m_selectionStreams.Count(STREAM_SUBTITLE); + return m_content.m_selectionStreams.CountType(STREAM_SUBTITLE); } int CVideoPlayer::GetSubtitle() diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h index ff1e554cf6..1661fc3a6a 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.h +++ b/xbmc/cores/VideoPlayer/VideoPlayer.h @@ -244,9 +244,9 @@ class CSelectionStreams public: CSelectionStreams() = default; - int IndexOf(StreamType type, int source, int64_t demuxerId, int id) const; - int Count(StreamType type) const; - int CountSource(StreamType type, StreamSource source) const; + int TypeIndexOf(StreamType type, int source, int64_t demuxerId, int id) const; + int CountTypeOfSource(StreamType type, StreamSource source) const; + int CountType(StreamType type) const; SelectionStream& Get(StreamType type, int index); bool Get(StreamType type, StreamFlags flag, SelectionStream& out); void Clear(StreamType type, StreamSource source); diff --git a/xbmc/dialogs/GUIDialogSeekBar.cpp b/xbmc/dialogs/GUIDialogSeekBar.cpp index e646097e02..138fa83621 100644 --- a/xbmc/dialogs/GUIDialogSeekBar.cpp +++ b/xbmc/dialogs/GUIDialogSeekBar.cpp @@ -17,6 +17,7 @@ #define POPUP_SEEK_PROGRESS 401 #define POPUP_SEEK_EPG_EVENT_PROGRESS 402 +#define POPUP_SEEK_TIMESHIFT_PROGRESS 403 CGUIDialogSeekBar::CGUIDialogSeekBar(void) : CGUIDialog(WINDOW_DIALOG_SEEK_BAR, "DialogSeekBar.xml", DialogModalityType::MODELESS) @@ -35,7 +36,9 @@ bool CGUIDialogSeekBar::OnMessage(CGUIMessage& message) return CGUIDialog::OnMessage(message); case GUI_MSG_ITEM_SELECT: if (message.GetSenderId() == GetID() && - (message.GetControlId() == POPUP_SEEK_PROGRESS || message.GetControlId() == POPUP_SEEK_EPG_EVENT_PROGRESS)) + (message.GetControlId() == POPUP_SEEK_PROGRESS || + message.GetControlId() == POPUP_SEEK_EPG_EVENT_PROGRESS || + message.GetControlId() == POPUP_SEEK_TIMESHIFT_PROGRESS)) return CGUIDialog::OnMessage(message); break; case GUI_MSG_REFRESH_TIMER: @@ -52,68 +55,83 @@ void CGUIDialogSeekBar::FrameMove() return; } - unsigned int percent = g_application.GetAppPlayer().GetSeekHandler().InProgress() - ? std::lrintf(GetSeekPercent()) - : std::lrintf(g_application.GetPercentage()); + int progress = GetProgress(); + if (progress != m_lastProgress) + CONTROL_SELECT_ITEM(POPUP_SEEK_PROGRESS, m_lastProgress = progress); - if (percent != m_lastPercent) - CONTROL_SELECT_ITEM(POPUP_SEEK_PROGRESS, m_lastPercent = percent); + int epgEventProgress = GetEpgEventProgress(); + if (epgEventProgress != m_lastEpgEventProgress) + CONTROL_SELECT_ITEM(POPUP_SEEK_EPG_EVENT_PROGRESS, m_lastEpgEventProgress = epgEventProgress); - unsigned int epgEventPercent = g_application.GetAppPlayer().GetSeekHandler().InProgress() - ? GetEpgEventSeekPercent() - : GetEpgEventProgress(); - - if (epgEventPercent != m_lastEpgEventPercent) - CONTROL_SELECT_ITEM(POPUP_SEEK_EPG_EVENT_PROGRESS, m_lastEpgEventPercent = epgEventPercent); + int timeshiftProgress = GetTimeshiftProgress(); + if (timeshiftProgress != m_lastTimeshiftProgress) + CONTROL_SELECT_ITEM(POPUP_SEEK_TIMESHIFT_PROGRESS, m_lastTimeshiftProgress = timeshiftProgress); CGUIDialog::FrameMove(); } -float CGUIDialogSeekBar::GetSeekPercent() const +int CGUIDialogSeekBar::GetProgress() const { - int totaltime = std::lrint(g_application.GetTotalTime()); - if (totaltime == 0) - return 0.0f; + CGUIInfoManager& infoMgr = CServiceBroker::GetGUI()->GetInfoManager(); - float percentPlayTime = static_cast<float>(std::lrint(g_application.GetTime() * 1000)) / totaltime * 0.1f; - float percentPerSecond = 100.0f / static_cast<float>(totaltime); - float percent = percentPlayTime + percentPerSecond * g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(); + int progress = 0; - if (percent > 100.0f) - percent = 100.0f; - if (percent < 0.0f) - percent = 0.0f; + if (g_application.GetAppPlayer().GetSeekHandler().GetSeekSize() != 0) + infoMgr.GetInt(progress, PLAYER_SEEKBAR); + else + infoMgr.GetInt(progress, PLAYER_PROGRESS); - return percent; + return progress; } int CGUIDialogSeekBar::GetEpgEventProgress() const { - int value = 0; - CServiceBroker::GetGUI()->GetInfoManager().GetInt(value, PVR_EPG_EVENT_PROGRESS); - return value; -} + CGUIInfoManager& infoMgr = CServiceBroker::GetGUI()->GetInfoManager(); + + int progress = 0; + infoMgr.GetInt(progress, PVR_EPG_EVENT_PROGRESS); -int CGUIDialogSeekBar::GetEpgEventSeekPercent() const -{ int seekSize = g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(); if (seekSize != 0) { - CGUIInfoManager& infoMgr = CServiceBroker::GetGUI()->GetInfoManager(); - - int progress = 0; - infoMgr.GetInt(progress, PVR_EPG_EVENT_PROGRESS); - int total = 0; infoMgr.GetInt(total, PVR_EPG_EVENT_DURATION); float totalTime = static_cast<float>(total); + if (totalTime == 0.0f) + return 0; + float percentPerSecond = 100.0f / totalTime; float percent = progress + percentPerSecond * seekSize; + percent = std::max(0.0f, std::min(percent, 100.0f)); return std::lrintf(percent); } - else + + return progress; +} + +int CGUIDialogSeekBar::GetTimeshiftProgress() const +{ + CGUIInfoManager& infoMgr = CServiceBroker::GetGUI()->GetInfoManager(); + + int progress = 0; + infoMgr.GetInt(progress, PVR_TIMESHIFT_PROGRESS_PLAY_POS); + + int seekSize = g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(); + if (seekSize != 0) { - return GetEpgEventProgress(); + int total = 0; + infoMgr.GetInt(total, PVR_TIMESHIFT_PROGRESS_DURATION); + + float totalTime = static_cast<float>(total); + if (totalTime == 0.0f) + return 0; + + float percentPerSecond = 100.0f / totalTime; + float percent = progress + percentPerSecond * seekSize; + percent = std::max(0.0f, std::min(percent, 100.0f)); + return std::lrintf(percent); } + + return progress; } diff --git a/xbmc/dialogs/GUIDialogSeekBar.h b/xbmc/dialogs/GUIDialogSeekBar.h index f50563a522..314bf2724e 100644 --- a/xbmc/dialogs/GUIDialogSeekBar.h +++ b/xbmc/dialogs/GUIDialogSeekBar.h @@ -18,10 +18,11 @@ public: bool OnMessage(CGUIMessage& message) override; void FrameMove() override; private: - float GetSeekPercent() const; + int GetProgress() const; int GetEpgEventProgress() const; - int GetEpgEventSeekPercent() const; + int GetTimeshiftProgress() const; - unsigned int m_lastPercent = ~0U; - unsigned int m_lastEpgEventPercent = ~0U; + int m_lastProgress = 0; + int m_lastEpgEventProgress = 0; + int m_lastTimeshiftProgress = 0; }; diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp index 4cefeddb5a..253e63d790 100644 --- a/xbmc/guilib/GUIControlFactory.cpp +++ b/xbmc/guilib/GUIControlFactory.cpp @@ -667,6 +667,7 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl bool defaultAlways = false; std::string strTmp; int singleInfo = 0; + int singleInfo2 = 0; std::string strLabel; int iUrlSet=0; std::string toggleSelect; @@ -855,6 +856,8 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl std::string infoString; if (XMLUtils::GetString(pControlNode, "info", infoString)) singleInfo = CServiceBroker::GetGUI()->GetInfoManager().TranslateString(infoString); + if (XMLUtils::GetString(pControlNode, "info2", infoString)) + singleInfo2 = CServiceBroker::GetGUI()->GetInfoManager().TranslateString(infoString); GetTexture(pControlNode, "texturefocus", textureFocus); GetTexture(pControlNode, "texturenofocus", textureNoFocus); @@ -1288,7 +1291,7 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl textureBackground, textureLeft, textureMid, textureRight, textureOverlay, bReveal); - static_cast<CGUIProgressControl*>(control)->SetInfo(singleInfo); + static_cast<CGUIProgressControl*>(control)->SetInfo(singleInfo, singleInfo2); } break; case CGUIControl::GUICONTROL_IMAGE: diff --git a/xbmc/guilib/GUIProgressControl.cpp b/xbmc/guilib/GUIProgressControl.cpp index 548ae7a033..4b60061d7a 100644 --- a/xbmc/guilib/GUIProgressControl.cpp +++ b/xbmc/guilib/GUIProgressControl.cpp @@ -177,9 +177,10 @@ void CGUIProgressControl::SetInvalid() m_guiOverlay.SetInvalid(); } -void CGUIProgressControl::SetInfo(int iInfo) +void CGUIProgressControl::SetInfo(int iInfo, int iInfo2) { m_iInfoCode = iInfo; + m_iInfoCode2 = iInfo2; } bool CGUIProgressControl::UpdateColors() @@ -220,17 +221,15 @@ bool CGUIProgressControl::UpdateLayout(void) if (m_guiLeft.GetFileName().empty() && m_guiRight.GetFileName().empty()) { // rendering without left and right image - fill the mid image completely - float width = m_fPercent * m_width * 0.01f; - float offset = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight())); - if (offset > 0) // Center texture to the background if necessary - bChanged |= m_guiMid.SetPosition(posX, posY + offset); - else - bChanged |= m_guiMid.SetPosition(posX, posY); + float width = (m_fPercent - m_fPercent2) * m_width * 0.01f; + float offsetX = m_fPercent2 * m_width * 0.01f;; + float offsetY = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight())); + bChanged |= m_guiMid.SetPosition(posX + (offsetX > 0 ? offsetX : 0), posY + (offsetY > 0 ? offsetY : 0)); bChanged |= m_guiMid.SetHeight(fScaleY * m_guiMid.GetTextureHeight()); if (m_bReveal) { bChanged |= m_guiMid.SetWidth(m_width); - float x = posX, y = posY + offset, w = width, h = fScaleY * m_guiMid.GetTextureHeight(); + float x = posX + offsetX, y = posY + offsetY, w = width, h = fScaleY * m_guiMid.GetTextureHeight(); CRect rect(x, y, x + w, y + h); if (rect != m_guiMidClipRect) { @@ -246,30 +245,25 @@ bool CGUIProgressControl::UpdateLayout(void) } else { - float fWidth = m_fPercent; + float fWidth = m_fPercent - m_fPercent2; float fFullWidth = m_guiBackground.GetTextureWidth() - m_guiLeft.GetTextureWidth() - m_guiRight.GetTextureWidth(); fWidth /= 100.0f; fWidth *= fFullWidth; - float offset = fabs(fScaleY * 0.5f * (m_guiLeft.GetTextureHeight() - m_guiBackground.GetTextureHeight())); - if (offset > 0) // Center texture to the background if necessary - bChanged |= m_guiLeft.SetPosition(posX, posY + offset); - else - bChanged |= m_guiLeft.SetPosition(posX, posY); + float offsetY = fabs(fScaleY * 0.5f * (m_guiLeft.GetTextureHeight() - m_guiBackground.GetTextureHeight())); + bChanged |= m_guiLeft.SetPosition(posX, posY + (offsetY > 0 ? offsetY : 0)); bChanged |= m_guiLeft.SetHeight(fScaleY * m_guiLeft.GetTextureHeight()); bChanged |= m_guiLeft.SetWidth(fScaleX * m_guiLeft.GetTextureWidth()); posX += fScaleX * m_guiLeft.GetTextureWidth(); - offset = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight())); - if (offset > 0) // Center texture to the background if necessary - bChanged |= m_guiMid.SetPosition(posX, posY + offset); - else - bChanged |= m_guiMid.SetPosition(posX, posY); + float offsetX = m_fPercent2 * fWidth * 0.01f;; + offsetY = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight())); + bChanged |= m_guiMid.SetPosition(posX + offsetX, posY + (offsetY > 0 ? offsetY : 0)); bChanged |= m_guiMid.SetHeight(fScaleY * m_guiMid.GetTextureHeight()); if (m_bReveal) { bChanged |= m_guiMid.SetWidth(fScaleX * fFullWidth); - float x = posX, y = posY + offset, w = fScaleX * fWidth, h = fScaleY * m_guiMid.GetTextureHeight(); + float x = posX + offsetX, y = posY + offsetY, w = fScaleX * fWidth, h = fScaleY * m_guiMid.GetTextureHeight(); CRect rect(x, y, x + w, y + h); if (rect != m_guiMidClipRect) { @@ -285,11 +279,8 @@ bool CGUIProgressControl::UpdateLayout(void) posX += fWidth * fScaleX; - offset = fabs(fScaleY * 0.5f * (m_guiRight.GetTextureHeight() - m_guiBackground.GetTextureHeight())); - if (offset > 0) // Center texture to the background if necessary - bChanged |= m_guiRight.SetPosition(posX, posY + offset); - else - bChanged |= m_guiRight.SetPosition(posX, posY); + offsetY = fabs(fScaleY * 0.5f * (m_guiRight.GetTextureHeight() - m_guiBackground.GetTextureHeight())); + bChanged |= m_guiRight.SetPosition(posX, posY + (offsetY > 0 ? offsetY : 0)); bChanged |= m_guiRight.SetHeight(fScaleY * m_guiRight.GetTextureHeight()); bChanged |= m_guiRight.SetWidth(fScaleX * m_guiRight.GetTextureWidth()); } @@ -312,10 +303,13 @@ void CGUIProgressControl::UpdateInfo(const CGUIListItem *item) { int value; if (CServiceBroker::GetGUI()->GetInfoManager().GetInt(value, m_iInfoCode, m_parentID, item)) - m_fPercent = (float)value; - - if (m_fPercent < 0.0f) m_fPercent = 0.0f; - if (m_fPercent > 100.0f) m_fPercent = 100.0f; + m_fPercent = std::max(0.0f, std::min(static_cast<float>(value), 100.0f)); + } + if (m_iInfoCode2) + { + int value; + if (CServiceBroker::GetGUI()->GetInfoManager().GetInt(value, m_iInfoCode2, m_parentID, item)) + m_fPercent2 = std::max(0.0f, std::min(static_cast<float>(value), 100.0f)); } } } diff --git a/xbmc/guilib/GUIProgressControl.h b/xbmc/guilib/GUIProgressControl.h index 66cf65afca..2b4ccfb38a 100644 --- a/xbmc/guilib/GUIProgressControl.h +++ b/xbmc/guilib/GUIProgressControl.h @@ -42,7 +42,7 @@ public: bool OnMessage(CGUIMessage& message) override; void SetPosition(float posX, float posY) override; void SetPercentage(float fPercent); - void SetInfo(int iInfo); + void SetInfo(int iInfo, int iInfo2 = 0); int GetInfo() const {return m_iInfoCode;}; float GetPercentage() const; @@ -59,7 +59,9 @@ protected: CRect m_guiMidClipRect; int m_iInfoCode; + int m_iInfoCode2 = 0; float m_fPercent; + float m_fPercent2 = 0.0f; bool m_bReveal; bool m_bChanged; }; diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h index 7e5c7b7aec..413beacaa1 100644 --- a/xbmc/guilib/guiinfo/GUIInfoLabels.h +++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h @@ -584,7 +584,15 @@ #define PVR_EPG_EVENT_FINISH_TIME (PVR_STRINGS_START + 61) #define PVR_TIMESHIFT_OFFSET (PVR_STRINGS_START + 62) #define PVR_EPG_EVENT_SEEK_TIME (PVR_STRINGS_START + 63) -#define PVR_STRINGS_END PVR_EPG_EVENT_SEEK_TIME +#define PVR_TIMESHIFT_PROGRESS_PLAY_POS (PVR_STRINGS_START + 64) +#define PVR_TIMESHIFT_PROGRESS_DURATION (PVR_STRINGS_START + 65) +#define PVR_TIMESHIFT_PROGRESS_EPG_START (PVR_STRINGS_START + 66) +#define PVR_TIMESHIFT_PROGRESS_EPG_END (PVR_STRINGS_START + 67) +#define PVR_TIMESHIFT_PROGRESS_BUFFER_START (PVR_STRINGS_START + 68) +#define PVR_TIMESHIFT_PROGRESS_BUFFER_END (PVR_STRINGS_START + 69) +#define PVR_TIMESHIFT_PROGRESS_START_TIME (PVR_STRINGS_START + 70) +#define PVR_TIMESHIFT_PROGRESS_END_TIME (PVR_STRINGS_START + 71) +#define PVR_STRINGS_END PVR_TIMESHIFT_PROGRESS_END_TIME #define RDS_DATA_START 1400 #define RDS_HAS_RDS (RDS_DATA_START) diff --git a/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp b/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp index c721ad60d1..572edc22c3 100644 --- a/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp +++ b/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp @@ -66,12 +66,7 @@ float CPlayerGUIInfo::GetSeekPercent() const float fPercentPlayTime = static_cast<float>(GetPlayTime() * 1000) / iTotal * 0.1f; float fPercentPerSecond = 100.0f / static_cast<float>(iTotal); float fPercent = fPercentPlayTime + fPercentPerSecond * g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(); - - if (fPercent > 100.0f) - fPercent = 100.0f; - if (fPercent < 0.0f) - fPercent = 0.0f; - + fPercent = std::max(0.0f, std::min(fPercent, 100.0f)); return fPercent; } diff --git a/xbmc/pvr/CMakeLists.txt b/xbmc/pvr/CMakeLists.txt index a1098e7a1e..37e22a1fca 100644 --- a/xbmc/pvr/CMakeLists.txt +++ b/xbmc/pvr/CMakeLists.txt @@ -10,7 +10,8 @@ set(SOURCES PVRActionListener.cpp PVRJobs.cpp PVRGUIChannelNavigator.cpp PVRGUIProgressHandler.cpp - PVRGUITimerInfo.cpp) + PVRGUITimerInfo.cpp + PVRGUITimesInfo.cpp) set(HEADERS PVRActionListener.h PVRDatabase.h @@ -26,6 +27,7 @@ set(HEADERS PVRActionListener.h PVRJobs.h PVRGUIChannelNavigator.h PVRGUIProgressHandler.h - PVRGUITimerInfo.h) + PVRGUITimerInfo.h + PVRGUITimesInfo.h) core_add_library(pvr) diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index 370bd7b0c3..1907a27671 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -14,7 +14,6 @@ #include "Application.h" #include "GUIInfoManager.h" #include "ServiceBroker.h" -#include "cores/DataCacheCore.h" #include "guilib/GUIComponent.h" #include "guilib/LocalizeStrings.h" #include "guilib/guiinfo/GUIInfo.h" @@ -52,9 +51,11 @@ CPVRGUIInfo::~CPVRGUIInfo(void) void CPVRGUIInfo::ResetProperties(void) { CSingleLock lock(m_critSection); + m_anyTimersInfo.ResetProperties(); m_tvTimersInfo.ResetProperties(); m_radioTimersInfo.ResetProperties(); + m_timesInfo.Reset(); m_bHasTVRecordings = false; m_bHasRadioRecordings = false; m_iCurrentActiveClient = 0; @@ -68,7 +69,6 @@ void CPVRGUIInfo::ResetProperties(void) m_strBackendChannels .clear(); m_iBackendDiskTotal = 0; m_iBackendDiskUsed = 0; - m_iDuration = 0; m_bIsPlayingTV = false; m_bIsPlayingRadio = false; m_bIsPlayingRecording = false; @@ -78,15 +78,7 @@ void CPVRGUIInfo::ResetProperties(void) m_bCanRecordPlayingChannel = false; m_bHasTVChannels = false; m_bHasRadioChannels = false; - m_bHasTimeshiftData = false; - m_bIsTimeshifting = false; - m_iStartTime = time_t(0); - m_iTimeshiftStartTime = time_t(0); - m_iTimeshiftEndTime = time_t(0); - m_iTimeshiftPlayTime = time_t(0); - m_iTimeshiftOffset = 0; - - ResetPlayingTag(); + ClearQualityInfo(m_qualityInfo); ClearDescrambleInfo(m_descrambleInfo); @@ -134,7 +126,7 @@ void CPVRGUIInfo::Notify(const Observable &obs, const ObservableMessage msg) void CPVRGUIInfo::Process(void) { - unsigned int mLoop(0); + unsigned int iLoop = 0; int toggleInterval = g_advancedSettings.m_iPVRInfoToggleInterval / 1000; /* updated on request */ @@ -169,11 +161,7 @@ void CPVRGUIInfo::Process(void) Sleep(0); if (!m_bStop) - UpdateTimeshift(); - Sleep(0); - - if (!m_bStop) - UpdatePlayingTag(); + UpdateTimeshiftData(); Sleep(0); if (!m_bStop) @@ -185,18 +173,15 @@ void CPVRGUIInfo::Process(void) Sleep(0); // Update the backend cache every toggleInterval seconds - if (!m_bStop && mLoop % toggleInterval == 0) + if (!m_bStop && iLoop % toggleInterval == 0) UpdateBackendCache(); - if (++mLoop == 1000) - mLoop = 0; + if (++iLoop == 1000) + iLoop = 0; if (!m_bStop) Sleep(1000); } - - if (!m_bStop) - ResetPlayingTag(); } void CPVRGUIInfo::UpdateQualityData(void) @@ -272,65 +257,9 @@ void CPVRGUIInfo::UpdateMisc(void) m_bIsRecordingPlayingChannel = bIsRecordingPlayingChannel; } -void CPVRGUIInfo::UpdateTimeshift(void) +void CPVRGUIInfo::UpdateTimeshiftData(void) { - if (!CServiceBroker::GetPVRManager().IsPlayingTV() && !CServiceBroker::GetPVRManager().IsPlayingRadio()) - { - // If nothing is playing (anymore), there is no need to poll the timeshift values from the clients. - CSingleLock lock(m_critSection); - if (m_bHasTimeshiftData) - { - m_bHasTimeshiftData = false; - m_bIsTimeshifting = false; - m_iStartTime = 0; - m_iTimeshiftStartTime = 0; - m_iTimeshiftEndTime = 0; - m_iTimeshiftPlayTime = 0; - m_iLastTimeshiftUpdate = 0; - m_iTimeshiftOffset = 0; - } - return; - } - - bool bIsTimeshifting = CServiceBroker::GetPVRManager().IsTimeshifting(); - time_t now = std::time(nullptr); - time_t iStartTime = CServiceBroker::GetDataCacheCore().GetStartTime(); - time_t iPlayTime = CServiceBroker::GetDataCacheCore().GetPlayTime() / 1000; - time_t iMinTime = bIsTimeshifting ? CServiceBroker::GetDataCacheCore().GetMinTime() / 1000 : 0; - time_t iMaxTime = bIsTimeshifting ? CServiceBroker::GetDataCacheCore().GetMaxTime() / 1000 : 0; - bool bPlaying = CServiceBroker::GetDataCacheCore().GetSpeed() == 1.0; - - CSingleLock lock(m_critSection); - - m_iLastTimeshiftUpdate = now; - - if (!iStartTime) - { - if (m_iStartTime == 0) - iStartTime = now; - else - iStartTime = m_iStartTime; - } - - m_bIsTimeshifting = bIsTimeshifting; - m_iStartTime = iStartTime; - m_iTimeshiftStartTime = iStartTime + iMinTime; - m_iTimeshiftEndTime = iStartTime + iMaxTime; - - if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) - { - // timeshifting supported - m_iTimeshiftPlayTime = iStartTime + iPlayTime; - } - else if (bPlaying) - { - // timeshifting not supported - m_iTimeshiftPlayTime = now - m_iTimeshiftOffset; - } - - m_iTimeshiftOffset = now - m_iTimeshiftPlayTime; - - m_bHasTimeshiftData = true; + m_timesInfo.Update(); } bool CPVRGUIInfo::InitCurrentItem(CFileItem *item) @@ -701,32 +630,53 @@ bool CPVRGUIInfo::GetPVRLabel(const CFileItem *item, const CGUIInfo &info, std:: switch (info.m_info) { case PVR_EPG_EVENT_DURATION: - CharInfoEpgEventDuration(item, static_cast<TIME_FORMAT>(info.GetData1()), strValue); + { + const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; + strValue = m_timesInfo.GetEpgEventDuration(epgTag, static_cast<TIME_FORMAT>(info.GetData1())); return true; + } case PVR_EPG_EVENT_ELAPSED_TIME: - CharInfoEpgEventElapsedTime(item, static_cast<TIME_FORMAT>(info.GetData1()), strValue); + { + const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; + strValue = m_timesInfo.GetEpgEventElapsedTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1())); return true; + } case PVR_EPG_EVENT_REMAINING_TIME: - CharInfoEpgEventRemainingTime(item, static_cast<TIME_FORMAT>(info.GetData1()), strValue); + { + const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; + strValue = m_timesInfo.GetEpgEventRemainingTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1())); return true; + } case PVR_EPG_EVENT_FINISH_TIME: - CharInfoEpgEventFinishTime(item, static_cast<TIME_FORMAT>(info.GetData1()), strValue); + { + const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; + strValue = m_timesInfo.GetEpgEventFinishTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1())); return true; + } case PVR_TIMESHIFT_START_TIME: - CharInfoTimeshiftStartTime(static_cast<TIME_FORMAT>(info.GetData1()), strValue); + strValue = m_timesInfo.GetTimeshiftStartTime(static_cast<TIME_FORMAT>(info.GetData1())); return true; case PVR_TIMESHIFT_END_TIME: - CharInfoTimeshiftEndTime(static_cast<TIME_FORMAT>(info.GetData1()), strValue); + strValue = m_timesInfo.GetTimeshiftEndTime(static_cast<TIME_FORMAT>(info.GetData1())); return true; case PVR_TIMESHIFT_PLAY_TIME: - CharInfoTimeshiftPlayTime(static_cast<TIME_FORMAT>(info.GetData1()), strValue); + strValue = m_timesInfo.GetTimeshiftPlayTime(static_cast<TIME_FORMAT>(info.GetData1())); return true; case PVR_TIMESHIFT_OFFSET: - CharInfoTimeshiftOffset(static_cast<TIME_FORMAT>(info.GetData1()), strValue); + strValue = m_timesInfo.GetTimeshiftOffset(static_cast<TIME_FORMAT>(info.GetData1())); + return true; + case PVR_TIMESHIFT_PROGRESS_DURATION: + strValue = m_timesInfo.GetTimeshiftProgressDuration(static_cast<TIME_FORMAT>(info.GetData1())); + return true; + case PVR_TIMESHIFT_PROGRESS_START_TIME: + strValue = m_timesInfo.GetTimeshiftProgressStartTime(static_cast<TIME_FORMAT>(info.GetData1())); + return true; + case PVR_TIMESHIFT_PROGRESS_END_TIME: + strValue = m_timesInfo.GetTimeshiftProgressEndTime(static_cast<TIME_FORMAT>(info.GetData1())); return true; case PVR_EPG_EVENT_SEEK_TIME: - strValue = StringUtils::SecondsToTimeString(GetElapsedTime() + g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(), - static_cast<TIME_FORMAT>(info.GetData1())).c_str(); + strValue = m_timesInfo.GetEpgEventSeekTime(g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(), + static_cast<TIME_FORMAT>(info.GetData1())); return true; case PVR_NOW_RECORDING_TITLE: strValue = m_anyTimersInfo.GetActiveTimerTitle(); @@ -1090,24 +1040,35 @@ bool CPVRGUIInfo::GetPVRInt(const CFileItem *item, const CGUIInfo &info, int& iV case PVR_EPG_EVENT_DURATION: { const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; - if (epgTag && epgTag != m_playingEpgTag) - iValue = epgTag->GetDuration(); - else - iValue = m_iDuration; + iValue = m_timesInfo.GetEpgEventDuration(epgTag); return true; } case PVR_EPG_EVENT_PROGRESS: { const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; - if (epgTag && epgTag != m_playingEpgTag) - iValue = std::lrintf(epgTag->ProgressPercentage()); - else - iValue = std::lrintf(static_cast<float>(GetElapsedTime()) / m_iDuration * 100); + iValue = m_timesInfo.GetEpgEventProgress(epgTag); return true; } case PVR_TIMESHIFT_PROGRESS: - iValue = std::lrintf(static_cast<float>(m_iTimeshiftPlayTime - m_iTimeshiftStartTime) / - (m_iTimeshiftEndTime - m_iTimeshiftStartTime) * 100); + iValue = m_timesInfo.GetTimeshiftProgress(); + return true; + case PVR_TIMESHIFT_PROGRESS_DURATION: + iValue = m_timesInfo.GetTimeshiftProgressDuration(); + return true; + case PVR_TIMESHIFT_PROGRESS_PLAY_POS: + iValue = m_timesInfo.GetTimeshiftProgressPlayPosition(); + return true; + case PVR_TIMESHIFT_PROGRESS_EPG_START: + iValue = m_timesInfo.GetTimeshiftProgressEpgStart(); + return true; + case PVR_TIMESHIFT_PROGRESS_EPG_END: + iValue = m_timesInfo.GetTimeshiftProgressEpgEnd(); + return true; + case PVR_TIMESHIFT_PROGRESS_BUFFER_START: + iValue = m_timesInfo.GetTimeshiftProgressBufferStart(); + return true; + case PVR_TIMESHIFT_PROGRESS_BUFFER_END: + iValue = m_timesInfo.GetTimeshiftProgressBufferEnd(); return true; case PVR_ACTUAL_STREAM_SIG_PROGR: iValue = std::lrintf(static_cast<float>(m_qualityInfo.iSignal) / 0xFFFF * 100); @@ -1345,7 +1306,7 @@ bool CPVRGUIInfo::GetPVRBool(const CFileItem *item, const CGUIInfo &info, bool& bValue = m_bIsPlayingEncryptedStream; return true; case PVR_IS_TIMESHIFTING: - bValue = m_bIsTimeshifting; + bValue = m_timesInfo.IsTimeshifting(); return true; case PVR_CAN_RECORD_PLAYING_CHANNEL: bValue = m_bCanRecordPlayingChannel; @@ -1389,84 +1350,6 @@ bool CPVRGUIInfo::GetRadioRDSBool(const CFileItem *item, const CGUIInfo &info, b return false; } -namespace -{ - std::string TimeToTimeString(time_t datetime, TIME_FORMAT format, bool withSeconds) - { - CDateTime time; - time.SetFromUTCDateTime(datetime); - return time.GetAsLocalizedTime(format, withSeconds); - } -} // unnamed namespace - -void CPVRGUIInfo::CharInfoTimeshiftStartTime(TIME_FORMAT format, std::string &strValue) const -{ - strValue = TimeToTimeString(m_iTimeshiftStartTime, format, false); -} - -void CPVRGUIInfo::CharInfoTimeshiftEndTime(TIME_FORMAT format, std::string &strValue) const -{ - strValue = TimeToTimeString(m_iTimeshiftEndTime, format, false); -} - -void CPVRGUIInfo::CharInfoTimeshiftPlayTime(TIME_FORMAT format, std::string &strValue) const -{ - strValue = TimeToTimeString(m_iTimeshiftPlayTime, format, true); -} - -void CPVRGUIInfo::CharInfoTimeshiftOffset(TIME_FORMAT format, std::string &strValue) const -{ - strValue = StringUtils::SecondsToTimeString(m_iTimeshiftOffset, format).c_str(); -} - -void CPVRGUIInfo::CharInfoEpgEventDuration(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const -{ - int iDuration = 0; - const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; - if (epgTag && epgTag != m_playingEpgTag) - iDuration = epgTag->GetDuration(); - else - iDuration = m_iDuration; - - strValue = StringUtils::SecondsToTimeString(iDuration, format).c_str(); -} - -void CPVRGUIInfo::CharInfoEpgEventElapsedTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const -{ - int iElapsed = 0; - const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; - if (epgTag && epgTag != m_playingEpgTag) - iElapsed = epgTag->Progress(); - else - iElapsed = GetElapsedTime(); - - strValue = StringUtils::SecondsToTimeString(iElapsed, format).c_str(); -} - -int CPVRGUIInfo::GetRemainingTime(const CFileItem *item) const -{ - int iRemaining = 0; - const CPVREpgInfoTagPtr epgTag = (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr; - if (epgTag && epgTag != m_playingEpgTag) - iRemaining = epgTag->GetDuration() - epgTag->Progress(); - else - iRemaining = m_iDuration - GetElapsedTime(); - - return iRemaining; -} - -void CPVRGUIInfo::CharInfoEpgEventRemainingTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const -{ - strValue = StringUtils::SecondsToTimeString(GetRemainingTime(item), format).c_str(); -} - -void CPVRGUIInfo::CharInfoEpgEventFinishTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const -{ - CDateTime finish = CDateTime::GetCurrentDateTime(); - finish += CDateTimeSpan(0, 0, 0, GetRemainingTime(item)); - strValue = finish.GetAsLocalizedTime(format); -} - void CPVRGUIInfo::CharInfoBackendNumber(std::string &strValue) const { size_t numBackends = m_backendProperties.size(); @@ -1709,80 +1592,3 @@ void CPVRGUIInfo::UpdateNextTimer(void) m_tvTimersInfo.UpdateNextTimer(); m_radioTimersInfo.UpdateNextTimer(); } - -int CPVRGUIInfo::GetElapsedTime(void) const -{ - CSingleLock lock(m_critSection); - - if (m_playingEpgTag || m_iTimeshiftStartTime) - { - CDateTime current(m_iTimeshiftPlayTime); - CDateTime start = m_playingEpgTag ? m_playingEpgTag->StartAsUTC() - : CDateTime(m_iTimeshiftStartTime); - CDateTimeSpan time = current > start ? current - start : CDateTimeSpan(0, 0, 0, 0); - return time.GetSecondsTotal(); - } - else - { - return 0; - } -} - -void CPVRGUIInfo::ResetPlayingTag(void) -{ - CSingleLock lock(m_critSection); - m_playingEpgTag.reset(); - m_iDuration = 0; -} - -CPVREpgInfoTagPtr CPVRGUIInfo::GetPlayingTag() const -{ - CSingleLock lock(m_critSection); - return m_playingEpgTag; -} - -void CPVRGUIInfo::UpdatePlayingTag(void) -{ - const CPVRChannelPtr currentChannel(CServiceBroker::GetPVRManager().GetPlayingChannel()); - const CPVREpgInfoTagPtr currentTag(CServiceBroker::GetPVRManager().GetPlayingEpgTag()); - if (currentChannel || currentTag) - { - CPVREpgInfoTagPtr epgTag(GetPlayingTag()); - CPVRChannelPtr channel; - if (epgTag) - channel = epgTag->Channel(); - - if (!epgTag || !epgTag->IsActive() || - !channel || !currentChannel || *channel != *currentChannel) - { - const CPVREpgInfoTagPtr newTag(currentTag ? currentTag : currentChannel->GetEPGNow()); - - CSingleLock lock(m_critSection); - if (newTag) - { - m_playingEpgTag = newTag; - m_iDuration = m_playingEpgTag->GetDuration(); - } - else if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) - { - m_playingEpgTag.reset(); - m_iDuration = m_iTimeshiftEndTime - m_iTimeshiftStartTime; - } - else - { - m_playingEpgTag.reset(); - m_iDuration = 0; - } - } - } - else - { - const CPVRRecordingPtr recording(CServiceBroker::GetPVRManager().GetPlayingRecording()); - if (recording) - { - CSingleLock lock(m_critSection); - m_playingEpgTag.reset(); - m_iDuration = recording->GetDuration(); - } - } -} diff --git a/xbmc/pvr/PVRGUIInfo.h b/xbmc/pvr/PVRGUIInfo.h index 78b74634a8..9d3e05ab59 100644 --- a/xbmc/pvr/PVRGUIInfo.h +++ b/xbmc/pvr/PVRGUIInfo.h @@ -19,6 +19,7 @@ #include "utils/Observer.h" #include "pvr/PVRGUITimerInfo.h" +#include "pvr/PVRGUITimesInfo.h" #include "pvr/PVRTypes.h" #include "pvr/addons/PVRClients.h" @@ -52,17 +53,6 @@ namespace PVR bool GetInt(int& value, const CGUIListItem *item, int contextWindow, const KODI::GUILIB::GUIINFO::CGUIInfo &info) const override; bool GetBool(bool& value, const CGUIListItem *item, int contextWindow, const KODI::GUILIB::GUIINFO::CGUIInfo &info) const override; - /*! - * @brief Clear the playing EPG tag. - */ - void ResetPlayingTag(void); - - /*! - * @brief Get the currently playing EPG tag. - * @return The currently playing EPG tag or NULL if no EPG tag is playing. - */ - CPVREpgInfoTagPtr GetPlayingTag() const; - private: void ResetProperties(void); void ClearQualityInfo(PVR_SIGNAL_STATUS &qualityInfo); @@ -70,14 +60,14 @@ namespace PVR void Process(void) override; - void UpdatePlayingTag(void); void UpdateTimersCache(void); void UpdateBackendCache(void); void UpdateQualityData(void); void UpdateDescrambleData(void); void UpdateMisc(void); void UpdateNextTimer(void); - void UpdateTimeshift(void); + void UpdateTimeshiftData(void); + void UpdateTimeshiftProgressData(); void UpdateTimersToggle(void); @@ -92,10 +82,6 @@ namespace PVR bool GetPVRBool(const CFileItem *item, const KODI::GUILIB::GUIINFO::CGUIInfo &info, bool& bValue) const; bool GetRadioRDSBool(const CFileItem *item, const KODI::GUILIB::GUIINFO::CGUIInfo &info, bool &bValue) const; - void CharInfoEpgEventDuration(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const; - void CharInfoEpgEventElapsedTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const; - void CharInfoEpgEventRemainingTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const; - void CharInfoEpgEventFinishTime(const CFileItem *item, TIME_FORMAT format, std::string &strValue) const; void CharInfoBackendNumber(std::string &strValue) const; void CharInfoTotalDiskSpace(std::string &strValue) const; void CharInfoSignal(std::string &strValue) const; @@ -117,19 +103,6 @@ namespace PVR void CharInfoService(std::string &strValue) const; void CharInfoMux(std::string &strValue) const; void CharInfoProvider(std::string &strValue) const; - void CharInfoTimeshiftStartTime(TIME_FORMAT format, std::string &strValue) const; - void CharInfoTimeshiftEndTime(TIME_FORMAT format, std::string &strValue) const; - void CharInfoTimeshiftPlayTime(TIME_FORMAT format, std::string &strValue) const; - void CharInfoTimeshiftOffset(TIME_FORMAT format, std::string &strValue) const; - - /*! - * @brief Get the elapsed time since the start of the currently playing epg event or if - * no epg is available since the start of the playback of the current Live TV stream. - * @return The time in seconds or 0 if no channel is playing. - */ - int GetElapsedTime(void) const; - - int GetRemainingTime(const CFileItem *item) const; /** @name PVRGUIInfo data */ //@{ @@ -137,6 +110,8 @@ namespace PVR CPVRGUITVTimerInfo m_tvTimersInfo; CPVRGUIRadioTimerInfo m_radioTimersInfo; + CPVRGUITimesInfo m_timesInfo; + bool m_bHasTVRecordings; bool m_bHasRadioRecordings; unsigned int m_iCurrentActiveClient; @@ -150,7 +125,6 @@ namespace PVR std::string m_strBackendChannels; long long m_iBackendDiskTotal; long long m_iBackendDiskUsed; - unsigned int m_iDuration; bool m_bIsPlayingTV; bool m_bIsPlayingRadio; bool m_bIsPlayingRecording; @@ -167,18 +141,8 @@ namespace PVR PVR_SIGNAL_STATUS m_qualityInfo; /*!< stream quality information */ PVR_DESCRAMBLE_INFO m_descrambleInfo; /*!< stream descramble information */ - CPVREpgInfoTagPtr m_playingEpgTag; std::vector<SBackend> m_backendProperties; - bool m_bHasTimeshiftData; - bool m_bIsTimeshifting; - time_t m_iLastTimeshiftUpdate; - time_t m_iStartTime; - time_t m_iTimeshiftStartTime; - time_t m_iTimeshiftEndTime; - time_t m_iTimeshiftPlayTime; - unsigned int m_iTimeshiftOffset; - mutable CCriticalSection m_critSection; /** @@ -187,7 +151,7 @@ namespace PVR * backend querying when we're not displaying any of the queried * information. */ - mutable std::atomic<bool> m_updateBackendCacheRequested; + mutable std::atomic<bool> m_updateBackendCacheRequested; bool m_bRegistered; }; diff --git a/xbmc/pvr/PVRGUITimesInfo.cpp b/xbmc/pvr/PVRGUITimesInfo.cpp new file mode 100644 index 0000000000..2dbcda3567 --- /dev/null +++ b/xbmc/pvr/PVRGUITimesInfo.cpp @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2012-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "PVRGUITimesInfo.h" + +#include <cmath> + +#include "ServiceBroker.h" +#include "cores/DataCacheCore.h" +#include "settings/AdvancedSettings.h" +#include "threads/SingleLock.h" +#include "utils/StringUtils.h" + +#include "pvr/PVRManager.h" + +using namespace PVR; + +CPVRGUITimesInfo::CPVRGUITimesInfo() +{ + Reset(); +} + +void CPVRGUITimesInfo::Reset() +{ + CSingleLock lock(m_critSection); + + m_iStartTime = 0; + m_iDuration = 0; + m_iTimeshiftStartTime = 0; + m_iTimeshiftEndTime = 0; + m_iTimeshiftPlayTime = 0; + m_iTimeshiftOffset = 0; + + m_iTimeshiftProgressStartTime = 0; + m_iTimeshiftProgressEndTime = 0; + m_iTimeshiftProgressDuration = 0; + + m_playingEpgTag.reset(); +} + +void CPVRGUITimesInfo::UpdatePlayingTag() +{ + const CPVRChannelPtr currentChannel = CServiceBroker::GetPVRManager().GetPlayingChannel(); + CPVREpgInfoTagPtr currentTag = CServiceBroker::GetPVRManager().GetPlayingEpgTag(); + + if (currentChannel || currentTag) + { + if (!currentTag) + currentTag = currentChannel->GetEPGNow(); + + CSingleLock lock(m_critSection); + + const CPVRChannelPtr playingChannel = m_playingEpgTag ? m_playingEpgTag->Channel() : nullptr; + if (!m_playingEpgTag || !m_playingEpgTag->IsActive() || + !playingChannel || !currentChannel || *playingChannel != *currentChannel) + { + if (currentTag) + { + m_playingEpgTag = currentTag; + m_iDuration = m_playingEpgTag->GetDuration(); + } + else if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) + { + m_playingEpgTag.reset(); + m_iDuration = m_iTimeshiftEndTime - m_iTimeshiftStartTime; + } + else + { + m_playingEpgTag.reset(); + m_iDuration = 0; + } + } + } + else + { + const CPVRRecordingPtr recording = CServiceBroker::GetPVRManager().GetPlayingRecording(); + if (recording) + { + CSingleLock lock(m_critSection); + m_playingEpgTag.reset(); + m_iDuration = recording->GetDuration(); + } + } +} + +void CPVRGUITimesInfo::UpdateTimeshiftData() +{ + if (!CServiceBroker::GetPVRManager().IsPlayingTV() && !CServiceBroker::GetPVRManager().IsPlayingRadio()) + { + // If nothing is playing (anymore), there is no need to update data. + Reset(); + return; + } + + time_t now = std::time(nullptr); + time_t iStartTime; + int64_t iPlayTime, iMinTime, iMaxTime; + CServiceBroker::GetDataCacheCore().GetPlayTimes(iStartTime, iPlayTime, iMinTime, iMaxTime); + bool bPlaying = CServiceBroker::GetDataCacheCore().GetSpeed() == 1.0; + + CSingleLock lock(m_critSection); + + if (!iStartTime) + { + if (m_iStartTime == 0) + iStartTime = now; + else + iStartTime = m_iStartTime; + + iMinTime = iPlayTime; + iMaxTime = iPlayTime; + } + + m_iStartTime = iStartTime; + m_iTimeshiftStartTime = iStartTime + iMinTime / 1000; + m_iTimeshiftEndTime = iStartTime + iMaxTime / 1000; + + if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) + { + // timeshifting supported + m_iTimeshiftPlayTime = iStartTime + iPlayTime / 1000; + m_iTimeshiftOffset = (iMaxTime - iPlayTime) / 1000; + } + else + { + // timeshifting not supported + if (bPlaying) + m_iTimeshiftPlayTime = now - m_iTimeshiftOffset; + + m_iTimeshiftOffset = now - m_iTimeshiftPlayTime; + } + + UpdateTimeshiftProgressData(); +} + +void CPVRGUITimesInfo::UpdateTimeshiftProgressData() +{ + // Note: General idea of the ts progress is always to be able to visualise both the complete + // ts buffer and the complete playing epg event (if any) side by side with the same time + // scale. Ts progress start and end times will be calculated accordingly. + // + Start is usually ts buffer start, except if start time of playing epg event is + // before ts buffer start, then progress start is epg event start. + // + End is usually ts buffer end, except if end time of playing epg event is + // after ts buffer end, then progress end is epg event end. + + CSingleLock lock(m_critSection); + + ////////////////////////////////////////////////////////////////////////////////////// + // start time + ////////////////////////////////////////////////////////////////////////////////////// + bool bUpdatedStartTime = false; + if (m_playingEpgTag) + { + time_t start = 0; + m_playingEpgTag->StartAsUTC().GetAsTime(start); + if (start < m_iTimeshiftStartTime) + { + // playing event started before start of ts buffer + m_iTimeshiftProgressStartTime = start; + bUpdatedStartTime = true; + } + } + + if (!bUpdatedStartTime) + { + // default to ts buffer start + m_iTimeshiftProgressStartTime = m_iTimeshiftStartTime; + } + + ////////////////////////////////////////////////////////////////////////////////////// + // end time + ////////////////////////////////////////////////////////////////////////////////////// + bool bUpdatedEndTime = false; + if (m_playingEpgTag) + { + time_t end = 0; + m_playingEpgTag->EndAsUTC().GetAsTime(end); + if (end > m_iTimeshiftEndTime) + { + // playing event will end after end of ts buffer + m_iTimeshiftProgressEndTime = end; + bUpdatedEndTime = true; + } + } + + if (!bUpdatedEndTime) + { + // default to ts buffer end + m_iTimeshiftProgressEndTime = m_iTimeshiftEndTime; + } + + ////////////////////////////////////////////////////////////////////////////////////// + // duration + ////////////////////////////////////////////////////////////////////////////////////// + m_iTimeshiftProgressDuration = m_iTimeshiftProgressEndTime - m_iTimeshiftProgressStartTime; +} + +void CPVRGUITimesInfo::Update() +{ + UpdatePlayingTag(); + UpdateTimeshiftData(); +} + +std::string CPVRGUITimesInfo::TimeToTimeString(time_t datetime, TIME_FORMAT format, bool withSeconds) +{ + CDateTime time; + time.SetFromUTCDateTime(datetime); + return time.GetAsLocalizedTime(format, withSeconds); +} + +std::string CPVRGUITimesInfo::GetTimeshiftStartTime(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return TimeToTimeString(m_iTimeshiftStartTime, format, false); +} + +std::string CPVRGUITimesInfo::GetTimeshiftEndTime(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return TimeToTimeString(m_iTimeshiftEndTime, format, false); +} + +std::string CPVRGUITimesInfo::GetTimeshiftPlayTime(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return TimeToTimeString(m_iTimeshiftPlayTime, format, true); +} + +std::string CPVRGUITimesInfo::GetTimeshiftOffset(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return StringUtils::SecondsToTimeString(m_iTimeshiftOffset, format); +} + +std::string CPVRGUITimesInfo::GetTimeshiftProgressDuration(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return StringUtils::SecondsToTimeString(m_iTimeshiftProgressDuration, format); +} + +std::string CPVRGUITimesInfo::GetTimeshiftProgressStartTime(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return TimeToTimeString(m_iTimeshiftProgressStartTime, format, false); +} + +std::string CPVRGUITimesInfo::GetTimeshiftProgressEndTime(TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return TimeToTimeString(m_iTimeshiftProgressEndTime, format, false); +} + +std::string CPVRGUITimesInfo::GetEpgEventDuration(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return StringUtils::SecondsToTimeString(GetEpgEventDuration(epgTag), format); +} + +std::string CPVRGUITimesInfo::GetEpgEventElapsedTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const +{ + int iElapsed = 0; + CSingleLock lock(m_critSection); + if (epgTag && epgTag != m_playingEpgTag) + iElapsed = epgTag->Progress(); + else + iElapsed = GetElapsedTime(); + + return StringUtils::SecondsToTimeString(iElapsed, format); +} + +std::string CPVRGUITimesInfo::GetEpgEventRemainingTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const +{ + CSingleLock lock(m_critSection); + return StringUtils::SecondsToTimeString(GetRemainingTime(epgTag), format); +} + +std::string CPVRGUITimesInfo::GetEpgEventFinishTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const +{ + CDateTime finish = CDateTime::GetCurrentDateTime(); + finish += CDateTimeSpan(0, 0, 0, GetRemainingTime(epgTag)); + return finish.GetAsLocalizedTime(format); +} + +std::string CPVRGUITimesInfo::GetEpgEventSeekTime(int iSeekSize, TIME_FORMAT format) const +{ + return StringUtils::SecondsToTimeString(GetElapsedTime() + iSeekSize, format); +} + +int CPVRGUITimesInfo::GetElapsedTime() const +{ + CSingleLock lock(m_critSection); + if (m_playingEpgTag || m_iTimeshiftStartTime) + { + CDateTime current(m_iTimeshiftPlayTime); + CDateTime start = m_playingEpgTag ? m_playingEpgTag->StartAsUTC() : CDateTime(m_iTimeshiftStartTime); + CDateTimeSpan time = current > start ? current - start : CDateTimeSpan(0, 0, 0, 0); + return time.GetSecondsTotal(); + } + else + { + return 0; + } +} + +int CPVRGUITimesInfo::GetRemainingTime(const CPVREpgInfoTagPtr& epgTag) const +{ + CSingleLock lock(m_critSection); + if (epgTag && epgTag != m_playingEpgTag) + return epgTag->GetDuration() - epgTag->Progress(); + else + return m_iDuration - GetElapsedTime(); +} + +int CPVRGUITimesInfo::GetTimeshiftProgress() const +{ + CSingleLock lock(m_critSection); + return std::lrintf(static_cast<float>(m_iTimeshiftPlayTime - m_iTimeshiftStartTime) / (m_iTimeshiftEndTime - m_iTimeshiftStartTime) * 100); +} + +int CPVRGUITimesInfo::GetTimeshiftProgressDuration() const +{ + CSingleLock lock(m_critSection); + return m_iTimeshiftProgressDuration; +} + +int CPVRGUITimesInfo::GetTimeshiftProgressPlayPosition() const +{ + CSingleLock lock(m_critSection); + return std::lrintf(static_cast<float>(m_iTimeshiftPlayTime - m_iTimeshiftProgressStartTime) / m_iTimeshiftProgressDuration * 100); +} + +int CPVRGUITimesInfo::GetTimeshiftProgressEpgStart() const +{ + CSingleLock lock(m_critSection); + if (m_playingEpgTag) + { + time_t epgStart = 0; + m_playingEpgTag->StartAsUTC().GetAsTime(epgStart); + return std::lrintf(static_cast<float>(epgStart - m_iTimeshiftProgressStartTime) / m_iTimeshiftProgressDuration * 100); + } + return 0; +} + +int CPVRGUITimesInfo::GetTimeshiftProgressEpgEnd() const +{ + CSingleLock lock(m_critSection); + if (m_playingEpgTag) + { + time_t epgEnd = 0; + m_playingEpgTag->EndAsUTC().GetAsTime(epgEnd); + return std::lrintf(static_cast<float>(epgEnd - m_iTimeshiftProgressStartTime) / m_iTimeshiftProgressDuration * 100); + } + return 0; +} + +int CPVRGUITimesInfo::GetTimeshiftProgressBufferStart() const +{ + CSingleLock lock(m_critSection); + return std::lrintf(static_cast<float>(m_iTimeshiftStartTime - m_iTimeshiftProgressStartTime) / m_iTimeshiftProgressDuration * 100); +} + +int CPVRGUITimesInfo::GetTimeshiftProgressBufferEnd() const +{ + CSingleLock lock(m_critSection); + return std::lrintf(static_cast<float>(m_iTimeshiftEndTime - m_iTimeshiftProgressStartTime) / m_iTimeshiftProgressDuration * 100); +} + +int CPVRGUITimesInfo::GetEpgEventDuration(const CPVREpgInfoTagPtr& epgTag) const +{ + CSingleLock lock(m_critSection); + if (epgTag && epgTag != m_playingEpgTag) + return epgTag->GetDuration(); + else + return m_iDuration; +} + +int CPVRGUITimesInfo::GetEpgEventProgress(const CPVREpgInfoTagPtr& epgTag) const +{ + CSingleLock lock(m_critSection); + if (epgTag && epgTag != m_playingEpgTag) + return std::lrintf(epgTag->ProgressPercentage()); + else + return std::lrintf(static_cast<float>(GetElapsedTime()) / m_iDuration * 100); +} + +bool CPVRGUITimesInfo::IsTimeshifting() const +{ + CSingleLock lock(m_critSection); + return (m_iTimeshiftOffset > static_cast<unsigned int>(g_advancedSettings.m_iPVRTimeshiftThreshold)); +} diff --git a/xbmc/pvr/PVRGUITimesInfo.h b/xbmc/pvr/PVRGUITimesInfo.h new file mode 100644 index 0000000000..479bdce5f9 --- /dev/null +++ b/xbmc/pvr/PVRGUITimesInfo.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2012-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "XBDateTime.h" +#include "threads/CriticalSection.h" + +#include "pvr/PVRTypes.h" + +namespace PVR +{ + class CPVRGUITimesInfo + { + public: + CPVRGUITimesInfo(); + virtual ~CPVRGUITimesInfo() = default; + + void Reset(); + void Update(); + + // GUI info labels + std::string GetTimeshiftStartTime(TIME_FORMAT format) const; + std::string GetTimeshiftEndTime(TIME_FORMAT format) const; + std::string GetTimeshiftPlayTime(TIME_FORMAT format) const; + std::string GetTimeshiftOffset(TIME_FORMAT format) const; + std::string GetTimeshiftProgressDuration(TIME_FORMAT format) const; + std::string GetTimeshiftProgressStartTime(TIME_FORMAT format) const; + std::string GetTimeshiftProgressEndTime(TIME_FORMAT format) const; + + std::string GetEpgEventDuration(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const; + std::string GetEpgEventElapsedTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const; + std::string GetEpgEventRemainingTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const; + std::string GetEpgEventFinishTime(const CPVREpgInfoTagPtr& epgTag, TIME_FORMAT format) const; + std::string GetEpgEventSeekTime(int iSeekSize, TIME_FORMAT format) const; + + // GUI info ints + int GetTimeshiftProgress() const; + int GetTimeshiftProgressDuration() const; + int GetTimeshiftProgressPlayPosition() const; + int GetTimeshiftProgressEpgStart() const; + int GetTimeshiftProgressEpgEnd() const; + int GetTimeshiftProgressBufferStart() const; + int GetTimeshiftProgressBufferEnd() const; + + int GetEpgEventDuration(const CPVREpgInfoTagPtr& epgTag) const; + int GetEpgEventProgress(const CPVREpgInfoTagPtr& epgTag) const; + + // GUI info bools + bool IsTimeshifting() const; + + private: + void UpdatePlayingTag(); + void UpdateTimeshiftData(); + void UpdateTimeshiftProgressData(); + + static std::string TimeToTimeString(time_t datetime, TIME_FORMAT format, bool withSeconds); + + int GetElapsedTime() const; + int GetRemainingTime(const CPVREpgInfoTagPtr& epgTag) const; + + mutable CCriticalSection m_critSection; + + CPVREpgInfoTagPtr m_playingEpgTag; + + time_t m_iStartTime; + unsigned int m_iDuration; + time_t m_iTimeshiftStartTime; + time_t m_iTimeshiftEndTime; + time_t m_iTimeshiftPlayTime; + unsigned int m_iTimeshiftOffset; + + time_t m_iTimeshiftProgressStartTime; + time_t m_iTimeshiftProgressEndTime; + unsigned int m_iTimeshiftProgressDuration; + }; + +} // namespace PVR diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 947ce39f2c..a26c0e0e1f 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -667,31 +667,12 @@ bool CPVRManager::IsRecordingOnPlayingChannel(void) const return currentChannel && currentChannel->IsRecording(); } -bool CPVRManager::IsTimeshifting(void) const -{ - bool bTimeshifting = false; - if (m_playingChannel) - { - const CPVRClientPtr client = GetClient(m_playingChannel->ClientID()); - if (client) - client->IsTimeshifting(bTimeshifting); - } - return bTimeshifting; -} - bool CPVRManager::CanRecordOnPlayingChannel(void) const { const CPVRChannelPtr currentChannel = GetPlayingChannel(); return currentChannel && currentChannel->CanRecord(); } -void CPVRManager::ResetPlayingTag(void) -{ - CSingleLock lock(m_critSection); - if (IsStarted() && m_guiInfo) - m_guiInfo->ResetPlayingTag(); -} - void CPVRManager::RestartParentalTimer() { if (m_parentalTimer) diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h index e5e02e30a8..a1c7094db2 100644 --- a/xbmc/pvr/PVRManager.h +++ b/xbmc/pvr/PVRManager.h @@ -192,12 +192,6 @@ namespace PVR bool IsPlayingEpgTag(const CPVREpgInfoTagPtr &epgTag) const; /*! - * @brief Check whether the currently playing livetv stream is timeshifted. - * @return True if there is a playing stream and if it is timeshifted, false otherwise. - */ - bool IsTimeshifting() const; - - /*! * @return True while the PVRManager is initialising. */ inline bool IsInitialising(void) const @@ -281,11 +275,6 @@ namespace PVR bool EpgsCreated(void) const; /*! - * @brief Reset the playing EPG tag. - */ - void ResetPlayingTag(void); - - /*! * @brief Inform PVR manager that playback of an item just started. * @param item The item that started to play. */ diff --git a/xbmc/pvr/epg/Epg.cpp b/xbmc/pvr/epg/Epg.cpp index 4e7ae97fe2..a6724421bd 100644 --- a/xbmc/pvr/epg/Epg.cpp +++ b/xbmc/pvr/epg/Epg.cpp @@ -501,13 +501,7 @@ bool CPVREpg::Update(const time_t start, const time_t end, int iUpdateTime, bool bGrabSuccess = LoadFromClients(start, end); if (bGrabSuccess) - { - CPVRChannelPtr channel(CServiceBroker::GetPVRManager().GetPlayingChannel()); - if (channel && - channel->EpgID() == m_iEpgID) - CServiceBroker::GetPVRManager().ResetPlayingTag(); m_bLoaded = true; - } else CLog::LogF(LOGERROR, "Failed to update table '%s'", Name().c_str()); diff --git a/xbmc/pvr/epg/EpgInfoTag.cpp b/xbmc/pvr/epg/EpgInfoTag.cpp index 27bf83813e..890ef7e38b 100644 --- a/xbmc/pvr/epg/EpgInfoTag.cpp +++ b/xbmc/pvr/epg/EpgInfoTag.cpp @@ -208,10 +208,9 @@ void CPVREpgInfoTag::ToSortable(SortItem& sortable, Field field) const CDateTime CPVREpgInfoTag::GetCurrentPlayingTime() const { - if (CServiceBroker::GetPVRManager().GetPlayingChannel() == Channel() && - CServiceBroker::GetPVRManager().IsTimeshifting()) + if (CServiceBroker::GetPVRManager().GetPlayingChannel() == Channel()) { - // timeshifting; start time valid? + // start time valid? time_t startTime = CServiceBroker::GetDataCacheCore().GetStartTime(); if (startTime > 0) { @@ -219,7 +218,6 @@ CDateTime CPVREpgInfoTag::GetCurrentPlayingTime() const } } - // not timeshifting return CDateTime::GetUTCDateTime(); } diff --git a/xbmc/pvr/epg/EpgInfoTag.h b/xbmc/pvr/epg/EpgInfoTag.h index 4b9560171c..56242597f5 100644 --- a/xbmc/pvr/epg/EpgInfoTag.h +++ b/xbmc/pvr/epg/EpgInfoTag.h @@ -101,7 +101,7 @@ namespace PVR int Progress(void) const; /*! - * @brief Get a pointer to the next event. Set by CPVREpg in a call to Sort() + * @brief Get a pointer to the next event. * @return A pointer to the next event or NULL if it's not set. */ CPVREpgInfoTagPtr GetNextEvent(void) const; diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index eded852e86..5c39cd1ffb 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -146,6 +146,7 @@ void CAdvancedSettings::Initialize() m_DXVAAllowHqScaling = true; m_videoFpsDetect = 1; m_maxTempo = 1.55f; + m_videoPreferStereoStream = false; m_mediacodecForceSoftwareRendering = false; @@ -348,6 +349,7 @@ void CAdvancedSettings::Initialize() m_bPVRChannelIconsAutoScan = true; m_bPVRAutoScanIconsUserSet = false; m_iPVRNumericChannelSwitchTimeout = 2000; + m_iPVRTimeshiftThreshold = 10; m_cacheMemSize = 1024 * 1024 * 20; m_cacheBufferMode = CACHE_BUFFER_MODE_INTERNET; // Default (buffer all internet streams/filesystems) @@ -677,6 +679,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) //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); + XMLUtils::GetBoolean(pElement, "preferstereostream", m_videoPreferStereoStream); // Store global display latency settings TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency"); @@ -1094,6 +1097,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) XMLUtils::GetBoolean(pPVR, "channeliconsautoscan", m_bPVRChannelIconsAutoScan); XMLUtils::GetBoolean(pPVR, "autoscaniconsuserset", m_bPVRAutoScanIconsUserSet); XMLUtils::GetInt(pPVR, "numericchannelswitchtimeout", m_iPVRNumericChannelSwitchTimeout, 50, 60000); + XMLUtils::GetInt(pPVR, "timeshiftthreshold", m_iPVRTimeshiftThreshold, 0, 60); } TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase"); diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index 0b0b027ac7..266b7d433b 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -180,6 +180,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler int m_videoFpsDetect; bool m_mediacodecForceSoftwareRendering; float m_maxTempo; + bool m_videoPreferStereoStream = false; std::string m_videoDefaultPlayer; float m_videoPlayCountMinimumPercent; @@ -323,8 +324,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler int m_iPVRInfoToggleInterval; /*!< @brief if there are more than 1 pvr gui info item available (e.g. multiple recordings active at the same time), use this toggle delay in milliseconds. defaults to 3000. */ bool m_bPVRChannelIconsAutoScan; /*!< @brief automatically scan user defined folder for channel icons when loading internal channel groups */ bool m_bPVRAutoScanIconsUserSet; /*!< @brief mark channel icons populated by auto scan as "user set" */ - int m_iPVRNumericChannelSwitchTimeout; /*!< @brief time in ms before the numeric dialog auto closes when confirmchannelswitch is disabled */ - + int m_iPVRNumericChannelSwitchTimeout; /*!< @brief time in msecs after that a channel switch occurs after entering a channel number, if confirmchannelswitch is disabled */ + int m_iPVRTimeshiftThreshold; /*!< @brief time diff between current playing time and timeshift buffer end, in seconds, before a playing stream is displayed as timeshifting. */ DatabaseSettings m_databaseMusic; // advanced music database setup DatabaseSettings m_databaseVideo; // advanced video database setup DatabaseSettings m_databaseTV; // advanced tv database setup |