diff options
30 files changed, 971 insertions, 611 deletions
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 3b4a83e04b..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"> @@ -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/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp index b1dc45a52a..638446d776 100644 --- a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp +++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp @@ -131,48 +131,19 @@ static NPT_WinsockSystem& WinsockInitializer = NPT_WinsockSystem::Initializer; #undef SetPort #endif -#ifndef TARGET_WINDOWS_STORE -#if !defined(EWOULDBLOCK) #define EWOULDBLOCK WSAEWOULDBLOCK -#endif -#if !defined(EINPROGRESS) #define EINPROGRESS WSAEINPROGRESS -#endif -#if !defined(ECONNREFUSED) #define ECONNREFUSED WSAECONNREFUSED -#endif -#if !defined(ECONNABORTED) #define ECONNABORTED WSAECONNABORTED -#endif -#if !defined(ECONNRESET) #define ECONNRESET WSAECONNRESET -#endif -#if !defined(ETIMEDOUT) #define ETIMEDOUT WSAETIMEDOUT -#endif -#if !defined(ENETRESET) #define ENETRESET WSAENETRESET -#endif -#if !defined(EADDRINUSE) #define EADDRINUSE WSAEADDRINUSE -#endif -#if !defined(ENETDOWN) #define ENETDOWN WSAENETDOWN -#endif -#if !defined(ENETUNREACH) #define ENETUNREACH WSAENETUNREACH -#endif -#if !defined(EHOSTUNREACH) -#define EHOSTUNREACH WSAEHOSTUNREACH -#endif -#if !defined(ENOTCONN) #define ENOTCONN WSAENOTCONN -#endif -#endif #if !defined(EAGAIN) #define EAGAIN WSAEWOULDBLOCK -#endif -#if !defined(EINTR) #define EINTR WSAEINTR #endif #if !defined(SHUT_RDWR) diff --git a/lib/libUPnP/patches/0045-platinum-win10-uwp-fixes.patch b/lib/libUPnP/patches/0045-platinum-win10-uwp-fixes.patch index 752c1d4301..22034321a2 100644 --- a/lib/libUPnP/patches/0045-platinum-win10-uwp-fixes.patch +++ b/lib/libUPnP/patches/0045-platinum-win10-uwp-fixes.patch @@ -4,17 +4,16 @@ Date: Fri, 2 Jun 2017 16:34:58 +0300 Subject: [PATCH] [win10] uwp fixes libUPnP --- - lib/libUPnP/CMakeLists.txt | 8 ++++-- lib/libUPnP/Neptune/Source/Core/NptConfig.h | 13 ++++++++++ lib/libUPnP/Neptune/Source/Core/NptUtils.cpp | 30 ++++++++++++++++++++++ lib/libUPnP/Neptune/Source/Core/NptUtils.h | 7 +++++ - .../Neptune/Source/System/Bsd/NptBsdSockets.cpp | 2 ++ .../Source/System/StdC/NptStdcEnvironment.cpp | 2 +- .../System/Win32/NptWin32DynamicLibraries.cpp | 4 +++ .../Source/System/Win32/NptWin32MessageQueue.cpp | 3 ++- .../Source/System/Win32/NptWin32MessageQueue.h | 3 +++ + .../Neptune/Source/System/Win32/NptWin32Queue.cpp | 6 ++--- .../Source/System/Win32/NptWin32SerialPort.cpp | 2 ++ - 10 files changed, 70 insertions(+), 4 deletions(-) + 9 files changed, 65 insertions(+), 5 deletions(-) diff --git a/lib/libUPnP/Neptune/Source/Core/NptConfig.h b/lib/libUPnP/Neptune/Source/Core/NptConfig.h index d51f67f94e..130d5cc33b 100644 @@ -121,26 +120,6 @@ index 3a06d497f4..89b2e29812 100644 +#endif + #endif // _NPT_UTILS_H_ -diff --git a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp -index ee86dbf4b0..a42dfbfb85 100644 ---- a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp -+++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp -@@ -131,6 +131,7 @@ static NPT_WinsockSystem& WinsockInitializer = NPT_WinsockSystem::Initializer; - #undef SetPort - #endif - -+#ifndef TARGET_WINDOWS_STORE - #if !defined(EWOULDBLOCK) - #define EWOULDBLOCK WSAEWOULDBLOCK - #endif -@@ -167,6 +168,7 @@ static NPT_WinsockSystem& WinsockInitializer = NPT_WinsockSystem::Initializer; - #if !defined(ENOTCONN) - #define ENOTCONN WSAENOTCONN - #endif -+#endif - #if !defined(EAGAIN) - #define EAGAIN WSAEWOULDBLOCK - #endif diff --git a/lib/libUPnP/Neptune/Source/System/StdC/NptStdcEnvironment.cpp b/lib/libUPnP/Neptune/Source/System/StdC/NptStdcEnvironment.cpp index c9f9939d2b..f700b2212b 100644 --- a/lib/libUPnP/Neptune/Source/System/StdC/NptStdcEnvironment.cpp diff --git a/lib/libUPnP/patches/0047-neptune-fix-device-discovery-on-windows.patch b/lib/libUPnP/patches/0047-neptune-fix-device-discovery-on-windows.patch new file mode 100644 index 0000000000..391ee3b302 --- /dev/null +++ b/lib/libUPnP/patches/0047-neptune-fix-device-discovery-on-windows.patch @@ -0,0 +1,49 @@ +--- a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp ++++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp +@@ -131,46 +131,19 @@ + #undef SetPort + #endif + +-#if !defined(EWOULDBLOCK) + #define EWOULDBLOCK WSAEWOULDBLOCK +-#endif +-#if !defined(EINPROGRESS) + #define EINPROGRESS WSAEINPROGRESS +-#endif +-#if !defined(ECONNREFUSED) + #define ECONNREFUSED WSAECONNREFUSED +-#endif +-#if !defined(ECONNABORTED) + #define ECONNABORTED WSAECONNABORTED +-#endif +-#if !defined(ECONNRESET) + #define ECONNRESET WSAECONNRESET +-#endif +-#if !defined(ETIMEDOUT) + #define ETIMEDOUT WSAETIMEDOUT +-#endif +-#if !defined(ENETRESET) + #define ENETRESET WSAENETRESET +-#endif +-#if !defined(EADDRINUSE) + #define EADDRINUSE WSAEADDRINUSE +-#endif +-#if !defined(ENETDOWN) + #define ENETDOWN WSAENETDOWN +-#endif +-#if !defined(ENETUNREACH) + #define ENETUNREACH WSAENETUNREACH +-#endif +-#if !defined(EHOSTUNREACH) +-#define EHOSTUNREACH WSAEHOSTUNREACH +-#endif +-#if !defined(ENOTCONN) + #define ENOTCONN WSAENOTCONN +-#endif + #if !defined(EAGAIN) + #define EAGAIN WSAEWOULDBLOCK +-#endif +-#if !defined(EINTR) + #define EINTR WSAEINTR + #endif + #if !defined(SHUT_RDWR) 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/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 e7f6cd3748..5c39cd1ffb 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -349,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) @@ -1096,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 be771cb3bb..266b7d433b 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -324,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 |