]> source.dussan.org Git - tigervnc.git/commitdiff
Combined video detection stuff with new polling code.
authorConstantin Kaplinsky <const@tightvnc.com>
Mon, 8 Oct 2007 14:54:18 +0000 (14:54 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Mon, 8 Oct 2007 14:54:18 +0000 (14:54 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2348 3789f03b-4d11-0410-bbf8-ca57d06f2519

unix/x0vncserver/PollingManager.cxx
unix/x0vncserver/PollingManager.h

index d251f5fa7d073bb0b349d7b5212aef245866ce42..93dce132ccfb7d0ee6bb40c51fed60364f294d37 100644 (file)
@@ -259,6 +259,9 @@ bool PollingManager::poll_New()
     pmxChanged += m_widthTiles;
   }
 
+  // Do the work related to video area detection.
+  bool videoDetected = detectVideo(mxChanged);
+
   // Inform the server about the changes.
   if (nTilesChanged)
     sendChanges(mxChanged);
@@ -266,7 +269,13 @@ bool PollingManager::poll_New()
   // Cleanup.
   delete[] mxChanged;
 
-  return (nTilesChanged != 0);
+#ifdef DEBUG
+  if (nTilesChanged != 0) {
+    fprintf(stderr, "#%d# ", nTilesChanged);
+  }
+#endif
+
+  return (nTilesChanged != 0 || videoDetected);
 }
 
 int PollingManager::checkRow(int x, int y, int w, bool *pmxChanged)
@@ -326,6 +335,52 @@ void PollingManager::sendChanges(bool *pmxChanged)
   }
 }
 
+bool PollingManager::detectVideo(bool *pmxChanged)
+{
+  // Configurable parameters.
+  const int VIDEO_THRESHOLD_0 = 3;
+  const int VIDEO_THRESHOLD_1 = 5;
+
+  // Each call: update counters in m_rateMatrix.
+  int numTiles = m_heightTiles * m_widthTiles;
+  for (int i = 0; i < numTiles; i++)
+    m_rateMatrix[i] += (pmxChanged[i] != false);
+
+  // Once per eight calls: detect video region. In other words, mark a
+  // region that consists of continuously changing pixels. Save the
+  // result in m_videoFlags[] and reset counters in m_rateMatrix[].
+  bool isGrandStep = (m_pollingStep % 8 == 0);
+  if (isGrandStep) {
+    for (int i = 0; i < numTiles; i++) {
+      if (m_rateMatrix[i] <= VIDEO_THRESHOLD_0) {
+        m_videoFlags[i] = 0;
+      } else if (m_rateMatrix[i] >= VIDEO_THRESHOLD_1) {
+        m_videoFlags[i] = 1;
+      }
+      m_rateMatrix[i] = 0;
+    }
+  }
+
+  // Choose the biggest rectangle from the region defined by
+  // m_videoFlags[].
+  Rect r;
+  getVideoAreaRect(&r);
+
+  // Exclude video rectangle from pmxChanged[].
+  for (int y = r.tl.y / 32; y < r.br.y / 32; y++) {
+    for (int x = r.tl.x / 32; x < r.br.x / 32; x++) {
+      pmxChanged[y * m_widthTiles + x] = false;
+    }
+  }
+
+  // Inform the server...
+  m_server->set_video_area(r);
+  if (!r.is_empty())
+    getScreenRect(r);
+
+  return (!r.is_empty());
+}
+
 bool PollingManager::poll_DetectVideo()
 {
   if (!m_server)
index 3b922d8a8c663b28cddbf39223caab4d71fa7943..cd83b4cad4b421a2d50314ab4e57de8614eb4e86 100644 (file)
@@ -137,6 +137,7 @@ private:
 
   int checkRow(int x, int y, int w, bool *pmxChanged);
   void sendChanges(bool *pmxChanged);
+  bool detectVideo(bool *pmxChanged);
 
   void adjustVideoArea();