From ee41d1bf8dcca8177575c957360a8f52d01207cb Mon Sep 17 00:00:00 2001
From: Marten Richter <marten.richter@freenet.de>
Date: Sun, 9 Sep 2012 14:57:59 +0200
Subject: [PATCH] Support Quarter Video Mode

---
 osdwin.cc   |   2 +-
 videoomx.cc | 158 ++++++++++++++++++++++++++++++++++------------------
 videoomx.h  |   3 +
 3 files changed, 108 insertions(+), 55 deletions(-)

diff --git a/osdwin.cc b/osdwin.cc
index 4f90c5b..83560b9 100644
--- a/osdwin.cc
+++ b/osdwin.cc
@@ -105,7 +105,7 @@ int OsdWin::getFD()
   return fdOsd;
 }
 
-Surface * OsdWin::createNewSurface();{
+Surface * OsdWin::createNewSurface(){
 	return (Surface*)new SurfaceWin();
 }
 
diff --git a/videoomx.cc b/videoomx.cc
index e1014e5..56e35e3 100644
--- a/videoomx.cc
+++ b/videoomx.cc
@@ -48,6 +48,9 @@ VideoOMX::VideoOMX() {
 	lastreftimePTS = 0;
 	firstsynched = false;
 
+	mode=NORMAL;
+	xpos=ypos=0.f;
+
 }
 
 VideoOMX::~VideoOMX()
@@ -240,15 +243,99 @@ int VideoOMX::setAspectRatio(UCHAR taspectRatio)
 int VideoOMX::setMode(UCHAR tmode)
 {
   if (!initted) return 0;
+  mode=tmode;
+  updateMode();
+  return 1;
+}
+
 
-  if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
+void VideoOMX::updateMode()
+{
+	clock_mutex.Lock();
+	if (omx_running) {
+		OMX_ERRORTYPE error;
+		OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
+		memset(&dispconf, 0, sizeof(dispconf));
+		dispconf.nSize = sizeof(dispconf);
+		dispconf.nVersion.nVersion = OMX_VERSION;
+		dispconf.nPortIndex = omx_rend_input_port;
+		dispconf.layer = 1;
+		dispconf.set = OMX_DISPLAY_SET_LAYER;
+		error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
+				&dispconf);
+		if (error != OMX_ErrorNone) {
+			Log::getInstance()->log("Video", Log::DEBUG,
+					"Set OMX_IndexConfigDisplayRegion1 failed %x", error);
+			clock_mutex.Unlock();
+			return;
+		}
+		dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
+		if (mode != QUARTER && mode != EIGHTH) {
+			//Set Fullscreen
+			dispconf.fullscreen = OMX_TRUE;
+		} else {
+			dispconf.fullscreen = OMX_FALSE;
+		}
+		error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
+				&dispconf);
+		if (error != OMX_ErrorNone) {
+			Log::getInstance()->log("Video", Log::DEBUG,
+					"Set OMX_IndexConfigDisplayRegion2 failed %x", error);
+			clock_mutex.Unlock();
+			return;
+		}
 
-  if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
-      && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
-  mode = tmode;
+		dispconf.set = OMX_DISPLAY_SET_MODE;
+		if (mode != QUARTER && mode != EIGHTH) {
+			dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
+					: OMX_DISPLAY_MODE_LETTERBOX;
+		} else {
+			dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
+		}
+		error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
+				&dispconf);
+		if (error != OMX_ErrorNone) {
+			Log::getInstance()->log("Video", Log::DEBUG,
+					"Set OMX_IndexConfigDisplayRegion3 failed %x", error);
+			clock_mutex.Unlock();
+			return;
+		}
 
