mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
11104 lines
366 KiB
Diff
11104 lines
366 KiB
Diff
From 320046ba60eca428368d9fe229670a61ea31ff80 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 28 May 2012 10:34:39 +0200
|
|
Subject: [PATCH 01/93] videoplayer: adapt lateness detection and dropping to
|
|
buffering
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/RenderManager.cpp | 16 +-
|
|
xbmc/cores/VideoRenderers/RenderManager.h | 12 +-
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 15 +-
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 31 ++++
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 +
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 194 +++++++++++++++++----
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.h | 23 +++
|
|
7 files changed, 260 insertions(+), 38 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
index a33591d..9e2c055 100644
|
|
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
@@ -284,6 +284,8 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
|
|
m_bIsStarted = true;
|
|
m_bReconfigured = true;
|
|
m_presentstep = PRESENT_IDLE;
|
|
+ m_presentpts = DVD_NOPTS_VALUE;
|
|
+ m_sleeptime = 1.0;
|
|
m_presentevent.notifyAll();
|
|
|
|
m_firstFlipPage = false; // tempfix
|
|
@@ -627,7 +629,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode)
|
|
m_pRenderer->SetViewMode(iViewMode);
|
|
}
|
|
|
|
-void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/)
|
|
+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/)
|
|
{
|
|
{ CSharedLock lock(m_sharedSection);
|
|
|
|
@@ -695,6 +697,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L
|
|
m.timestamp = timestamp;
|
|
m.presentfield = sync;
|
|
m.presentmethod = presentmethod;
|
|
+ m.pts = pts;
|
|
requeue(m_queued, m_free);
|
|
|
|
/* signal to any waiters to check state */
|
|
@@ -1063,6 +1066,8 @@ void CXBMCRenderManager::PrepareNextRender()
|
|
m_discard.push_back(m_presentsource);
|
|
m_presentsource = idx;
|
|
m_queued.pop_front();
|
|
+ m_sleeptime = m_Queue[idx].timestamp - clocktime;
|
|
+ m_presentpts = m_Queue[idx].pts;
|
|
m_presentevent.notifyAll();
|
|
}
|
|
}
|
|
@@ -1079,3 +1084,12 @@ void CXBMCRenderManager::DiscardBuffer()
|
|
m_presentstep = PRESENT_IDLE;
|
|
m_presentevent.notifyAll();
|
|
}
|
|
+
|
|
+bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel)
|
|
+{
|
|
+ CSingleLock lock(m_presentlock);
|
|
+ sleeptime = m_sleeptime;
|
|
+ pts = m_presentpts;
|
|
+ bufferLevel = m_queued.size() + m_discard.size();
|
|
+ return true;
|
|
+}
|
|
diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
|
|
index c469795..949c652 100644
|
|
--- a/xbmc/cores/VideoRenderers/RenderManager.h
|
|
+++ b/xbmc/cores/VideoRenderers/RenderManager.h
|
|
@@ -98,10 +98,11 @@ public:
|
|
*
|
|
* @param bStop reference to stop flag of calling thread
|
|
* @param timestamp of frame delivered with AddVideoPicture
|
|
+ * @param pts used for lateness detection
|
|
* @param source depreciated
|
|
* @param sync signals frame, top, or bottom field
|
|
*/
|
|
- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE);
|
|
+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE);
|
|
unsigned int PreInit();
|
|
void UnInit();
|
|
bool Flush();
|
|
@@ -176,6 +177,12 @@ public:
|
|
int WaitForBuffer(volatile bool& bStop, int timeout = 100);
|
|
|
|
/**
|
|
+ * Can be called by player for lateness detection. This is done best by
|
|
+ * looking at the end of the queue.
|
|
+ */
|
|
+ bool GetStats(double &sleeptime, double &pts, int &bufferLevel);
|
|
+
|
|
+ /**
|
|
* Video player call this on flush in oder to discard any queued frames
|
|
*/
|
|
void DiscardBuffer();
|
|
@@ -222,6 +229,7 @@ protected:
|
|
|
|
struct SPresent
|
|
{
|
|
+ double pts;
|
|
double timestamp;
|
|
EFIELDSYNC presentfield;
|
|
EPRESENTMETHOD presentmethod;
|
|
@@ -233,6 +241,8 @@ protected:
|
|
|
|
ERenderFormat m_format;
|
|
|
|
+ double m_sleeptime;
|
|
+ double m_presentpts;
|
|
double m_presentcorr;
|
|
double m_presenterr;
|
|
double m_errorbuff[ERRORBUFFSIZE];
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
index f6751f4..fb34463 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
@@ -132,6 +132,10 @@ struct DVDVideoUserData
|
|
#define DVP_FLAG_NOSKIP 0x00000010 // indicate this picture should never be dropped
|
|
#define DVP_FLAG_DROPPED 0x00000020 // indicate that this picture has been dropped in decoder stage, will have no data
|
|
|
|
+#define DVP_FLAG_DROPDEINT 0x00000040 // indicate that this picture was requested to have been dropped in deint stage
|
|
+#define DVP_FLAG_NO_POSTPROC 0x00000100
|
|
+#define DVP_FLAG_DRAIN 0x00000200
|
|
+
|
|
// DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2!
|
|
|
|
#define DVP_QSCALE_UNKNOWN 0
|
|
@@ -149,6 +153,9 @@ class CDVDCodecOptions;
|
|
#define VC_PICTURE 0x00000004 // the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data
|
|
#define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data
|
|
#define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again
|
|
+#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped
|
|
+#define VC_HURRY 0x00000040
|
|
+
|
|
class CDVDVideoCodec
|
|
{
|
|
public:
|
|
@@ -266,7 +273,6 @@ public:
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
/**
|
|
* Number of references to old pictures that are allowed to
|
|
* be retained when calling decode on the next demux packet
|
|
@@ -283,4 +289,11 @@ public:
|
|
* Interact with user settings so that user disabled codecs are disabled
|
|
*/
|
|
static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id);
|
|
+
|
|
+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced)
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ virtual void SetCodecControl(int flags) {}
|
|
};
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index 9b6a34d..413151d 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -164,6 +164,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
|
|
m_iLastKeyframe = 0;
|
|
m_dts = DVD_NOPTS_VALUE;
|
|
m_started = false;
|
|
+ m_decoderPts = DVD_NOPTS_VALUE;
|
|
}
|
|
|
|
CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
|
|
@@ -355,6 +356,14 @@ void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop)
|
|
{
|
|
if( m_pCodecContext )
|
|
{
|
|
+ if (bDrop && m_pHardware && m_pHardware->CanSkipDeint())
|
|
+ {
|
|
+ m_requestSkipDeint = true;
|
|
+ bDrop = false;
|
|
+ }
|
|
+ else
|
|
+ m_requestSkipDeint = false;
|
|
+
|
|
// i don't know exactly how high this should be set
|
|
// couldn't find any good docs on it. think it varies
|
|
// from codec to codec on what it does
|
|
@@ -556,6 +565,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
void CDVDVideoCodecFFmpeg::Reset()
|
|
{
|
|
m_started = false;
|
|
+ m_decoderPts = DVD_NOPTS_VALUE;
|
|
m_iLastKeyframe = m_pCodecContext->has_b_frames;
|
|
m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext);
|
|
|
|
@@ -665,6 +675,22 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
else
|
|
pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
|
|
|
|
+ if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE)
|
|
+ m_decoderPts = pDvdVideoPicture->pts;
|
|
+ else
|
|
+ m_decoderPts = m_dts;
|
|
+
|
|
+ if (m_requestSkipDeint)
|
|
+ {
|
|
+ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPDEINT;
|
|
+ m_skippedDeint = 1;
|
|
+ }
|
|
+ else
|
|
+ m_skippedDeint = 0;
|
|
+
|
|
+ m_requestSkipDeint = false;
|
|
+ pDvdVideoPicture->iFlags |= m_codecControlFlags;
|
|
+
|
|
if(!m_started)
|
|
pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
|
|
|
|
@@ -924,3 +950,8 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
|
|
else
|
|
return 0;
|
|
}
|
|
+
|
|
+void CDVDVideoCodecFFmpeg::SetCodecControl(int flags)
|
|
+{
|
|
+ m_codecControlFlags = flags;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
index 2287031..8376f72 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
@@ -45,6 +45,7 @@ public:
|
|
virtual int Check (AVCodecContext* avctx) = 0;
|
|
virtual void Reset () {}
|
|
virtual unsigned GetAllowedReferences() { return 0; }
|
|
+ virtual bool CanSkipDeint() {return false; }
|
|
virtual const std::string Name() = 0;
|
|
virtual CCriticalSection* Section() { return NULL; }
|
|
};
|
|
@@ -62,6 +63,8 @@ public:
|
|
virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open
|
|
virtual unsigned GetConvergeCount();
|
|
virtual unsigned GetAllowedReferences();
|
|
+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;}
|
|
+ virtual void SetCodecControl(int flags);
|
|
|
|
bool IsHardwareAllowed() { return !m_bSoftware; }
|
|
IHardwareDecoder * GetHardware() { return m_pHardware; };
|
|
@@ -127,4 +130,8 @@ protected:
|
|
double m_dts;
|
|
bool m_started;
|
|
std::vector<PixelFormat> m_formats;
|
|
+ double m_decoderPts, m_decoderInterval;
|
|
+ int m_skippedDeint;
|
|
+ bool m_requestSkipDeint;
|
|
+ int m_codecControlFlags;
|
|
};
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 99b3155..4fad1a3 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -38,6 +38,7 @@
|
|
#include "DVDCodecs/DVDCodecs.h"
|
|
#include "DVDCodecs/Overlay/DVDOverlayCodecCC.h"
|
|
#include "DVDCodecs/Overlay/DVDOverlaySSA.h"
|
|
+#include "guilib/GraphicContext.h"
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <numeric>
|
|
@@ -320,8 +321,10 @@ void CDVDPlayerVideo::Process()
|
|
|
|
int iDropped = 0; //frames dropped in a row
|
|
bool bRequestDrop = false;
|
|
+ int iDropDirective;
|
|
|
|
m_videoStats.Start();
|
|
+ m_droppingStats.Reset();
|
|
|
|
while (!m_bStop)
|
|
{
|
|
@@ -431,6 +434,7 @@ void CDVDPlayerVideo::Process()
|
|
picture.iFlags &= ~DVP_FLAG_ALLOCATED;
|
|
m_packets.clear();
|
|
m_started = false;
|
|
+ m_droppingStats.Reset();
|
|
}
|
|
else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush())
|
|
{
|
|
@@ -443,6 +447,7 @@ void CDVDPlayerVideo::Process()
|
|
//we need to recalculate the framerate
|
|
//TODO: this needs to be set on a streamchange instead
|
|
ResetFrameRateCalc();
|
|
+ m_droppingStats.Reset();
|
|
|
|
m_stalled = true;
|
|
m_started = false;
|
|
@@ -460,8 +465,10 @@ void CDVDPlayerVideo::Process()
|
|
m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;
|
|
if(m_speed == DVD_PLAYSPEED_PAUSE)
|
|
m_iNrOfPicturesNotToSkip = 0;
|
|
+
|
|
if (m_pVideoCodec)
|
|
m_pVideoCodec->SetSpeed(m_speed);
|
|
+ m_droppingStats.Reset();
|
|
}
|
|
else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
|
|
{
|
|
@@ -507,6 +514,28 @@ void CDVDPlayerVideo::Process()
|
|
m_iNrOfPicturesNotToSkip = 1;
|
|
}
|
|
|
|
+ bRequestDrop = false;
|
|
+ iDropDirective = CalcDropRequirement(pts);
|
|
+ if (iDropDirective & EOS_VERYLATE)
|
|
+ {
|
|
+ if (m_bAllowDrop)
|
|
+ {
|
|
+ m_pullupCorrection.Flush();
|
|
+ bRequestDrop = true;
|
|
+ }
|
|
+ }
|
|
+ int codecControl = 0;
|
|
+ if (iDropDirective & EOS_BUFFER_LEVEL)
|
|
+ codecControl |= DVP_FLAG_DRAIN;
|
|
+ if (m_speed > DVD_PLAYSPEED_NORMAL)
|
|
+ codecControl |= DVP_FLAG_NO_POSTPROC;
|
|
+ m_pVideoCodec->SetCodecControl(codecControl);
|
|
+ if (iDropDirective & EOS_DROPPED)
|
|
+ {
|
|
+ m_iDroppedFrames++;
|
|
+ iDropped++;
|
|
+ }
|
|
+
|
|
if (m_messageQueue.GetDataSize() == 0
|
|
|| m_speed < 0)
|
|
{
|
|
@@ -559,15 +588,7 @@ void CDVDPlayerVideo::Process()
|
|
}
|
|
|
|
m_videoStats.AddSampleBytes(pPacket->iSize);
|
|
- // assume decoder dropped a picture if it didn't give us any
|
|
- // picture from a demux packet, this should be reasonable
|
|
- // for libavformat as a demuxer as it normally packetizes
|
|
- // pictures when they come from demuxer
|
|
- if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE))
|
|
- {
|
|
- m_iDroppedFrames++;
|
|
- iDropped++;
|
|
- }
|
|
+
|
|
// reset the request, the following while loop may break before
|
|
// setting the flag to a new value
|
|
bRequestDrop = false;
|
|
@@ -1176,33 +1197,12 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
|
|
m_FlipTimeStamp += max(0.0, iSleepTime);
|
|
m_FlipTimeStamp += iFrameDuration;
|
|
|
|
- if (iSleepTime <= 0 && m_speed)
|
|
- m_iLateFrames++;
|
|
- else
|
|
- m_iLateFrames = 0;
|
|
-
|
|
- // ask decoder to drop frames next round, as we are very late
|
|
- if(m_iLateFrames > 10)
|
|
+ if ((pPicture->iFlags & DVP_FLAG_DROPPED))
|
|
{
|
|
- if (!(pPicture->iFlags & DVP_FLAG_NOSKIP))
|
|
- {
|
|
- //if we're calculating the framerate,
|
|
- //don't drop frames until we've calculated a stable framerate
|
|
- if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL)
|
|
- {
|
|
- result |= EOS_VERYLATE;
|
|
- m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it
|
|
- }
|
|
- m_iDroppedRequest++;
|
|
- }
|
|
- }
|
|
- else
|
|
- {
|
|
- m_iDroppedRequest = 0;
|
|
- }
|
|
-
|
|
- if( (pPicture->iFlags & DVP_FLAG_DROPPED) )
|
|
+ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate);
|
|
+ CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__);
|
|
return result | EOS_DROPPED;
|
|
+ }
|
|
|
|
// set fieldsync if picture is interlaced
|
|
EFIELDSYNC mDisplayField = FS_NONE;
|
|
@@ -1235,7 +1235,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
|
|
if (index < 0)
|
|
return EOS_DROPPED;
|
|
|
|
- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField);
|
|
+ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField);
|
|
|
|
return result;
|
|
#else
|
|
@@ -1535,3 +1535,127 @@ void CDVDPlayerVideo::CalcFrameRate()
|
|
m_iFrameRateCount = 0;
|
|
}
|
|
}
|
|
+
|
|
+int CDVDPlayerVideo::CalcDropRequirement(double pts)
|
|
+{
|
|
+ int result = 0;
|
|
+ double iSleepTime;
|
|
+ double iDecoderPts, iRenderPts;
|
|
+ double iInterval;
|
|
+ int interlaced;
|
|
+ double iGain;
|
|
+ double iLateness;
|
|
+ bool bNewFrame;
|
|
+ int iSkippedDeint = 0;
|
|
+ int iBufferLevel;
|
|
+
|
|
+ // get decoder stats
|
|
+ if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced))
|
|
+ iDecoderPts = pts;
|
|
+ if (iDecoderPts == DVD_NOPTS_VALUE)
|
|
+ iDecoderPts = pts;
|
|
+
|
|
+ // get render stats
|
|
+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel);
|
|
+
|
|
+ if (iBufferLevel < 0)
|
|
+ result |= EOS_BUFFER_LEVEL;
|
|
+ else if (iBufferLevel < 2)
|
|
+ {
|
|
+ result |= EOS_BUFFER_LEVEL;
|
|
+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - hurry: %d", iBufferLevel);
|
|
+ }
|
|
+
|
|
+ bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts;
|
|
+
|
|
+ if (interlaced)
|
|
+ iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE;
|
|
+ else
|
|
+ iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE;
|
|
+
|
|
+ if (m_droppingStats.m_lastDecoderPts > 0
|
|
+ && bNewFrame
|
|
+ && m_bAllowDrop
|
|
+ && m_droppingStats.m_dropRequests > 0)
|
|
+ {
|
|
+ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE;
|
|
+ if (iSkippedDeint)
|
|
+ {
|
|
+ CDroppingStats::CGain gain;
|
|
+ gain.gain = 1/m_fFrameRate;
|
|
+ gain.pts = iDecoderPts;
|
|
+ m_droppingStats.m_gain.push_back(gain);
|
|
+ m_droppingStats.m_totalGain += gain.gain;
|
|
+ result |= EOS_DROPPED;
|
|
+ m_droppingStats.m_dropRequests = 0;
|
|
+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped de-interlacing cycle, Sleeptime: %f, Bufferlevel: %d", iSleepTime, iBufferLevel);
|
|
+ }
|
|
+ else if (iGain > 1/m_fFrameRate)
|
|
+ {
|
|
+ CDroppingStats::CGain gain;
|
|
+ gain.gain = iGain;
|
|
+ gain.pts = iDecoderPts;
|
|
+ m_droppingStats.m_gain.push_back(gain);
|
|
+ m_droppingStats.m_totalGain += iGain;
|
|
+ result |= EOS_DROPPED;
|
|
+ m_droppingStats.m_dropRequests = 0;
|
|
+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped in decoder, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain);
|
|
+ }
|
|
+ }
|
|
+ m_droppingStats.m_lastDecoderPts = iDecoderPts;
|
|
+
|
|
+ // subtract gains
|
|
+ while (!m_droppingStats.m_gain.empty() &&
|
|
+ iRenderPts >= m_droppingStats.m_gain.front().pts)
|
|
+ {
|
|
+ m_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().gain;
|
|
+ m_droppingStats.m_gain.pop_front();
|
|
+ }
|
|
+
|
|
+ // calculate lateness
|
|
+ iLateness = iSleepTime + m_droppingStats.m_totalGain;
|
|
+ if (iLateness < 0 && m_speed)
|
|
+ {
|
|
+ if (bNewFrame)
|
|
+ m_droppingStats.m_lateFrames++;
|
|
+
|
|
+ // if lateness is smaller than frametime, we observe this state
|
|
+ // for 10 cycles
|
|
+ if (m_droppingStats.m_lateFrames > 10 || iLateness < -2/m_fFrameRate)
|
|
+ {
|
|
+ // is frame allowed to skip
|
|
+ if (m_iNrOfPicturesNotToSkip <= 0)
|
|
+ {
|
|
+ result |= EOS_VERYLATE;
|
|
+ if (bNewFrame)
|
|
+ m_droppingStats.m_dropRequests++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_droppingStats.m_dropRequests = 0;
|
|
+ m_droppingStats.m_lateFrames = 0;
|
|
+ }
|
|
+ m_droppingStats.m_lastRenderPts = iRenderPts;
|
|
+ return result;
|
|
+}
|
|
+
|
|
+void CDroppingStats::Reset()
|
|
+{
|
|
+ m_gain.clear();
|
|
+ m_totalGain = 0;
|
|
+ m_lastDecoderPts = 0;
|
|
+ m_lastRenderPts = 0;
|
|
+ m_lateFrames = 0;
|
|
+ m_dropRequests = 0;
|
|
+}
|
|
+
|
|
+void CDroppingStats::AddOutputDropGain(double pts, double frametime)
|
|
+{
|
|
+ CDroppingStats::CGain gain;
|
|
+ gain.gain = frametime;
|
|
+ gain.pts = pts;
|
|
+ m_gain.push_back(gain);
|
|
+ m_totalGain += frametime;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
index f8ad541..186e271 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
@@ -36,6 +36,25 @@ class CDVDOverlayCodecCC;
|
|
|
|
#define VIDEO_PICTURE_QUEUE_SIZE 1
|
|
|
|
+class CDroppingStats
|
|
+{
|
|
+public:
|
|
+ void Reset();
|
|
+ void AddOutputDropGain(double pts, double frametime);
|
|
+ struct CGain
|
|
+ {
|
|
+ double gain;
|
|
+ double pts;
|
|
+ };
|
|
+ std::deque<CGain> m_gain;
|
|
+ double m_totalGain;
|
|
+ double m_lastDecoderPts;
|
|
+ double m_lastRenderPts;
|
|
+ unsigned int m_lateFrames;
|
|
+ unsigned int m_dropRequests;
|
|
+};
|
|
+
|
|
+
|
|
class CDVDPlayerVideo : public CThread
|
|
{
|
|
public:
|
|
@@ -104,6 +123,7 @@ protected:
|
|
#define EOS_ABORT 1
|
|
#define EOS_DROPPED 2
|
|
#define EOS_VERYLATE 4
|
|
+#define EOS_BUFFER_LEVEL 8
|
|
|
|
void AutoCrop(DVDVideoPicture* pPicture);
|
|
void AutoCrop(DVDVideoPicture *pPicture, RECT &crop);
|
|
@@ -129,6 +149,7 @@ protected:
|
|
|
|
void ResetFrameRateCalc();
|
|
void CalcFrameRate();
|
|
+ int CalcDropRequirement(double pts);
|
|
|
|
double m_fFrameRate; //framerate of the video currently playing
|
|
bool m_bCalcFrameRate; //if we should calculate the framerate from the timestamps
|
|
@@ -182,5 +203,7 @@ protected:
|
|
CPullupCorrection m_pullupCorrection;
|
|
|
|
std::list<DVDMessageListItem> m_packets;
|
|
+
|
|
+ CDroppingStats m_droppingStats;
|
|
};
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From cbecaef2fb4c319c179c2283e82cead122f3bab5 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 2 Sep 2012 16:05:21 +0200
|
|
Subject: [PATCH 02/93] video player: present correct pts to user for a/v sync
|
|
(after buffering in renderer)
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 25 +++++++++++++++++++++++++
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.h | 2 +-
|
|
2 files changed, 26 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 4fad1a3..1d29b6f 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -1455,6 +1455,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc()
|
|
g_advancedSettings.m_videoFpsDetect == 0;
|
|
}
|
|
|
|
+double CDVDPlayerVideo::GetCurrentPts()
|
|
+{
|
|
+ double iSleepTime, iRenderPts;
|
|
+ int iBufferLevel;
|
|
+
|
|
+ // get render stats
|
|
+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel);
|
|
+
|
|
+ if( m_stalled )
|
|
+ iRenderPts = DVD_NOPTS_VALUE;
|
|
+ else
|
|
+ iRenderPts = iRenderPts - max(0.0, iSleepTime);
|
|
+
|
|
+ return iRenderPts;
|
|
+}
|
|
+
|
|
#define MAXFRAMERATEDIFF 0.01
|
|
#define MAXFRAMESERR 1000
|
|
|
|
@@ -1573,6 +1589,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts)
|
|
else
|
|
iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE;
|
|
|
|
+
|
|
+ m_FlipTimeStamp = m_pClock->GetAbsoluteClock() + max(0.0, iSleepTime) + iInterval;
|
|
+
|
|
+ if( m_stalled )
|
|
+ m_iCurrentPts = DVD_NOPTS_VALUE;
|
|
+ else
|
|
+ m_iCurrentPts = iRenderPts - max(0.0, iSleepTime);
|
|
+
|
|
+
|
|
if (m_droppingStats.m_lastDecoderPts > 0
|
|
&& bNewFrame
|
|
&& m_bAllowDrop
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
index 186e271..59c7f09 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
@@ -100,7 +100,7 @@ public:
|
|
|
|
bool InitializedOutputDevice();
|
|
|
|
- double GetCurrentPts() { return m_iCurrentPts; }
|
|
+ double GetCurrentPts();
|
|
int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); }
|
|
|
|
double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 893b7955a20aeaf74b06b7de1c28e08ef05625dd Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sat, 16 Feb 2013 18:25:53 +0100
|
|
Subject: [PATCH 03/93] videoplayer: some rework and documentation
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 28 ++++++++++++++++++++--
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 11 +++++++++
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +-
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +-
|
|
4 files changed, 39 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
index fb34463..ecd325c 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
|
|
@@ -154,7 +154,6 @@ class CDVDCodecOptions;
|
|
#define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data
|
|
#define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again
|
|
#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped
|
|
-#define VC_HURRY 0x00000040
|
|
|
|
class CDVDVideoCodec
|
|
{
|
|
@@ -290,10 +289,35 @@ public:
|
|
*/
|
|
static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id);
|
|
|
|
- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced)
|
|
+ /* For calculation of dropping requirements player asks for some information.
|
|
+ *
|
|
+ * - pts : right after decoder, used to detect gaps (dropped frames in decoder)
|
|
+ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle
|
|
+ * instead of dropping a full frame
|
|
+ * - interlaced : when detecting gaps in pts, player needs to know whether
|
|
+ * it's interlaced or not
|
|
+ *
|
|
+ * If codec does not implement this method, pts of decoded frame at input
|
|
+ * video player is used. In case coded does post-proc and de-interlacing there
|
|
+ * may be quite some frames queued up between exit decoder and entry player.
|
|
+ */
|
|
+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
+ /**
|
|
+ * Codec can be informed by player with the following flags:
|
|
+ *
|
|
+ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off
|
|
+ * postprocessing and de-interlacing
|
|
+ *
|
|
+ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing.
|
|
+ * If video buffers in RenderManager are about to run dry,
|
|
+ * this is signaled to codec. Codec can wait for post-proc
|
|
+ * to be finished instead of returning empty and getting another
|
|
+ * packet.
|
|
+ *
|
|
+ */
|
|
virtual void SetCodecControl(int flags) {}
|
|
};
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index 413151d..b59c1ee 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -951,6 +951,17 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
|
|
return 0;
|
|
}
|
|
|
|
+bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced)
|
|
+{
|
|
+ pts = m_decoderPts;
|
|
+ skippedDeint = m_skippedDeint;
|
|
+ if (m_pFrame)
|
|
+ interlaced = m_pFrame->interlaced_frame;
|
|
+ else
|
|
+ interlaced = 0;
|
|
+ return true;
|
|
+}
|
|
+
|
|
void CDVDVideoCodecFFmpeg::SetCodecControl(int flags)
|
|
{
|
|
m_codecControlFlags = flags;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
index 8376f72..c0ce198 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
@@ -63,7 +63,7 @@ public:
|
|
virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open
|
|
virtual unsigned GetConvergeCount();
|
|
virtual unsigned GetAllowedReferences();
|
|
- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;}
|
|
+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced);
|
|
virtual void SetCodecControl(int flags);
|
|
|
|
bool IsHardwareAllowed() { return !m_bSoftware; }
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 1d29b6f..ee07f30 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -1566,7 +1566,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts)
|
|
int iBufferLevel;
|
|
|
|
// get decoder stats
|
|
- if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced))
|
|
+ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced))
|
|
iDecoderPts = pts;
|
|
if (iDecoderPts == DVD_NOPTS_VALUE)
|
|
iDecoderPts = pts;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From af8d9a25047777c7dd11797b07168a7e7f6fe1ce Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sat, 1 Jun 2013 11:21:19 +0200
|
|
Subject: [PATCH 04/93] renderer: bump buffers to 5
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/BaseRenderer.h | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h
|
|
index dc2712a..9edfbd4 100644
|
|
--- a/xbmc/cores/VideoRenderers/BaseRenderer.h
|
|
+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h
|
|
@@ -29,7 +29,7 @@
|
|
|
|
#define MAX_PLANES 3
|
|
#define MAX_FIELDS 3
|
|
-#define NUM_BUFFERS 3
|
|
+#define NUM_BUFFERS 5
|
|
|
|
class CSetting;
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 2c520fc1ace027ecbecd06eb60aebe607e04c538 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 28 May 2012 10:41:31 +0200
|
|
Subject: [PATCH 05/93] videoplayer: update frametime, it might change due to
|
|
fps detection
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index ee07f30..b3175cd 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -708,6 +708,8 @@ void CDVDPlayerVideo::Process()
|
|
|
|
int iResult = OutputPicture(&picture, pts);
|
|
|
|
+ frametime = (double)DVD_TIME_BASE/m_fFrameRate;
|
|
+
|
|
if(m_started == false)
|
|
{
|
|
m_codecname = m_pVideoCodec->GetName();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From e4e8f007146ed6d84a10f56a8ec1c8f70643b050 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 28 May 2012 10:43:06 +0200
|
|
Subject: [PATCH 06/93] videoplayer: give streams with invalid fps a chance for
|
|
fps detection
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index b3175cd..9c36bdb 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -1497,7 +1497,7 @@ void CDVDPlayerVideo::CalcFrameRate()
|
|
double frameduration = m_pullupCorrection.GetFrameDuration();
|
|
|
|
if (frameduration == DVD_NOPTS_VALUE ||
|
|
- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1))
|
|
+ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid)))
|
|
{
|
|
//reset the stored framerates if no good framerate was detected
|
|
m_fStableFrameRate = 0.0;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From f565af531ea544c02207993205a2c1f79e003a77 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 28 May 2012 10:49:05 +0200
|
|
Subject: [PATCH 07/93] dvdplayer: allow rewinding at end of stream, do a seek
|
|
after rewind
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++-
|
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
index b056c8b..0d2b4ae 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
@@ -1633,7 +1633,7 @@ void CDVDPlayer::HandlePlaySpeed()
|
|
|
|
}
|
|
else if (m_CurrentVideo.id >= 0
|
|
- && m_CurrentVideo.inited == true
|
|
+ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file
|
|
&& m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts()
|
|
&& m_SpeedState.lasttime != GetTime())
|
|
{
|
|
@@ -2294,6 +2294,12 @@ void CDVDPlayer::HandleMessages()
|
|
pvrinputstream->Pause( speed == 0 );
|
|
}
|
|
|
|
+ // do a seek after rewind, clock is not in sync with current pts
|
|
+ if (m_playSpeed < 0 && speed >= 0)
|
|
+ {
|
|
+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true));
|
|
+ }
|
|
+
|
|
// if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE
|
|
// audioplayer, stops outputing audio to audiorendere, but still tries to
|
|
// sleep an correct amount for each packet
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From c686480a53d7cdcf63a3000bf408ef4153e359a1 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 15:22:05 +0200
|
|
Subject: [PATCH 08/93] X11: ditch SDL for video and window events
|
|
|
|
---
|
|
xbmc/Application.cpp | 2 +-
|
|
xbmc/system.h | 5 +
|
|
xbmc/windowing/Makefile.in | 1 +
|
|
xbmc/windowing/WinEvents.cpp | 4 +
|
|
xbmc/windowing/WinEventsX11.cpp | 784 ++++++++++++++++++++++++++++++++++++
|
|
xbmc/windowing/WinEventsX11.h | 65 +++
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 386 ++++++++++++------
|
|
xbmc/windowing/X11/WinSystemX11.h | 10 +-
|
|
8 files changed, 1129 insertions(+), 128 deletions(-)
|
|
create mode 100644 xbmc/windowing/WinEventsX11.cpp
|
|
create mode 100644 xbmc/windowing/WinEventsX11.h
|
|
|
|
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
|
|
index 265881f..43c4517 100644
|
|
--- a/xbmc/Application.cpp
|
|
+++ b/xbmc/Application.cpp
|
|
@@ -907,7 +907,7 @@ bool CApplication::CreateGUI()
|
|
|
|
uint32_t sdlFlags = 0;
|
|
|
|
-#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)
|
|
+#if (defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)) && !defined(HAS_GLX)
|
|
sdlFlags |= SDL_INIT_VIDEO;
|
|
#endif
|
|
|
|
diff --git a/xbmc/system.h b/xbmc/system.h
|
|
index 1f4e15f..075e44a 100644
|
|
--- a/xbmc/system.h
|
|
+++ b/xbmc/system.h
|
|
@@ -171,16 +171,21 @@
|
|
#define HAS_GL
|
|
#ifdef HAVE_X11
|
|
#define HAS_GLX
|
|
+#define HAS_X11_WIN_EVENTS
|
|
#endif
|
|
#ifdef HAVE_SDL
|
|
#define HAS_SDL
|
|
#ifndef HAS_SDL_OPENGL
|
|
#define HAS_SDL_OPENGL
|
|
#endif
|
|
+#ifndef HAVE_X11
|
|
#define HAS_SDL_WIN_EVENTS
|
|
+#endif
|
|
#else
|
|
+#ifndef HAVE_X11
|
|
#define HAS_LINUX_EVENTS
|
|
#endif
|
|
+#endif
|
|
#define HAS_LINUX_NETWORK
|
|
#define HAS_LIRC
|
|
#ifdef HAVE_LIBPULSE
|
|
diff --git a/xbmc/windowing/Makefile.in b/xbmc/windowing/Makefile.in
|
|
index 6704967..4b41723 100644
|
|
--- a/xbmc/windowing/Makefile.in
|
|
+++ b/xbmc/windowing/Makefile.in
|
|
@@ -1,6 +1,7 @@
|
|
SRCS=WinEventsSDL.cpp \
|
|
WinEventsLinux.cpp \
|
|
WinEventsWayland.cpp \
|
|
+ WinEventsX11.cpp \
|
|
WinSystem.cpp \
|
|
WinEvents.cpp
|
|
|
|
diff --git a/xbmc/windowing/WinEvents.cpp b/xbmc/windowing/WinEvents.cpp
|
|
index 1022ad2..8e64497 100644
|
|
--- a/xbmc/windowing/WinEvents.cpp
|
|
+++ b/xbmc/windowing/WinEvents.cpp
|
|
@@ -42,6 +42,10 @@
|
|
#include "WinEventsSDL.h"
|
|
#define WinEventsType CWinEventsSDL
|
|
|
|
+#elif (defined(TARGET_FREEBSD) || defined(TARGET_LINUX)) && defined(HAS_X11_WIN_EVENTS)
|
|
+#include "WinEventsX11.h"
|
|
+#define WinEventsType CWinEventsX11
|
|
+
|
|
#elif defined(HAVE_WAYLAND)
|
|
#include "WinEventsWayland.h"
|
|
#define WinEventsType CWinEventsWayland
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
new file mode 100644
|
|
index 0000000..ad58aad
|
|
--- /dev/null
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -0,0 +1,784 @@
|
|
+/*
|
|
+* Copyright (C) 2005-2012 Team XBMC
|
|
+* http://www.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, write to
|
|
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+* http://www.gnu.org/copyleft/gpl.html
|
|
+*
|
|
+*/
|
|
+
|
|
+#include "system.h"
|
|
+
|
|
+#ifdef HAS_X11_WIN_EVENTS
|
|
+
|
|
+#include "WinEvents.h"
|
|
+#include "WinEventsX11.h"
|
|
+#include "Application.h"
|
|
+#include "ApplicationMessenger.h"
|
|
+#include <X11/Xlib.h>
|
|
+#include "X11/WinSystemX11GL.h"
|
|
+#include "X11/keysymdef.h"
|
|
+#include "X11/XF86keysym.h"
|
|
+#include "utils/log.h"
|
|
+#include "guilib/GUIWindowManager.h"
|
|
+#include "input/MouseStat.h"
|
|
+
|
|
+CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0;
|
|
+
|
|
+static uint32_t SymMappingsX11[][2] =
|
|
+{
|
|
+ {XK_BackSpace, XBMCK_BACKSPACE}
|
|
+, {XK_Tab, XBMCK_TAB}
|
|
+, {XK_Clear, XBMCK_CLEAR}
|
|
+, {XK_Return, XBMCK_RETURN}
|
|
+, {XK_Pause, XBMCK_PAUSE}
|
|
+, {XK_Escape, XBMCK_ESCAPE}
|
|
+, {XK_Delete, XBMCK_DELETE}
|
|
+// multi-media keys
|
|
+, {XF86XK_Back, XBMCK_BROWSER_BACK}
|
|
+, {XF86XK_Forward, XBMCK_BROWSER_FORWARD}
|
|
+, {XF86XK_Refresh, XBMCK_BROWSER_REFRESH}
|
|
+, {XF86XK_Stop, XBMCK_BROWSER_STOP}
|
|
+, {XF86XK_Search, XBMCK_BROWSER_SEARCH}
|
|
+, {XF86XK_Favorites, XBMCK_BROWSER_FAVORITES}
|
|
+, {XF86XK_HomePage, XBMCK_BROWSER_HOME}
|
|
+, {XF86XK_AudioMute, XBMCK_VOLUME_MUTE}
|
|
+, {XF86XK_AudioLowerVolume, XBMCK_VOLUME_DOWN}
|
|
+, {XF86XK_AudioRaiseVolume, XBMCK_VOLUME_UP}
|
|
+, {XF86XK_AudioNext, XBMCK_MEDIA_NEXT_TRACK}
|
|
+, {XF86XK_AudioPrev, XBMCK_MEDIA_PREV_TRACK}
|
|
+, {XF86XK_AudioStop, XBMCK_MEDIA_STOP}
|
|
+, {XF86XK_AudioPause, XBMCK_MEDIA_PLAY_PAUSE}
|
|
+, {XF86XK_Mail, XBMCK_LAUNCH_MAIL}
|
|
+, {XF86XK_Select, XBMCK_LAUNCH_MEDIA_SELECT}
|
|
+, {XF86XK_Launch0, XBMCK_LAUNCH_APP1}
|
|
+, {XF86XK_Launch1, XBMCK_LAUNCH_APP2}
|
|
+, {XF86XK_WWW, XBMCK_LAUNCH_FILE_BROWSER}
|
|
+, {XF86XK_AudioMedia, XBMCK_LAUNCH_MEDIA_CENTER }
|
|
+ // Numeric keypad
|
|
+, {XK_KP_0, XBMCK_KP0}
|
|
+, {XK_KP_1, XBMCK_KP1}
|
|
+, {XK_KP_2, XBMCK_KP2}
|
|
+, {XK_KP_3, XBMCK_KP3}
|
|
+, {XK_KP_4, XBMCK_KP4}
|
|
+, {XK_KP_5, XBMCK_KP5}
|
|
+, {XK_KP_6, XBMCK_KP6}
|
|
+, {XK_KP_7, XBMCK_KP7}
|
|
+, {XK_KP_8, XBMCK_KP8}
|
|
+, {XK_KP_9, XBMCK_KP9}
|
|
+, {XK_KP_Separator, XBMCK_KP_PERIOD}
|
|
+, {XK_KP_Divide, XBMCK_KP_DIVIDE}
|
|
+, {XK_KP_Multiply, XBMCK_KP_MULTIPLY}
|
|
+, {XK_KP_Subtract, XBMCK_KP_MINUS}
|
|
+, {XK_KP_Add, XBMCK_KP_PLUS}
|
|
+, {XK_KP_Enter, XBMCK_KP_ENTER}
|
|
+, {XK_KP_Equal, XBMCK_KP_EQUALS}
|
|
+ // Arrows + Home/End pad
|
|
+, {XK_Up, XBMCK_UP}
|
|
+, {XK_Down, XBMCK_DOWN}
|
|
+, {XK_Right, XBMCK_RIGHT}
|
|
+, {XK_Left, XBMCK_LEFT}
|
|
+, {XK_Insert, XBMCK_INSERT}
|
|
+, {XK_Home, XBMCK_HOME}
|
|
+, {XK_End, XBMCK_END}
|
|
+, {XK_Page_Up, XBMCK_PAGEUP}
|
|
+, {XK_Page_Down, XBMCK_PAGEDOWN}
|
|
+ // Function keys
|
|
+, {XK_F1, XBMCK_F1}
|
|
+, {XK_F2, XBMCK_F2}
|
|
+, {XK_F3, XBMCK_F3}
|
|
+, {XK_F4, XBMCK_F4}
|
|
+, {XK_F5, XBMCK_F5}
|
|
+, {XK_F6, XBMCK_F6}
|
|
+, {XK_F7, XBMCK_F7}
|
|
+, {XK_F8, XBMCK_F8}
|
|
+, {XK_F9, XBMCK_F9}
|
|
+, {XK_F10, XBMCK_F10}
|
|
+, {XK_F11, XBMCK_F11}
|
|
+, {XK_F12, XBMCK_F12}
|
|
+, {XK_F13, XBMCK_F13}
|
|
+, {XK_F14, XBMCK_F14}
|
|
+, {XK_F15, XBMCK_F15}
|
|
+ // Key state modifier keys
|
|
+, {XK_Num_Lock, XBMCK_NUMLOCK}
|
|
+, {XK_Caps_Lock, XBMCK_CAPSLOCK}
|
|
+, {XK_Scroll_Lock, XBMCK_SCROLLOCK}
|
|
+, {XK_Shift_R, XBMCK_RSHIFT}
|
|
+, {XK_Shift_L, XBMCK_LSHIFT}
|
|
+, {XK_Control_R, XBMCK_RCTRL}
|
|
+, {XK_Control_L, XBMCK_LCTRL}
|
|
+, {XK_Alt_R, XBMCK_RALT}
|
|
+, {XK_Alt_L, XBMCK_LALT}
|
|
+, {XK_Meta_R, XBMCK_RMETA}
|
|
+, {XK_Meta_L, XBMCK_LMETA}
|
|
+, {XK_Super_L, XBMCK_LSUPER}
|
|
+, {XK_Super_R, XBMCK_RSUPER}
|
|
+, {XK_Mode_switch, XBMCK_MODE}
|
|
+, {XK_Multi_key, XBMCK_COMPOSE}
|
|
+ // Miscellaneous function keys
|
|
+, {XK_Help, XBMCK_HELP}
|
|
+, {XK_Print, XBMCK_PRINT}
|
|
+//, {0, XBMCK_SYSREQ}
|
|
+, {XK_Break, XBMCK_BREAK}
|
|
+, {XK_Menu, XBMCK_MENU}
|
|
+, {XF86XK_PowerOff, XBMCK_POWER}
|
|
+, {XK_EcuSign, XBMCK_EURO}
|
|
+, {XK_Undo, XBMCK_UNDO}
|
|
+ /* Media keys */
|
|
+, {XF86XK_Eject, XBMCK_EJECT}
|
|
+, {XF86XK_Stop, XBMCK_STOP}
|
|
+, {XF86XK_AudioRecord, XBMCK_RECORD}
|
|
+, {XF86XK_AudioRewind, XBMCK_REWIND}
|
|
+, {XF86XK_Phone, XBMCK_PHONE}
|
|
+, {XF86XK_AudioPlay, XBMCK_PLAY}
|
|
+, {XF86XK_AudioRandomPlay, XBMCK_SHUFFLE}
|
|
+, {XF86XK_AudioForward, XBMCK_FASTFORWARD}
|
|
+};
|
|
+
|
|
+bool CWinEventsX11::MessagePump()
|
|
+{
|
|
+ return CWinEventsX11Imp::MessagePump();
|
|
+}
|
|
+
|
|
+size_t CWinEventsX11::GetQueueSize()
|
|
+{
|
|
+ return CWinEventsX11Imp::GetQueueSize();
|
|
+}
|
|
+
|
|
+CWinEventsX11Imp::CWinEventsX11Imp()
|
|
+{
|
|
+ m_display = 0;
|
|
+ m_window = 0;
|
|
+ m_keybuf = 0;
|
|
+ m_utf16buf = 0;
|
|
+}
|
|
+
|
|
+CWinEventsX11Imp::~CWinEventsX11Imp()
|
|
+{
|
|
+ if (m_keybuf);
|
|
+ {
|
|
+ free(m_keybuf);
|
|
+ m_keybuf = 0;
|
|
+ }
|
|
+
|
|
+ if (m_utf16buf)
|
|
+ {
|
|
+ free(m_utf16buf);
|
|
+ m_utf16buf = 0;
|
|
+ }
|
|
+
|
|
+ if (m_xic)
|
|
+ {
|
|
+ XUnsetICFocus(m_xic);
|
|
+ XDestroyIC(m_xic);
|
|
+ m_xic = 0;
|
|
+ }
|
|
+
|
|
+ if (m_xim)
|
|
+ {
|
|
+ XCloseIM(m_xim);
|
|
+ m_xim = 0;
|
|
+ }
|
|
+
|
|
+ m_symLookupTable.clear();
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
+{
|
|
+ if (WinEvents)
|
|
+ return true;
|
|
+
|
|
+ WinEvents = new CWinEventsX11Imp();
|
|
+ WinEvents->m_display = dpy;
|
|
+ WinEvents->m_window = win;
|
|
+ WinEvents->m_keybuf = (char*)malloc(32*sizeof(char));
|
|
+ WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t));
|
|
+ WinEvents->m_keymodState = 0;
|
|
+ WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
+ WinEvents->m_structureChanged = false;
|
|
+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
+
|
|
+ // open input method
|
|
+ char *old_locale = NULL, *old_modifiers = NULL;
|
|
+ char res_name[8];
|
|
+ const char *p;
|
|
+ size_t n;
|
|
+
|
|
+ // set resource name to xbmc, not used
|
|
+ strcpy(res_name, "xbmc");
|
|
+
|
|
+ // save current locale, this should be "C"
|
|
+ p = setlocale(LC_ALL, NULL);
|
|
+ if (p)
|
|
+ {
|
|
+ old_locale = (char*)malloc(strlen(p) +1);
|
|
+ strcpy(old_locale, p);
|
|
+ }
|
|
+ p = XSetLocaleModifiers(NULL);
|
|
+ if (p)
|
|
+ {
|
|
+ old_modifiers = (char*)malloc(strlen(p) +1);
|
|
+ strcpy(old_modifiers, p);
|
|
+ }
|
|
+
|
|
+ // set users preferences and open input method
|
|
+ p = setlocale(LC_ALL, "");
|
|
+ XSetLocaleModifiers("");
|
|
+ WinEvents->m_xim = XOpenIM(WinEvents->m_display, NULL, res_name, res_name);
|
|
+
|
|
+ // restore old locale
|
|
+ if (old_locale)
|
|
+ {
|
|
+ setlocale(LC_ALL, old_locale);
|
|
+ free(old_locale);
|
|
+ }
|
|
+ if (old_modifiers)
|
|
+ {
|
|
+ XSetLocaleModifiers(old_modifiers);
|
|
+ free(old_modifiers);
|
|
+ }
|
|
+
|
|
+ WinEvents->m_xic = NULL;
|
|
+ if (WinEvents->m_xim)
|
|
+ {
|
|
+ WinEvents->m_xic = XCreateIC(WinEvents->m_xim,
|
|
+ XNClientWindow, WinEvents->m_window,
|
|
+ XNFocusWindow, WinEvents->m_window,
|
|
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
|
+ XNResourceName, res_name,
|
|
+ XNResourceClass, res_name,
|
|
+ NULL);
|
|
+ }
|
|
+
|
|
+ if (!WinEvents->m_xic)
|
|
+ CLog::Log(LOGWARNING,"CWinEventsX11::Init - no input method found");
|
|
+
|
|
+ // build Keysym lookup table
|
|
+ for (unsigned int i = 0; i < sizeof(SymMappingsX11)/(2*sizeof(uint32_t)); ++i)
|
|
+ {
|
|
+ WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1];
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void CWinEventsX11Imp::Quit()
|
|
+{
|
|
+ if (!WinEvents)
|
|
+ return;
|
|
+
|
|
+ delete WinEvents;
|
|
+ WinEvents = 0;
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::HasStructureChanged()
|
|
+{
|
|
+ if (!WinEvents)
|
|
+ return false;
|
|
+
|
|
+ bool ret = WinEvents->m_structureChanged;
|
|
+ WinEvents->m_structureChanged = false;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::MessagePump()
|
|
+{
|
|
+ if (!WinEvents)
|
|
+ return false;
|
|
+
|
|
+ bool ret = false;
|
|
+ XEvent xevent;
|
|
+ unsigned long serial = 0;
|
|
+
|
|
+ while (WinEvents && XPending(WinEvents->m_display))
|
|
+ {
|
|
+ memset(&xevent, 0, sizeof (XEvent));
|
|
+ XNextEvent(WinEvents->m_display, &xevent);
|
|
+
|
|
+ // ignore events generated by auto-repeat
|
|
+ if (xevent.type == KeyRelease && XPending(WinEvents->m_display))
|
|
+ {
|
|
+ XEvent peekevent;
|
|
+ XPeekEvent(WinEvents->m_display, &peekevent);
|
|
+ if ((peekevent.type == KeyPress) &&
|
|
+ (peekevent.xkey.keycode == xevent.xkey.keycode) &&
|
|
+ ((peekevent.xkey.time - xevent.xkey.time) < 2))
|
|
+ {
|
|
+ XNextEvent(WinEvents->m_display, &peekevent);
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (XFilterEvent(&xevent, None))
|
|
+ continue;
|
|
+
|
|
+ switch (xevent.type)
|
|
+ {
|
|
+ case MapNotify:
|
|
+ {
|
|
+ g_application.SetRenderGUI(true);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case UnmapNotify:
|
|
+ {
|
|
+ g_application.SetRenderGUI(false);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case FocusIn:
|
|
+ {
|
|
+ if (WinEvents->m_xic)
|
|
+ XSetICFocus(WinEvents->m_xic);
|
|
+ g_application.m_AppFocused = true;
|
|
+ if (serial == xevent.xfocus.serial)
|
|
+ break;
|
|
+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case FocusOut:
|
|
+ {
|
|
+ if (WinEvents->m_xic)
|
|
+ XUnsetICFocus(WinEvents->m_xic);
|
|
+ g_application.m_AppFocused = false;
|
|
+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
|
|
+ serial = xevent.xfocus.serial;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case Expose:
|
|
+ {
|
|
+ g_windowManager.MarkDirty();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case ConfigureNotify:
|
|
+ {
|
|
+ if (xevent.xconfigure.window != WinEvents->m_window)
|
|
+ break;
|
|
+
|
|
+ WinEvents->m_structureChanged = true;
|
|
+ XBMC_Event newEvent;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_VIDEORESIZE;
|
|
+ newEvent.resize.w = xevent.xconfigure.width;
|
|
+ newEvent.resize.h = xevent.xconfigure.height;
|
|
+ ret |= g_application.OnEvent(newEvent);
|
|
+ g_windowManager.MarkDirty();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case ClientMessage:
|
|
+ {
|
|
+ if (xevent.xclient.data.l[0] == WinEvents->m_wmDeleteMessage)
|
|
+ if (!g_application.m_bStop) CApplicationMessenger::Get().Quit();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case KeyPress:
|
|
+ {
|
|
+ XBMC_Event newEvent;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_KEYDOWN;
|
|
+ KeySym xkeysym;
|
|
+
|
|
+ // fallback if we have no IM
|
|
+ if (!WinEvents->m_xic)
|
|
+ {
|
|
+ static XComposeStatus state;
|
|
+ char keybuf[32];
|
|
+ xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
+ newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
+ newEvent.key.state = xevent.xkey.state;
|
|
+ newEvent.key.type = xevent.xkey.type;
|
|
+ if (XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state))
|
|
+ {
|
|
+ newEvent.key.keysym.unicode = keybuf[0];
|
|
+ }
|
|
+ ret |= ProcessKey(newEvent, 500);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ Status status;
|
|
+ int utf16size;
|
|
+ int utf16length;
|
|
+ int len;
|
|
+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey,
|
|
+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf),
|
|
+ &xkeysym, &status);
|
|
+ if (status == XBufferOverflow)
|
|
+ {
|
|
+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char));
|
|
+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey,
|
|
+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf),
|
|
+ &xkeysym, &status);
|
|
+ }
|
|
+ switch (status)
|
|
+ {
|
|
+ case XLookupNone:
|
|
+ break;
|
|
+ case XLookupChars:
|
|
+ case XLookupBoth:
|
|
+ {
|
|
+ if (len == 0)
|
|
+ break;
|
|
+ utf16size = len * sizeof(uint16_t);
|
|
+ if (utf16size > sizeof(WinEvents->m_utf16buf))
|
|
+ {
|
|
+ WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size);
|
|
+ if (WinEvents->m_utf16buf == NULL)
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size);
|
|
+ if (utf16length < 0)
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ for (unsigned int i = 0; i < utf16length - 1; i++)
|
|
+ {
|
|
+ newEvent.key.keysym.sym = XBMCK_UNKNOWN;
|
|
+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i];
|
|
+ newEvent.key.state = xevent.xkey.state;
|
|
+ newEvent.key.type = xevent.xkey.type;
|
|
+ ret |= ProcessKey(newEvent, 500);
|
|
+ }
|
|
+ if (utf16length > 0)
|
|
+ {
|
|
+ newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
+ xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1];
|
|
+ newEvent.key.state = xevent.xkey.state;
|
|
+ newEvent.key.type = xevent.xkey.type;
|
|
+
|
|
+ ret |= ProcessKey(newEvent, 500);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case XLookupKeySym:
|
|
+ {
|
|
+ newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
+ newEvent.key.state = xevent.xkey.state;
|
|
+ newEvent.key.type = xevent.xkey.type;
|
|
+ ret |= ProcessKey(newEvent, 500);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ }// switch status
|
|
+ break;
|
|
+ } //KeyPress
|
|
+
|
|
+ case KeyRelease:
|
|
+ {
|
|
+ XBMC_Event newEvent;
|
|
+ KeySym xkeysym;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_KEYUP;
|
|
+ xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
+ newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
+ newEvent.key.state = xevent.xkey.state;
|
|
+ newEvent.key.type = xevent.xkey.type;
|
|
+ ret |= ProcessKey(newEvent, 0);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // lose mouse coverage
|
|
+ case LeaveNotify:
|
|
+ {
|
|
+ g_Mouse.SetActive(false);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case MotionNotify:
|
|
+ {
|
|
+ XBMC_Event newEvent;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_MOUSEMOTION;
|
|
+ newEvent.motion.xrel = (int16_t)xevent.xmotion.x_root;
|
|
+ newEvent.motion.yrel = (int16_t)xevent.xmotion.y_root;
|
|
+ newEvent.motion.x = (int16_t)xevent.xmotion.x;
|
|
+ newEvent.motion.y = (int16_t)xevent.xmotion.y;
|
|
+ ret |= g_application.OnEvent(newEvent);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case ButtonPress:
|
|
+ {
|
|
+ XBMC_Event newEvent;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_MOUSEBUTTONDOWN;
|
|
+ newEvent.button.button = (unsigned char)xevent.xbutton.button;
|
|
+ newEvent.button.state = XBMC_PRESSED;
|
|
+ newEvent.button.x = (int16_t)xevent.xbutton.x;
|
|
+ newEvent.button.y = (int16_t)xevent.xbutton.y;
|
|
+ ret |= g_application.OnEvent(newEvent);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ case ButtonRelease:
|
|
+ {
|
|
+ XBMC_Event newEvent;
|
|
+ memset(&newEvent, 0, sizeof(newEvent));
|
|
+ newEvent.type = XBMC_MOUSEBUTTONUP;
|
|
+ newEvent.button.button = (unsigned char)xevent.xbutton.button;
|
|
+ newEvent.button.state = XBMC_RELEASED;
|
|
+ newEvent.button.x = (int16_t)xevent.xbutton.x;
|
|
+ newEvent.button.y = (int16_t)xevent.xbutton.y;
|
|
+ ret |= g_application.OnEvent(newEvent);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ default:
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ }// switch event.type
|
|
+ }// while
|
|
+
|
|
+ ret |= ProcessKeyRepeat();
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+size_t CWinEventsX11Imp::GetQueueSize()
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (WinEvents)
|
|
+ ret = XPending(WinEvents->m_display);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay)
|
|
+{
|
|
+ if (event.type == XBMC_KEYDOWN)
|
|
+ {
|
|
+ // check key modifiers
|
|
+ switch(event.key.keysym.sym)
|
|
+ {
|
|
+ case XBMCK_LSHIFT:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_LSHIFT;
|
|
+ break;
|
|
+ case XBMCK_RSHIFT:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_RSHIFT;
|
|
+ break;
|
|
+ case XBMCK_LCTRL:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_LCTRL;
|
|
+ break;
|
|
+ case XBMCK_RCTRL:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL;
|
|
+ break;
|
|
+ case XBMCK_LALT:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_LALT;
|
|
+ break;
|
|
+ case XBMCK_RALT:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL;
|
|
+ break;
|
|
+ case XBMCK_LMETA:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_LMETA;
|
|
+ break;
|
|
+ case XBMCK_RMETA:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_RMETA;
|
|
+ break;
|
|
+ case XBMCK_MODE:
|
|
+ WinEvents->m_keymodState |= XBMCKMOD_MODE;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState;
|
|
+ memcpy(&(WinEvents->m_lastKey), &event, sizeof(event));
|
|
+ WinEvents->m_repeatKeyTimeout.Set(repeatDelay);
|
|
+
|
|
+ bool ret = ProcessShortcuts(event);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ else if (event.type == XBMC_KEYUP)
|
|
+ {
|
|
+ switch(event.key.keysym.sym)
|
|
+ {
|
|
+ case XBMCK_LSHIFT:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_LSHIFT;
|
|
+ break;
|
|
+ case XBMCK_RSHIFT:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_RSHIFT;
|
|
+ break;
|
|
+ case XBMCK_LCTRL:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_LCTRL;
|
|
+ break;
|
|
+ case XBMCK_RCTRL:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL;
|
|
+ break;
|
|
+ case XBMCK_LALT:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_LALT;
|
|
+ break;
|
|
+ case XBMCK_RALT:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL;
|
|
+ break;
|
|
+ case XBMCK_LMETA:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_LMETA;
|
|
+ break;
|
|
+ case XBMCK_RMETA:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_RMETA;
|
|
+ break;
|
|
+ case XBMCK_MODE:
|
|
+ WinEvents->m_keymodState &= ~XBMCKMOD_MODE;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState;
|
|
+ memset(&(WinEvents->m_lastKey), 0, sizeof(event));
|
|
+ }
|
|
+
|
|
+ return g_application.OnEvent(event);
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event)
|
|
+{
|
|
+ if (event.key.keysym.mod & XBMCKMOD_ALT)
|
|
+ {
|
|
+ switch(event.key.keysym.sym)
|
|
+ {
|
|
+ case XBMCK_TAB: // ALT+TAB to minimize/hide
|
|
+ g_application.Minimize();
|
|
+ return true;
|
|
+
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool CWinEventsX11Imp::ProcessKeyRepeat()
|
|
+{
|
|
+ if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN))
|
|
+ {
|
|
+ if (WinEvents->m_repeatKeyTimeout.IsTimePast())
|
|
+ {
|
|
+ return ProcessKey(WinEvents->m_lastKey, 10);
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength)
|
|
+{
|
|
+ // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer.
|
|
+ uint16_t *p = utf16;
|
|
+ uint16_t const *const maxPtr = utf16 + utf16MaxLength;
|
|
+
|
|
+ // end_of_input points to the last byte of input as opposed to the next to the last byte.
|
|
+ char const *const endOfInput = utf8 + utf8Length - 1;
|
|
+
|
|
+ while (utf8 <= endOfInput)
|
|
+ {
|
|
+ unsigned char const c = *utf8;
|
|
+ if (p >= maxPtr)
|
|
+ {
|
|
+ //No more output space.
|
|
+ return -1;
|
|
+ }
|
|
+ if (c < 0x80)
|
|
+ {
|
|
+ //One byte ASCII.
|
|
+ *p++ = c;
|
|
+ utf8 += 1;
|
|
+ }
|
|
+ else if (c < 0xC0)
|
|
+ {
|
|
+ // Follower byte without preceding leader bytes.
|
|
+ return -1;
|
|
+ }
|
|
+ // 11 bits
|
|
+ else if (c < 0xE0)
|
|
+ {
|
|
+ // Two byte sequence. We need one follower byte.
|
|
+ if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F));
|
|
+ utf8 += 2;
|
|
+ }
|
|
+ // 16 bis
|
|
+ else if (c < 0xF0)
|
|
+ {
|
|
+ // Three byte sequence. We need two follower byte.
|
|
+ if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F));
|
|
+ utf8 += 3;
|
|
+ }
|
|
+ // 21 bits
|
|
+ else if (c < 0xF8)
|
|
+ {
|
|
+ int plane;
|
|
+ // Four byte sequence. We need three follower bytes.
|
|
+ if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) ||
|
|
+ ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) +
|
|
+ ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F);
|
|
+ utf8 += 4;
|
|
+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
+ }
|
|
+ // 26 bits
|
|
+ else if (c < 0xFC)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
+ utf8 += 5;
|
|
+ }
|
|
+ // 31 bit
|
|
+ else
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
+ utf8 += 6;
|
|
+ }
|
|
+ }
|
|
+ return p - utf16;
|
|
+}
|
|
+
|
|
+XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym)
|
|
+{
|
|
+ // try direct mapping first
|
|
+ std::map<uint32_t, uint32_t>::iterator it;
|
|
+ it = WinEvents->m_symLookupTable.find(keysym);
|
|
+ if (it != WinEvents->m_symLookupTable.end())
|
|
+ {
|
|
+ return (XBMCKey)(it->second);
|
|
+ }
|
|
+
|
|
+ // try ascii mappings
|
|
+ if (keysym>>8 == 0x00)
|
|
+ return (XBMCKey)(keysym & 0xFF);
|
|
+
|
|
+ return (XBMCKey)keysym;
|
|
+}
|
|
+#endif
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
new file mode 100644
|
|
index 0000000..ce57c23
|
|
--- /dev/null
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -0,0 +1,65 @@
|
|
+/*
|
|
+* Copyright (C) 2005-2012 Team XBMC
|
|
+* http://www.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, write to
|
|
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+* http://www.gnu.org/copyleft/gpl.html
|
|
+*
|
|
+*/
|
|
+#pragma once
|
|
+
|
|
+#include "WinEvents.h"
|
|
+#include <X11/Xlib.h>
|
|
+#include "threads/SystemClock.h"
|
|
+#include <map>
|
|
+
|
|
+class CWinEventsX11 : public IWinEvents
|
|
+{
|
|
+public:
|
|
+ virtual bool MessagePump();
|
|
+ virtual size_t GetQueueSize();
|
|
+};
|
|
+
|
|
+class CWinEventsX11Imp
|
|
+{
|
|
+public:
|
|
+ CWinEventsX11Imp();
|
|
+ virtual ~CWinEventsX11Imp();
|
|
+ static bool Init(Display *dpy, Window win);
|
|
+ static void Quit();
|
|
+ static bool HasStructureChanged();
|
|
+ static bool MessagePump();
|
|
+ static size_t GetQueueSize();
|
|
+
|
|
+protected:
|
|
+ static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength);
|
|
+ static XBMCKey LookupXbmcKeySym(KeySym keysym);
|
|
+ static bool ProcessKey(XBMC_Event &event, int repeatDelay);
|
|
+ static bool ProcessKeyRepeat();
|
|
+ static bool ProcessShortcuts(XBMC_Event& event);
|
|
+ static CWinEventsX11Imp *WinEvents;
|
|
+ Display *m_display;
|
|
+ Window m_window;
|
|
+ Atom m_wmDeleteMessage;
|
|
+ char *m_keybuf;
|
|
+ uint16_t *m_utf16buf;
|
|
+ XIM m_xim;
|
|
+ XIC m_xic;
|
|
+ XBMC_Event m_lastKey;
|
|
+ XbmcThreads::EndTime m_repeatKeyTimeout;
|
|
+ std::map<uint32_t,uint32_t> m_symLookupTable;
|
|
+ int m_keymodState;
|
|
+ bool m_structureChanged;
|
|
+};
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 083d1e9..40b8403 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -22,7 +22,6 @@
|
|
|
|
#ifdef HAS_GLX
|
|
|
|
-#include <SDL/SDL_syswm.h>
|
|
#include "WinSystemX11.h"
|
|
#include "settings/DisplaySettings.h"
|
|
#include "settings/Settings.h"
|
|
@@ -34,7 +33,6 @@
|
|
#include "XRandR.h"
|
|
#include <vector>
|
|
#include "threads/SingleLock.h"
|
|
-#include <X11/Xlib.h>
|
|
#include "cores/VideoRenderers/RenderManager.h"
|
|
#include "utils/TimeUtils.h"
|
|
#include "utils/StringUtils.h"
|
|
@@ -43,19 +41,22 @@
|
|
#include <X11/extensions/Xrandr.h>
|
|
#endif
|
|
|
|
+#include "../WinEventsX11.h"
|
|
+#include "input/MouseStat.h"
|
|
+
|
|
using namespace std;
|
|
|
|
CWinSystemX11::CWinSystemX11() : CWinSystemBase()
|
|
{
|
|
m_eWindowSystem = WINDOW_SYSTEM_X11;
|
|
m_glContext = NULL;
|
|
- m_SDLSurface = NULL;
|
|
m_dpy = NULL;
|
|
m_glWindow = 0;
|
|
- m_wmWindow = 0;
|
|
m_bWasFullScreenBeforeMinimize = false;
|
|
m_minimized = false;
|
|
+ m_bIgnoreNextFocusMessage = false;
|
|
m_dpyLostTime = 0;
|
|
+ m_invisibleCursor = 0;
|
|
|
|
XSetErrorHandler(XErrorHandler);
|
|
}
|
|
@@ -68,18 +69,6 @@ bool CWinSystemX11::InitWindowSystem()
|
|
{
|
|
if ((m_dpy = XOpenDisplay(NULL)))
|
|
{
|
|
-
|
|
- SDL_EnableUNICODE(1);
|
|
- // set repeat to 10ms to ensure repeat time < frame time
|
|
- // so that hold times can be reliably detected
|
|
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10);
|
|
-
|
|
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
-
|
|
return CWinSystemBase::InitWindowSystem();
|
|
}
|
|
else
|
|
@@ -117,45 +106,37 @@ bool CWinSystemX11::DestroyWindowSystem()
|
|
|
|
bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction)
|
|
{
|
|
- RESOLUTION_INFO& desktop = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP);
|
|
-
|
|
- if (fullScreen &&
|
|
- (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight ||
|
|
- res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen))
|
|
- {
|
|
- //on the first call to SDL_SetVideoMode, SDL stores the current displaymode
|
|
- //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode
|
|
- //before the first call to SDL_SetVideoMode, SDL changes the displaymode back
|
|
- //to the wrong mode on exit
|
|
-
|
|
- CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first");
|
|
- if (!SetFullScreen(true, desktop, false))
|
|
- return false;
|
|
- }
|
|
-
|
|
if(!SetFullScreen(fullScreen, res, false))
|
|
return false;
|
|
|
|
- CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon.png");
|
|
-
|
|
- if (iconTexture)
|
|
- SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL);
|
|
- SDL_WM_SetCaption("XBMC Media Center", NULL);
|
|
- delete iconTexture;
|
|
-
|
|
- // register XRandR Events
|
|
-#if defined(HAS_XRANDR)
|
|
- int iReturn;
|
|
- XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn);
|
|
- XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask);
|
|
-#endif
|
|
-
|
|
m_bWindowCreated = true;
|
|
return true;
|
|
}
|
|
|
|
bool CWinSystemX11::DestroyWindow()
|
|
{
|
|
+ if (!m_glWindow)
|
|
+ return true;
|
|
+
|
|
+ if (m_glContext)
|
|
+ glXMakeCurrent(m_dpy, None, NULL);
|
|
+
|
|
+ if (m_invisibleCursor)
|
|
+ {
|
|
+ XUndefineCursor(m_dpy, m_glWindow);
|
|
+ XFreeCursor(m_dpy, m_invisibleCursor);
|
|
+ m_invisibleCursor = 0;
|
|
+ }
|
|
+
|
|
+ CWinEventsX11Imp::Quit();
|
|
+
|
|
+ XUnmapWindow(m_dpy, m_glWindow);
|
|
+ XSync(m_dpy,TRUE);
|
|
+ XUngrabKeyboard(m_dpy, CurrentTime);
|
|
+ XUngrabPointer(m_dpy, CurrentTime);
|
|
+ XDestroyWindow(m_dpy, m_glWindow);
|
|
+ m_glWindow = 0;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -165,67 +146,105 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
&& m_nHeight == newHeight)
|
|
return true;
|
|
|
|
+ if (!SetWindow(newWidth, newHeight, false))
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ RefreshGlxContext();
|
|
m_nWidth = newWidth;
|
|
m_nHeight = newHeight;
|
|
+ m_bFullScreen = false;
|
|
|
|
- int options = SDL_OPENGL;
|
|
- if (m_bFullScreen)
|
|
- options |= SDL_FULLSCREEN;
|
|
- else
|
|
- options |= SDL_RESIZABLE;
|
|
+ return false;
|
|
+}
|
|
|
|
- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options)))
|
|
+void CWinSystemX11::RefreshWindow()
|
|
+{
|
|
+ g_xrandr.Query(true);
|
|
+ XOutput out = g_xrandr.GetCurrentOutput();
|
|
+ XMode mode = g_xrandr.GetCurrentMode(out.name);
|
|
+
|
|
+ // only overwrite desktop resolution, if we are not in fullscreen mode
|
|
+ if (!g_graphicsContext.IsFullScreenVideo())
|
|
{
|
|
- SetGrabMode();
|
|
- RefreshGlxContext();
|
|
- return true;
|
|
+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz);
|
|
+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz);
|
|
+ g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id;
|
|
+ g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name;
|
|
}
|
|
|
|
- return false;
|
|
+ RESOLUTION_INFO res;
|
|
+ unsigned int i;
|
|
+ bool found(false);
|
|
+ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i)
|
|
+ {
|
|
+ if (g_settings.m_ResInfo[i].strId == mode.id)
|
|
+ {
|
|
+ found = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!found)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (g_graphicsContext.IsFullScreenRoot())
|
|
+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true);
|
|
+ else
|
|
+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true);
|
|
}
|
|
|
|
bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
|
|
{
|
|
- m_nWidth = res.iWidth;
|
|
- m_nHeight = res.iHeight;
|
|
- m_bFullScreen = fullScreen;
|
|
|
|
#if defined(HAS_XRANDR)
|
|
XOutput out;
|
|
XMode mode;
|
|
- out.name = res.strOutput;
|
|
- mode.w = res.iWidth;
|
|
- mode.h = res.iHeight;
|
|
- mode.hz = res.fRefreshRate;
|
|
- mode.id = res.strId;
|
|
+
|
|
+ if (fullScreen)
|
|
+ {
|
|
+ out.name = res.strOutput;
|
|
+ mode.w = res.iWidth;
|
|
+ mode.h = res.iHeight;
|
|
+ mode.hz = res.fRefreshRate;
|
|
+ mode.id = res.strId;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput;
|
|
+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId;
|
|
+ }
|
|
|
|
- if(m_bFullScreen)
|
|
+ XOutput currout = g_xrandr.GetCurrentOutput();
|
|
+ XMode currmode = g_xrandr.GetCurrentMode(currout.name);
|
|
+
|
|
+ // only call xrandr if mode changes
|
|
+ if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h ||
|
|
+ currmode.hz != mode.hz || currmode.id != mode.id)
|
|
{
|
|
+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
|
|
OnLostDevice();
|
|
g_xrandr.SetMode(out, mode);
|
|
}
|
|
- else
|
|
- g_xrandr.RestoreState();
|
|
#endif
|
|
|
|
- int options = SDL_OPENGL;
|
|
- if (m_bFullScreen)
|
|
- options |= SDL_FULLSCREEN;
|
|
- else
|
|
- options |= SDL_RESIZABLE;
|
|
-
|
|
- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options)))
|
|
- {
|
|
- if ((m_SDLSurface->flags & SDL_OPENGL) != SDL_OPENGL)
|
|
- CLog::Log(LOGERROR, "CWinSystemX11::SetFullScreen SDL_OPENGL not set, SDL_GetError:%s", SDL_GetError());
|
|
+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen))
|
|
+ return false;
|
|
|
|
- SetGrabMode();
|
|
- RefreshGlxContext();
|
|
+ RefreshGlxContext();
|
|
|
|
- return true;
|
|
- }
|
|
+ m_nWidth = res.iWidth;
|
|
+ m_nHeight = res.iHeight;
|
|
+ m_bFullScreen = fullScreen;
|
|
|
|
- return false;
|
|
+ return true;
|
|
}
|
|
|
|
void CWinSystemX11::UpdateResolutions()
|
|
@@ -327,17 +346,10 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
bool CWinSystemX11::RefreshGlxContext()
|
|
{
|
|
bool retVal = false;
|
|
- SDL_SysWMinfo info;
|
|
- SDL_VERSION(&info.version);
|
|
- if (SDL_GetWMInfo(&info) <= 0)
|
|
- {
|
|
- CLog::Log(LOGERROR, "Failed to get window manager info from SDL");
|
|
- return false;
|
|
- }
|
|
|
|
- if(m_glWindow == info.info.x11.window && m_glContext)
|
|
+ if (m_glContext)
|
|
{
|
|
- CLog::Log(LOGERROR, "GLX: Same window as before, refreshing context");
|
|
+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
|
|
return true;
|
|
@@ -349,8 +361,6 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
int availableVisuals = 0;
|
|
vMask.screen = DefaultScreen(m_dpy);
|
|
XWindowAttributes winAttr;
|
|
- m_glWindow = info.info.x11.window;
|
|
- m_wmWindow = info.info.x11.wmwindow;
|
|
|
|
/* Assume a depth of 24 in case the below calls to XGetWindowAttributes()
|
|
or XGetVisualInfo() fail. That shouldn't happen unless something is
|
|
@@ -421,7 +431,10 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
|
|
void CWinSystemX11::ShowOSMouse(bool show)
|
|
{
|
|
- SDL_ShowCursor(show ? 1 : 0);
|
|
+ if (show)
|
|
+ XUndefineCursor(m_dpy,m_glWindow);
|
|
+ else if (m_invisibleCursor)
|
|
+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor);
|
|
}
|
|
|
|
void CWinSystemX11::ResetOSScreensaver()
|
|
@@ -435,8 +448,6 @@ void CWinSystemX11::ResetOSScreensaver()
|
|
{
|
|
m_screensaverReset.StartZero();
|
|
XResetScreenSaver(m_dpy);
|
|
- //need to flush the output buffer, since we don't check for events on m_dpy
|
|
- XFlush(m_dpy);
|
|
}
|
|
}
|
|
else
|
|
@@ -452,13 +463,27 @@ void CWinSystemX11::NotifyAppActiveChange(bool bActivated)
|
|
|
|
m_minimized = !bActivated;
|
|
}
|
|
+
|
|
+void CWinSystemX11::NotifyAppFocusChange(bool bGaining)
|
|
+{
|
|
+ if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage &&
|
|
+ !g_graphicsContext.IsFullScreenRoot())
|
|
+ g_graphicsContext.ToggleFullScreenRoot();
|
|
+ if (!bGaining)
|
|
+ m_bIgnoreNextFocusMessage = false;
|
|
+}
|
|
+
|
|
bool CWinSystemX11::Minimize()
|
|
{
|
|
m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot();
|
|
if (m_bWasFullScreenBeforeMinimize)
|
|
+ {
|
|
+ m_bIgnoreNextFocusMessage = true;
|
|
g_graphicsContext.ToggleFullScreenRoot();
|
|
+ }
|
|
+
|
|
+ XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy));
|
|
|
|
- SDL_WM_IconifyWindow();
|
|
m_minimized = true;
|
|
return true;
|
|
}
|
|
@@ -468,13 +493,13 @@ bool CWinSystemX11::Restore()
|
|
}
|
|
bool CWinSystemX11::Hide()
|
|
{
|
|
- XUnmapWindow(m_dpy, m_wmWindow);
|
|
+ XUnmapWindow(m_dpy, m_glWindow);
|
|
XSync(m_dpy, False);
|
|
return true;
|
|
}
|
|
bool CWinSystemX11::Show(bool raise)
|
|
{
|
|
- XMapWindow(m_dpy, m_wmWindow);
|
|
+ XMapWindow(m_dpy, m_glWindow);
|
|
XSync(m_dpy, False);
|
|
m_minimized = false;
|
|
return true;
|
|
@@ -506,6 +531,7 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
if (bGotEvent || bTimeout)
|
|
{
|
|
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
+ RefreshWindow();
|
|
|
|
CSingleLock lock(m_resourceSection);
|
|
|
|
@@ -564,37 +590,151 @@ bool CWinSystemX11::EnableFrameLimiter()
|
|
return m_minimized;
|
|
}
|
|
|
|
-void CWinSystemX11::SetGrabMode(const CSetting *setting /*= NULL*/)
|
|
+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
{
|
|
- bool enabled;
|
|
- if (setting)
|
|
- enabled = ((CSettingBool*)setting)->GetValue();
|
|
- else
|
|
- enabled = CSettings::Get().GetBool("input.enablesystemkeys");
|
|
-
|
|
- if (m_SDLSurface && m_SDLSurface->flags & SDL_FULLSCREEN)
|
|
+ bool changeWindow = false;
|
|
+ bool changeSize = false;
|
|
+ bool mouseActive = false;
|
|
+ float mouseX, mouseY;
|
|
+
|
|
+ if (m_glWindow && (m_bFullScreen != fullscreen))
|
|
{
|
|
- if (enabled)
|
|
+ mouseActive = g_Mouse.IsActive();
|
|
+ if (mouseActive)
|
|
{
|
|
- //SDL will always call XGrabPointer and XGrabKeyboard when in fullscreen
|
|
- //so temporarily zero the SDL_FULLSCREEN flag, then turn off SDL grab mode
|
|
- //this will make SDL call XUnGrabPointer and XUnGrabKeyboard
|
|
- m_SDLSurface->flags &= ~SDL_FULLSCREEN;
|
|
- SDL_WM_GrabInput(SDL_GRAB_OFF);
|
|
- m_SDLSurface->flags |= SDL_FULLSCREEN;
|
|
+ Window root_return, child_return;
|
|
+ int root_x_return, root_y_return;
|
|
+ int win_x_return, win_y_return;
|
|
+ unsigned int mask_return;
|
|
+ bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return,
|
|
+ &root_x_return, &root_y_return,
|
|
+ &win_x_return, &win_y_return,
|
|
+ &mask_return);
|
|
+ if (isInWin)
|
|
+ {
|
|
+ mouseX = (float)win_x_return/m_nWidth;
|
|
+ mouseY = (float)win_y_return/m_nHeight;
|
|
+ g_Mouse.SetActive(false);
|
|
+ }
|
|
+ else
|
|
+ mouseActive = false;
|
|
}
|
|
- else
|
|
+ DestroyWindow();
|
|
+ }
|
|
+
|
|
+ // create main window
|
|
+ if (!m_glWindow)
|
|
+ {
|
|
+ GLint att[] =
|
|
{
|
|
- //turn off key grabbing, which will actually make SDL turn it on when in fullscreen
|
|
- SDL_WM_GrabInput(SDL_GRAB_OFF);
|
|
- }
|
|
+ GLX_RGBA,
|
|
+ GLX_RED_SIZE, 8,
|
|
+ GLX_GREEN_SIZE, 8,
|
|
+ GLX_BLUE_SIZE, 8,
|
|
+ GLX_ALPHA_SIZE, 8,
|
|
+ GLX_DEPTH_SIZE, 24,
|
|
+ GLX_DOUBLEBUFFER,
|
|
+ None
|
|
+ };
|
|
+ Colormap cmap;
|
|
+ XSetWindowAttributes swa;
|
|
+ XVisualInfo *vi;
|
|
+
|
|
+ vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att);
|
|
+ cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);
|
|
+
|
|
+ int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen));
|
|
+ swa.override_redirect = fullscreen ? True : False;
|
|
+ swa.border_pixel = fullscreen ? 0 : 5;
|
|
+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
+ swa.colormap = cmap;
|
|
+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
+ swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask |
|
|
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
|
+ PropertyChangeMask | StructureNotifyMask | KeymapStateMask |
|
|
+ EnterWindowMask | LeaveWindowMask | ExposureMask;
|
|
+ unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask;
|
|
+
|
|
+ m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
|
|
+ 0, 0, width, height, 0, vi->depth,
|
|
+ InputOutput, vi->visual,
|
|
+ mask, &swa);
|
|
+
|
|
+ // define invisible cursor
|
|
+ Pixmap bitmapNoData;
|
|
+ XColor black;
|
|
+ static char noData[] = { 0,0,0,0,0,0,0,0 };
|
|
+ black.red = black.green = black.blue = 0;
|
|
+
|
|
+ bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8);
|
|
+ m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData,
|
|
+ &black, &black, 0, 0);
|
|
+ XFreePixmap(m_dpy, bitmapNoData);
|
|
+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor);
|
|
+
|
|
+ //init X11 events
|
|
+ CWinEventsX11Imp::Init(m_dpy, m_glWindow);
|
|
+
|
|
+ changeWindow = true;
|
|
+ changeSize = true;
|
|
}
|
|
-}
|
|
|
|
-void CWinSystemX11::OnSettingChanged(const CSetting *setting)
|
|
-{
|
|
- if (setting->GetId() == "input.enablesystemkeys")
|
|
- SetGrabMode(setting);
|
|
+ if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight)))
|
|
+ {
|
|
+ changeSize = true;
|
|
+ }
|
|
+
|
|
+ if (changeSize || changeWindow)
|
|
+ {
|
|
+ XResizeWindow(m_dpy, m_glWindow, width, height);
|
|
+ }
|
|
+
|
|
+ if (changeWindow)
|
|
+ {
|
|
+ if (!fullscreen)
|
|
+ {
|
|
+ XWMHints wm_hints;
|
|
+ XClassHint class_hints;
|
|
+ XTextProperty windowName, iconName;
|
|
+ std::string titleString = "XBMC Media Center";
|
|
+ char *title = (char*)titleString.c_str();
|
|
+
|
|
+ XStringListToTextProperty(&title, 1, &windowName);
|
|
+ XStringListToTextProperty(&title, 1, &iconName);
|
|
+ wm_hints.initial_state = NormalState;
|
|
+ wm_hints.input = True;
|
|
+ wm_hints.icon_pixmap = None;
|
|
+ wm_hints.flags = StateHint | IconPixmapHint | InputHint;
|
|
+
|
|
+ XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName,
|
|
+ NULL, 0, NULL, &wm_hints,
|
|
+ NULL);
|
|
+
|
|
+ // register interest in the delete window message
|
|
+ Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
|
|
+ XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1);
|
|
+ }
|
|
+ XMapRaised(m_dpy, m_glWindow);
|
|
+ XSync(m_dpy,TRUE);
|
|
+
|
|
+ if (changeWindow && mouseActive)
|
|
+ {
|
|
+ XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height);
|
|
+ }
|
|
+
|
|
+ if (fullscreen)
|
|
+ {
|
|
+ int result = -1;
|
|
+ while (result != GrabSuccess)
|
|
+ {
|
|
+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime);
|
|
+ XbmcThreads::ThreadSleep(100);
|
|
+ }
|
|
+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
}
|
|
|
|
#endif
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index b1464d0..34b912f 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -54,6 +54,7 @@ public:
|
|
virtual bool EnableFrameLimiter();
|
|
|
|
virtual void NotifyAppActiveChange(bool bActivated);
|
|
+ virtual void NotifyAppFocusChange(bool bGaining);
|
|
|
|
virtual bool Minimize();
|
|
virtual bool Restore() ;
|
|
@@ -66,20 +67,21 @@ public:
|
|
Display* GetDisplay() { return m_dpy; }
|
|
GLXWindow GetWindow() { return m_glWindow; }
|
|
GLXContext GetGlxContext() { return m_glContext; }
|
|
- virtual void OnSettingChanged(const CSetting *setting);
|
|
+ void RefreshWindow();
|
|
|
|
protected:
|
|
bool RefreshGlxContext();
|
|
void CheckDisplayEvents();
|
|
void OnLostDevice();
|
|
+ bool SetWindow(int width, int height, bool fullscreen);
|
|
|
|
- SDL_Surface* m_SDLSurface;
|
|
+ Window m_glWindow;
|
|
GLXContext m_glContext;
|
|
- GLXWindow m_glWindow;
|
|
- Window m_wmWindow;
|
|
Display* m_dpy;
|
|
+ Cursor m_invisibleCursor;
|
|
bool m_bWasFullScreenBeforeMinimize;
|
|
bool m_minimized;
|
|
+ bool m_bIgnoreNextFocusMessage;
|
|
int m_RREventBase;
|
|
CCriticalSection m_resourceSection;
|
|
std::vector<IDispResource*> m_resources;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 78d8cdb9dd83a7dfdbe77fa1bb137944200bed06 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 15:24:22 +0200
|
|
Subject: [PATCH 09/93] X11: Add xbmc icon
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 126 +++++++++++++++++++++++++++++++++++-
|
|
xbmc/windowing/X11/WinSystemX11.h | 3 +-
|
|
2 files changed, 127 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 40b8403..858ea5e 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -137,6 +137,9 @@ bool CWinSystemX11::DestroyWindow()
|
|
XDestroyWindow(m_dpy, m_glWindow);
|
|
m_glWindow = 0;
|
|
|
|
+ if (m_icon)
|
|
+ XFreePixmap(m_dpy, m_icon);
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -691,8 +694,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
|
|
if (changeWindow)
|
|
{
|
|
+ m_icon = None;
|
|
if (!fullscreen)
|
|
{
|
|
+ CreateIconPixmap();
|
|
XWMHints wm_hints;
|
|
XClassHint class_hints;
|
|
XTextProperty windowName, iconName;
|
|
@@ -703,7 +708,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
XStringListToTextProperty(&title, 1, &iconName);
|
|
wm_hints.initial_state = NormalState;
|
|
wm_hints.input = True;
|
|
- wm_hints.icon_pixmap = None;
|
|
+ wm_hints.icon_pixmap = m_icon;
|
|
wm_hints.flags = StateHint | IconPixmapHint | InputHint;
|
|
|
|
XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName,
|
|
@@ -737,4 +742,123 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
return true;
|
|
}
|
|
|
|
+bool CWinSystemX11::CreateIconPixmap()
|
|
+{
|
|
+ int depth;
|
|
+ XImage *img = NULL;
|
|
+ Visual *vis;
|
|
+ XWindowAttributes wndattribs;
|
|
+ XVisualInfo visInfo;
|
|
+ double rRatio;
|
|
+ double gRatio;
|
|
+ double bRatio;
|
|
+ int outIndex = 0;
|
|
+ int i,j;
|
|
+ int numBufBytes;
|
|
+ unsigned char *buf;
|
|
+ uint32_t *newBuf = 0;
|
|
+ size_t numNewBufBytes;
|
|
+
|
|
+ // Get visual Info
|
|
+ XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs);
|
|
+ visInfo.visualid = wndattribs.visual->visualid;
|
|
+ int nvisuals = 0;
|
|
+ XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals);
|
|
+ if (nvisuals != 1)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual");
|
|
+ return false;
|
|
+ }
|
|
+ visInfo = visuals[0];
|
|
+ XFree(visuals);
|
|
+
|
|
+ depth = visInfo.depth;
|
|
+ vis = visInfo.visual;
|
|
+
|
|
+ if (depth < 15)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ rRatio = vis->red_mask / 255.0;
|
|
+ gRatio = vis->green_mask / 255.0;
|
|
+ bRatio = vis->blue_mask / 255.0;
|
|
+
|
|
+ CTexture iconTexture;
|
|
+ iconTexture.LoadFromFile("special://xbmc/media/icon.png");
|
|
+ buf = iconTexture.GetPixels();
|
|
+
|
|
+ numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4;
|
|
+
|
|
+ if (depth>=24)
|
|
+ numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight()));
|
|
+ else
|
|
+ numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight()));
|
|
+
|
|
+ newBuf = (uint32_t*)malloc(numNewBufBytes);
|
|
+ if (!newBuf)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ for (i=0; i<iconTexture.GetHeight();++i)
|
|
+ {
|
|
+ for (j=0; j<iconTexture.GetWidth();++j)
|
|
+ {
|
|
+ unsigned int pos = i*iconTexture.GetPitch()+j*4;
|
|
+ unsigned int r, g, b;
|
|
+ r = (buf[pos+2] * rRatio);
|
|
+ g = (buf[pos+1] * gRatio);
|
|
+ b = (buf[pos+0] * bRatio);
|
|
+ r &= vis->red_mask;
|
|
+ g &= vis->green_mask;
|
|
+ b &= vis->blue_mask;
|
|
+ newBuf[outIndex] = r | g | b;
|
|
+ ++outIndex;
|
|
+ }
|
|
+ }
|
|
+ img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf,
|
|
+ iconTexture.GetWidth(), iconTexture.GetHeight(),
|
|
+ (depth>=24)?32:16, 0);
|
|
+ if (!img)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image");
|
|
+ free(newBuf);
|
|
+ return false;
|
|
+ }
|
|
+ if (!XInitImage(img))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed");
|
|
+ XDestroyImage(img);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // set byte order
|
|
+ union
|
|
+ {
|
|
+ char c[sizeof(short)];
|
|
+ short s;
|
|
+ } order;
|
|
+ order.s = 1;
|
|
+ if ((1 == order.c[0]))
|
|
+ {
|
|
+ img->byte_order = LSBFirst;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ img->byte_order = MSBFirst;
|
|
+ }
|
|
+
|
|
+ // create icon pixmap from image
|
|
+ m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth);
|
|
+ GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL);
|
|
+ XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height);
|
|
+ XFreeGC(m_dpy, gc);
|
|
+ XDestroyImage(img); // this also frees newBuf
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
#endif
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 34b912f..352e90e 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -79,6 +79,7 @@ protected:
|
|
GLXContext m_glContext;
|
|
Display* m_dpy;
|
|
Cursor m_invisibleCursor;
|
|
+ Pixmap m_icon;
|
|
bool m_bWasFullScreenBeforeMinimize;
|
|
bool m_minimized;
|
|
bool m_bIgnoreNextFocusMessage;
|
|
@@ -90,7 +91,7 @@ protected:
|
|
private:
|
|
bool IsSuitableVisual(XVisualInfo *vInfo);
|
|
static int XErrorHandler(Display* dpy, XErrorEvent* error);
|
|
- void SetGrabMode(const CSetting *setting = NULL);
|
|
+ bool CreateIconPixmap();
|
|
|
|
CStopWatch m_screensaverReset;
|
|
};
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From a5da9aa02e7fa7ee91d0c98ef20c57b3737670e0 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 20 May 2012 14:11:26 +0200
|
|
Subject: [PATCH 10/93] X11: add SDL joystick until we have a better solution
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++
|
|
1 file changed, 26 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index ad58aad..6f57a87 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -35,6 +35,10 @@
|
|
#include "guilib/GUIWindowManager.h"
|
|
#include "input/MouseStat.h"
|
|
|
|
+#ifdef HAS_SDL_JOYSTICK
|
|
+#include "input/SDLJoystick.h"
|
|
+#endif
|
|
+
|
|
CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0;
|
|
|
|
static uint32_t SymMappingsX11[][2] =
|
|
@@ -556,6 +560,28 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
ret |= ProcessKeyRepeat();
|
|
|
|
+#ifdef HAS_SDL_JOYSTICK
|
|
+ SDL_Event event;
|
|
+ while (SDL_PollEvent(&event))
|
|
+ {
|
|
+ switch(event.type)
|
|
+ {
|
|
+ case SDL_JOYBUTTONUP:
|
|
+ case SDL_JOYBUTTONDOWN:
|
|
+ case SDL_JOYAXISMOTION:
|
|
+ case SDL_JOYBALLMOTION:
|
|
+ case SDL_JOYHATMOTION:
|
|
+ g_Joystick.Update(event);
|
|
+ ret = true;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ memset(&event, 0, sizeof(SDL_Event));
|
|
+ }
|
|
+#endif
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 97fa84c30a5c726690f886ac596bfd80870d8d77 Mon Sep 17 00:00:00 2001
|
|
From: Joakim Plate <elupus@xbmc.org>
|
|
Date: Thu, 5 Jul 2012 12:35:55 +0200
|
|
Subject: [PATCH 11/93] X11: factor out code handling device reset notification
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 22 ++++++++++++++--------
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
2 files changed, 15 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 858ea5e..304dac8 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -533,14 +533,7 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
|
|
if (bGotEvent || bTimeout)
|
|
{
|
|
- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
- RefreshWindow();
|
|
-
|
|
- CSingleLock lock(m_resourceSection);
|
|
-
|
|
- // tell any shared resources
|
|
- for (vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
|
|
- (*i)->OnResetDevice();
|
|
+ NotifyXRREvent();
|
|
|
|
// reset fail safe timer
|
|
m_dpyLostTime = 0;
|
|
@@ -548,6 +541,19 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
#endif
|
|
}
|
|
|
|
+void CWinSystemX11::NotifyXRREvent()
|
|
+{
|
|
+ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
+ RefreshWindow();
|
|
+
|
|
+ CSingleLock lock(m_resourceSection);
|
|
+
|
|
+ // tell any shared resources
|
|
+ for (vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
|
|
+ (*i)->OnResetDevice();
|
|
+
|
|
+}
|
|
+
|
|
void CWinSystemX11::OnLostDevice()
|
|
{
|
|
CLog::Log(LOGDEBUG, "%s - notify display change event", __FUNCTION__);
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 352e90e..3f91b9b 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -68,6 +68,7 @@ public:
|
|
GLXWindow GetWindow() { return m_glWindow; }
|
|
GLXContext GetGlxContext() { return m_glContext; }
|
|
void RefreshWindow();
|
|
+ void NotifyXRREvent();
|
|
|
|
protected:
|
|
bool RefreshGlxContext();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 1d0601d1ec7d1ffcd14fd233d4f4769e862680bc Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 15:02:00 +0200
|
|
Subject: [PATCH 12/93] X11: move xrandr events to WinEventsX11
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++++
|
|
xbmc/windowing/WinEventsX11.h | 5 +++++
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 6 +++++-
|
|
3 files changed, 52 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 6f57a87..d77cb2a 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -35,6 +35,10 @@
|
|
#include "guilib/GUIWindowManager.h"
|
|
#include "input/MouseStat.h"
|
|
|
|
+#if defined(HAS_XRANDR)
|
|
+#include <X11/extensions/Xrandr.h>
|
|
+#endif
|
|
+
|
|
#ifdef HAS_SDL_JOYSTICK
|
|
#include "input/SDLJoystick.h"
|
|
#endif
|
|
@@ -212,6 +216,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_keymodState = 0;
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
+ WinEvents->m_xrrEventPending = false;
|
|
memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
|
|
// open input method
|
|
@@ -275,6 +280,13 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1];
|
|
}
|
|
|
|
+ // register for xrandr events
|
|
+#if defined(HAS_XRANDR)
|
|
+ int iReturn;
|
|
+ XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn);
|
|
+ XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask);
|
|
+#endif
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -297,6 +309,15 @@ bool CWinEventsX11Imp::HasStructureChanged()
|
|
return ret;
|
|
}
|
|
|
|
+void CWinEventsX11Imp::SetXRRFailSafeTimer(int millis)
|
|
+{
|
|
+ if (!WinEvents)
|
|
+ return;
|
|
+
|
|
+ WinEvents->m_xrrFailSafeTimer.Set(millis);
|
|
+ WinEvents->m_xrrEventPending = true;
|
|
+}
|
|
+
|
|
bool CWinEventsX11Imp::MessagePump()
|
|
{
|
|
if (!WinEvents)
|
|
@@ -556,10 +577,31 @@ bool CWinEventsX11Imp::MessagePump()
|
|
break;
|
|
}
|
|
}// switch event.type
|
|
+
|
|
+#if defined(HAS_XRANDR)
|
|
+ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify))
|
|
+ {
|
|
+ XRRUpdateConfiguration(&xevent);
|
|
+ if (xevent.xgeneric.serial != serial)
|
|
+ g_Windowing.NotifyXRREvent();
|
|
+ WinEvents->m_xrrEventPending = false;
|
|
+ serial = xevent.xgeneric.serial;
|
|
+ }
|
|
+#endif
|
|
+
|
|
}// while
|
|
|
|
ret |= ProcessKeyRepeat();
|
|
|
|
+#if defined(HAS_XRANDR)
|
|
+ if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast())
|
|
+ {
|
|
+ CLog::Log(LOGERROR,"CWinEventsX11::MessagePump - missed XRR Events");
|
|
+ g_Windowing.NotifyXRREvent();
|
|
+ WinEvents->m_xrrEventPending = false;
|
|
+ }
|
|
+#endif
|
|
+
|
|
#ifdef HAS_SDL_JOYSTICK
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event))
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index ce57c23..a412f32 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -40,6 +40,8 @@ public:
|
|
static bool Init(Display *dpy, Window win);
|
|
static void Quit();
|
|
static bool HasStructureChanged();
|
|
+ static void PendingResize(int width, int height);
|
|
+ static void SetXRRFailSafeTimer(int millis);
|
|
static bool MessagePump();
|
|
static size_t GetQueueSize();
|
|
|
|
@@ -62,4 +64,7 @@ protected:
|
|
std::map<uint32_t,uint32_t> m_symLookupTable;
|
|
int m_keymodState;
|
|
bool m_structureChanged;
|
|
+ int m_RREventBase;
|
|
+ XbmcThreads::EndTime m_xrrFailSafeTimer;
|
|
+ bool m_xrrEventPending;
|
|
};
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 304dac8..16b13aa 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -510,7 +510,7 @@ bool CWinSystemX11::Show(bool raise)
|
|
|
|
void CWinSystemX11::CheckDisplayEvents()
|
|
{
|
|
-#if defined(HAS_XRANDR)
|
|
+#if defined(HAS_XRANDR) && defined(HAS_SDL_VIDEO_X11)
|
|
bool bGotEvent(false);
|
|
bool bTimeout(false);
|
|
XEvent Event;
|
|
@@ -566,8 +566,12 @@ void CWinSystemX11::OnLostDevice()
|
|
(*i)->OnLostDevice();
|
|
}
|
|
|
|
+#if defined(HAS_SDL_VIDEO_X11)
|
|
// fail safe timer
|
|
m_dpyLostTime = CurrentHostCounter();
|
|
+#else
|
|
+ CWinEventsX11Imp::SetXRRFailSafeTimer(3000);
|
|
+#endif
|
|
}
|
|
|
|
void CWinSystemX11::Register(IDispResource *resource)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 3181b919ca96f6837dde69a178ebb43112dff734 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 12 Apr 2012 15:43:56 +0200
|
|
Subject: [PATCH 13/93] xrandr: remove method RestoreState
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++--
|
|
xbmc/windowing/X11/XRandR.cpp | 19 -------------------
|
|
xbmc/windowing/X11/XRandR.h | 1 -
|
|
3 files changed, 11 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 16b13aa..f61d425 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -80,9 +80,18 @@ bool CWinSystemX11::InitWindowSystem()
|
|
bool CWinSystemX11::DestroyWindowSystem()
|
|
{
|
|
#if defined(HAS_XRANDR)
|
|
- //restore videomode on exit
|
|
+ //restore desktop resolution on exit
|
|
if (m_bFullScreen)
|
|
- g_xrandr.RestoreState();
|
|
+ {
|
|
+ XOutput out;
|
|
+ XMode mode;
|
|
+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput;
|
|
+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId;
|
|
+ g_xrandr.SetMode(out, mode);
|
|
+ }
|
|
#endif
|
|
|
|
if (m_dpy)
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 0ac17ab..7e06655 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -139,25 +139,6 @@ void CXRandR::SaveState()
|
|
Query(true);
|
|
}
|
|
|
|
-void CXRandR::RestoreState()
|
|
-{
|
|
- vector<XOutput>::iterator outiter;
|
|
- for (outiter=m_current.begin() ; outiter!=m_current.end() ; outiter++)
|
|
- {
|
|
- vector<XMode> modes = (*outiter).modes;
|
|
- vector<XMode>::iterator modeiter;
|
|
- for (modeiter=modes.begin() ; modeiter!=modes.end() ; modeiter++)
|
|
- {
|
|
- XMode mode = *modeiter;
|
|
- if (mode.isCurrent)
|
|
- {
|
|
- SetMode(*outiter, mode);
|
|
- return;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
bool CXRandR::SetMode(XOutput output, XMode mode)
|
|
{
|
|
if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == ""))
|
|
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
|
|
index 0aec487..00b49dc 100644
|
|
--- a/xbmc/windowing/X11/XRandR.h
|
|
+++ b/xbmc/windowing/X11/XRandR.h
|
|
@@ -99,7 +99,6 @@ public:
|
|
bool SetMode(XOutput output, XMode mode);
|
|
void LoadCustomModeLinesToAllOutputs(void);
|
|
void SaveState();
|
|
- void RestoreState();
|
|
//bool Has1080i();
|
|
//bool Has1080p();
|
|
//bool Has720p();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 65e877e82067a917e683c5930b2dc3840693f3ea Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 20 May 2012 13:17:10 +0200
|
|
Subject: [PATCH 14/93] xrandr: observe orientation
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 89 ++++++++++++++++++++++++++++++-------
|
|
xbmc/windowing/X11/WinSystemX11.h | 2 +
|
|
xbmc/windowing/X11/XRandR.cpp | 7 +++
|
|
xbmc/windowing/X11/XRandR.h | 1 +
|
|
4 files changed, 82 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index f61d425..4257aeb 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -85,11 +85,11 @@ bool CWinSystemX11::DestroyWindowSystem()
|
|
{
|
|
XOutput out;
|
|
XMode mode;
|
|
- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput;
|
|
- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId;
|
|
+ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput;
|
|
+ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth;
|
|
+ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight;
|
|
+ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate;
|
|
+ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId;
|
|
g_xrandr.SetMode(out, mode);
|
|
}
|
|
#endif
|
|
@@ -173,25 +173,34 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
|
|
void CWinSystemX11::RefreshWindow()
|
|
{
|
|
- g_xrandr.Query(true);
|
|
+ if (!g_xrandr.Query(true))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
+ return;
|
|
+ }
|
|
XOutput out = g_xrandr.GetCurrentOutput();
|
|
XMode mode = g_xrandr.GetCurrentMode(out.name);
|
|
|
|
+ RotateResolutions();
|
|
+
|
|
// only overwrite desktop resolution, if we are not in fullscreen mode
|
|
if (!g_graphicsContext.IsFullScreenVideo())
|
|
{
|
|
CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz);
|
|
- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz);
|
|
- g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id;
|
|
- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name;
|
|
+ if (!out.isRotated)
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
+ else
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name;
|
|
}
|
|
|
|
RESOLUTION_INFO res;
|
|
unsigned int i;
|
|
bool found(false);
|
|
- for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i)
|
|
+ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
{
|
|
- if (g_settings.m_ResInfo[i].strId == mode.id)
|
|
+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id)
|
|
{
|
|
found = true;
|
|
break;
|
|
@@ -227,16 +236,24 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
}
|
|
else
|
|
{
|
|
- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput;
|
|
- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId;
|
|
+ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput;
|
|
+ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth;
|
|
+ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight;
|
|
+ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate;
|
|
+ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId;
|
|
}
|
|
|
|
XOutput currout = g_xrandr.GetCurrentOutput();
|
|
XMode currmode = g_xrandr.GetCurrentMode(currout.name);
|
|
|
|
+ // flip h/w when rotated
|
|
+ if (m_bIsRotated)
|
|
+ {
|
|
+ int w = mode.w;
|
|
+ mode.w = mode.h;
|
|
+ mode.h = w;
|
|
+ }
|
|
+
|
|
// only call xrandr if mode changes
|
|
if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h ||
|
|
currmode.hz != mode.hz || currmode.id != mode.id)
|
|
@@ -269,7 +286,11 @@ void CWinSystemX11::UpdateResolutions()
|
|
{
|
|
XOutput out = g_xrandr.GetCurrentOutput();
|
|
XMode mode = g_xrandr.GetCurrentMode(out.name);
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
+ m_bIsRotated = out.isRotated;
|
|
+ if (!m_bIsRotated)
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
+ else
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name;
|
|
}
|
|
@@ -308,6 +329,16 @@ void CWinSystemX11::UpdateResolutions()
|
|
res.iHeight = mode.h;
|
|
res.iScreenWidth = mode.w;
|
|
res.iScreenHeight = mode.h;
|
|
+ if (!m_bIsRotated)
|
|
+ {
|
|
+ res.iWidth = mode.w;
|
|
+ res.iHeight = mode.h;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ res.iWidth = mode.h;
|
|
+ res.iHeight = mode.w;
|
|
+ }
|
|
if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0)
|
|
res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h));
|
|
else
|
|
@@ -335,6 +366,30 @@ void CWinSystemX11::UpdateResolutions()
|
|
|
|
}
|
|
|
|
+void CWinSystemX11::RotateResolutions()
|
|
+{
|
|
+#if defined(HAS_XRANDR)
|
|
+ XOutput out = g_xrandr.GetCurrentOutput();
|
|
+ if (out.isRotated == m_bIsRotated)
|
|
+ return;
|
|
+
|
|
+ for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
+ {
|
|
+ int width = CDisplaySettings::Get().GetResolutionInfo(i).iWidth;
|
|
+ CDisplaySettings::Get().GetResolutionInfo(i).iWidth = CDisplaySettings::Get().GetResolutionInfo(i).iHeight;
|
|
+ CDisplaySettings::Get().GetResolutionInfo(i).iHeight = width;
|
|
+ }
|
|
+ // update desktop resolution
|
|
+// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
+// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
+// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
+// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz);
|
|
+
|
|
+ m_bIsRotated = out.isRotated;
|
|
+
|
|
+#endif
|
|
+}
|
|
+
|
|
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
{
|
|
int value;
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 3f91b9b..4175aab 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -75,12 +75,14 @@ protected:
|
|
void CheckDisplayEvents();
|
|
void OnLostDevice();
|
|
bool SetWindow(int width, int height, bool fullscreen);
|
|
+ void RotateResolutions();
|
|
|
|
Window m_glWindow;
|
|
GLXContext m_glContext;
|
|
Display* m_dpy;
|
|
Cursor m_invisibleCursor;
|
|
Pixmap m_icon;
|
|
+ bool m_bIsRotated;
|
|
bool m_bWasFullScreenBeforeMinimize;
|
|
bool m_minimized;
|
|
bool m_bIgnoreNextFocusMessage;
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 7e06655..330e945 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -98,6 +98,13 @@ bool CXRandR::Query(bool force)
|
|
xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 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
|
|
+ && (strcasecmp(output->Attribute("rotation"), "left") == 0 || strcasecmp(output->Attribute("rotation"), "right") == 0))
|
|
+ {
|
|
+ xoutput.isRotated = true;
|
|
+ }
|
|
+ else
|
|
+ xoutput.isRotated = false;
|
|
|
|
if (!xoutput.isConnected)
|
|
continue;
|
|
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
|
|
index 00b49dc..508604d 100644
|
|
--- a/xbmc/windowing/X11/XRandR.h
|
|
+++ b/xbmc/windowing/X11/XRandR.h
|
|
@@ -86,6 +86,7 @@ public:
|
|
int wmm;
|
|
int hmm;
|
|
std::vector<XMode> modes;
|
|
+ bool isRotated;
|
|
};
|
|
|
|
class CXRandR
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 6c652b01707baa034c3dacd7e2a6c1a38385f514 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 11:54:15 +0200
|
|
Subject: [PATCH 15/93] xrandr: allow getting info for multiple screen's
|
|
|
|
Refactored by: Joakim Plate <elupus@xbmc.org>
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 65 +++++++++++++++++++++++++++++++++----------
|
|
xbmc/windowing/X11/XRandR.h | 8 ++++--
|
|
2 files changed, 57 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 330e945..4685413 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -40,6 +40,7 @@ using namespace std;
|
|
CXRandR::CXRandR(bool query)
|
|
{
|
|
m_bInit = false;
|
|
+ m_numScreens = 1;
|
|
if (query)
|
|
Query();
|
|
}
|
|
@@ -56,11 +57,21 @@ bool CXRandR::Query(bool force)
|
|
return false;
|
|
|
|
m_outputs.clear();
|
|
- m_current.clear();
|
|
+ // query all screens
|
|
+ for(unsigned int screennum=0; screennum<m_numScreens; ++screennum)
|
|
+ {
|
|
+ if(!Query(force, screennum))
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
|
|
+bool CXRandR::Query(bool force, int screennum)
|
|
+{
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
cmd += "/xbmc-xrandr";
|
|
+ cmd.append("-q --screen %d", screennum);
|
|
|
|
FILE* file = popen(cmd.c_str(),"r");
|
|
if (!file)
|
|
@@ -80,7 +91,7 @@ bool CXRandR::Query(bool force)
|
|
pclose(file);
|
|
|
|
TiXmlElement *pRootElement = xmlDoc.RootElement();
|
|
- if (strcasecmp(pRootElement->Value(), "screen") != 0)
|
|
+ if (strcasecmp(pRootElement->Value(), "screen") != screennum)
|
|
{
|
|
// TODO ERROR
|
|
return false;
|
|
@@ -92,6 +103,7 @@ bool CXRandR::Query(bool force)
|
|
xoutput.name = output->Attribute("name");
|
|
StringUtils::Trim(xoutput.name);
|
|
xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0);
|
|
+ xoutput.screen = screennum;
|
|
xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0);
|
|
xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0);
|
|
xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0);
|
|
@@ -123,7 +135,6 @@ bool CXRandR::Query(bool force)
|
|
xoutput.modes.push_back(xmode);
|
|
if (xmode.isCurrent)
|
|
{
|
|
- m_current.push_back(xoutput);
|
|
hascurrent = true;
|
|
}
|
|
}
|
|
@@ -247,17 +258,6 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
|
|
return true;
|
|
}
|
|
|
|
-XOutput CXRandR::GetCurrentOutput()
|
|
-{
|
|
- Query();
|
|
- for (unsigned int j = 0; j < m_outputs.size(); j++)
|
|
- {
|
|
- if(m_outputs[j].isConnected)
|
|
- return m_outputs[j];
|
|
- }
|
|
- XOutput empty;
|
|
- return empty;
|
|
-}
|
|
XMode CXRandR::GetCurrentMode(CStdString outputName)
|
|
{
|
|
Query();
|
|
@@ -329,6 +329,43 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void)
|
|
}
|
|
}
|
|
|
|
+void CXRandR::SetNumScreens(unsigned int num)
|
|
+{
|
|
+ m_numScreens = num;
|
|
+ m_bInit = false;
|
|
+}
|
|
+
|
|
+bool CXRandR::IsOutputConnected(CStdString name)
|
|
+{
|
|
+ bool result = false;
|
|
+ Query();
|
|
+
|
|
+ for (unsigned int i = 0; i < m_outputs.size(); ++i)
|
|
+ {
|
|
+ if (m_outputs[i].name == name)
|
|
+ {
|
|
+ result = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+XOutput* CXRandR::GetOutput(CStdString outputName)
|
|
+{
|
|
+ XOutput *result = 0;
|
|
+ Query();
|
|
+ for (unsigned int i = 0; i < m_outputs.size(); ++i)
|
|
+ {
|
|
+ if (m_outputs[i].name == outputName)
|
|
+ {
|
|
+ result = &m_outputs[i];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
CXRandR g_xrandr;
|
|
|
|
#endif // HAS_XRANDR
|
|
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
|
|
index 508604d..d37838a 100644
|
|
--- a/xbmc/windowing/X11/XRandR.h
|
|
+++ b/xbmc/windowing/X11/XRandR.h
|
|
@@ -79,6 +79,7 @@ public:
|
|
}
|
|
CStdString name;
|
|
bool isConnected;
|
|
+ int screen;
|
|
int w;
|
|
int h;
|
|
int x;
|
|
@@ -94,12 +95,15 @@ class CXRandR
|
|
public:
|
|
CXRandR(bool query=false);
|
|
bool Query(bool force=false);
|
|
+ bool Query(bool force, int screennum);
|
|
std::vector<XOutput> GetModes(void);
|
|
- XOutput GetCurrentOutput();
|
|
XMode GetCurrentMode(CStdString outputName);
|
|
+ XOutput *GetOutput(CStdString outputName);
|
|
bool SetMode(XOutput output, XMode mode);
|
|
void LoadCustomModeLinesToAllOutputs(void);
|
|
void SaveState();
|
|
+ void SetNumScreens(unsigned int num);
|
|
+ bool IsOutputConnected(CStdString name);
|
|
//bool Has1080i();
|
|
//bool Has1080p();
|
|
//bool Has720p();
|
|
@@ -107,10 +111,10 @@ public:
|
|
|
|
private:
|
|
bool m_bInit;
|
|
- std::vector<XOutput> m_current;
|
|
std::vector<XOutput> m_outputs;
|
|
CStdString m_currentOutput;
|
|
CStdString m_currentMode;
|
|
+ unsigned int m_numScreens;
|
|
};
|
|
|
|
extern CXRandR g_xrandr;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From fec4134865c2071f80276d020f900307f45d8057 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 11:44:00 +0200
|
|
Subject: [PATCH 16/93] X11: fix multi-head setups
|
|
|
|
---
|
|
language/English/strings.po | 4 +-
|
|
system/settings/settings.xml | 11 ++
|
|
xbmc/rendering/gl/RenderSystemGL.h | 1 +
|
|
xbmc/settings/DisplaySettings.cpp | 44 ++++++-
|
|
xbmc/settings/DisplaySettings.h | 2 +
|
|
xbmc/settings/Settings.cpp | 6 +
|
|
xbmc/windowing/WinEventsX11.cpp | 7 +
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 255 +++++++++++++++++++++---------------
|
|
xbmc/windowing/X11/WinSystemX11.h | 10 +-
|
|
9 files changed, 227 insertions(+), 113 deletions(-)
|
|
|
|
diff --git a/language/English/strings.po b/language/English/strings.po
|
|
index 6b1070d..d9b34e1 100755
|
|
--- a/language/English/strings.po
|
|
+++ b/language/English/strings.po
|
|
@@ -1021,7 +1021,9 @@ msgctxt "#245"
|
|
msgid "Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1) (VShift: %2.2f)"
|
|
msgstr ""
|
|
|
|
-#empty string with id 246
|
|
+msgctxt "#246"
|
|
+msgid "Monitor"
|
|
+msgstr ""
|
|
|
|
msgctxt "#247"
|
|
msgid "Scripts"
|
|
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
|
|
index c6b03b9..4882978 100644
|
|
--- a/system/settings/settings.xml
|
|
+++ b/system/settings/settings.xml
|
|
@@ -2250,6 +2250,15 @@
|
|
<section id="system" label="13000" help="36349">
|
|
<category id="videoscreen" label="21373" help="36603">
|
|
<group id="1">
|
|
+ <setting id="videoscreen.monitor" type="string" label="246" help="">
|
|
+ <visible>HAS_GLX</visible>
|
|
+ <level>0</level>
|
|
+ <default>Default</default>
|
|
+ <constraints>
|
|
+ <options>monitors</options>
|
|
+ </constraints>
|
|
+ <control type="spinner" format="string" delayed="true" />
|
|
+ </setting>
|
|
<setting id="videoscreen.screen" type="integer" label="240" help="36351">
|
|
<level>0</level>
|
|
<default>0</default>
|
|
@@ -2271,6 +2280,7 @@
|
|
<dependency type="enable" setting="videoscreen.screen" operator="!is">-1</dependency> <!-- DM_WINDOWED -->
|
|
<dependency type="update" setting="videoscreen.screen" />
|
|
<dependency type="update" setting="videoscreen.screenmode" />
|
|
+ <dependency type="update" setting="videoscreen.monitor" />
|
|
</dependencies>
|
|
<control type="list" format="string" />
|
|
</setting>
|
|
@@ -2288,6 +2298,7 @@
|
|
<dependency type="enable" setting="videoscreen.screen" operator="!is">-1</dependency> <!-- DM_WINDOWED -->
|
|
<dependency type="update" setting="videoscreen.screen" />
|
|
<dependency type="update" setting="videoscreen.resolution" />
|
|
+ <dependency type="update" setting="videoscreen.monitor" />
|
|
</dependencies>
|
|
<control type="spinner" format="string" delayed="true" />
|
|
</setting>
|
|
diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h
|
|
index 4bd540b..f1e2c50 100644
|
|
--- a/xbmc/rendering/gl/RenderSystemGL.h
|
|
+++ b/xbmc/rendering/gl/RenderSystemGL.h
|
|
@@ -44,6 +44,7 @@ public:
|
|
virtual bool IsExtSupported(const char* extension);
|
|
|
|
virtual void SetVSync(bool vsync);
|
|
+ virtual void ResetVSync() { m_bVsyncInit = false; }
|
|
|
|
virtual void SetViewPort(CRect& viewPort);
|
|
virtual void GetViewPort(CRect& viewPort);
|
|
diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp
|
|
index c8c2bbd..966d08f 100644
|
|
--- a/xbmc/settings/DisplaySettings.cpp
|
|
+++ b/xbmc/settings/DisplaySettings.cpp
|
|
@@ -219,13 +219,19 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
|
|
const std::string &settingId = setting->GetId();
|
|
if (settingId == "videoscreen.resolution" ||
|
|
- settingId == "videoscreen.screen")
|
|
+ settingId == "videoscreen.screen" ||
|
|
+ settingId == "videoscreen.monitor")
|
|
{
|
|
RESOLUTION newRes = RES_DESKTOP;
|
|
if (settingId == "videoscreen.resolution")
|
|
newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue();
|
|
else if (settingId == "videoscreen.screen")
|
|
newRes = GetResolutionForScreen();
|
|
+ else if (settingId == "videoscreen.monitor")
|
|
+ {
|
|
+ g_Windowing.UpdateResolutions();
|
|
+ newRes = GetResolutionForScreen();
|
|
+ }
|
|
|
|
string screenmode = GetStringFromResolution(newRes);
|
|
CSettings::Get().SetString("videoscreen.screenmode", screenmode);
|
|
@@ -236,7 +242,11 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue());
|
|
|
|
SetCurrentResolution(newRes, false);
|
|
- g_graphicsContext.SetVideoResolution(newRes);
|
|
+ bool outputChanged = false;
|
|
+#if defined(HAS_GLX)
|
|
+ outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor"));
|
|
+#endif
|
|
+ g_graphicsContext.SetVideoResolution(newRes, outputChanged);
|
|
|
|
// check if the old or the new resolution was/is windowed
|
|
// in which case we don't show any prompt to the user
|
|
@@ -622,6 +632,10 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std:
|
|
if (g_advancedSettings.m_canWindowed)
|
|
list.push_back(make_pair(g_localizeStrings.Get(242), DM_WINDOWED));
|
|
|
|
+#if defined(HAS_GLX)
|
|
+ list.push_back(make_pair(g_localizeStrings.Get(244), 0));
|
|
+#else
|
|
+
|
|
for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++)
|
|
{
|
|
int screen = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen;
|
|
@@ -636,6 +650,7 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std:
|
|
RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res);
|
|
current = resInfo.iScreen;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t)
|
|
@@ -663,3 +678,28 @@ void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(const
|
|
SettingOptionsStereoscopicModesFiller(setting, list, current);
|
|
list.push_back(make_pair(g_localizeStrings.Get(36525), RENDER_STEREO_MODE_AUTO)); // option for autodetect
|
|
}
|
|
+
|
|
+void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t)
|
|
+{
|
|
+#if defined(HAS_GLX)
|
|
+ std::vector<CStdString> monitors;
|
|
+ g_Windowing.GetConnectedOutputs(&monitors);
|
|
+ for (unsigned int i=0; i<monitors.size(); ++i)
|
|
+ {
|
|
+ if(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput.Equals(monitors[i]))
|
|
+ {
|
|
+ current = monitors[i];
|
|
+ }
|
|
+ list.push_back(make_pair(monitors[i], monitors[i]));
|
|
+ }
|
|
+#endif
|
|
+}
|
|
+
|
|
+void CDisplaySettings::ClearCustomResolutions()
|
|
+{
|
|
+ if (m_resolutions.size() > RES_CUSTOM)
|
|
+ {
|
|
+ std::vector<RESOLUTION_INFO>::iterator firstCustom = m_resolutions.begin()+RES_CUSTOM;
|
|
+ m_resolutions.erase(firstCustom, m_resolutions.end());
|
|
+ }
|
|
+}
|
|
diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h
|
|
index 8ee1be2..bead24b 100644
|
|
--- a/xbmc/settings/DisplaySettings.h
|
|
+++ b/xbmc/settings/DisplaySettings.h
|
|
@@ -78,6 +78,7 @@ public:
|
|
|
|
void ApplyCalibrations();
|
|
void UpdateCalibrations();
|
|
+ void ClearCustomResolutions();
|
|
|
|
float GetZoomAmount() const { return m_zoomAmount; }
|
|
void SetZoomAmount(float zoomAmount) { m_zoomAmount = zoomAmount; }
|
|
@@ -95,6 +96,7 @@ public:
|
|
static void SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t);
|
|
static void SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t);
|
|
static void SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t);
|
|
+ static void SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t);
|
|
|
|
protected:
|
|
CDisplaySettings();
|
|
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
|
|
index 892a139..1037ddb 100644
|
|
--- a/xbmc/settings/Settings.cpp
|
|
+++ b/xbmc/settings/Settings.cpp
|
|
@@ -406,6 +406,7 @@ void CSettings::Uninitialize()
|
|
m_settingsManager->UnregisterSettingOptionsFiller("screens");
|
|
m_settingsManager->UnregisterSettingOptionsFiller("stereoscopicmodes");
|
|
m_settingsManager->UnregisterSettingOptionsFiller("preferedstereoscopicviewmodes");
|
|
+ m_settingsManager->UnregisterSettingOptionsFiller("monitors");
|
|
m_settingsManager->UnregisterSettingOptionsFiller("shutdownstates");
|
|
m_settingsManager->UnregisterSettingOptionsFiller("startupwindows");
|
|
m_settingsManager->UnregisterSettingOptionsFiller("streamlanguages");
|
|
@@ -835,6 +836,7 @@ void CSettings::InitializeOptionFillers()
|
|
m_settingsManager->RegisterSettingOptionsFiller("screens", CDisplaySettings::SettingOptionsScreensFiller);
|
|
m_settingsManager->RegisterSettingOptionsFiller("stereoscopicmodes", CDisplaySettings::SettingOptionsStereoscopicModesFiller);
|
|
m_settingsManager->RegisterSettingOptionsFiller("preferedstereoscopicviewmodes", CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller);
|
|
+ m_settingsManager->RegisterSettingOptionsFiller("monitors", CDisplaySettings::SettingOptionsMonitorsFiller);
|
|
m_settingsManager->RegisterSettingOptionsFiller("shutdownstates", CPowerManager::SettingOptionsShutdownStatesFiller);
|
|
m_settingsManager->RegisterSettingOptionsFiller("startupwindows", ADDON::CSkinInfo::SettingOptionsStartupWindowsFiller);
|
|
m_settingsManager->RegisterSettingOptionsFiller("streamlanguages", CLangInfo::SettingOptionsStreamLanguagesFiller);
|
|
@@ -865,6 +867,9 @@ void CSettings::InitializeConditions()
|
|
#ifdef HAS_GL
|
|
m_settingsManager->AddCondition("has_gl");
|
|
#endif
|
|
+#ifdef HAS_GLX
|
|
+ m_settingsManager->AddCondition("has_glx");
|
|
+#endif
|
|
#ifdef HAS_GLES
|
|
m_settingsManager->AddCondition("has_gles");
|
|
#endif
|
|
@@ -1017,6 +1022,7 @@ void CSettings::InitializeISettingCallbacks()
|
|
settingSet.insert("videoscreen.screen");
|
|
settingSet.insert("videoscreen.resolution");
|
|
settingSet.insert("videoscreen.screenmode");
|
|
+ settingSet.insert("videoscreen.monitor");
|
|
m_settingsManager->RegisterCallback(&CDisplaySettings::Get(), settingSet);
|
|
|
|
settingSet.clear();
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index d77cb2a..d98f12f 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -526,9 +526,16 @@ bool CWinEventsX11Imp::MessagePump()
|
|
break;
|
|
}
|
|
|
|
+ case EnterNotify:
|
|
+ {
|
|
+ g_Windowing.NotifyMouseCoverage(true);
|
|
+ break;
|
|
+ }
|
|
+
|
|
// lose mouse coverage
|
|
case LeaveNotify:
|
|
{
|
|
+ g_Windowing.NotifyMouseCoverage(false);
|
|
g_Mouse.SetActive(false);
|
|
break;
|
|
}
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 4257aeb..5e86772 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -36,6 +36,8 @@
|
|
#include "cores/VideoRenderers/RenderManager.h"
|
|
#include "utils/TimeUtils.h"
|
|
#include "utils/StringUtils.h"
|
|
+#include "settings/Settings.h"
|
|
+#include "windowing/WindowingFactory.h"
|
|
|
|
#if defined(HAS_XRANDR)
|
|
#include <X11/extensions/Xrandr.h>
|
|
@@ -57,6 +59,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase()
|
|
m_bIgnoreNextFocusMessage = false;
|
|
m_dpyLostTime = 0;
|
|
m_invisibleCursor = 0;
|
|
+ m_bIsInternalXrr = false;
|
|
|
|
XSetErrorHandler(XErrorHandler);
|
|
}
|
|
@@ -69,7 +72,8 @@ bool CWinSystemX11::InitWindowSystem()
|
|
{
|
|
if ((m_dpy = XOpenDisplay(NULL)))
|
|
{
|
|
- return CWinSystemBase::InitWindowSystem();
|
|
+ bool ret = CWinSystemBase::InitWindowSystem();
|
|
+ return ret;
|
|
}
|
|
else
|
|
CLog::Log(LOGERROR, "GLX Error: No Display found");
|
|
@@ -106,6 +110,8 @@ bool CWinSystemX11::DestroyWindowSystem()
|
|
|
|
//we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy
|
|
//so instead we just let m_dpy die on exit
|
|
+ // i have seen core dumps on ATI if the display is not closed here
|
|
+ XCloseDisplay(m_dpy);
|
|
}
|
|
|
|
// m_SDLSurface is free()'d by SDL_Quit().
|
|
@@ -128,7 +134,10 @@ bool CWinSystemX11::DestroyWindow()
|
|
return true;
|
|
|
|
if (m_glContext)
|
|
+ {
|
|
+ glFinish();
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
+ }
|
|
|
|
if (m_invisibleCursor)
|
|
{
|
|
@@ -158,7 +167,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
&& m_nHeight == newHeight)
|
|
return true;
|
|
|
|
- if (!SetWindow(newWidth, newHeight, false))
|
|
+ if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor")))
|
|
{
|
|
return false;
|
|
}
|
|
@@ -167,58 +176,11 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
m_nWidth = newWidth;
|
|
m_nHeight = newHeight;
|
|
m_bFullScreen = false;
|
|
+ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
|
|
return false;
|
|
}
|
|
|
|
-void CWinSystemX11::RefreshWindow()
|
|
-{
|
|
- if (!g_xrandr.Query(true))
|
|
- {
|
|
- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
- return;
|
|
- }
|
|
- XOutput out = g_xrandr.GetCurrentOutput();
|
|
- XMode mode = g_xrandr.GetCurrentMode(out.name);
|
|
-
|
|
- RotateResolutions();
|
|
-
|
|
- // only overwrite desktop resolution, if we are not in fullscreen mode
|
|
- if (!g_graphicsContext.IsFullScreenVideo())
|
|
- {
|
|
- CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz);
|
|
- if (!out.isRotated)
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
- else
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name;
|
|
- }
|
|
-
|
|
- RESOLUTION_INFO res;
|
|
- unsigned int i;
|
|
- bool found(false);
|
|
- for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
- {
|
|
- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id)
|
|
- {
|
|
- found = true;
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (!found)
|
|
- {
|
|
- CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution");
|
|
- return;
|
|
- }
|
|
-
|
|
- if (g_graphicsContext.IsFullScreenRoot())
|
|
- g_graphicsContext.SetVideoResolution((RESOLUTION)i, true);
|
|
- else
|
|
- g_graphicsContext.SetVideoResolution(RES_WINDOW, true);
|
|
-}
|
|
-
|
|
bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
|
|
{
|
|
|
|
@@ -243,8 +205,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId;
|
|
}
|
|
|
|
- XOutput currout = g_xrandr.GetCurrentOutput();
|
|
- XMode currmode = g_xrandr.GetCurrentMode(currout.name);
|
|
+ XMode currmode = g_xrandr.GetCurrentMode(out.name);
|
|
|
|
// flip h/w when rotated
|
|
if (m_bIsRotated)
|
|
@@ -255,16 +216,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
}
|
|
|
|
// only call xrandr if mode changes
|
|
- if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h ||
|
|
+ if (currmode.w != mode.w || currmode.h != mode.h ||
|
|
currmode.hz != mode.hz || currmode.id != mode.id)
|
|
{
|
|
CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
|
|
OnLostDevice();
|
|
+ m_bIsInternalXrr = true;
|
|
g_xrandr.SetMode(out, mode);
|
|
}
|
|
#endif
|
|
|
|
- if (!SetWindow(res.iWidth, res.iHeight, fullScreen))
|
|
+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor")))
|
|
return false;
|
|
|
|
RefreshGlxContext();
|
|
@@ -272,6 +234,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
m_nWidth = res.iWidth;
|
|
m_nHeight = res.iHeight;
|
|
m_bFullScreen = fullScreen;
|
|
+ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
|
|
return true;
|
|
}
|
|
@@ -280,19 +243,30 @@ void CWinSystemX11::UpdateResolutions()
|
|
{
|
|
CWinSystemBase::UpdateResolutions();
|
|
|
|
-
|
|
#if defined(HAS_XRANDR)
|
|
- if(g_xrandr.Query())
|
|
- {
|
|
- XOutput out = g_xrandr.GetCurrentOutput();
|
|
- XMode mode = g_xrandr.GetCurrentMode(out.name);
|
|
- m_bIsRotated = out.isRotated;
|
|
+ CStdString currentMonitor;
|
|
+ int numScreens = XScreenCount(m_dpy);
|
|
+ g_xrandr.SetNumScreens(numScreens);
|
|
+ if(g_xrandr.Query(true))
|
|
+ {
|
|
+ currentMonitor = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ // check if the monitor is connected
|
|
+ XOutput *out = g_xrandr.GetOutput(currentMonitor);
|
|
+ if (!out)
|
|
+ {
|
|
+ // choose first output
|
|
+ currentMonitor = g_xrandr.GetModes()[0].name;
|
|
+ out = g_xrandr.GetOutput(currentMonitor);
|
|
+ CSettings::Get().SetString("videoscreen.monitor", currentMonitor);
|
|
+ }
|
|
+ XMode mode = g_xrandr.GetCurrentMode(currentMonitor);
|
|
+ m_bIsRotated = out->isRotated;
|
|
if (!m_bIsRotated)
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz);
|
|
else
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz);
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name;
|
|
+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor;
|
|
}
|
|
else
|
|
#endif
|
|
@@ -303,23 +277,22 @@ void CWinSystemX11::UpdateResolutions()
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0);
|
|
}
|
|
|
|
-
|
|
#if defined(HAS_XRANDR)
|
|
|
|
+ // erase previous stored modes
|
|
+ CDisplaySettings::Get().ClearCustomResolutions();
|
|
+
|
|
CLog::Log(LOGINFO, "Available videomodes (xrandr):");
|
|
- vector<XOutput>::iterator outiter;
|
|
- vector<XOutput> outs;
|
|
- outs = g_xrandr.GetModes();
|
|
- CLog::Log(LOGINFO, "Number of connected outputs: %"PRIdS"", outs.size());
|
|
+
|
|
+ XOutput *out = g_xrandr.GetOutput(currentMonitor);
|
|
string modename = "";
|
|
|
|
- for (outiter = outs.begin() ; outiter != outs.end() ; outiter++)
|
|
+ if (out != NULL)
|
|
{
|
|
- XOutput out = *outiter;
|
|
vector<XMode>::iterator modeiter;
|
|
- CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out.name.c_str(), out.modes.size());
|
|
+ CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out->name.c_str(), out->modes.size());
|
|
|
|
- for (modeiter = out.modes.begin() ; modeiter!=out.modes.end() ; modeiter++)
|
|
+ for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++)
|
|
{
|
|
XMode mode = *modeiter;
|
|
CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d",
|
|
@@ -339,8 +312,8 @@ void CWinSystemX11::UpdateResolutions()
|
|
res.iWidth = mode.h;
|
|
res.iHeight = mode.w;
|
|
}
|
|
- if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0)
|
|
- res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h));
|
|
+ if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0)
|
|
+ res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h));
|
|
else
|
|
res.fPixelRatio = 1.0f;
|
|
|
|
@@ -366,28 +339,19 @@ void CWinSystemX11::UpdateResolutions()
|
|
|
|
}
|
|
|
|
-void CWinSystemX11::RotateResolutions()
|
|
+void CWinSystemX11::GetConnectedOutputs(std::vector<CStdString> *outputs)
|
|
{
|
|
-#if defined(HAS_XRANDR)
|
|
- XOutput out = g_xrandr.GetCurrentOutput();
|
|
- if (out.isRotated == m_bIsRotated)
|
|
- return;
|
|
-
|
|
- for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
+ vector<XOutput> outs;
|
|
+ outs = g_xrandr.GetModes();
|
|
+ for(unsigned int i=0; i<outs.size(); ++i)
|
|
{
|
|
- int width = CDisplaySettings::Get().GetResolutionInfo(i).iWidth;
|
|
- CDisplaySettings::Get().GetResolutionInfo(i).iWidth = CDisplaySettings::Get().GetResolutionInfo(i).iHeight;
|
|
- CDisplaySettings::Get().GetResolutionInfo(i).iHeight = width;
|
|
+ outputs->push_back(outs[i].name);
|
|
}
|
|
- // update desktop resolution
|
|
-// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight;
|
|
-// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth;
|
|
-// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate;
|
|
-// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz);
|
|
-
|
|
- m_bIsRotated = out.isRotated;
|
|
+}
|
|
|
|
-#endif
|
|
+bool CWinSystemX11::IsCurrentOutput(CStdString output)
|
|
+{
|
|
+ return m_currentOutput.Equals(output);
|
|
}
|
|
|
|
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
@@ -417,8 +381,11 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
if (m_glContext)
|
|
{
|
|
CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
|
|
+ glFinish();
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
|
|
+ XSync(m_dpy, FALSE);
|
|
+ g_Windowing.ResetVSync();
|
|
return true;
|
|
}
|
|
|
|
@@ -484,6 +451,8 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
{
|
|
// make this context current
|
|
glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
|
|
+ g_Windowing.ResetVSync();
|
|
+ XSync(m_dpy, False);
|
|
retVal = true;
|
|
}
|
|
else
|
|
@@ -525,24 +494,53 @@ void CWinSystemX11::ResetOSScreensaver()
|
|
|
|
void CWinSystemX11::NotifyAppActiveChange(bool bActivated)
|
|
{
|
|
- if (bActivated && m_bWasFullScreenBeforeMinimize && !g_graphicsContext.IsFullScreenRoot())
|
|
+ if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen)
|
|
+ {
|
|
g_graphicsContext.ToggleFullScreenRoot();
|
|
|
|
+ m_bWasFullScreenBeforeMinimize = false;
|
|
+ }
|
|
m_minimized = !bActivated;
|
|
}
|
|
|
|
void CWinSystemX11::NotifyAppFocusChange(bool bGaining)
|
|
{
|
|
if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage &&
|
|
- !g_graphicsContext.IsFullScreenRoot())
|
|
+ !m_bFullScreen)
|
|
+ {
|
|
+ m_bWasFullScreenBeforeMinimize = false;
|
|
g_graphicsContext.ToggleFullScreenRoot();
|
|
+ m_minimized = false;
|
|
+ }
|
|
if (!bGaining)
|
|
m_bIgnoreNextFocusMessage = false;
|
|
}
|
|
|
|
+void CWinSystemX11::NotifyMouseCoverage(bool covered)
|
|
+{
|
|
+ if (!m_bFullScreen)
|
|
+ return;
|
|
+
|
|
+ if (covered)
|
|
+ {
|
|
+ int result = -1;
|
|
+ while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
+ {
|
|
+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
+ XbmcThreads::ThreadSleep(100);
|
|
+ }
|
|
+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ XUngrabKeyboard(m_dpy, CurrentTime);
|
|
+ XUngrabPointer(m_dpy, CurrentTime);
|
|
+ }
|
|
+}
|
|
+
|
|
bool CWinSystemX11::Minimize()
|
|
{
|
|
- m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot();
|
|
+ m_bWasFullScreenBeforeMinimize = m_bFullScreen;
|
|
if (m_bWasFullScreenBeforeMinimize)
|
|
{
|
|
m_bIgnoreNextFocusMessage = true;
|
|
@@ -608,13 +606,46 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
void CWinSystemX11::NotifyXRREvent()
|
|
{
|
|
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
- RefreshWindow();
|
|
+ m_windowDirty = true;
|
|
|
|
- CSingleLock lock(m_resourceSection);
|
|
+ // if external event update resolutions
|
|
+ if (!m_bIsInternalXrr)
|
|
+ {
|
|
+ UpdateResolutions();
|
|
+ }
|
|
+ else if (!g_xrandr.Query(true))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
+ return;
|
|
+ }
|
|
+ m_bIsInternalXrr = false;
|
|
|
|
- // tell any shared resources
|
|
- for (vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
|
|
- (*i)->OnResetDevice();
|
|
+ CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ XOutput *out = g_xrandr.GetOutput(currentOutput);
|
|
+ XMode mode = g_xrandr.GetCurrentMode(currentOutput);
|
|
+
|
|
+ RESOLUTION_INFO res;
|
|
+ unsigned int i;
|
|
+ bool found(false);
|
|
+ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
+ {
|
|
+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id)
|
|
+ {
|
|
+ found = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!found)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution");
|
|
+ i = RES_DESKTOP;
|
|
+ }
|
|
+
|
|
+ if (g_graphicsContext.IsFullScreenRoot())
|
|
+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true);
|
|
+ else
|
|
+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true);
|
|
|
|
}
|
|
|
|
@@ -667,14 +698,14 @@ bool CWinSystemX11::EnableFrameLimiter()
|
|
return m_minimized;
|
|
}
|
|
|
|
-bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output)
|
|
{
|
|
bool changeWindow = false;
|
|
bool changeSize = false;
|
|
bool mouseActive = false;
|
|
float mouseX, mouseY;
|
|
|
|
- if (m_glWindow && (m_bFullScreen != fullscreen))
|
|
+ if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty))
|
|
{
|
|
mouseActive = g_Mouse.IsActive();
|
|
if (mouseActive)
|
|
@@ -696,6 +727,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
else
|
|
mouseActive = false;
|
|
}
|
|
+ OnLostDevice();
|
|
DestroyWindow();
|
|
}
|
|
|
|
@@ -717,7 +749,11 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
XSetWindowAttributes swa;
|
|
XVisualInfo *vi;
|
|
|
|
- vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att);
|
|
+ XOutput *out = g_xrandr.GetOutput(output);
|
|
+ if (!out)
|
|
+ out = g_xrandr.GetOutput(m_currentOutput);
|
|
+ m_nScreen = out->screen;
|
|
+ vi = glXChooseVisual(m_dpy, m_nScreen, att);
|
|
cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);
|
|
|
|
int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen));
|
|
@@ -733,7 +769,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask;
|
|
|
|
m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
|
|
- 0, 0, width, height, 0, vi->depth,
|
|
+ out->x, out->y, width, height, 0, vi->depth,
|
|
InputOutput, vi->visual,
|
|
mask, &swa);
|
|
|
|
@@ -804,14 +840,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen)
|
|
if (fullscreen)
|
|
{
|
|
int result = -1;
|
|
- while (result != GrabSuccess)
|
|
+ while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
{
|
|
- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime);
|
|
+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
XbmcThreads::ThreadSleep(100);
|
|
}
|
|
XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
-
|
|
}
|
|
+ CSingleLock lock(m_resourceSection);
|
|
+ // tell any shared resources
|
|
+ for (vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
|
|
+ (*i)->OnResetDevice();
|
|
+
|
|
+ m_windowDirty = false;
|
|
}
|
|
return true;
|
|
}
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 4175aab..94584ab 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -67,15 +67,16 @@ public:
|
|
Display* GetDisplay() { return m_dpy; }
|
|
GLXWindow GetWindow() { return m_glWindow; }
|
|
GLXContext GetGlxContext() { return m_glContext; }
|
|
- void RefreshWindow();
|
|
void NotifyXRREvent();
|
|
+ void GetConnectedOutputs(std::vector<CStdString> *outputs);
|
|
+ bool IsCurrentOutput(CStdString output);
|
|
+ void NotifyMouseCoverage(bool covered);
|
|
|
|
protected:
|
|
bool RefreshGlxContext();
|
|
void CheckDisplayEvents();
|
|
void OnLostDevice();
|
|
- bool SetWindow(int width, int height, bool fullscreen);
|
|
- void RotateResolutions();
|
|
+ bool SetWindow(int width, int height, bool fullscreen, const CStdString &output);
|
|
|
|
Window m_glWindow;
|
|
GLXContext m_glContext;
|
|
@@ -90,6 +91,9 @@ protected:
|
|
CCriticalSection m_resourceSection;
|
|
std::vector<IDispResource*> m_resources;
|
|
uint64_t m_dpyLostTime;
|
|
+ CStdString m_currentOutput;
|
|
+ bool m_windowDirty;
|
|
+ bool m_bIsInternalXrr;
|
|
|
|
private:
|
|
bool IsSuitableVisual(XVisualInfo *vInfo);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From bf5648cf0df4279b2135f65d39542258de32a307 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 11:36:32 +0200
|
|
Subject: [PATCH 17/93] X11: remove all DefaultScreen and RootWindow macros
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 6 +++---
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
xbmc/windowing/X11/WinSystemX11GL.cpp | 2 +-
|
|
3 files changed, 5 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 5e86772..c4fa17c 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -271,7 +271,7 @@ void CWinSystemX11::UpdateResolutions()
|
|
else
|
|
#endif
|
|
{
|
|
- int x11screen = DefaultScreen(m_dpy);
|
|
+ int x11screen = m_nScreen;
|
|
int w = DisplayWidth(m_dpy, x11screen);
|
|
int h = DisplayHeight(m_dpy, x11screen);
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0);
|
|
@@ -393,7 +393,7 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
XVisualInfo *visuals;
|
|
XVisualInfo *vInfo = NULL;
|
|
int availableVisuals = 0;
|
|
- vMask.screen = DefaultScreen(m_dpy);
|
|
+ vMask.screen = m_nScreen;
|
|
XWindowAttributes winAttr;
|
|
|
|
/* Assume a depth of 24 in case the below calls to XGetWindowAttributes()
|
|
@@ -547,7 +547,7 @@ bool CWinSystemX11::Minimize()
|
|
g_graphicsContext.ToggleFullScreenRoot();
|
|
}
|
|
|
|
- XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy));
|
|
+ XIconifyWindow(m_dpy, m_glWindow, m_nScreen);
|
|
|
|
m_minimized = true;
|
|
return true;
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 94584ab..2bcaf52 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -49,6 +49,7 @@ public:
|
|
virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays);
|
|
virtual void UpdateResolutions();
|
|
virtual int GetNumScreens() { return 1; }
|
|
+ virtual int GetCurrentScreen() { return m_nScreen; }
|
|
virtual void ShowOSMouse(bool show);
|
|
virtual void ResetOSScreensaver();
|
|
virtual bool EnableFrameLimiter();
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
index 6383754..21e7dc5 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
@@ -167,7 +167,7 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R
|
|
return false;
|
|
|
|
m_glxext = " ";
|
|
- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy));
|
|
+ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_nScreen);
|
|
m_glxext += " ";
|
|
|
|
CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str());
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 140a3ba6605aaba862ee004e78ff96aa84e0b8d9 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 11:45:22 +0200
|
|
Subject: [PATCH 18/93] X11: remove all DefaultScreen and RootWindow macros
|
|
(VideoRefClock)
|
|
|
|
Note this is on a separate display connection.
|
|
---
|
|
xbmc/video/VideoReferenceClock.cpp | 15 ++++++++-------
|
|
1 file changed, 8 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp
|
|
index 0b3950a..ca43b5a 100644
|
|
--- a/xbmc/video/VideoReferenceClock.cpp
|
|
+++ b/xbmc/video/VideoReferenceClock.cpp
|
|
@@ -271,7 +271,7 @@ bool CVideoReferenceClock::SetupGLX()
|
|
}
|
|
|
|
bool ExtensionFound = false;
|
|
- istringstream Extensions(glXQueryExtensionsString(m_Dpy, DefaultScreen(m_Dpy)));
|
|
+ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen()));
|
|
string ExtensionStr;
|
|
|
|
while (!ExtensionFound)
|
|
@@ -297,7 +297,7 @@ bool CVideoReferenceClock::SetupGLX()
|
|
m_bIsATI = true;
|
|
}
|
|
|
|
- m_vInfo = glXChooseVisual(m_Dpy, DefaultScreen(m_Dpy), singleBufferAttributes);
|
|
+ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes);
|
|
if (!m_vInfo)
|
|
{
|
|
CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL");
|
|
@@ -308,15 +308,16 @@ bool CVideoReferenceClock::SetupGLX()
|
|
{
|
|
Swa.border_pixel = 0;
|
|
Swa.event_mask = StructureNotifyMask;
|
|
- Swa.colormap = XCreateColormap(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), m_vInfo->visual, AllocNone );
|
|
+ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone );
|
|
SwaMask = CWBorderPixel | CWColormap | CWEventMask;
|
|
|
|
- m_Window = XCreateWindow(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), 0, 0, 256, 256, 0,
|
|
+ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0,
|
|
m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa);
|
|
}
|
|
else
|
|
{
|
|
- m_pixmap = XCreatePixmap(m_Dpy, DefaultRootWindow(m_Dpy), 256, 256, m_vInfo->depth);
|
|
+ Window window = g_Windowing.GetWindow();
|
|
+ m_pixmap = XCreatePixmap(m_Dpy, window, 256, 256, m_vInfo->depth);
|
|
if (!m_pixmap)
|
|
{
|
|
CLog::Log(LOGDEBUG, "CVideoReferenceClock: unable to create pixmap");
|
|
@@ -383,7 +384,7 @@ bool CVideoReferenceClock::SetupGLX()
|
|
|
|
//set up receiving of RandR events, we'll get one when the refreshrate changes
|
|
XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV);
|
|
- XRRSelectInput(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), RRScreenChangeNotifyMask);
|
|
+ XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask);
|
|
|
|
UpdateRefreshrate(true); //forced refreshrate update
|
|
m_MissedVblanks = 0;
|
|
@@ -518,7 +519,7 @@ int CVideoReferenceClock::GetRandRRate()
|
|
int RefreshRate;
|
|
XRRScreenConfiguration *CurrInfo;
|
|
|
|
- CurrInfo = XRRGetScreenInfo(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen));
|
|
+ CurrInfo = XRRGetScreenInfo(m_Dpy, g_Windowing.GetWindow());
|
|
RefreshRate = XRRConfigCurrentRate(CurrInfo);
|
|
XRRFreeScreenConfigInfo(CurrInfo);
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From bccf49bf686d33cf16db5f99e013a71e2c3a2373 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Wed, 20 Jun 2012 17:37:11 +0200
|
|
Subject: [PATCH 19/93] X11: recreate gl context after output has changed
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++----------
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
xbmc/windowing/X11/WinSystemX11GL.cpp | 9 +++++++++
|
|
3 files changed, 24 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index c4fa17c..f2fd18d 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -172,7 +172,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
return false;
|
|
}
|
|
|
|
- RefreshGlxContext();
|
|
m_nWidth = newWidth;
|
|
m_nHeight = newHeight;
|
|
m_bFullScreen = false;
|
|
@@ -223,14 +222,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
OnLostDevice();
|
|
m_bIsInternalXrr = true;
|
|
g_xrandr.SetMode(out, mode);
|
|
+ return true;
|
|
}
|
|
#endif
|
|
|
|
if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor")))
|
|
return false;
|
|
|
|
- RefreshGlxContext();
|
|
-
|
|
m_nWidth = res.iWidth;
|
|
m_nHeight = res.iHeight;
|
|
m_bFullScreen = fullScreen;
|
|
@@ -381,11 +379,8 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
if (m_glContext)
|
|
{
|
|
CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
|
|
- glFinish();
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
|
|
- XSync(m_dpy, FALSE);
|
|
- g_Windowing.ResetVSync();
|
|
return true;
|
|
}
|
|
|
|
@@ -445,14 +440,14 @@ bool CWinSystemX11::RefreshGlxContext()
|
|
{
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
glXDestroyContext(m_dpy, m_glContext);
|
|
+ XSync(m_dpy, FALSE);
|
|
+ m_newGlContext = true;
|
|
}
|
|
|
|
if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True)))
|
|
{
|
|
// make this context current
|
|
glXMakeCurrent(m_dpy, m_glWindow, m_glContext);
|
|
- g_Windowing.ResetVSync();
|
|
- XSync(m_dpy, False);
|
|
retVal = true;
|
|
}
|
|
else
|
|
@@ -729,6 +724,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
}
|
|
OnLostDevice();
|
|
DestroyWindow();
|
|
+ m_windowDirty = true;
|
|
}
|
|
|
|
// create main window
|
|
@@ -847,13 +843,21 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
}
|
|
XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
}
|
|
+
|
|
+ CDirtyRegionList dr;
|
|
+ RefreshGlxContext();
|
|
+ XSync(m_dpy, FALSE);
|
|
+ g_graphicsContext.Clear(0);
|
|
+ g_graphicsContext.Flip(dr);
|
|
+ g_Windowing.ResetVSync();
|
|
+ m_windowDirty = false;
|
|
+
|
|
CSingleLock lock(m_resourceSection);
|
|
// tell any shared resources
|
|
for (vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
|
|
(*i)->OnResetDevice();
|
|
-
|
|
- m_windowDirty = false;
|
|
}
|
|
+
|
|
return true;
|
|
}
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 2bcaf52..9666cc3 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -95,6 +95,7 @@ protected:
|
|
CStdString m_currentOutput;
|
|
bool m_windowDirty;
|
|
bool m_bIsInternalXrr;
|
|
+ bool m_newGlContext;
|
|
|
|
private:
|
|
bool IsSuitableVisual(XVisualInfo *vInfo);
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
index 21e7dc5..8e68d5d 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp
|
|
@@ -24,6 +24,7 @@
|
|
#include "WinSystemX11GL.h"
|
|
#include "utils/log.h"
|
|
#include "utils/StringUtils.h"
|
|
+#include "Application.h"
|
|
|
|
CWinSystemX11GL::CWinSystemX11GL()
|
|
{
|
|
@@ -197,17 +198,25 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R
|
|
|
|
bool CWinSystemX11GL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
|
|
{
|
|
+ m_newGlContext = false;
|
|
CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop);
|
|
CRenderSystemGL::ResetRenderSystem(newWidth, newHeight, false, 0);
|
|
|
|
+ if (m_newGlContext)
|
|
+ g_application.ReloadSkin();
|
|
+
|
|
return true;
|
|
}
|
|
|
|
bool CWinSystemX11GL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
|
|
{
|
|
+ m_newGlContext = false;
|
|
CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays);
|
|
CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate);
|
|
|
|
+ if (m_newGlContext)
|
|
+ g_application.ReloadSkin();
|
|
+
|
|
return true;
|
|
}
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 639f0284a947daac02be7bf2e727226f3f2c1526 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 12:06:25 +0200
|
|
Subject: [PATCH 20/93] X11: hook video reference clock in windowing
|
|
|
|
---
|
|
xbmc/video/VideoReferenceClock.cpp | 71 +++++++++++++++++++++++++++-----------
|
|
xbmc/video/VideoReferenceClock.h | 13 ++++++-
|
|
2 files changed, 63 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp
|
|
index ca43b5a..0ddf102 100644
|
|
--- a/xbmc/video/VideoReferenceClock.cpp
|
|
+++ b/xbmc/video/VideoReferenceClock.cpp
|
|
@@ -136,12 +136,23 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock")
|
|
m_Context = NULL;
|
|
m_pixmap = None;
|
|
m_glPixmap = None;
|
|
- m_RREventBase = 0;
|
|
m_UseNvSettings = true;
|
|
m_bIsATI = false;
|
|
#endif
|
|
}
|
|
|
|
+CVideoReferenceClock::~CVideoReferenceClock()
|
|
+{
|
|
+#if defined(HAS_GLX)
|
|
+ // some ATI voodoo, if we don't close the display, we crash on exit
|
|
+ if (m_Dpy)
|
|
+ {
|
|
+ XCloseDisplay(m_Dpy);
|
|
+ m_Dpy = NULL;
|
|
+ }
|
|
+#endif
|
|
+}
|
|
+
|
|
void CVideoReferenceClock::Process()
|
|
{
|
|
bool SetupSuccess = false;
|
|
@@ -152,6 +163,10 @@ void CVideoReferenceClock::Process()
|
|
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)
|
|
{
|
|
@@ -212,6 +227,16 @@ void CVideoReferenceClock::Process()
|
|
//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)
|
|
@@ -223,6 +248,9 @@ void CVideoReferenceClock::Process()
|
|
#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)
|
|
@@ -232,6 +260,24 @@ bool CVideoReferenceClock::WaitStarted(int 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[] = {
|
|
@@ -382,10 +428,6 @@ bool CVideoReferenceClock::SetupGLX()
|
|
return false;
|
|
}
|
|
|
|
- //set up receiving of RandR events, we'll get one when the refreshrate changes
|
|
- XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV);
|
|
- XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask);
|
|
-
|
|
UpdateRefreshrate(true); //forced refreshrate update
|
|
m_MissedVblanks = 0;
|
|
|
|
@@ -586,6 +628,9 @@ void CVideoReferenceClock::RunGLX()
|
|
|
|
while(!m_bStop)
|
|
{
|
|
+ if (m_xrrEvent)
|
|
+ return;
|
|
+
|
|
//wait for the next vblank
|
|
if (!m_bIsATI)
|
|
{
|
|
@@ -649,7 +694,6 @@ void CVideoReferenceClock::RunGLX()
|
|
UpdateClock((int)(VblankCount - PrevVblankCount), true);
|
|
SingleLock.Leave();
|
|
SendVblankSignal();
|
|
- UpdateRefreshrate();
|
|
IsReset = false;
|
|
}
|
|
else if (!m_bStop)
|
|
@@ -1186,23 +1230,10 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/)
|
|
|
|
#if defined(HAS_GLX) && defined(HAS_XRANDR)
|
|
|
|
- //check for RandR events
|
|
- bool GotEvent = Forced || m_RefreshChanged == 2;
|
|
- XEvent Event;
|
|
- while (XCheckTypedEvent(m_Dpy, m_RREventBase + RRScreenChangeNotify, &Event))
|
|
- {
|
|
- if (Event.type == m_RREventBase + RRScreenChangeNotify)
|
|
- {
|
|
- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Received RandR event %i", Event.type);
|
|
- GotEvent = true;
|
|
- }
|
|
- XRRUpdateConfiguration(&Event);
|
|
- }
|
|
-
|
|
if (!Forced)
|
|
m_RefreshChanged = 0;
|
|
|
|
- if (!GotEvent) //refreshrate did not change
|
|
+ if (!Forced) //refreshrate did not change
|
|
return false;
|
|
|
|
//the refreshrate can be wrong on nvidia drivers, so read it from nvidia-settings when it's available
|
|
diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h
|
|
index dd65a1b..afd71fc 100644
|
|
--- a/xbmc/video/VideoReferenceClock.h
|
|
+++ b/xbmc/video/VideoReferenceClock.h
|
|
@@ -30,6 +30,7 @@
|
|
#include <X11/X.h>
|
|
#include <X11/Xlib.h>
|
|
#include <GL/glx.h>
|
|
+ #include "guilib/DispResource.h"
|
|
#elif defined(TARGET_WINDOWS) && defined(HAS_DX)
|
|
#include <d3d9.h>
|
|
#include "guilib/D3DResource.h"
|
|
@@ -56,9 +57,13 @@ class CD3DCallback : public ID3DResource
|
|
#endif
|
|
|
|
class CVideoReferenceClock : public CThread
|
|
+#if defined(HAS_GLX) && defined(HAS_XRANDR)
|
|
+ ,public IDispResource
|
|
+#endif
|
|
{
|
|
public:
|
|
CVideoReferenceClock();
|
|
+ virtual ~CVideoReferenceClock();
|
|
|
|
int64_t GetTime(bool interpolated = true);
|
|
int64_t GetFrequency();
|
|
@@ -75,6 +80,11 @@ class CVideoReferenceClock : public CThread
|
|
void VblankHandler(int64_t nowtime, double fps);
|
|
#endif
|
|
|
|
+#if defined(HAS_GLX) && defined(HAS_XRANDR)
|
|
+ virtual void OnLostDevice();
|
|
+ virtual void OnResetDevice();
|
|
+#endif
|
|
+
|
|
private:
|
|
void Process();
|
|
bool UpdateRefreshrate(bool Forced = false);
|
|
@@ -121,7 +131,8 @@ class CVideoReferenceClock : public CThread
|
|
GLXContext m_Context;
|
|
Pixmap m_pixmap;
|
|
GLXPixmap m_glPixmap;
|
|
- int m_RREventBase;
|
|
+ bool m_xrrEvent;
|
|
+ CEvent m_releaseEvent, m_resetEvent;
|
|
|
|
bool m_UseNvSettings;
|
|
bool m_bIsATI;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From f6ca378b58cabe46334742050fe263a98ac64f94 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 21 Jun 2012 17:26:51 +0200
|
|
Subject: [PATCH 21/93] X11: fix video calibrations
|
|
|
|
---
|
|
xbmc/windowing/WinSystem.h | 1 +
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 36 +++++++++++++++++++++++++++++++++++-
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
3 files changed, 37 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h
|
|
index 00a2d24..c0db210 100644
|
|
--- a/xbmc/windowing/WinSystem.h
|
|
+++ b/xbmc/windowing/WinSystem.h
|
|
@@ -103,6 +103,7 @@ public:
|
|
std::vector<RESOLUTION_WHR> ScreenResolutions(int screen, float refreshrate);
|
|
std::vector<REFRESHRATE> RefreshRates(int screen, int width, int height, uint32_t dwFlags);
|
|
REFRESHRATE DefaultRefreshRate(int screen, std::vector<REFRESHRATE> rates);
|
|
+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo) { return true; };
|
|
|
|
// text input interface
|
|
virtual void EnableTextInput(bool bEnable) {}
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index f2fd18d..c4152c8 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -320,7 +320,7 @@ void CWinSystemX11::UpdateResolutions()
|
|
res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz);
|
|
res.strOutput = out.name;
|
|
res.strId = mode.id;
|
|
- res.iSubtitles = (int)(0.95*mode.h);
|
|
+ res.iSubtitles = (int)(0.965*mode.h);
|
|
res.fRefreshRate = mode.hz;
|
|
res.bFullScreen = true;
|
|
|
|
@@ -333,8 +333,42 @@ void CWinSystemX11::UpdateResolutions()
|
|
CDisplaySettings::Get().AddResolutionInfo(res);
|
|
}
|
|
}
|
|
+ CDisplaySettings::Get().ApplyCalibrations();
|
|
#endif
|
|
+}
|
|
+
|
|
+bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo)
|
|
+{
|
|
+ XOutput *out = g_xrandr.GetOutput(m_currentOutput);
|
|
+
|
|
+ // keep calibrations done on a not connected output
|
|
+ if (!out->name.Equals(resInfo.strOutput))
|
|
+ return true;
|
|
+
|
|
+ // keep calibrations not updated with resolution data
|
|
+ if (resInfo.iWidth == 0)
|
|
+ return true;
|
|
+
|
|
+ float fPixRatio;
|
|
+ if (resInfo.iHeight>0 && resInfo.iWidth>0 && out->hmm>0 && out->wmm>0)
|
|
+ fPixRatio = ((float)out->wmm/(float)resInfo.iWidth) / (((float)out->hmm/(float)resInfo.iHeight));
|
|
+ else
|
|
+ fPixRatio = 1.0f;
|
|
|
|
+ if (resInfo.Overscan.left != 0)
|
|
+ return true;
|
|
+ if (resInfo.Overscan.top != 0)
|
|
+ return true;
|
|
+ if (resInfo.Overscan.right != resInfo.iWidth)
|
|
+ return true;
|
|
+ if (resInfo.Overscan.bottom != resInfo.iHeight)
|
|
+ return true;
|
|
+ if (resInfo.fPixelRatio != fPixRatio)
|
|
+ return true;
|
|
+ if (resInfo.iSubtitles != (int)(0.965*resInfo.iHeight))
|
|
+ return true;
|
|
+
|
|
+ return false;
|
|
}
|
|
|
|
void CWinSystemX11::GetConnectedOutputs(std::vector<CStdString> *outputs)
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 9666cc3..5b52d6c 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -63,6 +63,7 @@ public:
|
|
virtual bool Show(bool raise = true);
|
|
virtual void Register(IDispResource *resource);
|
|
virtual void Unregister(IDispResource *resource);
|
|
+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo);
|
|
|
|
// Local to WinSystemX11 only
|
|
Display* GetDisplay() { return m_dpy; }
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From c329e543adfd4989b6e53f936200f552ab90a369 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 12:00:26 +0200
|
|
Subject: [PATCH 22/93] X11: deactivate screen saver on startup
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
2 files changed, 30 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index c4152c8..b76b229 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -521,6 +521,33 @@ void CWinSystemX11::ResetOSScreensaver()
|
|
}
|
|
}
|
|
|
|
+void CWinSystemX11::EnableSystemScreenSaver(bool bEnable)
|
|
+{
|
|
+ if (!m_dpy)
|
|
+ return;
|
|
+
|
|
+ if (bEnable)
|
|
+ XForceScreenSaver(m_dpy, ScreenSaverActive);
|
|
+ else
|
|
+ {
|
|
+ Window root_return, child_return;
|
|
+ int root_x_return, root_y_return;
|
|
+ int win_x_return, win_y_return;
|
|
+ unsigned int mask_return;
|
|
+ bool isInWin = XQueryPointer(m_dpy, RootWindow(m_dpy, m_nScreen), &root_return, &child_return,
|
|
+ &root_x_return, &root_y_return,
|
|
+ &win_x_return, &win_y_return,
|
|
+ &mask_return);
|
|
+
|
|
+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return+300, root_y_return+300);
|
|
+ XSync(m_dpy, FALSE);
|
|
+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, 0, 0);
|
|
+ XSync(m_dpy, FALSE);
|
|
+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return, root_y_return);
|
|
+ XSync(m_dpy, FALSE);
|
|
+ }
|
|
+}
|
|
+
|
|
void CWinSystemX11::NotifyAppActiveChange(bool bActivated)
|
|
{
|
|
if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen)
|
|
@@ -764,6 +791,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
// create main window
|
|
if (!m_glWindow)
|
|
{
|
|
+ EnableSystemScreenSaver(false);
|
|
+
|
|
GLint att[] =
|
|
{
|
|
GLX_RGBA,
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 5b52d6c..b2bd5a0 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -53,6 +53,7 @@ public:
|
|
virtual void ShowOSMouse(bool show);
|
|
virtual void ResetOSScreensaver();
|
|
virtual bool EnableFrameLimiter();
|
|
+ virtual void EnableSystemScreenSaver(bool bEnable);
|
|
|
|
virtual void NotifyAppActiveChange(bool bActivated);
|
|
virtual void NotifyAppFocusChange(bool bGaining);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From d157d02acb752b074e9691f5b75bd55363dc5528 Mon Sep 17 00:00:00 2001
|
|
From: FernetMenta <fernetmenta@online.de>
|
|
Date: Thu, 5 Jul 2012 12:10:09 +0200
|
|
Subject: [PATCH 23/93] X11: change method of going full-screen
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++-
|
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index b76b229..869baa8 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -38,6 +38,7 @@
|
|
#include "utils/StringUtils.h"
|
|
#include "settings/Settings.h"
|
|
#include "windowing/WindowingFactory.h"
|
|
+#include <X11/Xatom.h>
|
|
|
|
#if defined(HAS_XRANDR)
|
|
#include <X11/extensions/Xrandr.h>
|
|
@@ -816,7 +817,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);
|
|
|
|
int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen));
|
|
- swa.override_redirect = fullscreen ? True : False;
|
|
+ swa.override_redirect = False;
|
|
swa.border_pixel = fullscreen ? 0 : 5;
|
|
swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
swa.colormap = cmap;
|
|
@@ -832,6 +833,12 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
InputOutput, vi->visual,
|
|
mask, &swa);
|
|
|
|
+ if (fullscreen)
|
|
+ {
|
|
+ Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True);
|
|
+ XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
|
|
+ }
|
|
+
|
|
// define invisible cursor
|
|
Pixmap bitmapNoData;
|
|
XColor black;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 237a8d20a027e2fd3dfeb145aca32bff0525903a Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 28 Jun 2012 19:12:39 +0200
|
|
Subject: [PATCH 24/93] X11: reset key repeat and key modifier on focus lost
|
|
and gain
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index d98f12f..743aca9 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -368,6 +368,8 @@ bool CWinEventsX11Imp::MessagePump()
|
|
if (WinEvents->m_xic)
|
|
XSetICFocus(WinEvents->m_xic);
|
|
g_application.m_AppFocused = true;
|
|
+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
+ WinEvents->m_keymodState = 0;
|
|
if (serial == xevent.xfocus.serial)
|
|
break;
|
|
g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
|
|
@@ -379,6 +381,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
if (WinEvents->m_xic)
|
|
XUnsetICFocus(WinEvents->m_xic);
|
|
g_application.m_AppFocused = false;
|
|
+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
|
|
serial = xevent.xfocus.serial;
|
|
break;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From d86f85ddac13b7d104add8cac02c362f7a4fab28 Mon Sep 17 00:00:00 2001
|
|
From: Joakim Plate <elupus@xbmc.org>
|
|
Date: Thu, 5 Jul 2012 14:18:46 +0200
|
|
Subject: [PATCH 25/93] X11: replace custom utf8 to unicode with charset
|
|
convertor (squash to x11 events)
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 119 ++++------------------------------------
|
|
xbmc/windowing/WinEventsX11.h | 2 -
|
|
2 files changed, 11 insertions(+), 110 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 743aca9..6b98e67 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -32,6 +32,7 @@
|
|
#include "X11/keysymdef.h"
|
|
#include "X11/XF86keysym.h"
|
|
#include "utils/log.h"
|
|
+#include "utils/CharsetConverter.h"
|
|
#include "guilib/GUIWindowManager.h"
|
|
#include "input/MouseStat.h"
|
|
|
|
@@ -170,7 +171,6 @@ CWinEventsX11Imp::CWinEventsX11Imp()
|
|
m_display = 0;
|
|
m_window = 0;
|
|
m_keybuf = 0;
|
|
- m_utf16buf = 0;
|
|
}
|
|
|
|
CWinEventsX11Imp::~CWinEventsX11Imp()
|
|
@@ -181,12 +181,6 @@ CWinEventsX11Imp::~CWinEventsX11Imp()
|
|
m_keybuf = 0;
|
|
}
|
|
|
|
- if (m_utf16buf)
|
|
- {
|
|
- free(m_utf16buf);
|
|
- m_utf16buf = 0;
|
|
- }
|
|
-
|
|
if (m_xic)
|
|
{
|
|
XUnsetICFocus(m_xic);
|
|
@@ -212,7 +206,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_display = dpy;
|
|
WinEvents->m_window = win;
|
|
WinEvents->m_keybuf = (char*)malloc(32*sizeof(char));
|
|
- WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t));
|
|
WinEvents->m_keymodState = 0;
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
@@ -442,8 +435,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
}
|
|
|
|
Status status;
|
|
- int utf16size;
|
|
- int utf16length;
|
|
int len;
|
|
len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey,
|
|
WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf),
|
|
@@ -462,36 +453,29 @@ bool CWinEventsX11Imp::MessagePump()
|
|
case XLookupChars:
|
|
case XLookupBoth:
|
|
{
|
|
- if (len == 0)
|
|
- break;
|
|
- utf16size = len * sizeof(uint16_t);
|
|
- if (utf16size > sizeof(WinEvents->m_utf16buf))
|
|
- {
|
|
- WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size);
|
|
- if (WinEvents->m_utf16buf == NULL)
|
|
- {
|
|
- break;
|
|
- }
|
|
- }
|
|
- utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size);
|
|
- if (utf16length < 0)
|
|
+ CStdString data(WinEvents->m_keybuf, len);
|
|
+ CStdStringW keys;
|
|
+ g_charsetConverter.utf8ToW(data, keys, false);
|
|
+
|
|
+ if (keys.length() == 0)
|
|
{
|
|
break;
|
|
}
|
|
- for (unsigned int i = 0; i < utf16length - 1; i++)
|
|
+
|
|
+ for (unsigned int i = 0; i < keys.length() - 1; i++)
|
|
{
|
|
newEvent.key.keysym.sym = XBMCK_UNKNOWN;
|
|
- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i];
|
|
+ newEvent.key.keysym.unicode = keys[i];
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
ret |= ProcessKey(newEvent, 500);
|
|
}
|
|
- if (utf16length > 0)
|
|
+ if (keys.length() > 0)
|
|
{
|
|
newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1];
|
|
+ newEvent.key.keysym.unicode = keys[keys.length() - 1];
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
|
|
@@ -762,87 +746,6 @@ bool CWinEventsX11Imp::ProcessKeyRepeat()
|
|
return false;
|
|
}
|
|
|
|
-int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength)
|
|
-{
|
|
- // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer.
|
|
- uint16_t *p = utf16;
|
|
- uint16_t const *const maxPtr = utf16 + utf16MaxLength;
|
|
-
|
|
- // end_of_input points to the last byte of input as opposed to the next to the last byte.
|
|
- char const *const endOfInput = utf8 + utf8Length - 1;
|
|
-
|
|
- while (utf8 <= endOfInput)
|
|
- {
|
|
- unsigned char const c = *utf8;
|
|
- if (p >= maxPtr)
|
|
- {
|
|
- //No more output space.
|
|
- return -1;
|
|
- }
|
|
- if (c < 0x80)
|
|
- {
|
|
- //One byte ASCII.
|
|
- *p++ = c;
|
|
- utf8 += 1;
|
|
- }
|
|
- else if (c < 0xC0)
|
|
- {
|
|
- // Follower byte without preceding leader bytes.
|
|
- return -1;
|
|
- }
|
|
- // 11 bits
|
|
- else if (c < 0xE0)
|
|
- {
|
|
- // Two byte sequence. We need one follower byte.
|
|
- if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0))
|
|
- {
|
|
- return -1;
|
|
- }
|
|
- *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F));
|
|
- utf8 += 2;
|
|
- }
|
|
- // 16 bis
|
|
- else if (c < 0xF0)
|
|
- {
|
|
- // Three byte sequence. We need two follower byte.
|
|
- if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0))
|
|
- {
|
|
- return -1;
|
|
- }
|
|
- *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F));
|
|
- utf8 += 3;
|
|
- }
|
|
- // 21 bits
|
|
- else if (c < 0xF8)
|
|
- {
|
|
- int plane;
|
|
- // Four byte sequence. We need three follower bytes.
|
|
- if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) ||
|
|
- ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0))
|
|
- {
|
|
- return -1;
|
|
- }
|
|
- uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) +
|
|
- ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F);
|
|
- utf8 += 4;
|
|
- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
- }
|
|
- // 26 bits
|
|
- else if (c < 0xFC)
|
|
- {
|
|
- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
- utf8 += 5;
|
|
- }
|
|
- // 31 bit
|
|
- else
|
|
- {
|
|
- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported");
|
|
- utf8 += 6;
|
|
- }
|
|
- }
|
|
- return p - utf16;
|
|
-}
|
|
-
|
|
XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym)
|
|
{
|
|
// try direct mapping first
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index a412f32..9a8a912 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -46,7 +46,6 @@ public:
|
|
static size_t GetQueueSize();
|
|
|
|
protected:
|
|
- static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength);
|
|
static XBMCKey LookupXbmcKeySym(KeySym keysym);
|
|
static bool ProcessKey(XBMC_Event &event, int repeatDelay);
|
|
static bool ProcessKeyRepeat();
|
|
@@ -56,7 +55,6 @@ protected:
|
|
Window m_window;
|
|
Atom m_wmDeleteMessage;
|
|
char *m_keybuf;
|
|
- uint16_t *m_utf16buf;
|
|
XIM m_xim;
|
|
XIC m_xic;
|
|
XBMC_Event m_lastKey;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 196db63b99d44b058a6b1fdd80798afbaab4435f Mon Sep 17 00:00:00 2001
|
|
From: Joakim Plate <elupus@xbmc.org>
|
|
Date: Thu, 5 Jul 2012 14:23:54 +0200
|
|
Subject: [PATCH 26/93] X11: fixed invalid usage of sizeof() (squash into x11
|
|
changes)
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 11 +++++++----
|
|
xbmc/windowing/WinEventsX11.h | 1 +
|
|
2 files changed, 8 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 6b98e67..a62521f 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -171,6 +171,7 @@ CWinEventsX11Imp::CWinEventsX11Imp()
|
|
m_display = 0;
|
|
m_window = 0;
|
|
m_keybuf = 0;
|
|
+ m_keybuf_len = 0;
|
|
}
|
|
|
|
CWinEventsX11Imp::~CWinEventsX11Imp()
|
|
@@ -205,7 +206,8 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents = new CWinEventsX11Imp();
|
|
WinEvents->m_display = dpy;
|
|
WinEvents->m_window = win;
|
|
- WinEvents->m_keybuf = (char*)malloc(32*sizeof(char));
|
|
+ WinEvents->m_keybuf_len = 32*sizeof(char);
|
|
+ WinEvents->m_keybuf = (char*)malloc(WinEvents->m_keybuf_len);
|
|
WinEvents->m_keymodState = 0;
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
@@ -437,13 +439,14 @@ bool CWinEventsX11Imp::MessagePump()
|
|
Status status;
|
|
int len;
|
|
len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey,
|
|
- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf),
|
|
+ WinEvents->m_keybuf, WinEvents->m_keybuf_len,
|
|
&xkeysym, &status);
|
|
if (status == XBufferOverflow)
|
|
{
|
|
- WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char));
|
|
+ WinEvents->m_keybuf_len = len;
|
|
+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, WinEvents->m_keybuf_len);
|
|
len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey,
|
|
- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf),
|
|
+ WinEvents->m_keybuf, WinEvents->m_keybuf_len,
|
|
&xkeysym, &status);
|
|
}
|
|
switch (status)
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index 9a8a912..c69169c 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -55,6 +55,7 @@ protected:
|
|
Window m_window;
|
|
Atom m_wmDeleteMessage;
|
|
char *m_keybuf;
|
|
+ size_t m_keybuf_len;
|
|
XIM m_xim;
|
|
XIC m_xic;
|
|
XBMC_Event m_lastKey;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 3ccc149a56b520df7a8933b889273296ba875090 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sat, 9 Jun 2012 18:23:53 +0200
|
|
Subject: [PATCH 27/93] add missing keys to xbmc keytable
|
|
|
|
---
|
|
xbmc/input/XBMC_keytable.cpp | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp
|
|
index d57f4d3..b807897 100644
|
|
--- a/xbmc/input/XBMC_keytable.cpp
|
|
+++ b/xbmc/input/XBMC_keytable.cpp
|
|
@@ -180,6 +180,8 @@ static const XBMCKEYTABLE XBMCKeyTable[] =
|
|
, { XBMCK_LAUNCH_APP2, 0, 0, XBMCVK_LAUNCH_APP2, "launch_app2_pc_icon" }
|
|
, { XBMCK_LAUNCH_FILE_BROWSER, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER, "launch_file_browser" }
|
|
, { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" }
|
|
+, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" }
|
|
+, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" }
|
|
|
|
// Function keys
|
|
, { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 2b820efe0e7850414b31495b9569e6dac6e90a28 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Fri, 16 Mar 2012 15:57:51 +0100
|
|
Subject: [PATCH 28/93] videorefclock: temp deactivate of nv settings
|
|
|
|
---
|
|
xbmc/video/VideoReferenceClock.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp
|
|
index 0ddf102..3ae7107 100644
|
|
--- a/xbmc/video/VideoReferenceClock.cpp
|
|
+++ b/xbmc/video/VideoReferenceClock.cpp
|
|
@@ -136,7 +136,7 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock")
|
|
m_Context = NULL;
|
|
m_pixmap = None;
|
|
m_glPixmap = None;
|
|
- m_UseNvSettings = true;
|
|
+ m_UseNvSettings = false;
|
|
m_bIsATI = false;
|
|
#endif
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From cd2f165acc58eaa519b48cdb53a6b5a4a8120be0 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 20 Aug 2012 09:09:09 +0200
|
|
Subject: [PATCH 29/93] videorefclock: ask graphics context for refresh rate
|
|
|
|
---
|
|
xbmc/video/VideoReferenceClock.cpp | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp
|
|
index 3ae7107..27bebde 100644
|
|
--- a/xbmc/video/VideoReferenceClock.cpp
|
|
+++ b/xbmc/video/VideoReferenceClock.cpp
|
|
@@ -31,6 +31,7 @@
|
|
#include <sstream>
|
|
#include <X11/extensions/Xrandr.h>
|
|
#include "windowing/WindowingFactory.h"
|
|
+ #include "guilib/GraphicContext.h"
|
|
#define NVSETTINGSCMD "nvidia-settings -nt -q RefreshRate3"
|
|
#elif defined(TARGET_DARWIN_OSX)
|
|
#include <QuartzCore/CVDisplayLink.h>
|
|
@@ -1254,7 +1255,7 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/)
|
|
}
|
|
|
|
CSingleLock SingleLock(m_CritSection);
|
|
- m_RefreshRate = GetRandRRate();
|
|
+ m_RefreshRate = MathUtils::round_int(g_graphicsContext.GetFPS());
|
|
|
|
CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", (int)m_RefreshRate);
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 603317efd971a1f90d15ebb5c8bc381912b710e2 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 9 Jul 2012 14:00:18 +0200
|
|
Subject: [PATCH 30/93] X11: fix icon texture after
|
|
cc5ed3c2474084ebc0373a3046410e6f766e03f4
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 43 ++++++++++++++++++++++---------------
|
|
1 file changed, 26 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 869baa8..bfe3797 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -874,22 +874,24 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
if (!fullscreen)
|
|
{
|
|
CreateIconPixmap();
|
|
- XWMHints wm_hints;
|
|
- XClassHint class_hints;
|
|
+ XWMHints *wm_hints;
|
|
XTextProperty windowName, iconName;
|
|
std::string titleString = "XBMC Media Center";
|
|
char *title = (char*)titleString.c_str();
|
|
|
|
XStringListToTextProperty(&title, 1, &windowName);
|
|
XStringListToTextProperty(&title, 1, &iconName);
|
|
- wm_hints.initial_state = NormalState;
|
|
- wm_hints.input = True;
|
|
- wm_hints.icon_pixmap = m_icon;
|
|
- wm_hints.flags = StateHint | IconPixmapHint | InputHint;
|
|
|
|
+ wm_hints = XAllocWMHints();
|
|
+ wm_hints->initial_state = NormalState;
|
|
+ wm_hints->icon_pixmap = m_icon;
|
|
+ wm_hints->flags = StateHint | IconPixmapHint;
|
|
+
|
|
+ XSync(m_dpy,False);
|
|
XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName,
|
|
- NULL, 0, NULL, &wm_hints,
|
|
+ NULL, 0, NULL, wm_hints,
|
|
NULL);
|
|
+ XFree(wm_hints);
|
|
|
|
// register interest in the delete window message
|
|
Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
|
|
@@ -974,16 +976,21 @@ bool CWinSystemX11::CreateIconPixmap()
|
|
gRatio = vis->green_mask / 255.0;
|
|
bRatio = vis->blue_mask / 255.0;
|
|
|
|
- CTexture iconTexture;
|
|
- iconTexture.LoadFromFile("special://xbmc/media/icon.png");
|
|
- buf = iconTexture.GetPixels();
|
|
+ CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon.png");
|
|
+
|
|
+ if (!iconTexture)
|
|
+ return false;
|
|
|
|
- numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4;
|
|
+ buf = iconTexture->GetPixels();
|
|
+
|
|
+ numBufBytes = iconTexture->GetWidth() * iconTexture->GetHeight() * 4;
|
|
+ int wid = iconTexture->GetWidth();
|
|
+ int hi = iconTexture->GetHeight();
|
|
|
|
if (depth>=24)
|
|
- numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight()));
|
|
+ numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight()));
|
|
else
|
|
- numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight()));
|
|
+ numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight()));
|
|
|
|
newBuf = (uint32_t*)malloc(numNewBufBytes);
|
|
if (!newBuf)
|
|
@@ -992,11 +999,11 @@ bool CWinSystemX11::CreateIconPixmap()
|
|
return false;
|
|
}
|
|
|
|
- for (i=0; i<iconTexture.GetHeight();++i)
|
|
+ for (i=0; i<iconTexture->GetHeight();++i)
|
|
{
|
|
- for (j=0; j<iconTexture.GetWidth();++j)
|
|
+ for (j=0; j<iconTexture->GetWidth();++j)
|
|
{
|
|
- unsigned int pos = i*iconTexture.GetPitch()+j*4;
|
|
+ unsigned int pos = i*iconTexture->GetPitch()+j*4;
|
|
unsigned int r, g, b;
|
|
r = (buf[pos+2] * rRatio);
|
|
g = (buf[pos+1] * gRatio);
|
|
@@ -1009,7 +1016,7 @@ bool CWinSystemX11::CreateIconPixmap()
|
|
}
|
|
}
|
|
img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf,
|
|
- iconTexture.GetWidth(), iconTexture.GetHeight(),
|
|
+ iconTexture->GetWidth(), iconTexture->GetHeight(),
|
|
(depth>=24)?32:16, 0);
|
|
if (!img)
|
|
{
|
|
@@ -1047,6 +1054,8 @@ bool CWinSystemX11::CreateIconPixmap()
|
|
XFreeGC(m_dpy, gc);
|
|
XDestroyImage(img); // this also frees newBuf
|
|
|
|
+ delete iconTexture;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 14680a3fd13af0a41b43899fdf3a2da65abad5f4 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Tue, 10 Jul 2012 11:14:12 +0200
|
|
Subject: [PATCH 31/93] X11: check for window manager
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++++-
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
2 files changed, 73 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index bfe3797..af82061 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -816,8 +816,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
vi = glXChooseVisual(m_dpy, m_nScreen, att);
|
|
cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);
|
|
|
|
+ bool hasWM = HasWindowManager();
|
|
+
|
|
int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen));
|
|
- swa.override_redirect = False;
|
|
+ swa.override_redirect = hasWM ? False : True;
|
|
swa.border_pixel = fullscreen ? 0 : 5;
|
|
swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
swa.colormap = cmap;
|
|
@@ -833,7 +835,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
InputOutput, vi->visual,
|
|
mask, &swa);
|
|
|
|
- if (fullscreen)
|
|
+ if (fullscreen && hasWM)
|
|
{
|
|
Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True);
|
|
XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
|
|
@@ -1059,4 +1061,72 @@ bool CWinSystemX11::CreateIconPixmap()
|
|
return true;
|
|
}
|
|
|
|
+bool CWinSystemX11::HasWindowManager()
|
|
+{
|
|
+ Window wm_check;
|
|
+ unsigned char *data;
|
|
+ int status, real_format;
|
|
+ Atom real_type, prop;
|
|
+ unsigned long items_read, items_left, i;
|
|
+ char req = 0;
|
|
+
|
|
+ prop = XInternAtom(m_dpy, "_NET_SUPPORTING_WM_CHECK", True);
|
|
+ if (prop == None)
|
|
+ return false;
|
|
+ status = XGetWindowProperty(m_dpy, DefaultRootWindow(m_dpy), prop,
|
|
+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format,
|
|
+ &items_read, &items_left, &data);
|
|
+ if(status != Success || ! items_read)
|
|
+ {
|
|
+ if(status == Success)
|
|
+ XFree(data);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ wm_check = ((Window*)data)[0];
|
|
+ XFree(data);
|
|
+
|
|
+ status = XGetWindowProperty(m_dpy, wm_check, prop,
|
|
+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format,
|
|
+ &items_read, &items_left, &data);
|
|
+
|
|
+ if(status != Success || !items_read)
|
|
+ {
|
|
+ if(status == Success)
|
|
+ XFree(data);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if(wm_check != ((Window*)data)[0])
|
|
+ {
|
|
+ XFree(data);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ XFree(data);
|
|
+
|
|
+ prop = XInternAtom(m_dpy, "_NET_WM_NAME", True);
|
|
+ if (prop == None)
|
|
+ {
|
|
+ CLog::Log(LOGDEBUG,"Window Manager Name: ");
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ status = XGetWindowProperty(m_dpy, wm_check, prop,
|
|
+ 0L, (~0L), False, AnyPropertyType, &real_type, &real_format,
|
|
+ &items_read, &items_left, &data);
|
|
+
|
|
+ if(status == Success && items_read)
|
|
+ {
|
|
+ CLog::Log(LOGDEBUG,"Window Manager Name: %s", data);
|
|
+ }
|
|
+ else
|
|
+ CLog::Log(LOGDEBUG,"Window Manager Name: ");
|
|
+
|
|
+ if(status == Success)
|
|
+ XFree(data);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
#endif
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index b2bd5a0..3e62cd8 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -103,6 +103,7 @@ private:
|
|
bool IsSuitableVisual(XVisualInfo *vInfo);
|
|
static int XErrorHandler(Display* dpy, XErrorEvent* error);
|
|
bool CreateIconPixmap();
|
|
+ bool HasWindowManager();
|
|
|
|
CStopWatch m_screensaverReset;
|
|
};
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 0665385b9d92a49c75403273444d898589ec4185 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 12 Jul 2012 11:11:47 +0200
|
|
Subject: [PATCH 32/93] X11: dont set window on xrandr if no mode available
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index af82061..4f33c68 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -665,16 +665,17 @@ void CWinSystemX11::NotifyXRREvent()
|
|
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
m_windowDirty = true;
|
|
|
|
+ if (!g_xrandr.Query(true))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
+ return;
|
|
+ }
|
|
+
|
|
// if external event update resolutions
|
|
if (!m_bIsInternalXrr)
|
|
{
|
|
UpdateResolutions();
|
|
}
|
|
- else if (!g_xrandr.Query(true))
|
|
- {
|
|
- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
- return;
|
|
- }
|
|
m_bIsInternalXrr = false;
|
|
|
|
CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 2d78ed515c437b4dd082d585f2d06778bcb5cb03 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 26 Jul 2012 09:34:28 +0200
|
|
Subject: [PATCH 33/93] X11: fix crash after a resolution change on startup
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 4f33c68..bc4e963 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -223,7 +223,8 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
OnLostDevice();
|
|
m_bIsInternalXrr = true;
|
|
g_xrandr.SetMode(out, mode);
|
|
- return true;
|
|
+ if (m_glWindow)
|
|
+ return true;
|
|
}
|
|
#endif
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 8e45aca353568d3b1119aaae29d63ce10f76ca70 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sat, 15 Sep 2012 18:27:29 +0200
|
|
Subject: [PATCH 34/93] X11: lock graphics context in NotifyXRREvent
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index bc4e963..57a8d20 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -666,6 +666,8 @@ void CWinSystemX11::NotifyXRREvent()
|
|
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
m_windowDirty = true;
|
|
|
|
+ CSingleLock lock(g_graphicsContext);
|
|
+
|
|
if (!g_xrandr.Query(true))
|
|
{
|
|
CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 7cecb116072ee9dd7893f3eef06a11c2c4811294 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 20 Aug 2012 16:06:39 +0200
|
|
Subject: [PATCH 35/93] dvdplayer: observe pts counter overflow
|
|
|
|
---
|
|
.../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 197 ++++++++++++++++++++-
|
|
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 4 +
|
|
2 files changed, 200 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
index 1146c6f..16efae0 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
@@ -18,7 +18,6 @@
|
|
*
|
|
*/
|
|
|
|
-#include "system.h"
|
|
#ifndef __STDC_CONSTANT_MACROS
|
|
#define __STDC_CONSTANT_MACROS
|
|
#endif
|
|
@@ -26,6 +25,7 @@
|
|
#define __STDC_LIMIT_MACROS
|
|
#endif
|
|
#ifdef TARGET_POSIX
|
|
+#include "system.h"
|
|
#include "stdint.h"
|
|
#endif
|
|
#include "DVDDemuxFFmpeg.h"
|
|
@@ -489,6 +489,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
|
|
|
CreateStreams();
|
|
|
|
+ m_bPtsWrapChecked = false;
|
|
+ m_bPtsWrap = false;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -634,6 +637,12 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num)
|
|
if (pts == (int64_t)AV_NOPTS_VALUE)
|
|
return DVD_NOPTS_VALUE;
|
|
|
|
+ if (m_bPtsWrap)
|
|
+ {
|
|
+ if (pts < m_iStartTime && pts < m_iEndTime)
|
|
+ pts += m_iMaxTime;
|
|
+ }
|
|
+
|
|
// do calculations in floats as they can easily overflow otherwise
|
|
// we don't care for having a completly exact timestamp anyway
|
|
double timestamp = (double)pts * num / den;
|
|
@@ -773,6 +782,24 @@ DemuxPacket* CDVDDemuxFFmpeg::Read()
|
|
m_pkt.pkt.pts = AV_NOPTS_VALUE;
|
|
}
|
|
|
|
+ if (!m_bPtsWrapChecked && m_pFormatContext->iformat->flags & AVFMT_TS_DISCONT)
|
|
+ {
|
|
+ int defaultStream = av_find_default_stream_index(m_pFormatContext);
|
|
+ int64_t duration = m_pFormatContext->streams[defaultStream]->duration * 1.5;
|
|
+ m_iMaxTime = 1LL<<m_pFormatContext->streams[defaultStream]->pts_wrap_bits;
|
|
+ m_iStartTime = m_pFormatContext->streams[defaultStream]->start_time;
|
|
+ if (m_iStartTime != DVD_NOPTS_VALUE)
|
|
+ {
|
|
+ m_iEndTime = (m_iStartTime + duration) & ~m_iMaxTime;
|
|
+ if (m_iEndTime < m_iStartTime)
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"CDVDDemuxFFmpeg::Read - file contains pts overflow");
|
|
+ m_bPtsWrap = true;
|
|
+ }
|
|
+ }
|
|
+ m_bPtsWrapChecked = true;
|
|
+ }
|
|
+
|
|
// copy contents into our own packet
|
|
pPacket->iSize = m_pkt.pkt.size;
|
|
|
|
@@ -905,7 +932,16 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
|
|
ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0);
|
|
|
|
if(ret >= 0)
|
|
+ {
|
|
UpdateCurrentPTS();
|
|
+
|
|
+ // seek may fail silently on streams which allow discontinuity
|
|
+ // if current timestamp is way off asume a pts overflow and try bisect seek
|
|
+ if (m_bPtsWrap && fabs(time - m_iCurrentPts/1000) > 10000)
|
|
+ {
|
|
+ ret = SeekTimeDiscont(seek_pts, backwords) ? 1 : -1;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
if(m_iCurrentPts == DVD_NOPTS_VALUE)
|
|
@@ -924,6 +960,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
|
|
return (ret >= 0);
|
|
}
|
|
|
|
+bool CDVDDemuxFFmpeg::SeekTimeDiscont(int64_t pts, bool backwards)
|
|
+{
|
|
+ // this code is taken from ffmpeg function ff_gen_search
|
|
+ // it is modified to assume a pts overflow if timestamp < start_time
|
|
+ if (!m_pFormatContext->iformat->read_timestamp)
|
|
+ return false;
|
|
+
|
|
+ int defaultStream = av_find_default_stream_index(m_pFormatContext);
|
|
+
|
|
+ if (defaultStream < 0)
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // timestamp for default must be expressed in AV_TIME_BASE units
|
|
+ pts = av_rescale_rnd(pts, m_pFormatContext->streams[defaultStream]->time_base.den,
|
|
+ AV_TIME_BASE * (int64_t)m_pFormatContext->streams[defaultStream]->time_base.num,
|
|
+ AV_ROUND_NEAR_INF);
|
|
+
|
|
+ int64_t pos, pos_min, pos_max, pos_limit, ts, ts_min, ts_max;
|
|
+ int64_t start_pos, filesize;
|
|
+ int no_change;
|
|
+
|
|
+ pos_min = m_pFormatContext->data_offset;
|
|
+ ts_min = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
|
|
+ &pos_min, INT64_MAX);
|
|
+ if (ts_min == AV_NOPTS_VALUE)
|
|
+ return false;
|
|
+
|
|
+ if(ts_min >= pts)
|
|
+ {
|
|
+ pos = pos_min;
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ int step= 1024;
|
|
+ filesize = m_pInput->GetLength();
|
|
+ pos_max = filesize - 1;
|
|
+ do
|
|
+ {
|
|
+ pos_max -= step;
|
|
+ ts_max = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
|
|
+ &pos_max, pos_max + step);
|
|
+ step += step;
|
|
+ }while (ts_max == AV_NOPTS_VALUE && pos_max >= step);
|
|
+
|
|
+ if (ts_max == AV_NOPTS_VALUE)
|
|
+ return false;
|
|
+
|
|
+ if (ts_max < m_iStartTime && ts_max < m_iEndTime)
|
|
+ ts_max += m_iMaxTime;
|
|
+
|
|
+ for(;;)
|
|
+ {
|
|
+ int64_t tmp_pos = pos_max + 1;
|
|
+ int64_t tmp_ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
|
|
+ &tmp_pos, INT64_MAX);
|
|
+ if(tmp_ts == AV_NOPTS_VALUE)
|
|
+ break;
|
|
+
|
|
+ if (tmp_ts < m_iStartTime && tmp_ts < m_iEndTime)
|
|
+ tmp_ts += m_iMaxTime;
|
|
+
|
|
+ ts_max = tmp_ts;
|
|
+ pos_max = tmp_pos;
|
|
+ if (tmp_pos >= filesize)
|
|
+ break;
|
|
+ }
|
|
+ pos_limit = pos_max;
|
|
+
|
|
+ if(ts_max <= pts)
|
|
+ {
|
|
+ bool ret = SeekByte(pos_max);
|
|
+ if (ret)
|
|
+ {
|
|
+ m_iCurrentPts = ConvertTimestamp(ts_max, m_pFormatContext->streams[defaultStream]->time_base.den,
|
|
+ m_pFormatContext->streams[defaultStream]->time_base.num);
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ if(ts_min > ts_max)
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+ else if (ts_min == ts_max)
|
|
+ {
|
|
+ pos_limit = pos_min;
|
|
+ }
|
|
+
|
|
+ no_change=0;
|
|
+ while (pos_min < pos_limit)
|
|
+ {
|
|
+ if (no_change == 0)
|
|
+ {
|
|
+ int64_t approximate_keyframe_distance= pos_max - pos_limit;
|
|
+ // interpolate position (better than dichotomy)
|
|
+ pos = av_rescale_rnd(pts - ts_min, pos_max - pos_min,
|
|
+ ts_max - ts_min, AV_ROUND_NEAR_INF)
|
|
+ + pos_min - approximate_keyframe_distance;
|
|
+ }
|
|
+ else if (no_change == 1)
|
|
+ {
|
|
+ // bisection, if interpolation failed to change min or max pos last time
|
|
+ pos = (pos_min + pos_limit) >> 1;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* linear search if bisection failed, can only happen if there
|
|
+ are very few or no keyframes between min/max */
|
|
+ pos = pos_min;
|
|
+ }
|
|
+ if (pos <= pos_min)
|
|
+ pos= pos_min + 1;
|
|
+ else if (pos > pos_limit)
|
|
+ pos= pos_limit;
|
|
+ start_pos = pos;
|
|
+
|
|
+ ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
|
|
+ &pos, INT64_MAX);
|
|
+ if (pos == pos_max)
|
|
+ no_change++;
|
|
+ else
|
|
+ no_change=0;
|
|
+
|
|
+ if (ts == AV_NOPTS_VALUE)
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (ts < m_iStartTime && ts < m_iEndTime)
|
|
+ ts += m_iMaxTime;
|
|
+
|
|
+ if (pts <= ts)
|
|
+ {
|
|
+ pos_limit = start_pos - 1;
|
|
+ pos_max = pos;
|
|
+ ts_max = ts;
|
|
+ }
|
|
+ if (pts >= ts)
|
|
+ {
|
|
+ pos_min = pos;
|
|
+ ts_min = ts;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pos = (backwards) ? pos_min : pos_max;
|
|
+ ts = (backwards) ? ts_min : ts_max;
|
|
+
|
|
+ bool ret = SeekByte(pos);
|
|
+ if (ret)
|
|
+ {
|
|
+ m_iCurrentPts = ConvertTimestamp(ts, m_pFormatContext->streams[defaultStream]->time_base.den,
|
|
+ m_pFormatContext->streams[defaultStream]->time_base.num);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
bool CDVDDemuxFFmpeg::SeekByte(int64_t pos)
|
|
{
|
|
CSingleLock lock(m_critSection);
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
index aef5ab1..35abbdf 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
@@ -100,6 +100,7 @@ public:
|
|
DemuxPacket* Read();
|
|
|
|
bool SeekTime(int time, bool backwords = false, double* startpts = NULL);
|
|
+ bool SeekTimeDiscont(int64_t pts, bool backwards);
|
|
bool SeekByte(int64_t pos);
|
|
int GetStreamLength();
|
|
CDemuxStream* GetStream(int iStreamId);
|
|
@@ -158,5 +159,8 @@ protected:
|
|
AVPacket pkt; // packet ffmpeg returned
|
|
int result; // result from av_read_packet
|
|
}m_pkt;
|
|
+
|
|
+ bool m_bPtsWrap, m_bPtsWrapChecked;
|
|
+ int64_t m_iStartTime, m_iMaxTime, m_iEndTime;
|
|
};
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From a2b098917cab5f9db00c69177792c373547f2bb8 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Tue, 2 Oct 2012 13:02:10 +0200
|
|
Subject: [PATCH 36/93] dvdplayer: avoid short screen flicker caused by
|
|
unnecessary reconfigure of renderer
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 5 ++++-
|
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 9c36bdb..322a581 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -1054,13 +1054,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
|
|
|
|
#ifdef HAS_VIDEO_PLAYBACK
|
|
double config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate;
|
|
+ double render_framerate = g_graphicsContext.GetFPS();
|
|
+ if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") == ADJUST_REFRESHRATE_OFF)
|
|
+ render_framerate = config_framerate;
|
|
/* check so that our format or aspect has changed. if it has, reconfigure renderer */
|
|
if (!g_renderManager.IsConfigured()
|
|
|| ( m_output.width != pPicture->iWidth )
|
|
|| ( m_output.height != pPicture->iHeight )
|
|
|| ( m_output.dwidth != pPicture->iDisplayWidth )
|
|
|| ( m_output.dheight != pPicture->iDisplayHeight )
|
|
- || ( m_output.framerate != config_framerate )
|
|
+ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 && render_framerate != config_framerate)
|
|
|| ( m_output.color_format != (unsigned int)pPicture->format )
|
|
|| ( m_output.extended_format != pPicture->extended_format )
|
|
|| ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From a67d385916ef70447e5167ca352f9f53de7e2778 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 11 Oct 2012 12:05:50 +0200
|
|
Subject: [PATCH 37/93] vdpau: advanced settings for auto deinterlacing
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++----
|
|
xbmc/settings/AdvancedSettings.cpp | 4 ++++
|
|
xbmc/settings/AdvancedSettings.h | 2 ++
|
|
3 files changed, 10 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
index b4d2d38..cd72cc6 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
@@ -1987,10 +1987,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */)
|
|
if (method == VS_INTERLACEMETHOD_AUTO)
|
|
{
|
|
int deint = -1;
|
|
-// if (m_config.outHeight >= 720)
|
|
-// deint = g_advancedSettings.m_videoVDPAUdeintHD;
|
|
-// else
|
|
-// deint = g_advancedSettings.m_videoVDPAUdeintSD;
|
|
+ if (m_config.outHeight >= 720)
|
|
+ deint = g_advancedSettings.m_videoVDPAUdeintHD;
|
|
+ else
|
|
+ deint = g_advancedSettings.m_videoVDPAUdeintSD;
|
|
|
|
if (deint != -1)
|
|
{
|
|
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
|
|
index eff43dd..7532914 100644
|
|
--- a/xbmc/settings/AdvancedSettings.cpp
|
|
+++ b/xbmc/settings/AdvancedSettings.cpp
|
|
@@ -163,6 +163,8 @@ void CAdvancedSettings::Initialize()
|
|
m_videoAutoScaleMaxFps = 30.0f;
|
|
m_videoDisableBackgroundDeinterlace = false;
|
|
m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect
|
|
+ m_videoVDPAUdeintHD = -1;
|
|
+ m_videoVDPAUdeintSD = -1;
|
|
m_videoVDPAUtelecine = false;
|
|
m_videoVDPAUdeintSkipChromaHD = false;
|
|
m_DXVACheckCompatibility = false;
|
|
@@ -600,6 +602,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
|
|
XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading);
|
|
XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
|
|
XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
|
|
+ XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD);
|
|
+ XMLUtils::GetInt(pElement,"vdpauSDdeint",m_videoVDPAUdeintSD);
|
|
XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine);
|
|
XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD);
|
|
|
|
diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h
|
|
index 3995f35..c43351d 100644
|
|
--- a/xbmc/settings/AdvancedSettings.h
|
|
+++ b/xbmc/settings/AdvancedSettings.h
|
|
@@ -160,6 +160,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
|
|
int m_videoPercentSeekBackwardBig;
|
|
CStdString m_videoPPFFmpegDeint;
|
|
CStdString m_videoPPFFmpegPostProc;
|
|
+ int m_videoVDPAUdeintHD;
|
|
+ int m_videoVDPAUdeintSD;
|
|
bool m_videoVDPAUtelecine;
|
|
bool m_videoVDPAUdeintSkipChromaHD;
|
|
bool m_musicUseTimeSeeking;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 56a0e9d6cb08dcecbfdea964b99996c59ebd0c91 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Fri, 2 Nov 2012 13:20:03 +0100
|
|
Subject: [PATCH 38/93] player: fix rewind
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++-
|
|
xbmc/cores/dvdplayer/DVDPlayer.cpp | 30 +++++++++++++++++++-----------
|
|
xbmc/cores/dvdplayer/DVDPlayer.h | 7 ++++---
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 +++-
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.h | 1 +
|
|
5 files changed, 31 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDMessage.h b/xbmc/cores/dvdplayer/DVDMessage.h
|
|
index 2ea8b8f..e8274f9 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDMessage.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDMessage.h
|
|
@@ -220,7 +220,7 @@ private:
|
|
class CDVDMsgPlayerSeek : public CDVDMsg
|
|
{
|
|
public:
|
|
- CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false)
|
|
+ CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false, bool sync = true)
|
|
: CDVDMsg(PLAYER_SEEK)
|
|
, m_time(time)
|
|
, m_backward(backward)
|
|
@@ -228,6 +228,7 @@ public:
|
|
, m_accurate(accurate)
|
|
, m_restore(restore)
|
|
, m_trickplay(trickplay)
|
|
+ , m_sync(sync)
|
|
{}
|
|
int GetTime() { return m_time; }
|
|
bool GetBackward() { return m_backward; }
|
|
@@ -235,6 +236,7 @@ public:
|
|
bool GetAccurate() { return m_accurate; }
|
|
bool GetRestore() { return m_restore; }
|
|
bool GetTrickPlay() { return m_trickplay; }
|
|
+ bool GetSync() { return m_sync; }
|
|
private:
|
|
int m_time;
|
|
bool m_backward;
|
|
@@ -242,6 +244,7 @@ private:
|
|
bool m_accurate;
|
|
bool m_restore; // whether to restore any EDL cut time
|
|
bool m_trickplay;
|
|
+ bool m_sync;
|
|
};
|
|
|
|
class CDVDMsgPlayerSeekChapter : public CDVDMsg
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
index 0d2b4ae..a4c0422 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
|
|
@@ -1634,11 +1634,13 @@ void CDVDPlayer::HandlePlaySpeed()
|
|
}
|
|
else if (m_CurrentVideo.id >= 0
|
|
&& (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file
|
|
- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts()
|
|
+ && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200))
|
|
+ && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE)
|
|
&& m_SpeedState.lasttime != GetTime())
|
|
{
|
|
m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts();
|
|
m_SpeedState.lasttime = GetTime();
|
|
+ m_SpeedState.lastabstime = CDVDClock::GetAbsoluteClock();
|
|
// check how much off clock video is when ff/rw:ing
|
|
// a problem here is that seeking isn't very accurate
|
|
// and since the clock will be resynced after seek
|
|
@@ -1657,7 +1659,7 @@ void CDVDPlayer::HandlePlaySpeed()
|
|
{
|
|
CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up");
|
|
int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL);
|
|
- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true));
|
|
+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true, false));
|
|
}
|
|
}
|
|
}
|
|
@@ -2143,7 +2145,7 @@ void CDVDPlayer::HandleMessages()
|
|
else
|
|
m_StateInput.dts = start;
|
|
|
|
- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
|
|
+ FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync());
|
|
}
|
|
else
|
|
CLog::Log(LOGWARNING, "error while seeking");
|
|
@@ -2279,9 +2281,10 @@ void CDVDPlayer::HandleMessages()
|
|
double offset;
|
|
offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp;
|
|
offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
|
|
+ offset = DVD_TIME_TO_MSEC(offset);
|
|
if(offset > 1000) offset = 1000;
|
|
if(offset < -1000) offset = -1000;
|
|
- m_State.time += DVD_TIME_TO_MSEC(offset);
|
|
+ m_State.time += offset;
|
|
m_State.timestamp = CDVDClock::GetAbsoluteClock();
|
|
}
|
|
|
|
@@ -2297,7 +2300,8 @@ void CDVDPlayer::HandleMessages()
|
|
// do a seek after rewind, clock is not in sync with current pts
|
|
if (m_playSpeed < 0 && speed >= 0)
|
|
{
|
|
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true));
|
|
+ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset);
|
|
+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true));
|
|
}
|
|
|
|
// if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE
|
|
@@ -3293,7 +3297,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers)
|
|
return true;
|
|
}
|
|
|
|
-void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
|
|
+void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync)
|
|
{
|
|
double startpts;
|
|
if(accurate)
|
|
@@ -3305,19 +3309,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
|
|
if(startpts != DVD_NOPTS_VALUE)
|
|
startpts -= m_offset_pts;
|
|
|
|
- m_CurrentAudio.inited = false;
|
|
+ if (sync)
|
|
+ {
|
|
+ m_CurrentAudio.inited = false;
|
|
+ m_CurrentVideo.inited = false;
|
|
+ m_CurrentSubtitle.inited = false;
|
|
+ m_CurrentTeletext.inited = false;
|
|
+ }
|
|
+
|
|
m_CurrentAudio.dts = DVD_NOPTS_VALUE;
|
|
m_CurrentAudio.startpts = startpts;
|
|
|
|
- m_CurrentVideo.inited = false;
|
|
m_CurrentVideo.dts = DVD_NOPTS_VALUE;
|
|
m_CurrentVideo.startpts = startpts;
|
|
|
|
- m_CurrentSubtitle.inited = false;
|
|
m_CurrentSubtitle.dts = DVD_NOPTS_VALUE;
|
|
m_CurrentSubtitle.startpts = startpts;
|
|
|
|
- m_CurrentTeletext.inited = false;
|
|
m_CurrentTeletext.dts = DVD_NOPTS_VALUE;
|
|
m_CurrentTeletext.startpts = startpts;
|
|
|
|
@@ -3361,7 +3369,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
|
|
m_CurrentTeletext.started = false;
|
|
}
|
|
|
|
- if(pts != DVD_NOPTS_VALUE)
|
|
+ if(pts != DVD_NOPTS_VALUE && sync)
|
|
m_clock.Discontinuity(pts);
|
|
UpdatePlayState(0);
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h
|
|
index e2a836b..6ecaf3f 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayer.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
|
|
@@ -308,7 +308,7 @@ protected:
|
|
bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
|
|
|
|
|
|
- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
|
|
+ void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true);
|
|
|
|
void HandleMessages();
|
|
void HandlePlaySpeed();
|
|
@@ -357,8 +357,9 @@ protected:
|
|
int m_playSpeed;
|
|
struct SSpeedState
|
|
{
|
|
- double lastpts; // holds last display pts during ff/rw operations
|
|
- double lasttime;
|
|
+ double lastpts; // holds last display pts during ff/rw operations
|
|
+ int64_t lasttime;
|
|
+ double lastabstime;
|
|
} m_SpeedState;
|
|
|
|
int m_errorCount;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 322a581..9c5469b 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -1470,7 +1470,7 @@ double CDVDPlayerVideo::GetCurrentPts()
|
|
|
|
if( m_stalled )
|
|
iRenderPts = DVD_NOPTS_VALUE;
|
|
- else
|
|
+ else if ( m_speed == DVD_PLAYSPEED_NORMAL)
|
|
iRenderPts = iRenderPts - max(0.0, iSleepTime);
|
|
|
|
return iRenderPts;
|
|
@@ -1570,6 +1570,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts)
|
|
int iSkippedDeint = 0;
|
|
int iBufferLevel;
|
|
|
|
+ m_droppingStats.m_lastPts = pts;
|
|
+
|
|
// get decoder stats
|
|
if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced))
|
|
iDecoderPts = pts;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
index 59c7f09..65dea76 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
|
|
@@ -50,6 +50,7 @@ public:
|
|
double m_totalGain;
|
|
double m_lastDecoderPts;
|
|
double m_lastRenderPts;
|
|
+ double m_lastPts;
|
|
unsigned int m_lateFrames;
|
|
unsigned int m_dropRequests;
|
|
};
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From b209430c56ad955fb164c88cf4696a5ab1f162db Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Fri, 23 Nov 2012 17:41:12 +0100
|
|
Subject: [PATCH 39/93] xrandr: fix query for multiple screens
|
|
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 10 ++++++----
|
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 4685413..e610150 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -58,12 +58,14 @@ bool CXRandR::Query(bool force)
|
|
|
|
m_outputs.clear();
|
|
// query all screens
|
|
+ // we are happy if at least one screen returns results
|
|
+ bool success = false;
|
|
for(unsigned int screennum=0; screennum<m_numScreens; ++screennum)
|
|
{
|
|
- if(!Query(force, screennum))
|
|
- return false;
|
|
+ if(Query(force, screennum))
|
|
+ success = true;
|
|
}
|
|
- return true;
|
|
+ return success;
|
|
}
|
|
|
|
bool CXRandR::Query(bool force, int screennum)
|
|
@@ -71,7 +73,7 @@ bool CXRandR::Query(bool force, int screennum)
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
cmd += "/xbmc-xrandr";
|
|
- cmd.append("-q --screen %d", screennum);
|
|
+ cmd.AppendFormat(" -q --screen %d", screennum);
|
|
|
|
FILE* file = popen(cmd.c_str(),"r");
|
|
if (!file)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 8d42739f0833403d688d7da9676d098ad3be45c6 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 2 Dec 2012 15:46:55 +0100
|
|
Subject: [PATCH 40/93] X11: add debug log to print out refresh after xrr event
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++++
|
|
1 file changed, 6 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 57a8d20..a237dc0 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -685,6 +685,12 @@ void CWinSystemX11::NotifyXRREvent()
|
|
XOutput *out = g_xrandr.GetOutput(currentOutput);
|
|
XMode mode = g_xrandr.GetCurrentMode(currentOutput);
|
|
|
|
+ if (out)
|
|
+ CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__
|
|
+ , out->name.c_str(), mode.id.c_str(), mode.hz);
|
|
+ else
|
|
+ CLog::Log(LOGWARNING, "%s - output name not set", __FUNCTION__);
|
|
+
|
|
RESOLUTION_INFO res;
|
|
unsigned int i;
|
|
bool found(false);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From ef3118362dcf019e927700e59f0cc4e7a0d506b1 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Tue, 11 Dec 2012 11:08:13 +0100
|
|
Subject: [PATCH 41/93] X11: dont call XCloseDisplay on shutdown, it crashes
|
|
when powered doen by cec on ATI
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index a237dc0..ab660b1 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -112,7 +112,8 @@ bool CWinSystemX11::DestroyWindowSystem()
|
|
//we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy
|
|
//so instead we just let m_dpy die on exit
|
|
// i have seen core dumps on ATI if the display is not closed here
|
|
- XCloseDisplay(m_dpy);
|
|
+ // crashes when shutting down via cec
|
|
+// XCloseDisplay(m_dpy);
|
|
}
|
|
|
|
// m_SDLSurface is free()'d by SDL_Quit().
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From da4c24ede3be3b5c074c44123e83e9059c25688d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Gr=C3=A9gory=20Coutant?= <gregory.coutant@gmail.com>
|
|
Date: Wed, 12 Dec 2012 19:49:47 +0100
|
|
Subject: [PATCH 42/93] x11: support for multiple x screens
|
|
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index e610150..5c53574 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -93,7 +93,7 @@ bool CXRandR::Query(bool force, int screennum)
|
|
pclose(file);
|
|
|
|
TiXmlElement *pRootElement = xmlDoc.RootElement();
|
|
- if (strcasecmp(pRootElement->Value(), "screen") != screennum)
|
|
+ if (atoi(pRootElement->Attribute("id")) != screennum)
|
|
{
|
|
// TODO ERROR
|
|
return false;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From c7215a8c352ad44a928a9d18f89ebf52c8dcf9fc Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 24 Dec 2012 16:02:42 +0100
|
|
Subject: [PATCH 43/93] pvr: increase changes counter of stream on stream
|
|
change, cosmetics after dd307930d39d92f145a01a16600cd00e01ec39be
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 5 ++---
|
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
|
|
index e5f8234..96c9e89 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp
|
|
@@ -339,9 +339,7 @@ void CDVDDemuxPVRClient::RequestStreams()
|
|
if (stm)
|
|
{
|
|
st = dynamic_cast<CDemuxStreamAudioPVRClient*>(stm);
|
|
- if (!st
|
|
- || (st->codec != (AVCodecID)props.stream[i].iCodecId)
|
|
- || (st->iChannels != props.stream[i].iChannels))
|
|
+ if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId))
|
|
DisposeStream(i);
|
|
}
|
|
if (!m_streams[i])
|
|
@@ -358,6 +356,7 @@ void CDVDDemuxPVRClient::RequestStreams()
|
|
st->iBitsPerSample = props.stream[i].iBitsPerSample;
|
|
m_streams[i] = st;
|
|
st->m_parser_split = true;
|
|
+ st->changes++;
|
|
}
|
|
else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_VIDEO)
|
|
{
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 26da0298234aeea96c4df4d3317589abb822cf1b Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 17 Jan 2013 16:03:22 +0100
|
|
Subject: [PATCH 44/93] X11: add keymapping for XF86XK_Sleep
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index a62521f..263cb5a 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -143,6 +143,7 @@ static uint32_t SymMappingsX11[][2] =
|
|
, {XK_Break, XBMCK_BREAK}
|
|
, {XK_Menu, XBMCK_MENU}
|
|
, {XF86XK_PowerOff, XBMCK_POWER}
|
|
+, {XF86XK_Sleep, XBMCK_SLEEP}
|
|
, {XK_EcuSign, XBMCK_EURO}
|
|
, {XK_Undo, XBMCK_UNDO}
|
|
/* Media keys */
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From b0d730552ceac8e144436e96e9a88fe28e565ef6 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Mon, 21 Jan 2013 09:00:19 +0100
|
|
Subject: [PATCH 45/93] X11: remove toggle full screen after resume
|
|
|
|
---
|
|
xbmc/powermanagement/PowerManager.cpp | 5 -----
|
|
1 file changed, 5 deletions(-)
|
|
|
|
diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp
|
|
index 590a887..35b5a21 100644
|
|
--- a/xbmc/powermanagement/PowerManager.cpp
|
|
+++ b/xbmc/powermanagement/PowerManager.cpp
|
|
@@ -268,11 +268,6 @@ void CPowerManager::OnWake()
|
|
#if defined(TARGET_WINDOWS)
|
|
ShowWindow(g_hWnd,SW_RESTORE);
|
|
SetForegroundWindow(g_hWnd);
|
|
-#elif !defined(TARGET_DARWIN_OSX)
|
|
- // Hack to reclaim focus, thus rehiding system mouse pointer.
|
|
- // Surely there's a better way?
|
|
- g_graphicsContext.ToggleFullScreenRoot();
|
|
- g_graphicsContext.ToggleFullScreenRoot();
|
|
#endif
|
|
}
|
|
g_application.ResetScreenSaver();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 876139f6eb64b5e72689d5fe6a9bf65f60070b2e Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Wed, 23 Jan 2013 17:03:02 +0100
|
|
Subject: [PATCH 46/93] xrandr: set screen on mode change command
|
|
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 5c53574..4355ef7 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -246,7 +246,7 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
|
|
m_currentMode = modeFound.id;
|
|
char cmd[255];
|
|
if (getenv("XBMC_BIN_HOME"))
|
|
- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str());
|
|
+ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str());
|
|
else
|
|
return false;
|
|
CLog::Log(LOGINFO, "XRANDR: %s", cmd);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 4262d964615f251d99d6d773d5fa9a96f5230053 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Wed, 23 Jan 2013 17:03:39 +0100
|
|
Subject: [PATCH 47/93] X11: recreate glx context when output changes
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 6 +++---
|
|
xbmc/windowing/X11/WinSystemX11.h | 2 +-
|
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index ab660b1..4329a22 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -409,11 +409,11 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
return true;
|
|
}
|
|
|
|
-bool CWinSystemX11::RefreshGlxContext()
|
|
+bool CWinSystemX11::RefreshGlxContext(bool force)
|
|
{
|
|
bool retVal = false;
|
|
|
|
- if (m_glContext)
|
|
+ if (m_glContext && !force)
|
|
{
|
|
CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context");
|
|
glXMakeCurrent(m_dpy, None, NULL);
|
|
@@ -930,7 +930,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
}
|
|
|
|
CDirtyRegionList dr;
|
|
- RefreshGlxContext();
|
|
+ RefreshGlxContext(!m_currentOutput.Equals(output));
|
|
XSync(m_dpy, FALSE);
|
|
g_graphicsContext.Clear(0);
|
|
g_graphicsContext.Flip(dr);
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 3e62cd8..2a1fb41 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -76,7 +76,7 @@ public:
|
|
void NotifyMouseCoverage(bool covered);
|
|
|
|
protected:
|
|
- bool RefreshGlxContext();
|
|
+ bool RefreshGlxContext(bool force);
|
|
void CheckDisplayEvents();
|
|
void OnLostDevice();
|
|
bool SetWindow(int width, int height, bool fullscreen, const CStdString &output);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 76bab5ec893f9534f50f38474b22a56300307631 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Fri, 14 Dec 2012 14:19:15 +0100
|
|
Subject: [PATCH 48/93] pvr: do not show selection dialog for a single menu
|
|
hook
|
|
|
|
---
|
|
xbmc/pvr/addons/PVRClients.cpp | 9 ++++++---
|
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
|
|
index 14c9cde..57b18a5 100644
|
|
--- a/xbmc/pvr/addons/PVRClients.cpp
|
|
+++ b/xbmc/pvr/addons/PVRClients.cpp
|
|
@@ -733,6 +733,7 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF
|
|
{
|
|
hooks = client->GetMenuHooks();
|
|
std::vector<int> hookIDs;
|
|
+ int selection = 0;
|
|
|
|
CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
|
|
pDialog->Reset();
|
|
@@ -743,9 +744,11 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF
|
|
pDialog->Add(client->GetString(hooks->at(i).iLocalizedStringId));
|
|
hookIDs.push_back(i);
|
|
}
|
|
- pDialog->DoModal();
|
|
-
|
|
- int selection = pDialog->GetSelectedLabel();
|
|
+ if (hookIDs.size() > 1)
|
|
+ {
|
|
+ pDialog->DoModal();
|
|
+ selection = pDialog->GetSelectedLabel();
|
|
+ }
|
|
if (selection >= 0)
|
|
client->CallMenuHook(hooks->at(hookIDs.at(selection)), item);
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 2069a5213f76e57a558189b52f098af75d9c21cf Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 3 Feb 2013 08:17:16 +0100
|
|
Subject: [PATCH 49/93] X11: use default screen parameters if no output
|
|
connected
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 55 ++++++++++++++++++++++---------------
|
|
1 file changed, 33 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 4329a22..2adf8a0 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -207,25 +207,27 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
}
|
|
|
|
XMode currmode = g_xrandr.GetCurrentMode(out.name);
|
|
-
|
|
- // flip h/w when rotated
|
|
- if (m_bIsRotated)
|
|
+ if (!currmode.name.empty())
|
|
{
|
|
- int w = mode.w;
|
|
- mode.w = mode.h;
|
|
- mode.h = w;
|
|
- }
|
|
+ // flip h/w when rotated
|
|
+ if (m_bIsRotated)
|
|
+ {
|
|
+ int w = mode.w;
|
|
+ mode.w = mode.h;
|
|
+ mode.h = w;
|
|
+ }
|
|
|
|
- // only call xrandr if mode changes
|
|
- if (currmode.w != mode.w || currmode.h != mode.h ||
|
|
- currmode.hz != mode.hz || currmode.id != mode.id)
|
|
- {
|
|
- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
|
|
- OnLostDevice();
|
|
- m_bIsInternalXrr = true;
|
|
- g_xrandr.SetMode(out, mode);
|
|
- if (m_glWindow)
|
|
- return true;
|
|
+ // only call xrandr if mode changes
|
|
+ if (currmode.w != mode.w || currmode.h != mode.h ||
|
|
+ currmode.hz != mode.hz || currmode.id != mode.id)
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
|
|
+ OnLostDevice();
|
|
+ m_bIsInternalXrr = true;
|
|
+ g_xrandr.SetMode(out, mode);
|
|
+ if (m_glWindow)
|
|
+ return true;
|
|
+ }
|
|
}
|
|
#endif
|
|
|
|
@@ -272,9 +274,10 @@ void CWinSystemX11::UpdateResolutions()
|
|
else
|
|
#endif
|
|
{
|
|
- int x11screen = m_nScreen;
|
|
- int w = DisplayWidth(m_dpy, x11screen);
|
|
- int h = DisplayHeight(m_dpy, x11screen);
|
|
+ CSettings::Get().SetString("videoscreen.monitor", "Default");
|
|
+ m_nScreen = DefaultScreen(m_dpy);
|
|
+ int w = DisplayWidth(m_dpy, m_nScreen);
|
|
+ int h = DisplayHeight(m_dpy, m_nScreen);
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0);
|
|
}
|
|
|
|
@@ -819,11 +822,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
Colormap cmap;
|
|
XSetWindowAttributes swa;
|
|
XVisualInfo *vi;
|
|
+ int x0 = 0;
|
|
+ int y0 = 0;
|
|
|
|
XOutput *out = g_xrandr.GetOutput(output);
|
|
if (!out)
|
|
out = g_xrandr.GetOutput(m_currentOutput);
|
|
- m_nScreen = out->screen;
|
|
+ if (out)
|
|
+ {
|
|
+ m_nScreen = out->screen;
|
|
+ x0 = out->x;
|
|
+ y0 = out->y;
|
|
+ }
|
|
+
|
|
vi = glXChooseVisual(m_dpy, m_nScreen, att);
|
|
cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);
|
|
|
|
@@ -842,7 +853,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask;
|
|
|
|
m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
|
|
- out->x, out->y, width, height, 0, vi->depth,
|
|
+ x0, y0, width, height, 0, vi->depth,
|
|
InputOutput, vi->visual,
|
|
mask, &swa);
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From aebb14e8a7d079871c69f31df00a0b894e9d5ef9 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sat, 23 Mar 2013 15:13:32 +0100
|
|
Subject: [PATCH 50/93] X11: create parent window
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 69 +++++++++++++++++++++++--------------
|
|
xbmc/windowing/X11/WinSystemX11.h | 2 +-
|
|
2 files changed, 44 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 2adf8a0..07f3f3d 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -55,6 +55,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase()
|
|
m_glContext = NULL;
|
|
m_dpy = NULL;
|
|
m_glWindow = 0;
|
|
+ m_mainWindow = 0;
|
|
m_bWasFullScreenBeforeMinimize = false;
|
|
m_minimized = false;
|
|
m_bIgnoreNextFocusMessage = false;
|
|
@@ -132,7 +133,7 @@ bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RES
|
|
|
|
bool CWinSystemX11::DestroyWindow()
|
|
{
|
|
- if (!m_glWindow)
|
|
+ if (!m_mainWindow)
|
|
return true;
|
|
|
|
if (m_glContext)
|
|
@@ -143,19 +144,21 @@ bool CWinSystemX11::DestroyWindow()
|
|
|
|
if (m_invisibleCursor)
|
|
{
|
|
- XUndefineCursor(m_dpy, m_glWindow);
|
|
+ XUndefineCursor(m_dpy, m_mainWindow);
|
|
XFreeCursor(m_dpy, m_invisibleCursor);
|
|
m_invisibleCursor = 0;
|
|
}
|
|
|
|
CWinEventsX11Imp::Quit();
|
|
|
|
- XUnmapWindow(m_dpy, m_glWindow);
|
|
+ XUnmapWindow(m_dpy, m_mainWindow);
|
|
XSync(m_dpy,TRUE);
|
|
XUngrabKeyboard(m_dpy, CurrentTime);
|
|
XUngrabPointer(m_dpy, CurrentTime);
|
|
XDestroyWindow(m_dpy, m_glWindow);
|
|
+ XDestroyWindow(m_dpy, m_mainWindow);
|
|
m_glWindow = 0;
|
|
+ m_mainWindow = 0;
|
|
|
|
if (m_icon)
|
|
XFreePixmap(m_dpy, m_icon);
|
|
@@ -225,7 +228,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
OnLostDevice();
|
|
m_bIsInternalXrr = true;
|
|
g_xrandr.SetMode(out, mode);
|
|
- if (m_glWindow)
|
|
+ if (m_mainWindow)
|
|
return true;
|
|
}
|
|
}
|
|
@@ -503,9 +506,9 @@ bool CWinSystemX11::RefreshGlxContext(bool force)
|
|
void CWinSystemX11::ShowOSMouse(bool show)
|
|
{
|
|
if (show)
|
|
- XUndefineCursor(m_dpy,m_glWindow);
|
|
+ XUndefineCursor(m_dpy,m_mainWindow);
|
|
else if (m_invisibleCursor)
|
|
- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor);
|
|
+ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor);
|
|
}
|
|
|
|
void CWinSystemX11::ResetOSScreensaver()
|
|
@@ -588,10 +591,10 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered)
|
|
int result = -1;
|
|
while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
{
|
|
- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
+ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
XbmcThreads::ThreadSleep(100);
|
|
}
|
|
- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
}
|
|
else
|
|
{
|
|
@@ -609,7 +612,7 @@ bool CWinSystemX11::Minimize()
|
|
g_graphicsContext.ToggleFullScreenRoot();
|
|
}
|
|
|
|
- XIconifyWindow(m_dpy, m_glWindow, m_nScreen);
|
|
+ XIconifyWindow(m_dpy, m_mainWindow, m_nScreen);
|
|
|
|
m_minimized = true;
|
|
return true;
|
|
@@ -620,13 +623,13 @@ bool CWinSystemX11::Restore()
|
|
}
|
|
bool CWinSystemX11::Hide()
|
|
{
|
|
- XUnmapWindow(m_dpy, m_glWindow);
|
|
+ XUnmapWindow(m_dpy, m_mainWindow);
|
|
XSync(m_dpy, False);
|
|
return true;
|
|
}
|
|
bool CWinSystemX11::Show(bool raise)
|
|
{
|
|
- XMapWindow(m_dpy, m_glWindow);
|
|
+ XMapWindow(m_dpy, m_mainWindow);
|
|
XSync(m_dpy, False);
|
|
m_minimized = false;
|
|
return true;
|
|
@@ -776,7 +779,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
bool mouseActive = false;
|
|
float mouseX, mouseY;
|
|
|
|
- if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty))
|
|
+ if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty))
|
|
{
|
|
mouseActive = g_Mouse.IsActive();
|
|
if (mouseActive)
|
|
@@ -785,7 +788,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
int root_x_return, root_y_return;
|
|
int win_x_return, win_y_return;
|
|
unsigned int mask_return;
|
|
- bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return,
|
|
+ bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return,
|
|
&root_x_return, &root_y_return,
|
|
&win_x_return, &win_y_return,
|
|
&mask_return);
|
|
@@ -804,7 +807,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
}
|
|
|
|
// create main window
|
|
- if (!m_glWindow)
|
|
+ if (!m_mainWindow)
|
|
{
|
|
EnableSystemScreenSaver(false);
|
|
|
|
@@ -845,22 +848,31 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
swa.border_pixel = fullscreen ? 0 : 5;
|
|
swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
swa.colormap = cmap;
|
|
- swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
|
|
swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask |
|
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
|
PropertyChangeMask | StructureNotifyMask | KeymapStateMask |
|
|
EnterWindowMask | LeaveWindowMask | ExposureMask;
|
|
unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask;
|
|
|
|
- m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
|
|
+ m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
|
|
x0, y0, width, height, 0, vi->depth,
|
|
InputOutput, vi->visual,
|
|
mask, &swa);
|
|
|
|
+ swa.override_redirect = False;
|
|
+ swa.border_pixel = 0;
|
|
+ swa.event_mask = 0;
|
|
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap;
|
|
+
|
|
+ m_glWindow = XCreateWindow(m_dpy, m_mainWindow,
|
|
+ 0, 0, width, height, 0, vi->depth,
|
|
+ InputOutput, vi->visual,
|
|
+ mask, &swa);
|
|
+
|
|
if (fullscreen && hasWM)
|
|
{
|
|
Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True);
|
|
- XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
|
|
+ XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
|
|
}
|
|
|
|
// define invisible cursor
|
|
@@ -869,14 +881,14 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
static char noData[] = { 0,0,0,0,0,0,0,0 };
|
|
black.red = black.green = black.blue = 0;
|
|
|
|
- bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8);
|
|
+ bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8);
|
|
m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData,
|
|
&black, &black, 0, 0);
|
|
XFreePixmap(m_dpy, bitmapNoData);
|
|
- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor);
|
|
+ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor);
|
|
|
|
//init X11 events
|
|
- CWinEventsX11Imp::Init(m_dpy, m_glWindow);
|
|
+ CWinEventsX11Imp::Init(m_dpy, m_mainWindow);
|
|
|
|
changeWindow = true;
|
|
changeSize = true;
|
|
@@ -889,13 +901,17 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
|
|
if (changeSize || changeWindow)
|
|
{
|
|
+ XResizeWindow(m_dpy, m_mainWindow, width, height);
|
|
+ }
|
|
+
|
|
+ if ((width != m_nWidth) || (height != m_nHeight) || changeWindow)
|
|
+ {
|
|
XResizeWindow(m_dpy, m_glWindow, width, height);
|
|
}
|
|
|
|
if (changeWindow)
|
|
{
|
|
m_icon = None;
|
|
- if (!fullscreen)
|
|
{
|
|
CreateIconPixmap();
|
|
XWMHints *wm_hints;
|
|
@@ -912,21 +928,22 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
wm_hints->flags = StateHint | IconPixmapHint;
|
|
|
|
XSync(m_dpy,False);
|
|
- XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName,
|
|
+ XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName,
|
|
NULL, 0, NULL, wm_hints,
|
|
NULL);
|
|
XFree(wm_hints);
|
|
|
|
// register interest in the delete window message
|
|
Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
|
|
- XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1);
|
|
+ XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1);
|
|
}
|
|
XMapRaised(m_dpy, m_glWindow);
|
|
+ XMapRaised(m_dpy, m_mainWindow);
|
|
XSync(m_dpy,TRUE);
|
|
|
|
if (changeWindow && mouseActive)
|
|
{
|
|
- XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height);
|
|
+ XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height);
|
|
}
|
|
|
|
if (fullscreen)
|
|
@@ -934,10 +951,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
int result = -1;
|
|
while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
{
|
|
- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
+ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
XbmcThreads::ThreadSleep(100);
|
|
}
|
|
- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
}
|
|
|
|
CDirtyRegionList dr;
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 2a1fb41..e8993f1 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -81,7 +81,7 @@ protected:
|
|
void OnLostDevice();
|
|
bool SetWindow(int width, int height, bool fullscreen, const CStdString &output);
|
|
|
|
- Window m_glWindow;
|
|
+ Window m_glWindow, m_mainWindow;
|
|
GLXContext m_glContext;
|
|
Display* m_dpy;
|
|
Cursor m_invisibleCursor;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From ecc4546cbeef4193a0cf2bcad35357f3fcf6fcc8 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 24 Mar 2013 12:30:12 +0100
|
|
Subject: [PATCH 51/93] X11: use system key repeat rate instead of hardcoded
|
|
one, taken from 58fd64b194e38b73b5f3132744bab35e994e7441
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 58 +++++++++++++----------------------------
|
|
xbmc/windowing/WinEventsX11.h | 5 +---
|
|
2 files changed, 19 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 263cb5a..09f56ff 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
WinEvents->m_xrrEventPending = false;
|
|
- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
|
|
// open input method
|
|
char *old_locale = NULL, *old_modifiers = NULL;
|
|
@@ -328,20 +327,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
memset(&xevent, 0, sizeof (XEvent));
|
|
XNextEvent(WinEvents->m_display, &xevent);
|
|
|
|
- // ignore events generated by auto-repeat
|
|
- if (xevent.type == KeyRelease && XPending(WinEvents->m_display))
|
|
- {
|
|
- XEvent peekevent;
|
|
- XPeekEvent(WinEvents->m_display, &peekevent);
|
|
- if ((peekevent.type == KeyPress) &&
|
|
- (peekevent.xkey.keycode == xevent.xkey.keycode) &&
|
|
- ((peekevent.xkey.time - xevent.xkey.time) < 2))
|
|
- {
|
|
- XNextEvent(WinEvents->m_display, &peekevent);
|
|
- continue;
|
|
- }
|
|
- }
|
|
-
|
|
if (XFilterEvent(&xevent, None))
|
|
continue;
|
|
|
|
@@ -364,7 +349,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
if (WinEvents->m_xic)
|
|
XSetICFocus(WinEvents->m_xic);
|
|
g_application.m_AppFocused = true;
|
|
- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
WinEvents->m_keymodState = 0;
|
|
if (serial == xevent.xfocus.serial)
|
|
break;
|
|
@@ -377,7 +361,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
if (WinEvents->m_xic)
|
|
XUnsetICFocus(WinEvents->m_xic);
|
|
g_application.m_AppFocused = false;
|
|
- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event));
|
|
g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
|
|
serial = xevent.xfocus.serial;
|
|
break;
|
|
@@ -433,7 +416,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
{
|
|
newEvent.key.keysym.unicode = keybuf[0];
|
|
}
|
|
- ret |= ProcessKey(newEvent, 500);
|
|
+ ret |= ProcessKey(newEvent);
|
|
break;
|
|
}
|
|
|
|
@@ -472,7 +455,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
newEvent.key.keysym.unicode = keys[i];
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
- ret |= ProcessKey(newEvent, 500);
|
|
+ ret |= ProcessKey(newEvent);
|
|
}
|
|
if (keys.length() > 0)
|
|
{
|
|
@@ -483,7 +466,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
|
|
- ret |= ProcessKey(newEvent, 500);
|
|
+ ret |= ProcessKey(newEvent);
|
|
}
|
|
break;
|
|
}
|
|
@@ -494,7 +477,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
- ret |= ProcessKey(newEvent, 500);
|
|
+ ret |= ProcessKey(newEvent);
|
|
break;
|
|
}
|
|
|
|
@@ -504,6 +487,18 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
case KeyRelease:
|
|
{
|
|
+ // if we have a queued press directly after, this is a repeat
|
|
+ if( XEventsQueued( WinEvents->m_display, QueuedAfterReading ) )
|
|
+ {
|
|
+ XEvent next_event;
|
|
+ XPeekEvent( WinEvents->m_display, &next_event );
|
|
+ if(next_event.type == KeyPress
|
|
+ && next_event.xkey.window == xevent.xkey.window
|
|
+ && next_event.xkey.keycode == xevent.xkey.keycode
|
|
+ && (next_event.xkey.time - xevent.xkey.time < 2) )
|
|
+ continue;
|
|
+ }
|
|
+
|
|
XBMC_Event newEvent;
|
|
KeySym xkeysym;
|
|
memset(&newEvent, 0, sizeof(newEvent));
|
|
@@ -513,7 +508,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
newEvent.key.state = xevent.xkey.state;
|
|
newEvent.key.type = xevent.xkey.type;
|
|
- ret |= ProcessKey(newEvent, 0);
|
|
+ ret |= ProcessKey(newEvent);
|
|
break;
|
|
}
|
|
|
|
@@ -589,8 +584,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
}// while
|
|
|
|
- ret |= ProcessKeyRepeat();
|
|
-
|
|
#if defined(HAS_XRANDR)
|
|
if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast())
|
|
{
|
|
@@ -635,7 +628,7 @@ size_t CWinEventsX11Imp::GetQueueSize()
|
|
return ret;
|
|
}
|
|
|
|
-bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay)
|
|
+bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event)
|
|
{
|
|
if (event.type == XBMC_KEYDOWN)
|
|
{
|
|
@@ -673,8 +666,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay)
|
|
break;
|
|
}
|
|
event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState;
|
|
- memcpy(&(WinEvents->m_lastKey), &event, sizeof(event));
|
|
- WinEvents->m_repeatKeyTimeout.Set(repeatDelay);
|
|
|
|
bool ret = ProcessShortcuts(event);
|
|
if (ret)
|
|
@@ -715,7 +706,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay)
|
|
break;
|
|
}
|
|
event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState;
|
|
- memset(&(WinEvents->m_lastKey), 0, sizeof(event));
|
|
}
|
|
|
|
return g_application.OnEvent(event);
|
|
@@ -738,18 +728,6 @@ bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event)
|
|
return false;
|
|
}
|
|
|
|
-bool CWinEventsX11Imp::ProcessKeyRepeat()
|
|
-{
|
|
- if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN))
|
|
- {
|
|
- if (WinEvents->m_repeatKeyTimeout.IsTimePast())
|
|
- {
|
|
- return ProcessKey(WinEvents->m_lastKey, 10);
|
|
- }
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym)
|
|
{
|
|
// try direct mapping first
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index c69169c..6429291 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -47,8 +47,7 @@ public:
|
|
|
|
protected:
|
|
static XBMCKey LookupXbmcKeySym(KeySym keysym);
|
|
- static bool ProcessKey(XBMC_Event &event, int repeatDelay);
|
|
- static bool ProcessKeyRepeat();
|
|
+ static bool ProcessKey(XBMC_Event &event);
|
|
static bool ProcessShortcuts(XBMC_Event& event);
|
|
static CWinEventsX11Imp *WinEvents;
|
|
Display *m_display;
|
|
@@ -58,8 +57,6 @@ protected:
|
|
size_t m_keybuf_len;
|
|
XIM m_xim;
|
|
XIC m_xic;
|
|
- XBMC_Event m_lastKey;
|
|
- XbmcThreads::EndTime m_repeatKeyTimeout;
|
|
std::map<uint32_t,uint32_t> m_symLookupTable;
|
|
int m_keymodState;
|
|
bool m_structureChanged;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 4e3bbd52ba8c190b152d0ef21a8da4d3d512f056 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 24 Mar 2013 16:04:48 +0100
|
|
Subject: [PATCH 52/93] linux: use CLOCK_MONOTONIC_RAW as this is not subject
|
|
to NTP
|
|
|
|
---
|
|
xbmc/threads/SystemClock.cpp | 2 +-
|
|
xbmc/utils/TimeUtils.cpp | 2 +-
|
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/threads/SystemClock.cpp b/xbmc/threads/SystemClock.cpp
|
|
index 657a154..35e3abf 100644
|
|
--- a/xbmc/threads/SystemClock.cpp
|
|
+++ b/xbmc/threads/SystemClock.cpp
|
|
@@ -43,7 +43,7 @@ namespace XbmcThreads
|
|
now_time = (uint64_t)timeGetTime();
|
|
#else
|
|
struct timespec ts = {};
|
|
- clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
|
now_time = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
|
|
#endif
|
|
if (!start_time_set)
|
|
diff --git a/xbmc/utils/TimeUtils.cpp b/xbmc/utils/TimeUtils.cpp
|
|
index c06b8c5..4390d2e 100644
|
|
--- a/xbmc/utils/TimeUtils.cpp
|
|
+++ b/xbmc/utils/TimeUtils.cpp
|
|
@@ -43,7 +43,7 @@ int64_t CurrentHostCounter(void)
|
|
return( (int64_t)PerformanceCount.QuadPart );
|
|
#else
|
|
struct timespec now;
|
|
- clock_gettime(CLOCK_MONOTONIC, &now);
|
|
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
|
|
return( ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec );
|
|
#endif
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 6f70066f6cc093386d9cc087c3d089012b810f05 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 28 Mar 2013 15:18:53 +0100
|
|
Subject: [PATCH 53/93] OMXPlayer: some caching fixes for pvr
|
|
|
|
---
|
|
xbmc/cores/omxplayer/OMXPlayer.cpp | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp
|
|
index a3d3928..7b81178 100644
|
|
--- a/xbmc/cores/omxplayer/OMXPlayer.cpp
|
|
+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp
|
|
@@ -2556,7 +2556,8 @@ void COMXPlayer::HandleMessages()
|
|
m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true));
|
|
|
|
m_playSpeed = speed;
|
|
- m_caching = CACHESTATE_DONE;
|
|
+ if (m_caching != CACHESTATE_PVR && m_playSpeed != DVD_PLAYSPEED_NORMAL)
|
|
+ m_caching = CACHESTATE_DONE;
|
|
m_clock.SetSpeed(speed);
|
|
m_av_clock.OMXSetSpeed(speed);
|
|
m_av_clock.OMXPause();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 73977466eae71113f367f88b3a6a39e2d2077089 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Thu, 28 Mar 2013 20:50:59 +0100
|
|
Subject: [PATCH 54/93] 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 43c4517..4131707 100644
|
|
--- a/xbmc/Application.cpp
|
|
+++ b/xbmc/Application.cpp
|
|
@@ -2307,10 +2307,11 @@ void CApplication::Render()
|
|
if (frameTime < singleFrameTime)
|
|
Sleep(singleFrameTime - frameTime);
|
|
}
|
|
- m_lastFrameTime = XbmcThreads::SystemClockMillis();
|
|
|
|
if (flip)
|
|
g_graphicsContext.Flip(dirtyRegions);
|
|
+
|
|
+ m_lastFrameTime = XbmcThreads::SystemClockMillis();
|
|
CTimeUtils::UpdateFrameTime(flip);
|
|
|
|
g_renderManager.UpdateResolution();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From c0b389a1a384684536183067a0b514bbc9c24477 Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sat, 13 Apr 2013 08:32:06 +0200
|
|
Subject: [PATCH 55/93] X11: fix mouse coverage
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++++---
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
2 files changed, 9 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 07f3f3d..2acb36d 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -583,10 +583,10 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining)
|
|
|
|
void CWinSystemX11::NotifyMouseCoverage(bool covered)
|
|
{
|
|
- if (!m_bFullScreen)
|
|
+ if (!m_bFullScreen || !m_mainWindow)
|
|
return;
|
|
|
|
- if (covered)
|
|
+ if (covered && !m_bIsGrabbed)
|
|
{
|
|
int result = -1;
|
|
while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
@@ -595,11 +595,13 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered)
|
|
XbmcThreads::ThreadSleep(100);
|
|
}
|
|
XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+ m_bIsGrabbed = true;
|
|
}
|
|
- else
|
|
+ else if (!covered && m_bIsGrabbed)
|
|
{
|
|
XUngrabKeyboard(m_dpy, CurrentTime);
|
|
XUngrabPointer(m_dpy, CurrentTime);
|
|
+ m_bIsGrabbed = false;
|
|
}
|
|
}
|
|
|
|
@@ -955,7 +957,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
XbmcThreads::ThreadSleep(100);
|
|
}
|
|
XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
+ m_bIsGrabbed = true;
|
|
}
|
|
+ else
|
|
+ m_bIsGrabbed = false;
|
|
|
|
CDirtyRegionList dr;
|
|
RefreshGlxContext(!m_currentOutput.Equals(output));
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index e8993f1..5cccfb7 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -90,6 +90,7 @@ protected:
|
|
bool m_bWasFullScreenBeforeMinimize;
|
|
bool m_minimized;
|
|
bool m_bIgnoreNextFocusMessage;
|
|
+ bool m_bIsGrabbed;
|
|
int m_RREventBase;
|
|
CCriticalSection m_resourceSection;
|
|
std::vector<IDispResource*> m_resources;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 884c573f53a288c206bd13348ce3e60dae0cb564 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Wed, 8 May 2013 13:14:58 +0200
|
|
Subject: [PATCH 56/93] X11: fix incorrectly used screen num in desktop
|
|
resolution
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 5 +++--
|
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 2acb36d..101ba98 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -268,9 +268,9 @@ void CWinSystemX11::UpdateResolutions()
|
|
XMode mode = g_xrandr.GetCurrentMode(currentMonitor);
|
|
m_bIsRotated = out->isRotated;
|
|
if (!m_bIsRotated)
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz);
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
else
|
|
- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz);
|
|
+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor;
|
|
}
|
|
@@ -305,6 +305,7 @@ void CWinSystemX11::UpdateResolutions()
|
|
CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d",
|
|
mode.id.c_str(), mode.name.c_str(), mode.hz, mode.w, mode.h);
|
|
RESOLUTION_INFO res;
|
|
+ res.iScreen = 0; // not used by X11
|
|
res.iWidth = mode.w;
|
|
res.iHeight = mode.h;
|
|
res.iScreenWidth = mode.w;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 836500221bf270ed628d35468a28873c96d41764 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 9 May 2013 12:07:09 +0200
|
|
Subject: [PATCH 57/93] X11: do not overwrite user selected monitor with
|
|
fallback
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 31 ++++++++++++++-----------------
|
|
xbmc/windowing/X11/WinSystemX11.h | 1 +
|
|
2 files changed, 15 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 101ba98..c614c9b 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -172,7 +172,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
&& m_nHeight == newHeight)
|
|
return true;
|
|
|
|
- if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor")))
|
|
+ if (!SetWindow(newWidth, newHeight, false, m_userOutput))
|
|
{
|
|
return false;
|
|
}
|
|
@@ -180,7 +180,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
m_nWidth = newWidth;
|
|
m_nHeight = newHeight;
|
|
m_bFullScreen = false;
|
|
- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ m_currentOutput = m_userOutput;
|
|
|
|
return false;
|
|
}
|
|
@@ -234,13 +234,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
|
|
}
|
|
#endif
|
|
|
|
- if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor")))
|
|
+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, m_userOutput))
|
|
return false;
|
|
|
|
m_nWidth = res.iWidth;
|
|
m_nHeight = res.iHeight;
|
|
m_bFullScreen = fullScreen;
|
|
- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ m_currentOutput = m_userOutput;
|
|
|
|
return true;
|
|
}
|
|
@@ -250,34 +250,32 @@ void CWinSystemX11::UpdateResolutions()
|
|
CWinSystemBase::UpdateResolutions();
|
|
|
|
#if defined(HAS_XRANDR)
|
|
- CStdString currentMonitor;
|
|
int numScreens = XScreenCount(m_dpy);
|
|
g_xrandr.SetNumScreens(numScreens);
|
|
if(g_xrandr.Query(true))
|
|
{
|
|
- currentMonitor = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
// check if the monitor is connected
|
|
- XOutput *out = g_xrandr.GetOutput(currentMonitor);
|
|
+ XOutput *out = g_xrandr.GetOutput(m_userOutput);
|
|
if (!out)
|
|
{
|
|
// choose first output
|
|
- currentMonitor = g_xrandr.GetModes()[0].name;
|
|
- out = g_xrandr.GetOutput(currentMonitor);
|
|
- CSettings::Get().SetString("videoscreen.monitor", currentMonitor);
|
|
+ m_userOutput = g_xrandr.GetModes()[0].name;
|
|
+ out = g_xrandr.GetOutput(m_userOutput);
|
|
}
|
|
- XMode mode = g_xrandr.GetCurrentMode(currentMonitor);
|
|
+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
m_bIsRotated = out->isRotated;
|
|
if (!m_bIsRotated)
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
else
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz);
|
|
CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id;
|
|
- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor;
|
|
+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = m_userOutput;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
- CSettings::Get().SetString("videoscreen.monitor", "Default");
|
|
+ m_userOutput = "No Output";
|
|
m_nScreen = DefaultScreen(m_dpy);
|
|
int w = DisplayWidth(m_dpy, m_nScreen);
|
|
int h = DisplayHeight(m_dpy, m_nScreen);
|
|
@@ -291,7 +289,7 @@ void CWinSystemX11::UpdateResolutions()
|
|
|
|
CLog::Log(LOGINFO, "Available videomodes (xrandr):");
|
|
|
|
- XOutput *out = g_xrandr.GetOutput(currentMonitor);
|
|
+ XOutput *out = g_xrandr.GetOutput(m_userOutput);
|
|
string modename = "";
|
|
|
|
if (out != NULL)
|
|
@@ -691,9 +689,8 @@ void CWinSystemX11::NotifyXRREvent()
|
|
}
|
|
m_bIsInternalXrr = false;
|
|
|
|
- CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
- XOutput *out = g_xrandr.GetOutput(currentOutput);
|
|
- XMode mode = g_xrandr.GetCurrentMode(currentOutput);
|
|
+ XOutput *out = g_xrandr.GetOutput(m_userOutput);
|
|
+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
|
|
if (out)
|
|
CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 5cccfb7..1b658e2 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -96,6 +96,7 @@ protected:
|
|
std::vector<IDispResource*> m_resources;
|
|
uint64_t m_dpyLostTime;
|
|
CStdString m_currentOutput;
|
|
+ CStdString m_userOutput;
|
|
bool m_windowDirty;
|
|
bool m_bIsInternalXrr;
|
|
bool m_newGlContext;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 01061c02fe55c312e6e7e4b56f9cc29760ce547d Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sun, 12 May 2013 10:50:30 +0200
|
|
Subject: [PATCH 58/93] xrandr: add turn on/off to wrapper
|
|
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 78 +++++++++++++++++++++++++++++++++++++++----
|
|
xbmc/windowing/X11/XRandR.h | 6 ++--
|
|
2 files changed, 75 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 4355ef7..223472c 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -29,6 +29,7 @@
|
|
#include "utils/XBMCTinyXML.h"
|
|
#include "utils/StringUtils.h"
|
|
#include "../xbmc/utils/log.h"
|
|
+#include "threads/SystemClock.h"
|
|
|
|
#if defined(TARGET_FREEBSD)
|
|
#include <sys/types.h>
|
|
@@ -45,7 +46,7 @@ CXRandR::CXRandR(bool query)
|
|
Query();
|
|
}
|
|
|
|
-bool CXRandR::Query(bool force)
|
|
+bool CXRandR::Query(bool force, bool ignoreoff)
|
|
{
|
|
if (!force)
|
|
if (m_bInit)
|
|
@@ -62,13 +63,13 @@ bool CXRandR::Query(bool force)
|
|
bool success = false;
|
|
for(unsigned int screennum=0; screennum<m_numScreens; ++screennum)
|
|
{
|
|
- if(Query(force, screennum))
|
|
+ if(Query(force, screennum, ignoreoff))
|
|
success = true;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
-bool CXRandR::Query(bool force, int screennum)
|
|
+bool CXRandR::Query(bool force, int screennum, bool ignoreoff)
|
|
{
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
@@ -136,11 +137,9 @@ bool CXRandR::Query(bool force, int screennum)
|
|
xmode.isCurrent = (strcasecmp(mode->Attribute("current"), "true") == 0);
|
|
xoutput.modes.push_back(xmode);
|
|
if (xmode.isCurrent)
|
|
- {
|
|
hascurrent = true;
|
|
- }
|
|
}
|
|
- if (hascurrent)
|
|
+ if (hascurrent || !ignoreoff)
|
|
m_outputs.push_back(xoutput);
|
|
else
|
|
CLog::Log(LOGWARNING, "CXRandR::Query - output %s has no current mode, assuming disconnected", xoutput.name.c_str());
|
|
@@ -148,6 +147,71 @@ bool CXRandR::Query(bool force, int screennum)
|
|
return m_outputs.size() > 0;
|
|
}
|
|
|
|
+bool CXRandR::TurnOffOutput(CStdString name)
|
|
+{
|
|
+ CStdString cmd;
|
|
+ cmd = getenv("XBMC_BIN_HOME");
|
|
+ cmd += "/xbmc-xrandr";
|
|
+ cmd.AppendFormat(" --output %s --off", name.c_str());
|
|
+
|
|
+ int status = system(cmd.c_str());
|
|
+ if (status == -1)
|
|
+ return false;
|
|
+
|
|
+ if (WEXITSTATUS(status) != 0)
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool CXRandR::TurnOnOutput(CStdString name)
|
|
+{
|
|
+ XOutput *output = GetOutput(name);
|
|
+ if (!output)
|
|
+ return false;
|
|
+
|
|
+ XMode mode = GetCurrentMode(output->name);
|
|
+ if (mode.isCurrent)
|
|
+ return true;
|
|
+
|
|
+ // get preferred mode
|
|
+ for (unsigned int j = 0; j < m_outputs.size(); j++)
|
|
+ {
|
|
+ if (m_outputs[j].name == output->name)
|
|
+ {
|
|
+ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++)
|
|
+ {
|
|
+ if (m_outputs[j].modes[i].isPreferred)
|
|
+ {
|
|
+ mode = m_outputs[j].modes[i];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!mode.isPreferred)
|
|
+ return false;
|
|
+
|
|
+ if (!SetMode(*output, mode))
|
|
+ return false;
|
|
+
|
|
+ XbmcThreads::EndTime timeout(5000);
|
|
+ while (!timeout.IsTimePast())
|
|
+ {
|
|
+ if (!Query(true))
|
|
+ return false;
|
|
+
|
|
+ output = GetOutput(name);
|
|
+ if (output && output->h > 0)
|
|
+ return true;
|
|
+
|
|
+ Sleep(200);
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
std::vector<XOutput> CXRandR::GetModes(void)
|
|
{
|
|
Query();
|
|
@@ -161,7 +225,7 @@ void CXRandR::SaveState()
|
|
|
|
bool CXRandR::SetMode(XOutput output, XMode mode)
|
|
{
|
|
- if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == ""))
|
|
+ if ((output.name == "" && mode.id == ""))
|
|
return true;
|
|
|
|
Query();
|
|
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
|
|
index d37838a..059062f 100644
|
|
--- a/xbmc/windowing/X11/XRandR.h
|
|
+++ b/xbmc/windowing/X11/XRandR.h
|
|
@@ -94,8 +94,8 @@ class CXRandR
|
|
{
|
|
public:
|
|
CXRandR(bool query=false);
|
|
- bool Query(bool force=false);
|
|
- bool Query(bool force, int screennum);
|
|
+ bool Query(bool force=false, bool ignoreoff=true);
|
|
+ bool Query(bool force, int screennum, bool ignoreoff=true);
|
|
std::vector<XOutput> GetModes(void);
|
|
XMode GetCurrentMode(CStdString outputName);
|
|
XOutput *GetOutput(CStdString outputName);
|
|
@@ -104,6 +104,8 @@ public:
|
|
void SaveState();
|
|
void SetNumScreens(unsigned int num);
|
|
bool IsOutputConnected(CStdString name);
|
|
+ bool TurnOffOutput(CStdString name);
|
|
+ bool TurnOnOutput(CStdString name);
|
|
//bool Has1080i();
|
|
//bool Has1080p();
|
|
//bool Has720p();
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From fa66d3ddccf1c807feea602bd334b9adbc12ffe8 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sun, 19 May 2013 12:55:35 +0200
|
|
Subject: [PATCH 59/93] xrandr: add GetPreferredMode to wrapper
|
|
|
|
---
|
|
xbmc/windowing/X11/XRandR.cpp | 23 +++++++++++++++++++++++
|
|
xbmc/windowing/X11/XRandR.h | 1 +
|
|
2 files changed, 24 insertions(+)
|
|
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 223472c..62003f5 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -347,6 +347,29 @@ XMode CXRandR::GetCurrentMode(CStdString outputName)
|
|
return result;
|
|
}
|
|
|
|
+XMode CXRandR::GetPreferredMode(CStdString outputName)
|
|
+{
|
|
+ Query();
|
|
+ XMode result;
|
|
+
|
|
+ for (unsigned int j = 0; j < m_outputs.size(); j++)
|
|
+ {
|
|
+ if (m_outputs[j].name == outputName || outputName == "")
|
|
+ {
|
|
+ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++)
|
|
+ {
|
|
+ if (m_outputs[j].modes[i].isPreferred)
|
|
+ {
|
|
+ result = m_outputs[j].modes[i];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return result;
|
|
+}
|
|
+
|
|
void CXRandR::LoadCustomModeLinesToAllOutputs(void)
|
|
{
|
|
Query();
|
|
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
|
|
index 059062f..ab7cc63 100644
|
|
--- a/xbmc/windowing/X11/XRandR.h
|
|
+++ b/xbmc/windowing/X11/XRandR.h
|
|
@@ -98,6 +98,7 @@ public:
|
|
bool Query(bool force, int screennum, bool ignoreoff=true);
|
|
std::vector<XOutput> GetModes(void);
|
|
XMode GetCurrentMode(CStdString outputName);
|
|
+ XMode GetPreferredMode(CStdString outputName);
|
|
XOutput *GetOutput(CStdString outputName);
|
|
bool SetMode(XOutput output, XMode mode);
|
|
void LoadCustomModeLinesToAllOutputs(void);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 7c1b95f1c1354fbc2a32224592ba778b91b538d4 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sat, 11 May 2013 17:12:12 +0200
|
|
Subject: [PATCH 60/93] X11: multi-head improvement - poll for desired output
|
|
if we do not get an xrr event
|
|
|
|
---
|
|
language/English/strings.po | 9 +++-
|
|
system/settings/settings.xml | 8 +++-
|
|
xbmc/settings/DisplaySettings.cpp | 4 ++
|
|
xbmc/windowing/WinEventsX11.cpp | 6 +++
|
|
xbmc/windowing/WinEventsX11.h | 1 +
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 83 +++++++++++++++++++++++++++++++++----
|
|
xbmc/windowing/X11/WinSystemX11.h | 2 +-
|
|
xbmc/windowing/X11/XRandR.cpp | 6 ++-
|
|
8 files changed, 106 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/language/English/strings.po b/language/English/strings.po
|
|
index d9b34e1..516c5c1 100755
|
|
--- a/language/English/strings.po
|
|
+++ b/language/English/strings.po
|
|
@@ -6558,7 +6558,7 @@ msgctxt "#14071"
|
|
msgid "Allow file renaming and deletion"
|
|
msgstr ""
|
|
|
|
-#empty strings from id 14072 to 14073
|
|
+#empty strings from id 14073 to 14073
|
|
|
|
msgctxt "#14074"
|
|
msgid "Set timezone"
|
|
@@ -6696,7 +6696,12 @@ msgctxt "#14101"
|
|
msgid "Acceleration"
|
|
msgstr ""
|
|
|
|
-#empty strings from id 14102 to 15011
|
|
+#: xbmc/settings/settings.xml
|
|
+msgctxt "#14102"
|
|
+msgid "Switch off other Monitor"
|
|
+msgstr ""
|
|
+
|
|
+#empty strings from id 14103 to 15011
|
|
|
|
#: xbmc/video/VideoDatabase.cpp
|
|
msgctxt "#15012"
|
|
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
|
|
index 4882978..fafabf4 100644
|
|
--- a/system/settings/settings.xml
|
|
+++ b/system/settings/settings.xml
|
|
@@ -2251,7 +2251,7 @@
|
|
<category id="videoscreen" label="21373" help="36603">
|
|
<group id="1">
|
|
<setting id="videoscreen.monitor" type="string" label="246" help="">
|
|
- <visible>HAS_GLX</visible>
|
|
+ <requirement>HAS_GLX</requirement>
|
|
<level>0</level>
|
|
<default>Default</default>
|
|
<constraints>
|
|
@@ -2259,6 +2259,11 @@
|
|
</constraints>
|
|
<control type="spinner" format="string" delayed="true" />
|
|
</setting>
|
|
+ <setting id="videoscreen.monitorsingle" type="boolean" label="14102" help="">
|
|
+ <requirement>HAS_GLX</requirement>
|
|
+ <level>0</level>
|
|
+ <default>false</default>
|
|
+ </setting>
|
|
<setting id="videoscreen.screen" type="integer" label="240" help="36351">
|
|
<level>0</level>
|
|
<default>0</default>
|
|
@@ -2311,6 +2316,7 @@
|
|
<control type="toggle" />
|
|
</setting>
|
|
<setting id="videoscreen.blankdisplays" type="boolean" parent="videoscreen.screen" label="13130" help="36355">
|
|
+ <requirement>!HAS_GLX</requirement>
|
|
<level>1</level>
|
|
<default>false</default>
|
|
<dependencies>
|
|
diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp
|
|
index 966d08f..40bc3b3 100644
|
|
--- a/xbmc/settings/DisplaySettings.cpp
|
|
+++ b/xbmc/settings/DisplaySettings.cpp
|
|
@@ -265,6 +265,10 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
m_resolutionChangeAborted = false;
|
|
}
|
|
}
|
|
+ else if (settingId == "videoscreen.monitorsingle")
|
|
+ {
|
|
+ g_Windowing.UpdateResolutions();
|
|
+ }
|
|
|
|
return true;
|
|
}
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 09f56ff..908c8b6 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -213,6 +213,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
WinEvents->m_xrrEventPending = false;
|
|
+ WinEvents->m_xrrPollTimer.Set(3000);
|
|
|
|
// open input method
|
|
char *old_locale = NULL, *old_modifiers = NULL;
|
|
@@ -591,6 +592,11 @@ bool CWinEventsX11Imp::MessagePump()
|
|
g_Windowing.NotifyXRREvent();
|
|
WinEvents->m_xrrEventPending = false;
|
|
}
|
|
+ else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast())
|
|
+ {
|
|
+ g_Windowing.NotifyXRREvent(true);
|
|
+ WinEvents->m_xrrPollTimer.Set(3000);
|
|
+ }
|
|
#endif
|
|
|
|
#ifdef HAS_SDL_JOYSTICK
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index 6429291..91a604f 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -62,5 +62,6 @@ protected:
|
|
bool m_structureChanged;
|
|
int m_RREventBase;
|
|
XbmcThreads::EndTime m_xrrFailSafeTimer;
|
|
+ XbmcThreads::EndTime m_xrrPollTimer;
|
|
bool m_xrrEventPending;
|
|
};
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index c614c9b..b3fe510 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -252,18 +252,62 @@ void CWinSystemX11::UpdateResolutions()
|
|
#if defined(HAS_XRANDR)
|
|
int numScreens = XScreenCount(m_dpy);
|
|
g_xrandr.SetNumScreens(numScreens);
|
|
- if(g_xrandr.Query(true))
|
|
+
|
|
+ bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle");
|
|
+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ if (m_userOutput.Equals("Default"))
|
|
+ switchOnOff = false;
|
|
+
|
|
+ if(g_xrandr.Query(true, !switchOnOff))
|
|
{
|
|
- m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
// check if the monitor is connected
|
|
- XOutput *out = g_xrandr.GetOutput(m_userOutput);
|
|
+ // might take a while when connected to a receiver
|
|
+ XbmcThreads::EndTime timeout(3000);
|
|
+ XOutput *out = NULL;
|
|
+ while (!m_userOutput.Equals("Default") && !timeout.IsTimePast())
|
|
+ {
|
|
+ out = g_xrandr.GetOutput(m_userOutput);
|
|
+ if (out)
|
|
+ {
|
|
+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
+ if (mode.isCurrent || switchOnOff)
|
|
+ break;
|
|
+ else
|
|
+ {
|
|
+ out = NULL;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ Sleep(500);
|
|
+ if (!g_xrandr.Query(true, !switchOnOff))
|
|
+ break;
|
|
+ }
|
|
if (!out)
|
|
{
|
|
- // choose first output
|
|
m_userOutput = g_xrandr.GetModes()[0].name;
|
|
out = g_xrandr.GetOutput(m_userOutput);
|
|
}
|
|
+
|
|
+ // switch on output
|
|
+ if(switchOnOff)
|
|
+ g_xrandr.TurnOnOutput(m_userOutput);
|
|
+
|
|
+ // switch off other outputs if desired
|
|
+ if (switchOnOff)
|
|
+ {
|
|
+ std::vector<XOutput> outputs = g_xrandr.GetModes();
|
|
+ for (int i=0; i<outputs.size(); i++)
|
|
+ {
|
|
+ if (outputs[i].name.Equals(m_userOutput))
|
|
+ continue;
|
|
+ g_xrandr.TurnOffOutput(outputs[i].name);
|
|
+ }
|
|
+ }
|
|
+
|
|
XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
+ if (mode.id.empty())
|
|
+ mode = g_xrandr.GetPreferredMode(m_userOutput);
|
|
m_bIsRotated = out->isRotated;
|
|
if (!m_bIsRotated)
|
|
UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz);
|
|
@@ -382,7 +426,9 @@ bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo)
|
|
void CWinSystemX11::GetConnectedOutputs(std::vector<CStdString> *outputs)
|
|
{
|
|
vector<XOutput> outs;
|
|
+ g_xrandr.Query(true);
|
|
outs = g_xrandr.GetModes();
|
|
+ outputs->push_back("Default");
|
|
for(unsigned int i=0; i<outs.size(); ++i)
|
|
{
|
|
outputs->push_back(outs[i].name);
|
|
@@ -669,14 +715,34 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
#endif
|
|
}
|
|
|
|
-void CWinSystemX11::NotifyXRREvent()
|
|
+void CWinSystemX11::NotifyXRREvent(bool poll)
|
|
{
|
|
- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
+ // we may not get an event if desired monitor becomes available
|
|
+ // hence we need to poll
|
|
+ if (poll)
|
|
+ {
|
|
+ CStdString output = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default"))
|
|
+ return;
|
|
+
|
|
+ int numScreens = XScreenCount(m_dpy);
|
|
+ g_xrandr.SetNumScreens(numScreens);
|
|
+ g_xrandr.Query(true);
|
|
+ if (!g_xrandr.IsOutputConnected(output))
|
|
+ return;
|
|
+
|
|
+ // if output is turned off by user, respect it
|
|
+ XMode mode = g_xrandr.GetCurrentMode(output);
|
|
+ if (!mode.isCurrent)
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll);
|
|
m_windowDirty = true;
|
|
|
|
CSingleLock lock(g_graphicsContext);
|
|
|
|
- if (!g_xrandr.Query(true))
|
|
+ if (!g_xrandr.Query(!poll))
|
|
{
|
|
CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
return;
|
|
@@ -703,7 +769,8 @@ void CWinSystemX11::NotifyXRREvent()
|
|
bool found(false);
|
|
for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i)
|
|
{
|
|
- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id)
|
|
+ res = CDisplaySettings::Get().GetResolutionInfo(i);
|
|
+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId.Equals(mode.id))
|
|
{
|
|
found = true;
|
|
break;
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 1b658e2..7ec5be4 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -70,7 +70,7 @@ public:
|
|
Display* GetDisplay() { return m_dpy; }
|
|
GLXWindow GetWindow() { return m_glWindow; }
|
|
GLXContext GetGlxContext() { return m_glContext; }
|
|
- void NotifyXRREvent();
|
|
+ void NotifyXRREvent(bool poll = false);
|
|
void GetConnectedOutputs(std::vector<CStdString> *outputs);
|
|
bool IsCurrentOutput(CStdString output);
|
|
void NotifyMouseCoverage(bool covered);
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 62003f5..8525ede 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -149,10 +149,14 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff)
|
|
|
|
bool CXRandR::TurnOffOutput(CStdString name)
|
|
{
|
|
+ XOutput *output = GetOutput(name);
|
|
+ if (!output)
|
|
+ return false;
|
|
+
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
cmd += "/xbmc-xrandr";
|
|
- cmd.AppendFormat(" --output %s --off", name.c_str());
|
|
+ cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str());
|
|
|
|
int status = system(cmd.c_str());
|
|
if (status == -1)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 08ec19f07d729af80bc81487a445ffd6794d82ed Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Wed, 15 May 2013 09:14:34 +0200
|
|
Subject: [PATCH 61/93] X11: ignore mouse move event form other windows
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 908c8b6..938ad26 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -328,7 +328,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
memset(&xevent, 0, sizeof (XEvent));
|
|
XNextEvent(WinEvents->m_display, &xevent);
|
|
|
|
- if (XFilterEvent(&xevent, None))
|
|
+ if (XFilterEvent(&xevent, WinEvents->m_window))
|
|
continue;
|
|
|
|
switch (xevent.type)
|
|
@@ -529,6 +529,8 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
case MotionNotify:
|
|
{
|
|
+ if (xevent.xmotion.window != WinEvents->m_window)
|
|
+ break;
|
|
XBMC_Event newEvent;
|
|
memset(&newEvent, 0, sizeof(newEvent));
|
|
newEvent.type = XBMC_MOUSEMOTION;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 1f153f70a4adc06e1b23c09bfee4daa6f59ff1db Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 11 Jun 2013 16:20:29 +0200
|
|
Subject: [PATCH 62/93] renderer: allow some lateness within vblank interval
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++--
|
|
xbmc/cores/VideoRenderers/RenderManager.h | 1 +
|
|
2 files changed, 11 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
index 9e2c055..8dc8a91 100644
|
|
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
@@ -378,6 +378,8 @@ void CXBMCRenderManager::FrameFinish()
|
|
if(g_graphicsContext.IsFullScreenVideo())
|
|
WaitPresentTime(m.timestamp);
|
|
|
|
+ m_clock_framefinish = GetPresentTime();
|
|
+
|
|
{ CSingleLock lock(m_presentlock);
|
|
|
|
if(m_presentstep == PRESENT_FRAME)
|
|
@@ -1030,6 +1032,12 @@ void CXBMCRenderManager::PrepareNextRender()
|
|
|
|
double clocktime = GetPresentTime();
|
|
double frametime = 1.0 / GetMaximumFPS();
|
|
+ double correction = 0.0;
|
|
+ int fps = g_VideoReferenceClock.GetRefreshRate();
|
|
+ if((fps > 0) && g_graphicsContext.IsFullScreenVideo() && (clocktime != m_clock_framefinish))
|
|
+ {
|
|
+ correction = frametime;
|
|
+ }
|
|
|
|
/* see if any future queued frames are already due */
|
|
std::deque<int>::reverse_iterator curr, prev;
|
|
@@ -1038,8 +1046,8 @@ void CXBMCRenderManager::PrepareNextRender()
|
|
++prev;
|
|
while (prev != m_queued.rend())
|
|
{
|
|
- if(clocktime > m_Queue[*prev].timestamp /* previous frame is late */
|
|
- && clocktime > m_Queue[*curr].timestamp - frametime) /* selected frame is close to it's display time */
|
|
+ if(clocktime > m_Queue[*prev].timestamp + correction /* previous frame is late */
|
|
+ && clocktime > m_Queue[*curr].timestamp - frametime + correction) /* selected frame is close to it's display time */
|
|
break;
|
|
++curr;
|
|
++prev;
|
|
diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
|
|
index 949c652..d84ff6c 100644
|
|
--- a/xbmc/cores/VideoRenderers/RenderManager.h
|
|
+++ b/xbmc/cores/VideoRenderers/RenderManager.h
|
|
@@ -252,6 +252,7 @@ protected:
|
|
XbmcThreads::ConditionVariable m_presentevent;
|
|
CCriticalSection m_presentlock;
|
|
CEvent m_flushEvent;
|
|
+ double m_clock_framefinish;
|
|
|
|
|
|
OVERLAY::CRenderer m_overlays;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 0505eab3a4d5a351fb5700e919e190674472675d Mon Sep 17 00:00:00 2001
|
|
From: xbmc <fernetmenta@online.de>
|
|
Date: Sun, 16 Jun 2013 13:22:58 +0200
|
|
Subject: [PATCH 63/93] X11: another fix for mouse coverage
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 938ad26..e4ca56d 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -515,14 +515,16 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
case EnterNotify:
|
|
{
|
|
- g_Windowing.NotifyMouseCoverage(true);
|
|
+ if (xevent.xcrossing.mode == NotifyNormal)
|
|
+ g_Windowing.NotifyMouseCoverage(true);
|
|
break;
|
|
}
|
|
|
|
// lose mouse coverage
|
|
case LeaveNotify:
|
|
{
|
|
- g_Windowing.NotifyMouseCoverage(false);
|
|
+ if (xevent.xcrossing.mode == NotifyNormal)
|
|
+ g_Windowing.NotifyMouseCoverage(false);
|
|
g_Mouse.SetActive(false);
|
|
break;
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 3479849f9941a74852f8057de0352f52775168fc Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Fri, 5 Jul 2013 12:14:00 +0200
|
|
Subject: [PATCH 64/93] X11: set windows class name
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++-
|
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index b3fe510..df5fe9b 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -982,8 +982,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
{
|
|
CreateIconPixmap();
|
|
XWMHints *wm_hints;
|
|
+ XClassHint *class_hints;
|
|
XTextProperty windowName, iconName;
|
|
std::string titleString = "XBMC Media Center";
|
|
+ std::string classString = "xbmc.bin";
|
|
char *title = (char*)titleString.c_str();
|
|
|
|
XStringListToTextProperty(&title, 1, &windowName);
|
|
@@ -994,10 +996,15 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
wm_hints->icon_pixmap = m_icon;
|
|
wm_hints->flags = StateHint | IconPixmapHint;
|
|
|
|
+ class_hints = XAllocClassHint();
|
|
+ class_hints->res_class = (char*)classString.c_str();
|
|
+ class_hints->res_name = (char*)classString.c_str();
|
|
+
|
|
XSync(m_dpy,False);
|
|
XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName,
|
|
NULL, 0, NULL, wm_hints,
|
|
- NULL);
|
|
+ class_hints);
|
|
+ XFree(class_hints);
|
|
XFree(wm_hints);
|
|
|
|
// register interest in the delete window message
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 25a211eaa8d5125fc99353198b2a2caff23bf13c Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 25 Jul 2013 17:18:13 +0200
|
|
Subject: [PATCH 65/93] 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 6709993..6ca2cf4 100644
|
|
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
|
|
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
|
|
@@ -30,8 +30,8 @@ using namespace ActiveAE;
|
|
#include "settings/AdvancedSettings.h"
|
|
#include "windowing/WindowingFactory.h"
|
|
|
|
-#define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds
|
|
-#define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds
|
|
+#define MAX_CACHE_LEVEL 0.4 // total cache time of stream in seconds
|
|
+#define MAX_WATER_LEVEL 0.2 // buffered time after stream stages in seconds
|
|
#define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds
|
|
|
|
void CEngineStats::Reset(unsigned int sampleRate)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 0153f224e0288a2fd3d2ea6066b53fa142435580 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sun, 4 Aug 2013 10:11:16 +0200
|
|
Subject: [PATCH 66/93] Revert "vdpau: comment some features that will be added
|
|
later"
|
|
|
|
This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf.
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 12 ++++--------
|
|
1 file changed, 4 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
index cd72cc6..351586a 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
|
|
@@ -1117,8 +1117,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame)
|
|
m_bufferStats.IncDecoded();
|
|
m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic));
|
|
|
|
- //TODO
|
|
- // m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC);
|
|
+ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC);
|
|
}
|
|
|
|
int retval = 0;
|
|
@@ -2311,8 +2310,7 @@ void CMixer::InitCycle()
|
|
int flags;
|
|
uint64_t latency;
|
|
m_config.stats->GetParams(latency, flags);
|
|
- // TODO
|
|
- if (0) //flags & DVP_FLAG_NO_POSTPROC)
|
|
+ if (flags & DVP_FLAG_NO_POSTPROC)
|
|
SetPostProcFeatures(false);
|
|
else
|
|
SetPostProcFeatures(true);
|
|
@@ -2324,8 +2322,7 @@ void CMixer::InitCycle()
|
|
bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED;
|
|
m_SeenInterlaceFlag |= interlaced;
|
|
|
|
- // TODO
|
|
- if (//!(flags & DVP_FLAG_NO_POSTPROC) &&
|
|
+ if (!(flags & DVP_FLAG_NO_POSTPROC) &&
|
|
(mode == VS_DEINTERLACEMODE_FORCE ||
|
|
(mode == VS_DEINTERLACEMODE_AUTO && interlaced)))
|
|
{
|
|
@@ -2347,8 +2344,7 @@ void CMixer::InitCycle()
|
|
m_config.stats->SetCanSkipDeint(true);
|
|
}
|
|
|
|
- // TODO
|
|
- if (0) //m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT)
|
|
+ if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT)
|
|
{
|
|
m_mixersteps = 1;
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 59ce2ef98300a41255d4d860c62d3dde6f9b3272 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Fri, 9 Aug 2013 18:01:40 +0200
|
|
Subject: [PATCH 67/93] X11: fix keysyms
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index e4ca56d..b20130c 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -461,7 +461,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
if (keys.length() > 0)
|
|
{
|
|
newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
- xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
+ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL);
|
|
newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
newEvent.key.keysym.unicode = keys[keys.length() - 1];
|
|
newEvent.key.state = xevent.xkey.state;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 9cec1f9aa579e00c1e22d67ff0fbb7a9466035b2 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Fri, 9 Aug 2013 18:42:36 +0200
|
|
Subject: [PATCH 68/93] X11: fix keysym for non-IM
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index b20130c..a38890c 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -408,7 +408,7 @@ bool CWinEventsX11Imp::MessagePump()
|
|
{
|
|
static XComposeStatus state;
|
|
char keybuf[32];
|
|
- xkeysym = XLookupKeysym(&xevent.xkey, 0);
|
|
+ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL);
|
|
newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym);
|
|
newEvent.key.keysym.scancode = xevent.xkey.keycode;
|
|
newEvent.key.state = xevent.xkey.state;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 7c9b3dd5116848f8b4140450cc7e635870c91c35 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sat, 10 Aug 2013 11:18:16 +0200
|
|
Subject: [PATCH 69/93] add some missing multi media keys
|
|
|
|
---
|
|
system/keymaps/keyboard.xml | 3 +++
|
|
xbmc/input/XBMC_keytable.cpp | 4 ++++
|
|
xbmc/input/XBMC_vkeys.h | 3 +++
|
|
3 files changed, 10 insertions(+)
|
|
|
|
diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml
|
|
index 45682a2..01f7904 100644
|
|
--- a/system/keymaps/keyboard.xml
|
|
+++ b/system/keymaps/keyboard.xml
|
|
@@ -119,6 +119,9 @@
|
|
<prev_track>SkipPrevious</prev_track>
|
|
<stop>Stop</stop>
|
|
<play_pause>Pause</play_pause>
|
|
+ <fastforward>FastForward</fastforward>
|
|
+ <rewind>Rewind</rewind>
|
|
+ <record/>
|
|
<launch_mail></launch_mail>
|
|
<launch_media_select>XBMC.ActivateWindow(MyMusic)</launch_media_select>
|
|
<launch_app1_pc_icon>ActivateWindow(MyPrograms)</launch_app1_pc_icon>
|
|
diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp
|
|
index b807897..30bad46 100644
|
|
--- a/xbmc/input/XBMC_keytable.cpp
|
|
+++ b/xbmc/input/XBMC_keytable.cpp
|
|
@@ -182,6 +182,10 @@ static const XBMCKEYTABLE XBMCKeyTable[] =
|
|
, { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" }
|
|
, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" }
|
|
, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" }
|
|
+, { XBMCK_REWIND, 0, 0, XBMCVK_MEDIA_REWIND, "rewind" }
|
|
+, { XBMCK_FASTFORWARD, 0, 0, XBMCVK_MEDIA_FASTFORWARD, "fastforward" }
|
|
+, { XBMCK_RECORD, 0, 0, XBMCVK_MEDIA_RECORD, "record" }
|
|
+
|
|
|
|
// Function keys
|
|
, { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"}
|
|
diff --git a/xbmc/input/XBMC_vkeys.h b/xbmc/input/XBMC_vkeys.h
|
|
index ee6bb69..364b45a 100644
|
|
--- a/xbmc/input/XBMC_vkeys.h
|
|
+++ b/xbmc/input/XBMC_vkeys.h
|
|
@@ -188,6 +188,9 @@ typedef enum {
|
|
XBMCVK_LAUNCH_APP2 = 0xC1,
|
|
XBMCVK_LAUNCH_FILE_BROWSER = 0xC2,
|
|
XBMCVK_LAUNCH_MEDIA_CENTER = 0xC3,
|
|
+ XBMCVK_MEDIA_RECORD = 0xC4,
|
|
+ XBMCVK_MEDIA_REWIND = 0xC5,
|
|
+ XBMCVK_MEDIA_FASTFORWARD = 0xC6,
|
|
|
|
XBMCVK_LCONTROL = 0xD0,
|
|
XBMCVK_RCONTROL = 0xD1,
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From de2b2ba8265aba77dee620d279a61da8d3b87a61 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sat, 10 Aug 2013 15:53:45 +0200
|
|
Subject: [PATCH 70/93] X11: squash multi
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index df5fe9b..d8e04d6 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -437,7 +437,7 @@ void CWinSystemX11::GetConnectedOutputs(std::vector<CStdString> *outputs)
|
|
|
|
bool CWinSystemX11::IsCurrentOutput(CStdString output)
|
|
{
|
|
- return m_currentOutput.Equals(output);
|
|
+ return output.Equals("Default") || m_currentOutput.Equals(output);
|
|
}
|
|
|
|
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From cf58d7d9830ee42813d1f7e7103fed4106d34d74 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 3 Sep 2013 20:46:17 +0200
|
|
Subject: [PATCH 71/93] X11: do not poll default monitor
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index d8e04d6..01f5272 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -722,7 +722,7 @@ void CWinSystemX11::NotifyXRREvent(bool poll)
|
|
if (poll)
|
|
{
|
|
CStdString output = CSettings::Get().GetString("videoscreen.monitor");
|
|
- if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default"))
|
|
+ if (output.Equals(m_currentOutput) || output.Equals("Default"))
|
|
return;
|
|
|
|
int numScreens = XScreenCount(m_dpy);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 21110ddf412223af1991542b1c5573da683f99a7 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 29 Oct 2013 20:57:28 +0100
|
|
Subject: [PATCH 72/93] X11: fix broken monitor switching
|
|
|
|
---
|
|
system/settings/settings.xml | 1 -
|
|
xbmc/settings/DisplaySettings.cpp | 40 ++++++++++++++++++++++++++-------------
|
|
2 files changed, 27 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
|
|
index fafabf4..b13829b 100644
|
|
--- a/system/settings/settings.xml
|
|
+++ b/system/settings/settings.xml
|
|
@@ -2303,7 +2303,6 @@
|
|
<dependency type="enable" setting="videoscreen.screen" operator="!is">-1</dependency> <!-- DM_WINDOWED -->
|
|
<dependency type="update" setting="videoscreen.screen" />
|
|
<dependency type="update" setting="videoscreen.resolution" />
|
|
- <dependency type="update" setting="videoscreen.monitor" />
|
|
</dependencies>
|
|
<control type="spinner" format="string" delayed="true" />
|
|
</setting>
|
|
diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp
|
|
index 40bc3b3..1663836 100644
|
|
--- a/xbmc/settings/DisplaySettings.cpp
|
|
+++ b/xbmc/settings/DisplaySettings.cpp
|
|
@@ -219,19 +219,13 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
|
|
const std::string &settingId = setting->GetId();
|
|
if (settingId == "videoscreen.resolution" ||
|
|
- settingId == "videoscreen.screen" ||
|
|
- settingId == "videoscreen.monitor")
|
|
+ settingId == "videoscreen.screen")
|
|
{
|
|
RESOLUTION newRes = RES_DESKTOP;
|
|
if (settingId == "videoscreen.resolution")
|
|
newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue();
|
|
else if (settingId == "videoscreen.screen")
|
|
newRes = GetResolutionForScreen();
|
|
- else if (settingId == "videoscreen.monitor")
|
|
- {
|
|
- g_Windowing.UpdateResolutions();
|
|
- newRes = GetResolutionForScreen();
|
|
- }
|
|
|
|
string screenmode = GetStringFromResolution(newRes);
|
|
CSettings::Get().SetString("videoscreen.screenmode", screenmode);
|
|
@@ -242,11 +236,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue());
|
|
|
|
SetCurrentResolution(newRes, false);
|
|
- bool outputChanged = false;
|
|
-#if defined(HAS_GLX)
|
|
- outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor"));
|
|
-#endif
|
|
- g_graphicsContext.SetVideoResolution(newRes, outputChanged);
|
|
+ g_graphicsContext.SetVideoResolution(newRes);
|
|
|
|
// check if the old or the new resolution was/is windowed
|
|
// in which case we don't show any prompt to the user
|
|
@@ -265,6 +255,28 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
|
|
m_resolutionChangeAborted = false;
|
|
}
|
|
}
|
|
+ else if (settingId == "videoscreen.monitor")
|
|
+ {
|
|
+ g_Windowing.UpdateResolutions();
|
|
+ RESOLUTION newRes = GetResolutionForScreen();
|
|
+
|
|
+ SetCurrentResolution(newRes, false);
|
|
+ g_graphicsContext.SetVideoResolution(newRes, true);
|
|
+
|
|
+ if (!m_resolutionChangeAborted)
|
|
+ {
|
|
+ bool cancelled = false;
|
|
+ if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
|
|
+ {
|
|
+ m_resolutionChangeAborted = true;
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ m_resolutionChangeAborted = false;
|
|
+
|
|
+ return true;
|
|
+ }
|
|
else if (settingId == "videoscreen.monitorsingle")
|
|
{
|
|
g_Windowing.UpdateResolutions();
|
|
@@ -688,9 +700,11 @@ void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std
|
|
#if defined(HAS_GLX)
|
|
std::vector<CStdString> monitors;
|
|
g_Windowing.GetConnectedOutputs(&monitors);
|
|
+ std::string currentMonitor = CSettings::Get().GetString("videoscreen.monitor");
|
|
for (unsigned int i=0; i<monitors.size(); ++i)
|
|
{
|
|
- if(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput.Equals(monitors[i]))
|
|
+ if(currentMonitor.compare("Default") != 0 &&
|
|
+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput.Equals(monitors[i]))
|
|
{
|
|
current = monitors[i];
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From e95d85f22fecbc71b04569a4ceafe4971a0e5ba0 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 29 Oct 2013 20:57:59 +0100
|
|
Subject: [PATCH 73/93] X11: remove polling for connected outputs, use xrr
|
|
events
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 44 +++++++++++----------
|
|
xbmc/windowing/WinEventsX11.h | 1 -
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 76 ++++++++++++++-----------------------
|
|
xbmc/windowing/X11/WinSystemX11.h | 8 ++--
|
|
4 files changed, 58 insertions(+), 71 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index a38890c..fe91a2b 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
WinEvents->m_structureChanged = false;
|
|
WinEvents->m_xrrEventPending = false;
|
|
- WinEvents->m_xrrPollTimer.Set(3000);
|
|
|
|
// open input method
|
|
char *old_locale = NULL, *old_modifiers = NULL;
|
|
@@ -280,7 +279,11 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win)
|
|
#if defined(HAS_XRANDR)
|
|
int iReturn;
|
|
XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn);
|
|
- XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask);
|
|
+ int numScreens = XScreenCount(WinEvents->m_display);
|
|
+ for (int i = 0; i < numScreens; i++)
|
|
+ {
|
|
+ XRRSelectInput(WinEvents->m_display, RootWindow(WinEvents->m_display, i), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask);
|
|
+ }
|
|
#endif
|
|
|
|
return true;
|
|
@@ -328,6 +331,26 @@ bool CWinEventsX11Imp::MessagePump()
|
|
memset(&xevent, 0, sizeof (XEvent));
|
|
XNextEvent(WinEvents->m_display, &xevent);
|
|
|
|
+#if defined(HAS_XRANDR)
|
|
+ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify))
|
|
+ {
|
|
+ XRRUpdateConfiguration(&xevent);
|
|
+ if (xevent.xgeneric.serial != serial)
|
|
+ g_Windowing.NotifyXRREvent();
|
|
+ WinEvents->m_xrrEventPending = false;
|
|
+ serial = xevent.xgeneric.serial;
|
|
+ continue;
|
|
+ }
|
|
+ else if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRNotify))
|
|
+ {
|
|
+ if (xevent.xgeneric.serial != serial)
|
|
+ g_Windowing.NotifyXRREvent();
|
|
+ WinEvents->m_xrrEventPending = false;
|
|
+ serial = xevent.xgeneric.serial;
|
|
+ continue;
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (XFilterEvent(&xevent, WinEvents->m_window))
|
|
continue;
|
|
|
|
@@ -575,18 +598,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
break;
|
|
}
|
|
}// switch event.type
|
|
-
|
|
-#if defined(HAS_XRANDR)
|
|
- if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify))
|
|
- {
|
|
- XRRUpdateConfiguration(&xevent);
|
|
- if (xevent.xgeneric.serial != serial)
|
|
- g_Windowing.NotifyXRREvent();
|
|
- WinEvents->m_xrrEventPending = false;
|
|
- serial = xevent.xgeneric.serial;
|
|
- }
|
|
-#endif
|
|
-
|
|
}// while
|
|
|
|
#if defined(HAS_XRANDR)
|
|
@@ -596,11 +607,6 @@ bool CWinEventsX11Imp::MessagePump()
|
|
g_Windowing.NotifyXRREvent();
|
|
WinEvents->m_xrrEventPending = false;
|
|
}
|
|
- else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast())
|
|
- {
|
|
- g_Windowing.NotifyXRREvent(true);
|
|
- WinEvents->m_xrrPollTimer.Set(3000);
|
|
- }
|
|
#endif
|
|
|
|
#ifdef HAS_SDL_JOYSTICK
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index 91a604f..6429291 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -62,6 +62,5 @@ protected:
|
|
bool m_structureChanged;
|
|
int m_RREventBase;
|
|
XbmcThreads::EndTime m_xrrFailSafeTimer;
|
|
- XbmcThreads::EndTime m_xrrPollTimer;
|
|
bool m_xrrEventPending;
|
|
};
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 01f5272..442efa6 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -168,8 +168,21 @@ bool CWinSystemX11::DestroyWindow()
|
|
|
|
bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
|
|
{
|
|
+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
+ if (m_userOutput.compare("Default") == 0)
|
|
+ {
|
|
+ std::vector<XOutput> outputs = g_xrandr.GetModes();
|
|
+ if (outputs.size() > 0)
|
|
+ {
|
|
+ m_userOutput = outputs[0].name;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ m_userOutput = g_xrandr.GetModes()[0].name;
|
|
+
|
|
if(m_nWidth == newWidth
|
|
- && m_nHeight == newHeight)
|
|
+ && m_nHeight == newHeight
|
|
+ && m_userOutput.compare(m_currentOutput) == 0)
|
|
return true;
|
|
|
|
if (!SetWindow(newWidth, newHeight, false, m_userOutput))
|
|
@@ -255,33 +268,23 @@ void CWinSystemX11::UpdateResolutions()
|
|
|
|
bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle");
|
|
m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
- if (m_userOutput.Equals("Default"))
|
|
+ if (m_userOutput.compare("Default") == 0)
|
|
switchOnOff = false;
|
|
|
|
if(g_xrandr.Query(true, !switchOnOff))
|
|
{
|
|
- // check if the monitor is connected
|
|
- // might take a while when connected to a receiver
|
|
- XbmcThreads::EndTime timeout(3000);
|
|
XOutput *out = NULL;
|
|
- while (!m_userOutput.Equals("Default") && !timeout.IsTimePast())
|
|
+ if (m_userOutput.compare("Default") != 0)
|
|
{
|
|
out = g_xrandr.GetOutput(m_userOutput);
|
|
if (out)
|
|
{
|
|
XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
- if (mode.isCurrent || switchOnOff)
|
|
- break;
|
|
- else
|
|
+ if (!mode.isCurrent && !switchOnOff)
|
|
{
|
|
out = NULL;
|
|
- break;
|
|
}
|
|
}
|
|
-
|
|
- Sleep(500);
|
|
- if (!g_xrandr.Query(true, !switchOnOff))
|
|
- break;
|
|
}
|
|
if (!out)
|
|
{
|
|
@@ -289,17 +292,16 @@ void CWinSystemX11::UpdateResolutions()
|
|
out = g_xrandr.GetOutput(m_userOutput);
|
|
}
|
|
|
|
- // switch on output
|
|
- if(switchOnOff)
|
|
- g_xrandr.TurnOnOutput(m_userOutput);
|
|
-
|
|
- // switch off other outputs if desired
|
|
if (switchOnOff)
|
|
{
|
|
+ // switch on output
|
|
+ g_xrandr.TurnOnOutput(m_userOutput);
|
|
+
|
|
+ // switch off other outputs
|
|
std::vector<XOutput> outputs = g_xrandr.GetModes();
|
|
for (int i=0; i<outputs.size(); i++)
|
|
{
|
|
- if (outputs[i].name.Equals(m_userOutput))
|
|
+ if (outputs[i].name.Equals(m_userOutput.c_str()))
|
|
continue;
|
|
g_xrandr.TurnOffOutput(outputs[i].name);
|
|
}
|
|
@@ -437,7 +439,7 @@ void CWinSystemX11::GetConnectedOutputs(std::vector<CStdString> *outputs)
|
|
|
|
bool CWinSystemX11::IsCurrentOutput(CStdString output)
|
|
{
|
|
- return output.Equals("Default") || m_currentOutput.Equals(output);
|
|
+ return (output.Equals("Default")) || (m_currentOutput.compare(output) == 0);
|
|
}
|
|
|
|
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo)
|
|
@@ -715,34 +717,14 @@ void CWinSystemX11::CheckDisplayEvents()
|
|
#endif
|
|
}
|
|
|
|
-void CWinSystemX11::NotifyXRREvent(bool poll)
|
|
+void CWinSystemX11::NotifyXRREvent()
|
|
{
|
|
- // we may not get an event if desired monitor becomes available
|
|
- // hence we need to poll
|
|
- if (poll)
|
|
- {
|
|
- CStdString output = CSettings::Get().GetString("videoscreen.monitor");
|
|
- if (output.Equals(m_currentOutput) || output.Equals("Default"))
|
|
- return;
|
|
-
|
|
- int numScreens = XScreenCount(m_dpy);
|
|
- g_xrandr.SetNumScreens(numScreens);
|
|
- g_xrandr.Query(true);
|
|
- if (!g_xrandr.IsOutputConnected(output))
|
|
- return;
|
|
-
|
|
- // if output is turned off by user, respect it
|
|
- XMode mode = g_xrandr.GetCurrentMode(output);
|
|
- if (!mode.isCurrent)
|
|
- return;
|
|
- }
|
|
-
|
|
- CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll);
|
|
+ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
|
|
m_windowDirty = true;
|
|
|
|
CSingleLock lock(g_graphicsContext);
|
|
|
|
- if (!g_xrandr.Query(!poll))
|
|
+ if (!g_xrandr.Query(true))
|
|
{
|
|
CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr");
|
|
return;
|
|
@@ -839,14 +821,14 @@ bool CWinSystemX11::EnableFrameLimiter()
|
|
return m_minimized;
|
|
}
|
|
|
|
-bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output)
|
|
+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output)
|
|
{
|
|
bool changeWindow = false;
|
|
bool changeSize = false;
|
|
bool mouseActive = false;
|
|
float mouseX, mouseY;
|
|
|
|
- if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty))
|
|
+ if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty))
|
|
{
|
|
mouseActive = g_Mouse.IsActive();
|
|
if (mouseActive)
|
|
@@ -1035,7 +1017,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd
|
|
m_bIsGrabbed = false;
|
|
|
|
CDirtyRegionList dr;
|
|
- RefreshGlxContext(!m_currentOutput.Equals(output));
|
|
+ RefreshGlxContext(m_currentOutput.compare(output) != 0);
|
|
XSync(m_dpy, FALSE);
|
|
g_graphicsContext.Clear(0);
|
|
g_graphicsContext.Flip(dr);
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 7ec5be4..14622cb 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -70,7 +70,7 @@ public:
|
|
Display* GetDisplay() { return m_dpy; }
|
|
GLXWindow GetWindow() { return m_glWindow; }
|
|
GLXContext GetGlxContext() { return m_glContext; }
|
|
- void NotifyXRREvent(bool poll = false);
|
|
+ void NotifyXRREvent();
|
|
void GetConnectedOutputs(std::vector<CStdString> *outputs);
|
|
bool IsCurrentOutput(CStdString output);
|
|
void NotifyMouseCoverage(bool covered);
|
|
@@ -79,7 +79,7 @@ protected:
|
|
bool RefreshGlxContext(bool force);
|
|
void CheckDisplayEvents();
|
|
void OnLostDevice();
|
|
- bool SetWindow(int width, int height, bool fullscreen, const CStdString &output);
|
|
+ bool SetWindow(int width, int height, bool fullscreen, const std::string &output);
|
|
|
|
Window m_glWindow, m_mainWindow;
|
|
GLXContext m_glContext;
|
|
@@ -95,8 +95,8 @@ protected:
|
|
CCriticalSection m_resourceSection;
|
|
std::vector<IDispResource*> m_resources;
|
|
uint64_t m_dpyLostTime;
|
|
- CStdString m_currentOutput;
|
|
- CStdString m_userOutput;
|
|
+ std::string m_currentOutput;
|
|
+ std::string m_userOutput;
|
|
bool m_windowDirty;
|
|
bool m_bIsInternalXrr;
|
|
bool m_newGlContext;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 953a0ecd6ee55b1ef2842bb92d35e4e874f6b859 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 31 Oct 2013 09:37:13 +0100
|
|
Subject: [PATCH 74/93] X11: remove grabbing of keyboard and mouse
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 4 ----
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 40 -------------------------------------
|
|
xbmc/windowing/X11/WinSystemX11.h | 2 --
|
|
3 files changed, 46 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index fe91a2b..550c84d 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -538,16 +538,12 @@ bool CWinEventsX11Imp::MessagePump()
|
|
|
|
case EnterNotify:
|
|
{
|
|
- if (xevent.xcrossing.mode == NotifyNormal)
|
|
- g_Windowing.NotifyMouseCoverage(true);
|
|
break;
|
|
}
|
|
|
|
// lose mouse coverage
|
|
case LeaveNotify:
|
|
{
|
|
- if (xevent.xcrossing.mode == NotifyNormal)
|
|
- g_Windowing.NotifyMouseCoverage(false);
|
|
g_Mouse.SetActive(false);
|
|
break;
|
|
}
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 442efa6..695b352 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -153,8 +153,6 @@ bool CWinSystemX11::DestroyWindow()
|
|
|
|
XUnmapWindow(m_dpy, m_mainWindow);
|
|
XSync(m_dpy,TRUE);
|
|
- XUngrabKeyboard(m_dpy, CurrentTime);
|
|
- XUngrabPointer(m_dpy, CurrentTime);
|
|
XDestroyWindow(m_dpy, m_glWindow);
|
|
XDestroyWindow(m_dpy, m_mainWindow);
|
|
m_glWindow = 0;
|
|
@@ -628,30 +626,6 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining)
|
|
m_bIgnoreNextFocusMessage = false;
|
|
}
|
|
|
|
-void CWinSystemX11::NotifyMouseCoverage(bool covered)
|
|
-{
|
|
- if (!m_bFullScreen || !m_mainWindow)
|
|
- return;
|
|
-
|
|
- if (covered && !m_bIsGrabbed)
|
|
- {
|
|
- int result = -1;
|
|
- while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
- {
|
|
- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
- XbmcThreads::ThreadSleep(100);
|
|
- }
|
|
- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
- m_bIsGrabbed = true;
|
|
- }
|
|
- else if (!covered && m_bIsGrabbed)
|
|
- {
|
|
- XUngrabKeyboard(m_dpy, CurrentTime);
|
|
- XUngrabPointer(m_dpy, CurrentTime);
|
|
- m_bIsGrabbed = false;
|
|
- }
|
|
-}
|
|
-
|
|
bool CWinSystemX11::Minimize()
|
|
{
|
|
m_bWasFullScreenBeforeMinimize = m_bFullScreen;
|
|
@@ -1002,20 +976,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
|
|
XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height);
|
|
}
|
|
|
|
- if (fullscreen)
|
|
- {
|
|
- int result = -1;
|
|
- while (result != GrabSuccess && result != AlreadyGrabbed)
|
|
- {
|
|
- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
|
- XbmcThreads::ThreadSleep(100);
|
|
- }
|
|
- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
- m_bIsGrabbed = true;
|
|
- }
|
|
- else
|
|
- m_bIsGrabbed = false;
|
|
-
|
|
CDirtyRegionList dr;
|
|
RefreshGlxContext(m_currentOutput.compare(output) != 0);
|
|
XSync(m_dpy, FALSE);
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h
|
|
index 14622cb..d1c8729 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.h
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.h
|
|
@@ -73,7 +73,6 @@ public:
|
|
void NotifyXRREvent();
|
|
void GetConnectedOutputs(std::vector<CStdString> *outputs);
|
|
bool IsCurrentOutput(CStdString output);
|
|
- void NotifyMouseCoverage(bool covered);
|
|
|
|
protected:
|
|
bool RefreshGlxContext(bool force);
|
|
@@ -90,7 +89,6 @@ protected:
|
|
bool m_bWasFullScreenBeforeMinimize;
|
|
bool m_minimized;
|
|
bool m_bIgnoreNextFocusMessage;
|
|
- bool m_bIsGrabbed;
|
|
int m_RREventBase;
|
|
CCriticalSection m_resourceSection;
|
|
std::vector<IDispResource*> m_resources;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 039e80014380b831d46199301999e27b1d40df96 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 31 Oct 2013 10:46:40 +0100
|
|
Subject: [PATCH 75/93] X11: set ExposureMask on gl window, fixes not updated
|
|
areas
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 695b352..e55583c 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -884,8 +884,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
|
|
|
|
swa.override_redirect = False;
|
|
swa.border_pixel = 0;
|
|
- swa.event_mask = 0;
|
|
- mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap;
|
|
+ swa.event_mask = ExposureMask;
|
|
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask;
|
|
|
|
m_glWindow = XCreateWindow(m_dpy, m_mainWindow,
|
|
0, 0, width, height, 0, vi->depth,
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 4469a824b82534d92692717e6f510a84c816eb46 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 31 Oct 2013 11:25:19 +0100
|
|
Subject: [PATCH 76/93] X11: drop shortcuts, have WM do this
|
|
|
|
---
|
|
xbmc/windowing/WinEventsX11.cpp | 21 ---------------------
|
|
xbmc/windowing/WinEventsX11.h | 1 -
|
|
2 files changed, 22 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp
|
|
index 550c84d..a5b4ba2 100644
|
|
--- a/xbmc/windowing/WinEventsX11.cpp
|
|
+++ b/xbmc/windowing/WinEventsX11.cpp
|
|
@@ -678,10 +678,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event)
|
|
break;
|
|
}
|
|
event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState;
|
|
-
|
|
- bool ret = ProcessShortcuts(event);
|
|
- if (ret)
|
|
- return ret;
|
|
}
|
|
else if (event.type == XBMC_KEYUP)
|
|
{
|
|
@@ -723,23 +719,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event)
|
|
return g_application.OnEvent(event);
|
|
}
|
|
|
|
-bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event)
|
|
-{
|
|
- if (event.key.keysym.mod & XBMCKMOD_ALT)
|
|
- {
|
|
- switch(event.key.keysym.sym)
|
|
- {
|
|
- case XBMCK_TAB: // ALT+TAB to minimize/hide
|
|
- g_application.Minimize();
|
|
- return true;
|
|
-
|
|
- default:
|
|
- return false;
|
|
- }
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym)
|
|
{
|
|
// try direct mapping first
|
|
diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h
|
|
index 6429291..4334d21 100644
|
|
--- a/xbmc/windowing/WinEventsX11.h
|
|
+++ b/xbmc/windowing/WinEventsX11.h
|
|
@@ -48,7 +48,6 @@ public:
|
|
protected:
|
|
static XBMCKey LookupXbmcKeySym(KeySym keysym);
|
|
static bool ProcessKey(XBMC_Event &event);
|
|
- static bool ProcessShortcuts(XBMC_Event& event);
|
|
static CWinEventsX11Imp *WinEvents;
|
|
Display *m_display;
|
|
Window m_window;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 386745d4d1e4ea4b5bde6cfad26b719e45168beb Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 7 Nov 2013 15:02:00 +0100
|
|
Subject: [PATCH 77/93] X11: adapt to new settings
|
|
|
|
---
|
|
system/settings/settings.xml | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
|
|
index b13829b..b756fca 100644
|
|
--- a/system/settings/settings.xml
|
|
+++ b/system/settings/settings.xml
|
|
@@ -2263,6 +2263,7 @@
|
|
<requirement>HAS_GLX</requirement>
|
|
<level>0</level>
|
|
<default>false</default>
|
|
+ <control type="toggle" />
|
|
</setting>
|
|
<setting id="videoscreen.screen" type="integer" label="240" help="36351">
|
|
<level>0</level>
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From c4292a4b8577828802204b56c4fc448dd9bd76f5 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 14 Nov 2013 09:28:24 +0100
|
|
Subject: [PATCH 78/93] X11: adapt to changes in cstdstring
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 4 ++--
|
|
xbmc/windowing/X11/XRandR.cpp | 4 ++--
|
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index e55583c..9962f08 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -369,8 +369,8 @@ void CWinSystemX11::UpdateResolutions()
|
|
|
|
CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio);
|
|
|
|
- res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz);
|
|
- res.strOutput = out.name;
|
|
+ res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz);
|
|
+ res.strOutput = out->name;
|
|
res.strId = mode.id;
|
|
res.iSubtitles = (int)(0.965*mode.h);
|
|
res.fRefreshRate = mode.hz;
|
|
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
|
|
index 8525ede..c94f2e3 100644
|
|
--- a/xbmc/windowing/X11/XRandR.cpp
|
|
+++ b/xbmc/windowing/X11/XRandR.cpp
|
|
@@ -74,7 +74,7 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff)
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
cmd += "/xbmc-xrandr";
|
|
- cmd.AppendFormat(" -q --screen %d", screennum);
|
|
+ cmd = StringUtils::Format("%s -q --screen %d", cmd.c_str(), screennum);
|
|
|
|
FILE* file = popen(cmd.c_str(),"r");
|
|
if (!file)
|
|
@@ -156,7 +156,7 @@ bool CXRandR::TurnOffOutput(CStdString name)
|
|
CStdString cmd;
|
|
cmd = getenv("XBMC_BIN_HOME");
|
|
cmd += "/xbmc-xrandr";
|
|
- cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str());
|
|
+ cmd = StringUtils::Format("%s --screen %d --output %s --off", cmd.c_str(), output->screen, name.c_str());
|
|
|
|
int status = system(cmd.c_str());
|
|
if (status == -1)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 029c809c1c28b7163ab02406668f176f49282626 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Mon, 18 Nov 2013 17:44:31 +0100
|
|
Subject: [PATCH 79/93] ActiveAE: correct time of buffered samples by resample
|
|
ratio
|
|
|
|
---
|
|
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 2 +-
|
|
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 1 +
|
|
2 files changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
|
|
index 6ca2cf4..e2a4b6f 100644
|
|
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
|
|
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
|
|
@@ -102,7 +102,7 @@ float CEngineStats::GetDelay(CActiveAEStream *stream)
|
|
if (delay < 0)
|
|
delay = 0.0;
|
|
|
|
- delay += stream->m_bufferedTime;
|
|
+ delay += stream->m_bufferedTime / stream->m_streamResampleRatio;
|
|
return delay;
|
|
}
|
|
|
|
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
|
|
index 99989b3..0287e73 100644
|
|
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
|
|
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
|
|
@@ -58,6 +58,7 @@ CActiveAEStream::CActiveAEStream(AEAudioFormat *format)
|
|
m_forceResampler = false;
|
|
m_remapper = NULL;
|
|
m_remapBuffer = NULL;
|
|
+ m_streamResampleRatio = 1.0;
|
|
}
|
|
|
|
CActiveAEStream::~CActiveAEStream()
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From f599ea4e785a09cae43ac3e80f9cb5eb576b9eff Mon Sep 17 00:00:00 2001
|
|
From: Marcel Groothuis <margro.xbmc@gmail.com>
|
|
Date: Thu, 5 Dec 2013 22:02:50 +0100
|
|
Subject: [PATCH 80/93] ffmpeg demuxer: faster channel change for PVR addons
|
|
without internal demuxing (such as MediaPortal, ArgusTV, MythTV, NextPVR)
|
|
Credits: FernetMenta, Davilla, Popcornmix, Whaupt
|
|
|
|
---
|
|
.../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 143 ++++++++++++++++++---
|
|
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 5 +-
|
|
.../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 13 +-
|
|
3 files changed, 139 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
index 16efae0..6ebbb6e 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
@@ -51,6 +51,8 @@
|
|
#include "utils/StringUtils.h"
|
|
#include "URL.h"
|
|
|
|
+#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE)
|
|
+
|
|
void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo)
|
|
{
|
|
if(!m_stream) return;
|
|
@@ -217,6 +219,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux()
|
|
m_program = UINT_MAX;
|
|
m_pkt.result = -1;
|
|
memset(&m_pkt.pkt, 0, sizeof(AVPacket));
|
|
+ m_streaminfo = true; /* set to true if we want to look for streams before playback */
|
|
}
|
|
|
|
CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg()
|
|
@@ -237,10 +240,11 @@ bool CDVDDemuxFFmpeg::Aborted()
|
|
return false;
|
|
}
|
|
|
|
-bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
|
+bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo)
|
|
{
|
|
AVInputFormat* iformat = NULL;
|
|
std::string strFile;
|
|
+ m_streaminfo = streaminfo;
|
|
m_iCurrentPts = DVD_NOPTS_VALUE;
|
|
m_speed = DVD_PLAYSPEED_NORMAL;
|
|
m_program = UINT_MAX;
|
|
@@ -259,8 +263,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
|
m_pInput = pInput;
|
|
strFile = m_pInput->GetFileName();
|
|
|
|
- bool streaminfo = true; /* set to true if we want to look for streams before playback*/
|
|
-
|
|
if( m_pInput->GetContent().length() > 0 )
|
|
{
|
|
std::string content = m_pInput->GetContent();
|
|
@@ -450,13 +452,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
|
m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
|
|
m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0;
|
|
|
|
- if (streaminfo)
|
|
+ if (m_streaminfo)
|
|
{
|
|
- /* too speed up dvd switches, only analyse very short */
|
|
+ /* to speed up dvd switches, only analyse very short */
|
|
if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD))
|
|
m_pFormatContext->max_analyze_duration = 500000;
|
|
|
|
-
|
|
CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__);
|
|
int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
|
|
if (iErr < 0)
|
|
@@ -476,6 +477,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
|
|
}
|
|
CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__);
|
|
}
|
|
+ else
|
|
+ m_program = 0;
|
|
+
|
|
// reset any timeout
|
|
m_timeout.SetInfinite();
|
|
|
|
@@ -533,7 +537,7 @@ void CDVDDemuxFFmpeg::Reset()
|
|
{
|
|
CDVDInputStream* pInputStream = m_pInput;
|
|
Dispose();
|
|
- Open(pInputStream);
|
|
+ Open(pInputStream, m_streaminfo);
|
|
}
|
|
|
|
void CDVDDemuxFFmpeg::Flush()
|
|
@@ -728,25 +732,32 @@ DemuxPacket* CDVDDemuxFFmpeg::Read()
|
|
}
|
|
else
|
|
{
|
|
+ ParsePacket(&m_pkt.pkt);
|
|
+
|
|
AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index];
|
|
|
|
- if (m_program != UINT_MAX)
|
|
+ if (IsVideoReady())
|
|
{
|
|
- /* check so packet belongs to selected program */
|
|
- for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
|
|
+ if (m_program != UINT_MAX)
|
|
{
|
|
- if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i])
|
|
+ /* check so packet belongs to selected program */
|
|
+ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
|
|
{
|
|
- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
|
|
- break;
|
|
+ if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i])
|
|
+ {
|
|
+ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
|
|
+ break;
|
|
+ }
|
|
}
|
|
- }
|
|
|
|
- if (!pPacket)
|
|
- bReturnEmpty = true;
|
|
+ if (!pPacket)
|
|
+ bReturnEmpty = true;
|
|
+ }
|
|
+ else
|
|
+ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
|
|
}
|
|
else
|
|
- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
|
|
+ bReturnEmpty = true;
|
|
|
|
if (pPacket)
|
|
{
|
|
@@ -1683,3 +1694,101 @@ bool CDVDDemuxFFmpeg::IsProgramChange()
|
|
}
|
|
return false;
|
|
}
|
|
+
|
|
+void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt)
|
|
+{
|
|
+ AVStream *st = m_pFormatContext->streams[pkt->stream_index];
|
|
+ CDemuxStream *stream = GetStreamInternal(pkt->stream_index);
|
|
+
|
|
+ // if the stream is new, tell ffmpeg to parse the stream
|
|
+ if (!stream && !st->parser)
|
|
+ {
|
|
+ st->need_parsing = AVSTREAM_PARSE_FULL;
|
|
+ }
|
|
+
|
|
+ // split extradata
|
|
+ if(st->parser && st->parser->parser->split && !st->codec->extradata)
|
|
+ {
|
|
+ int i = st->parser->parser->split(st->codec, pkt->data, pkt->size);
|
|
+ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE)
|
|
+ {
|
|
+ // Found extradata, fill it in. This will cause
|
|
+ // a new stream to be created and used.
|
|
+ st->codec->extradata_size = i;
|
|
+ st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
|
+ if (st->codec->extradata)
|
|
+ {
|
|
+ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size);
|
|
+ memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);
|
|
+ memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ st->codec->extradata_size = 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // for video we need a decoder to get desired information into codec context
|
|
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
|
+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
|
|
+ {
|
|
+ // open a decoder, it will be cleared down by ffmpeg on closing the stream
|
|
+ if (!st->codec->codec)
|
|
+ {
|
|
+ const AVCodec* codec;
|
|
+ AVDictionary *thread_opt = NULL;
|
|
+ codec = avcodec_find_decoder(st->codec->codec_id);
|
|
+ // Force thread count to 1 since the h264 decoder will not extract
|
|
+ // SPS and PPS to extradata during multi-threaded decoding
|
|
+ av_dict_set(&thread_opt, "threads", "1", 0);
|
|
+ avcodec_open2(st->codec, codec, &thread_opt);
|
|
+
|
|
+ av_dict_free(&thread_opt);
|
|
+ }
|
|
+
|
|
+ // We don't need to actually decode here
|
|
+ // we just want to transport SPS data into codec context
|
|
+ st->codec->skip_idct = AVDISCARD_ALL;
|
|
+ st->codec->skip_frame = AVDISCARD_ALL;
|
|
+ st->codec->skip_loop_filter = AVDISCARD_ALL;
|
|
+
|
|
+ // We are looking for an IDR frame
|
|
+ AVFrame picture;
|
|
+ memset(&picture, 0, sizeof(AVFrame));
|
|
+ picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE;
|
|
+ picture.pkt_pos = -1;
|
|
+ picture.key_frame = 1;
|
|
+ picture.format = -1;
|
|
+
|
|
+ int got_picture = 0;
|
|
+ avcodec_decode_video2(st->codec, &picture, &got_picture, pkt);
|
|
+ }
|
|
+}
|
|
+
|
|
+bool CDVDDemuxFFmpeg::IsVideoReady()
|
|
+{
|
|
+ AVStream *st;
|
|
+ if(m_program != UINT_MAX)
|
|
+ {
|
|
+ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
|
|
+ {
|
|
+ int idx = m_pFormatContext->programs[m_program]->stream_index[i];
|
|
+ st = m_pFormatContext->streams[idx];
|
|
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
|
+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
|
|
+ {
|
|
+ st = m_pFormatContext->streams[i];
|
|
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
|
+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
index 35abbdf..acde9a8 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
@@ -89,7 +89,7 @@ public:
|
|
CDVDDemuxFFmpeg();
|
|
virtual ~CDVDDemuxFFmpeg();
|
|
|
|
- bool Open(CDVDInputStream* pInput);
|
|
+ bool Open(CDVDInputStream* pInput, bool streaminfo = true);
|
|
void Dispose();
|
|
void Reset();
|
|
void Flush();
|
|
@@ -128,6 +128,8 @@ protected:
|
|
CDemuxStream* GetStreamInternal(int iStreamId);
|
|
void CreateStreams(unsigned int program = UINT_MAX);
|
|
void DisposeStreams();
|
|
+ void ParsePacket(AVPacket *pkt);
|
|
+ bool IsVideoReady();
|
|
|
|
AVDictionary *GetFFMpegOptionsFromURL(const CURL &url);
|
|
double ConvertTimestamp(int64_t pts, int den, int num);
|
|
@@ -162,5 +164,6 @@ protected:
|
|
|
|
bool m_bPtsWrap, m_bPtsWrapChecked;
|
|
int64_t m_iStartTime, m_iMaxTime, m_iEndTime;
|
|
+ bool m_streaminfo;
|
|
};
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
index ca689d0..f383563 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
@@ -99,26 +99,31 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
|
|
}
|
|
#endif
|
|
|
|
+ bool streaminfo = true; /* Look for streams before playback */
|
|
if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER))
|
|
{
|
|
CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream;
|
|
CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream();
|
|
+
|
|
+ /* Don't parse the streaminfo for live streams to reduce the channel switch time */
|
|
+ bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels");
|
|
+ streaminfo = !liveStream;
|
|
+
|
|
if(pOtherStream)
|
|
{
|
|
/* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */
|
|
if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
|
|
{
|
|
auto_ptr<CDVDDemuxFFmpeg> demuxer(new CDVDDemuxFFmpeg());
|
|
- if(demuxer->Open(pOtherStream))
|
|
+ if(demuxer->Open(pOtherStream, streaminfo))
|
|
return demuxer.release();
|
|
else
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
- std::string filename = pInputStream->GetFileName();
|
|
/* Use PVR demuxer only for live streams */
|
|
- if (filename.substr(0, 14) == "pvr://channels")
|
|
+ if (liveStream)
|
|
{
|
|
boost::shared_ptr<CPVRClient> client;
|
|
if (g_PVRClients->GetPlayingClient(client) &&
|
|
@@ -134,7 +139,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
|
|
}
|
|
|
|
auto_ptr<CDVDDemuxFFmpeg> demuxer(new CDVDDemuxFFmpeg());
|
|
- if(demuxer->Open(pInputStream))
|
|
+ if(demuxer->Open(pInputStream, streaminfo))
|
|
return demuxer.release();
|
|
else
|
|
return NULL;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 51bc8b6305c3774d0967737d87abd35e6a4634a9 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Thu, 14 Nov 2013 20:35:04 +0100
|
|
Subject: [PATCH 81/93] ffmpeg demuxer: make sure we start mpegts video with an
|
|
i-frame
|
|
|
|
---
|
|
.../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 31 +++++++++++++++++++++-
|
|
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 +
|
|
2 files changed, 31 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
index 6ebbb6e..782fb3d 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
@@ -448,6 +448,13 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo)
|
|
if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0)
|
|
m_pFormatContext->max_analyze_duration = 500000;
|
|
|
|
+ bool short_analyze = false;
|
|
+ if (iformat && (strcmp(iformat->name, "mpegts") == 0))
|
|
+ {
|
|
+ m_pFormatContext->max_analyze_duration = 500000;
|
|
+ short_analyze = true;
|
|
+ }
|
|
+
|
|
// we need to know if this is matroska or avi later
|
|
m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
|
|
m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0;
|
|
@@ -476,6 +483,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo)
|
|
}
|
|
}
|
|
CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__);
|
|
+
|
|
+ if (short_analyze)
|
|
+ {
|
|
+ // make sure we start video with an i-frame
|
|
+ ResetVideoStreams();
|
|
+ }
|
|
}
|
|
else
|
|
m_program = 0;
|
|
@@ -1730,7 +1743,7 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt)
|
|
}
|
|
|
|
// for video we need a decoder to get desired information into codec context
|
|
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
|
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata &&
|
|
(!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
|
|
{
|
|
// open a decoder, it will be cleared down by ffmpeg on closing the stream
|
|
@@ -1792,3 +1805,19 @@ bool CDVDDemuxFFmpeg::IsVideoReady()
|
|
}
|
|
return true;
|
|
}
|
|
+
|
|
+void CDVDDemuxFFmpeg::ResetVideoStreams()
|
|
+{
|
|
+ AVStream *st;
|
|
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
|
|
+ {
|
|
+ st = m_pFormatContext->streams[i];
|
|
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
|
+ {
|
|
+ if (st->codec->extradata)
|
|
+ m_dllAvUtil.av_free(st->codec->extradata);
|
|
+ st->codec->extradata = NULL;
|
|
+ st->codec->width = 0;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
index acde9a8..9ec0877 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
|
|
@@ -130,6 +130,7 @@ protected:
|
|
void DisposeStreams();
|
|
void ParsePacket(AVPacket *pkt);
|
|
bool IsVideoReady();
|
|
+ void ResetVideoStreams();
|
|
|
|
AVDictionary *GetFFMpegOptionsFromURL(const CURL &url);
|
|
double ConvertTimestamp(int64_t pts, int den, int num);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 24a3fa6f5b58a3c2c9bf4b53a778ca503143c6c6 Mon Sep 17 00:00:00 2001
|
|
From: Wolfgang Haupt <w.haupt@at-visions.com>
|
|
Date: Thu, 5 Dec 2013 22:11:57 +0100
|
|
Subject: [PATCH 82/93] DVDFactoryDemuxer: skip streaminfo for udp tcp and
|
|
pvr-channels
|
|
|
|
---
|
|
.../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 14 ++++++---
|
|
xbmc/utils/URIUtils.cpp | 35 ++++++++++++++++++++++
|
|
xbmc/utils/URIUtils.h | 4 +++
|
|
3 files changed, 49 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
index f383563..d6580fd 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
|
|
@@ -105,9 +105,9 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
|
|
CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream;
|
|
CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream();
|
|
|
|
- /* Don't parse the streaminfo for live streams to reduce the channel switch time */
|
|
- bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels");
|
|
- streaminfo = !liveStream;
|
|
+ /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */
|
|
+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName());
|
|
+ streaminfo = !useFastswitch;
|
|
|
|
if(pOtherStream)
|
|
{
|
|
@@ -123,7 +123,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
|
|
}
|
|
|
|
/* Use PVR demuxer only for live streams */
|
|
- if (liveStream)
|
|
+ if (URIUtils::IsPVRChannel(pInputStream->GetFileName()))
|
|
{
|
|
boost::shared_ptr<CPVRClient> client;
|
|
if (g_PVRClients->GetPlayingClient(client) &&
|
|
@@ -138,6 +138,12 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
|
|
}
|
|
}
|
|
|
|
+ if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
|
|
+ {
|
|
+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName());
|
|
+ streaminfo = !useFastswitch;
|
|
+ }
|
|
+
|
|
auto_ptr<CDVDDemuxFFmpeg> demuxer(new CDVDDemuxFFmpeg());
|
|
if(demuxer->Open(pInputStream, streaminfo))
|
|
return demuxer.release();
|
|
diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
|
|
index 12dadba..bca61a1 100644
|
|
--- a/xbmc/utils/URIUtils.cpp
|
|
+++ b/xbmc/utils/URIUtils.cpp
|
|
@@ -788,6 +788,36 @@ bool URIUtils::IsFTP(const CStdString& strFile)
|
|
StringUtils::StartsWithNoCase(strFile2, "ftps:");
|
|
}
|
|
|
|
+bool URIUtils::IsUDP(const CStdString& strFile)
|
|
+{
|
|
+ CStdString strFile2(strFile);
|
|
+
|
|
+ if (IsStack(strFile))
|
|
+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
|
|
+
|
|
+ return StringUtils::StartsWithNoCase(strFile2, "udp:");
|
|
+}
|
|
+
|
|
+bool URIUtils::IsTCP(const CStdString& strFile)
|
|
+{
|
|
+ CStdString strFile2(strFile);
|
|
+
|
|
+ if (IsStack(strFile))
|
|
+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
|
|
+
|
|
+ return StringUtils::StartsWithNoCase(strFile2, "tcp:");
|
|
+}
|
|
+
|
|
+bool URIUtils::IsPVRChannel(const CStdString& strFile)
|
|
+{
|
|
+ CStdString strFile2(strFile);
|
|
+
|
|
+ if (IsStack(strFile))
|
|
+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
|
|
+
|
|
+ return StringUtils::StartsWithNoCase(strFile2, "pvr://channels");
|
|
+}
|
|
+
|
|
bool URIUtils::IsDAV(const CStdString& strFile)
|
|
{
|
|
CStdString strFile2(strFile);
|
|
@@ -1285,3 +1315,8 @@ bool URIUtils::UpdateUrlEncoding(std::string &strFilename)
|
|
strFilename = newFilename;
|
|
return true;
|
|
}
|
|
+
|
|
+bool URIUtils::IsUsingFastSwitch(const CStdString& strFile)
|
|
+{
|
|
+ return IsUDP(strFile) || IsTCP(strFile) || IsPVRChannel(strFile);
|
|
+}
|
|
diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h
|
|
index b94e94c..b45630f 100644
|
|
--- a/xbmc/utils/URIUtils.h
|
|
+++ b/xbmc/utils/URIUtils.h
|
|
@@ -88,6 +88,8 @@ public:
|
|
static bool IsDOSPath(const CStdString &path);
|
|
static bool IsDVD(const CStdString& strFile);
|
|
static bool IsFTP(const CStdString& strFile);
|
|
+ static bool IsUDP(const CStdString& strFile);
|
|
+ static bool IsTCP(const CStdString& strFile);
|
|
static bool IsHD(const CStdString& strFileName);
|
|
static bool IsHDHomeRun(const CStdString& strFile);
|
|
static bool IsSlingbox(const CStdString& strFile);
|
|
@@ -127,6 +129,8 @@ public:
|
|
static bool IsAndroidApp(const CStdString& strFile);
|
|
static bool IsLibraryFolder(const CStdString& strFile);
|
|
static bool IsLibraryContent(const std::string& strFile);
|
|
+ static bool IsPVRChannel(const CStdString& strFile);
|
|
+ static bool IsUsingFastSwitch(const CStdString& strFile);
|
|
|
|
static void AddSlashAtEnd(std::string& strFolder);
|
|
static bool HasSlashAtEnd(const std::string& strFile, bool checkURL = false);
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 93d15cd098d70bdc0629d6e550f27877ab0dd63e Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 28 Jan 2014 08:43:29 +0100
|
|
Subject: [PATCH 83/93] squash fast switch
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
index 782fb3d..b57b391 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
|
|
@@ -1815,7 +1815,7 @@ void CDVDDemuxFFmpeg::ResetVideoStreams()
|
|
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
|
{
|
|
if (st->codec->extradata)
|
|
- m_dllAvUtil.av_free(st->codec->extradata);
|
|
+ av_free(st->codec->extradata);
|
|
st->codec->extradata = NULL;
|
|
st->codec->width = 0;
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 1228259650fdf7fd118787abf1f6c934c46097d6 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sun, 9 Mar 2014 00:15:35 +0200
|
|
Subject: [PATCH 84/93] linux: add shared lib for sse4 operations
|
|
|
|
Conflicts:
|
|
configure.in
|
|
---
|
|
Makefile.in | 8 ++-
|
|
configure.in | 18 +++++++
|
|
xbmc/DllPaths_generated.h.in | 3 ++
|
|
xbmc/linux/sse4/CopyFrame.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++
|
|
xbmc/linux/sse4/DllLibSSE4.h | 43 ++++++++++++++++
|
|
xbmc/linux/sse4/Makefile.in | 20 ++++++++
|
|
6 files changed, 206 insertions(+), 1 deletion(-)
|
|
create mode 100644 xbmc/linux/sse4/CopyFrame.cpp
|
|
create mode 100644 xbmc/linux/sse4/DllLibSSE4.h
|
|
create mode 100644 xbmc/linux/sse4/Makefile.in
|
|
|
|
diff --git a/Makefile.in b/Makefile.in
|
|
index 8eda3c4..b0b5c24 100644
|
|
--- a/Makefile.in
|
|
+++ b/Makefile.in
|
|
@@ -317,6 +317,12 @@ CHECK_LIBADD=@WAYLAND_TEST_LIBS@
|
|
endif
|
|
endif
|
|
|
|
+ifeq (@USE_SSE4@,1)
|
|
+LIBSSE4+=sse4
|
|
+sse4 : force
|
|
+ $(MAKE) -C xbmc/linux/sse4
|
|
+endif
|
|
+
|
|
CHECK_PROGRAMS = xbmc-test
|
|
|
|
CLEAN_FILES += $(CHECK_PROGRAMS) $(CHECK_EXTENSIONS)
|
|
@@ -446,7 +452,7 @@ endif
|
|
|
|
codecs: papcodecs dvdpcodecs dvdpextcodecs
|
|
|
|
-libs: libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH)
|
|
+libs: $(LIBSSE4) libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH)
|
|
|
|
externals: codecs libs visualizations screensavers libaddon pvraddons
|
|
|
|
diff --git a/configure.in b/configure.in
|
|
index 1cd6b2e..8756b20 100644
|
|
--- a/configure.in
|
|
+++ b/configure.in
|
|
@@ -883,6 +883,19 @@ if test "$use_static_ffmpeg" = "yes"; then
|
|
VORBISENC_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc`
|
|
fi
|
|
|
|
+use_sse4=no
|
|
+if test "$ARCH" = "x86_64-linux" || test "$ARCH" = "i486-linux"; then
|
|
+ SAVE_CFLAGS="$CFLAGS"
|
|
+ CFLAGS="-msse4.1"
|
|
+ AC_COMPILE_IFELSE(
|
|
+ [AC_LANG_SOURCE([int foo;])],
|
|
+ [ use_sse4=yes
|
|
+ USE_SSE4=1],
|
|
+ [ use_sse=no
|
|
+ USE_SSE4=0])
|
|
+ CFLAGS="$SAVE_CFLAGS"
|
|
+fi
|
|
+
|
|
# Checks for library functions.
|
|
AC_FUNC_ALLOCA
|
|
AC_FUNC_CHOWN
|
|
@@ -2591,6 +2604,10 @@ if test "$use_codec_libstagefright" = "yes"; then
|
|
OUTPUT_FILES="$OUTPUT_FILES xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile"
|
|
fi
|
|
|
|
+if test "$use_sse4" = "yes"; then
|
|
+OUTPUT_FILES="$OUTPUT_FILES xbmc/linux/sse4/Makefile"
|
|
+fi
|
|
+
|
|
OUTPUT_FILES="$OUTPUT_FILES \
|
|
xbmc/interfaces/python/Makefile \
|
|
xbmc/interfaces/python/test/Makefile"
|
|
@@ -2669,6 +2686,7 @@ AC_SUBST(USE_DOXYGEN)
|
|
AC_SUBST(USE_PVR_ADDONS)
|
|
AC_SUBST(GNUTLS_ALL_LIBS)
|
|
AC_SUBST(VORBISENC_ALL_LIBS)
|
|
+AC_SUBST(USE_SSE4)
|
|
|
|
# pushd and popd are not available in other shells besides bash, so implement
|
|
# our own pushd/popd functions
|
|
diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in
|
|
index d35ea97..3bf8f96 100644
|
|
--- a/xbmc/DllPaths_generated.h.in
|
|
+++ b/xbmc/DllPaths_generated.h.in
|
|
@@ -104,4 +104,7 @@
|
|
/* xkbcommon */
|
|
#define DLL_PATH_XKBCOMMON "@XKBCOMMON_LIBRARY_SONAME@"
|
|
|
|
+/* sse4 */
|
|
+#define DLL_PATH_LIBSSE4 "special://xbmcbin/system/libsse4-@ARCH@.so"
|
|
+
|
|
#endif
|
|
diff --git a/xbmc/linux/sse4/CopyFrame.cpp b/xbmc/linux/sse4/CopyFrame.cpp
|
|
new file mode 100644
|
|
index 0000000..6d23d83
|
|
--- /dev/null
|
|
+++ b/xbmc/linux/sse4/CopyFrame.cpp
|
|
@@ -0,0 +1,115 @@
|
|
+/*
|
|
+ * Copyright (C) 2005-2013 Team XBMC
|
|
+ * http://xbmc.org
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library 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
|
|
+ * Lesser 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
|
|
+ * <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "smmintrin.h"
|
|
+
|
|
+#define CACHED_BUFFER_SIZE 4096
|
|
+typedef unsigned int UINT;
|
|
+
|
|
+extern "C"
|
|
+{
|
|
+
|
|
+/*
|
|
+ * http://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers
|
|
+ * COPIES VIDEO FRAMES FROM USWC MEMORY TO WB SYSTEM MEMORY VIA CACHED BUFFER
|
|
+ * ASSUMES PITCH IS A MULTIPLE OF 64B CACHE LINE SIZE, WIDTH MAY NOT BE
|
|
+ */
|
|
+void copy_frame( void * pSrc, void * pDest, void * pCacheBlock,
|
|
+ UINT width, UINT height, UINT pitch )
|
|
+{
|
|
+ __m128i x0, x1, x2, x3;
|
|
+ __m128i *pLoad;
|
|
+ __m128i *pStore;
|
|
+ __m128i *pCache;
|
|
+ UINT x, y, yLoad, yStore;
|
|
+ UINT rowsPerBlock;
|
|
+ UINT width64;
|
|
+ UINT extraPitch;
|
|
+
|
|
+
|
|
+ rowsPerBlock = CACHED_BUFFER_SIZE / pitch;
|
|
+ width64 = (width + 63) & ~0x03f;
|
|
+ extraPitch = (pitch - width64) / 16;
|
|
+
|
|
+ pLoad = (__m128i *)pSrc;
|
|
+ pStore = (__m128i *)pDest;
|
|
+
|
|
+ // COPY THROUGH 4KB CACHED BUFFER
|
|
+ for( y = 0; y < height; y += rowsPerBlock )
|
|
+ {
|
|
+ // ROWS LEFT TO COPY AT END
|
|
+ if( y + rowsPerBlock > height )
|
|
+ rowsPerBlock = height - y;
|
|
+
|
|
+ pCache = (__m128i *)pCacheBlock;
|
|
+
|
|
+ _mm_mfence();
|
|
+
|
|
+ // LOAD ROWS OF PITCH WIDTH INTO CACHED BLOCK
|
|
+ for( yLoad = 0; yLoad < rowsPerBlock; yLoad++ )
|
|
+ {
|
|
+ // COPY A ROW, CACHE LINE AT A TIME
|
|
+ for( x = 0; x < pitch; x +=64 )
|
|
+ {
|
|
+ x0 = _mm_stream_load_si128( pLoad +0 );
|
|
+ x1 = _mm_stream_load_si128( pLoad +1 );
|
|
+ x2 = _mm_stream_load_si128( pLoad +2 );
|
|
+ x3 = _mm_stream_load_si128( pLoad +3 );
|
|
+
|
|
+ _mm_store_si128( pCache +0, x0 );
|
|
+ _mm_store_si128( pCache +1, x1 );
|
|
+ _mm_store_si128( pCache +2, x2 );
|
|
+ _mm_store_si128( pCache +3, x3 );
|
|
+
|
|
+ pCache += 4;
|
|
+ pLoad += 4;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ _mm_mfence();
|
|
+
|
|
+ pCache = (__m128i *)pCacheBlock;
|
|
+
|
|
+ // STORE ROWS OF FRAME WIDTH FROM CACHED BLOCK
|
|
+ for( yStore = 0; yStore < rowsPerBlock; yStore++ )
|
|
+ {
|
|
+ // copy a row, cache line at a time
|
|
+ for( x = 0; x < width64; x +=64 )
|
|
+ {
|
|
+ x0 = _mm_load_si128( pCache );
|
|
+ x1 = _mm_load_si128( pCache +1 );
|
|
+ x2 = _mm_load_si128( pCache +2 );
|
|
+ x3 = _mm_load_si128( pCache +3 );
|
|
+
|
|
+ _mm_stream_si128( pStore, x0 );
|
|
+ _mm_stream_si128( pStore +1, x1 );
|
|
+ _mm_stream_si128( pStore +2, x2 );
|
|
+ _mm_stream_si128( pStore +3, x3 );
|
|
+
|
|
+ pCache += 4;
|
|
+ pStore += 4;
|
|
+ }
|
|
+
|
|
+ pCache += extraPitch;
|
|
+ pStore += extraPitch;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+}
|
|
diff --git a/xbmc/linux/sse4/DllLibSSE4.h b/xbmc/linux/sse4/DllLibSSE4.h
|
|
new file mode 100644
|
|
index 0000000..01424ac
|
|
--- /dev/null
|
|
+++ b/xbmc/linux/sse4/DllLibSSE4.h
|
|
@@ -0,0 +1,43 @@
|
|
+#pragma once
|
|
+/*
|
|
+ * Copyright (C) 2005-2013 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
|
|
+ * <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "DynamicDll.h"
|
|
+
|
|
+extern "C" {
|
|
+
|
|
+}
|
|
+
|
|
+class DllLibSSE4Interface
|
|
+{
|
|
+public:
|
|
+ virtual ~DllLibSSE4Interface() {}
|
|
+ virtual void copy_frame(void * pSrc, void * pDest, void * pCacheBlock, UINT width, UINT height, UINT pitch) = 0;
|
|
+};
|
|
+
|
|
+class DllLibSSE4 : public DllDynamic, DllLibSSE4Interface
|
|
+{
|
|
+ DECLARE_DLL_WRAPPER(DllLibSSE4, DLL_PATH_LIBSSE4)
|
|
+ DEFINE_METHOD6(void, copy_frame, (void *p1, void *p2, void *p3, UINT p4, UINT p5, UINT p6))
|
|
+
|
|
+ BEGIN_METHOD_RESOLVE()
|
|
+ RESOLVE_METHOD(copy_frame)
|
|
+ END_METHOD_RESOLVE()
|
|
+};
|
|
diff --git a/xbmc/linux/sse4/Makefile.in b/xbmc/linux/sse4/Makefile.in
|
|
new file mode 100644
|
|
index 0000000..45aa826
|
|
--- /dev/null
|
|
+++ b/xbmc/linux/sse4/Makefile.in
|
|
@@ -0,0 +1,20 @@
|
|
+ARCH=@ARCH@
|
|
+DEFINES+=
|
|
+CXXFLAGS=-fPIC -msse4.1
|
|
+LIBNAME=libsse4
|
|
+OBJS=CopyFrame.o
|
|
+
|
|
+LIB_SHARED=@abs_top_srcdir@/system/$(LIBNAME)-$(ARCH).so
|
|
+
|
|
+all: $(LIB_SHARED)
|
|
+
|
|
+$(LIB_SHARED): $(OBJS)
|
|
+ $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS)
|
|
+
|
|
+CLEAN_FILES = \
|
|
+ $(LIB_SHARED) \
|
|
+
|
|
+DISTCLEAN_FILES= \
|
|
+ Makefile \
|
|
+
|
|
+include ../../../Makefile.include
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 05f30fe9aa91c0b69d0e71490d73bdc34e0bf0af Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Sun, 9 Mar 2014 00:16:57 +0200
|
|
Subject: [PATCH 85/93] vaapi: option to enable sw filters
|
|
|
|
Conflicts:
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
---
|
|
language/English/strings.po | 17 ++-
|
|
system/settings/settings.xml | 15 ++
|
|
xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +-
|
|
xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 1 +
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 76 ++++++++--
|
|
.../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 3 +
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 154 +++++++++++++++++++++
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 36 ++++-
|
|
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 32 ++---
|
|
9 files changed, 296 insertions(+), 42 deletions(-)
|
|
|
|
diff --git a/language/English/strings.po b/language/English/strings.po
|
|
index 516c5c1..47ac883 100755
|
|
--- a/language/English/strings.po
|
|
+++ b/language/English/strings.po
|
|
@@ -6092,7 +6092,13 @@ msgctxt "#13456"
|
|
msgid "Hardware accelerated"
|
|
msgstr ""
|
|
|
|
-#empty strings from id 13457 to 13499
|
|
+#. Option for video related setting #13454: sw filter
|
|
+#: system/settings/settings.xml
|
|
+msgctxt "#13457"
|
|
+msgid "Use SW Filter for VAAPI"
|
|
+msgstr ""
|
|
+
|
|
+#empty strings from id 13458 to 13499
|
|
|
|
#: system/settings/settings.xml
|
|
msgctxt "#13500"
|
|
@@ -15177,7 +15183,14 @@ msgctxt "#36431"
|
|
msgid "Defines whether video decoding should be performed in software (requires more CPU) or with hardware acceleration where possible."
|
|
msgstr ""
|
|
|
|
-#empty strings from id 36432 to 36499
|
|
+#. Description for video related setting #13457: vaapi sw filter
|
|
+#: system/settings/settings.xml
|
|
+msgctxt "#36432"
|
|
+msgid "This option enables the deinterlacing methods available for software decoding. It gives the possiblity to use high quality deinterlacers in combination with VAAPI."
|
|
+msgstr ""
|
|
+
|
|
+#empty strings from id 36433 to 36499
|
|
+
|
|
#end reservation
|
|
|
|
#: system/settings/settings.xml
|
|
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
|
|
index b756fca..3a9325e 100644
|
|
--- a/system/settings/settings.xml
|
|
+++ b/system/settings/settings.xml
|
|
@@ -715,6 +715,21 @@
|
|
<default>false</default>
|
|
<control type="toggle" />
|
|
</setting>
|
|
+ <setting id="videoplayer.usevaapiswfilter" type="boolean" parent="videoplayer.usevaapi" label="13457" help="36432">
|
|
+ <requirement>HAVE_LIBVA</requirement>
|
|
+ <dependencies>
|
|
+ <dependency type="enable">
|
|
+ <and>
|
|
+ <condition setting="videoplayer.usevaapi" operator="is">true</condition>
|
|
+ <condition setting="videoplayer.decodingmethod" operator="is">1</condition>
|
|
+ </and>
|
|
+ </dependency>
|
|
+ <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevaapivc1" operator="is">true</dependency>
|
|
+ </dependencies>
|
|
+ <level>3</level>
|
|
+ <default>false</default>
|
|
+ <control type="toggle" />
|
|
+ </setting>
|
|
<setting id="videoplayer.usedxva2" type="boolean" label="13427" help="36158">
|
|
<requirement>HasDXVA2</requirement>
|
|
<dependencies>
|
|
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
index 8dc8a91..c15f559 100644
|
|
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
|
|
@@ -986,10 +986,10 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO
|
|
if (mInt == VS_INTERLACEMETHOD_NONE)
|
|
return VS_INTERLACEMETHOD_NONE;
|
|
|
|
- if(!m_pRenderer->Supports(mInt))
|
|
+ if(m_pRenderer && !m_pRenderer->Supports(mInt))
|
|
mInt = VS_INTERLACEMETHOD_AUTO;
|
|
|
|
- if (mInt == VS_INTERLACEMETHOD_AUTO)
|
|
+ if (m_pRenderer && mInt == VS_INTERLACEMETHOD_AUTO)
|
|
return m_pRenderer->AutoInterlaceMethod();
|
|
|
|
return mInt;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
|
|
index 5443cb3..002c8e1 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
|
|
@@ -456,6 +456,7 @@ static const EFormatMap g_format_map[] = {
|
|
, { PIX_FMT_YUV420P16, RENDER_FMT_YUV420P16 }
|
|
, { PIX_FMT_UYVY422, RENDER_FMT_UYVY422 }
|
|
, { PIX_FMT_YUYV422, RENDER_FMT_YUYV422 }
|
|
+, { PIX_FMT_NV12, RENDER_FMT_NV12 }
|
|
, { PIX_FMT_VAAPI_VLD, RENDER_FMT_VAAPI }
|
|
, { PIX_FMT_DXVA2_VLD, RENDER_FMT_DXVA }
|
|
, { PIX_FMT_NONE , RENDER_FMT_NONE }
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index b59c1ee..2df9de9 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -38,6 +38,7 @@
|
|
#include "utils/log.h"
|
|
#include "boost/shared_ptr.hpp"
|
|
#include "threads/Atomics.h"
|
|
+#include "settings/MediaSettings.h"
|
|
|
|
#ifndef TARGET_POSIX
|
|
#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
|
|
@@ -165,6 +166,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
|
|
m_dts = DVD_NOPTS_VALUE;
|
|
m_started = false;
|
|
m_decoderPts = DVD_NOPTS_VALUE;
|
|
+ m_interlace = false;
|
|
}
|
|
|
|
CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
|
|
@@ -388,7 +390,7 @@ unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags)
|
|
{
|
|
m_filters_next.clear();
|
|
|
|
- if(m_pHardware)
|
|
+ if(m_pHardware && !m_pHardware->UseFilter())
|
|
return 0;
|
|
|
|
if(flags & FILTER_ROTATE)
|
|
@@ -462,10 +464,10 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
if(section)
|
|
lock = shared_ptr<CSingleLock>(new CSingleLock(*section));
|
|
|
|
- int result;
|
|
+ int result = 0;
|
|
if(pData)
|
|
result = m_pHardware->Check(m_pCodecContext);
|
|
- else
|
|
+ else if (!m_pHardware->UseFilter())
|
|
result = m_pHardware->Decode(m_pCodecContext, NULL);
|
|
|
|
if(result)
|
|
@@ -520,19 +522,60 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
|| m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3)
|
|
m_started = true;
|
|
|
|
- if(m_pHardware == NULL)
|
|
+ m_interlace = m_pFrame->interlaced_frame;
|
|
+
|
|
+ if(m_pHardware == NULL || m_pHardware->UseFilter())
|
|
{
|
|
+ if (m_pHardware)
|
|
+ {
|
|
+ m_pFrame->pkt_dts = pts_dtoi(m_dts);
|
|
+ int result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
|
|
+ if (result == VC_BUFFER)
|
|
+ return result;
|
|
+ m_pHardware->MapFrame(m_pCodecContext, m_pFrame);
|
|
+ m_dts = pts_itod(m_pFrame->pkt_dts);
|
|
+ m_pFrame->pkt_dts = 0;
|
|
+ }
|
|
+
|
|
bool need_scale = std::find( m_formats.begin()
|
|
, m_formats.end()
|
|
- , m_pCodecContext->pix_fmt) == m_formats.end();
|
|
+ , m_pFrame->format) == m_formats.end();
|
|
|
|
bool need_reopen = false;
|
|
+
|
|
+
|
|
+ // ask codec to do deinterlacing if possible
|
|
+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
|
+ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
|
|
+
|
|
+ unsigned int mFilters = 0;
|
|
+
|
|
+ if (mDeintMode != VS_DEINTERLACEMODE_OFF)
|
|
+ {
|
|
+ if (mDeintMode == VS_DEINTERLACEMODE_FORCE ||
|
|
+ m_pFrame->interlaced_frame)
|
|
+ {
|
|
+ if (mInt == VS_INTERLACEMETHOD_DEINTERLACE)
|
|
+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY;
|
|
+ else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
|
|
+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED;
|
|
+
|
|
+ if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters)
|
|
+ mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!g_renderManager.Supports(RENDERFEATURE_ROTATION))
|
|
+ mFilters |= CDVDVideoCodec::FILTER_ROTATE;
|
|
+
|
|
+ SetFilters(mFilters);
|
|
+
|
|
if(!m_filters.Equals(m_filters_next))
|
|
need_reopen = true;
|
|
|
|
if(m_pFilterIn)
|
|
{
|
|
- if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt
|
|
+ if(m_pFilterIn->outputs[0]->format != m_pFrame->format
|
|
|| m_pFilterIn->outputs[0]->w != m_pCodecContext->width
|
|
|| m_pFilterIn->outputs[0]->h != m_pCodecContext->height)
|
|
need_reopen = true;
|
|
@@ -549,7 +592,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
}
|
|
|
|
int result;
|
|
- if(m_pHardware)
|
|
+ if(m_pHardware && !m_pHardware->UseFilter())
|
|
result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
|
|
else if(m_pFilterGraph)
|
|
result = FilterProcess(m_pFrame);
|
|
@@ -645,6 +688,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
|
|
pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
|
|
pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;
|
|
+ pDvdVideoPicture->color_matrix = m_pCodecContext->colorspace;
|
|
if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG
|
|
|| m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P)
|
|
pDvdVideoPicture->color_range = 1;
|
|
@@ -668,7 +712,11 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN;
|
|
}
|
|
|
|
- pDvdVideoPicture->dts = m_dts;
|
|
+ if (pDvdVideoPicture->iRepeatPicture)
|
|
+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
|
|
+ else
|
|
+ pDvdVideoPicture->dts = m_dts;
|
|
+
|
|
m_dts = DVD_NOPTS_VALUE;
|
|
if (m_pFrame->reordered_opaque)
|
|
pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
|
|
@@ -699,7 +747,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
|
|
bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
|
|
{
|
|
- if(m_pHardware)
|
|
+ if(m_pHardware && !m_pHardware->UseFilter())
|
|
return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture);
|
|
|
|
if(!GetPictureCommon(pDvdVideoPicture))
|
|
@@ -724,6 +772,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
|
|
pix_fmt = (PixelFormat)m_pFrame->format;
|
|
|
|
pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -738,7 +787,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
|
|
if (filters.empty() && !scale)
|
|
return 0;
|
|
|
|
- if (m_pHardware)
|
|
+ if (m_pHardware && !m_pHardware->UseFilter())
|
|
{
|
|
CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode");
|
|
return 0;
|
|
@@ -756,7 +805,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
|
|
CStdString args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d",
|
|
m_pCodecContext->width,
|
|
m_pCodecContext->height,
|
|
- m_pCodecContext->pix_fmt,
|
|
+ m_pFrame->format,
|
|
m_pCodecContext->time_base.num,
|
|
m_pCodecContext->time_base.den,
|
|
m_pCodecContext->sample_aspect_ratio.num,
|
|
@@ -955,10 +1004,7 @@ bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &in
|
|
{
|
|
pts = m_decoderPts;
|
|
skippedDeint = m_skippedDeint;
|
|
- if (m_pFrame)
|
|
- interlaced = m_pFrame->interlaced_frame;
|
|
- else
|
|
- interlaced = 0;
|
|
+ interlaced = m_interlace;
|
|
return true;
|
|
}
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
index c0ce198..4f88532 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
@@ -48,6 +48,8 @@ public:
|
|
virtual bool CanSkipDeint() {return false; }
|
|
virtual const std::string Name() = 0;
|
|
virtual CCriticalSection* Section() { return NULL; }
|
|
+ virtual bool UseFilter() { return false; }
|
|
+ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame) { return false; }
|
|
};
|
|
|
|
CDVDVideoCodecFFmpeg();
|
|
@@ -134,4 +136,5 @@ protected:
|
|
int m_skippedDeint;
|
|
bool m_requestSkipDeint;
|
|
int m_codecControlFlags;
|
|
+ bool m_interlace;
|
|
};
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
index bfefc9d..51f9bed 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
@@ -24,6 +24,17 @@
|
|
#include "DVDVideoCodec.h"
|
|
#include <boost/scoped_array.hpp>
|
|
#include <boost/weak_ptr.hpp>
|
|
+#include "utils/log.h"
|
|
+#include "threads/SingleLock.h"
|
|
+#include "XMemUtils.h"
|
|
+#include "utils/CPUInfo.h"
|
|
+#include "settings/Settings.h"
|
|
+
|
|
+extern "C" {
|
|
+#include "libavutil/avutil.h"
|
|
+}
|
|
+
|
|
+#define CACHED_BUFFER_SIZE 4096
|
|
|
|
#define CHECK(a) \
|
|
do { \
|
|
@@ -166,12 +177,17 @@ CDecoder::CDecoder()
|
|
m_context = 0;
|
|
m_hwaccel = (vaapi_context*)calloc(1, sizeof(vaapi_context));
|
|
memset(m_surfaces, 0, sizeof(*m_surfaces));
|
|
+ m_frame_buffer = NULL;
|
|
+ m_cache = NULL;
|
|
}
|
|
|
|
CDecoder::~CDecoder()
|
|
{
|
|
Close();
|
|
free(m_hwaccel);
|
|
+ _aligned_free(m_frame_buffer);
|
|
+ _aligned_free(m_cache);
|
|
+ m_dllSSE4.Unload();
|
|
}
|
|
|
|
void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic)
|
|
@@ -388,6 +404,11 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su
|
|
if (!EnsureContext(avctx))
|
|
return false;
|
|
|
|
+ if (avctx->width <= 1920 && avctx->height <= 1088)
|
|
+ CheckUseFilter();
|
|
+ else
|
|
+ m_use_filter = false;
|
|
+
|
|
m_hwaccel->display = m_display->get();
|
|
|
|
avctx->hwaccel_context = m_hwaccel;
|
|
@@ -472,7 +493,35 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
|
|
return status;
|
|
|
|
if(frame)
|
|
+ {
|
|
+ if (m_use_filter)
|
|
+ {
|
|
+ VASurfaceID surface = GetSurfaceID(frame);
|
|
+ std::list<CSurfacePtr>::iterator it;
|
|
+ for(it = m_surfaces_used.begin(); it != m_surfaces_used.end(); ++it)
|
|
+ {
|
|
+ if((*it)->m_id == surface)
|
|
+ {
|
|
+ m_holder.surface = *it;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (it == m_surfaces_used.end())
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "VAAPI::Decode - surface not found");
|
|
+ return VC_ERROR;
|
|
+ }
|
|
+ CProcPic pic;
|
|
+ memset(&pic.frame, 0, sizeof(AVFrame));
|
|
+ av_frame_ref(&pic.frame, frame);
|
|
+ pic.surface = *it;
|
|
+ m_surfaces_proc.push_back(pic);
|
|
+ if (m_surfaces_proc.size() < m_renderbuffers_count)
|
|
+ return VC_BUFFER;
|
|
+ }
|
|
+
|
|
return VC_BUFFER | VC_PICTURE;
|
|
+ }
|
|
else
|
|
return VC_BUFFER;
|
|
}
|
|
@@ -550,4 +599,109 @@ unsigned CDecoder::GetAllowedReferences()
|
|
return m_renderbuffers_count;
|
|
}
|
|
|
|
+void CDecoder::Reset()
|
|
+{
|
|
+ m_surfaces_proc.clear();
|
|
+}
|
|
+
|
|
+void CDecoder::CheckUseFilter()
|
|
+{
|
|
+ m_use_filter = true;
|
|
+ _aligned_free(m_frame_buffer);
|
|
+ _aligned_free(m_cache);
|
|
+ if (CSettings::Get().GetBool("videoplayer.usevaapiswfilter"))
|
|
+ {
|
|
+ if (!(g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE4))
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter cpu does not support SSE4");
|
|
+ m_use_filter = false;
|
|
+ return;
|
|
+ }
|
|
+ if (!m_dllSSE4.Load())
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter failed loading sse4 lib");
|
|
+ m_use_filter = false;
|
|
+ return;
|
|
+ }
|
|
+ VAImage image;
|
|
+ VASurfaceID surface = m_surfaces_free.front()->m_id;
|
|
+ VAStatus status = vaDeriveImage(m_display->get(), surface, &image);
|
|
+ m_use_filter = true;
|
|
+ if (status != VA_STATUS_SUCCESS)
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter vaDeriveImage not supported");
|
|
+ m_use_filter = false;
|
|
+ }
|
|
+ if (image.format.fourcc != VA_FOURCC_NV12)
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter image format not NV12");
|
|
+ m_use_filter = false;
|
|
+ }
|
|
+ if ((image.pitches[0] % 64) || (image.pitches[1] % 64))
|
|
+ {
|
|
+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter patches no multiple of 64");
|
|
+ m_use_filter = false;
|
|
+ }
|
|
+ if (m_use_filter)
|
|
+ {
|
|
+ m_frame_buffer = (uint8_t*)_aligned_malloc(image.height*image.width*2 + 256, 64);
|
|
+ m_cache = (uint8_t*)_aligned_malloc(CACHED_BUFFER_SIZE, 64);
|
|
+ }
|
|
+ vaDestroyImage(m_display->get(),image.image_id);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_use_filter = false;
|
|
+ }
|
|
+}
|
|
+
|
|
+bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame)
|
|
+{
|
|
+ if (m_surfaces_proc.empty())
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+ if(frame)
|
|
+ {
|
|
+ CProcPic pic = m_surfaces_proc.front();
|
|
+ m_surfaces_proc.pop_front();
|
|
+ VASurfaceID surface = pic.surface->m_id;
|
|
+ VASurfaceStatus surf_status;
|
|
+ VAImage image;
|
|
+ uint8_t *buf;
|
|
+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status))
|
|
+ while (surf_status != VASurfaceReady)
|
|
+ {
|
|
+ Sleep(1);
|
|
+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status))
|
|
+ }
|
|
+ CHECK(vaDeriveImage(m_display->get(), surface, &image));
|
|
+ CHECK(vaMapBuffer(m_display->get(), image.buf, (void**)&buf))
|
|
+
|
|
+ uint8_t *src, *dst;
|
|
+ src = buf + image.offsets[0];
|
|
+ dst = m_frame_buffer + image.offsets[0];
|
|
+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height, image.pitches[0]);
|
|
+ src = buf + image.offsets[1];
|
|
+ dst = m_frame_buffer + image.offsets[1];
|
|
+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]);
|
|
+
|
|
+ av_frame_unref(frame);
|
|
+ av_frame_move_ref(frame, &pic.frame);
|
|
+
|
|
+ frame->format = AV_PIX_FMT_NV12;
|
|
+ frame->data[0] = m_frame_buffer + image.offsets[0];
|
|
+ frame->linesize[0] = image.pitches[0];
|
|
+ frame->data[1] = m_frame_buffer + image.offsets[1];
|
|
+ frame->linesize[1] = image.pitches[1];
|
|
+ frame->data[2] = NULL;
|
|
+ frame->data[3] = NULL;
|
|
+ frame->pkt_size = image.data_size;
|
|
+
|
|
+ CHECK(vaUnmapBuffer(m_display->get(), image.buf))
|
|
+ CHECK(vaDestroyImage(m_display->get(),image.image_id))
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
#endif
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
index a520e42..3541c9c 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
@@ -22,14 +22,19 @@
|
|
#include "system_gl.h"
|
|
|
|
#include "DllAvCodec.h"
|
|
+
|
|
#include "DVDVideoCodecFFmpeg.h"
|
|
-#include <libavcodec/vaapi.h>
|
|
#include <va/va.h>
|
|
#include <va/va_x11.h>
|
|
#include <va/va_glx.h>
|
|
#include <list>
|
|
#include <boost/shared_ptr.hpp>
|
|
+#include "linux/sse4/DllLibSSE4.h"
|
|
|
|
+extern "C" {
|
|
+#include "libavcodec/vaapi.h"
|
|
+#include "libavcodec/avcodec.h"
|
|
+}
|
|
|
|
namespace VAAPI {
|
|
|
|
@@ -101,11 +106,31 @@ struct CHolder
|
|
{}
|
|
};
|
|
|
|
+struct CProcPic
|
|
+{
|
|
+ AVFrame frame;
|
|
+ CSurfacePtr surface;
|
|
+ CProcPic()
|
|
+ {}
|
|
+ CProcPic(const CProcPic &other)
|
|
+ {
|
|
+ memcpy(&this->frame, &other.frame, sizeof(AVFrame));
|
|
+ surface = other.surface;
|
|
+ }
|
|
+ CProcPic & operator= (const CProcPic &other)
|
|
+ {
|
|
+ memcpy(&this->frame, &other.frame, sizeof(AVFrame));
|
|
+ surface = other.surface;
|
|
+ return *this;
|
|
+ }
|
|
+};
|
|
+
|
|
class CDecoder
|
|
: public CDVDVideoCodecFFmpeg::IHardwareDecoder
|
|
{
|
|
bool EnsureContext(AVCodecContext *avctx);
|
|
bool EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count);
|
|
+ void CheckUseFilter();
|
|
public:
|
|
CDecoder();
|
|
~CDecoder();
|
|
@@ -114,9 +139,12 @@ public:
|
|
virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture);
|
|
virtual int Check (AVCodecContext* avctx);
|
|
virtual void Close();
|
|
+ virtual void Reset();
|
|
virtual const std::string Name() { return "vaapi"; }
|
|
virtual CCriticalSection* Section() { if(m_display) return m_display.get(); else return NULL; }
|
|
virtual unsigned GetAllowedReferences();
|
|
+ virtual bool UseFilter() { return m_use_filter; }
|
|
+ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame);
|
|
|
|
int GetBuffer(AVCodecContext *avctx, AVFrame *pic);
|
|
void RelBuffer(AVCodecContext *avctx, AVFrame *pic);
|
|
@@ -132,14 +160,20 @@ protected:
|
|
int m_refs;
|
|
std::list<CSurfacePtr> m_surfaces_used;
|
|
std::list<CSurfacePtr> m_surfaces_free;
|
|
+ std::list<CProcPic> m_surfaces_proc;
|
|
|
|
CDisplayPtr m_display;
|
|
VAConfigID m_config;
|
|
VAContextID m_context;
|
|
+ bool m_use_filter;
|
|
+ uint8_t *m_frame_buffer;
|
|
+ uint8_t *m_cache;
|
|
|
|
vaapi_context *m_hwaccel;
|
|
|
|
CHolder m_holder; // silly struct to pass data to renderer
|
|
+
|
|
+ DllLibSSE4 m_dllSSE4;
|
|
};
|
|
|
|
}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
index 9c5469b..b30e450 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
|
|
@@ -554,28 +554,6 @@ void CDVDPlayerVideo::Process()
|
|
// decoder still needs to provide an empty image structure, with correct flags
|
|
m_pVideoCodec->SetDropState(bRequestDrop);
|
|
|
|
- // ask codec to do deinterlacing if possible
|
|
- EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
|
- EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
|
|
-
|
|
- unsigned int mFilters = 0;
|
|
-
|
|
- if (mDeintMode != VS_DEINTERLACEMODE_OFF)
|
|
- {
|
|
- if (mInt == VS_INTERLACEMETHOD_DEINTERLACE)
|
|
- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY;
|
|
- else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
|
|
- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED;
|
|
-
|
|
- if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters)
|
|
- mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;
|
|
- }
|
|
-
|
|
- if (!g_renderManager.Supports(RENDERFEATURE_ROTATION))
|
|
- mFilters |= CDVDVideoCodec::FILTER_ROTATE;
|
|
-
|
|
- mFilters = m_pVideoCodec->SetFilters(mFilters);
|
|
-
|
|
int iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts);
|
|
|
|
// buffer packets so we can recover should decoder flush for some reason
|
|
@@ -662,6 +640,8 @@ void CDVDPlayerVideo::Process()
|
|
|
|
//Deinterlace if codec said format was interlaced or if we have selected we want to deinterlace
|
|
//this video
|
|
+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
|
+ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
|
|
if ((mDeintMode == VS_DEINTERLACEMODE_AUTO && (picture.iFlags & DVP_FLAG_INTERLACED)) || mDeintMode == VS_DEINTERLACEMODE_FORCE)
|
|
{
|
|
if(mInt == VS_INTERLACEMETHOD_SW_BLEND)
|
|
@@ -704,7 +684,15 @@ void CDVDPlayerVideo::Process()
|
|
}
|
|
|
|
if (picture.iRepeatPicture)
|
|
+ {
|
|
+ double pts;
|
|
+ int skipped, deint;
|
|
+ m_pVideoCodec->GetCodecStats(pts, skipped, deint);
|
|
+ picture.iDuration = frametime;
|
|
+ if (deint && (frametime <= 0.02*DVD_TIME_BASE))
|
|
+ picture.iDuration *= 2;
|
|
picture.iDuration *= picture.iRepeatPicture + 1;
|
|
+ }
|
|
|
|
int iResult = OutputPicture(&picture, pts);
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From eb235f0541bef993a9db30642ed451b723b7953e Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Fri, 3 Jan 2014 20:50:46 +0100
|
|
Subject: [PATCH 86/93] X11: check for user output on resize window
|
|
|
|
---
|
|
xbmc/windowing/X11/WinSystemX11.cpp | 17 ++++++++++++++---
|
|
1 file changed, 14 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
index 9962f08..c95f4ec 100644
|
|
--- a/xbmc/windowing/X11/WinSystemX11.cpp
|
|
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
|
|
@@ -167,7 +167,20 @@ bool CWinSystemX11::DestroyWindow()
|
|
bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
|
|
{
|
|
m_userOutput = CSettings::Get().GetString("videoscreen.monitor");
|
|
- if (m_userOutput.compare("Default") == 0)
|
|
+ XOutput *out = NULL;
|
|
+ if (m_userOutput.compare("Default") != 0)
|
|
+ {
|
|
+ out = g_xrandr.GetOutput(m_userOutput);
|
|
+ if (out)
|
|
+ {
|
|
+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput);
|
|
+ if (!mode.isCurrent)
|
|
+ {
|
|
+ out = NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (!out)
|
|
{
|
|
std::vector<XOutput> outputs = g_xrandr.GetModes();
|
|
if (outputs.size() > 0)
|
|
@@ -176,8 +189,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
|
|
}
|
|
}
|
|
|
|
- m_userOutput = g_xrandr.GetModes()[0].name;
|
|
-
|
|
if(m_nWidth == newWidth
|
|
&& m_nHeight == newHeight
|
|
&& m_userOutput.compare(m_currentOutput) == 0)
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From cf354441917e2066e406fad51200f20d762f09d2 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Fri, 24 Jan 2014 18:29:33 +0100
|
|
Subject: [PATCH 87/93] dvdplayer: flush ffmpeg after hw decoder returned an
|
|
error
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 9 +++++++++
|
|
1 file changed, 9 insertions(+)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index 2df9de9..f4c9929 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -471,7 +471,12 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
result = m_pHardware->Decode(m_pCodecContext, NULL);
|
|
|
|
if(result)
|
|
+ {
|
|
+ if (result & VC_ERROR)
|
|
+ avcodec_flush_buffers(m_pCodecContext);
|
|
+
|
|
return result;
|
|
+ }
|
|
}
|
|
|
|
if(m_pFilterGraph)
|
|
@@ -593,7 +598,11 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
|
|
int result;
|
|
if(m_pHardware && !m_pHardware->UseFilter())
|
|
+ {
|
|
result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
|
|
+ if (result & VC_ERROR)
|
|
+ avcodec_flush_buffers(m_pCodecContext);
|
|
+ }
|
|
else if(m_pFilterGraph)
|
|
result = FilterProcess(m_pFrame);
|
|
else
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 8184d80ea878672e0ad27ef24bc0daab05bf6397 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 28 Jan 2014 10:05:26 +0100
|
|
Subject: [PATCH 88/93] xbmc pr 3080
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 14 ++++++++++++--
|
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index f4c9929..283af9e 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -495,6 +495,14 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
|
|
m_dllAvCodec.av_init_packet(&avpkt);
|
|
avpkt.data = pData;
|
|
avpkt.size = iSize;
|
|
+#define SET_PKT_TS(ts) \
|
|
+ if(ts != DVD_NOPTS_VALUE)\
|
|
+ avpkt.ts = (ts / DVD_TIME_BASE) * AV_TIME_BASE;\
|
|
+ else\
|
|
+ avpkt.ts = AV_NOPTS_VALUE
|
|
+ SET_PKT_TS(pts);
|
|
+ SET_PKT_TS(dts);
|
|
+#undef SET_PKT_TS
|
|
/* We lie, but this flag is only used by pngdec.c.
|
|
* Setting it correctly would allow CorePNG decoding. */
|
|
avpkt.flags = AV_PKT_FLAG_KEY;
|
|
@@ -727,8 +735,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
pDvdVideoPicture->dts = m_dts;
|
|
|
|
m_dts = DVD_NOPTS_VALUE;
|
|
- if (m_pFrame->reordered_opaque)
|
|
- pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
|
|
+
|
|
+ int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame);
|
|
+ if(bpts != AV_NOPTS_VALUE)
|
|
+ pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;
|
|
else
|
|
pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From dbfcb8af2d7aa02dd5de3227e226493e80e7be4d Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 28 Jan 2014 17:24:58 +0100
|
|
Subject: [PATCH 89/93] set preatpicture if pts is equal to last frame
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index 283af9e..ff18b73 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -738,7 +738,15 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
|
|
|
|
int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame);
|
|
if(bpts != AV_NOPTS_VALUE)
|
|
+ {
|
|
pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;
|
|
+ if (pDvdVideoPicture->pts == m_decoderPts)
|
|
+ {
|
|
+ pDvdVideoPicture->iRepeatPicture = -0.5;
|
|
+ pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
|
|
+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
|
|
+ }
|
|
+ }
|
|
else
|
|
pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 4ae7d07c09a3d2e3fe0dc7042f37a11c89622357 Mon Sep 17 00:00:00 2001
|
|
From: fritsch <Peter.Fruehberger@gmail.com>
|
|
Date: Mon, 27 Jan 2014 19:49:03 +0100
|
|
Subject: [PATCH 90/93] Introduce SWCodec - these are codecs that don't have
|
|
any GPU acceleration (yet) - add HVEC
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 15 +++++++++------
|
|
.../cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +-
|
|
xbmc/settings/AdvancedSettings.cpp | 4 ++--
|
|
xbmc/settings/AdvancedSettings.h | 2 +-
|
|
4 files changed, 13 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index ff18b73..354e206 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -160,7 +160,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
|
|
m_iScreenHeight = 0;
|
|
m_iOrientation = 0;
|
|
m_bSoftware = false;
|
|
- m_isHi10p = false;
|
|
+ m_isSWCodec = false;
|
|
m_pHardware = NULL;
|
|
m_iLastKeyframe = 0;
|
|
m_dts = DVD_NOPTS_VALUE;
|
|
@@ -216,10 +216,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
|
|
// this is needed to not open the decoders
|
|
m_bSoftware = true;
|
|
// this we need to enable multithreading for hi10p via advancedsettings
|
|
- m_isHi10p = true;
|
|
+ m_isSWCodec = true;
|
|
break;
|
|
}
|
|
}
|
|
+ else if (hints.codec == AV_CODEC_ID_HEVC)
|
|
+ m_isSWCodec = true;
|
|
|
|
if(pCodec == NULL)
|
|
pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec);
|
|
@@ -245,12 +247,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
|
|
* sensitive to changes in frame sizes, and it causes crashes
|
|
* during HW accell - so we unset it in this case.
|
|
*
|
|
- * When we detect Hi10p and user did not disable hi10pmultithreading
|
|
+ * When we detect a pure SW codec and user did not disable SWmultithreading
|
|
* via advancedsettings.xml we keep the ffmpeg default thread type.
|
|
* */
|
|
- if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading)
|
|
+ if(m_isSWCodec && !g_advancedSettings.m_videoDisableSWMultithreading)
|
|
{
|
|
- CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d",
|
|
+ CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for swcodec: %d",
|
|
m_pCodecContext->thread_type);
|
|
}
|
|
else if ((EDECODEMETHOD) CSettings::Get().GetInt("videoplayer.decodingmethod") == VS_DECODEMETHOD_SOFTWARE && CSettings::Get().GetBool("videoplayer.useframemtdec"))
|
|
@@ -302,7 +304,8 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
|
|
int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount());
|
|
if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded
|
|
&& ( pCodec->id == AV_CODEC_ID_H264
|
|
- || pCodec->id == AV_CODEC_ID_MPEG4 ))
|
|
+ || pCodec->id == AV_CODEC_ID_MPEG4
|
|
+ || pCodec->id == AV_CODEC_ID_HEVC))
|
|
m_pCodecContext->thread_count = num_threads;
|
|
|
|
if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
index 4f88532..e301aa8 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
|
|
@@ -126,7 +126,7 @@ protected:
|
|
|
|
std::string m_name;
|
|
bool m_bSoftware;
|
|
- bool m_isHi10p;
|
|
+ bool m_isSWCodec;
|
|
IHardwareDecoder *m_pHardware;
|
|
int m_iLastKeyframe;
|
|
double m_dts;
|
|
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
|
|
index 7532914..0d5e546 100644
|
|
--- a/xbmc/settings/AdvancedSettings.cpp
|
|
+++ b/xbmc/settings/AdvancedSettings.cpp
|
|
@@ -182,7 +182,7 @@ void CAdvancedSettings::Initialize()
|
|
m_stagefrightConfig.useInputDTS = false;
|
|
|
|
m_videoDefaultLatency = 0.0;
|
|
- m_videoDisableHi10pMultithreading = false;
|
|
+ m_videoDisableSWMultithreading = false;
|
|
|
|
m_musicUseTimeSeeking = true;
|
|
m_musicTimeSeekForward = 10;
|
|
@@ -599,7 +599,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
|
|
XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f);
|
|
XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers);
|
|
XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f);
|
|
- XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading);
|
|
+ XMLUtils::GetBoolean(pElement,"disableswmultithreading",m_videoDisableSWMultithreading);
|
|
XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
|
|
XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
|
|
XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD);
|
|
diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h
|
|
index c43351d..7075f05 100644
|
|
--- a/xbmc/settings/AdvancedSettings.h
|
|
+++ b/xbmc/settings/AdvancedSettings.h
|
|
@@ -194,7 +194,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
|
|
bool m_DXVANoDeintProcForProgressive;
|
|
int m_videoFpsDetect;
|
|
int m_videoBusyDialogDelay_ms;
|
|
- bool m_videoDisableHi10pMultithreading;
|
|
+ bool m_videoDisableSWMultithreading;
|
|
StagefrightConfig m_stagefrightConfig;
|
|
|
|
CStdString m_videoDefaultPlayer;
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 0f809b66ecb03c219083ea821f4dbba543e818f5 Mon Sep 17 00:00:00 2001
|
|
From: Rainer Hochecker <fernetmenta@online.de>
|
|
Date: Tue, 11 Feb 2014 18:15:06 +0100
|
|
Subject: [PATCH 91/93] 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 0287e73..6904cb9 100644
|
|
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
|
|
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
|
|
@@ -276,7 +276,13 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size)
|
|
}
|
|
}
|
|
if (!m_inMsgEvent.WaitMSec(200))
|
|
+ {
|
|
+ double cachetime = GetCacheTime();
|
|
+ CSingleLock lock(m_streamLock);
|
|
+ CLog::Log(LOGWARNING, "CActiveAEStream::AddData - timeout waiting for buffer, paused: %d, cache time: %f, free buffers: %d",
|
|
+ m_paused, cachetime, m_streamFreeBuffers);
|
|
break;
|
|
+ }
|
|
}
|
|
return copied;
|
|
}
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From 513134b092630d3d59ee738a2761b93c08e3312f Mon Sep 17 00:00:00 2001
|
|
From: Stefan Saraev <stefan@saraev.ca>
|
|
Date: Mon, 24 Feb 2014 20:49:47 +0200
|
|
Subject: [PATCH 92/93] vaapi: fix build
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 13 ++-----------
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 6 +-----
|
|
2 files changed, 3 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
index 51f9bed..f957393 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
|
|
@@ -24,16 +24,10 @@
|
|
#include "DVDVideoCodec.h"
|
|
#include <boost/scoped_array.hpp>
|
|
#include <boost/weak_ptr.hpp>
|
|
-#include "utils/log.h"
|
|
-#include "threads/SingleLock.h"
|
|
#include "XMemUtils.h"
|
|
#include "utils/CPUInfo.h"
|
|
#include "settings/Settings.h"
|
|
|
|
-extern "C" {
|
|
-#include "libavutil/avutil.h"
|
|
-}
|
|
-
|
|
#define CACHED_BUFFER_SIZE 4096
|
|
|
|
#define CHECK(a) \
|
|
@@ -512,8 +506,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
|
|
return VC_ERROR;
|
|
}
|
|
CProcPic pic;
|
|
- memset(&pic.frame, 0, sizeof(AVFrame));
|
|
- av_frame_ref(&pic.frame, frame);
|
|
+ memcpy(&pic.frame, frame, sizeof(AVFrame));
|
|
pic.surface = *it;
|
|
m_surfaces_proc.push_back(pic);
|
|
if (m_surfaces_proc.size() < m_renderbuffers_count)
|
|
@@ -686,9 +679,7 @@ bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame)
|
|
dst = m_frame_buffer + image.offsets[1];
|
|
m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]);
|
|
|
|
- av_frame_unref(frame);
|
|
- av_frame_move_ref(frame, &pic.frame);
|
|
-
|
|
+ memcpy(frame, &pic.frame, sizeof(AVFrame));
|
|
frame->format = AV_PIX_FMT_NV12;
|
|
frame->data[0] = m_frame_buffer + image.offsets[0];
|
|
frame->linesize[0] = image.pitches[0];
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
index 3541c9c..49d3117 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
|
|
@@ -22,8 +22,8 @@
|
|
#include "system_gl.h"
|
|
|
|
#include "DllAvCodec.h"
|
|
-
|
|
#include "DVDVideoCodecFFmpeg.h"
|
|
+#include <libavcodec/vaapi.h>
|
|
#include <va/va.h>
|
|
#include <va/va_x11.h>
|
|
#include <va/va_glx.h>
|
|
@@ -31,10 +31,6 @@
|
|
#include <boost/shared_ptr.hpp>
|
|
#include "linux/sse4/DllLibSSE4.h"
|
|
|
|
-extern "C" {
|
|
-#include "libavcodec/vaapi.h"
|
|
-#include "libavcodec/avcodec.h"
|
|
-}
|
|
|
|
namespace VAAPI {
|
|
|
|
--
|
|
1.9.0
|
|
|
|
|
|
From f0b8551028faafa5bb3c5880263759a6239e836a Mon Sep 17 00:00:00 2001
|
|
From: Stefan Saraev <stefan@saraev.ca>
|
|
Date: Mon, 24 Feb 2014 20:58:52 +0200
|
|
Subject: [PATCH 93/93] no hevc in ffmpeg 1.2
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
index 354e206..6bc35b1 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
|
|
@@ -220,8 +220,11 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
|
|
break;
|
|
}
|
|
}
|
|
+ #ifdef AV_CODEC_ID_HEVC
|
|
else if (hints.codec == AV_CODEC_ID_HEVC)
|
|
m_isSWCodec = true;
|
|
+ #endif
|
|
+
|
|
|
|
if(pCodec == NULL)
|
|
pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec);
|
|
@@ -304,8 +307,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
|
|
int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount());
|
|
if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded
|
|
&& ( pCodec->id == AV_CODEC_ID_H264
|
|
- || pCodec->id == AV_CODEC_ID_MPEG4
|
|
- || pCodec->id == AV_CODEC_ID_HEVC))
|
|
+ || pCodec->id == AV_CODEC_ID_MPEG4 ))
|
|
m_pCodecContext->thread_count = num_threads;
|
|
|
|
if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
|
|
--
|
|
1.9.0
|
|
|