diff --git a/packages/mediacenter/kodi-theme-Confluence/package.mk b/packages/mediacenter/kodi-theme-Confluence/package.mk index aa26962711..7957d79d83 100644 --- a/packages/mediacenter/kodi-theme-Confluence/package.mk +++ b/packages/mediacenter/kodi-theme-Confluence/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="kodi-theme-Confluence" -PKG_VERSION="14-34923de" +PKG_VERSION="14-af6d342" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index d4915d6c90..ed20b2f82c 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="kodi" -PKG_VERSION="14-34923de" +PKG_VERSION="14-af6d342" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch b/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch index 32385626d3..200646e5f0 100644 --- a/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch +++ b/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch @@ -1,7 +1,7 @@ -From 2d20f3215d6fe7ab66a03ff198162a3babca58d5 Mon Sep 17 00:00:00 2001 +From 809ea3eb89ef0a91faf26efd4bc82aed0b461226 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 01/21] videoplayer: adapt lateness detection and dropping to +Subject: [PATCH 01/25] videoplayer: adapt lateness detection and dropping to buffering --- @@ -643,10 +643,10 @@ index dcd0ffd..1f0e661 100644 }; -From 1250c52a4f9cab6eb74550acd4661e84ea25d0d3 Mon Sep 17 00:00:00 2001 +From b99be4f964628418dd297848f1736400d8b250d5 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 02/21] video player: present correct pts to user for a/v sync +Subject: [PATCH 02/25] video player: present correct pts to user for a/v sync (after buffering in renderer) --- @@ -695,10 +695,10 @@ index 1f0e661..a38a9c3 100644 double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */ int GetDecoderFreeSpace() { return 0; } -From 25eb4e4315be5c5bae049bb24000089c60ecd1f5 Mon Sep 17 00:00:00 2001 +From 9593b30af54cb1373fc06e3715a98774de8c147f Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 03/21] videoplayer: update frametime, it might change due to +Subject: [PATCH 03/25] videoplayer: update frametime, it might change due to fps detection --- @@ -719,10 +719,10 @@ index 374f4bd..4a255c6 100644 { m_codecname = m_pVideoCodec->GetName(); -From 8124a37001e190e74109025a1d60be30e42d3854 Mon Sep 17 00:00:00 2001 +From 47c2aa4204d69e323bb868b0bef1ec4bf388dc6f Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 04/21] videoplayer: give streams with invalid fps a chance for +Subject: [PATCH 04/25] videoplayer: give streams with invalid fps a chance for fps detection --- @@ -743,10 +743,10 @@ index 4a255c6..391d802 100644 //reset the stored framerates if no good framerate was detected m_fStableFrameRate = 0.0; -From 1837b6803d3c64d7e5a67a788e501ec4cd9d6611 Mon Sep 17 00:00:00 2001 +From d2526968c1bd8dedd3260e3438a37a571a2dc546 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 05/21] dvdplayer: allow rewinding at end of stream, do a seek +Subject: [PATCH 05/25] dvdplayer: allow rewinding at end of stream, do a seek after rewind --- @@ -754,7 +754,7 @@ Subject: [PATCH 05/21] dvdplayer: allow rewinding at end of stream, do a seek 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 73181a4..90e9a30 100644 +index 63cbe66..f5f697e 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -1793,7 +1793,7 @@ void CDVDPlayer::HandlePlaySpeed() @@ -780,10 +780,10 @@ index 73181a4..90e9a30 100644 // audioplayer, stops outputing audio to audiorendere, but still tries to // sleep an correct amount for each packet -From 5ab5287cb2328a0baea889ae09a35da4778ee05f Mon Sep 17 00:00:00 2001 +From 3e5828029247ca604cf9410c3bccbb62dca0eb98 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 06/21] dvdplayer: observe pts counter overflow +Subject: [PATCH 06/25] dvdplayer: observe pts counter overflow --- .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 197 ++++++++++++++++++++- @@ -791,7 +791,7 @@ Subject: [PATCH 06/21] dvdplayer: observe pts counter overflow 2 files changed, 199 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index b835fa8..3217fcd 100644 +index 81a511e..9626dae 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -18,7 +18,6 @@ @@ -1062,10 +1062,10 @@ index 48f0a69..bdc84b2 100644 }; -From 9196a5855f87acb79020c600566ad597f1990582 Mon Sep 17 00:00:00 2001 +From ff139f2838539f5914b7c588d711c93585d4dab2 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 07/21] dvdplayer: avoid short screen flicker caused by +Subject: [PATCH 07/25] dvdplayer: avoid short screen flicker caused by unnecessary reconfigure of renderer --- @@ -1095,10 +1095,10 @@ index 391d802..0fe775f 100644 || ( m_output.extended_format != pPicture->extended_format ) || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified -From acb0644901944e2a9760bbd5ad9f2cbb4bcc576f Mon Sep 17 00:00:00 2001 +From a7acb2ac4c76d74a7f05545b52a46a37a98c396a Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 08/21] vdpau: advanced settings for auto deinterlacing +Subject: [PATCH 08/25] vdpau: advanced settings for auto deinterlacing --- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++---- @@ -1126,10 +1126,10 @@ index e5e7970..8c353af 100644 if (deint != -1) { diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index ba97f5f..d75913e 100644 +index 3aff9f6..c92f1ce 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp -@@ -156,6 +156,8 @@ void CAdvancedSettings::Initialize() +@@ -157,6 +157,8 @@ void CAdvancedSettings::Initialize() m_videoAutoScaleMaxFps = 30.0f; m_videoDisableBackgroundDeinterlace = false; m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect @@ -1138,7 +1138,7 @@ index ba97f5f..d75913e 100644 m_videoVDPAUtelecine = false; m_videoVDPAUdeintSkipChromaHD = false; m_DXVACheckCompatibility = false; -@@ -588,6 +590,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) +@@ -590,6 +592,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); @@ -1148,7 +1148,7 @@ index ba97f5f..d75913e 100644 XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index f58142f..d35354a 100644 +index 1d9021e..1a5a28c 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -162,6 +162,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler @@ -1161,10 +1161,10 @@ index f58142f..d35354a 100644 bool m_videoVDPAUdeintSkipChromaHD; bool m_musicUseTimeSeeking; -From e531b548282a87ef399eefc1d867f91cd8a2fab0 Mon Sep 17 00:00:00 2001 +From e078b3892b2b1cb43130b67d0296b5e220cba4b9 Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 09/21] player: fix rewind +Subject: [PATCH 09/25] player: fix rewind --- xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- @@ -1212,7 +1212,7 @@ index a365821..07366df 100644 class CDVDMsgPlayerSeekChapter : public CDVDMsg diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 90e9a30..0e700f4 100644 +index f5f697e..7eb564a 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -1794,11 +1794,13 @@ void CDVDPlayer::HandlePlaySpeed() @@ -1278,7 +1278,7 @@ index 90e9a30..0e700f4 100644 +void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync) { double startpts; - if(accurate) + if(accurate && !m_omxplayer_mode) @@ -3426,19 +3430,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) if(startpts != DVD_NOPTS_VALUE) startpts -= m_offset_pts; @@ -1376,20 +1376,20 @@ index a38a9c3..4e1b3d6 100644 unsigned int m_dropRequests; }; -From 30a6db94de2121f8c933df5e1f53a5402877916f Mon Sep 17 00:00:00 2001 +From e4d7a97d16dbe8f24aece5dd4056f5d8d88f9838 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 28 Mar 2013 20:50:59 +0100 -Subject: [PATCH 10/21] fix incorrect display of fps when dr kicks in +Subject: [PATCH 10/25] fix incorrect display of fps when dr kicks in --- xbmc/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index b456d77..28339f5 100644 +index bb4342e..55c4cf4 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -2299,10 +2299,11 @@ void CApplication::Render() +@@ -2319,10 +2319,11 @@ void CApplication::Render() if (frameTime < singleFrameTime) Sleep(singleFrameTime - frameTime); } @@ -1403,20 +1403,20 @@ index b456d77..28339f5 100644 g_renderManager.UpdateResolution(); -From 52f5df248b827ba1102a8fb73a63ab57015c313f Mon Sep 17 00:00:00 2001 +From b37fc41f7df0e17fa5bc942315bf443e90c1c232 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Thu, 25 Jul 2013 17:18:13 +0200 -Subject: [PATCH 11/21] ActiveAE: slightly reduce buffer size +Subject: [PATCH 11/25] ActiveAE: slightly reduce buffer size --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 91da985..4b9cd11 100644 +index 0e4d8da..99538dc 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -32,8 +32,8 @@ using namespace ActiveAE; +@@ -33,8 +33,8 @@ using namespace ActiveAE; #include "utils/TimeUtils.h" @@ -1428,10 +1428,10 @@ index 91da985..4b9cd11 100644 void CEngineStats::Reset(unsigned int sampleRate) -From ad38713092703b739998f35313d5b2fdfcf6e88d Mon Sep 17 00:00:00 2001 +From 3286b3504f1eab59279098b847bd16caf2a9c9e2 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 4 Aug 2013 10:11:16 +0200 -Subject: [PATCH 12/21] Revert "vdpau: comment some features that will be added +Subject: [PATCH 12/25] Revert "vdpau: comment some features that will be added later" This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf. @@ -1484,10 +1484,10 @@ index 8c353af..33ec1f4 100644 m_mixersteps = 1; } -From e4a53b5d59db44951ff6432742049acdb039adfa Mon Sep 17 00:00:00 2001 +From 7f91eefdde73877dcb49f1e651f55338050ed1ce Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Tue, 28 Jan 2014 10:05:26 +0100 -Subject: [PATCH 13/21] xbmc pr 3080 +Subject: [PATCH 13/25] xbmc pr 3080 --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 8 ++++++++ @@ -1513,20 +1513,20 @@ index 2d955c2..245ef50 100644 * Setting it correctly would allow CorePNG decoding. */ avpkt.flags = AV_PKT_FLAG_KEY; -From 5ac82d336d51759b84c8df2fb8c6814713ddaf25 Mon Sep 17 00:00:00 2001 +From 58a59f432309d49f421699b5f2ed1e7b66a5d478 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Tue, 11 Feb 2014 18:15:06 +0100 -Subject: [PATCH 14/21] ActiveAE: add some debug logging +Subject: [PATCH 14/25] ActiveAE: add some debug logging --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -index 7acc0d0..fec0313 100644 +index 96bce12..7bd9c9b 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -@@ -264,7 +264,13 @@ unsigned int CActiveAEStream::AddData(uint8_t* const *data, unsigned int offset, +@@ -265,7 +265,13 @@ unsigned int CActiveAEStream::AddData(uint8_t* const *data, unsigned int offset, } } if (!m_inMsgEvent.WaitMSec(200)) @@ -1541,10 +1541,10 @@ index 7acc0d0..fec0313 100644 return copied; } -From 00046bd3f234c310f09ed5a53a29bfcbf0adfab3 Mon Sep 17 00:00:00 2001 +From 3a7699cc6b002a53738498e6a663616dac3c7bef Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 23 Aug 2014 11:42:31 +0200 -Subject: [PATCH 15/21] dvdplayer: rename codec ctrl flags +Subject: [PATCH 15/25] dvdplayer: rename codec ctrl flags --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 14 ++++++++------ @@ -1656,10 +1656,10 @@ index 6250d55..c216ce5 100644 if (iDropDirective & EOS_DROPPED) { -From a8459a22976d1f0a3fa41d23951580169ca0ce16 Mon Sep 17 00:00:00 2001 +From 8cdde771fa0ff751fa77e8abbb023c3671f4b96a Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 13 Jun 2014 14:37:16 +0200 -Subject: [PATCH 16/21] VAAPI: implement codec control flags +Subject: [PATCH 16/25] VAAPI: implement codec control flags --- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 21 ++++++++++++++++++--- @@ -1707,10 +1707,10 @@ index 67f0e80..2984847 100644 pDvdVideoPicture->pts = DVD_NOPTS_VALUE; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 8b5b5b8..84b0142 100644 +index 87e66fe..732e92b 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -733,6 +733,8 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) +@@ -739,6 +739,8 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) pic.DVDPic.color_matrix = avctx->colorspace; m_bufferStats.IncDecoded(); m_vaapiOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); @@ -1719,7 +1719,7 @@ index 8b5b5b8..84b0142 100644 } int retval = 0; -@@ -1699,8 +1701,8 @@ bool COutput::PreferPP() +@@ -1799,8 +1801,8 @@ bool COutput::PreferPP() void COutput::InitCycle() { uint64_t latency; @@ -1730,7 +1730,7 @@ index 8b5b5b8..84b0142 100644 m_config.stats->SetCanSkipDeint(false); -@@ -1708,7 +1710,8 @@ void COutput::InitCycle() +@@ -1808,7 +1810,8 @@ void COutput::InitCycle() EINTERLACEMETHOD method = CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod; bool interlaced = m_currentPicture.DVDPic.iFlags & DVP_FLAG_INTERLACED; @@ -1740,7 +1740,7 @@ index 8b5b5b8..84b0142 100644 (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) { if((method == VS_INTERLACEMETHOD_AUTO && interlaced) -@@ -2542,6 +2545,7 @@ bool CVppPostproc::AddPicture(CVaapiDecodedPicture &pic) +@@ -2626,6 +2629,7 @@ bool CVppPostproc::AddPicture(CVaapiDecodedPicture &pic) m_decodedPics.push_front(pic); m_frameCount++; m_step = 0; @@ -1748,7 +1748,7 @@ index 8b5b5b8..84b0142 100644 return true; } -@@ -2586,6 +2590,13 @@ bool CVppPostproc::Filter(CVaapiProcessedPicture &outPic) +@@ -2670,6 +2674,13 @@ bool CVppPostproc::Filter(CVaapiProcessedPicture &outPic) } outPic.DVDPic = it->DVDPic; @@ -1763,10 +1763,10 @@ index 8b5b5b8..84b0142 100644 VAProcFilterParameterBufferDeinterlacing *filterParams; VABufferID pipelineBuf; -From 1c09a6f01af923dd427d612085225547d52d46ec Mon Sep 17 00:00:00 2001 +From 41d3e4368c6e22071560a32f63e48014dd02a957 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Thu, 4 Sep 2014 09:25:48 +0200 -Subject: [PATCH 17/21] consider rounding errors in dropping control +Subject: [PATCH 17/25] consider rounding errors in dropping control --- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- @@ -1786,20 +1786,21 @@ index c216ce5..7235cb4 100644 CDroppingStats::CGain gain; gain.gain = iGain; -From 39d509822eb5868fd66e3b844f3869f77fc95a82 Mon Sep 17 00:00:00 2001 + +From 79c91b12014813c368c23fa9e81b8ae884298a97 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 4 Oct 2014 21:25:31 +0200 -Subject: [PATCH 19/21] vaapi: lock gfx context on pre-cleanup +Subject: [PATCH 19/25] vaapi: lock gfx context on pre-cleanup --- xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 84b0142..c89333b 100644 +index 732e92b..849e26a 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -612,6 +612,7 @@ long CDecoder::Release() +@@ -618,6 +618,7 @@ long CDecoder::Release() CSingleLock lock(m_DecoderSection); CLog::Log(LOGNOTICE,"VAAPI::Release pre-cleanup"); @@ -1808,597 +1809,3526 @@ index 84b0142..c89333b 100644 if (m_vaapiOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::PRECLEANUP, &reply, -From f1d71b41d302e72f41a77736b54f8e6ad6e19f3d Mon Sep 17 00:00:00 2001 +From c1352bbe96d55904d5e309861e9cf3a2f4d48ead Mon Sep 17 00:00:00 2001 From: Rainer Hochecker -Date: Tue, 7 Oct 2014 11:46:12 +0200 -Subject: [PATCH 20/21] vaapi: glIsSync, glIsTexture seem to unreliable on - Intel +Date: Wed, 15 Oct 2014 13:21:07 +0200 +Subject: [PATCH 20/25] X11: expose crtc needed by drm video sync --- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) + xbmc-xrandr.c | 4 ++-- + xbmc/windowing/X11/WinSystemX11.cpp | 23 ++++++++++++++++++++--- + xbmc/windowing/X11/WinSystemX11.h | 3 +++ + xbmc/windowing/X11/XRandR.cpp | 19 +++++++++++++++++++ + xbmc/windowing/X11/XRandR.h | 2 ++ + 5 files changed, 46 insertions(+), 5 deletions(-) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index c89333b..9c58eaa 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -1962,7 +1962,7 @@ bool COutput::ProcessSyncPicture() - #ifdef GL_ARB_sync - if (pic->usefence) - { -- if (glIsSync(pic->fence)) -+ if (pic->fence) - { - GLint state; - GLsizei length; -@@ -2115,7 +2115,7 @@ void COutput::ReleaseBufferPool(bool precleanup) - if (pic->usefence) - { - #ifdef GL_ARB_sync -- while (glIsSync(pic->fence)) -+ while (pic->fence) - { - GLint state; - GLsizei length; -@@ -2123,6 +2123,7 @@ void COutput::ReleaseBufferPool(bool precleanup) - if(state == GL_SIGNALED || timeout.IsTimePast()) - { - glDeleteSync(pic->fence); -+ pic->fence = None; - } - else - { -@@ -2148,7 +2149,8 @@ void COutput::ReleaseBufferPool(bool precleanup) - if (precleanup && pic->valid) - continue; - -- if (glIsTexture(pic->texture)) -+ -+ if (pic->texture) - { - glDeleteTextures(1, &pic->texture); - glXDestroyPixmap(m_Display, pic->glPixmap); - -From a5e5cfeb6c00d85365ada7254a9d7a21708a137e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 4 Oct 2014 13:53:35 +0200 -Subject: [PATCH 21/21] vaapi: workaround intel bugs - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 3 + - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 231 +++++++++++++++++-------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 28 ++- - 3 files changed, 189 insertions(+), 73 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 7859949..9b5d0a9 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -2541,6 +2541,9 @@ bool CLinuxRendererGL::UploadVAAPITexture(int index) - return false; +diff --git a/xbmc-xrandr.c b/xbmc-xrandr.c +index 3c686e2..7d164d0 100644 +--- a/xbmc-xrandr.c ++++ b/xbmc-xrandr.c +@@ -3005,9 +3005,9 @@ main (int argc, char **argv) + if (mode) + { + if (crtc_info) { +- printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\"", ++ printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\" crtc=\"%d\"", + crtc_info->width, crtc_info->height, +- crtc_info->x, crtc_info->y); ++ crtc_info->x, crtc_info->y, crtc->crtc.index); + } else { + printf (" w=\"%d\" h=\"%d\" x=\"%d\" y=\"%d\"", + mode->width, mode->height, output->x, output->y); +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index e5fa05a..83ad7df 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -217,10 +217,13 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + } } -+ if (!vaapi->CopyGlx()) -+ return false; -+ - plane.id = vaapi->texture; - - // in stereoscopic mode sourceRect may only -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 9c58eaa..849e26a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -417,6 +417,12 @@ bool CVideoSurfaces::HasFree() - return !m_freeSurfaces.empty(); - } - -+int CVideoSurfaces::NumFree() -+{ -+ CSingleLock lock(m_section); -+ return m_freeSurfaces.size(); -+} -+ - bool CVideoSurfaces::HasRefs() - { - CSingleLock lock(m_section); -@@ -740,7 +746,6 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) - - int retval = 0; - uint16_t decoded, processed, render; -- int vapipe; - bool vpp; - Message *msg; - while (m_vaapiOutput.m_controlPort.ReceiveInMessage(&msg)) -@@ -758,8 +763,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) - while (!retval) - { - // first fill the buffers to keep vaapi busy -- vapipe = vpp ? decoded + processed : decoded; -- if (vapipe < 4 && m_videoSurfaces.HasFree()) -+ if (decoded < 2 && processed < 3 && m_videoSurfaces.HasFree()) - { - retval |= VC_BUFFER; - } -@@ -797,8 +801,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) - msg->Release(); - } - -- vapipe = vpp ? decoded + processed : decoded; -- if (vapipe < 4 && m_videoSurfaces.HasFree()) -+ if (decoded < 2 && processed < 3 && m_videoSurfaces.HasFree()) - { - retval |= VC_BUFFER; - } -@@ -1088,6 +1091,10 @@ void CDecoder::ReturnRenderPicture(CVaapiRenderPicture *renderPic) - m_vaapiOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPIC, &renderPic, sizeof(renderPic)); - } - -+void CDecoder::ReturnProcPicture(int id) -+{ -+ m_vaapiOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPROCPIC, &id, sizeof(int)); -+} - - //----------------------------------------------------------------------------- - // RenderPicture -@@ -1129,6 +1136,69 @@ void CVaapiRenderPicture::ReturnUnused() - vaapi->ReturnRenderPicture(this); - } - -+bool CVaapiRenderPicture::CopyGlx() -+{ -+ CSingleLock lock(renderPicSection); -+ -+ if (glx.bound == true) -+ return true; -+ -+ if (glx.procPic.source == CVaapiProcessedPicture::SKIP_SRC || -+ glx.procPic.source == CVaapiProcessedPicture::VPP_SRC) +- if(m_nWidth == newWidth +- && m_nHeight == newHeight +- && m_userOutput.compare(m_currentOutput) == 0) ++ if(m_nWidth == newWidth && ++ m_nHeight == newHeight && ++ m_userOutput.compare(m_currentOutput) == 0) + { -+ unsigned int colorStandard; -+ switch(glx.procPic.DVDPic.color_matrix) ++ UpdateCrtc(); + return true; ++ } + + if (!SetWindow(newWidth, newHeight, false, m_userOutput)) + { +@@ -1232,6 +1235,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: + #endif + } + ++ UpdateCrtc(); ++ + return true; + } + +@@ -1423,4 +1428,16 @@ bool CWinSystemX11::HasWindowManager() + return true; + } + ++void CWinSystemX11::UpdateCrtc() ++{ ++ XWindowAttributes winattr; ++ int posx, posy; ++ Window child; ++ XGetWindowAttributes(m_dpy, m_mainWindow, &winattr); ++ XTranslateCoordinates(m_dpy, m_mainWindow, RootWindow(m_dpy, m_nScreen), winattr.x, winattr.y, ++ &posx, &posy, &child); ++ ++ m_crtc = g_xrandr.GetCrtc(posx+winattr.width/2, posy+winattr.height/2); ++} ++ + #endif +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 35ae99f..d156554 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -87,6 +87,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + void GetConnectedOutputs(std::vector *outputs); + bool IsCurrentOutput(CStdString output); + void RecreateWindow(); ++ int GetCrtc() { return m_crtc; } + + protected: + bool RefreshGlxContext(bool force); +@@ -118,12 +119,14 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + bool m_bIsInternalXrr; + bool m_newGlContext; + int m_MouseX, m_MouseY; ++ int m_crtc; + + private: + bool IsSuitableVisual(XVisualInfo *vInfo); + static int XErrorHandler(Display* dpy, XErrorEvent* error); + bool CreateIconPixmap(); + bool HasWindowManager(); ++ void UpdateCrtc(); + + CStopWatch m_screensaverReset; + }; +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 3102f3d..d9d7a8f 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -117,6 +117,7 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) + xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); + xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); + xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); ++ xoutput.crtc = (output->Attribute("crtc") != NULL ? atoi(output->Attribute("crtc")) : 0); + xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); + xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); + if (output->Attribute("rotation") != NULL +@@ -477,6 +478,24 @@ XOutput* CXRandR::GetOutput(CStdString outputName) + return result; + } + ++int CXRandR::GetCrtc(int x, int y) ++{ ++ int crtc = 0; ++ for (unsigned int i = 0; i < m_outputs.size(); ++i) ++ { ++ if (!m_outputs[i].isConnected) ++ continue; ++ ++ if ((m_outputs[i].x <= x && (m_outputs[i].x+m_outputs[i].w) > x) && ++ (m_outputs[i].y <= y && (m_outputs[i].y+m_outputs[i].h) > y)) + { -+ case AVCOL_SPC_BT709: -+ colorStandard = VA_SRC_BT709; -+ break; -+ case AVCOL_SPC_BT470BG: -+ case AVCOL_SPC_SMPTE170M: -+ colorStandard = VA_SRC_BT601; -+ break; -+ case AVCOL_SPC_SMPTE240M: -+ case AVCOL_SPC_FCC: -+ case AVCOL_SPC_UNSPECIFIED: -+ case AVCOL_SPC_RGB: -+ default: -+ if(texWidth > 1000) -+ colorStandard = VA_SRC_BT709; -+ else -+ colorStandard = VA_SRC_BT601; ++ crtc = m_outputs[i].crtc; ++ break; ++ } ++ } ++ return crtc; ++} ++ + CXRandR g_xrandr; + + #endif // HAS_XRANDR +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index ab7cc63..4538bad 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -84,6 +84,7 @@ class XOutput + int h; + int x; + int y; ++ int crtc; + int wmm; + int hmm; + std::vector modes; +@@ -107,6 +108,7 @@ class CXRandR + bool IsOutputConnected(CStdString name); + bool TurnOffOutput(CStdString name); + bool TurnOnOutput(CStdString name); ++ int GetCrtc(int x, int y); + //bool Has1080i(); + //bool Has1080p(); + //bool Has720p(); + +From b44f111e7ea6831b3da31776756f43d2cd922446 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sun, 19 Oct 2014 21:34:47 +0300 +Subject: [PATCH 21/25] [linux] Add FDEventMonitor for monitoring file + descriptors + +Add FDEventMonitor helper thread for monitoring file descriptors for +events (ready for read, ready for write) without the need for spawning +a separate thread with a tight loop around poll()/select(). + +FDEventMonitor uses an eventfd for signaling poll() instead of a +timeout, therefore it can sleep for long times in case of no events but +still immediately respond to e.g. shutdown. +--- + xbmc/linux/FDEventMonitor.cpp | 248 ++++++++++++++++++++++++++++++++++++++++++ + xbmc/linux/FDEventMonitor.h | 89 +++++++++++++++ + xbmc/linux/Makefile.in | 1 + + 3 files changed, 338 insertions(+) + create mode 100644 xbmc/linux/FDEventMonitor.cpp + create mode 100644 xbmc/linux/FDEventMonitor.h + +diff --git a/xbmc/linux/FDEventMonitor.cpp b/xbmc/linux/FDEventMonitor.cpp +new file mode 100644 +index 0000000..4a41477 +--- /dev/null ++++ b/xbmc/linux/FDEventMonitor.cpp +@@ -0,0 +1,248 @@ ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++#include "system.h" ++#ifdef HAS_ALSA ++ ++#include ++#include ++#include ++ ++#include "utils/log.h" ++ ++#include "FDEventMonitor.h" ++ ++CFDEventMonitor::CFDEventMonitor() : ++ CThread("FDEventMonitor"), ++ m_nextID(0), ++ m_wakeupfd(-1) ++{ ++} ++ ++CFDEventMonitor::~CFDEventMonitor() ++{ ++ CSingleLock lock(m_mutex); ++ InterruptPoll(); ++ ++ if (m_wakeupfd >= 0) ++ { ++ /* sets m_bStop */ ++ StopThread(false); ++ ++ /* wake up the poll() call */ ++ eventfd_write(m_wakeupfd, 1); ++ ++ /* Wait for the thread to stop */ ++ { ++ CSingleExit exit(m_mutex); ++ StopThread(true); + } + -+ if (vaSyncSurface(glx.vadsp, glx.procPic.videoSurface) != VA_STATUS_SUCCESS) -+ return false; ++ close(m_wakeupfd); ++ } ++} + -+ if (vaPutSurface(glx.vadsp, -+ glx.procPic.videoSurface, -+ glx.pixmap, -+ 0,0, -+ texWidth, texHeight, -+ 0,0, -+ texWidth, texHeight, -+ NULL,0, -+ VA_FRAME_PICTURE | colorStandard) != VA_STATUS_SUCCESS) ++void CFDEventMonitor::AddFD(const MonitoredFD& monitoredFD, int& id) ++{ ++ CSingleLock lock(m_mutex); ++ InterruptPoll(); ++ ++ AddFDLocked(monitoredFD, id); ++ ++ StartMonitoring(); ++} ++ ++void CFDEventMonitor::AddFDs(const std::vector& monitoredFDs, ++ std::vector& ids) ++{ ++ CSingleLock lock(m_mutex); ++ InterruptPoll(); ++ ++ for (unsigned int i = 0; i < monitoredFDs.size(); ++i) ++ { ++ int id; ++ AddFDLocked(monitoredFDs[i], id); ++ ids.push_back(id); ++ } ++ ++ StartMonitoring(); ++} ++ ++void CFDEventMonitor::RemoveFD(int id) ++{ ++ CSingleLock lock(m_mutex); ++ InterruptPoll(); ++ ++ if (m_monitoredFDs.erase(id) != 1) ++ { ++ CLog::Log(LOGERROR, "CFDEventMonitor::RemoveFD - Tried to remove non-existing monitoredFD %d", id); ++ } ++ ++ UpdatePollDescs(); ++} ++ ++void CFDEventMonitor::RemoveFDs(const std::vector& ids) ++{ ++ CSingleLock lock(m_mutex); ++ InterruptPoll(); ++ ++ for (unsigned int i = 0; i < ids.size(); ++i) ++ { ++ if (m_monitoredFDs.erase(ids[i]) != 1) + { -+ return false; ++ CLog::Log(LOGERROR, "CFDEventMonitor::RemoveFDs - Tried to remove non-existing monitoredFD %d while removing %u FDs", ids[i], (unsigned)ids.size()); ++ } ++ } ++ ++ UpdatePollDescs(); ++} ++ ++void CFDEventMonitor::Process() ++{ ++ eventfd_t dummy; ++ ++ while (!m_bStop) ++ { ++ CSingleLock lock(m_mutex); ++ CSingleLock pollLock(m_pollMutex); ++ ++ /* ++ * Leave the main mutex here to allow another thread to ++ * lock it while we are in poll(). ++ * By then calling InterruptPoll() the other thread can ++ * wake up poll and wait for the processing to pause at ++ * the above lock(m_mutex). ++ */ ++ lock.Leave(); ++ ++ int err = poll(&m_pollDescs[0], m_pollDescs.size(), -1); ++ ++ if (err < 0 && errno != EINTR) ++ { ++ CLog::Log(LOGERROR, "CFDEventMonitor::Process - poll() failed, error %d, stopping monitoring", errno); ++ StopThread(false); + } + -+ XSync(glx.x11dsp, false); -+ glEnable(glx.textureTarget); -+ glBindTexture(glx.textureTarget, texture); -+ glx.glXBindTexImageEXT(glx.x11dsp, glx.glPixmap, GLX_FRONT_LEFT_EXT, NULL); -+ glBindTexture(glx.textureTarget, 0); -+ glDisable(glx.textureTarget); ++ // Something woke us up - either there is data available or we are being ++ // paused/stopped via m_wakeupfd. + -+ glx.bound = true; ++ for (unsigned int i = 0; i < m_pollDescs.size(); ++i) ++ { ++ struct pollfd& pollDesc = m_pollDescs[i]; ++ int id = m_monitoredFDbyPollDescs[i]; ++ const MonitoredFD& monitoredFD = m_monitoredFDs[id]; + -+ vaapi->ReturnProcPicture(glx.procPic.id); -+ glx.procPic.id = -1; ++ if (pollDesc.revents) ++ { ++ if (monitoredFD.callback) ++ { ++ monitoredFD.callback(id, pollDesc.fd, pollDesc.revents, ++ monitoredFD.callbackData); ++ } ++ ++ if (pollDesc.revents & (POLLERR | POLLHUP | POLLNVAL)) ++ { ++ CLog::Log(LOGERROR, "CFDEventMonitor::Process - polled fd %d got revents 0x%x, removing it", pollDesc.fd, pollDesc.revents); ++ ++ /* Probably would be nice to inform our caller that their FD was ++ * dropped, but oh well... */ ++ m_monitoredFDs.erase(id); ++ UpdatePollDescs(); ++ } ++ ++ pollDesc.revents = 0; ++ } ++ } ++ ++ /* flush wakeup fd */ ++ eventfd_read(m_wakeupfd, &dummy); ++ ++ } ++} ++ ++void CFDEventMonitor::AddFDLocked(const MonitoredFD& monitoredFD, int& id) ++{ ++ id = m_nextID; ++ ++ while (m_monitoredFDs.count(id)) ++ { ++ ++id; ++ } ++ m_nextID = id + 1; ++ ++ m_monitoredFDs[id] = monitoredFD; ++ ++ AddPollDesc(id, monitoredFD.fd, monitoredFD.events); ++} ++ ++void CFDEventMonitor::AddPollDesc(int id, int fd, short events) ++{ ++ struct pollfd newPollFD; ++ newPollFD.fd = fd; ++ newPollFD.events = events; ++ newPollFD.revents = 0; ++ ++ m_pollDescs.push_back(newPollFD); ++ m_monitoredFDbyPollDescs.push_back(id); ++} ++ ++void CFDEventMonitor::UpdatePollDescs() ++{ ++ m_monitoredFDbyPollDescs.clear(); ++ m_pollDescs.clear(); ++ ++ for (std::map::iterator it = m_monitoredFDs.begin(); ++ it != m_monitoredFDs.end(); ++it) ++ { ++ AddPollDesc(it->first, it->second.fd, it->second.events); ++ } ++} ++ ++void CFDEventMonitor::StartMonitoring() ++{ ++ if (!IsRunning()) ++ { ++ /* Start the monitoring thread */ ++ ++ m_wakeupfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); ++ if (m_wakeupfd < 0) ++ { ++ CLog::Log(LOGERROR, "CFDEventMonitor::StartMonitoring - Failed to create eventfd, error %d", errno); ++ return; ++ } ++ ++ /* Add wakeup fd to the fd list */ ++ int id; ++ AddFDLocked(MonitoredFD(m_wakeupfd, POLLIN, NULL, NULL), id); ++ ++ Create(false); ++ } ++} ++ ++void CFDEventMonitor::InterruptPoll() ++{ ++ if (m_wakeupfd >= 0) ++ { ++ eventfd_write(m_wakeupfd, 1); ++ /* wait for the poll() result handling (if any) to end */ ++ CSingleLock pollLock(m_pollMutex); ++ } ++} ++ ++#endif +diff --git a/xbmc/linux/FDEventMonitor.h b/xbmc/linux/FDEventMonitor.h +new file mode 100644 +index 0000000..4602d12 +--- /dev/null ++++ b/xbmc/linux/FDEventMonitor.h +@@ -0,0 +1,89 @@ ++#pragma once ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#include ++#include ++ ++#include "threads/CriticalSection.h" ++#include "threads/Thread.h" ++ ++#include "utils/GlobalsHandling.h" ++ ++/** ++ * Monitor a file descriptor with callback on poll() events. ++ */ ++class CFDEventMonitor : private CThread ++{ ++public: ++ ++ typedef void (*EventCallback)(int id, int fd, short revents, void *data); ++ ++ struct MonitoredFD ++ { ++ int fd; /**< File descriptor to be monitored */ ++ short events; /**< Events to be monitored (see poll(2)) */ ++ ++ EventCallback callback; /** Callback to be called on events */ ++ void *callbackData; /** data parameter for EventCallback */ ++ ++ MonitoredFD(int fd_, short events_, EventCallback callback_, void *callbackData_) : ++ fd(fd_), events(events_), callback(callback_), callbackData(callbackData_) {} ++ MonitoredFD() : fd(-1), events(0), callback(NULL), callbackData(NULL) {} ++ }; ++ ++ CFDEventMonitor(); ++ ~CFDEventMonitor(); ++ ++ void AddFD(const MonitoredFD& monitoredFD, int& id); ++ void AddFDs(const std::vector& monitoredFDs, std::vector& ids); ++ ++ void RemoveFD(int id); ++ void RemoveFDs(const std::vector& ids); ++ ++protected: ++ virtual void Process(); ++ ++private: ++ void AddFDLocked(const MonitoredFD& monitoredFD, int& id); ++ ++ void AddPollDesc(int id, int fd, short events); ++ void UpdatePollDescs(); ++ ++ void StartMonitoring(); ++ void InterruptPoll(); ++ ++ std::map m_monitoredFDs; ++ ++ /* these are kept synchronized */ ++ std::vector m_monitoredFDbyPollDescs; ++ std::vector m_pollDescs; ++ ++ int m_nextID; ++ int m_wakeupfd; ++ ++ CCriticalSection m_mutex; ++ CCriticalSection m_pollMutex; ++}; ++ ++XBMC_GLOBAL_REF(CFDEventMonitor, g_fdEventMonitor); ++#define g_fdEventMonitor XBMC_GLOBAL_USE(CFDEventMonitor) +diff --git a/xbmc/linux/Makefile.in b/xbmc/linux/Makefile.in +index c147d8f..744fd06 100644 +--- a/xbmc/linux/Makefile.in ++++ b/xbmc/linux/Makefile.in +@@ -4,6 +4,7 @@ SRCS = ConvUtils.cpp + SRCS += DBusUtil.cpp + SRCS += DBusMessage.cpp + SRCS += DBusReserve.cpp ++SRCS += FDEventMonitor.cpp + SRCS += LinuxResourceCounter.cpp + SRCS += LinuxTimezone.cpp + SRCS += PosixMountProvider.cpp + +From 4e8ff5755b8173f5b520c0b96dc6945c7981d652 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sun, 19 Oct 2014 21:36:44 +0300 +Subject: [PATCH 22/25] [AE] ALSA: Add ALSADeviceMonitor for monitoring card + removals/additions + +--- + xbmc/cores/AudioEngine/Makefile.in | 1 + + xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 8 ++ + xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 9 ++ + .../AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp | 131 +++++++++++++++++++++ + .../AudioEngine/Sinks/alsa/ALSADeviceMonitor.h | 49 ++++++++ + 5 files changed, 198 insertions(+) + create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp + create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h + +diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in +index efb44cc..614ede2 100644 +--- a/xbmc/cores/AudioEngine/Makefile.in ++++ b/xbmc/cores/AudioEngine/Makefile.in +@@ -50,6 +50,7 @@ SRCS += Sinks/osx/CoreAudioHelpers.cpp + SRCS += Sinks/osx/CoreAudioStream.cpp + else + SRCS += Sinks/AESinkALSA.cpp ++SRCS += Sinks/alsa/ALSADeviceMonitor.cpp + SRCS += Sinks/AESinkOSS.cpp + ifeq (@USE_PULSE@,1) + SRCS += Sinks/AESinkPULSE.cpp +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +index a464b4b..c2d5758 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +@@ -1066,6 +1066,10 @@ bool CAESinkALSA::OpenPCMDevice(const std::string &name, const std::string ¶ + + void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) + { ++#if HAVE_LIBUDEV ++ m_deviceMonitor.Start(); ++#endif ++ + /* ensure that ALSA has been initialized */ + snd_lib_error_set_handler(sndLibErrorHandler); + if(!snd_config || force) +@@ -1577,4 +1581,8 @@ void CAESinkALSA::sndLibErrorHandler(const char *file, int line, const char *fun + va_end(arg); + } + ++#if HAVE_LIBUDEV ++CALSADeviceMonitor CAESinkALSA::m_deviceMonitor; // ARGH ++#endif ++ + #endif +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +index 7e05ce6..1177f41 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +@@ -24,6 +24,7 @@ + + #include "cores/AudioEngine/Interfaces/AESink.h" + #include "cores/AudioEngine/Utils/AEDeviceInfo.h" ++#include "cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h" + #include + + #define ALSA_PCM_NEW_HW_PARAMS_API +@@ -31,6 +32,10 @@ + + #include "threads/CriticalSection.h" + ++// ARGH... this is apparently needed to avoid FDEventMonitor ++// being destructed before CALSA*Monitor below. ++#include "linux/FDEventMonitor.h" ++ + class CAESinkALSA : public IAESink + { + public: +@@ -79,6 +84,10 @@ class CAESinkALSA : public IAESink + snd_pcm_t *m_pcm; + int m_timeout; + ++#if HAVE_LIBUDEV ++ static CALSADeviceMonitor m_deviceMonitor; ++#endif ++ + struct ALSAConfig + { + unsigned int sampleRate; +diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp +new file mode 100644 +index 0000000..e3269ad +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp +@@ -0,0 +1,131 @@ ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++#include "system.h" ++#if defined(HAS_ALSA) && defined(HAVE_LIBUDEV) ++ ++#include ++ ++#include "ALSADeviceMonitor.h" ++#include "AEFactory.h" ++#include "linux/FDEventMonitor.h" ++#include "utils/log.h" ++ ++CALSADeviceMonitor::CALSADeviceMonitor() : ++ m_fdMonitorId(0), ++ m_udev(NULL), ++ m_udevMonitor(NULL) ++{ ++} ++ ++CALSADeviceMonitor::~CALSADeviceMonitor() ++{ ++ Stop(); ++} ++ ++void CALSADeviceMonitor::Start() ++{ ++ int err; ++ ++ if (!m_udev) ++ { ++ m_udev = udev_new(); ++ if (!m_udev) ++ { ++ CLog::Log(LOGWARNING, "CALSADeviceMonitor::Start - Unable to open udev handle"); ++ return; ++ } ++ ++ m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev"); ++ if (!m_udevMonitor) ++ { ++ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_new_from_netlink() failed"); ++ goto err_unref_udev; ++ } ++ ++ err = udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitor, "sound", NULL); ++ if (err) ++ { ++ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_filter_add_match_subsystem_devtype() failed"); ++ goto err_unref_monitor; ++ } ++ ++ err = udev_monitor_enable_receiving(m_udevMonitor); ++ if (err) ++ { ++ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_enable_receiving() failed"); ++ goto err_unref_monitor; ++ } ++ ++ g_fdEventMonitor.AddFD( ++ CFDEventMonitor::MonitoredFD(udev_monitor_get_fd(m_udevMonitor), ++ POLLIN, FDEventCallback, m_udevMonitor), ++ m_fdMonitorId); ++ } ++ ++ return; ++ ++err_unref_monitor: ++ udev_monitor_unref(m_udevMonitor); ++ m_udevMonitor = NULL; ++err_unref_udev: ++ udev_unref(m_udev); ++ m_udev = NULL; ++} ++ ++void CALSADeviceMonitor::Stop() ++{ ++ if (m_udev) ++ { ++ g_fdEventMonitor.RemoveFD(m_fdMonitorId); ++ ++ udev_monitor_unref(m_udevMonitor); ++ m_udevMonitor = NULL; ++ udev_unref(m_udev); ++ m_udev = NULL; ++ } ++} ++ ++void CALSADeviceMonitor::FDEventCallback(int id, int fd, short revents, void *data) ++{ ++ struct udev_monitor *udevMonitor = (struct udev_monitor *)data; ++ bool audioDevicesChanged = false; ++ struct udev_device *device; ++ ++ while ((device = udev_monitor_receive_device(udevMonitor)) != NULL) ++ { ++ const char* action = udev_device_get_action(device); ++ const char* soundInitialized = udev_device_get_property_value(device, "SOUND_INITIALIZED"); ++ ++ /* cardX devices emit a "change" event when ready (i.e. all subdevices added) */ ++ if (action && soundInitialized && ++ (strcmp(action, "change") == 0 || strcmp(action, "remove") == 0)) ++ { ++ audioDevicesChanged = true; ++ } ++ udev_device_unref(device); ++ } ++ ++ if (audioDevicesChanged) ++ { ++ CAEFactory::DeviceChange(); ++ } ++} ++ ++#endif +diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h +new file mode 100644 +index 0000000..f9e2f26 +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h +@@ -0,0 +1,49 @@ ++#pragma once ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++#if defined(HAS_ALSA) && defined(HAVE_LIBUDEV) ++ ++#include ++#include ++ ++#include ++ ++class CALSADeviceMonitor ++{ ++public: ++ CALSADeviceMonitor(); ++ ~CALSADeviceMonitor(); ++ ++ void Start(); ++ void Stop(); ++ ++private: ++ static void FDEventCallback(int id, int fd, short revents, void *data); ++ ++ int m_fdMonitorId; ++ ++ struct udev *m_udev; ++ struct udev_monitor* m_udevMonitor; ++}; ++ ++#endif ++ + +From 2e9eefd989c5294e4710f3533cc59c83ffd0a77e Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sun, 19 Oct 2014 21:37:49 +0300 +Subject: [PATCH 23/25] [AE] ALSA: Add ALSADeviceMonitor for monitoring ELD + changes + +ELD changes can happen e.g. when the connected HDMI sink is changed. +--- + xbmc/cores/AudioEngine/Makefile.in | 1 + + xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 9 ++ + xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 2 + + .../AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp | 173 +++++++++++++++++++++ + .../AudioEngine/Sinks/alsa/ALSAHControlMonitor.h | 69 ++++++++ + 5 files changed, 254 insertions(+) + create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp + create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h + +diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in +index 614ede2..8f13088 100644 +--- a/xbmc/cores/AudioEngine/Makefile.in ++++ b/xbmc/cores/AudioEngine/Makefile.in +@@ -51,6 +51,7 @@ SRCS += Sinks/osx/CoreAudioStream.cpp + else + SRCS += Sinks/AESinkALSA.cpp + SRCS += Sinks/alsa/ALSADeviceMonitor.cpp ++SRCS += Sinks/alsa/ALSAHControlMonitor.cpp + SRCS += Sinks/AESinkOSS.cpp + ifeq (@USE_PULSE@,1) + SRCS += Sinks/AESinkPULSE.cpp +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +index c2d5758..f92f488 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +@@ -1083,6 +1083,8 @@ void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) + snd_config_t *config; + snd_config_copy(&config, snd_config); + ++ m_controlMonitor.Clear(); ++ + /* Always enumerate the default device. + * Note: If "default" is a stereo device, EnumerateDevice() + * will automatically add "@" instead to enable surroundXX mangling. +@@ -1160,6 +1162,8 @@ void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) + } + snd_device_name_free_hint(hints); + ++ m_controlMonitor.Start(); ++ + /* set the displayname for default device */ + if (!list.empty() && list[0].m_deviceName == "default") + { +@@ -1340,6 +1344,10 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev + { + snd_hctl_load(hctl); + bool badHDMI = false; ++ ++ /* add ELD to monitoring */ ++ m_controlMonitor.Add(strHwName, SND_CTL_ELEM_IFACE_PCM, dev, "ELD"); ++ + if (!GetELD(hctl, dev, info, badHDMI)) + CLog::Log(LOGDEBUG, "CAESinkALSA - Unable to obtain ELD information for device \"%s\" (not supported by device, or kernel older than 3.2)", + device.c_str()); +@@ -1584,5 +1592,6 @@ void CAESinkALSA::sndLibErrorHandler(const char *file, int line, const char *fun + #if HAVE_LIBUDEV + CALSADeviceMonitor CAESinkALSA::m_deviceMonitor; // ARGH + #endif ++CALSAHControlMonitor CAESinkALSA::m_controlMonitor; // ARGH + + #endif +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +index 1177f41..8be8709 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +@@ -25,6 +25,7 @@ + #include "cores/AudioEngine/Interfaces/AESink.h" + #include "cores/AudioEngine/Utils/AEDeviceInfo.h" + #include "cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h" ++#include "cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h" + #include + + #define ALSA_PCM_NEW_HW_PARAMS_API +@@ -87,6 +88,7 @@ class CAESinkALSA : public IAESink + #if HAVE_LIBUDEV + static CALSADeviceMonitor m_deviceMonitor; + #endif ++ static CALSAHControlMonitor m_controlMonitor; + + struct ALSAConfig + { +diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp +new file mode 100644 +index 0000000..9b595ee +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp +@@ -0,0 +1,173 @@ ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++#include "system.h" ++#ifdef HAS_ALSA ++ ++#include "ALSAHControlMonitor.h" ++ ++#include "AEFactory.h" ++#include "linux/FDEventMonitor.h" ++#include "utils/log.h" ++ ++CALSAHControlMonitor::CALSAHControlMonitor() ++{ ++} ++ ++CALSAHControlMonitor::~CALSAHControlMonitor() ++{ ++ Clear(); ++} ++ ++bool CALSAHControlMonitor::Add(const std::string& ctlHandleName, ++ snd_ctl_elem_iface_t interface, ++ unsigned int device, ++ const std::string& name) ++{ ++ snd_hctl_t *hctl = GetHandle(ctlHandleName); ++ ++ if (!hctl) ++ { ++ return false; ++ } ++ ++ snd_ctl_elem_id_t *id; ++ ++ snd_ctl_elem_id_alloca(&id); ++ ++ snd_ctl_elem_id_set_interface(id, interface); ++ snd_ctl_elem_id_set_name (id, name.c_str()); ++ snd_ctl_elem_id_set_device (id, device); ++ ++ snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id); ++ ++ if (!elem) ++ { ++ PutHandle(ctlHandleName); ++ return false; ++ } ++ ++ snd_hctl_elem_set_callback(elem, HCTLCallback); ++ ++ return true; ++} ++ ++void CALSAHControlMonitor::Clear() ++{ ++ Stop(); ++ ++ for (std::map::iterator it = m_ctlHandles.begin(); ++ it != m_ctlHandles.end(); ++it) ++ { ++ snd_hctl_close(it->second.handle); ++ } ++ m_ctlHandles.clear(); ++} ++ ++void CALSAHControlMonitor::Start() ++{ ++ assert(m_fdMonitorIds.size() == 0); ++ ++ std::vector pollfds; ++ std::vector monitoredFDs; ++ ++ for (std::map::iterator it = m_ctlHandles.begin(); ++ it != m_ctlHandles.end(); ++it) ++ { ++ pollfds.resize(snd_hctl_poll_descriptors_count(it->second.handle)); ++ int fdcount = snd_hctl_poll_descriptors(it->second.handle, &pollfds[0], pollfds.size()); ++ ++ for (int j = 0; j < fdcount; ++j) ++ { ++ monitoredFDs.push_back(CFDEventMonitor::MonitoredFD(pollfds[j].fd, ++ pollfds[j].events, ++ FDEventCallback, ++ it->second.handle)); ++ } ++ } ++ ++ g_fdEventMonitor.AddFDs(monitoredFDs, m_fdMonitorIds); ++} ++ ++ ++void CALSAHControlMonitor::Stop() ++{ ++ g_fdEventMonitor.RemoveFDs(m_fdMonitorIds); ++ m_fdMonitorIds.clear(); ++} ++ ++int CALSAHControlMonitor::HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask) ++{ ++ /* ++ * Currently we just re-enumerate on any change. ++ * Custom callbacks for handling other control monitoring may be implemented when needed. ++ */ ++ if (mask & SND_CTL_EVENT_MASK_VALUE) ++ { ++ CAEFactory::DeviceChange(); ++ } ++ ++ return 0; ++} ++ ++void CALSAHControlMonitor::FDEventCallback(int id, int fd, short revents, void *data) ++{ ++ /* Run ALSA event handling when the FD has events */ ++ snd_hctl_t *hctl = (snd_hctl_t *)data; ++ snd_hctl_handle_events(hctl); ++} ++ ++snd_hctl_t* CALSAHControlMonitor::GetHandle(const std::string& ctlHandleName) ++{ ++ if (!m_ctlHandles.count(ctlHandleName)) ++ { ++ snd_hctl_t *hctl; ++ ++ if (snd_hctl_open(&hctl, ctlHandleName.c_str(), 0) != 0) ++ { ++ CLog::Log(LOGWARNING, "CALSAHControlMonitor::GetHandle - snd_hctl_open() failed for \"%s\"", ctlHandleName.c_str()); ++ return NULL; ++ } ++ if (snd_hctl_load(hctl) != 0) ++ { ++ CLog::Log(LOGERROR, "CALSAHControlMonitor::GetHandle - snd_hctl_load() failed for \"%s\"", ctlHandleName.c_str()); ++ snd_hctl_close(hctl); ++ return NULL; ++ } ++ ++ snd_hctl_nonblock(hctl, 1); ++ ++ m_ctlHandles[ctlHandleName] = CTLHandle(hctl); ++ } ++ ++ m_ctlHandles[ctlHandleName].useCount++; ++ return m_ctlHandles[ctlHandleName].handle; ++} ++ ++void CALSAHControlMonitor::PutHandle(const std::string& ctlHandleName) ++{ ++ if (--m_ctlHandles[ctlHandleName].useCount == 0) ++ { ++ snd_hctl_close(m_ctlHandles[ctlHandleName].handle); ++ m_ctlHandles.erase(ctlHandleName); ++ } ++} ++ ++ ++#endif +diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h +new file mode 100644 +index 0000000..56dfd50 +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h +@@ -0,0 +1,69 @@ ++#pragma once ++/* ++ * Copyright (C) 2014 Team Kodi ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with Kodi; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++#ifdef HAS_ALSA ++ ++#include ++#include ++#include ++ ++#include ++ ++class CALSAHControlMonitor ++{ ++public: ++ CALSAHControlMonitor(); ++ ~CALSAHControlMonitor(); ++ ++ bool Add(const std::string& ctlHandleName, ++ snd_ctl_elem_iface_t interface, ++ unsigned int device, ++ const std::string& name); ++ ++ void Clear(); ++ ++ void Start(); ++ void Stop(); ++ ++private: ++ static int HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask); ++ static void FDEventCallback(int id, int fd, short revents, void *data); ++ ++ snd_hctl_t* GetHandle(const std::string& ctlHandleName); ++ void PutHandle(const std::string& ctlHandleName); ++ ++ struct CTLHandle ++ { ++ snd_hctl_t *handle; ++ int useCount; ++ ++ CTLHandle(snd_hctl_t *handle_) : handle(handle_), useCount(0) {} ++ CTLHandle() : handle(NULL), useCount(0) {} ++ }; ++ ++ std::map m_ctlHandles; ++ ++ std::vector m_fdMonitorIds; ++}; ++ ++#endif ++ + +From 1b20da8454ceeee95158aa4b1d046bb4e8e44b2d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 17 Oct 2014 08:55:16 +0200 +Subject: [PATCH 24/25] videorefclock: refactoring + +--- + Makefile.in | 1 + + project/VS2010Express/XBMC.vcxproj | 5 +- + project/VS2010Express/XBMC.vcxproj.filters | 14 +- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 5 +- + xbmc/settings/AdvancedSettings.cpp | 4 - + xbmc/settings/AdvancedSettings.h | 3 - + xbmc/video/VideoReferenceClock.cpp | 871 ++--------------------------- + xbmc/video/VideoReferenceClock.h | 90 +-- + xbmc/video/videosync/Makefile | 7 + + xbmc/video/videosync/VideoSync.h | 34 ++ + xbmc/video/videosync/VideoSyncCocoa.cpp | 40 ++ + xbmc/video/videosync/VideoSyncCocoa.h | 32 ++ + xbmc/video/videosync/VideoSyncD3D.cpp | 208 +++++++ + xbmc/video/videosync/VideoSyncD3D.h | 50 ++ + xbmc/video/videosync/VideoSyncGLX.cpp | 287 ++++++++++ + xbmc/video/videosync/VideoSyncGLX.h | 55 ++ + 16 files changed, 777 insertions(+), 929 deletions(-) + create mode 100644 xbmc/video/videosync/Makefile + create mode 100644 xbmc/video/videosync/VideoSync.h + create mode 100644 xbmc/video/videosync/VideoSyncCocoa.cpp + create mode 100644 xbmc/video/videosync/VideoSyncCocoa.h + create mode 100644 xbmc/video/videosync/VideoSyncD3D.cpp + create mode 100644 xbmc/video/videosync/VideoSyncD3D.h + create mode 100644 xbmc/video/videosync/VideoSyncGLX.cpp + create mode 100644 xbmc/video/videosync/VideoSyncGLX.h + +diff --git a/Makefile.in b/Makefile.in +index bd28e52..1ce9039 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -96,6 +96,7 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \ + xbmc/storage/storage.a \ + xbmc/utils/utils.a \ + xbmc/video/dialogs/videodialogs.a \ ++ xbmc/video/videosync/videosync.a \ + xbmc/video/video.a \ + xbmc/video/windows/videowindows.a \ + xbmc/view/view.a \ +diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj +index ed5ad2a..cb3505d 100644 +--- a/project/VS2010Express/XBMC.vcxproj ++++ b/project/VS2010Express/XBMC.vcxproj +@@ -1139,6 +1139,7 @@ + + + ++ + + + +@@ -2025,6 +2026,8 @@ + + + ++ ++ + + + +@@ -2551,4 +2554,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters +index ca16ec8..dbb9b9d 100644 +--- a/project/VS2010Express/XBMC.vcxproj.filters ++++ b/project/VS2010Express/XBMC.vcxproj.filters +@@ -319,6 +319,9 @@ + + {3adbba6a-6fbf-4192-b215-108d94bde1e0} + ++ ++ {9775d5c0-c640-4606-a625-e6cdcf9f959e} ++ + + + +@@ -3077,6 +3080,9 @@ + + filesystem + ++ ++ video\videosync ++ + + + +@@ -6022,6 +6028,12 @@ + + filesystem + ++ ++ video\videosync ++ ++ ++ video\videosync ++ + + + +@@ -6067,4 +6079,4 @@ + interfaces\swig + + +- ++ +\ No newline at end of file +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 7235cb4..c2d4b31 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -164,7 +164,7 @@ CDVDPlayerVideo::CDVDPlayerVideo( CDVDClock* pClock + CDVDPlayerVideo::~CDVDPlayerVideo() + { + StopThread(); +- g_VideoReferenceClock.StopThread(); ++ g_VideoReferenceClock.Stop(); + } + + double CDVDPlayerVideo::GetOutputDelay() +@@ -205,9 +205,6 @@ bool CDVDPlayerVideo::OpenStream( CDVDStreamInfo &hint ) + if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && !g_VideoReferenceClock.IsRunning()) + { + g_VideoReferenceClock.Create(); +- //we have to wait for the clock to start otherwise alsa can cause trouble +- if (!g_VideoReferenceClock.WaitStarted(2000)) +- CLog::Log(LOGDEBUG, "g_VideoReferenceClock didn't start in time"); + } + + if(m_messageQueue.IsInited()) +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index c92f1ce..89069a9 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -365,8 +365,6 @@ void CAdvancedSettings::Initialize() + m_bPVRAutoScanIconsUserSet = false; + m_iPVRNumericChannelSwitchTimeout = 1000; + +- m_measureRefreshrate = false; +- + m_cacheMemBufferSize = 1024 * 1024 * 20; + m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems) + // the following setting determines the readRate of a player data +@@ -1097,8 +1095,6 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) + XMLUtils::GetInt(pPVR, "numericchannelswitchtimeout", m_iPVRNumericChannelSwitchTimeout, 50, 60000); + } + +- XMLUtils::GetBoolean(pRootElement, "measurerefreshrate", m_measureRefreshrate); +- + TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase"); + if (pDatabase) + { +diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h +index 1a5a28c..eccd25c 100644 +--- a/xbmc/settings/AdvancedSettings.h ++++ b/xbmc/settings/AdvancedSettings.h +@@ -367,9 +367,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler + 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 */ + +- bool m_measureRefreshrate; //when true the videoreferenceclock will measure the refreshrate when direct3d is used +- //otherwise it will use the windows refreshrate +- + DatabaseSettings m_databaseMusic; // advanced music database setup + DatabaseSettings m_databaseVideo; // advanced video database setup + DatabaseSettings m_databaseTV; // advanced tv database setup +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index 6d84b60..cd713bc 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -26,88 +26,19 @@ + #include "utils/TimeUtils.h" + #include "utils/StringUtils.h" + #include "threads/SingleLock.h" ++#include "guilib/GraphicContext.h" ++#include "video/videosync/VideoSync.h" + +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- #include +- #include +- #include "windowing/WindowingFactory.h" +- #include "guilib/GraphicContext.h" +-#elif defined(TARGET_DARWIN_OSX) +- #include +- #include "osx/CocoaInterface.h" +-#elif defined(TARGET_DARWIN_IOS) +- #include "windowing/WindowingFactory.h" +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- #pragma comment (lib,"d3d9.lib") +- #if (D3DX_SDK_VERSION >= 42) //aug 2009 sdk and up there is no dxerr9 anymore +- #include +- #pragma comment (lib,"DxErr.lib") +- #else +- #include +- #define DXGetErrorString(hr) DXGetErrorString9(hr) +- #define DXGetErrorDescription(hr) DXGetErrorDescription9(hr) +- #pragma comment (lib,"Dxerr9.lib") +- #endif +- #include "windowing/WindowingFactory.h" +- #include "settings/AdvancedSettings.h" ++#if defined(HAS_GLX) ++#include "video/videosync/VideoSyncGLX.h" ++#endif ++#if defined(TARGET_WINDOWS) ++#include "video/videosync/VideoSyncD3D.h" + #endif + + using namespace std; + +-#if defined(TARGET_WINDOWS) && defined(HAS_DX) +- +- void CD3DCallback::Reset() +- { +- m_devicevalid = true; +- m_deviceused = false; +- } +- +- void CD3DCallback::OnDestroyDevice() +- { +- CSingleLock lock(m_critsection); +- m_devicevalid = false; +- while (m_deviceused) +- { +- lock.Leave(); +- m_releaseevent.Wait(); +- lock.Enter(); +- } +- } +- +- void CD3DCallback::OnCreateDevice() +- { +- CSingleLock lock(m_critsection); +- m_devicevalid = true; +- m_createevent.Set(); +- } +- +- void CD3DCallback::Aquire() +- { +- CSingleLock lock(m_critsection); +- while(!m_devicevalid) +- { +- lock.Leave(); +- m_createevent.Wait(); +- lock.Enter(); +- } +- m_deviceused = true; +- } +- +- void CD3DCallback::Release() +- { +- CSingleLock lock(m_critsection); +- m_deviceused = false; +- m_releaseevent.Set(); +- } +- +- bool CD3DCallback::IsValid() +- { +- return m_devicevalid; +- } +- +-#endif +- +-CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") ++CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock") + { + m_SystemFrequency = CurrentHostFrequency(); + m_ClockSpeed = 1.0; +@@ -119,34 +50,34 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") + m_CurrTime = 0; + m_LastIntTime = 0; + m_CurrTimeFract = 0.0; +- m_LastRefreshTime = 0; + m_fineadjust = 0.0; + m_RefreshRate = 0.0; +- m_PrevRefreshRate = 0; + m_MissedVblanks = 0; + m_RefreshChanged = 0; + m_VblankTime = 0; + +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- m_glXWaitVideoSyncSGI = NULL; +- m_glXGetVideoSyncSGI = NULL; +- m_Dpy = NULL; +- m_vInfo = NULL; +- m_Window = 0; +- m_Context = NULL; +-#endif ++ m_pVideoSync = NULL; + } + + CVideoReferenceClock::~CVideoReferenceClock() + { +-#if defined(HAS_GLX) +- // some ATI voodoo, if we don't close the display, we crash on exit +- if (m_Dpy) ++} ++ ++void CVideoReferenceClock::Stop() ++{ ++ CSingleExit lock(g_graphicsContext); ++ StopThread(); ++} ++ ++void CVideoReferenceClock::CBUpdateClock(int NrVBlanks, uint64_t time) ++{ + { +- XCloseDisplay(m_Dpy); +- m_Dpy = NULL; ++ CSingleLock lock(g_VideoReferenceClock.m_CritSection); ++ g_VideoReferenceClock.m_VblankTime = time; ++ g_VideoReferenceClock.UpdateClock(NrVBlanks, true); + } +-#endif ++ ++ g_VideoReferenceClock.SendVblankSignal(); + } + + void CVideoReferenceClock::Process() +@@ -154,33 +85,21 @@ void CVideoReferenceClock::Process() + bool SetupSuccess = false; + int64_t Now; + +-#if defined(TARGET_WINDOWS) && defined(HAS_DX) +- //register callback +- m_D3dCallback.Reset(); +- g_Windowing.Register(&m_D3dCallback); +-#endif +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- g_Windowing.Register(this); +- m_xrrEvent = false; +-#endif +- + while(!m_bStop) + { + //set up the vblank clock +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- SetupSuccess = SetupGLX(); +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- SetupSuccess = SetupD3D(); +-#elif defined(TARGET_DARWIN) +- SetupSuccess = SetupCocoa(); +-#elif defined(HAS_GLX) +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: compiled without RandR support"); ++#if defined(HAS_GLX) ++ m_pVideoSync = new CVideoSyncGLX(); + #elif defined(TARGET_WINDOWS) +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: only available on directx build"); +-#else +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: no implementation available"); ++ m_pVideoSync = new CVideoSyncD3D(); ++#elif defined(TARGET_DARWIN) ++ m_pVideoSync = new CVideoSyncCocoa(); + #endif + ++ SetupSuccess = m_pVideoSync->Setup(CBUpdateClock); ++ ++ UpdateRefreshrate(); ++ + CSingleLock SingleLock(m_CritSection); + Now = CurrentHostCounter(); + m_CurrTime = Now + m_ClockOffset; //add the clock offset from the previous time we stopped +@@ -190,6 +109,7 @@ void CVideoReferenceClock::Process() + m_TotalMissedVblanks = 0; + m_fineadjust = 1.0; + m_RefreshChanged = 0; ++ m_MissedVblanks = 0; + m_Started.Set(); + + if (SetupSuccess) +@@ -199,14 +119,7 @@ void CVideoReferenceClock::Process() + SingleLock.Leave(); + + //run the clock +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- RunGLX(); +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- RunD3D(); +-#elif defined(TARGET_DARWIN) +- RunCocoa(); +-#endif +- ++ m_pVideoSync->Run(m_bStop); + } + else + { +@@ -221,650 +134,13 @@ void CVideoReferenceClock::Process() + SingleLock.Leave(); + + //clean up the vblank clock +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- CleanupGLX(); +- if (m_xrrEvent) +- { +- m_releaseEvent.Set(); +- while (!m_bStop) +- { +- if (m_resetEvent.WaitMSec(100)) +- break; +- } +- m_xrrEvent = false; +- } +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- CleanupD3D(); +-#elif defined(TARGET_DARWIN) +- CleanupCocoa(); +-#endif +- if (!SetupSuccess) break; +- } +- +-#if defined(TARGET_WINDOWS) && defined(HAS_DX) +- g_Windowing.Unregister(&m_D3dCallback); +-#endif +-#if defined(HAS_GLX) +- g_Windowing.Unregister(this); +-#endif +-} +- +-bool CVideoReferenceClock::WaitStarted(int MSecs) +-{ +- //not waiting here can cause issues with alsa +- return m_Started.WaitMSec(MSecs); +-} +- +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- +-void CVideoReferenceClock::OnLostDevice() +-{ +- if (!m_xrrEvent) +- { +- m_releaseEvent.Reset(); +- m_resetEvent.Reset(); +- m_xrrEvent = true; +- m_releaseEvent.Wait(); +- } +-} +- +-void CVideoReferenceClock::OnResetDevice() +-{ +- m_xrrEvent = false; +- m_resetEvent.Set(); +-} +- +-bool CVideoReferenceClock::SetupGLX() +-{ +- int singleBufferAttributes[] = { +- GLX_RGBA, +- GLX_RED_SIZE, 0, +- GLX_GREEN_SIZE, 0, +- GLX_BLUE_SIZE, 0, +- None +- }; +- +- int ReturnV, SwaMask; +- unsigned int GlxTest; +- XSetWindowAttributes Swa; +- +- m_vInfo = NULL; +- m_Context = NULL; +- m_Window = 0; +- +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up GLX"); +- +- if (!m_Dpy) +- { +- m_Dpy = XOpenDisplay(NULL); +- if (!m_Dpy) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Unable to open display"); +- return false; +- } +- } +- +- if (!glXQueryExtension(m_Dpy, NULL, NULL)) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX"); +- return false; +- } +- +- bool ExtensionFound = false; +- istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); +- string ExtensionStr; +- +- while (!ExtensionFound) +- { +- Extensions >> ExtensionStr; +- if (Extensions.fail()) ++ m_pVideoSync->Cleanup(); ++ delete m_pVideoSync; ++ if (!SetupSuccess) + break; +- +- if (ExtensionStr == "GLX_SGI_video_sync") +- ExtensionFound = true; +- } +- +- if (!ExtensionFound) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX_SGI_video_sync"); +- return false; +- } +- +- m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); +- if (!m_vInfo) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); +- return false; +- } +- +- Swa.border_pixel = 0; +- Swa.event_mask = StructureNotifyMask; +- Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); +- SwaMask = CWBorderPixel | CWColormap | CWEventMask; +- +- m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, +- m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); +- +- m_Context = glXCreateContext(m_Dpy, m_vInfo, NULL, True); +- if (!m_Context) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXCreateContext returned NULL"); +- return false; +- } +- +- ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); +- if (ReturnV != True) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); +- return false; +- } +- +- m_glXWaitVideoSyncSGI = (int (*)(int, int, unsigned int*))glXGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI"); +- if (!m_glXWaitVideoSyncSGI) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI not found"); +- return false; +- } +- +- ReturnV = m_glXWaitVideoSyncSGI(2, 0, &GlxTest); +- if (ReturnV) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); +- return false; +- } +- +- m_glXGetVideoSyncSGI = (int (*)(unsigned int*))glXGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI"); +- if (!m_glXGetVideoSyncSGI) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI not found"); +- return false; +- } +- +- ReturnV = m_glXGetVideoSyncSGI(&GlxTest); +- if (ReturnV) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI returned %i", ReturnV); +- return false; +- } +- +- XRRSizes(m_Dpy, m_vInfo->screen, &ReturnV); +- if (ReturnV == 0) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: RandR not supported"); +- return false; +- } +- +- UpdateRefreshrate(true); //forced refreshrate update +- m_MissedVblanks = 0; +- +- return true; +-} +- +-void CVideoReferenceClock::CleanupGLX() +-{ +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up GLX"); +- +- if (m_vInfo) +- { +- XFree(m_vInfo); +- m_vInfo = NULL; +- } +- if (m_Context) +- { +- glXMakeCurrent(m_Dpy, None, NULL); +- glXDestroyContext(m_Dpy, m_Context); +- m_Context = NULL; +- } +- if (m_Window) +- { +- XDestroyWindow(m_Dpy, m_Window); +- m_Window = 0; +- } +- +- //ati saves the Display* in their libGL, if we close it here, we crash +- if (m_Dpy) +- { +- XCloseDisplay(m_Dpy); +- m_Dpy = NULL; + } + } + +-void CVideoReferenceClock::RunGLX() +-{ +- unsigned int PrevVblankCount; +- unsigned int VblankCount; +- int ReturnV; +- bool IsReset = false; +- int64_t Now; +- +- CSingleLock SingleLock(m_CritSection); +- SingleLock.Leave(); +- +- //get the current vblank counter +- m_glXGetVideoSyncSGI(&VblankCount); +- PrevVblankCount = VblankCount; +- +- while(!m_bStop) +- { +- if (m_xrrEvent) +- return; +- +- //wait for the next vblank +- ReturnV = m_glXWaitVideoSyncSGI(2, (VblankCount + 1) % 2, &VblankCount); +- m_glXGetVideoSyncSGI(&VblankCount); //the vblank count returned by glXWaitVideoSyncSGI is not always correct +- Now = CurrentHostCounter(); //get the timestamp of this vblank +- +- if(ReturnV) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); +- return; +- } +- +- if (VblankCount > PrevVblankCount) +- { +- //update the vblank timestamp, update the clock and send a signal that we got a vblank +- SingleLock.Enter(); +- m_VblankTime = Now; +- UpdateClock((int)(VblankCount - PrevVblankCount), true); +- SingleLock.Leave(); +- SendVblankSignal(); +- IsReset = false; +- } +- else +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Vblank counter has reset"); +- +- //only try reattaching once +- if (IsReset) +- return; +- +- //because of a bug in the nvidia driver, glXWaitVideoSyncSGI breaks when the vblank counter resets +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detaching glX context"); +- ReturnV = glXMakeCurrent(m_Dpy, None, NULL); +- if (ReturnV != True) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); +- return; +- } +- +- //sleep here so we don't busy spin when this constantly happens, for example when the display went to sleep +- Sleep(1000); +- +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Attaching glX context"); +- ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); +- if (ReturnV != True) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); +- return; +- } +- +- m_glXGetVideoSyncSGI(&VblankCount); +- +- IsReset = true; +- } +- PrevVblankCount = VblankCount; +- } +-} +- +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- +-void CVideoReferenceClock::RunD3D() +-{ +- D3DRASTER_STATUS RasterStatus; +- int64_t Now; +- int64_t LastVBlankTime; +- unsigned int LastLine; +- int NrVBlanks; +- double VBlankTime; +- int ReturnV; +- +- CSingleLock SingleLock(m_CritSection); +- SingleLock.Leave(); +- +- //get the scanline we're currently at +- m_D3dDev->GetRasterStatus(0, &RasterStatus); +- if (RasterStatus.InVBlank) LastLine = 0; +- else LastLine = RasterStatus.ScanLine; +- +- //init the vblanktime +- Now = CurrentHostCounter(); +- LastVBlankTime = Now; +- +- while(!m_bStop && m_D3dCallback.IsValid()) +- { +- //get the scanline we're currently at +- ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); +- if (ReturnV != D3D_OK) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", +- DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); +- return; +- } +- +- //if InVBlank is set, or the current scanline is lower than the previous scanline, a vblank happened +- if ((RasterStatus.InVBlank && LastLine > 0) || (RasterStatus.ScanLine < LastLine)) +- { +- //calculate how many vblanks happened +- Now = CurrentHostCounter() - m_SystemFrequency * RasterStatus.ScanLine / (m_Height * MathUtils::round_int(m_RefreshRate)); +- VBlankTime = (double)(Now - LastVBlankTime) / (double)m_SystemFrequency; +- NrVBlanks = MathUtils::round_int(VBlankTime * m_RefreshRate); +- +- //update the vblank timestamp, update the clock and send a signal that we got a vblank +- SingleLock.Enter(); +- m_VblankTime = Now; +- UpdateClock(NrVBlanks, true); +- SingleLock.Leave(); +- SendVblankSignal(); +- +- if (UpdateRefreshrate()) +- { +- //we have to measure the refreshrate again +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Displaymode changed"); +- return; +- } +- +- //save the timestamp of this vblank so we can calculate how many vblanks happened next time +- LastVBlankTime = Now; +- +- //because we had a vblank, sleep until half the refreshrate period +- Now = CurrentHostCounter(); +- int SleepTime = (int)((LastVBlankTime + (m_SystemFrequency / MathUtils::round_int(m_RefreshRate) / 2) - Now) * 1000 / m_SystemFrequency); +- if (SleepTime > 100) SleepTime = 100; //failsafe +- if (SleepTime > 0) ::Sleep(SleepTime); +- } +- else +- { +- ::Sleep(1); +- } +- +- if (RasterStatus.InVBlank) LastLine = 0; +- else LastLine = RasterStatus.ScanLine; +- } +-} +- +-//how many times we measure the refreshrate +-#define NRMEASURES 6 +-//how long to measure in milliseconds +-#define MEASURETIME 250 +- +-bool CVideoReferenceClock::SetupD3D() +-{ +- int ReturnV; +- +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up Direct3d"); +- +- m_D3dCallback.Aquire(); +- +- //get d3d device +- m_D3dDev = g_Windowing.Get3DDevice(); +- +- //we need a high priority thread to get accurate timing +- if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: SetThreadPriority failed"); +- +- D3DCAPS9 DevCaps; +- ReturnV = m_D3dDev->GetDeviceCaps(&DevCaps); +- if (ReturnV != D3D_OK) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDeviceCaps returned %s: %s", +- DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); +- return false; +- } +- +- if ((DevCaps.Caps & D3DCAPS_READ_SCANLINE) != D3DCAPS_READ_SCANLINE) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Hardware does not support GetRasterStatus"); +- return false; +- } +- +- D3DRASTER_STATUS RasterStatus; +- ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); +- if (ReturnV != D3D_OK) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", +- DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); +- return false; +- } +- +- D3DDISPLAYMODE DisplayMode; +- ReturnV = m_D3dDev->GetDisplayMode(0, &DisplayMode); +- if (ReturnV != D3D_OK) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetDisplayMode returned returned %s: %s", +- DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); +- return false; +- } +- +- //forced update of windows refreshrate +- UpdateRefreshrate(true); +- +- if (g_advancedSettings.m_measureRefreshrate) +- { +- //measure the refreshrate a couple times +- list Measures; +- for (int i = 0; i < NRMEASURES; i++) +- Measures.push_back(MeasureRefreshrate(MEASURETIME)); +- +- //build up a string of measured rates +- CStdString StrRates; +- for (list::iterator it = Measures.begin(); it != Measures.end(); it++) +- StrRates += StringUtils::Format("%.2f ", *it); +- +- //get the top half of the measured rates +- Measures.sort(); +- double RefreshRate = 0.0; +- int NrMeasurements = 0; +- while (NrMeasurements < NRMEASURES / 2 && !Measures.empty()) +- { +- if (Measures.back() > 0.0) +- { +- RefreshRate += Measures.back(); +- NrMeasurements++; +- } +- Measures.pop_back(); +- } +- +- if (NrMeasurements < NRMEASURES / 2) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, unable to get a good measurement", +- StrRates.c_str(), m_RefreshRate); +- return false; +- } +- +- RefreshRate /= NrMeasurements; +- m_RefreshRate = RefreshRate; +- +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: refreshrate measurements: %s, assuming %i hertz", StrRates.c_str(), m_RefreshRate); +- } +- else +- { +- m_RefreshRate = m_PrevRefreshRate; +- if (MathUtils::round_int(m_RefreshRate) == 23 || +- MathUtils::round_int(m_RefreshRate) == 29 || +- MathUtils::round_int(m_RefreshRate) == 59) +- m_RefreshRate++; +- +- if (m_Interlaced) +- { +- m_RefreshRate *= 2; +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: display is interlaced"); +- } +- +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: detected refreshrate: %i hertz, assuming %i hertz", m_PrevRefreshRate, MathUtils::round_int(m_RefreshRate)); +- } +- +- m_MissedVblanks = 0; +- +- return true; +-} +- +-double CVideoReferenceClock::MeasureRefreshrate(int MSecs) +-{ +- D3DRASTER_STATUS RasterStatus; +- int64_t Now; +- int64_t Target; +- int64_t Prev; +- int64_t AvgInterval; +- int64_t MeasureCount; +- unsigned int LastLine; +- int ReturnV; +- +- Now = CurrentHostCounter(); +- Target = Now + (m_SystemFrequency * MSecs / 1000); +- Prev = -1; +- AvgInterval = 0; +- MeasureCount = 0; +- +- //start measuring vblanks +- LastLine = 0; +- while(Now <= Target) +- { +- ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); +- Now = CurrentHostCounter(); +- if (ReturnV != D3D_OK) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: GetRasterStatus returned returned %s: %s", +- DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); +- return -1.0; +- } +- +- if ((RasterStatus.InVBlank && LastLine != 0) || (!RasterStatus.InVBlank && RasterStatus.ScanLine < LastLine)) +- { //we got a vblank +- if (Prev != -1) //need two for a measurement +- { +- AvgInterval += Now - Prev; //save how long this vblank lasted +- MeasureCount++; +- } +- Prev = Now; //save this time for the next measurement +- } +- +- //save the current scanline +- if (RasterStatus.InVBlank) +- LastLine = 0; +- else +- LastLine = RasterStatus.ScanLine; +- +- ::Sleep(1); +- } +- +- if (MeasureCount < 1) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Didn't measure any vblanks"); +- return -1.0; +- } +- +- double fRefreshRate = 1.0 / ((double)AvgInterval / (double)MeasureCount / (double)m_SystemFrequency); +- +- return fRefreshRate; +-} +- +-void CVideoReferenceClock::CleanupD3D() +-{ +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up Direct3d"); +- m_D3dCallback.Release(); +-} +- +-#elif defined(TARGET_DARWIN) +-#if defined(TARGET_DARWIN_OSX) +-// Called by the Core Video Display Link whenever it's appropriate to render a frame. +-static CVReturn DisplayLinkCallBack(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) +-{ +- double fps = 60.0; +- +- if (inNow->videoRefreshPeriod > 0) +- fps = (double)inOutputTime->videoTimeScale / (double)inOutputTime->videoRefreshPeriod; +- +- // Create an autorelease pool (necessary to call into non-Obj-C code from Obj-C code) +- void* pool = Cocoa_Create_AutoReleasePool(); +- +- CVideoReferenceClock *VideoReferenceClock = reinterpret_cast(displayLinkContext); +- VideoReferenceClock->VblankHandler(inOutputTime->hostTime, fps); +- +- // Destroy the autorelease pool +- Cocoa_Destroy_AutoReleasePool(pool); +- +- return kCVReturnSuccess; +-} +-#endif +-bool CVideoReferenceClock::SetupCocoa() +-{ +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up Cocoa"); +- +- //init the vblank timestamp +- m_LastVBlankTime = CurrentHostCounter(); +- m_MissedVblanks = 0; +- m_RefreshRate = 60; //init the refreshrate so we don't get any division by 0 errors +- +- #if defined(TARGET_DARWIN_IOS) +- { +- g_Windowing.InitDisplayLink(); +- } +- #else +- if (!Cocoa_CVDisplayLinkCreate((void*)DisplayLinkCallBack, reinterpret_cast(this))) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cocoa_CVDisplayLinkCreate failed"); +- return false; +- } +- else +- #endif +- { +- UpdateRefreshrate(true); +- return true; +- } +-} +- +-void CVideoReferenceClock::RunCocoa() +-{ +- //because cocoa has a vblank callback, we just keep sleeping until we're asked to stop the thread +- while(!m_bStop) +- { +- Sleep(1000); +- } +-} +- +-void CVideoReferenceClock::CleanupCocoa() +-{ +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up Cocoa"); +- #if defined(TARGET_DARWIN_IOS) +- g_Windowing.DeinitDisplayLink(); +- #else +- Cocoa_CVDisplayLinkRelease(); +- #endif +-} +- +-void CVideoReferenceClock::VblankHandler(int64_t nowtime, double fps) +-{ +- int NrVBlanks; +- double VBlankTime; +- int RefreshRate = MathUtils::round_int(fps); +- +- CSingleLock SingleLock(m_CritSection); +- +- if (RefreshRate != MathUtils::round_int(m_RefreshRate)) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %f hertz, rounding to %i hertz", fps, RefreshRate); +- m_RefreshRate = RefreshRate; +- } +- m_LastRefreshTime = m_CurrTime; +- +- //calculate how many vblanks happened +- VBlankTime = (double)(nowtime - m_LastVBlankTime) / (double)m_SystemFrequency; +- NrVBlanks = MathUtils::round_int(VBlankTime * m_RefreshRate); +- +- //save the timestamp of this vblank so we can calculate how many happened next time +- m_LastVBlankTime = nowtime; +- +- //update the vblank timestamp, update the clock and send a signal that we got a vblank +- m_VblankTime = nowtime; +- UpdateClock(NrVBlanks, true); +- +- SingleLock.Leave(); +- +- SendVblankSignal(); +- UpdateRefreshrate(); +-} +-#endif +- + //this is called from the vblank run function and from CVideoReferenceClock::Wait in case of a late update + void CVideoReferenceClock::UpdateClock(int NrVBlanks, bool CheckMissed) + { +@@ -979,79 +255,12 @@ double CVideoReferenceClock::GetSpeed() + return 1.0; + } + +-bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) ++void CVideoReferenceClock::UpdateRefreshrate() + { +- //if the graphicscontext signaled that the refreshrate changed, we check it about one second later +- if (m_RefreshChanged == 1 && !Forced) +- { +- m_LastRefreshTime = m_CurrTime; +- m_RefreshChanged = 2; +- return false; +- } +- +- //update the refreshrate about once a second, or update immediately if a forced update is required +- if (m_CurrTime - m_LastRefreshTime < m_SystemFrequency && !Forced) +- return false; +- +- if (Forced) +- m_LastRefreshTime = 0; +- else +- m_LastRefreshTime = m_CurrTime; +- +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- +- if (!Forced) +- m_RefreshChanged = 0; +- +- if (!Forced) //refreshrate did not change +- return false; +- + CSingleLock SingleLock(m_CritSection); +- m_RefreshRate = g_graphicsContext.GetFPS(); ++ m_RefreshRate = m_pVideoSync->GetFps(); + + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %.3f hertz", m_RefreshRate); +- +- return true; +- +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- +- D3DDISPLAYMODE DisplayMode; +- m_D3dDev->GetDisplayMode(0, &DisplayMode); +- +- //0 indicates adapter default +- if (DisplayMode.RefreshRate == 0) +- DisplayMode.RefreshRate = 60; +- +- if (m_PrevRefreshRate != DisplayMode.RefreshRate || m_Width != DisplayMode.Width || m_Height != DisplayMode.Height || +- m_Interlaced != g_Windowing.Interlaced() || Forced ) +- { +- m_PrevRefreshRate = DisplayMode.RefreshRate; +- m_Width = DisplayMode.Width; +- m_Height = DisplayMode.Height; +- m_Interlaced = g_Windowing.Interlaced(); +- return true; +- } +- +- return false; +- +-#elif defined(TARGET_DARWIN) +- #if defined(TARGET_DARWIN_IOS) +- int RefreshRate = round(g_Windowing.GetDisplayLinkFPS() + 0.5); +- #else +- int RefreshRate = MathUtils::round_int(Cocoa_GetCVDisplayLinkRefreshPeriod()); +- #endif +- +- if (RefreshRate != MathUtils::round_int(m_RefreshRate) || Forced) +- { +- CSingleLock SingleLock(m_CritSection); +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", RefreshRate); +- m_RefreshRate = RefreshRate; +- return true; +- } +- return false; +-#endif +- +- return false; + } + + //dvdplayer needs to know the refreshrate for matching the fps of the video playing to it +diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h +index 6027031..f7a3982 100644 +--- a/xbmc/video/VideoReferenceClock.h ++++ b/xbmc/video/VideoReferenceClock.h +@@ -19,47 +19,12 @@ + * + */ + +-#include "system.h" // for HAS_XRANDR, and Win32 types + #include "threads/Thread.h" + #include "threads/CriticalSection.h" + +-//TODO: get rid of #ifdef hell, abstract implementations in separate classes +- +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- #include "system_gl.h" +- #include +- #include +- #include +- #include "guilib/DispResource.h" +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- #include +- #include "guilib/D3DResource.h" +- +-class CD3DCallback : public ID3DResource +-{ +- public: +- void Reset(); +- void OnDestroyDevice(); +- void OnCreateDevice(); +- void Aquire(); +- void Release(); +- bool IsValid(); +- +- private: +- bool m_devicevalid; +- bool m_deviceused; +- +- CCriticalSection m_critsection; +- CEvent m_createevent; +- CEvent m_releaseevent; +-}; +- +-#endif ++class CVideoSync; + + class CVideoReferenceClock : public CThread +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- ,public IDispResource +-#endif + { + public: + CVideoReferenceClock(); +@@ -71,40 +36,30 @@ class CVideoReferenceClock : public CThread + double GetSpeed(); + double GetRefreshRate(double* interval = NULL); + int64_t Wait(int64_t Target); +- bool WaitStarted(int MSecs); + bool GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate); + void SetFineAdjust(double fineadjust); + void RefreshChanged() { m_RefreshChanged = 1; } +- +-#if defined(TARGET_DARWIN) +- void VblankHandler(int64_t nowtime, double fps); +-#endif +- +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- virtual void OnLostDevice(); +- virtual void OnResetDevice(); +-#endif ++ void Stop(); + + private: + void Process(); +- bool UpdateRefreshrate(bool Forced = false); ++ void UpdateRefreshrate(); + void SendVblankSignal(); + void UpdateClock(int NrVBlanks, bool CheckMissed); + double UpdateInterval(); + int64_t TimeOfNextVblank(); ++ static void CBUpdateClock(int NrVBlanks, uint64_t time); + + int64_t m_CurrTime; //the current time of the clock when using vblank as clock source + int64_t m_LastIntTime; //last interpolated clock value, to make sure the clock doesn't go backwards + double m_CurrTimeFract; //fractional part that is lost due to rounding when updating the clock + double m_ClockSpeed; //the frequency of the clock set by dvdplayer + int64_t m_ClockOffset; //the difference between the vblank clock and systemclock, set when vblank clock is stopped +- int64_t m_LastRefreshTime; //last time we updated the refreshrate + int64_t m_SystemFrequency; //frequency of the systemclock + double m_fineadjust; + + bool m_UseVblank; //set to true when vblank is used as clock source + double m_RefreshRate; //current refreshrate +- int m_PrevRefreshRate; //previous refreshrate, used for log printing and getting refreshrate from nvidia-settings + int m_MissedVblanks; //number of clock updates missed by the vblank clock + int m_RefreshChanged; //1 = we changed the refreshrate, 2 = we should check the refreshrate forced + int m_TotalMissedVblanks;//total number of clock updates missed, used by codec information screen +@@ -115,42 +70,7 @@ class CVideoReferenceClock : public CThread + + CCriticalSection m_CritSection; + +-#if defined(HAS_GLX) && defined(HAS_XRANDR) +- bool SetupGLX(); +- void RunGLX(); +- void CleanupGLX(); +- +- int (*m_glXWaitVideoSyncSGI) (int, int, unsigned int*); +- int (*m_glXGetVideoSyncSGI) (unsigned int*); +- +- Display* m_Dpy; +- XVisualInfo *m_vInfo; +- Window m_Window; +- GLXContext m_Context; +- bool m_xrrEvent; +- CEvent m_releaseEvent, m_resetEvent; +- +-#elif defined(TARGET_WINDOWS) && defined(HAS_DX) +- bool SetupD3D(); +- double MeasureRefreshrate(int MSecs); +- void RunD3D(); +- void CleanupD3D(); +- +- LPDIRECT3DDEVICE9 m_D3dDev; +- CD3DCallback m_D3dCallback; +- +- unsigned int m_Width; +- unsigned int m_Height; +- bool m_Interlaced; +- +-#elif defined(TARGET_DARWIN) +- bool SetupCocoa(); +- void RunCocoa(); +- void CleanupCocoa(); +- +- int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened +- //not the same as m_VblankTime +-#endif ++ CVideoSync *m_pVideoSync; + }; + + extern CVideoReferenceClock g_VideoReferenceClock; +diff --git a/xbmc/video/videosync/Makefile b/xbmc/video/videosync/Makefile +new file mode 100644 +index 0000000..ce74840 +--- /dev/null ++++ b/xbmc/video/videosync/Makefile +@@ -0,0 +1,7 @@ ++SRCS=VideoSyncGLX.cpp \ ++ VideoSyncCocoa.cpp \ ++ ++LIB=videosync.a ++ ++include ../../../Makefile.include ++-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +\ No newline at end of file +diff --git a/xbmc/video/videosync/VideoSync.h b/xbmc/video/videosync/VideoSync.h +new file mode 100644 +index 0000000..f87a2b5 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSync.h +@@ -0,0 +1,34 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++typedef void (*PUPDATECLOCK)(int NrVBlanks, uint64_t time); ++ ++class CVideoSync ++{ ++public: ++ virtual bool Setup(PUPDATECLOCK func) = 0; ++ virtual void Run(volatile bool& stop) = 0; ++ virtual void Cleanup() = 0; ++ virtual float GetFps() = 0; ++protected: ++ PUPDATECLOCK UpdateClock; ++ float m_fps; ++}; +diff --git a/xbmc/video/videosync/VideoSyncCocoa.cpp b/xbmc/video/videosync/VideoSyncCocoa.cpp +new file mode 100644 +index 0000000..733f32d +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncCocoa.cpp +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(TARGET_DARWIN) ++ ++bool CVideoSyncCocoa::Setup(PUPDATECLOCK func) ++{ ++ return false; ++} ++ ++void CVideoSyncCocoa::Run(volatile bool& stop) ++{ ++ ++} ++ ++void CVideoSyncCocoa::Cleanup() ++{ ++ ++} ++ ++#endif +diff --git a/xbmc/video/videosync/VideoSyncCocoa.h b/xbmc/video/videosync/VideoSyncCocoa.h +new file mode 100644 +index 0000000..5112874 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncCocoa.h +@@ -0,0 +1,32 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#if defined(TARGET_DARWIN) ++ ++class CVideoSyncCocoa : public CVideoSync ++{ ++public: ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(volatile bool& stop); ++ virtual void Cleanup(); ++}; ++ ++#endif +diff --git a/xbmc/video/videosync/VideoSyncD3D.cpp b/xbmc/video/videosync/VideoSyncD3D.cpp +new file mode 100644 +index 0000000..166635f +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncD3D.cpp +@@ -0,0 +1,208 @@ ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(TARGET_WINDOWS) ++ ++#pragma comment (lib,"d3d9.lib") ++#pragma comment (lib,"DxErr.lib") ++#include ++#include "utils/log.h" ++#include "Utils/TimeUtils.h" ++#include "Utils/MathUtils.h" ++#include "windowing\WindowingFactory.h" ++#include "video/videosync/VideoSyncD3D.h" ++#include "guilib/GraphicContext.h" ++ ++void CVideoSyncD3D::OnDestroyDevice() ++{ ++ if (!m_displayLost) ++ { ++ m_displayLost = true; ++ m_lostEvent.Wait(); ++ } ++} ++ ++void CVideoSyncD3D::OnResetDevice() ++{ ++ m_displayReset = true; ++} ++ ++bool CVideoSyncD3D::Setup(PUPDATECLOCK func) ++{ ++ int ReturnV; ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: Setting up Direct3d"); ++ CSingleLock lock(g_graphicsContext); ++ g_Windowing.Register(this); ++ m_displayLost = false; ++ m_displayReset = false; ++ m_lostEvent.Reset(); ++ UpdateClock = func; ++ ++ //get d3d device ++ m_D3dDev = g_Windowing.Get3DDevice(); ++ //we need a high priority thread to get accurate timing ++ if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: SetThreadPriority failed"); ++ ++ D3DCAPS9 DevCaps; ++ ReturnV = m_D3dDev->GetDeviceCaps(&DevCaps); ++ ++ if (ReturnV != D3D_OK) ++ { ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetDeviceCaps returned %s: %s", ++ DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); ++ return false; ++ } ++ ++ if ((DevCaps.Caps & D3DCAPS_READ_SCANLINE) != D3DCAPS_READ_SCANLINE) ++ { ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: Hardware does not support GetRasterStatus"); ++ return false; ++ } ++ ++ D3DRASTER_STATUS RasterStatus; ++ ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); ++ if (ReturnV != D3D_OK) ++ { ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetRasterStatus returned returned %s: %s", ++ DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); ++ return false; ++ } ++ ++ D3DDISPLAYMODE DisplayMode; ++ ReturnV = m_D3dDev->GetDisplayMode(0, &DisplayMode); ++ if (ReturnV != D3D_OK) ++ { ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetDisplayMode returned returned %s: %s", ++ DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); ++ return false; ++ } ++ m_height = DisplayMode.Height; ++ ++ return true; ++} ++ ++void CVideoSyncD3D::Run(volatile bool& stop) ++{ ++ D3DRASTER_STATUS RasterStatus; ++ int64_t Now; ++ int64_t LastVBlankTime; ++ unsigned int LastLine; ++ int NrVBlanks; ++ double VBlankTime; ++ int ReturnV; ++ int64_t systemFrequency = CurrentHostFrequency(); ++ ++ //get the scanline we're currently at ++ m_D3dDev->GetRasterStatus(0, &RasterStatus); ++ if (RasterStatus.InVBlank) ++ LastLine = 0; ++ else ++ LastLine = RasterStatus.ScanLine; ++ ++ //init the vblanktime ++ Now = CurrentHostCounter(); ++ LastVBlankTime = Now; ++ m_lastUpdateTime = Now - systemFrequency; ++ while (!stop && !m_displayLost && !m_displayReset) ++ { ++ //get the scanline we're currently at ++ ReturnV = m_D3dDev->GetRasterStatus(0, &RasterStatus); ++ if (ReturnV != D3D_OK) ++ { ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: GetRasterStatus returned returned %s: %s", ++ DXGetErrorString(ReturnV), DXGetErrorDescription(ReturnV)); ++ return; ++ } ++ ++ //if InVBlank is set, or the current scanline is lower than the previous scanline, a vblank happened ++ if ((RasterStatus.InVBlank && LastLine > 0) || (RasterStatus.ScanLine < LastLine)) ++ { ++ //calculate how many vblanks happened ++ Now = CurrentHostCounter() - systemFrequency * RasterStatus.ScanLine / (m_height * MathUtils::round_int(m_fps)); ++ VBlankTime = (double)(Now - LastVBlankTime) / (double)systemFrequency; ++ NrVBlanks = MathUtils::round_int(VBlankTime * m_fps); ++ //update the vblank timestamp, update the clock and send a signal that we got a vblank ++ UpdateClock(NrVBlanks, Now); ++ ++ //save the timestamp of this vblank so we can calculate how many vblanks happened next time ++ LastVBlankTime = Now; ++ //because we had a vblank, sleep until half the refreshrate period ++ Now = CurrentHostCounter(); ++ ++ if ((Now - m_lastUpdateTime) >= systemFrequency) ++ { ++ if (m_fps != GetFps()) ++ break; ++ } ++ ++ int SleepTime = (int)((LastVBlankTime + (systemFrequency / MathUtils::round_int(m_fps) / 2) - Now) * 1000 / systemFrequency); ++ if (SleepTime > 100) ++ SleepTime = 100; //failsafe ++ if (SleepTime > 0) ++ ::Sleep(SleepTime); ++ } ++ else ++ { ++ ::Sleep(1); ++ } ++ ++ if (RasterStatus.InVBlank) ++ LastLine = 0; ++ else ++ LastLine = RasterStatus.ScanLine; ++ } ++ ++ m_lostEvent.Set(); ++ while (!stop && m_displayLost && !m_displayReset) ++ { ++ Sleep(10); ++ } ++} ++ ++void CVideoSyncD3D::Cleanup() ++{ ++ CLog::Log(LOGDEBUG, "CVideoSyncD3D: Cleaning up Direct3d"); ++ CSingleLock lock(g_graphicsContext); ++ ++ m_lostEvent.Set(); ++ g_Windowing.Unregister(this); ++} ++ ++float CVideoSyncD3D::GetFps() ++{ ++ D3DDISPLAYMODE DisplayMode; ++ m_D3dDev->GetDisplayMode(0, &DisplayMode); ++ m_fps = DisplayMode.RefreshRate; ++ if (m_fps == 0) ++ m_fps = 60; ++ ++ if (m_fps == 23 || m_fps == 29 || m_fps == 59) ++ m_fps++; ++ ++ if (g_Windowing.Interlaced()) ++ { ++ m_fps *= 2; ++ } ++ return m_fps; ++} ++#endif +diff --git a/xbmc/video/videosync/VideoSyncD3D.h b/xbmc/video/videosync/VideoSyncD3D.h +new file mode 100644 +index 0000000..5ccbdd2 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncD3D.h +@@ -0,0 +1,50 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#if defined(TARGET_WINDOWS) ++ ++#include "video/videosync/VideoSync.h" ++#include ++#include "guilib/D3DResource.h" ++#include "threads/CriticalSection.h" ++#include "threads/Event.h" ++ ++class CVideoSyncD3D : public CVideoSync, ID3DResource ++{ ++public: ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(volatile bool& stop); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++ ++ virtual void OnCreateDevice() {} ++ virtual void OnDestroyDevice(); ++ virtual void OnResetDevice(); ++private: ++ LPDIRECT3DDEVICE9 m_D3dDev; ++ int m_height; ++ volatile bool m_displayLost; ++ volatile bool m_displayReset; ++ CEvent m_lostEvent; ++ int64_t m_lastUpdateTime; ++}; ++ ++#endif +diff --git a/xbmc/video/videosync/VideoSyncGLX.cpp b/xbmc/video/videosync/VideoSyncGLX.cpp +new file mode 100644 +index 0000000..fe83904 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncGLX.cpp +@@ -0,0 +1,287 @@ ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(HAS_GLX) ++ ++#include "video/videosync/VideoSyncGLX.h" ++#include ++#include ++#include "windowing/WindowingFactory.h" ++#include "guilib/GraphicContext.h" ++#include "threads/SingleLock.h" ++#include "utils/log.h" ++#include "utils/TimeUtils.h" ++#include ++ ++using namespace std; ++ ++Display* CVideoSyncGLX::m_Dpy = NULL; ++ ++void CVideoSyncGLX::OnLostDevice() ++{ ++ if (!m_displayLost) ++ { ++ m_displayLost = true; ++ m_lostEvent.Wait(); ++ } ++} ++ ++void CVideoSyncGLX::OnResetDevice() ++{ ++ m_displayReset = true; ++} ++ ++bool CVideoSyncGLX::Setup(PUPDATECLOCK func) ++{ ++ CSingleLock lock(g_graphicsContext); ++ ++ m_glXWaitVideoSyncSGI = NULL; ++ m_glXGetVideoSyncSGI = NULL; ++ m_vInfo = NULL; ++ m_Window = 0; ++ m_Context = NULL; ++ UpdateClock = func; ++ ++ int singleBufferAttributes[] = { ++ GLX_RGBA, ++ GLX_RED_SIZE, 0, ++ GLX_GREEN_SIZE, 0, ++ GLX_BLUE_SIZE, 0, ++ None ++ }; ++ ++ int ReturnV, SwaMask; ++ unsigned int GlxTest; ++ XSetWindowAttributes Swa; ++ ++ m_vInfo = NULL; ++ m_Context = NULL; ++ m_Window = 0; ++ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Setting up GLX"); ++ ++ g_Windowing.Register(this); ++ ++ m_displayLost = false; ++ m_displayReset = false; ++ m_lostEvent.Reset(); ++ ++ if (!m_Dpy) ++ { ++ m_Dpy = XOpenDisplay(NULL); ++ if (!m_Dpy) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Unable to open display"); ++ return false; ++ } ++ } ++ ++ if (!glXQueryExtension(m_Dpy, NULL, NULL)) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX"); ++ return false; ++ } ++ ++ bool ExtensionFound = false; ++ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); ++ string ExtensionStr; ++ ++ while (!ExtensionFound) ++ { ++ Extensions >> ExtensionStr; ++ if (Extensions.fail()) ++ break; ++ ++ if (ExtensionStr == "GLX_SGI_video_sync") ++ ExtensionFound = true; ++ } ++ ++ if (!ExtensionFound) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: X server does not support GLX_SGI_video_sync"); ++ return false; ++ } ++ ++ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); ++ if (!m_vInfo) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); ++ return false; ++ } ++ ++ Swa.border_pixel = 0; ++ Swa.event_mask = StructureNotifyMask; ++ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); ++ SwaMask = CWBorderPixel | CWColormap | CWEventMask; ++ ++ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, ++ m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); ++ ++ m_Context = glXCreateContext(m_Dpy, m_vInfo, NULL, True); ++ if (!m_Context) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXCreateContext returned NULL"); ++ return false; ++ } ++ ++ ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); ++ if (ReturnV != True) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); ++ return false; ++ } ++ ++ m_glXWaitVideoSyncSGI = (int (*)(int, int, unsigned int*))glXGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI"); ++ if (!m_glXWaitVideoSyncSGI) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI not found"); ++ return false; ++ } ++ ++ ReturnV = m_glXWaitVideoSyncSGI(2, 0, &GlxTest); ++ if (ReturnV) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); ++ return false; ++ } ++ ++ m_glXGetVideoSyncSGI = (int (*)(unsigned int*))glXGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI"); ++ if (!m_glXGetVideoSyncSGI) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI not found"); ++ return false; ++ } ++ ++ ReturnV = m_glXGetVideoSyncSGI(&GlxTest); ++ if (ReturnV) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXGetVideoSyncSGI returned %i", ReturnV); ++ return false; + } + + return true; +} + - void CVaapiRenderPicture::Sync() - { - #ifdef GL_ARB_sync -@@ -1143,6 +1213,15 @@ void CVaapiRenderPicture::Sync() - fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - } - #endif ++void CVideoSyncGLX::Run(volatile bool& stop) ++{ ++ unsigned int PrevVblankCount; ++ unsigned int VblankCount; ++ int ReturnV; ++ bool IsReset = false; ++ int64_t Now; + -+ if (DVDPic.format == RENDER_FMT_VAAPI && glx.bound) ++ //get the current vblank counter ++ m_glXGetVideoSyncSGI(&VblankCount); ++ PrevVblankCount = VblankCount; ++ ++ while(!stop && !m_displayLost && !m_displayReset) + { -+ glEnable(glx.textureTarget); -+ glBindTexture(glx.textureTarget, texture); -+ glx.glXReleaseTexImageEXT(glx.x11dsp, glx.glPixmap, GLX_FRONT_LEFT_EXT); -+ glBindTexture(glx.textureTarget, 0); -+ glDisable(glx.textureTarget); -+ } - } - - //----------------------------------------------------------------------------- -@@ -1274,6 +1353,11 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - pic = *((CVaapiRenderPicture**)msg->data); - QueueReturnPicture(pic); - return; -+ case COutputDataProtocol::RETURNPROCPIC: -+ int id; -+ id = *((int*)msg->data); -+ ProcessReturnProcPicture(id); -+ return; - default: - break; - } -@@ -1360,6 +1444,12 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - m_controlPort.SendInMessage(COutputControlProtocol::STATS); - m_extTimeout = 0; - return; -+ case COutputDataProtocol::RETURNPROCPIC: -+ int id; -+ id = *((int*)msg->data); -+ ProcessReturnProcPicture(id); -+ m_extTimeout = 0; -+ return; - default: - break; - } -@@ -1488,7 +1578,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - m_config.stats->DecProcessed(); - m_bufferPool.processedPics.pop_front(); - outPic = ProcessPicture(procPic); -- ReleaseProcessedPicture(procPic); -+ //ReleaseProcessedPicture(procPic); - if (outPic) - { - m_config.stats->IncRender(); -@@ -1675,8 +1765,15 @@ void COutput::Flush() - - bool COutput::HasWork() - { -- if ((!m_bufferPool.freeRenderPics.empty() && !m_bufferPool.processedPics.empty()) || -- (!m_bufferPool.decodedPics.empty() && m_bufferPool.processedPics.size() < 4)) -+ // send a pic to renderer -+ if (!m_bufferPool.freeRenderPics.empty() && !m_bufferPool.processedPics.empty()) -+ return true; ++ //wait for the next vblank ++ ReturnV = m_glXWaitVideoSyncSGI(2, (VblankCount + 1) % 2, &VblankCount); ++ m_glXGetVideoSyncSGI(&VblankCount); //the vblank count returned by glXWaitVideoSyncSGI is not always correct ++ Now = CurrentHostCounter(); //get the timestamp of this vblank + -+ bool ppWantsPic = true; -+ if (m_pp) -+ ppWantsPic = m_pp->WantsPic(); -+ -+ if (!m_bufferPool.decodedPics.empty() && m_bufferPool.processedPics.size() < 4 && ppWantsPic) - return true; - - return false; -@@ -1689,6 +1786,9 @@ bool COutput::PreferPP() - if (!m_pp) - return true; - -+ if (!m_pp->WantsPic()) -+ return false; -+ - if (!m_pp->DoesSync() && m_bufferPool.processedPics.size() < 4) - return true; - -@@ -1808,53 +1908,11 @@ CVaapiRenderPicture* COutput::ProcessPicture(CVaapiProcessedPicture &pic) - if (pic.source == CVaapiProcessedPicture::SKIP_SRC || - pic.source == CVaapiProcessedPicture::VPP_SRC) - { -- unsigned int colorStandard; -- switch(pic.DVDPic.color_matrix) -- { -- case AVCOL_SPC_BT709: -- colorStandard = VA_SRC_BT709; -- break; -- case AVCOL_SPC_BT470BG: -- case AVCOL_SPC_SMPTE170M: -- colorStandard = VA_SRC_BT601; -- break; -- case AVCOL_SPC_SMPTE240M: -- case AVCOL_SPC_FCC: -- case AVCOL_SPC_UNSPECIFIED: -- case AVCOL_SPC_RGB: -- default: -- if(m_config.surfaceWidth > 1000) -- colorStandard = VA_SRC_BT709; -- else -- colorStandard = VA_SRC_BT601; -- } -- -- if (!CheckSuccess(vaSyncSurface(m_config.dpy, pic.videoSurface))) -- return NULL; -- -- XLockDisplay(m_Display); -- if (!CheckSuccess(vaPutSurface(m_config.dpy, -- pic.videoSurface, -- retPic->pixmap, -- 0,0, -- m_config.vidWidth, m_config.vidHeight, -- 0,0, -- m_config.outWidth, m_config.outHeight, -- NULL,0, -- VA_FRAME_PICTURE | colorStandard))) -- { -- return NULL; -- } -- XUnlockDisplay(m_Display); -- -- XSync(m_config.x11dsp, false); -- glEnable(m_textureTarget); -- glBindTexture(m_textureTarget, retPic->texture); -- glXBindTexImageEXT(m_Display, retPic->glPixmap, GLX_FRONT_LEFT_EXT, NULL); -- glBindTexture(m_textureTarget, 0); -- glDisable(m_textureTarget); -- -+ pic.id = m_bufferPool.procPicId++; -+ m_bufferPool.processedPicsAway.push_back(pic); - retPic->DVDPic.format = RENDER_FMT_VAAPI; -+ retPic->glx.procPic = pic; -+ retPic->glx.bound = false; - } - else if (pic.source == CVaapiProcessedPicture::FFMPEG_SRC) - { -@@ -1917,6 +1975,18 @@ void COutput::DropVppProcessedPictures() - else - ++it; - } -+ -+ it = m_bufferPool.processedPicsAway.begin(); -+ while (it != m_bufferPool.processedPicsAway.end()) -+ { -+ if (it->source == CVaapiProcessedPicture::VPP_SRC) ++ if(ReturnV) + { -+ it = m_bufferPool.processedPicsAway.erase(it); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXWaitVideoSyncSGI returned %i", ReturnV); ++ return; ++ } ++ ++ if (VblankCount > PrevVblankCount) ++ { ++ UpdateClock((int)(VblankCount - PrevVblankCount), Now); ++ IsReset = false; + } + else -+ ++it; ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Vblank counter has reset"); ++ ++ //only try reattaching once ++ if (IsReset) ++ return; ++ ++ //because of a bug in the nvidia driver, glXWaitVideoSyncSGI breaks when the vblank counter resets ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detaching glX context"); ++ ReturnV = glXMakeCurrent(m_Dpy, None, NULL); ++ if (ReturnV != True) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); ++ return; ++ } ++ ++ //sleep here so we don't busy spin when this constantly happens, for example when the display went to sleep ++ Sleep(1000); ++ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Attaching glX context"); ++ ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context); ++ if (ReturnV != True) ++ { ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXMakeCurrent returned %i", ReturnV); ++ return; ++ } ++ ++ m_glXGetVideoSyncSGI(&VblankCount); ++ ++ IsReset = true; ++ } ++ PrevVblankCount = VblankCount; ++ } ++ m_lostEvent.Set(); ++ while(!stop && m_displayLost && !m_displayReset) ++ { ++ Sleep(10); ++ } ++} ++ ++void CVideoSyncGLX::Cleanup() ++{ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Cleaning up GLX"); ++ CSingleLock lock(g_graphicsContext); ++ ++ if (m_vInfo) ++ { ++ XFree(m_vInfo); ++ m_vInfo = NULL; ++ } ++ if (m_Context) ++ { ++ glXMakeCurrent(m_Dpy, None, NULL); ++ glXDestroyContext(m_Dpy, m_Context); ++ m_Context = NULL; ++ } ++ if (m_Window) ++ { ++ XDestroyWindow(m_Dpy, m_Window); ++ m_Window = 0; + } + - m_controlPort.SendInMessage(COutputControlProtocol::STATS); - } - -@@ -2014,16 +2084,22 @@ void COutput::ProcessReturnPicture(CVaapiRenderPicture *pic) - if (pic->avFrame) - av_frame_unref(pic->avFrame); - -- if (pic->DVDPic.format == RENDER_FMT_VAAPI) -+ ProcessReturnProcPicture(pic->glx.procPic.id); -+ pic->valid = false; ++ m_lostEvent.Set(); ++ g_Windowing.Unregister(this); +} + -+void COutput::ProcessReturnProcPicture(int id) ++float CVideoSyncGLX::GetFps() +{ -+ std::deque::iterator it; -+ for (it=m_bufferPool.processedPicsAway.begin(); it!=m_bufferPool.processedPicsAway.end(); ++it) - { -- glEnable(m_textureTarget); -- glBindTexture(m_textureTarget, pic->texture); -- glXReleaseTexImageEXT(m_Display, pic->glPixmap, GLX_FRONT_LEFT_EXT); -- glBindTexture(m_textureTarget, 0); -- glDisable(m_textureTarget); -+ if (it->id == id) -+ { -+ ReleaseProcessedPicture(*it); -+ m_bufferPool.processedPicsAway.erase(it); -+ break; -+ } - } -- -- pic->valid = false; - } - - bool COutput::EnsureBufferPool() -@@ -2069,32 +2145,39 @@ bool COutput::EnsureBufferPool() - { - pic = m_bufferPool.allRenderPics[i]; - -- pic->pixmap = XCreatePixmap(m_Display, -+ pic->glx.pixmap = XCreatePixmap(m_Display, - m_Window, - m_config.outWidth, - m_config.outHeight, - wndattribs.depth); -- if (!pic->pixmap) -+ if (!pic->glx.pixmap) - { - CLog::Log(LOGERROR, "VAAPI::COutput::EnsureBufferPool - Unable to create XPixmap"); - return false; - } - - // create gl pixmap -- pic->glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], pic->pixmap, pixmapAttribs); -+ pic->glx.glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], pic->glx.pixmap, pixmapAttribs); - -- if (!pic->glPixmap) -+ if (!pic->glx.glPixmap) - { - CLog::Log(LOGINFO, "VAAPI::COutput::EnsureBufferPool - Could not create glPixmap"); - return false; - } - - glGenTextures(1, &pic->texture); -+ pic->glx.vadsp = m_config.dpy; -+ pic->glx.x11dsp = m_Display; -+ pic->glx.glXBindTexImageEXT = glXBindTexImageEXT; -+ pic->glx.glXReleaseTexImageEXT = glXReleaseTexImageEXT; -+ pic->glx.textureTarget = m_textureTarget; - - pic->avFrame = av_frame_alloc(); - pic->valid = false; - } - -+ m_bufferPool.procPicId = 0; -+ - CLog::Log(LOGNOTICE, "VAAPI::COutput::InitBufferPool - Surfaces created"); - return true; - } -@@ -2153,8 +2236,8 @@ void COutput::ReleaseBufferPool(bool precleanup) - if (pic->texture) - { - glDeleteTextures(1, &pic->texture); -- glXDestroyPixmap(m_Display, pic->glPixmap); -- XFreePixmap(m_Display, pic->pixmap); -+ glXDestroyPixmap(m_Display, pic->glx.glPixmap); -+ XFreePixmap(m_Display, pic->glx.pixmap); - pic->texture = None; - } - av_frame_free(&pic->avFrame); -@@ -2193,7 +2276,6 @@ bool COutput::GLInit() - - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); - glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); -- - return true; - } - -@@ -2377,7 +2459,7 @@ bool CVppPostproc::PreInit(CVaapiConfig &config, SDiMethods *methods) - - // create surfaces - VASurfaceID surfaces[32]; -- int nb_surfaces = 5; -+ int nb_surfaces = NUM_RENDER_PICS; - if (!CheckSuccess(vaCreateSurfaces(m_config.dpy, - VA_RT_FORMAT_YUV420, - m_config.surfaceWidth, -@@ -2794,6 +2876,15 @@ bool CVppPostproc::DoesSync() - return false; - } - -+bool CVppPostproc::WantsPic() -+{ -+ // need at least 2 for deinterlacing -+ if (m_videoSurfaces.NumFree() > 1) -+ return true; -+ -+ return false; ++ m_fps = g_graphicsContext.GetFPS(); ++ return m_fps; +} + - bool CVppPostproc::CheckSuccess(VAStatus status) - { - if (status != VA_STATUS_SUCCESS) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index c45e97d..6b2b67a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -144,6 +144,7 @@ struct CVaapiProcessedPicture - DVDVideoPicture DVDPic; - VASurfaceID videoSurface; - AVFrame *frame; -+ int id; - enum - { - VPP_SRC, -@@ -153,6 +154,19 @@ struct CVaapiProcessedPicture - bool crop; - }; - -+struct VaapiGlx ++#endif +diff --git a/xbmc/video/videosync/VideoSyncGLX.h b/xbmc/video/videosync/VideoSyncGLX.h +new file mode 100644 +index 0000000..38d719d +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncGLX.h +@@ -0,0 +1,55 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#if defined(HAS_GLX) ++ ++#include "video/videosync/VideoSync.h" ++#include "system_gl.h" ++#include ++#include ++#include ++#include "guilib/DispResource.h" ++#include "threads/Event.h" ++ ++class CVideoSyncGLX : public CVideoSync, IDispResource +{ -+ Display *x11dsp; -+ VADisplay vadsp; -+ Pixmap pixmap; -+ GLXPixmap glPixmap; -+ GLenum textureTarget; -+ PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; -+ PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; -+ CVaapiProcessedPicture procPic; -+ bool bound; ++public: ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(volatile bool& stop); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++ virtual void OnLostDevice(); ++ virtual void OnResetDevice(); ++ ++private: ++ int (*m_glXWaitVideoSyncSGI) (int, int, unsigned int*); ++ int (*m_glXGetVideoSyncSGI) (unsigned int*); ++ ++ static Display* m_Dpy; ++ XVisualInfo *m_vInfo; ++ Window m_Window; ++ GLXContext m_Context; ++ volatile bool m_displayLost; ++ volatile bool m_displayReset; ++ CEvent m_lostEvent; +}; + - /** - * Ready to render textures - * Sent from COutput back to CDecoder -@@ -168,6 +182,7 @@ class CVaapiRenderPicture - : texWidth(0), texHeight(0), texture(None), valid(false), vaapi(NULL), avFrame(NULL), - usefence(false), refCount(0), renderPicSection(section) { fence = None; } - void Sync(); -+ bool CopyGlx(); - DVDVideoPicture DVDPic; - int texWidth, texHeight; - CRect crop; -@@ -182,8 +197,7 @@ class CVaapiRenderPicture - bool usefence; - GLsync fence; - int refCount; -- Pixmap pixmap; -- GLXPixmap glPixmap; -+ VaapiGlx glx; - CCriticalSection &renderPicSection; - }; ++#endif + +From db963725b85eb9f6bc712884678c2b1bd976f5a2 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 18 Oct 2014 11:47:02 +0200 +Subject: [PATCH 25/25] videorefclock: add video sync drm + +--- + configure.in | 3 + + xbmc/video/VideoReferenceClock.cpp | 11 +- + xbmc/video/videosync/Makefile | 1 + + xbmc/video/videosync/VideoSyncDRM.cpp | 191 ++++++++++++++++++++++++++++++++++ + xbmc/video/videosync/VideoSyncDRM.h | 46 ++++++++ + 5 files changed, 251 insertions(+), 1 deletion(-) + create mode 100644 xbmc/video/videosync/VideoSyncDRM.cpp + create mode 100644 xbmc/video/videosync/VideoSyncDRM.h + +diff --git a/configure.in b/configure.in +index d4d2fa6..a5bb1b0 100644 +--- a/configure.in ++++ b/configure.in +@@ -1333,6 +1333,9 @@ if test "$use_x11" = "yes" && test "$host_vendor" != "apple"; then + PKG_CHECK_MODULES([XEXT], [xext], + [INCLUDES="$INCLUDES $XEXT_CFLAGS"; LIBS="$LIBS $XEXT_LIBS"], + AC_MSG_ERROR($missing_library)) ++ PKG_CHECK_MODULES([DRM], [libdrm], ++ [INCLUDES="$INCLUDES $DRM_CFLAGS"; LIBS="$LIBS $DRM_LIBS"], ++ AC_MSG_ERROR($missing_library)) + AC_DEFINE([HAVE_X11], [1], [Define to 1 if you have X11 libs installed.]) + else + AC_MSG_RESULT($x11_disabled) +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index cd713bc..d50d196 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -28,10 +28,14 @@ + #include "threads/SingleLock.h" + #include "guilib/GraphicContext.h" + #include "video/videosync/VideoSync.h" ++#include "windowing/WindowingFactory.h" -@@ -204,8 +218,10 @@ struct VaapiBufferPool - std::deque freeRenderPics; - std::deque syncRenderPics; - std::deque processedPics; -+ std::deque processedPicsAway; - std::deque decodedPics; - CCriticalSection renderPicSec; -+ int procPicId; - }; - - class COutputControlProtocol : public Protocol -@@ -235,6 +251,7 @@ class COutputDataProtocol : public Protocol + #if defined(HAS_GLX) + #include "video/videosync/VideoSyncGLX.h" + #endif ++#if defined(HAVE_X11) ++#include "video/videosync/VideoSyncDRM.h" ++#endif + #if defined(TARGET_WINDOWS) + #include "video/videosync/VideoSyncD3D.h" + #endif +@@ -88,7 +92,12 @@ void CVideoReferenceClock::Process() + while(!m_bStop) { - NEWFRAME = 0, - RETURNPIC, -+ RETURNPROCPIC, - }; - enum InSignal - { -@@ -276,6 +293,7 @@ class COutput : private CThread - CVaapiRenderPicture* ProcessPicture(CVaapiProcessedPicture &pic); - void QueueReturnPicture(CVaapiRenderPicture *pic); - void ProcessReturnPicture(CVaapiRenderPicture *pic); -+ void ProcessReturnProcPicture(int id); - bool ProcessSyncPicture(); - void ReleaseProcessedPicture(CVaapiProcessedPicture &pic); - void DropVppProcessedPictures(); -@@ -332,6 +350,7 @@ class CVideoSurfaces - int Size(); - bool HasFree(); - bool HasRefs(); -+ int NumFree(); - protected: - std::map m_state; - std::list m_freeSurfaces; -@@ -393,7 +412,7 @@ class CDecoder - virtual void Close(); - virtual long Release(); - virtual bool CanSkipDeint(); -- virtual unsigned GetAllowedReferences() { return 5; } -+ virtual unsigned GetAllowedReferences() { return 4; } + //set up the vblank clock +-#if defined(HAS_GLX) ++#if defined(HAVE_X11) ++ std::string gpuvendor = g_Windowing.GetRenderVendor(); ++ std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower); ++ if (gpuvendor.compare(0, 5, "intel") == 0) ++ m_pVideoSync = new CVideoSyncDRM(); ++ else + m_pVideoSync = new CVideoSyncGLX(); + #elif defined(TARGET_WINDOWS) + m_pVideoSync = new CVideoSyncD3D(); +diff --git a/xbmc/video/videosync/Makefile b/xbmc/video/videosync/Makefile +index ce74840..ff4aecb 100644 +--- a/xbmc/video/videosync/Makefile ++++ b/xbmc/video/videosync/Makefile +@@ -1,5 +1,6 @@ + SRCS=VideoSyncGLX.cpp \ + VideoSyncCocoa.cpp \ ++ VideoSyncDRM.cpp \ - virtual int Check(AVCodecContext* avctx); - virtual const std::string Name() { return "vaapi"; } -@@ -410,6 +429,7 @@ class CDecoder - bool CheckStatus(VAStatus vdp_st, int line); - void FiniVAAPIOutput(); - void ReturnRenderPicture(CVaapiRenderPicture *renderPic); -+ void ReturnProcPicture(int id); - long ReleasePicReference(); - bool CheckSuccess(VAStatus status); + LIB=videosync.a -@@ -458,6 +478,7 @@ class CPostproc - virtual void Flush() = 0; - virtual bool Compatible(EINTERLACEMETHOD method) = 0; - virtual bool DoesSync() = 0; -+ virtual bool WantsPic() {return true;} - protected: - CVaapiConfig m_config; - int m_step; -@@ -497,6 +518,7 @@ class CVppPostproc : public CPostproc - void Flush(); - bool Compatible(EINTERLACEMETHOD method); - bool DoesSync(); -+ bool WantsPic(); - protected: - bool CheckSuccess(VAStatus status); - void Dispose(); +diff --git a/xbmc/video/videosync/VideoSyncDRM.cpp b/xbmc/video/videosync/VideoSyncDRM.cpp +new file mode 100644 +index 0000000..1929a3a +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncDRM.cpp +@@ -0,0 +1,191 @@ ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(HAVE_X11) ++ ++#include "video/videosync/VideoSyncDRM.h" ++#include "xf86drm.h" ++#include ++#include ++#include "utils/TimeUtils.h" ++#include "utils/MathUtils.h" ++#include "windowing/WindowingFactory.h" ++#include "guilib/GraphicContext.h" ++#include "utils/log.h" ++ ++bool CVideoSyncDRM::Setup(PUPDATECLOCK func) ++{ ++ CLog::Log(LOGDEBUG, "CVideoSyncDRM::%s - setting up DRM", __FUNCTION__); ++ ++ UpdateClock = func; ++ ++ m_fd = open("/dev/dri/card0", O_RDWR, 0); ++ if (m_fd < 0) ++ { ++ CLog::Log(LOGERROR, "CVideoSyncDRM::%s - can't open /dev/dri/card0", __FUNCTION__); ++ return false; ++ } ++ ++ drmVBlank vbl; ++ int ret; ++ vbl.request.type = DRM_VBLANK_RELATIVE; ++ vbl.request.sequence = 0; ++ ret = drmWaitVBlank(m_fd, &vbl); ++ if (ret != 0) ++ { ++ CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); ++ return false; ++ } ++ ++ m_abort = false; ++ g_Windowing.Register(this); ++ ++ return true; ++} ++ ++void CVideoSyncDRM::Run(volatile bool& stop) ++{ ++ drmVBlank vbl; ++ VblInfo info; ++ int ret; ++ int crtc = g_Windowing.GetCrtc(); ++ ++ vbl.request.type = DRM_VBLANK_RELATIVE; ++ if (crtc == 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); ++ } ++ else if (crtc > 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | ++ (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); ++ } ++ vbl.request.sequence = 0; ++ ret = drmWaitVBlank(m_fd, &vbl); ++ if (ret != 0) ++ { ++ CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); ++ return; ++ } ++ ++ info.start = CurrentHostCounter(); ++ info.videoSync = this; ++ ++ vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); ++ if (crtc == 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); ++ } ++ else if (crtc > 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | ++ (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); ++ } ++ vbl.request.sequence = 1; ++ vbl.request.signal = (unsigned long)&info; ++ ret = drmWaitVBlank(m_fd, &vbl); ++ if (ret != 0) ++ { ++ CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmWaitVBlank returned error", __FUNCTION__); ++ return; ++ } ++ ++ drmEventContext evctx; ++ memset(&evctx, 0, sizeof evctx); ++ evctx.version = DRM_EVENT_CONTEXT_VERSION; ++ evctx.vblank_handler = EventHandler; ++ evctx.page_flip_handler = NULL; ++ ++ timeval timeout; ++ fd_set fds; ++ FD_ZERO(&fds); ++ FD_SET(m_fd, &fds); ++ ++ while (!stop && !m_abort) ++ { ++ timeout.tv_sec = 1; ++ timeout.tv_usec = 0; ++ ret = select(m_fd + 1, &fds, NULL, NULL, &timeout); ++ ++ if (ret <= 0) ++ { ++ continue; ++ } ++ ++ ret = drmHandleEvent(m_fd, &evctx); ++ if (ret != 0) ++ { ++ CLog::Log(LOGERROR, "CVideoSyncDRM::%s - drmHandleEvent returned error", __FUNCTION__); ++ break; ++ } ++ } ++} ++ ++void CVideoSyncDRM::Cleanup() ++{ ++ close(m_fd); ++ g_Windowing.Unregister(this); ++} ++ ++void CVideoSyncDRM::EventHandler(int fd, unsigned int frame, unsigned int sec, ++ unsigned int usec, void *data) ++{ ++ drmVBlank vbl; ++ struct timeval end; ++ VblInfo *info = (VblInfo*)data; ++ int crtc = g_Windowing.GetCrtc(); ++ ++ vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); ++ if (crtc == 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY); ++ } ++ else if (crtc > 1) ++ { ++ vbl.request.type = (drmVBlankSeqType)(vbl.request.type | ++ (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK); ++ } ++ vbl.request.sequence = 1; ++ vbl.request.signal = (unsigned long)data; ++ ++ drmWaitVBlank(info->videoSync->m_fd, &vbl); ++ ++ uint64_t now = CurrentHostCounter(); ++ float diff = (float)(now - info->start)/CurrentHostFrequency(); ++ int vblanks = MathUtils::round_int(diff * info->videoSync->m_fps); ++ info->start = now; ++ ++ info->videoSync->UpdateClock(vblanks, now); ++} ++ ++void CVideoSyncDRM::OnResetDevice() ++{ ++ m_abort = true; ++} ++ ++float CVideoSyncDRM::GetFps() ++{ ++ m_fps = g_graphicsContext.GetFPS(); ++ return m_fps; ++} ++ ++#endif +diff --git a/xbmc/video/videosync/VideoSyncDRM.h b/xbmc/video/videosync/VideoSyncDRM.h +new file mode 100644 +index 0000000..35f3e21 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncDRM.h +@@ -0,0 +1,46 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#if defined(HAVE_X11) ++ ++#include "video/videosync/VideoSync.h" ++#include "guilib/DispResource.h" ++ ++class CVideoSyncDRM : public CVideoSync, IDispResource ++{ ++public: ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(volatile bool& stop); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++ virtual void OnResetDevice(); ++private: ++ static void EventHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data); ++ int m_fd; ++ volatile bool m_abort; ++ struct VblInfo ++ { ++ uint64_t start; ++ CVideoSyncDRM *videoSync; ++ }; ++}; ++ ++#endif diff --git a/projects/RPi/patches/kodi/kodi-001-newclock4.patch b/projects/RPi/patches/kodi/kodi-001-newclock4.patch index 6fc278652f..7bdd8b6f23 100644 --- a/projects/RPi/patches/kodi/kodi-001-newclock4.patch +++ b/projects/RPi/patches/kodi/kodi-001-newclock4.patch @@ -1,7 +1,7 @@ -From 0fb175f191f1d348b0fb2c5ae4301b7e26cd38b6 Mon Sep 17 00:00:00 2001 +From 9478d6c8350dec4994147f3c0584394ef9992ffe Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 7 Apr 2014 18:19:32 +0100 -Subject: [PATCH 01/88] [rbp/omxplayer] When opening a stream don't try to +Subject: [PATCH 01/93] [rbp/omxplayer] When opening a stream don't try to update gui so often --- @@ -25,10 +25,10 @@ index e7cfcdd..20b99ad 100644 g_windowManager.ProcessRenderLoop(false); if (allowCancel && dialog->IsCanceled()) -From e2be18e9c1d63873a4b194e5888571d0f59bd1eb Mon Sep 17 00:00:00 2001 +From c38bc7e99058b8afa0c32d54bd4a8b87332bf5c8 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 29 Apr 2014 15:23:22 +0100 -Subject: [PATCH 02/88] [ffmpeg] Speed up wtv index creation +Subject: [PATCH 02/93] [ffmpeg] Speed up wtv index creation The index creation is O(N^2) with number of entries (typically thousands). On a Pi this can take more than 60 seconds to execute for a recording of a few hours. @@ -114,10 +114,10 @@ index 0000000..4ac5636 + } + } -From 5f39c4a49b854f0edadf73a4f8f05ac3d48ed053 Mon Sep 17 00:00:00 2001 +From cbfeb51aed12b340d8d7dfdfaf89e132032c5045 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:49:17 +1300 -Subject: [PATCH 03/88] adds GetTvShowSeasons +Subject: [PATCH 03/93] adds GetTvShowSeasons --- xbmc/video/VideoDatabase.cpp | 30 ++++++++++++++++++++++++------ @@ -193,10 +193,10 @@ index 78259ed..cbb26b7 100644 bool GetArtTypes(const MediaType &mediaType, std::vector &artTypes); -From 6698d8aa78b855e60b16a176277354cb759676a5 Mon Sep 17 00:00:00 2001 +From 276584b6872d9c247e548da95718f7497667b3d1 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:50:10 +1300 -Subject: [PATCH 04/88] move AddSeason() public. +Subject: [PATCH 04/93] move AddSeason() public. --- xbmc/video/VideoDatabase.h | 2 +- @@ -223,10 +223,10 @@ index cbb26b7..1a79c00 100644 /*! \brief Adds a path to the tvshow link table. \param idShow the id of the show. -From a437f73647103824d808572a8cb274a9d18dd402 Mon Sep 17 00:00:00 2001 +From c771e8d01977279201e9ed58e1793f3b5924ce55 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:48:24 +1300 -Subject: [PATCH 05/88] adds GetArt function to (video) scraper, allowing art +Subject: [PATCH 05/93] adds GetArt function to (video) scraper, allowing art to be fetched given the video identifier. --- @@ -237,7 +237,7 @@ Subject: [PATCH 05/88] adds GetArt function to (video) scraper, allowing art 4 files changed, 53 insertions(+) diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp -index 76d5248..f3f2930 100644 +index 4d22ce7..36865ac 100644 --- a/xbmc/addons/Scraper.cpp +++ b/xbmc/addons/Scraper.cpp @@ -924,6 +924,44 @@ EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl @@ -341,10 +341,10 @@ index 22ac229..75bc341 100644 enum LOOKUP_STATE { DO_NOTHING = 0, FIND_MOVIE = 1, -From fc5835d26ec5a89a4870a4797e19047b1492f2f7 Mon Sep 17 00:00:00 2001 +From db42a00769832c65e30dc0a60e9bac57ebcb91c5 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:53:14 +1300 -Subject: [PATCH 06/88] refresh season art if a new season is found that isn't +Subject: [PATCH 06/93] refresh season art if a new season is found that isn't recorded in the database yet. Fixes #14339 --- @@ -353,7 +353,7 @@ Subject: [PATCH 06/88] refresh season art if a new season is found that isn't 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp -index 9bf4349..f14b978 100644 +index 22f94ae..35fcc96 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp @@ -1372,6 +1372,10 @@ namespace VIDEO @@ -448,10 +448,10 @@ index 92883e7..47d5ed4 100644 bool ProcessItemByVideoInfoTag(const CFileItem *item, EPISODELIST &episodeList); -From 45467aa1dbcbce0e31bd9266480ef2e29c332d00 Mon Sep 17 00:00:00 2001 +From 9d5752d8307fc85c74430294f21ca7a0aff3b428 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:53:34 +1300 -Subject: [PATCH 07/88] REMOVEME: updated thetvdb.com scraper to support art +Subject: [PATCH 07/93] REMOVEME: updated thetvdb.com scraper to support art updates --- @@ -559,10 +559,10 @@ index f27e4fc..bdf329f 100644 -From e6e425270f311de3202cb4cd9a3684fe6dc59ca0 Mon Sep 17 00:00:00 2001 +From 05f1b6e9eb818c9e2d060dec48e2858f712a4343 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 2 Aug 2014 17:48:04 +0100 -Subject: [PATCH 08/88] [omx] Report decoded image name +Subject: [PATCH 08/93] [omx] Report decoded image name --- xbmc/cores/omxplayer/OMXImage.cpp | 1 + @@ -581,20 +581,20 @@ index 3fbea3b..57f69c5 100644 else { -From 76836bef384f9076800b4d28f236990f8207948e Mon Sep 17 00:00:00 2001 +From 2b86daa55de2c3b4886b5fc07bba5f870c33fbe3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 14 Dec 2013 16:55:05 +0000 -Subject: [PATCH 09/88] logging: Add microsecond timer to log messages +Subject: [PATCH 09/93] logging: Add microsecond timer to log messages --- xbmc/utils/log.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp -index 4e51166..3c405ab 100644 +index 3443f12..31c4a99 100644 --- a/xbmc/utils/log.cpp +++ b/xbmc/utils/log.cpp -@@ -23,6 +23,7 @@ +@@ -24,6 +24,7 @@ #include "threads/Thread.h" #include "utils/StringUtils.h" #include "CompileInfo.h" @@ -602,7 +602,7 @@ index 4e51166..3c405ab 100644 static const char* const levelNames[] = {"DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "SEVERE", "FATAL", "NONE"}; -@@ -195,19 +196,31 @@ void CLog::PrintDebugString(const std::string& line) +@@ -198,19 +199,31 @@ void CLog::PrintDebugString(const std::string& line) bool CLog::WriteLogString(int logLevel, const std::string& logString) { @@ -637,10 +637,10 @@ index 4e51166..3c405ab 100644 levelNames[logLevel]) + strData; -From 75e494302ff1480f5aa2a0347e384116086a05be Mon Sep 17 00:00:00 2001 +From 029cc8c20cea7e28cd60d9ee189a5457a8fe0a4e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 8 Mar 2014 15:36:06 +0000 -Subject: [PATCH 12/88] [hifiberry] Hack: force it to be recognised as IEC958 +Subject: [PATCH 12/93] [hifiberry] Hack: force it to be recognised as IEC958 capable to enable passthrough options --- @@ -663,10 +663,10 @@ index a464b4b..7eba389 100644 info.m_displayName.substr(info.m_displayName.size()-5) == " HDMI") { -From a75bc8435a2d56c0e5e63b64f1f663b650e17768 Mon Sep 17 00:00:00 2001 +From c717063d13a2674ef9307daf75b31c54b39f70ec Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 11 Dec 2013 17:21:54 +0000 -Subject: [PATCH 13/88] Move the reference-counting of Begin and End calls from +Subject: [PATCH 13/93] Move the reference-counting of Begin and End calls from DX and GL source files into GUIFontTTF.cpp. --- @@ -1054,10 +1054,10 @@ index c0bb53a..735fb3a 100644 protected: virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); -From acb4a6b7e5dfdfc67b81419d2568a48a61a08d2d Mon Sep 17 00:00:00 2001 +From 846c1b3b8d5d9752b4d16d5bd4f8b7d82faec5cc Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 11 Dec 2013 18:47:54 +0000 -Subject: [PATCH 14/88] Convert CGUIFontTTFBase::m_vertex to be managed as a +Subject: [PATCH 14/93] Convert CGUIFontTTFBase::m_vertex to be managed as a std::vector. Also retired CGUIFontTTFBase::m_vertex_count and @@ -1237,10 +1237,10 @@ index 97853fd..b76c6a5 100644 *vertices++ = m_vertex[i]; *vertices++ = m_vertex[i+1]; -From ec7796db5c9145f195f7c75a8ada28bc9857a29b Mon Sep 17 00:00:00 2001 +From 43162d4f2cea4a8663a0b719bd40dcff62eed9ff Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Mon, 16 Dec 2013 18:58:12 +0000 -Subject: [PATCH 15/88] CGUIFontTTFBase::RenderCharacter can now append to +Subject: [PATCH 15/93] CGUIFontTTFBase::RenderCharacter can now append to arbitrary vectors of vertices rather than only CGUIFontTTFBase::m_vertex --- @@ -1313,17 +1313,17 @@ index 5675725..a5d44f4 100644 virtual CBaseTexture* ReallocTexture(unsigned int& newHeight) = 0; -From 3920823d71730917234d3c4391d1c018c11d09df Mon Sep 17 00:00:00 2001 +From f7049ef39efd99b24616d1ff3184e30e5455a90b Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 17:18:38 +0000 -Subject: [PATCH 16/88] Add a cache of font glyph bounding box vertices. +Subject: [PATCH 16/93] Add a cache of font glyph bounding box vertices. This is implemented as a template because ultimately we will key on different parameters and store values of different types, depending upon whether we have a GLES or non-GLES backend, and for GLES, whether or not the currently applicable transformation matrices permit the use of hardware clipping. --- - XBMC.xcodeproj/project.pbxproj | 10 ++ + Kodi.xcodeproj/project.pbxproj | 10 ++ project/VS2010Express/XBMC.vcxproj | 2 + project/VS2010Express/XBMC.vcxproj.filters | 6 + xbmc/guilib/GUIFontCache.cpp | 105 ++++++++++++++ @@ -1338,6 +1338,106 @@ applicable transformation matrices permit the use of hardware clipping. create mode 100644 xbmc/guilib/GUIFontCache.cpp create mode 100644 xbmc/guilib/GUIFontCache.h +diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj +index 71b4f2e..5b5d2c7 100644 +--- a/Kodi.xcodeproj/project.pbxproj ++++ b/Kodi.xcodeproj/project.pbxproj +@@ -168,6 +168,9 @@ + 1D638128161E211E003603ED /* PeripheralImon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D638126161E211E003603ED /* PeripheralImon.cpp */; }; + 1DAFDB7C16DFDCA7007F8C68 /* PeripheralBusCEC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DAFDB7A16DFDCA7007F8C68 /* PeripheralBusCEC.cpp */; }; + 1DE0443515828F4B005DDB4D /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE0443315828F4B005DDB4D /* Exception.cpp */; }; ++ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; ++ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; ++ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; + 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; + 36A9443D15821E2800727135 /* DatabaseUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443B15821E2800727135 /* DatabaseUtils.cpp */; }; + 36A9444115821E7C00727135 /* SortUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443F15821E7C00727135 /* SortUtils.cpp */; }; +@@ -4018,6 +4021,8 @@ + 1DAFDB7B16DFDCA7007F8C68 /* PeripheralBusCEC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBusCEC.h; sourceTree = ""; }; + 1DE0443315828F4B005DDB4D /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Exception.cpp; path = commons/Exception.cpp; sourceTree = ""; }; + 1DE0443415828F4B005DDB4D /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Exception.h; path = commons/Exception.h; sourceTree = ""; }; ++ 2F4564D31970129A00396109 /* GUIFontCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIFontCache.cpp; sourceTree = ""; }; ++ 2F4564D41970129A00396109 /* GUIFontCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIFontCache.h; sourceTree = ""; }; + 32C631261423A90F00F18420 /* JpegIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JpegIO.cpp; sourceTree = ""; }; + 32C631271423A90F00F18420 /* JpegIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JpegIO.h; sourceTree = ""; }; + 36A9443B15821E2800727135 /* DatabaseUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseUtils.cpp; sourceTree = ""; }; +@@ -6532,6 +6537,8 @@ + 18B7C7101294222D009E7A26 /* GUIFixedListContainer.h */, + 18B7C76B1294222E009E7A26 /* GUIFont.cpp */, + 18B7C7111294222D009E7A26 /* GUIFont.h */, ++ 2F4564D31970129A00396109 /* GUIFontCache.cpp */, ++ 2F4564D41970129A00396109 /* GUIFontCache.h */, + 18B7C76C1294222E009E7A26 /* GUIFontManager.cpp */, + 18B7C7121294222D009E7A26 /* GUIFontManager.h */, + 18B7C76D1294222E009E7A26 /* GUIFontTTF.cpp */, +@@ -11030,6 +11037,7 @@ + 7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */, + F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */, + F54C51D20F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp in Sources */, ++ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */, + F54C51D50F1E784800D46E3C /* karaokelyricscdg.cpp in Sources */, + F54C51D80F1E785700D46E3C /* karaokelyrics.cpp in Sources */, + F54C51E50F1E787700D46E3C /* karaokelyricstextkar.cpp in Sources */, +@@ -12704,6 +12712,7 @@ + DFF0F45B17528350002DA3A4 /* Control.cpp in Sources */, + DFF0F45C17528350002DA3A4 /* Dialog.cpp in Sources */, + DFF0F45D17528350002DA3A4 /* File.cpp in Sources */, ++ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */, + DFF0F45E17528350002DA3A4 /* InfoTagMusic.cpp in Sources */, + DFF0F45F17528350002DA3A4 /* InfoTagVideo.cpp in Sources */, + DFF0F46017528350002DA3A4 /* Keyboard.cpp in Sources */, +@@ -13500,6 +13509,7 @@ + E499131D174E5DAD00741B6D /* GUIVisualisationControl.cpp in Sources */, + E499131E174E5DAD00741B6D /* GUIWindow.cpp in Sources */, + E499131F174E5DAD00741B6D /* GUIWindowManager.cpp in Sources */, ++ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */, + E4991320174E5DAD00741B6D /* GUIWrappingListContainer.cpp in Sources */, + E4991321174E5DAD00741B6D /* imagefactory.cpp in Sources */, + E4991322174E5DAD00741B6D /* IWindowManagerCallback.cpp in Sources */, +diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj +index ed5ad2a..bc1db7e 100644 +--- a/project/VS2010Express/XBMC.vcxproj ++++ b/project/VS2010Express/XBMC.vcxproj +@@ -427,6 +427,7 @@ + + + ++ + + + +@@ -1752,6 +1753,7 @@ + + + ++ + + + +diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters +index ca16ec8..a79aec4 100644 +--- a/project/VS2010Express/XBMC.vcxproj.filters ++++ b/project/VS2010Express/XBMC.vcxproj.filters +@@ -991,6 +991,9 @@ + + guilib + ++ ++ guilib ++ + + guilib + +@@ -3891,6 +3894,9 @@ + + guilib + ++ ++ guilib ++ + + guilib + diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp new file mode 100644 index 0000000..2c72f9c @@ -1976,10 +2076,10 @@ index f351c99..9036ba9 100644 + return !operator==(a, b); +} -From a94b6585c65bdc8b06003fce9fc99accbb42a2cb Mon Sep 17 00:00:00 2001 +From 7d313fc00055314b8c081fd1967cb0e03d391005 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 23 Jan 2014 22:24:17 +0000 -Subject: [PATCH 17/88] Lay the groundwork for hardware clipping. +Subject: [PATCH 17/93] Lay the groundwork for hardware clipping. For glScissor() to replace CGraphicContext::ClipRect, a necessary condition is that no shear or rotation is introduced between the coordinate systems @@ -2241,10 +2341,10 @@ index 98e398a..81ee49e 100644 virtual void ResetScissors(); -From 62be6ccfe7b9e51cc4e360cb1261ae5399aaaf93 Mon Sep 17 00:00:00 2001 +From 3df2170637df9887f926d4e1d9863711d38d7e6f Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 23 Jan 2014 16:42:22 +0000 -Subject: [PATCH 18/88] Increase font cache hit rate by keying on the +Subject: [PATCH 18/93] Increase font cache hit rate by keying on the fractional part of m_originX and m_originY *after* they have been through the graphics context's transformation matrix, plus the scale/rotation elements of the matrix, rather than the origin in the original frame of reference plus @@ -2445,10 +2545,10 @@ index 3b93672..258dffa 100644 private: virtual bool FirstBegin() = 0; -From 21a1cbbbf6ebb56ed1f037470165946dc57c1df1 Mon Sep 17 00:00:00 2001 +From eadc2e4307f98ef4c5ac46deb5adddec61a7b794 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 8 Jan 2014 12:16:33 +0000 -Subject: [PATCH 19/88] Rewrite of scrolling text code. +Subject: [PATCH 19/93] Rewrite of scrolling text code. No longer shuffles the string round to minimise the number of characters before the clipping rectangle; this doesn't save much on rendering time but @@ -2764,10 +2864,10 @@ index 2cda726..fbc579e 100644 private: void Process(); -From d424b7cc2480ff833644d3dfa274c7d4637d05e8 Mon Sep 17 00:00:00 2001 +From f1aa72cc304e7e3a33a3496684ba310ce5e568a3 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Mon, 27 Jan 2014 23:21:10 +0000 -Subject: [PATCH 20/88] Move the application of the translation offsets into +Subject: [PATCH 20/93] Move the application of the translation offsets into the GLES code. Still all pure software at this stage. Main change is in the data types at @@ -2961,10 +3061,10 @@ index 9935ea4..18c9358 100644 memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch()); if (m_texture) -From fca2bf09eb092fc78703ffa3e06fe53b1c6670e9 Mon Sep 17 00:00:00 2001 +From 68d1c6e18a31d8755ca9fe84be4ed23cb0268b85 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 15:28:06 +0000 -Subject: [PATCH 21/88] Rather than applying the translation offsets to the +Subject: [PATCH 21/93] Rather than applying the translation offsets to the vertices, now applies them to the model view matrix from the top of the matrix stack and pushes it over to OpenGL. The vertices themselves are still all held client-side. @@ -3108,10 +3208,10 @@ index 81ee49e..d2f9cd1 100644 protected: virtual void SetVSyncImpl(bool enable) = 0; -From cb15fabacab40e581453f16aa48a0707f66fc7f7 Mon Sep 17 00:00:00 2001 +From 9b739d0b0ba93fa5b7b2594f476017617f4755cd Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 29 Jan 2014 13:21:19 +0000 -Subject: [PATCH 22/88] Enable hardware clipping. +Subject: [PATCH 22/93] Enable hardware clipping. --- xbmc/guilib/GUIFontTTF.cpp | 4 ++-- @@ -3183,10 +3283,10 @@ index ea08bf4..b63e337 100644 glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW)); } -From 40d4f5bfb89977f8c10a403ce3fe247af5ad9069 Mon Sep 17 00:00:00 2001 +From f2282dad8ab5266f89259402dd106bff8e6af50c Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 15:32:51 +0000 -Subject: [PATCH 23/88] Move the vertex data across to a vertex buffer object +Subject: [PATCH 23/93] Move the vertex data across to a vertex buffer object just prior to drawing. --- @@ -3237,10 +3337,10 @@ index b63e337..b00055d 100644 // Disable the attributes used by this shader -From a5cbcbcfa9441f572b50ca04a22a7197d591cb61 Mon Sep 17 00:00:00 2001 +From c807a180836274264215f82b59c357f68930116c Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 16:04:04 +0000 -Subject: [PATCH 24/88] Move vertex data into an OpenGL VBO when the font cache +Subject: [PATCH 24/93] Move vertex data into an OpenGL VBO when the font cache entry is populated. The font cache now stores the "name" (handle) of the VBO, rather than a vector @@ -3513,10 +3613,10 @@ index 735fb3a..6102c90 100644 protected: virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); -From a4a06da228796c5b244bcf74debe3fee530bf6eb Mon Sep 17 00:00:00 2001 +From b57a210d83e2bdaf3253bcabd1dec20a1c24499a Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 16 Jan 2014 16:29:42 +0000 -Subject: [PATCH 25/88] Switch from glDrawArrays() to glDrawElements(). +Subject: [PATCH 25/93] Switch from glDrawArrays() to glDrawElements(). This involves setting up a static VBO containing the indexes necessary to convert from quads to triangles on the fly in the GPU. @@ -3737,10 +3837,10 @@ index 6de3532..258a293 100644 if (m_display != EGL_NO_DISPLAY) -From c71017ac871e463931aa15b98f9c85adb4e03bed Mon Sep 17 00:00:00 2001 +From 99bd43bc4f9426397bab9d2292327035bf8db432 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 1 May 2014 16:28:39 +0100 -Subject: [PATCH 26/88] Improved file buffering in CArchive +Subject: [PATCH 26/93] Improved file buffering in CArchive Even though memcpy is typically inlined by the compiler into byte/word loads and stores (at least for release builds), the frequency with which 1, 2 and 4 @@ -3800,10 +3900,10 @@ index 6ed0f8f..8506d95 100644 } else -From 80dccee914caa93facbbc614f3b4a5763a9f6685 Mon Sep 17 00:00:00 2001 +From 693f1291aaa8bd3bfee495f0cdf6d875cc1b4675 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 10 Sep 2014 22:07:21 +0100 -Subject: [PATCH 27/88] [mmal] Allow mmal codec for dvd stills +Subject: [PATCH 27/93] [mmal] Allow mmal codec for dvd stills --- xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 4 ++++ @@ -3825,236 +3925,10 @@ index f139433..4183a2b 100644 { // If dvd is an mpeg2 and hint.stills -From 0cf6e135b6f83dd8d3ba0352e1e118749eebe997 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 2 Aug 2014 17:47:38 +0100 -Subject: [PATCH 29/88] [VideoReferenceClock] Add OMX support - ---- - xbmc/linux/RBP.cpp | 34 ++++++++++++++++++++++++ - xbmc/linux/RBP.h | 3 +++ - xbmc/video/VideoReferenceClock.cpp | 53 ++++++++++++++++++++++++++++++++++++++ - xbmc/video/VideoReferenceClock.h | 6 +++++ - 4 files changed, 96 insertions(+) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 73a42c4..11376fc 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -32,6 +32,7 @@ CRBP::CRBP() - m_omx_initialized = false; - m_DllBcmHost = new DllBcmHost(); - m_OMX = new COMXCore(); -+ m_element = 0; - } - - CRBP::~CRBP() -@@ -53,6 +54,9 @@ bool CRBP::Initialize() - - m_DllBcmHost->bcm_host_init(); - -+ uint32_t vc_image_ptr; -+ m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); -+ - m_omx_initialized = m_OMX->Initialize(); - if(!m_omx_initialized) - return false; -@@ -156,6 +160,36 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - return image; - } - -+void CRBP::WaitVsync(void) -+{ -+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); -+ -+ VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; -+ VC_RECT_T src_rect; -+ VC_RECT_T dst_rect; -+ vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); -+ vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); -+ -+ if (m_element) -+ vc_dispmanx_element_remove( update, m_element ); -+ -+ m_element = vc_dispmanx_element_add( update, -+ display, -+ 2000, // layer -+ &dst_rect, -+ m_resource, -+ &src_rect, -+ DISPMANX_PROTECTION_NONE, -+ &alpha, -+ NULL, // clamp -+ (DISPMANX_TRANSFORM_T)0 ); -+ -+ vc_dispmanx_update_submit_sync(update); -+ vc_dispmanx_display_close( display ); -+} -+ -+ - void CRBP::Deinitialize() - { - if (m_omx_image_init) -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index e9a2d5a..4fd18f3 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -57,6 +57,7 @@ class CRBP - // stride can be null for packed output - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); - DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } -+ void WaitVsync(); - - private: - DllBcmHost *m_DllBcmHost; -@@ -69,6 +70,8 @@ class CRBP - bool m_codec_mpg2_enabled; - bool m_codec_wvc1_enabled; - COMXCore *m_OMX; -+ DISPMANX_RESOURCE_HANDLE_T m_resource; -+ DISPMANX_ELEMENT_HANDLE_T m_element; - class DllLibOMXCore; - CCriticalSection m_critSection; - }; -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 6d84b60..916a15c 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -50,6 +50,9 @@ - #endif - #include "windowing/WindowingFactory.h" - #include "settings/AdvancedSettings.h" -+#elif defined(TARGET_RASPBERRY_PI) -+ #include "guilib/GraphicContext.h" -+ #include "linux/RBP.h" - #endif - - using namespace std; -@@ -177,6 +180,8 @@ void CVideoReferenceClock::Process() - CLog::Log(LOGDEBUG, "CVideoReferenceClock: compiled without RandR support"); - #elif defined(TARGET_WINDOWS) - CLog::Log(LOGDEBUG, "CVideoReferenceClock: only available on directx build"); -+#elif defined(TARGET_RASPBERRY_PI) -+ SetupSuccess = SetupOMX(); - #else - CLog::Log(LOGDEBUG, "CVideoReferenceClock: no implementation available"); - #endif -@@ -205,6 +210,8 @@ void CVideoReferenceClock::Process() - RunD3D(); - #elif defined(TARGET_DARWIN) - RunCocoa(); -+#elif defined(TARGET_RASPBERRY_PI) -+ RunOMX(); - #endif - - } -@@ -237,6 +244,8 @@ void CVideoReferenceClock::Process() - CleanupD3D(); - #elif defined(TARGET_DARWIN) - CleanupCocoa(); -+#elif defined(TARGET_RASPBERRY_PI) -+ CleanupOMX(); - #endif - if (!SetupSuccess) break; - } -@@ -863,6 +872,50 @@ void CVideoReferenceClock::VblankHandler(int64_t nowtime, double fps) - SendVblankSignal(); - UpdateRefreshrate(); - } -+#elif defined(TARGET_RASPBERRY_PI) -+bool CVideoReferenceClock::SetupOMX() -+{ -+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up OMX"); -+ -+ //init the vblank timestamp -+ m_MissedVblanks = 0; -+ m_RefreshRate = g_graphicsContext.GetFPS(); -+ -+ UpdateRefreshrate(true); -+ return true; -+} -+ -+void CVideoReferenceClock::RunOMX() -+{ -+ CSingleLock SingleLock(m_CritSection); -+ SingleLock.Leave(); -+ -+ while(!m_bStop) -+ { -+ g_RBP.WaitVsync(); -+ -+ m_RefreshRate = g_graphicsContext.GetFPS(); -+ CLog::Log(LOGDEBUG, "CVideoReferenceClock:%s fps:%.2f missed:%d Time:%.3f", __func__, m_RefreshRate, m_TotalMissedVblanks, m_CurrTime * 1e-6); -+ //update the vblank timestamp, update the clock and send a signal that we got a vblank -+ SingleLock.Enter(); -+ m_VblankTime = CurrentHostCounter(); -+ UpdateClock(1, true); -+ SingleLock.Leave(); -+ SendVblankSignal(); -+ -+ if (UpdateRefreshrate()) -+ { -+ //we have to measure the refreshrate again -+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: Displaymode changed"); -+ return; -+ } -+ } -+} -+ -+void CVideoReferenceClock::CleanupOMX() -+{ -+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up OMX"); -+} - #endif - - //this is called from the vblank run function and from CVideoReferenceClock::Wait in case of a late update -diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h -index 6027031..2dabac1 100644 ---- a/xbmc/video/VideoReferenceClock.h -+++ b/xbmc/video/VideoReferenceClock.h -@@ -150,6 +150,12 @@ class CVideoReferenceClock : public CThread - - int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened - //not the same as m_VblankTime -+#elif defined(TARGET_RASPBERRY_PI) -+ bool SetupOMX(); -+ void RunOMX(); -+ void CleanupOMX(); -+ int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened -+ //not the same as m_VblankTime - #endif - }; - - -From 438669fbe7069d7237fbcad6bc72fd7a8d5889ab Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 12 Aug 2014 00:03:18 +0100 -Subject: [PATCH 30/88] videoreferenceclock: Boost priority - ---- - xbmc/video/VideoReferenceClock.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 916a15c..c491d29 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -157,6 +157,9 @@ void CVideoReferenceClock::Process() - bool SetupSuccess = false; - int64_t Now; - -+ /* This shouldn't be very busy and timing is important so increase priority */ -+ SetPriority(GetPriority()+1); -+ - #if defined(TARGET_WINDOWS) && defined(HAS_DX) - //register callback - m_D3dCallback.Reset(); - -From 32863b916ebb3f59b555e8560e1763b09c1fe5b1 Mon Sep 17 00:00:00 2001 +From db74784cc4446e9186001bbd27dedbf0f92db6c0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 5 Feb 2014 11:46:33 +0000 -Subject: [PATCH 31/88] [rbp/settings] Allow av sync type to be enabled +Subject: [PATCH 29/93] [rbp/settings] Allow av sync type to be enabled It works for dvdplayer --- @@ -4062,7 +3936,7 @@ It works for dvdplayer 1 file changed, 7 deletions(-) diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 319d9e5..e80ad91 100644 +index 5985517..f572eed 100644 --- a/system/settings/rbp.xml +++ b/system/settings/rbp.xml @@ -1,13 +1,6 @@ @@ -4080,10 +3954,10 @@ index 319d9e5..e80ad91 100644 false -From 8a3bef46ae9e92ae3e739ce8962b1c6580c3d760 Mon Sep 17 00:00:00 2001 +From 6d2d21314564c7603d31db53c19ccf1955e0563c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 16 Apr 2014 21:18:06 +0100 -Subject: [PATCH 33/88] [omxplayer] Don't propagate 3d flags based on supported +Subject: [PATCH 31/93] [omxplayer] Don't propagate 3d flags based on supported 3d modes --- @@ -4136,10 +4010,10 @@ index 2c25fd9..c2bd788 100644 unsigned int iDisplayWidth = width; unsigned int iDisplayHeight = height; -From 461db3a5d935997a7bfcd504ef18fccba4ce52a1 Mon Sep 17 00:00:00 2001 +From 2c2e5a3c6bb253e7a6cd51c241e5a6a07d38438b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:00:52 +0100 -Subject: [PATCH 34/88] [graphics] Don't set stereo mode based on resolution +Subject: [PATCH 32/93] [graphics] Don't set stereo mode based on resolution The resolution change should follow stereo mode --- @@ -4197,10 +4071,10 @@ index 282792c..f1926de 100644 m_iScreenWidth = info_mod.iWidth; -From 846e9d7e07c12468ef86587f5bca16c70598bb2e Mon Sep 17 00:00:00 2001 +From 3aea0fd665794464b801349ca973a8d1d2fdbb0a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:01:51 +0100 -Subject: [PATCH 35/88] [graphics] Allow switching to a more suitable 3D +Subject: [PATCH 33/93] [graphics] Allow switching to a more suitable 3D resolution --- @@ -4286,10 +4160,10 @@ index 2904c1b..8d3774f 100644 void ResetOverscan(RESOLUTION_INFO &resinfo); void ResetScreenParameters(RESOLUTION res); -From 6761ff32dfb4a483c355d19c7e1e01bdd39dc818 Mon Sep 17 00:00:00 2001 +From b83d7913c9f41fc6d33e06a0630c6bc0a2cd9cdd Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:38:55 +0100 -Subject: [PATCH 36/88] [3D] Support switching to 3D resolutions +Subject: [PATCH 34/93] [3D] Support switching to 3D resolutions Include matching 3D flags (SBS/TAB) in the score of a resolution to switch to, to enable switching to 3d modes. Also remove the old code that treated 3D modes differently when assigning a score. @@ -4371,10 +4245,10 @@ index 83c3adb..8076e76 100644 return current; } -From 175136d5d3871f90a0e298120cb8c6012159dbf9 Mon Sep 17 00:00:00 2001 +From 4a2d025959974b4753af33181add5a6fe7a6828c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 23 Apr 2014 00:05:07 +0100 -Subject: [PATCH 37/88] [graphics] Make pixel ratio for 3d modes consistent +Subject: [PATCH 35/93] [graphics] Make pixel ratio for 3d modes consistent Note: Use the stored stereo flags from lists of resolutions. Use current stereo mode for current resolution. @@ -4577,10 +4451,10 @@ index c58c28a..bf1e589 100644 AddUniqueResolution(res2, resolutions); -From 58c8800edbc1a15169ff6de916dafa9fd254d2c3 Mon Sep 17 00:00:00 2001 +From 5a6db7cb1c9a4cc3d0b830078564c85b64193dc9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 10 Aug 2014 16:45:16 +0100 -Subject: [PATCH 38/88] filesystem: Make support of browsing into archives +Subject: [PATCH 36/93] filesystem: Make support of browsing into archives optional The ability to browse, scan and play content in archives can cause problems on low powered/low memory devices. @@ -4596,10 +4470,10 @@ Add a settings option to enable this feature and default to disabled on Pi 4 files changed, 28 insertions(+) diff --git a/language/English/strings.po b/language/English/strings.po -index 1836b29..82b1279 100755 +index 4fe550a..0c01f5e 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -15957,4 +15957,13 @@ msgstr "" +@@ -15969,4 +15969,13 @@ msgstr "" #: system/settings/rbp.xml msgctxt "#38010" msgid "GPU accelerated" @@ -4614,7 +4488,7 @@ index 1836b29..82b1279 100755 +msgid "Allow viewing and playing files in archives (e.g. zip, rar)" msgstr "" diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index e80ad91..13e30ad 100644 +index f572eed..f3c8a01 100644 --- a/system/settings/rbp.xml +++ b/system/settings/rbp.xml @@ -1,5 +1,15 @@ @@ -4634,7 +4508,7 @@ index e80ad91..13e30ad 100644 diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index d8736c3..dc33d95 100644 +index 27aa739..3eb28b9 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -226,6 +226,11 @@ @@ -4679,10 +4553,10 @@ index 2fd8777..3b294cd 100644 { // XBMC Smart playlist - just XML renamed to XSP // read the name of the playlist in -From d4e2e5498836c39f6765d52f28309392621f8ea5 Mon Sep 17 00:00:00 2001 +From 74b47fc99e2e48b5986a395a20c88d7a5a54c3d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 11 Aug 2014 22:56:13 +0100 -Subject: [PATCH 40/88] [omxplayer] Add acceleration option to choose +Subject: [PATCH 38/93] [omxplayer] Add acceleration option to choose omxplayer/dvdplayer automatically --- @@ -4692,10 +4566,10 @@ Subject: [PATCH 40/88] [omxplayer] Add acceleration option to choose 3 files changed, 77 insertions(+) diff --git a/language/English/strings.po b/language/English/strings.po -index 82b1279..aee9a3a 100755 +index 0c01f5e..216837b 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -15967,3 +15967,13 @@ msgstr "" +@@ -15979,3 +15979,13 @@ msgstr "" msgctxt "#38021" msgid "Allow viewing and playing files in archives (e.g. zip, rar)" msgstr "" @@ -4710,7 +4584,7 @@ index 82b1279..aee9a3a 100755 +msgid "Uses codec information and audio setting to choose dvdplayer or omxplayer as appropriate" +msgstr "" diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index dc33d95..f4fcb7c 100644 +index 3eb28b9..9835d1f 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -751,6 +751,15 @@ @@ -4730,7 +4604,7 @@ index dc33d95..f4fcb7c 100644 HAS_OMXPLAYER diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 21d5f7c..713739b 100644 +index 6cd4f2d..7ae8826 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -490,6 +490,62 @@ void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer, std:: @@ -4806,10 +4680,10 @@ index 21d5f7c..713739b 100644 // allow renderer to switch to fullscreen if requested m_dvdPlayerVideo->EnableFullscreen(m_PlayerOptions.fullscreen); -From 7dc5ca6ed6eb20cf63964badd122773dbcfea03c Mon Sep 17 00:00:00 2001 +From bcc045a526dae8cf24051a2852069732ca9c20c7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 12 Aug 2014 16:51:18 +0100 -Subject: [PATCH 41/88] AE: Add some logging for suspend/resume +Subject: [PATCH 39/93] AE: Add some logging for suspend/resume --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 5 +++++ @@ -4860,7 +4734,7 @@ index 0e4d8da..64775c0 100644 &reply, 5000)) diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 9e98207..4f85dc7 100644 +index 6c7fcc2..e96713c 100644 --- a/xbmc/cores/omxplayer/OMXAudio.cpp +++ b/xbmc/cores/omxplayer/OMXAudio.cpp @@ -932,6 +932,7 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo @@ -4880,10 +4754,10 @@ index 9e98207..4f85dc7 100644 } -From 2766a736638a7ed216ec315f0f341b2a4684034d Mon Sep 17 00:00:00 2001 +From fac7392424b543698ae9707cc6a40288c8c6b346 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 9 Jul 2014 22:45:43 +0100 -Subject: [PATCH 42/88] [rbp] Make cachemembuffersize default depend on memory +Subject: [PATCH 40/93] [rbp] Make cachemembuffersize default depend on memory size --- @@ -4892,7 +4766,7 @@ Subject: [PATCH 42/88] [rbp] Make cachemembuffersize default depend on memory 2 files changed, 10 insertions(+) diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 11376fc..b67fbb1 100644 +index 73a42c4..ae12e59 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp @@ -22,6 +22,7 @@ @@ -4903,7 +4777,7 @@ index 11376fc..b67fbb1 100644 #include "utils/log.h" #include "cores/omxplayer/OMXImage.h" -@@ -84,6 +85,9 @@ bool CRBP::Initialize() +@@ -80,6 +81,9 @@ bool CRBP::Initialize() if (!m_gui_resolution_limit) m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080; @@ -4913,7 +4787,7 @@ index 11376fc..b67fbb1 100644 g_OMXImage.Initialize(); m_omx_image_init = true; return true; -@@ -96,6 +100,7 @@ void CRBP::LogFirmwareVerison() +@@ -92,6 +96,7 @@ void CRBP::LogFirmwareVerison() response[sizeof(response) - 1] = '\0'; CLog::Log(LOGNOTICE, "Raspberry PI firmware version: %s", response); CLog::Log(LOGNOTICE, "ARM mem: %dMB GPU mem: %dMB MPG2:%d WVC1:%d", m_arm_mem, m_gpu_mem, m_codec_mpg2_enabled, m_codec_wvc1_enabled); @@ -4922,10 +4796,10 @@ index 11376fc..b67fbb1 100644 response[sizeof(response) - 1] = '\0'; CLog::Log(LOGNOTICE, "Config:\n%s", response); diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 6109cec..2959ae8 100644 +index 3aff9f6..c7f47f4 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp -@@ -364,7 +364,12 @@ void CAdvancedSettings::Initialize() +@@ -365,7 +365,12 @@ void CAdvancedSettings::Initialize() m_measureRefreshrate = false; @@ -4939,10 +4813,10 @@ index 6109cec..2959ae8 100644 // the following setting determines the readRate of a player data // as multiply of the default data read rate -From 72392bd0153806e1e500d5e6d1ed1adefbb102c2 Mon Sep 17 00:00:00 2001 +From b45eb1381e2a2e6b0187183c9974072692af9a56 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 16 Jun 2014 19:06:00 +0100 -Subject: [PATCH 44/88] [experimental] Disable quiet-noise generation +Subject: [PATCH 42/93] [experimental] Disable quiet-noise generation --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 2 ++ @@ -4969,10 +4843,10 @@ index c6272cc..9111593 100644 void CActiveAESink::SetSilenceTimer() -From 76de204c4a1eb8c0f4ec665042d6971cd7fcf975 Mon Sep 17 00:00:00 2001 +From 27dc9f1c3790556b6a17e395dff244cb1944ef23 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 30 May 2014 14:58:43 +0100 -Subject: [PATCH 45/88] [settings] Experiment: Report DESKTOP resolution in +Subject: [PATCH 43/93] [settings] Experiment: Report DESKTOP resolution in video settings --- @@ -4994,10 +4868,10 @@ index 6902f83..50c5f97 100644 StringUtils::Format("%dx%d%s", resolution->width, resolution->height, ModeFlagsToString(resolution->flags, false).c_str()), -From dd67fb4e0413eab25b5f3bc77bc2d772625f2506 Mon Sep 17 00:00:00 2001 +From 5a278804be8572f5fa92abd966af5f435a4914a2 Mon Sep 17 00:00:00 2001 From: macrule Date: Thu, 11 Apr 2013 18:24:42 +0200 -Subject: [PATCH 46/88] Added some vc_tv_* functions that were missing in +Subject: [PATCH 44/93] Added some vc_tv_* functions that were missing in DllBCM. --- @@ -5032,10 +4906,10 @@ index b92fdb8..9c7e293 100644 HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags) { return ::vc_tv_hdmi_power_on_best(width, height, frame_rate, scan_mode, match_flags); }; -From b7d184caa2f8e10ff1a8574405bfa957867d7a2c Mon Sep 17 00:00:00 2001 +From 33d7a2cecf00179d2aecdad0994784f04d1c83ba Mon Sep 17 00:00:00 2001 From: macrule Date: Thu, 11 Apr 2013 18:29:03 +0200 -Subject: [PATCH 47/88] Added private utility function to map a float display +Subject: [PATCH 45/93] Added private utility function to map a float display aspect, to the respective SDTV_ASPECT_* enum value. --- @@ -5073,10 +4947,10 @@ index bf1e589..518a87d 100644 bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &resolutions) -From 83f9763d93eb1189c353cf861d196bc4009f1c0f Mon Sep 17 00:00:00 2001 +From f33b4e2e265cf05a0cbedca3cc744f30d7cc2b23 Mon Sep 17 00:00:00 2001 From: macrule Date: Thu, 11 Apr 2013 19:50:58 +0200 -Subject: [PATCH 48/88] Changed SDTV resolutions to be treated similarly to +Subject: [PATCH 46/93] Changed SDTV resolutions to be treated similarly to HDMI resolutions in SetNativeResolution. This means that the SDTV interface is powered up and set to the right mode. @@ -5173,10 +5047,10 @@ index 59401f5..a0acb1a 100644 int m_width; int m_height; -From 5ff25c07d6213a3f8b722909e1d29cec34fc67b7 Mon Sep 17 00:00:00 2001 +From 9029f7266e87672337da5af65940e245e0d2e406 Mon Sep 17 00:00:00 2001 From: macrule Date: Thu, 11 Apr 2013 19:54:59 +0200 -Subject: [PATCH 49/88] Added methods SuspendVideoOutput() and +Subject: [PATCH 47/93] Added methods SuspendVideoOutput() and ResumeVideoOutput() to CRBP class, which can be used to power down the Raspberry PI's video interface, and restore it at a later point. @@ -5187,10 +5061,10 @@ Subject: [PATCH 49/88] Added methods SuspendVideoOutput() and 3 files changed, 21 insertions(+) diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index b67fbb1..2ff6078 100644 +index ae12e59..958464f 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp -@@ -212,4 +212,19 @@ void CRBP::Deinitialize() +@@ -178,4 +178,19 @@ void CRBP::Deinitialize() m_initialized = false; m_omx_initialized = false; } @@ -5211,12 +5085,12 @@ index b67fbb1..2ff6078 100644 + #endif diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index 4fd18f3..f947acc 100644 +index e9a2d5a..04ddaa0 100644 --- a/xbmc/linux/RBP.h +++ b/xbmc/linux/RBP.h -@@ -59,6 +59,9 @@ class CRBP +@@ -58,6 +58,9 @@ class CRBP + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } - void WaitVsync(); + void SuspendVideoOutput(); + void ResumeVideoOutput(); @@ -5240,10 +5114,10 @@ index 9dc39d5..ca36082 100644 CEGLNativeTypeRaspberryPI::CEGLNativeTypeRaspberryPI() { -From aec31972c715b6946656ad6402258cb15f542bbe Mon Sep 17 00:00:00 2001 +From 93dc16a3746743070fe50721641349193acdf465 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 11 Aug 2013 15:03:36 +0100 -Subject: [PATCH 50/88] PowerManager (and its IPowerSyscall instance) now gets +Subject: [PATCH 48/93] PowerManager (and its IPowerSyscall instance) now gets called from CApplication::OnKey() and can process and suppress key presses. This is a requirement to implement a virtual sleep state. @@ -5255,10 +5129,10 @@ Subject: [PATCH 50/88] PowerManager (and its IPowerSyscall instance) now gets 4 files changed, 23 insertions(+) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 10903bf..8e63e25 100644 +index bb4342e..b74e3ae 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -2332,6 +2332,13 @@ bool CApplication::OnKey(const CKey& key) +@@ -2352,6 +2352,13 @@ bool CApplication::OnKey(const CKey& key) // special handling if the screensaver is active CAction action = CButtonTranslator::GetInstance().GetAction(iWin, key); @@ -5336,10 +5210,10 @@ index 0b1f10a..e42b143 100644 void OnSleep(); void OnWake(); -From c4d68d2b3060b755f616557839e8b7d3abd1f890 Mon Sep 17 00:00:00 2001 +From d35d64af5eb8ad4563d0f1ff9336de254bd69ea4 Mon Sep 17 00:00:00 2001 From: macrule Date: Wed, 17 Apr 2013 13:23:01 +0200 -Subject: [PATCH 51/88] Added CPowerSyscallVirtualSleep class, which acts as a +Subject: [PATCH 49/93] Added CPowerSyscallVirtualSleep class, which acts as a base class for devices that have no native standby mode, and need to fake it in some way. @@ -5515,10 +5389,10 @@ index 0000000..ef6e682 + +#endif // _POWER_SYSCALL_VIRTUAL_SLEEP_H_ -From 4f198e9cfec4a2e261c558226ae39bf531cbdb3d Mon Sep 17 00:00:00 2001 +From 02771d11f930b08e48590c0cfbb0847104ea3590 Mon Sep 17 00:00:00 2001 From: macrule Date: Wed, 17 Apr 2013 13:24:22 +0200 -Subject: [PATCH 52/88] Added power management support for the Raspberry Pi. +Subject: [PATCH 50/93] Added power management support for the Raspberry Pi. Since it doesn't support true standby, we fake it by turning video on or off, and ignoring remote inputs during the standby phase. @@ -5664,10 +5538,10 @@ index 0000000..fd1d67c + +#endif // _RASPBERRY_PI_POWER_SYSCALL_H_ -From b0b217f0878b0470d6b52a2b38044c5c78196342 Mon Sep 17 00:00:00 2001 +From c4ea3a8c3e901e2add2e1f6ce55748bd4487e232 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Mar 2014 16:16:29 +0000 -Subject: [PATCH 53/88] [power] hack - don't kill lirc or cec +Subject: [PATCH 51/93] [power] hack - don't kill lirc or cec --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 37 +++++++++++++++++++++++ @@ -5751,10 +5625,10 @@ index 2d8c750..901f449 100644 CBuiltins::Execute("LIRC.Start"); #endif -From c6da6fa95b75e8103141d1ae6460a91562d1b5b1 Mon Sep 17 00:00:00 2001 +From 2c7e9c7314d18ef74a71ced81660caa2633456f2 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Mar 2014 16:47:54 +0000 -Subject: [PATCH 54/88] [power] hack - wake on any action +Subject: [PATCH 52/93] [power] hack - wake on any action --- xbmc/powermanagement/PowerSyscallVirtualSleep.cpp | 6 +++--- @@ -5783,10 +5657,10 @@ index 6a1e47b..a717a09 100644 if(VirtualWake()) { -From 178e9a2a4515847c60c42e9a7faa31940924a6ae Mon Sep 17 00:00:00 2001 +From 7b4fa7354635ba7815c7e41bb1f75ab51a104e5a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Mar 2014 17:30:07 +0000 -Subject: [PATCH 55/88] [power] hack - Make suspend toggle suspend state +Subject: [PATCH 53/93] [power] hack - Make suspend toggle suspend state --- xbmc/powermanagement/PowerSyscallVirtualSleep.cpp | 5 +++++ @@ -5809,10 +5683,10 @@ index a717a09..d39c3ed 100644 return false; } -From 6f0f5289e4d100848caba3d5e9728a8257273368 Mon Sep 17 00:00:00 2001 +From 582c104b073cf55fb78460d565230ddefc5a625c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 4 Mar 2014 19:33:44 +0000 -Subject: [PATCH 56/88] [power] Add back in powerdown and reboot +Subject: [PATCH 54/93] [power] Add back in powerdown and reboot --- .../linux/RaspberryPIPowerSyscall.cpp | 34 ++++++++++++++++++++++ @@ -5890,10 +5764,10 @@ index fd1d67c..062132e 100644 virtual bool CanReboot() { return true; } -From 23d1437daeadcca45975cc39c1b830e839a8309c Mon Sep 17 00:00:00 2001 +From 54bdf26b8cb3d20eec154e7ee5db7bce20a777c9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 26 Apr 2014 17:27:52 +0100 -Subject: [PATCH 57/88] [cec] Don't suspend pi on tv switch off - it can't wake +Subject: [PATCH 55/93] [cec] Don't suspend pi on tv switch off - it can't wake up --- @@ -5914,452 +5788,20 @@ index a906628..9b5271a 100644 -From 9fe228d21a28daff0a7444a6ae36bf092931018b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 Aug 2014 19:09:32 +0100 -Subject: [PATCH 58/88] rbp: Use new dispmanx function for vsync callbacks - ---- - xbmc/linux/RBP.cpp | 85 ++++++++++++++----------- - xbmc/linux/RBP.h | 5 +- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- - 3 files changed, 52 insertions(+), 42 deletions(-) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 2ff6078..360fc39 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -33,7 +33,7 @@ CRBP::CRBP() - m_omx_initialized = false; - m_DllBcmHost = new DllBcmHost(); - m_OMX = new COMXCore(); -- m_element = 0; -+ m_display = DISPMANX_NO_HANDLE; - } - - CRBP::~CRBP() -@@ -55,8 +55,7 @@ bool CRBP::Initialize() - - m_DllBcmHost->bcm_host_init(); - -- uint32_t vc_image_ptr; -- m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); -+ //OpenDisplay(0 /*screen*/); - - m_omx_initialized = m_OMX->Initialize(); - if(!m_omx_initialized) -@@ -109,13 +108,24 @@ void CRBP::LogFirmwareVerison() - CLog::Log(LOGNOTICE, "Config:\n%s", response); - } - -+DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) -+{ -+ if (m_display == DISPMANX_NO_HANDLE) -+ m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ return m_display; -+} -+ -+void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) -+{ -+ assert(display == m_display); -+ vc_dispmanx_display_close(m_display); -+ m_display = DISPMANX_NO_HANDLE; -+} -+ - void CRBP::GetDisplaySize(int &width, int &height) - { -- DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_MODEINFO_T info; -- -- display = vc_dispmanx_display_open( 0 /*screen*/ ); -- if (vc_dispmanx_display_get_info(display, &info) == 0) -+ if (vc_dispmanx_display_get_info(m_display, &info) == 0) - { - width = info.width; - height = info.height; -@@ -125,12 +135,10 @@ void CRBP::GetDisplaySize(int &width, int &height) - width = 0; - height = 0; - } -- vc_dispmanx_display_close(display ); - } - - unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) - { -- DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_RESOURCE_HANDLE_T resource; - VC_RECT_T rect; - unsigned char *image = NULL; -@@ -145,7 +153,6 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - if (!pstride) - flags |= DISPMANX_SNAPSHOT_PACK; - -- display = vc_dispmanx_display_open( 0 /*screen*/ ); - stride = ((width + 15) & ~15) * 4; - image = new unsigned char [height * stride]; - -@@ -153,45 +160,44 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - { - resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); - -- vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); -+ assert(m_display != DISPMANX_NO_HANDLE); -+ vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); - - vc_dispmanx_rect_set(&rect, 0, 0, width, height); - vc_dispmanx_resource_read_data(resource, &rect, image, stride); - vc_dispmanx_resource_delete( resource ); -- vc_dispmanx_display_close(display ); - } - if (pstride) - *pstride = stride; - return image; - } - --void CRBP::WaitVsync(void) -+ -+static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) -+{ -+ CEvent *sync = (CEvent *)arg; -+ sync->Set(); -+} -+ -+void CRBP::WaitVsync() - { -- DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); -- DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); -- -- VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; -- VC_RECT_T src_rect; -- VC_RECT_T dst_rect; -- vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); -- vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); -- -- if (m_element) -- vc_dispmanx_element_remove( update, m_element ); -- -- m_element = vc_dispmanx_element_add( update, -- display, -- 2000, // layer -- &dst_rect, -- m_resource, -- &src_rect, -- DISPMANX_PROTECTION_NONE, -- &alpha, -- NULL, // clamp -- (DISPMANX_TRANSFORM_T)0 ); -- -- vc_dispmanx_update_submit_sync(update); -- vc_dispmanx_display_close( display ); -+ int s; -+ CEvent sync; -+ DISPMANX_DISPLAY_HANDLE_T m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ if (m_display == DISPMANX_NO_HANDLE) -+ { -+ CLog::Log(LOGDEBUG, "CRBP::%s skipping while display closed", __func__); -+ return; -+ } -+ s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&sync); -+ if (s == 0) -+ { -+ sync.Wait(); -+ } -+ else assert(0); -+ s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); -+ assert(s == 0); -+ vc_dispmanx_display_close( m_display ); - } - - -@@ -203,6 +209,9 @@ void CRBP::Deinitialize() - if(m_omx_initialized) - m_OMX->Deinitialize(); - -+ if (m_display) -+ CloseDisplay(m_display); -+ - m_DllBcmHost->bcm_host_deinit(); - - if(m_initialized) -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index f947acc..ca80045 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -53,6 +53,8 @@ class CRBP - bool GetCodecMpg2() { return m_codec_mpg2_enabled; } - bool GetCodecWvc1() { return m_codec_wvc1_enabled; } - void GetDisplaySize(int &width, int &height); -+ DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); -+ void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); - int GetGUIResolutionLimit() { return m_gui_resolution_limit; } - // stride can be null for packed output - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); -@@ -73,10 +75,9 @@ class CRBP - bool m_codec_mpg2_enabled; - bool m_codec_wvc1_enabled; - COMXCore *m_OMX; -- DISPMANX_RESOURCE_HANDLE_T m_resource; -- DISPMANX_ELEMENT_HANDLE_T m_element; - class DllLibOMXCore; - CCriticalSection m_critSection; -+ DISPMANX_DISPLAY_HANDLE_T m_display; - }; - - extern CRBP g_RBP; -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index ca36082..4b74ea0 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) - m_desktopRes = res; - } - -- m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); -+ m_dispman_display = g_RBP.OpenDisplay(0); - - m_width = res.iWidth; - m_height = res.iHeight; -@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() - - if (m_dispman_display != DISPMANX_NO_HANDLE) - { -- m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); -+ g_RBP.CloseDisplay(m_dispman_display); - m_dispman_display = DISPMANX_NO_HANDLE; - } - DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); - -From fe17b7692bd6141a191b89dfcb2c056da01e9181 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 19 Aug 2014 17:56:45 +0100 -Subject: [PATCH 59/88] Revert "rbp: Use new dispmanx function for vsync - callbacks" - -This reverts commit afbf8fbceaa6649fb4a6bbd9a1cee6087590412b. ---- - xbmc/linux/RBP.cpp | 85 +++++++++++-------------- - xbmc/linux/RBP.h | 5 +- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- - 3 files changed, 42 insertions(+), 52 deletions(-) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 360fc39..2ff6078 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -33,7 +33,7 @@ CRBP::CRBP() - m_omx_initialized = false; - m_DllBcmHost = new DllBcmHost(); - m_OMX = new COMXCore(); -- m_display = DISPMANX_NO_HANDLE; -+ m_element = 0; - } - - CRBP::~CRBP() -@@ -55,7 +55,8 @@ bool CRBP::Initialize() - - m_DllBcmHost->bcm_host_init(); - -- //OpenDisplay(0 /*screen*/); -+ uint32_t vc_image_ptr; -+ m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); - - m_omx_initialized = m_OMX->Initialize(); - if(!m_omx_initialized) -@@ -108,24 +109,13 @@ void CRBP::LogFirmwareVerison() - CLog::Log(LOGNOTICE, "Config:\n%s", response); - } - --DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) --{ -- if (m_display == DISPMANX_NO_HANDLE) -- m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -- return m_display; --} -- --void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) --{ -- assert(display == m_display); -- vc_dispmanx_display_close(m_display); -- m_display = DISPMANX_NO_HANDLE; --} -- - void CRBP::GetDisplaySize(int &width, int &height) - { -+ DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_MODEINFO_T info; -- if (vc_dispmanx_display_get_info(m_display, &info) == 0) -+ -+ display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ if (vc_dispmanx_display_get_info(display, &info) == 0) - { - width = info.width; - height = info.height; -@@ -135,10 +125,12 @@ void CRBP::GetDisplaySize(int &width, int &height) - width = 0; - height = 0; - } -+ vc_dispmanx_display_close(display ); - } - - unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) - { -+ DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_RESOURCE_HANDLE_T resource; - VC_RECT_T rect; - unsigned char *image = NULL; -@@ -153,6 +145,7 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - if (!pstride) - flags |= DISPMANX_SNAPSHOT_PACK; - -+ display = vc_dispmanx_display_open( 0 /*screen*/ ); - stride = ((width + 15) & ~15) * 4; - image = new unsigned char [height * stride]; - -@@ -160,44 +153,45 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - { - resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); - -- assert(m_display != DISPMANX_NO_HANDLE); -- vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); -+ vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); - - vc_dispmanx_rect_set(&rect, 0, 0, width, height); - vc_dispmanx_resource_read_data(resource, &rect, image, stride); - vc_dispmanx_resource_delete( resource ); -+ vc_dispmanx_display_close(display ); - } - if (pstride) - *pstride = stride; - return image; - } - -- --static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) --{ -- CEvent *sync = (CEvent *)arg; -- sync->Set(); --} -- --void CRBP::WaitVsync() -+void CRBP::WaitVsync(void) - { -- int s; -- CEvent sync; -- DISPMANX_DISPLAY_HANDLE_T m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -- if (m_display == DISPMANX_NO_HANDLE) -- { -- CLog::Log(LOGDEBUG, "CRBP::%s skipping while display closed", __func__); -- return; -- } -- s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&sync); -- if (s == 0) -- { -- sync.Wait(); -- } -- else assert(0); -- s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); -- assert(s == 0); -- vc_dispmanx_display_close( m_display ); -+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); -+ -+ VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; -+ VC_RECT_T src_rect; -+ VC_RECT_T dst_rect; -+ vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); -+ vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); -+ -+ if (m_element) -+ vc_dispmanx_element_remove( update, m_element ); -+ -+ m_element = vc_dispmanx_element_add( update, -+ display, -+ 2000, // layer -+ &dst_rect, -+ m_resource, -+ &src_rect, -+ DISPMANX_PROTECTION_NONE, -+ &alpha, -+ NULL, // clamp -+ (DISPMANX_TRANSFORM_T)0 ); -+ -+ vc_dispmanx_update_submit_sync(update); -+ vc_dispmanx_display_close( display ); - } - - -@@ -209,9 +203,6 @@ void CRBP::Deinitialize() - if(m_omx_initialized) - m_OMX->Deinitialize(); - -- if (m_display) -- CloseDisplay(m_display); -- - m_DllBcmHost->bcm_host_deinit(); - - if(m_initialized) -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index ca80045..f947acc 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -53,8 +53,6 @@ class CRBP - bool GetCodecMpg2() { return m_codec_mpg2_enabled; } - bool GetCodecWvc1() { return m_codec_wvc1_enabled; } - void GetDisplaySize(int &width, int &height); -- DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); -- void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); - int GetGUIResolutionLimit() { return m_gui_resolution_limit; } - // stride can be null for packed output - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); -@@ -75,9 +73,10 @@ class CRBP - bool m_codec_mpg2_enabled; - bool m_codec_wvc1_enabled; - COMXCore *m_OMX; -+ DISPMANX_RESOURCE_HANDLE_T m_resource; -+ DISPMANX_ELEMENT_HANDLE_T m_element; - class DllLibOMXCore; - CCriticalSection m_critSection; -- DISPMANX_DISPLAY_HANDLE_T m_display; - }; - - extern CRBP g_RBP; -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index 4b74ea0..ca36082 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) - m_desktopRes = res; - } - -- m_dispman_display = g_RBP.OpenDisplay(0); -+ m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); - - m_width = res.iWidth; - m_height = res.iHeight; -@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() - - if (m_dispman_display != DISPMANX_NO_HANDLE) - { -- g_RBP.CloseDisplay(m_dispman_display); -+ m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); - m_dispman_display = DISPMANX_NO_HANDLE; - } - DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); - -From 609deee8db8195bf7bfc5b242e5ab99f53782721 Mon Sep 17 00:00:00 2001 +From 6b4c2273af5269e98fab04d781390345db7a73e7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 27 Jun 2014 00:01:05 +0100 -Subject: [PATCH 60/88] [rbp] Resume video output on startup +Subject: [PATCH 56/93] [rbp] Resume video output on startup --- xbmc/linux/RBP.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 2ff6078..34e0108 100644 +index 958464f..162b505 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp -@@ -88,6 +88,9 @@ bool CRBP::Initialize() +@@ -84,6 +84,9 @@ bool CRBP::Initialize() if (g_advancedSettings.m_cacheMemBufferSize == ~0) g_advancedSettings.m_cacheMemBufferSize = m_arm_mem < 256 ? 1024 * 1024 * 2 : 1024 * 1024 * 20; @@ -6370,10 +5812,10 @@ index 2ff6078..34e0108 100644 m_omx_image_init = true; return true; -From 3e1a03218ec3f36542bd1309144ae6f525e73b24 Mon Sep 17 00:00:00 2001 +From 16e79bcb580f8cbb0c29e77fa9f65e4c5bdd1bbc Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 16 Aug 2014 21:01:42 +0100 -Subject: [PATCH 61/88] omxrender: Hacks to reduce GUI rendering rate when +Subject: [PATCH 57/93] omxrender: Hacks to reduce GUI rendering rate when playing video --- @@ -6383,10 +5825,10 @@ Subject: [PATCH 61/88] omxrender: Hacks to reduce GUI rendering rate when 3 files changed, 60 insertions(+) diff --git a/language/English/strings.po b/language/English/strings.po -index aee9a3a..996f682 100755 +index 216837b..5690347 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -15977,3 +15977,30 @@ msgstr "" +@@ -15989,3 +15989,30 @@ msgstr "" msgctxt "#37034" msgid "Uses codec information and audio setting to choose dvdplayer or omxplayer as appropriate" msgstr "" @@ -6418,7 +5860,7 @@ index aee9a3a..996f682 100755 +msgid "24 fps" +msgstr "" diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 13e30ad..e721d31 100644 +index f3c8a01..2996c29 100644 --- a/system/settings/rbp.xml +++ b/system/settings/rbp.xml @@ -25,6 +25,22 @@ @@ -6445,10 +5887,10 @@ index 13e30ad..e721d31 100644 diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 8e63e25..9c74cbd 100644 +index b74e3ae..c349e47 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -2180,6 +2180,23 @@ void CApplication::Render() +@@ -2200,6 +2200,23 @@ void CApplication::Render() if (m_bStop) return; @@ -6473,10 +5915,10 @@ index 8e63e25..9c74cbd 100644 int vsync_mode = CSettings::Get().GetInt("videoscreen.vsync"); -From de90d423fe10286ae4eef2f3501f04cd2aa63cf4 Mon Sep 17 00:00:00 2001 +From e85c9696bdeec0eb84f4f1e5795ee8c00fdf2791 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 9 Sep 2014 12:04:26 +0100 -Subject: [PATCH 62/88] egl: Treat unknown display aspect ratio as square pixel +Subject: [PATCH 58/93] egl: Treat unknown display aspect ratio as square pixel --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 ++-- @@ -6505,10 +5947,10 @@ index ca36082..1529045 100644 SetResolutionString(m_desktopRes); -From 40f5a6ec1e609050700e235e106df623bcccaeb8 Mon Sep 17 00:00:00 2001 +From 72381ea1c22a9f96860a524800a117990b9a5925 Mon Sep 17 00:00:00 2001 From: anaconda Date: Thu, 11 Sep 2014 21:30:43 +0200 -Subject: [PATCH 63/88] Disable textbox autoscrolling while on screensaver. +Subject: [PATCH 59/93] Disable textbox autoscrolling while on screensaver. --- xbmc/guilib/GUITextBox.cpp | 3 ++- @@ -6536,10 +5978,10 @@ index b7ef051..ba68fad 100644 if (m_lastRenderTime) m_autoScrollDelayTime += currentTime - m_lastRenderTime; -From 12830030ed4f1d7864bb3bb43d98d44526b011e0 Mon Sep 17 00:00:00 2001 +From 36352571f62af986f453eef251bd3d71a00a54fc Mon Sep 17 00:00:00 2001 From: anaconda Date: Sat, 13 Sep 2014 19:49:01 +0200 -Subject: [PATCH 64/88] SQUASH: only if dim or black +Subject: [PATCH 60/93] SQUASH: only if dim or black --- xbmc/Application.cpp | 7 +++++++ @@ -6548,10 +5990,10 @@ Subject: [PATCH 64/88] SQUASH: only if dim or black 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 9c74cbd..b2d56cd 100644 +index c349e47..9808500 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -5813,3 +5813,10 @@ void CApplication::CloseNetworkShares() +@@ -5853,3 +5853,10 @@ void CApplication::CloseNetworkShares() CSFTPSessionManager::DisconnectAllSessions(); #endif } @@ -6563,10 +6005,10 @@ index 9c74cbd..b2d56cd 100644 + return ""; +} diff --git a/xbmc/Application.h b/xbmc/Application.h -index 4157891..f807a98 100644 +index 23fd4cf..fd8908a 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h -@@ -373,6 +373,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs +@@ -374,6 +374,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs void SetLoggingIn(bool loggingIn) { m_loggingIn = loggingIn; } @@ -6591,420 +6033,10 @@ index ba68fad..e149418 100644 if (m_lastRenderTime) m_autoScrollDelayTime += currentTime - m_lastRenderTime; -From a56767138ba6566ebdf52a76cfe1294e27d79795 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 16 Sep 2014 00:52:02 +0100 -Subject: [PATCH 65/88] [PiSink] Initial dual audio support - ---- - system/settings/rbp.xml | 5 - - xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 219 ++++++++++++++++++++++++------ - xbmc/cores/AudioEngine/Sinks/AESinkPi.h | 5 + - xbmc/cores/omxplayer/OMXAudio.cpp | 12 +- - 4 files changed, 186 insertions(+), 55 deletions(-) - -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index e721d31..2996c29 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -80,11 +80,6 @@ - - - -- -- 2 -- false -- -- - - 101 - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -index 7af2078..89684e4 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -@@ -43,7 +43,8 @@ CAEDeviceInfo CAESinkPi::m_info; - CAESinkPi::CAESinkPi() : - m_sinkbuffer_sec_per_byte(0), - m_Initialized(false), -- m_submitted(0) -+ m_submitted(0), -+ m_omx_output(NULL) - { - } - -@@ -56,13 +57,26 @@ void CAESinkPi::SetAudioDest() - OMX_ERRORTYPE omx_err = OMX_ErrorNone; - OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest; - OMX_INIT_STRUCTURE(audioDest); -- if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -- strncpy((char *)audioDest.sName, "local", strlen("local")); -- else -- strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); -- omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ if ( m_omx_render.IsInitialized() ) -+ { -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -+ strncpy((char *)audioDest.sName, "local", strlen("local")); -+ else -+ strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); -+ omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } -+ if ( m_omx_render_slave.IsInitialized() ) -+ { -+ if (CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") -+ strncpy((char *)audioDest.sName, "local", strlen("local")); -+ else -+ strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi")); -+ omx_err = m_omx_render_slave.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - m_omx_render_slave.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } - } - - static void SetAudioProps(bool stream_channels, uint32_t channel_map) -@@ -176,8 +190,11 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - m_initFormat = format; - - // analogue only supports stereo -- if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") -+ { - format.m_channelLayout = AE_CH_LAYOUT_2_0; -+ m_passthrough = false; -+ } - - // setup for a 50ms sink feed from SoftAE - if (format.m_dataFormat != AE_FMT_FLOATP && format.m_dataFormat != AE_FMT_FLOAT && -@@ -196,18 +213,29 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - m_format = format; - m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); - -- CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d framesize:%d bufsize:%d bytes/s=%.2f", CLASSNAME, __func__, -- m_format.m_dataFormat, channels, m_format.m_sampleRate, m_format.m_frameSize, m_format.m_frameSize * m_format.m_frames, 1.0/m_sinkbuffer_sec_per_byte); -- -- CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); -+ CLog::Log(LOGDEBUG, "%s:%s Format:%d Channels:%d Samplerate:%d framesize:%d bufsize:%d bytes/s=%.2f dest=%s", CLASSNAME, __func__, -+ m_format.m_dataFormat, channels, m_format.m_sampleRate, m_format.m_frameSize, m_format.m_frameSize * m_format.m_frames, 1.0/m_sinkbuffer_sec_per_byte, -+ CSettings::Get().GetString("audiooutput.audiodevice").c_str()); - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; - - if (!m_omx_render.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); - -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") -+ { -+ if (!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit)) -+ CLog::Log(LOGERROR, "%s::%s - m_omx_splitter.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ if (!m_omx_render_slave.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) -+ CLog::Log(LOGERROR, "%s::%s - m_omx_render.Initialize omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ m_omx_output = &m_omx_splitter; -+ } -+ else -+ m_omx_output = &m_omx_render; -+ -+ SetAudioDest(); -+ - OMX_INIT_STRUCTURE(m_pcm_input); -- m_pcm_input.nPortIndex = m_omx_render.GetInputPort(); - m_pcm_input.eNumData = OMX_NumericalDataSigned; - m_pcm_input.eEndian = OMX_EndianLittle; - m_pcm_input.bInterleaved = OMX_TRUE; -@@ -222,37 +250,100 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - m_pcm_input.nChannels = channels; - m_pcm_input.nSamplingRate = m_format.m_sampleRate; - -- omx_err = m_omx_render.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s::%s - error m_omx_render SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ if ( m_omx_splitter.IsInitialized() ) -+ { -+ m_pcm_input.nPortIndex = m_omx_splitter.GetInputPort(); -+ omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ -+ m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort(); -+ omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -+ if(omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ -+ m_pcm_input.nPortIndex = m_omx_splitter.GetOutputPort() + 1; -+ omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -+ if(omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } - -- m_omx_render.ResetEos(); -+ if ( m_omx_render_slave.IsInitialized() ) -+ { -+ m_pcm_input.nPortIndex = m_omx_render_slave.GetInputPort(); -+ omx_err = m_omx_render_slave.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_render_slave SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } - -- SetAudioDest(); -+ if ( m_omx_render.IsInitialized() ) -+ { -+ m_pcm_input.nPortIndex = m_omx_render.GetInputPort(); -+ omx_err = m_omx_render.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_render SetParameter in omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } - -- // set up the number/size of buffers for decoder input -- OMX_PARAM_PORTDEFINITIONTYPE port_param; -- OMX_INIT_STRUCTURE(port_param); -- port_param.nPortIndex = m_omx_render.GetInputPort(); -+ if ( m_omx_output->IsInitialized() ) -+ { -+ // set up the number/size of buffers for decoder input -+ OMX_PARAM_PORTDEFINITIONTYPE port_param; -+ OMX_INIT_STRUCTURE(port_param); -+ port_param.nPortIndex = m_omx_output->GetInputPort(); - -- omx_err = m_omx_render.GetParameter(OMX_IndexParamPortDefinition, &port_param); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ omx_err = m_omx_output->GetParameter(OMX_IndexParamPortDefinition, &port_param); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); - -- port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)NUM_OMX_BUFFERS); -- port_param.nBufferSize = m_format.m_frameSize * m_format.m_frames; -+ port_param.nBufferCountActual = std::max((unsigned int)port_param.nBufferCountMin, (unsigned int)NUM_OMX_BUFFERS); -+ port_param.nBufferSize = ALIGN_UP(m_format.m_frameSize * m_format.m_frames, port_param.nBufferAlignment); - -- omx_err = m_omx_render.SetParameter(OMX_IndexParamPortDefinition, &port_param); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (intput) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ omx_err = m_omx_output->SetParameter(OMX_IndexParamPortDefinition, &port_param); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - error set OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); - -- omx_err = m_omx_render.AllocInputBuffers(); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); -+ omx_err = m_omx_output->AllocInputBuffers(); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - Error alloc buffers 0x%08x", CLASSNAME, __func__, omx_err); -+ } - -- omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting); -- if (omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s:%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ if ( m_omx_splitter.IsInitialized() ) -+ { -+ m_omx_tunnel_splitter.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort()); -+ omx_err = m_omx_tunnel_splitter.Establish(); -+ if (omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter.Establish 0x%08x", omx_err); -+ return false; -+ } -+ -+ m_omx_tunnel_splitter_slave.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort() + 1, &m_omx_render_slave, m_omx_render_slave.GetInputPort()); -+ omx_err = m_omx_tunnel_splitter_slave.Establish(); -+ if (omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_slave.Establish 0x%08x", omx_err); -+ return false; -+ } -+ } -+ -+ if ( m_omx_splitter.IsInitialized() ) -+ { -+ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - m_omx_splitter OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } -+ if ( m_omx_render.IsInitialized() ) -+ { -+ omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } -+ if ( m_omx_render_slave.IsInitialized() ) -+ { -+ omx_err = m_omx_render_slave.SetStateForComponent(OMX_StateExecuting); -+ if (omx_err != OMX_ErrorNone) -+ CLog::Log(LOGERROR, "%s:%s - m_omx_render_slave OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err); -+ } - - m_Initialized = true; - return true; -@@ -263,12 +354,32 @@ void CAESinkPi::Deinitialize() - { - CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); - SetAudioProps(false, 0); -- if (m_Initialized) -- { -+ -+ if ( m_omx_render.IsInitialized() ) -+ m_omx_render.IgnoreNextError(OMX_ErrorPortUnpopulated); -+ if ( m_omx_render_slave.IsInitialized() ) -+ m_omx_render_slave.IgnoreNextError(OMX_ErrorPortUnpopulated); -+ -+ if ( m_omx_tunnel_splitter.IsInitialized() ) -+ m_omx_tunnel_splitter.Deestablish(); -+ if ( m_omx_tunnel_splitter_slave.IsInitialized() ) -+ m_omx_tunnel_splitter_slave.Deestablish(); -+ -+ if ( m_omx_splitter.IsInitialized() ) -+ m_omx_splitter.FlushAll(); -+ if ( m_omx_render.IsInitialized() ) - m_omx_render.FlushAll(); -+ if ( m_omx_render_slave.IsInitialized() ) -+ m_omx_render_slave.FlushAll(); -+ -+ if ( m_omx_splitter.IsInitialized() ) -+ m_omx_splitter.Deinitialize(); -+ if ( m_omx_render.IsInitialized() ) - m_omx_render.Deinitialize(); -- m_Initialized = false; -- } -+ if ( m_omx_render_slave.IsInitialized() ) -+ m_omx_render_slave.Deinitialize(); -+ -+ m_Initialized = false; - } - - bool CAESinkPi::IsCompatible(const AEAudioFormat &format, const std::string &device) -@@ -314,7 +425,7 @@ double CAESinkPi::GetCacheTotal() - - unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset) - { -- if (!m_Initialized || !frames) -+ if (!m_Initialized || !m_omx_output || !frames) - return frames; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; -@@ -332,7 +443,7 @@ unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned - if (delay <= 0.0 && m_submitted) - CLog::Log(LOGNOTICE, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames); - -- omx_buffer = m_omx_render.GetInputBuffer(1000); -+ omx_buffer = m_omx_output->GetInputBuffer(1000); - if (omx_buffer == NULL) - { - CLog::Log(LOGERROR, "CAESinkPi::AddPackets timeout"); -@@ -351,7 +462,7 @@ unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned - for (int i=0; i < planes; i++) - memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, data[i] + offset * pitch, planesize); - } -- omx_err = m_omx_render.EmptyThisBuffer(omx_buffer); -+ omx_err = m_omx_output->EmptyThisBuffer(omx_buffer); - if (omx_err != OMX_ErrorNone) - CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err); - m_submitted++; -@@ -419,6 +530,26 @@ void CAESinkPi::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) - m_info.m_dataFormats.push_back(AE_FMT_S16NEP); - - list.push_back(m_info); -+ -+ m_info.m_channels.Reset(); -+ m_info.m_dataFormats.clear(); -+ m_info.m_sampleRates.clear(); -+ -+ m_info.m_deviceType = AE_DEVTYPE_PCM; -+ m_info.m_deviceName = "Both"; -+ m_info.m_displayName = "HDMI and Analogue"; -+ m_info.m_displayNameExtra = ""; -+ m_info.m_channels += AE_CH_FL; -+ m_info.m_channels += AE_CH_FR; -+ m_info.m_sampleRates.push_back(48000); -+ m_info.m_dataFormats.push_back(AE_FMT_FLOAT); -+ m_info.m_dataFormats.push_back(AE_FMT_S32LE); -+ m_info.m_dataFormats.push_back(AE_FMT_S16LE); -+ m_info.m_dataFormats.push_back(AE_FMT_FLOATP); -+ m_info.m_dataFormats.push_back(AE_FMT_S32NEP); -+ m_info.m_dataFormats.push_back(AE_FMT_S16NEP); -+ -+ list.push_back(m_info); - } - - #endif -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h b/xbmc/cores/AudioEngine/Sinks/AESinkPi.h -index 8ab1d08..5c57999 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.h -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.h -@@ -57,8 +57,13 @@ class CAESinkPi : public IAESink - bool m_Initialized; - uint32_t m_submitted; - OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input; -+ COMXCoreComponent *m_omx_output; -+ COMXCoreComponent m_omx_splitter; - COMXCoreComponent m_omx_render; -+ COMXCoreComponent m_omx_render_slave; - bool m_passthrough; -+ COMXCoreTunel m_omx_tunnel_splitter; -+ COMXCoreTunel m_omx_tunnel_splitter_slave; - }; - - #endif -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 4f85dc7..e96713c 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -124,17 +124,17 @@ bool COMXAudio::PortSettingsChanged() - if(!m_omx_mixer.Initialize("OMX.broadcom.audio_mixer", OMX_IndexParamAudioInit)) - return false; - } -- if(CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") - { - if(!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit)) - return false; - } -- if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") - { - if(!m_omx_render_analog.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; - } -- if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:HDMI") - { - if(!m_omx_render_hdmi.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; -@@ -252,7 +252,7 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || (CSettings::Get().GetBool("audiooutput.dualaudio") && CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue")) -+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); -@@ -278,7 +278,7 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || (CSettings::Get().GetBool("audiooutput.dualaudio") && CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue")) -+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock")) - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); -@@ -601,7 +601,7 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - CAEChannelInfo stdLayout = (enum AEStdChLayout)CSettings::Get().GetInt("audiooutput.channels"); - - // ignore layout setting for analogue -- if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") - stdLayout = AE_CH_LAYOUT_2_0; - - // force out layout to stereo if input is not multichannel - it gives the receiver a chance to upmix - -From 4d78c4ddad578458e99e90eef4c746ef5567643d Mon Sep 17 00:00:00 2001 +From 0a65f36f3e14ab8296153100fcb4283b0241621b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 18 Sep 2014 14:24:56 +0100 -Subject: [PATCH 66/88] [omxplayer] Only enable audio clock master when A/V +Subject: [PATCH 61/93] [omxplayer] Only enable audio clock master when A/V sync method is set to audio clock --- @@ -7035,483 +6067,10 @@ index e96713c..036552a 100644 OMX_CONFIG_BOOLEANTYPE configBool; OMX_INIT_STRUCTURE(configBool); -From fa419f5d488a49d1a45f290213ee6204668482bd Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 Aug 2014 19:09:32 +0100 -Subject: [PATCH 67/88] rbp: Use new dispmanx function for vsync callbacks - -[rbp] Enable vsync handler all the time ---- - xbmc/linux/RBP.cpp | 96 ++++++++++++++----------- - xbmc/linux/RBP.h | 7 +- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- - 3 files changed, 61 insertions(+), 46 deletions(-) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 34e0108..8ce60cb 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -33,7 +33,7 @@ CRBP::CRBP() - m_omx_initialized = false; - m_DllBcmHost = new DllBcmHost(); - m_OMX = new COMXCore(); -- m_element = 0; -+ m_display = DISPMANX_NO_HANDLE; - } - - CRBP::~CRBP() -@@ -55,8 +55,7 @@ bool CRBP::Initialize() - - m_DllBcmHost->bcm_host_init(); - -- uint32_t vc_image_ptr; -- m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); -+ //OpenDisplay(0 /*screen*/); - - m_omx_initialized = m_OMX->Initialize(); - if(!m_omx_initialized) -@@ -112,13 +111,55 @@ void CRBP::LogFirmwareVerison() - CLog::Log(LOGNOTICE, "Config:\n%s", response); - } - -+static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) -+{ -+ CEvent *sync = (CEvent *)arg; -+ sync->Set(); -+} -+ -+void CRBP::WaitVsync() -+{ -+ CSingleLock lock (m_critSection); -+ if (m_display == DISPMANX_NO_HANDLE) -+ { -+ // don't busy spin -+ Sleep(10); -+ return; -+ } -+ m_vsync.Reset(); -+ m_vsync.Wait(); -+} -+ -+DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) -+{ -+ CSingleLock lock (m_critSection); -+ if (m_display == DISPMANX_NO_HANDLE) -+ m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ -+ if (m_display != DISPMANX_NO_HANDLE) -+ { -+ int s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&m_vsync); -+ assert(s == 0); -+ } -+ return m_display; -+} -+ -+void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) -+{ -+ CSingleLock lock (m_critSection); -+ assert(display == m_display); -+ -+ int s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); -+ assert(s == 0); -+ -+ vc_dispmanx_display_close(m_display); -+ m_display = DISPMANX_NO_HANDLE; -+} -+ - void CRBP::GetDisplaySize(int &width, int &height) - { -- DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_MODEINFO_T info; -- -- display = vc_dispmanx_display_open( 0 /*screen*/ ); -- if (vc_dispmanx_display_get_info(display, &info) == 0) -+ if (vc_dispmanx_display_get_info(m_display, &info) == 0) - { - width = info.width; - height = info.height; -@@ -128,12 +169,10 @@ void CRBP::GetDisplaySize(int &width, int &height) - width = 0; - height = 0; - } -- vc_dispmanx_display_close(display ); - } - - unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) - { -- DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_RESOURCE_HANDLE_T resource; - VC_RECT_T rect; - unsigned char *image = NULL; -@@ -148,7 +187,6 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - if (!pstride) - flags |= DISPMANX_SNAPSHOT_PACK; - -- display = vc_dispmanx_display_open( 0 /*screen*/ ); - stride = ((width + 15) & ~15) * 4; - image = new unsigned char [height * stride]; - -@@ -156,56 +194,30 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - { - resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); - -- vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); -+ assert(m_display != DISPMANX_NO_HANDLE); -+ vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); - - vc_dispmanx_rect_set(&rect, 0, 0, width, height); - vc_dispmanx_resource_read_data(resource, &rect, image, stride); - vc_dispmanx_resource_delete( resource ); -- vc_dispmanx_display_close(display ); - } - if (pstride) - *pstride = stride; - return image; - } - --void CRBP::WaitVsync(void) --{ -- DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); -- DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); -- -- VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; -- VC_RECT_T src_rect; -- VC_RECT_T dst_rect; -- vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); -- vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); -- -- if (m_element) -- vc_dispmanx_element_remove( update, m_element ); -- -- m_element = vc_dispmanx_element_add( update, -- display, -- 2000, // layer -- &dst_rect, -- m_resource, -- &src_rect, -- DISPMANX_PROTECTION_NONE, -- &alpha, -- NULL, // clamp -- (DISPMANX_TRANSFORM_T)0 ); -- -- vc_dispmanx_update_submit_sync(update); -- vc_dispmanx_display_close( display ); --} -- -- - void CRBP::Deinitialize() - { -+ CSingleLock lock (m_critSection); - if (m_omx_image_init) - g_OMXImage.Deinitialize(); - - if(m_omx_initialized) - m_OMX->Deinitialize(); - -+ if (m_display) -+ CloseDisplay(m_display); -+ - m_DllBcmHost->bcm_host_deinit(); - - if(m_initialized) -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index f947acc..029d69c 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -38,6 +38,7 @@ - #include "DllBCM.h" - #include "OMXCore.h" - #include "threads/CriticalSection.h" -+#include "threads/Event.h" - - class CRBP - { -@@ -53,6 +54,8 @@ class CRBP - bool GetCodecMpg2() { return m_codec_mpg2_enabled; } - bool GetCodecWvc1() { return m_codec_wvc1_enabled; } - void GetDisplaySize(int &width, int &height); -+ DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); -+ void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); - int GetGUIResolutionLimit() { return m_gui_resolution_limit; } - // stride can be null for packed output - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); -@@ -73,10 +76,10 @@ class CRBP - bool m_codec_mpg2_enabled; - bool m_codec_wvc1_enabled; - COMXCore *m_OMX; -- DISPMANX_RESOURCE_HANDLE_T m_resource; -- DISPMANX_ELEMENT_HANDLE_T m_element; - class DllLibOMXCore; - CCriticalSection m_critSection; -+ DISPMANX_DISPLAY_HANDLE_T m_display; -+ CEvent m_vsync; - }; - - extern CRBP g_RBP; -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index 1529045..b6bf1fc 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) - m_desktopRes = res; - } - -- m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); -+ m_dispman_display = g_RBP.OpenDisplay(0); - - m_width = res.iWidth; - m_height = res.iHeight; -@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() - - if (m_dispman_display != DISPMANX_NO_HANDLE) - { -- m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); -+ g_RBP.CloseDisplay(m_dispman_display); - m_dispman_display = DISPMANX_NO_HANDLE; - } - DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); - -From 38716528fd3836091adaf141c8b30cd455ad3ac2 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 18 Sep 2014 23:14:31 +0100 -Subject: [PATCH 68/88] Revert "rbp: Use new dispmanx function for vsync - callbacks" - -This reverts commit e56163da23b6a844e7eee076e4583bce606f788b. ---- - xbmc/linux/RBP.cpp | 96 +++++++++++-------------- - xbmc/linux/RBP.h | 7 +- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- - 3 files changed, 46 insertions(+), 61 deletions(-) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 8ce60cb..34e0108 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -33,7 +33,7 @@ CRBP::CRBP() - m_omx_initialized = false; - m_DllBcmHost = new DllBcmHost(); - m_OMX = new COMXCore(); -- m_display = DISPMANX_NO_HANDLE; -+ m_element = 0; - } - - CRBP::~CRBP() -@@ -55,7 +55,8 @@ bool CRBP::Initialize() - - m_DllBcmHost->bcm_host_init(); - -- //OpenDisplay(0 /*screen*/); -+ uint32_t vc_image_ptr; -+ m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); - - m_omx_initialized = m_OMX->Initialize(); - if(!m_omx_initialized) -@@ -111,55 +112,13 @@ void CRBP::LogFirmwareVerison() - CLog::Log(LOGNOTICE, "Config:\n%s", response); - } - --static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) --{ -- CEvent *sync = (CEvent *)arg; -- sync->Set(); --} -- --void CRBP::WaitVsync() --{ -- CSingleLock lock (m_critSection); -- if (m_display == DISPMANX_NO_HANDLE) -- { -- // don't busy spin -- Sleep(10); -- return; -- } -- m_vsync.Reset(); -- m_vsync.Wait(); --} -- --DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) --{ -- CSingleLock lock (m_critSection); -- if (m_display == DISPMANX_NO_HANDLE) -- m_display = vc_dispmanx_display_open( 0 /*screen*/ ); -- -- if (m_display != DISPMANX_NO_HANDLE) -- { -- int s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&m_vsync); -- assert(s == 0); -- } -- return m_display; --} -- --void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) --{ -- CSingleLock lock (m_critSection); -- assert(display == m_display); -- -- int s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); -- assert(s == 0); -- -- vc_dispmanx_display_close(m_display); -- m_display = DISPMANX_NO_HANDLE; --} -- - void CRBP::GetDisplaySize(int &width, int &height) - { -+ DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_MODEINFO_T info; -- if (vc_dispmanx_display_get_info(m_display, &info) == 0) -+ -+ display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ if (vc_dispmanx_display_get_info(display, &info) == 0) - { - width = info.width; - height = info.height; -@@ -169,10 +128,12 @@ void CRBP::GetDisplaySize(int &width, int &height) - width = 0; - height = 0; - } -+ vc_dispmanx_display_close(display ); - } - - unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) - { -+ DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_RESOURCE_HANDLE_T resource; - VC_RECT_T rect; - unsigned char *image = NULL; -@@ -187,6 +148,7 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - if (!pstride) - flags |= DISPMANX_SNAPSHOT_PACK; - -+ display = vc_dispmanx_display_open( 0 /*screen*/ ); - stride = ((width + 15) & ~15) * 4; - image = new unsigned char [height * stride]; - -@@ -194,30 +156,56 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - { - resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); - -- assert(m_display != DISPMANX_NO_HANDLE); -- vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); -+ vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); - - vc_dispmanx_rect_set(&rect, 0, 0, width, height); - vc_dispmanx_resource_read_data(resource, &rect, image, stride); - vc_dispmanx_resource_delete( resource ); -+ vc_dispmanx_display_close(display ); - } - if (pstride) - *pstride = stride; - return image; - } - -+void CRBP::WaitVsync(void) -+{ -+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); -+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); -+ -+ VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; -+ VC_RECT_T src_rect; -+ VC_RECT_T dst_rect; -+ vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); -+ vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); -+ -+ if (m_element) -+ vc_dispmanx_element_remove( update, m_element ); -+ -+ m_element = vc_dispmanx_element_add( update, -+ display, -+ 2000, // layer -+ &dst_rect, -+ m_resource, -+ &src_rect, -+ DISPMANX_PROTECTION_NONE, -+ &alpha, -+ NULL, // clamp -+ (DISPMANX_TRANSFORM_T)0 ); -+ -+ vc_dispmanx_update_submit_sync(update); -+ vc_dispmanx_display_close( display ); -+} -+ -+ - void CRBP::Deinitialize() - { -- CSingleLock lock (m_critSection); - if (m_omx_image_init) - g_OMXImage.Deinitialize(); - - if(m_omx_initialized) - m_OMX->Deinitialize(); - -- if (m_display) -- CloseDisplay(m_display); -- - m_DllBcmHost->bcm_host_deinit(); - - if(m_initialized) -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index 029d69c..f947acc 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -38,7 +38,6 @@ - #include "DllBCM.h" - #include "OMXCore.h" - #include "threads/CriticalSection.h" --#include "threads/Event.h" - - class CRBP - { -@@ -54,8 +53,6 @@ class CRBP - bool GetCodecMpg2() { return m_codec_mpg2_enabled; } - bool GetCodecWvc1() { return m_codec_wvc1_enabled; } - void GetDisplaySize(int &width, int &height); -- DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); -- void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); - int GetGUIResolutionLimit() { return m_gui_resolution_limit; } - // stride can be null for packed output - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); -@@ -76,10 +73,10 @@ class CRBP - bool m_codec_mpg2_enabled; - bool m_codec_wvc1_enabled; - COMXCore *m_OMX; -+ DISPMANX_RESOURCE_HANDLE_T m_resource; -+ DISPMANX_ELEMENT_HANDLE_T m_element; - class DllLibOMXCore; - CCriticalSection m_critSection; -- DISPMANX_DISPLAY_HANDLE_T m_display; -- CEvent m_vsync; - }; - - extern CRBP g_RBP; -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index b6bf1fc..1529045 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) - m_desktopRes = res; - } - -- m_dispman_display = g_RBP.OpenDisplay(0); -+ m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); - - m_width = res.iWidth; - m_height = res.iHeight; -@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() - - if (m_dispman_display != DISPMANX_NO_HANDLE) - { -- g_RBP.CloseDisplay(m_dispman_display); -+ m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); - m_dispman_display = DISPMANX_NO_HANDLE; - } - DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); - -From c82c26a3a043883ba32b20473ef2a424bedb18b2 Mon Sep 17 00:00:00 2001 +From a511b714be053d7de28e6543c80ee51f3bb08330 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 19 Sep 2014 11:54:49 +0100 -Subject: [PATCH 69/88] [dvdplayer/rbp] Add pi specific option to maintain +Subject: [PATCH 62/93] [dvdplayer/rbp] Add pi specific option to maintain vsync with pll adjustment New A/V sync option in settings/video/playback to do "Adjust PLL". @@ -7530,10 +6089,10 @@ Needed updated firmware 7 files changed, 76 insertions(+), 3 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 996f682..7a27549 100755 +index 5690347..722490a 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -16004,3 +16004,8 @@ msgstr "" +@@ -16016,3 +16016,8 @@ msgstr "" msgctxt "#38005" msgid "24 fps" msgstr "" @@ -7675,10 +6234,10 @@ index e8b2ab6..02c64a0 100644 struct SInfo { diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 34e0108..3cd8e18 100644 +index 162b505..8cd2425 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp -@@ -230,4 +230,17 @@ void CRBP::ResumeVideoOutput() +@@ -196,4 +196,17 @@ void CRBP::ResumeVideoOutput() CLog::Log(LOGDEBUG, "Raspberry PI resuming video output\n"); } @@ -7697,22 +6256,22 @@ index 34e0108..3cd8e18 100644 + #endif diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index f947acc..606c24f 100644 +index 04ddaa0..1a69a8e 100644 --- a/xbmc/linux/RBP.h +++ b/xbmc/linux/RBP.h -@@ -58,6 +58,7 @@ class CRBP +@@ -57,6 +57,7 @@ class CRBP + // stride can be null for packed output unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } - void WaitVsync(); + double AdjustHDMIClock(double adjust); void SuspendVideoOutput(); void ResumeVideoOutput(); -From 4085c67b535627e1723ca8d7f82f3cdeaa67f54e Mon Sep 17 00:00:00 2001 +From 051ad4548f88ba8ed1d6ec96485cf83c4781350e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 21 Sep 2014 18:31:31 +0100 -Subject: [PATCH 70/88] hack: revert squash: don't update originaldts when +Subject: [PATCH 63/93] hack: revert squash: don't update originaldts when marked as invalid --- @@ -7720,7 +6279,7 @@ Subject: [PATCH 70/88] hack: revert squash: don't update originaldts when 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 713739b..b88adb4 100644 +index 7ae8826..7406be9 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -2106,6 +2106,7 @@ void CDVDPlayer::CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket) @@ -7732,10 +6291,10 @@ index 713739b..b88adb4 100644 } else -From 5a175022f112ed4f1d66598a3cc36831f0793b8e Mon Sep 17 00:00:00 2001 +From 232485e0c8f79dfd69047912bd1121f2ed410a99 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 27 Sep 2014 15:27:04 +0100 -Subject: [PATCH 71/88] [omxplayer] Don't sync up to passthrough audio packets +Subject: [PATCH 64/93] [omxplayer] Don't sync up to passthrough audio packets - let GPU handle it --- @@ -7763,10 +6322,10 @@ index 036552a..ce35b07 100644 unsigned pitch = (m_Passthrough || m_HWDecode) ? 1:(m_BitsPerSample >> 3) * m_InputChannels; unsigned int demuxer_samples = len / pitch; -From a266d4d3f5b8b20bd6ad2f18cadc6460b63edb74 Mon Sep 17 00:00:00 2001 +From 82d86558ddedf2b8ba7aebbabcb164b630b4867f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 27 Sep 2014 15:32:37 +0100 -Subject: [PATCH 72/88] [dvdplayer] exerimental: don't raise priority of audio +Subject: [PATCH 65/93] [dvdplayer] exerimental: don't raise priority of audio thread --- @@ -7774,7 +6333,7 @@ Subject: [PATCH 72/88] [dvdplayer] exerimental: don't raise priority of audio 1 file changed, 4 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index b88adb4..31dda29 100644 +index 7406be9..8868bcb 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -3320,7 +3320,11 @@ bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset) @@ -7790,10 +6349,10 @@ index b88adb4..31dda29 100644 } -From 8bf6e87fc6a72e35fbae5e0f076c67bf3be954e5 Mon Sep 17 00:00:00 2001 +From 52f1bdd8525393c0d0fbcc12e9bcdeaaf57b1b74 Mon Sep 17 00:00:00 2001 From: da-anda Date: Sun, 17 Aug 2014 21:09:59 +0200 -Subject: [PATCH 73/88] handle stereoscopic mode of videos in mixed playlists +Subject: [PATCH 66/93] handle stereoscopic mode of videos in mixed playlists --- language/English/strings.po | 2 +- @@ -7801,10 +6360,10 @@ Subject: [PATCH 73/88] handle stereoscopic mode of videos in mixed playlists 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 7a27549..dd46ea5 100755 +index 722490a..979116b 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -15628,7 +15628,7 @@ msgstr "" +@@ -15640,7 +15640,7 @@ msgstr "" #. Description of setting "Videos -> Playback -> Disable stereoscopic mode when playback is stopped" with label #36526 #: system/settings/settings.xml msgctxt "#36538" @@ -7961,10 +6520,10 @@ index 35ba597..b013942 100644 case 2: // Mono SetStereoMode( RENDER_STEREO_MODE_MONO ); -From a411c11e4cc4dd9a0fafe83f7886c88e4eb29c65 Mon Sep 17 00:00:00 2001 +From effc3590e018274bcfc75d386804b7f479fe5648 Mon Sep 17 00:00:00 2001 From: da-anda Date: Sat, 16 Aug 2014 11:20:54 +0200 -Subject: [PATCH 74/88] remember user selected 3D modes between videos until +Subject: [PATCH 67/93] remember user selected 3D modes between videos until playback ended --- @@ -8181,36 +6740,10 @@ index c1dfb93..cb54bd0 100644 -From bae79caf7d0aabff2e681cab22830c8192657bb0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 28 Sep 2014 17:35:31 +0100 -Subject: [PATCH 75/88] [renderer] Avoid warning for too few buffers with - bypass renderer - -Bypass renderer doesn't use a video render queue, so shouldn't generate a warning message ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 1ecdc16..cc3a76b 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -270,7 +270,8 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - if(m_QueueSize < 2) - { - m_QueueSize = 2; -- CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, renderbuffers, buffers); -+ if (m_format != RENDER_FMT_BYPASS) -+ CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, renderbuffers, buffers); - } - - m_pRenderer->SetBufferSize(m_QueueSize); - -From aaa268df687880936e1c0d9456b7e7670cf814e9 Mon Sep 17 00:00:00 2001 +From d3d223135cd4c72f4a8512bd52531a1cb3ff0c7c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 28 Sep 2014 19:28:17 +0100 -Subject: [PATCH 76/88] [mmalcodec] Introduce a preroll period to buffer up +Subject: [PATCH 68/93] [mmalcodec] Introduce a preroll period to buffer up frames on startup --- @@ -8294,10 +6827,10 @@ index b4aa571..a2da46b 100644 MMAL_COMPONENT_T *m_dec; MMAL_PORT_T *m_dec_input; -From 0ac7bd7de554636f538192fb24158493022d9b11 Mon Sep 17 00:00:00 2001 +From cae246a856bea8e55433062f726ea8c0808b7f8f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 11 Apr 2014 16:12:27 +0100 -Subject: [PATCH 77/88] [omxplayer] Add ability to log more timestamp info in +Subject: [PATCH 69/93] [omxplayer] Add ability to log more timestamp info in extra debug settings --- @@ -8310,7 +6843,7 @@ Subject: [PATCH 77/88] [omxplayer] Add ability to log more timestamp info in 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index dd46ea5..d699647 100755 +index 979116b..d2297b7 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -2886,6 +2886,11 @@ msgctxt "#679" @@ -8338,7 +6871,7 @@ index 92e2835..ad02d95 100644 #include "utils/params_check_macros.h" diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 31dda29..afdf74a 100644 +index 8868bcb..099cef0 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -1135,7 +1135,8 @@ void CDVDPlayer::OMXDoProcessing() @@ -8424,10 +6957,10 @@ index c2bd788..5c4a515 100644 || m_speed < 0) { diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 2959ae8..c9f9c94 100644 +index c7f47f4..1e9ee66 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp -@@ -1388,6 +1388,9 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se +@@ -1389,6 +1389,9 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se #ifdef HAVE_LIBCEC list.push_back(std::make_pair(g_localizeStrings.Get(679), LOGCEC)); #endif @@ -8438,10 +6971,10 @@ index 2959ae8..c9f9c94 100644 void CAdvancedSettings::setExtraLogLevel(const std::vector &components) -From 5dafcbd232750aa408bcec39e5f91b60acb23ad6 Mon Sep 17 00:00:00 2001 +From 7a6868b0568637b853f620e8f4ca6d839c65b60e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 7 Apr 2014 23:13:55 +0100 -Subject: [PATCH 78/88] [omxplayer] Add ability to dump out audio/video data +Subject: [PATCH 70/93] [omxplayer] Add ability to dump out audio/video data for later debugging --- @@ -8453,7 +6986,7 @@ Subject: [PATCH 78/88] [omxplayer] Add ability to dump out audio/video data 5 files changed, 112 insertions(+) diff --git a/language/English/strings.po b/language/English/strings.po -index d699647..856d371 100755 +index d2297b7..43699cc 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -2891,6 +2891,16 @@ msgctxt "#697" @@ -8668,10 +7201,10 @@ index 0363aaa..6cfb148 100644 if (omx_err != OMX_ErrorNone) { diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index c9f9c94..00d5e61 100644 +index 1e9ee66..123ce5f 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp -@@ -1391,6 +1391,10 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se +@@ -1392,6 +1392,10 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se #ifdef TARGET_RASPBERRY_PI list.push_back(std::make_pair(g_localizeStrings.Get(697), LOGOMXPLAYER)); #endif @@ -8683,10 +7216,10 @@ index c9f9c94..00d5e61 100644 void CAdvancedSettings::setExtraLogLevel(const std::vector &components) -From 83e540011c95472c0e41e9d3d9a69afb75a20472 Mon Sep 17 00:00:00 2001 +From cfdbd04aab22c3559349142560292192d40c67e4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 Oct 2014 16:34:51 +0100 -Subject: [PATCH 79/88] [mmalcodec] squash: Avoid preroll when using trickplay +Subject: [PATCH 71/93] [mmalcodec] squash: Avoid preroll when using trickplay --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp | 5 +++++ @@ -8781,10 +7314,10 @@ index a2da46b..4f81bbd 100644 MMAL_COMPONENT_T *m_dec; -From b1066eb16576a94e979243c89320e90246ca3b21 Mon Sep 17 00:00:00 2001 +From 7f778eb57f7645d06cf909e9ebf2bd9c65aca44a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 Oct 2014 22:45:09 +0100 -Subject: [PATCH 80/88] [mmalrenderer] Add choice of 3 deinterlace schemes +Subject: [PATCH 72/93] [mmalrenderer] Add choice of 3 deinterlace schemes --- xbmc/cores/VideoRenderers/MMALRenderer.cpp | 4 ++++ @@ -8825,7 +7358,7 @@ index cee1499..42c62db 100644 if (status != MMAL_SUCCESS) { diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index afdf74a..676b35270a 100644 +index 099cef0..c3f9b6a 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -618,6 +618,7 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback) @@ -8903,10 +7436,10 @@ index 6cfb148..37765b1 100644 image_filter.eImageFilter = OMX_ImageFilterDeInterlaceFast; else -From ef73ce6916594207a6e910cb943d7f2973365df6 Mon Sep 17 00:00:00 2001 +From e2e63f367716300550c0a65abe34b437333f7cec Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 24 Sep 2014 23:13:52 +0100 -Subject: [PATCH 81/88] [audio] Add settings option to boost centre channel +Subject: [PATCH 73/93] [audio] Add settings option to boost centre channel when downmixing This allows a dB volume increase to be added to centre channel. @@ -8924,10 +7457,10 @@ Should work with Pi Sink (dvdplayer/paplayer) and omxplayer 5 files changed, 45 insertions(+) diff --git a/language/English/strings.po b/language/English/strings.po -index 856d371..3da0a86 100755 +index 43699cc..a77a578 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -16024,3 +16024,17 @@ msgstr "" +@@ -16036,3 +16036,17 @@ msgstr "" msgctxt "#38006" msgid "Adjust PLL" msgstr "" @@ -8946,7 +7479,7 @@ index 856d371..3da0a86 100755 +msgctxt "#38009" +msgid "%i dB" diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index f4fcb7c..cd2bea6 100644 +index 9835d1f..db381ab 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2457,6 +2457,18 @@ @@ -9028,10 +7561,10 @@ index 22ee423..db2968f 100644 // stereo upmix if (upmix && m_src_channels == 2 && m_dst_channels > 2) -From 923296874b60c37352c3605b7cd2b50530414a7a Mon Sep 17 00:00:00 2001 +From 6509e957562274c96aa8f1cfbbdd34f4c0623aac Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 3 Oct 2014 18:38:07 +0100 -Subject: [PATCH 82/88] [omxcore] Skip out of flush on error +Subject: [PATCH 74/93] [omxcore] Skip out of flush on error --- xbmc/linux/OMXCore.cpp | 4 ++-- @@ -9060,10 +7593,10 @@ index 4ae29ba..4caa304 100644 OMX_ERRORTYPE omx_err = OMX_ErrorNone; -From fc2f230c5a2bb3baef275f5d61e1a16cc49380e5 Mon Sep 17 00:00:00 2001 +From 5821b6c7dc7c8471aa47addc2b7c9e9f2c34d8f6 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 3 Oct 2014 18:40:06 +0100 -Subject: [PATCH 83/88] [SinkPi] Handle multichannel layout more like OMXAudio +Subject: [PATCH 75/93] [SinkPi] Handle multichannel layout more like OMXAudio --- xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 14 +++++++------- @@ -9122,10 +7655,10 @@ index 89684e4..fd9a03d 100644 m_format = format; m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); -From d535a9edff8b08243aaf69ffb10a2b630a27aabd Mon Sep 17 00:00:00 2001 +From 745db5eb24729e5daa0cf8329c2951bfdbc925ce Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 5 Oct 2014 14:05:25 +0100 -Subject: [PATCH 84/88] [PiSink] Allow audio output latency to be set in +Subject: [PATCH 76/93] [PiSink] Allow audio output latency to be set in settings --- @@ -9136,10 +7669,10 @@ Subject: [PATCH 84/88] [PiSink] Allow audio output latency to be set in 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 3da0a86..1bc647f 100755 +index a77a578..d18a57c 100755 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -16038,3 +16038,18 @@ msgstr "" +@@ -16050,3 +16050,18 @@ msgstr "" #: system/settings/settings.xml msgctxt "#38009" msgid "%i dB" @@ -9253,10 +7786,10 @@ index 5c57999..cac5051 100644 bool m_Initialized; uint32_t m_submitted; -From 65e9f504ac1fc8177430eacfb8af8edf117a315e Mon Sep 17 00:00:00 2001 +From 51a81c742e269d89d93cf04a2c93980ccb60b01c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 6 Oct 2014 21:29:41 +0100 -Subject: [PATCH 85/88] [AE] Don't submit data to resampler when more than one +Subject: [PATCH 77/93] [AE] Don't submit data to resampler when more than one frame is buffered --- @@ -9277,10 +7810,10 @@ index e40ac2e..9e42385 100644 bool hasInput = !m_inputSamples.empty(); -From 897693bca9cc30d2346ab65efe7677f18e52df24 Mon Sep 17 00:00:00 2001 +From e371d8d055e0a05c22513f4183463c30b9f22124 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Oct 2014 22:37:52 +0100 -Subject: [PATCH 86/88] [rbp] Fix for orientation handling of Pi textures +Subject: [PATCH 78/93] [rbp] Fix for orientation handling of Pi textures There were a number of "off by one" errors in the orientations when using accelerated jpeg<->textures on the Pi. This mostly worked out, but was the root cause of this issue: @@ -9422,52 +7955,10 @@ index 3950b3f..a17bfba 100644 } } -From 7ce67eff4bd7884f01df5018c6db57c32a74ee4f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 18 Oct 2014 14:41:39 +0100 -Subject: [PATCH 87/88] [omxplayer] Restore flush/accurate seek flags to fix - issue with edl skipping - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 676b35270a..c3f9b6a 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -2176,7 +2176,7 @@ void CDVDPlayer::CheckAutoSceneSkip() - /* - * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. - */ -- m_messenger.Put(new CDVDMsgPlayerSeek(seek, true, false, true, false, true)); -+ m_messenger.Put(new CDVDMsgPlayerSeek(seek, true, m_omxplayer_mode, true, false, true)); - /* - * Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping - * if there was an error with seeking and it landed somewhere unexpected, perhaps back in the -@@ -2194,7 +2194,7 @@ void CDVDPlayer::CheckAutoSceneSkip() - /* - * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. - */ -- m_messenger.Put(new CDVDMsgPlayerSeek(cut.end + 1, true, false, true, false, true)); -+ m_messenger.Put(new CDVDMsgPlayerSeek(cut.end + 1, true, m_omxplayer_mode, true, false, true)); - /* - * Each commercial break is only skipped once so poorly detected commercial breaks can be - * manually re-entered. Start and end are recorded to prevent looping and to allow seeking back -@@ -3479,7 +3479,7 @@ void CDVDPlayer::UpdateClockMaster() - void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) - { - double startpts; -- if(accurate) -+ if(accurate && !m_omxplayer_mode) - startpts = pts; - else - startpts = DVD_NOPTS_VALUE; - -From 469f6cd8487d2af728d76bacd8a20bca730d17b6 Mon Sep 17 00:00:00 2001 +From 0263164b18169a8b4a3f3eef5b3f79ae4b9b00a7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 18 Oct 2014 18:13:43 +0100 -Subject: [PATCH 88/88] [mmal] Exit preroll when we have some decoded frames +Subject: [PATCH 79/93] [mmal] Exit preroll when we have some decoded frames --- xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 4 ++++ @@ -9488,3 +7979,929 @@ index 42c62db..0498ec7 100644 if (!m_output_ready.empty() && !m_preroll) { #if defined(MMAL_DEBUG_VERBOSE) + +From 04c568bf50711851b121bec62673d8b6b4c61e10 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sat, 18 Oct 2014 20:28:49 +0100 +Subject: [PATCH 80/93] config: Add -finstrument-functions + +--- + tools/depends/configure.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/depends/configure.in b/tools/depends/configure.in +index 9c4ef7a..bd96e41 100644 +--- a/tools/depends/configure.in ++++ b/tools/depends/configure.in +@@ -303,14 +303,14 @@ if test "$use_platform" = "raspberry-pi"; then + -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated \ + -Wno-deprecated-declarations -isystem${use_firmware}/opt/vc/include \ + -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ +- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux -finstrument-functions" + platform_cxxflags="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s \ + -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi \ + -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \ + -isystem${use_firmware}/opt/vc/include \ + -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ +- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" +- platform_ldflags="-L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos \ ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux -finstrument-functions" ++ platform_ldflags="-L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos -lmmal -lmmal_core -lmmal_util \ + -lvchiq_arm" + fi + + +From 389b36da150bd82b1a28daa09a6d677f96ac7218 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sat, 18 Oct 2014 23:02:57 +0100 +Subject: [PATCH 81/93] Revert "config: Add -finstrument-functions" + +This reverts commit 13e6b5aab2e86e8c38202147475d5251236b4e51. +--- + tools/depends/configure.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/depends/configure.in b/tools/depends/configure.in +index bd96e41..9c4ef7a 100644 +--- a/tools/depends/configure.in ++++ b/tools/depends/configure.in +@@ -303,14 +303,14 @@ if test "$use_platform" = "raspberry-pi"; then + -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated \ + -Wno-deprecated-declarations -isystem${use_firmware}/opt/vc/include \ + -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ +- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux -finstrument-functions" ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" + platform_cxxflags="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s \ + -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi \ + -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \ + -isystem${use_firmware}/opt/vc/include \ + -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ +- -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux -finstrument-functions" +- platform_ldflags="-L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos -lmmal -lmmal_core -lmmal_util \ ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" ++ platform_ldflags="-L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos \ + -lvchiq_arm" + fi + + +From 3fa51aad445494b71ff4fcd321eca9e610e76d1a Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 19 Oct 2014 13:43:46 +0100 +Subject: [PATCH 82/93] Revert "hack: revert squash: don't update originaldts + when marked as invalid" + +This reverts commit 4085c67b535627e1723ca8d7f82f3cdeaa67f54e. +--- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index c3f9b6a..5ceec72 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -2111,7 +2111,6 @@ void CDVDPlayer::CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket) + // not sure yet - flags the packets as unknown until we get confirmation on another audio/video packet + pPacket->dts = DVD_NOPTS_VALUE; + pPacket->pts = DVD_NOPTS_VALUE; +- current.originaldts = pPacket->dts; + } + } + else + +From cd42eb297f699ac3bef8aaf62dda6a2804812f7c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 19 Oct 2014 15:28:47 +0100 +Subject: [PATCH 83/93] [omxplayer] Remove unused function + +--- + xbmc/cores/omxplayer/OMXAudio.cpp | 12 ------------ + xbmc/cores/omxplayer/OMXAudio.h | 1 - + 2 files changed, 13 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp +index db2968f..4616dbd 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.cpp ++++ b/xbmc/cores/omxplayer/OMXAudio.cpp +@@ -1860,15 +1860,3 @@ unsigned int COMXAudio::SyncAC3(BYTE* pData, unsigned int iSize) + m_LostSync = true; + return iSize; + } +- +-void COMXAudio::CheckOutputBufferSize(void **buffer, int *oldSize, int newSize) +-{ +- if (newSize > *oldSize) +- { +- if (*buffer) +- _aligned_free(*buffer); +- *buffer = _aligned_malloc(newSize, 16); +- *oldSize = newSize; +- } +- memset(*buffer, 0x0, *oldSize); +-} +diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h +index 85a0b98..7cf10ad 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.h ++++ b/xbmc/cores/omxplayer/OMXAudio.h +@@ -157,7 +157,6 @@ class COMXAudio + COMXCoreTunel m_omx_tunnel_splitter_analog; + COMXCoreTunel m_omx_tunnel_splitter_hdmi; + +- static void CheckOutputBufferSize(void **buffer, int *oldSize, int newSize); + CCriticalSection m_critSection; + }; + #endif + +From 619cd15988bf4b6070e3b8e4a27fdecacb9358ff Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 19 Oct 2014 17:41:35 +0100 +Subject: [PATCH 84/93] [omxplayer] Avoid reopening stream when interlace + hasn't really changed + +--- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index 5ceec72..20fbdef 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -618,7 +618,7 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback) + m_OmxPlayerState.bOmxSentEOFs = false; + m_OmxPlayerState.threshold = 0.2f; + m_OmxPlayerState.current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; +- m_OmxPlayerState.interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); ++ m_OmxPlayerState.interlace_method = VS_INTERLACEMETHOD_MAX; + #ifdef HAS_OMXPLAYER + m_omxplayer_mode = CSettings::Get().GetBool("videoplayer.useomxplayer"); + #else +@@ -1123,10 +1123,16 @@ void CDVDPlayer::OMXDoProcessing() + float threshold = 0.1f; + bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false; + ++ if (m_OmxPlayerState.interlace_method == VS_INTERLACEMETHOD_MAX) ++ m_OmxPlayerState.interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); ++ + // if deinterlace setting has changed, we should close and open video + if (m_OmxPlayerState.current_deinterlace != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode || +- m_OmxPlayerState.interlace_method != g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod)) ++ (m_OmxPlayerState.current_deinterlace != VS_DEINTERLACEMODE_OFF && m_OmxPlayerState.interlace_method != g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod))) + { ++ CLog::Log(LOGERROR, "%s - Reopen stream due to interlace change (%d,%d,%d,%d)", __FUNCTION__, m_OmxPlayerState.current_deinterlace, CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode, ++ m_OmxPlayerState.interlace_method, g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod)); ++ + CloseStream(m_CurrentVideo, false); + OpenStream(m_CurrentVideo, m_CurrentVideo.id, m_CurrentVideo.source); + if (m_State.canseek) + +From 0754575e71f468520c79a9b6e6d92e6873b2e167 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 26 Oct 2014 16:20:35 +0000 +Subject: [PATCH 85/93] [omxplayer] Request 3 render buffers + +This avoids stuttering when using subtitle and avoids a warning of too few render buffers +--- + xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +index 5c4a515..783ac20 100644 +--- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +@@ -786,7 +786,7 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height, f + + if(!g_renderManager.Configure(width, height, + iDisplayWidth, iDisplayHeight, m_fFrameRate, flags, format, 0, +- m_hints.orientation, 0)) ++ m_hints.orientation, 3)) + { + CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); + return; + +From 05ab4bae55fc0ee55d8b37c81180c7cf99955624 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 26 Oct 2014 17:57:59 +0000 +Subject: [PATCH 86/93] [rbp] Add method for waiting for next vsync + +--- + xbmc/linux/RBP.cpp | 34 ++++++++++++++++++++++++++++++++++ + xbmc/linux/RBP.h | 3 +++ + 2 files changed, 37 insertions(+) + +diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp +index 8cd2425..3cd8e18 100644 +--- a/xbmc/linux/RBP.cpp ++++ b/xbmc/linux/RBP.cpp +@@ -33,6 +33,7 @@ CRBP::CRBP() + m_omx_initialized = false; + m_DllBcmHost = new DllBcmHost(); + m_OMX = new COMXCore(); ++ m_element = 0; + } + + CRBP::~CRBP() +@@ -54,6 +55,9 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + ++ uint32_t vc_image_ptr; ++ m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); ++ + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) + return false; +@@ -164,6 +168,36 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw + return image; + } + ++void CRBP::WaitVsync(void) ++{ ++ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); ++ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); ++ ++ VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; ++ VC_RECT_T src_rect; ++ VC_RECT_T dst_rect; ++ vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); ++ vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); ++ ++ if (m_element) ++ vc_dispmanx_element_remove( update, m_element ); ++ ++ m_element = vc_dispmanx_element_add( update, ++ display, ++ 2000, // layer ++ &dst_rect, ++ m_resource, ++ &src_rect, ++ DISPMANX_PROTECTION_NONE, ++ &alpha, ++ NULL, // clamp ++ (DISPMANX_TRANSFORM_T)0 ); ++ ++ vc_dispmanx_update_submit_sync(update); ++ vc_dispmanx_display_close( display ); ++} ++ ++ + void CRBP::Deinitialize() + { + if (m_omx_image_init) +diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h +index 1a69a8e..606c24f 100644 +--- a/xbmc/linux/RBP.h ++++ b/xbmc/linux/RBP.h +@@ -57,6 +57,7 @@ class CRBP + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); + DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } ++ void WaitVsync(); + double AdjustHDMIClock(double adjust); + + void SuspendVideoOutput(); +@@ -73,6 +74,8 @@ class CRBP + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; + COMXCore *m_OMX; ++ DISPMANX_RESOURCE_HANDLE_T m_resource; ++ DISPMANX_ELEMENT_HANDLE_T m_element; + class DllLibOMXCore; + CCriticalSection m_critSection; + }; + +From 078876c4a216bafc478e8e8ae8f73b6dbe14cb69 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 18 Aug 2014 19:09:32 +0100 +Subject: [PATCH 87/93] rbp: Use new dispmanx function for vsync callbacks + +--- + xbmc/linux/RBP.cpp | 85 ++++++++++++++----------- + xbmc/linux/RBP.h | 5 +- + xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- + 3 files changed, 52 insertions(+), 42 deletions(-) + +diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp +index 3cd8e18..d341a86 100644 +--- a/xbmc/linux/RBP.cpp ++++ b/xbmc/linux/RBP.cpp +@@ -33,7 +33,7 @@ CRBP::CRBP() + m_omx_initialized = false; + m_DllBcmHost = new DllBcmHost(); + m_OMX = new COMXCore(); +- m_element = 0; ++ m_display = DISPMANX_NO_HANDLE; + } + + CRBP::~CRBP() +@@ -55,8 +55,7 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + +- uint32_t vc_image_ptr; +- m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); ++ //OpenDisplay(0 /*screen*/); + + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) +@@ -112,13 +111,24 @@ void CRBP::LogFirmwareVerison() + CLog::Log(LOGNOTICE, "Config:\n%s", response); + } + ++DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) ++{ ++ if (m_display == DISPMANX_NO_HANDLE) ++ m_display = vc_dispmanx_display_open( 0 /*screen*/ ); ++ return m_display; ++} ++ ++void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) ++{ ++ assert(display == m_display); ++ vc_dispmanx_display_close(m_display); ++ m_display = DISPMANX_NO_HANDLE; ++} ++ + void CRBP::GetDisplaySize(int &width, int &height) + { +- DISPMANX_DISPLAY_HANDLE_T display; + DISPMANX_MODEINFO_T info; +- +- display = vc_dispmanx_display_open( 0 /*screen*/ ); +- if (vc_dispmanx_display_get_info(display, &info) == 0) ++ if (vc_dispmanx_display_get_info(m_display, &info) == 0) + { + width = info.width; + height = info.height; +@@ -128,12 +138,10 @@ void CRBP::GetDisplaySize(int &width, int &height) + width = 0; + height = 0; + } +- vc_dispmanx_display_close(display ); + } + + unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) + { +- DISPMANX_DISPLAY_HANDLE_T display; + DISPMANX_RESOURCE_HANDLE_T resource; + VC_RECT_T rect; + unsigned char *image = NULL; +@@ -148,7 +156,6 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw + if (!pstride) + flags |= DISPMANX_SNAPSHOT_PACK; + +- display = vc_dispmanx_display_open( 0 /*screen*/ ); + stride = ((width + 15) & ~15) * 4; + image = new unsigned char [height * stride]; + +@@ -156,45 +163,44 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw + { + resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); + +- vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); ++ assert(m_display != DISPMANX_NO_HANDLE); ++ vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); + + vc_dispmanx_rect_set(&rect, 0, 0, width, height); + vc_dispmanx_resource_read_data(resource, &rect, image, stride); + vc_dispmanx_resource_delete( resource ); +- vc_dispmanx_display_close(display ); + } + if (pstride) + *pstride = stride; + return image; + } + +-void CRBP::WaitVsync(void) ++ ++static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) ++{ ++ CEvent *sync = (CEvent *)arg; ++ sync->Set(); ++} ++ ++void CRBP::WaitVsync() + { +- DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); +- DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); +- +- VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; +- VC_RECT_T src_rect; +- VC_RECT_T dst_rect; +- vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); +- vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); +- +- if (m_element) +- vc_dispmanx_element_remove( update, m_element ); +- +- m_element = vc_dispmanx_element_add( update, +- display, +- 2000, // layer +- &dst_rect, +- m_resource, +- &src_rect, +- DISPMANX_PROTECTION_NONE, +- &alpha, +- NULL, // clamp +- (DISPMANX_TRANSFORM_T)0 ); +- +- vc_dispmanx_update_submit_sync(update); +- vc_dispmanx_display_close( display ); ++ int s; ++ CEvent sync; ++ DISPMANX_DISPLAY_HANDLE_T m_display = vc_dispmanx_display_open( 0 /*screen*/ ); ++ if (m_display == DISPMANX_NO_HANDLE) ++ { ++ CLog::Log(LOGDEBUG, "CRBP::%s skipping while display closed", __func__); ++ return; ++ } ++ s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&sync); ++ if (s == 0) ++ { ++ sync.Wait(); ++ } ++ else assert(0); ++ s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); ++ assert(s == 0); ++ vc_dispmanx_display_close( m_display ); + } + + +@@ -206,6 +212,9 @@ void CRBP::Deinitialize() + if(m_omx_initialized) + m_OMX->Deinitialize(); + ++ if (m_display) ++ CloseDisplay(m_display); ++ + m_DllBcmHost->bcm_host_deinit(); + + if(m_initialized) +diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h +index 606c24f..4e4156d 100644 +--- a/xbmc/linux/RBP.h ++++ b/xbmc/linux/RBP.h +@@ -53,6 +53,8 @@ class CRBP + bool GetCodecMpg2() { return m_codec_mpg2_enabled; } + bool GetCodecWvc1() { return m_codec_wvc1_enabled; } + void GetDisplaySize(int &width, int &height); ++ DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); ++ void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); +@@ -74,10 +76,9 @@ class CRBP + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; + COMXCore *m_OMX; +- DISPMANX_RESOURCE_HANDLE_T m_resource; +- DISPMANX_ELEMENT_HANDLE_T m_element; + class DllLibOMXCore; + CCriticalSection m_critSection; ++ DISPMANX_DISPLAY_HANDLE_T m_display; + }; + + extern CRBP g_RBP; +diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +index 1529045..b6bf1fc 100644 +--- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp ++++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) + m_desktopRes = res; + } + +- m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); ++ m_dispman_display = g_RBP.OpenDisplay(0); + + m_width = res.iWidth; + m_height = res.iHeight; +@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() + + if (m_dispman_display != DISPMANX_NO_HANDLE) + { +- m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); ++ g_RBP.CloseDisplay(m_dispman_display); + m_dispman_display = DISPMANX_NO_HANDLE; + } + DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); + +From ebc1f034acad1859e8172f4541d779459b5a601b Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 19 Aug 2014 17:56:45 +0100 +Subject: [PATCH 88/93] Revert "rbp: Use new dispmanx function for vsync + callbacks" + +This reverts commit afbf8fbceaa6649fb4a6bbd9a1cee6087590412b. +--- + xbmc/linux/RBP.cpp | 85 +++++++++++-------------- + xbmc/linux/RBP.h | 5 +- + xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 +- + 3 files changed, 42 insertions(+), 52 deletions(-) + +diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp +index d341a86..3cd8e18 100644 +--- a/xbmc/linux/RBP.cpp ++++ b/xbmc/linux/RBP.cpp +@@ -33,7 +33,7 @@ CRBP::CRBP() + m_omx_initialized = false; + m_DllBcmHost = new DllBcmHost(); + m_OMX = new COMXCore(); +- m_display = DISPMANX_NO_HANDLE; ++ m_element = 0; + } + + CRBP::~CRBP() +@@ -55,7 +55,8 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + +- //OpenDisplay(0 /*screen*/); ++ uint32_t vc_image_ptr; ++ m_resource = vc_dispmanx_resource_create( VC_IMAGE_RGB565, 1, 1, &vc_image_ptr ); + + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) +@@ -111,24 +112,13 @@ void CRBP::LogFirmwareVerison() + CLog::Log(LOGNOTICE, "Config:\n%s", response); + } + +-DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) +-{ +- if (m_display == DISPMANX_NO_HANDLE) +- m_display = vc_dispmanx_display_open( 0 /*screen*/ ); +- return m_display; +-} +- +-void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) +-{ +- assert(display == m_display); +- vc_dispmanx_display_close(m_display); +- m_display = DISPMANX_NO_HANDLE; +-} +- + void CRBP::GetDisplaySize(int &width, int &height) + { ++ DISPMANX_DISPLAY_HANDLE_T display; + DISPMANX_MODEINFO_T info; +- if (vc_dispmanx_display_get_info(m_display, &info) == 0) ++ ++ display = vc_dispmanx_display_open( 0 /*screen*/ ); ++ if (vc_dispmanx_display_get_info(display, &info) == 0) + { + width = info.width; + height = info.height; +@@ -138,10 +128,12 @@ void CRBP::GetDisplaySize(int &width, int &height) + width = 0; + height = 0; + } ++ vc_dispmanx_display_close(display ); + } + + unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) + { ++ DISPMANX_DISPLAY_HANDLE_T display; + DISPMANX_RESOURCE_HANDLE_T resource; + VC_RECT_T rect; + unsigned char *image = NULL; +@@ -156,6 +148,7 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw + if (!pstride) + flags |= DISPMANX_SNAPSHOT_PACK; + ++ display = vc_dispmanx_display_open( 0 /*screen*/ ); + stride = ((width + 15) & ~15) * 4; + image = new unsigned char [height * stride]; + +@@ -163,44 +156,45 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw + { + resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); + +- assert(m_display != DISPMANX_NO_HANDLE); +- vc_dispmanx_snapshot(m_display, resource, (DISPMANX_TRANSFORM_T)flags); ++ vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); + + vc_dispmanx_rect_set(&rect, 0, 0, width, height); + vc_dispmanx_resource_read_data(resource, &rect, image, stride); + vc_dispmanx_resource_delete( resource ); ++ vc_dispmanx_display_close(display ); + } + if (pstride) + *pstride = stride; + return image; + } + +- +-static void vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *arg) +-{ +- CEvent *sync = (CEvent *)arg; +- sync->Set(); +-} +- +-void CRBP::WaitVsync() ++void CRBP::WaitVsync(void) + { +- int s; +- CEvent sync; +- DISPMANX_DISPLAY_HANDLE_T m_display = vc_dispmanx_display_open( 0 /*screen*/ ); +- if (m_display == DISPMANX_NO_HANDLE) +- { +- CLog::Log(LOGDEBUG, "CRBP::%s skipping while display closed", __func__); +- return; +- } +- s = vc_dispmanx_vsync_callback(m_display, vsync_callback, (void *)&sync); +- if (s == 0) +- { +- sync.Wait(); +- } +- else assert(0); +- s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); +- assert(s == 0); +- vc_dispmanx_display_close( m_display ); ++ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( 0 /*screen*/ ); ++ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); ++ ++ VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, /*alpha 0->255*/ 0 }; ++ VC_RECT_T src_rect; ++ VC_RECT_T dst_rect; ++ vc_dispmanx_rect_set( &src_rect, 0, 0, 1 << 16, 1 << 16 ); ++ vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1 ); ++ ++ if (m_element) ++ vc_dispmanx_element_remove( update, m_element ); ++ ++ m_element = vc_dispmanx_element_add( update, ++ display, ++ 2000, // layer ++ &dst_rect, ++ m_resource, ++ &src_rect, ++ DISPMANX_PROTECTION_NONE, ++ &alpha, ++ NULL, // clamp ++ (DISPMANX_TRANSFORM_T)0 ); ++ ++ vc_dispmanx_update_submit_sync(update); ++ vc_dispmanx_display_close( display ); + } + + +@@ -212,9 +206,6 @@ void CRBP::Deinitialize() + if(m_omx_initialized) + m_OMX->Deinitialize(); + +- if (m_display) +- CloseDisplay(m_display); +- + m_DllBcmHost->bcm_host_deinit(); + + if(m_initialized) +diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h +index 4e4156d..606c24f 100644 +--- a/xbmc/linux/RBP.h ++++ b/xbmc/linux/RBP.h +@@ -53,8 +53,6 @@ class CRBP + bool GetCodecMpg2() { return m_codec_mpg2_enabled; } + bool GetCodecWvc1() { return m_codec_wvc1_enabled; } + void GetDisplaySize(int &width, int &height); +- DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); +- void CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display); + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); +@@ -76,9 +74,10 @@ class CRBP + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; + COMXCore *m_OMX; ++ DISPMANX_RESOURCE_HANDLE_T m_resource; ++ DISPMANX_ELEMENT_HANDLE_T m_element; + class DllLibOMXCore; + CCriticalSection m_critSection; +- DISPMANX_DISPLAY_HANDLE_T m_display; + }; + + extern CRBP g_RBP; +diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +index b6bf1fc..1529045 100644 +--- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp ++++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +@@ -306,7 +306,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) + m_desktopRes = res; + } + +- m_dispman_display = g_RBP.OpenDisplay(0); ++ m_dispman_display = m_DllBcmHost->vc_dispmanx_display_open(0); + + m_width = res.iWidth; + m_height = res.iHeight; +@@ -571,7 +571,7 @@ void CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow() + + if (m_dispman_display != DISPMANX_NO_HANDLE) + { +- g_RBP.CloseDisplay(m_dispman_display); ++ m_DllBcmHost->vc_dispmanx_display_close(m_dispman_display); + m_dispman_display = DISPMANX_NO_HANDLE; + } + DLOG("CEGLNativeTypeRaspberryPI::DestroyDispmaxWindow\n"); + +From 9a38a21663d36334d858afeb6973637bcdee0ddb Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 22 Oct 2014 19:43:11 +0100 +Subject: [PATCH 91/93] [rbp] Add VideoReference clock for Raspberry Pi + +--- + xbmc/video/VideoReferenceClock.cpp | 4 +++ + xbmc/video/videosync/Makefile | 1 + + xbmc/video/videosync/VideoSyncPi.cpp | 61 ++++++++++++++++++++++++++++++++++++ + xbmc/video/videosync/VideoSyncPi.h | 35 +++++++++++++++++++++ + 4 files changed, 101 insertions(+) + create mode 100644 xbmc/video/videosync/VideoSyncPi.cpp + create mode 100644 xbmc/video/videosync/VideoSyncPi.h + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index d50d196..58ad3b6 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -35,6 +35,8 @@ + #endif + #if defined(HAVE_X11) + #include "video/videosync/VideoSyncDRM.h" ++#elif defined(TARGET_RASPBERRY_PI) ++#include "video/videosync/VideoSyncPi.h" + #endif + #if defined(TARGET_WINDOWS) + #include "video/videosync/VideoSyncD3D.h" +@@ -103,6 +105,8 @@ void CVideoReferenceClock::Process() + m_pVideoSync = new CVideoSyncD3D(); + #elif defined(TARGET_DARWIN) + m_pVideoSync = new CVideoSyncCocoa(); ++#elif defined(TARGET_RASPBERRY_PI) ++ m_pVideoSync = new CVideoSyncPi(); + #endif + + SetupSuccess = m_pVideoSync->Setup(CBUpdateClock); +diff --git a/xbmc/video/videosync/Makefile b/xbmc/video/videosync/Makefile +index dc78ed7..cb50933 100644 +--- a/xbmc/video/videosync/Makefile ++++ b/xbmc/video/videosync/Makefile +@@ -1,6 +1,7 @@ + SRCS=VideoSyncGLX.cpp \ + VideoSyncCocoa.cpp \ + VideoSyncDRM.cpp \ ++ VideoSyncPi.cpp \ + + LIB=videosync.a + +diff --git a/xbmc/video/videosync/VideoSyncPi.cpp b/xbmc/video/videosync/VideoSyncPi.cpp +new file mode 100644 +index 0000000..aef016d +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncPi.cpp +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(TARGET_RASPBERRY_PI) ++ ++#include "video/videosync/VideoSyncPi.h" ++#include "guilib/GraphicContext.h" ++#include "utils/TimeUtils.h" ++#include "utils/log.h" ++#include "linux/RBP.h" ++ ++bool CVideoSyncPi::Setup(PUPDATECLOCK func) ++{ ++ UpdateClock = func; ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up RPi"); ++ return true; ++} ++ ++void CVideoSyncPi::Run(volatile bool& stop) ++{ ++ while (!stop) ++ { ++ g_RBP.WaitVsync(); ++ uint64_t now = CurrentHostCounter(); ++ UpdateClock(1, now); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock:%s Time:%.3f", __func__, now * 1e-6); ++ } ++} ++ ++void CVideoSyncPi::Cleanup() ++{ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up RPi"); ++} ++ ++float CVideoSyncPi::GetFps() ++{ ++ m_fps = g_graphicsContext.GetFPS(); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.2f", m_fps); ++ return m_fps; ++} ++ ++#endif +diff --git a/xbmc/video/videosync/VideoSyncPi.h b/xbmc/video/videosync/VideoSyncPi.h +new file mode 100644 +index 0000000..e9cea45 +--- /dev/null ++++ b/xbmc/video/videosync/VideoSyncPi.h +@@ -0,0 +1,35 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2014 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#if defined(TARGET_RASPBERRY_PI) ++ ++#include "video/videosync/VideoSync.h" ++ ++class CVideoSyncPi : public CVideoSync ++{ ++public: ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(volatile bool& stop); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++}; ++ ++#endif + +From 8e0c0fdb676b1530993fa9615124c40a03fe18df Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 26 Oct 2014 18:22:23 +0000 +Subject: [PATCH 92/93] [VideoReferenceClock] Boost priority + +This shouldn't be very busy and timing is important so increase priority +--- + xbmc/video/VideoReferenceClock.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index 58ad3b6..a65d225 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -91,6 +91,9 @@ void CVideoReferenceClock::Process() + bool SetupSuccess = false; + int64_t Now; + ++ /* This shouldn't be very busy and timing is important so increase priority */ ++ SetPriority(GetPriority()+1); ++ + while(!m_bStop) + { + //set up the vblank clock + +From e28e365cfee907ff94a2c05b00ca441a4fd4775c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 27 Oct 2014 01:07:34 +0000 +Subject: [PATCH 93/93] [cec] Reduce overflowing double_tap_timeout_ms value + +--- + system/peripherals.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/system/peripherals.xml b/system/peripherals.xml +index 9b5271a..0d2d86f 100644 +--- a/system/peripherals.xml ++++ b/system/peripherals.xml +@@ -30,7 +30,7 @@ + + + +- ++ + + +