mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
xbmc: add PR3211
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
ac359292c5
commit
e51f6ba9c6
@ -0,0 +1,290 @@
|
||||
From 4bdcd85735abd6e6948f2842501d2d949f57b405 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 21 Aug 2013 23:48:56 +0100
|
||||
Subject: [PATCH] [rbp/omxplayer] Avoid too many calls to GPU
|
||||
|
||||
We currently read the media time once per packet received from demuxer to determine gpu underrun.
|
||||
We've found that TrueHD audio in particular produces ~1000 packets per second (whether it is the active track or not).
|
||||
The cost of reading media time (from gpu) is high enough that 1000 calls per second makes us fail to keep up.
|
||||
So, cache the media time, and only read it at most 50 times per second.
|
||||
---
|
||||
xbmc/cores/omxplayer/OMXPlayer.cpp | 209 +++++++++++++++++++------------------
|
||||
xbmc/cores/omxplayer/OMXPlayer.h | 2 +
|
||||
2 files changed, 110 insertions(+), 101 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp
|
||||
index 6c13e35..12122e5 100644
|
||||
--- a/xbmc/cores/omxplayer/OMXPlayer.cpp
|
||||
+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp
|
||||
@@ -474,6 +474,8 @@ void COMXSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer)
|
||||
m_stepped = false;
|
||||
m_video_fifo = 0;
|
||||
m_audio_fifo = 0;
|
||||
+ m_last_check_time = 0.0;
|
||||
+ m_stamp = 0.0;
|
||||
|
||||
memset(&m_SpeedState, 0, sizeof(m_SpeedState));
|
||||
|
||||
@@ -1114,117 +1116,121 @@ void COMXPlayer::Process()
|
||||
|
||||
while (!m_bAbortRequest)
|
||||
{
|
||||
- const bool m_Pause = m_playSpeed == DVD_PLAYSPEED_PAUSE;
|
||||
- const bool not_accepts_data = (!m_omxPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0) ||
|
||||
- (!m_omxPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0);
|
||||
- /* when the video/audio fifos are low, we pause clock, when high we resume */
|
||||
- double stamp = m_av_clock.OMXMediaTime();
|
||||
- double audio_pts = floor(m_omxPlayerAudio.GetCurrentPts());
|
||||
- double video_pts = floor(m_omxPlayerVideo.GetCurrentPts());
|
||||
-
|
||||
- float audio_fifo = audio_pts / DVD_TIME_BASE - stamp * 1e-6;
|
||||
- float video_fifo = video_pts / DVD_TIME_BASE - stamp * 1e-6;
|
||||
- float threshold = 0.1f;
|
||||
- bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false;
|
||||
-
|
||||
- // if deinterlace setting has changed, we should close and open video
|
||||
- if (current_deinterlace != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode)
|
||||
+ double now = m_clock.GetAbsoluteClock();
|
||||
+ if (m_last_check_time == 0.0 || m_last_check_time + DVD_MSEC_TO_TIME(20) <= now)
|
||||
{
|
||||
- int iStream = m_CurrentVideo.id, source = m_CurrentVideo.source;
|
||||
- CloseVideoStream(false);
|
||||
- OpenVideoStream(iStream, source);
|
||||
- if (m_State.canseek)
|
||||
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
|
||||
- current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
||||
- }
|
||||
+ m_last_check_time = now;
|
||||
+ m_stamp = m_av_clock.OMXMediaTime();
|
||||
+ const bool m_Pause = m_playSpeed == DVD_PLAYSPEED_PAUSE;
|
||||
+ const bool not_accepts_data = (!m_omxPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0) ||
|
||||
+ (!m_omxPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0);
|
||||
+ /* when the video/audio fifos are low, we pause clock, when high we resume */
|
||||
+ double audio_pts = floor(m_omxPlayerAudio.GetCurrentPts());
|
||||
+ double video_pts = floor(m_omxPlayerVideo.GetCurrentPts());
|
||||
+
|
||||
+ float audio_fifo = audio_pts / DVD_TIME_BASE - m_stamp * 1e-6;
|
||||
+ float video_fifo = video_pts / DVD_TIME_BASE - m_stamp * 1e-6;
|
||||
+ float threshold = 0.1f;
|
||||
+ bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false;
|
||||
+
|
||||
+ // if deinterlace setting has changed, we should close and open video
|
||||
+ if (current_deinterlace != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode)
|
||||
+ {
|
||||
+ int iStream = m_CurrentVideo.id, source = m_CurrentVideo.source;
|
||||
+ CloseVideoStream(false);
|
||||
+ OpenVideoStream(iStream, source);
|
||||
+ if (m_State.canseek)
|
||||
+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
|
||||
+ current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
||||
+ }
|
||||
|
||||
- m_video_fifo = (int)(100.0*(m_omxPlayerVideo.GetDecoderBufferSize()-m_omxPlayerVideo.GetDecoderFreeSpace())/m_omxPlayerVideo.GetDecoderBufferSize());
|
||||
- m_audio_fifo = (int)(100.0*audio_fifo/m_omxPlayerAudio.GetCacheTotal());
|
||||
+ m_video_fifo = (int)(100.0*(m_omxPlayerVideo.GetDecoderBufferSize()-m_omxPlayerVideo.GetDecoderFreeSpace())/m_omxPlayerVideo.GetDecoderBufferSize());
|
||||
+ m_audio_fifo = (int)(100.0*audio_fifo/m_omxPlayerAudio.GetCacheTotal());
|
||||
|
||||
- #ifdef _DEBUG
|
||||
- static unsigned count;
|
||||
- if ((count++ & 15) == 0)
|
||||
- {
|
||||
- char response[80];
|
||||
- if (m_omxPlayerVideo.GetDecoderBufferSize() && m_omxPlayerAudio.GetCacheTotal())
|
||||
- vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d",
|
||||
- m_video_fifo,
|
||||
- (int)(100.0*video_fifo/m_omxPlayerAudio.GetCacheTotal()),
|
||||
- 0, 100);
|
||||
- if (m_omxPlayerAudio.GetCacheTotal())
|
||||
- vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d",
|
||||
- m_audio_fifo,
|
||||
- (int)(100.0*m_omxPlayerAudio.GetDelay()/m_omxPlayerAudio.GetCacheTotal()),
|
||||
- 0, 100);
|
||||
- vc_gencmd(response, sizeof response, "render_bar 6 video_queue %d %d %d %d",
|
||||
- m_omxPlayerVideo.GetLevel(), 0, 0, 100);
|
||||
- vc_gencmd(response, sizeof response, "render_bar 7 audio_queue %d %d %d %d",
|
||||
- m_omxPlayerAudio.GetLevel(), 0, 0, 100);
|
||||
- }
|
||||
- #endif
|
||||
- if (audio_pts != DVD_NOPTS_VALUE)
|
||||
- {
|
||||
- audio_fifo_low = m_HasAudio && audio_fifo < threshold;
|
||||
- audio_fifo_high = audio_pts != DVD_NOPTS_VALUE && audio_fifo >= m_threshold;
|
||||
- }
|
||||
- if (video_pts != DVD_NOPTS_VALUE)
|
||||
- {
|
||||
- video_fifo_low = m_HasVideo && video_fifo < threshold;
|
||||
- video_fifo_high = video_pts != DVD_NOPTS_VALUE && video_fifo >= m_threshold;
|
||||
- }
|
||||
- if (!m_HasAudio && m_HasVideo)
|
||||
- audio_fifo_high = true;
|
||||
- if (!m_HasVideo && m_HasAudio)
|
||||
- video_fifo_high = true;
|
||||
-
|
||||
- #ifdef _DEBUG
|
||||
- CLog::Log(LOGDEBUG, "%s - M:%.6f-%.6f (A:%.6f V:%.6f) PEF:%d%d%d S:%.2f A:%.2f V:%.2f/T:%.2f (A:%d%d V:%d%d) A:%d%% V:%d%% (%.2f,%.2f)", __FUNCTION__,
|
||||
- stamp*1e-6, m_av_clock.OMXClockAdjustment()*1e-6, audio_pts*1e-6, video_pts*1e-6, m_av_clock.OMXIsPaused(), bOmxSentEOFs, not_accepts_data, m_playSpeed * (1.0f/DVD_PLAYSPEED_NORMAL),
|
||||
- audio_pts == DVD_NOPTS_VALUE ? 0.0:audio_fifo, video_pts == DVD_NOPTS_VALUE ? 0.0:video_fifo, m_threshold,
|
||||
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high,
|
||||
- m_omxPlayerAudio.GetLevel(), m_omxPlayerVideo.GetLevel(), m_omxPlayerAudio.GetDelay(), (float)m_omxPlayerAudio.GetCacheTotal());
|
||||
- #endif
|
||||
-
|
||||
- if (TP(m_playSpeed))
|
||||
- {
|
||||
- if (m_CurrentVideo.started)
|
||||
+ #ifdef _DEBUG
|
||||
+ static unsigned count;
|
||||
+ if ((count++ & 7) == 0)
|
||||
{
|
||||
- if (stamp == 0.0)
|
||||
- {
|
||||
- /* trickplay modes progress by stepping */
|
||||
- CLog::Log(LOGDEBUG, "COMXPlayer::Process - Seeking step speed:%.2f last:%.2f v:%.2f", (double)m_playSpeed / DVD_PLAYSPEED_NORMAL, m_SpeedState.lastpts*1e-6, video_pts*1e-6);
|
||||
- m_av_clock.OMXStep();
|
||||
- }
|
||||
- else
|
||||
+ char response[80];
|
||||
+ if (m_omxPlayerVideo.GetDecoderBufferSize() && m_omxPlayerAudio.GetCacheTotal())
|
||||
+ vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d",
|
||||
+ m_video_fifo,
|
||||
+ (int)(100.0*video_fifo/m_omxPlayerAudio.GetCacheTotal()),
|
||||
+ 0, 100);
|
||||
+ if (m_omxPlayerAudio.GetCacheTotal())
|
||||
+ vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d",
|
||||
+ m_audio_fifo,
|
||||
+ (int)(100.0*m_omxPlayerAudio.GetDelay()/m_omxPlayerAudio.GetCacheTotal()),
|
||||
+ 0, 100);
|
||||
+ vc_gencmd(response, sizeof response, "render_bar 6 video_queue %d %d %d %d",
|
||||
+ m_omxPlayerVideo.GetLevel(), 0, 0, 100);
|
||||
+ vc_gencmd(response, sizeof response, "render_bar 7 audio_queue %d %d %d %d",
|
||||
+ m_omxPlayerAudio.GetLevel(), 0, 0, 100);
|
||||
+ }
|
||||
+ #endif
|
||||
+ if (audio_pts != DVD_NOPTS_VALUE)
|
||||
+ {
|
||||
+ audio_fifo_low = m_HasAudio && audio_fifo < threshold;
|
||||
+ audio_fifo_high = audio_pts != DVD_NOPTS_VALUE && audio_fifo >= m_threshold;
|
||||
+ }
|
||||
+ if (video_pts != DVD_NOPTS_VALUE)
|
||||
+ {
|
||||
+ video_fifo_low = m_HasVideo && video_fifo < threshold;
|
||||
+ video_fifo_high = video_pts != DVD_NOPTS_VALUE && video_fifo >= m_threshold;
|
||||
+ }
|
||||
+ if (!m_HasAudio && m_HasVideo)
|
||||
+ audio_fifo_high = true;
|
||||
+ if (!m_HasVideo && m_HasAudio)
|
||||
+ video_fifo_high = true;
|
||||
+
|
||||
+ #ifdef _DEBUG
|
||||
+ CLog::Log(LOGDEBUG, "%s - M:%.6f-%.6f (A:%.6f V:%.6f) PEF:%d%d%d S:%.2f A:%.2f V:%.2f/T:%.2f (A:%d%d V:%d%d) A:%d%% V:%d%% (%.2f,%.2f)", __FUNCTION__,
|
||||
+ m_stamp*1e-6, m_av_clock.OMXClockAdjustment()*1e-6, audio_pts*1e-6, video_pts*1e-6, m_av_clock.OMXIsPaused(), bOmxSentEOFs, not_accepts_data, m_playSpeed * (1.0f/DVD_PLAYSPEED_NORMAL),
|
||||
+ audio_pts == DVD_NOPTS_VALUE ? 0.0:audio_fifo, video_pts == DVD_NOPTS_VALUE ? 0.0:video_fifo, m_threshold,
|
||||
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high,
|
||||
+ m_omxPlayerAudio.GetLevel(), m_omxPlayerVideo.GetLevel(), m_omxPlayerAudio.GetDelay(), (float)m_omxPlayerAudio.GetCacheTotal());
|
||||
+ #endif
|
||||
+
|
||||
+ if (TP(m_playSpeed))
|
||||
+ {
|
||||
+ if (m_CurrentVideo.started)
|
||||
{
|
||||
- m_av_clock.OMXMediaTime(0.0);
|
||||
- m_stepped = true;
|
||||
+ if (m_stamp == 0.0 && (!m_stepped || m_playSpeed > 0))
|
||||
+ {
|
||||
+ /* trickplay modes progress by stepping */
|
||||
+ CLog::Log(LOGDEBUG, "COMXPlayer::Process - Seeking step speed:%.2f last:%.2f v:%.2f", (double)m_playSpeed / DVD_PLAYSPEED_NORMAL, m_SpeedState.lastpts*1e-6, video_pts*1e-6);
|
||||
+ m_av_clock.OMXStep();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ m_av_clock.OMXMediaTime(0.0);
|
||||
+ m_last_check_time = 0.0;
|
||||
+ m_stepped = true;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- }
|
||||
- else if(!m_Pause && (bOmxSentEOFs || not_accepts_data || (audio_fifo_high && video_fifo_high)))
|
||||
- {
|
||||
- if (m_av_clock.OMXIsPaused())
|
||||
+ else if(!m_Pause && (bOmxSentEOFs || not_accepts_data || (audio_fifo_high && video_fifo_high)))
|
||||
{
|
||||
- CLog::Log(LOGDEBUG, "Resume %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
|
||||
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
|
||||
- m_av_clock.OMXStateExecute();
|
||||
- m_av_clock.OMXResume();
|
||||
+ if (m_av_clock.OMXIsPaused())
|
||||
+ {
|
||||
+ CLog::Log(LOGDEBUG, "Resume %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
|
||||
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
|
||||
+ m_av_clock.OMXStateExecute();
|
||||
+ m_av_clock.OMXResume();
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
- else if (m_Pause || audio_fifo_low || video_fifo_low)
|
||||
- {
|
||||
- if (!m_av_clock.OMXIsPaused() && !TPA(m_playSpeed))
|
||||
+ else if (m_Pause || audio_fifo_low || video_fifo_low)
|
||||
{
|
||||
- if (!m_Pause)
|
||||
- m_threshold = std::min(2.0f*m_threshold, 16.0f);
|
||||
- CLog::Log(LOGDEBUG, "Pause %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
|
||||
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
|
||||
- m_av_clock.OMXPause();
|
||||
+ if (!m_av_clock.OMXIsPaused() && !TPA(m_playSpeed))
|
||||
+ {
|
||||
+ if (!m_Pause)
|
||||
+ m_threshold = std::min(2.0f*m_threshold, 16.0f);
|
||||
+ CLog::Log(LOGDEBUG, "Pause %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
|
||||
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
|
||||
+ m_av_clock.OMXPause();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
-
|
||||
- // handle messages send to this thread, like seek or demuxer reset requests
|
||||
HandleMessages();
|
||||
|
||||
if(m_bAbortRequest)
|
||||
@@ -2294,6 +2300,7 @@ void COMXPlayer::HandleMessages()
|
||||
FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
|
||||
// mark mediatime as invalid
|
||||
m_av_clock.OMXMediaTime(0.0);
|
||||
+ m_last_check_time = 0.0;
|
||||
}
|
||||
else
|
||||
CLog::Log(LOGWARNING, "error while seeking");
|
||||
@@ -3044,7 +3051,7 @@ int64_t COMXPlayer::GetTime()
|
||||
if(offset > limit) offset = limit;
|
||||
if(offset < -limit) offset = -limit;
|
||||
}
|
||||
- //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)m_State.time, (double)m_State.timestamp, (int)DVD_TIME_TO_MSEC(m_State.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime()), (int)m_playSpeed, (int)m_caching, llrint(m_State.time + DVD_TIME_TO_MSEC(offset)));}
|
||||
+ //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)m_State.time, (double)m_State.timestamp, (int)DVD_TIME_TO_MSEC(m_State.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_stamp), (int)m_playSpeed, (int)m_caching, llrint(m_State.time + DVD_TIME_TO_MSEC(offset)));}
|
||||
return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
|
||||
}
|
||||
|
||||
@@ -4300,7 +4307,7 @@ void COMXPlayer::UpdatePlayState(double timeout)
|
||||
state.cache_bytes = 0;
|
||||
|
||||
state.timestamp = m_clock.GetAbsoluteClock();
|
||||
- //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)state.time, (double)state.timestamp, (int)DVD_TIME_TO_MSEC(state.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime()), (int)m_playSpeed, (int)m_caching, llrint(state.time + DVD_TIME_TO_MSEC(offset)));}
|
||||
+ //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)state.time, (double)state.timestamp, (int)DVD_TIME_TO_MSEC(state.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_stamp), (int)m_playSpeed, (int)m_caching, llrint(state.time + DVD_TIME_TO_MSEC(offset)));}
|
||||
|
||||
CSingleLock lock(m_StateSection);
|
||||
m_StateInput = state;
|
||||
diff --git a/xbmc/cores/omxplayer/OMXPlayer.h b/xbmc/cores/omxplayer/OMXPlayer.h
|
||||
index 6f0c148..f0e5216 100644
|
||||
--- a/xbmc/cores/omxplayer/OMXPlayer.h
|
||||
+++ b/xbmc/cores/omxplayer/OMXPlayer.h
|
||||
@@ -378,6 +378,8 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
|
||||
bool m_stepped;
|
||||
int m_video_fifo;
|
||||
int m_audio_fifo;
|
||||
+ double m_last_check_time; // we periodically check for gpu underrun
|
||||
+ double m_stamp; // last media stamp
|
||||
|
||||
CDVDOverlayContainer m_overlayContainer;
|
||||
|
||||
--
|
||||
1.8.4
|
||||
|
Loading…
x
Reference in New Issue
Block a user