-//  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
-  return 1;
+		if (mode == QUARTER || mode == EIGHTH) {
+			unsigned int display_width, display_height;
+			display_width = display_height = 0;
+			if (graphics_get_display_size(0, &display_width, &display_height)
+					< 0) {
+				Log::getInstance()->log("OSD", Log::WARN,
+						"Getting display size failed! (BCM API) ");
+				clock_mutex.Unlock();
+				return;
+			}
+			//UnSetFullscreen with window
+			dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
+			dispconf.dest_rect.x_offset
+					= (int) (xpos * ((float) display_width));
+			dispconf.dest_rect.y_offset = (int) (ypos
+					* ((float) display_height));
+			if (mode == QUARTER) {
+				dispconf.dest_rect.width = display_width >> 1;
+				dispconf.dest_rect.height = display_height >> 1;
+			} else if (mode == EIGHTH) {
+				dispconf.dest_rect.width = display_width >> 2;
+				dispconf.dest_rect.height = display_height >> 2;
+			}
+			error = OMX_SetParameter(omx_vid_rend,
+					OMX_IndexConfigDisplayRegion, &dispconf);
+			if (error != OMX_ErrorNone) {
+				Log::getInstance()->log("Video", Log::DEBUG,
+						"Set OMX_IndexConfigDisplayRegion failed %x", error);
+				clock_mutex.Unlock();
+				return;
+			}
+		}
+
+	}
+	clock_mutex.Unlock();
 }
 
 int VideoOMX::signalOff()
@@ -272,52 +359,14 @@ int VideoOMX::setSource()
   return 1;
 }
 
-int VideoOMX::setPosition(int x, int y)
-{
-  if (!initted) return 0;
-
-//  vid_pos_regs_t pos_d;
-//  pos_d.x = x;
-//  pos_d.y = y;
-
-/*  vid_pos_regs_t pos_d;
-
-  memset(&pos_d, 0, sizeof(pos_d));
-
-  pos_d.dest.y = y;
-  pos_d.dest.x = x;
-/*
-typedef struct {
-  int w;
-  int h;
-  int scale;
-  int x1;
-  int y;
-  int x;
-  int y2;
-  int x3;
-  int y3;
-  int x4;
-  int y4;
-} vid_pos_regs_t;
-*/
-
-/*
-  pos_d.w = 100;
-  pos_d.h = 30;
-  pos_d.scale = 2;
-  pos_d.x1 = 0;
-  pos_d.y = 100;            // Top left X
-  pos_d.x = 50;            // Top left Y
-  pos_d.y2 = 30;
-  pos_d.x3 = 60;
-  pos_d.y3 = 90;
-  pos_d.x4 = 120;
-  pos_d.y4 = 150;
-*/
+int VideoOMX::setPosition(int x, int y) {
+	if (!initted)
+		return 0;
+	xpos = ((float) x*2.f) / ((float) screenWidth);
+	ypos = ((float) y*2.f) / ((float) screenHeight);
 
-//  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
-  return 1;
+	updateMode();
+	return 1;
 }
 
 int VideoOMX::sync()
@@ -759,7 +808,7 @@ int VideoOMX::AllocateCodecsOMX()
 		DeAllocateCodecsOMX();
 		return 0;
 	}
-	clock_mutex.Unlock();
+
 
 
 	Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
@@ -888,7 +937,7 @@ int VideoOMX::AllocateCodecsOMX()
 	}
 
 	//raspbi specifif
-	OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
+	/*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
 	memset(&dispconf,0,sizeof(dispconf));
 	dispconf.nSize=sizeof(dispconf);
 	dispconf.nVersion.nVersion=OMX_VERSION;
@@ -903,7 +952,7 @@ int VideoOMX::AllocateCodecsOMX()
 		clock_mutex.Unlock();
 		DeAllocateCodecsOMX();
 		return 0;
-	}
+	}*/
 
 /*	dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
 	dispconf.fullscreen=OMX_FALSE;
@@ -934,6 +983,7 @@ int VideoOMX::AllocateCodecsOMX()
 	iframemode=false;
 	omx_running=true;
 	clock_mutex.Unlock();
+	updateMode();
 	threadStart();
 
 	setClockExecutingandRunning();
diff --git a/videoomx.h b/videoomx.h
index 8695438..260774a 100644
--- a/videoomx.h
+++ b/videoomx.h
@@ -239,6 +239,9 @@ class VideoOMX : public Video, public Thread_TYPE
 
 	   bool omx_mpeg2;
 	   bool omx_h264;
+	   UCHAR mode;
+	   float xpos,ypos;
+	   void updateMode();//called internally to adjust for different parameters
 
 
 
-- 
2.39.5