summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucian Muresan <lucianm@users.sourceforge.net>2015-10-07 19:34:10 +0200
committerTobias Grimm <etobi@debian.org>2015-10-07 19:37:51 +0200
commitc9ae571d6375286dc081024b9d3dcc0cf15f2f3d (patch)
tree30be7678b24a51eef89b4e9bf58cc061d174a183
parentc18a8256c6e347da7f53d577802a194c9f45c605 (diff)
downloadvdr-plugin-xine-c9ae571d6375286dc081024b9d3dcc0cf15f2f3d.tar.gz
vdr-plugin-xine-c9ae571d6375286dc081024b9d3dcc0cf15f2f3d.tar.bz2
vdr-1.7.40
Origin: https://patchwork.linuxtv.org/patch/16100/
-rw-r--r--xineDevice.c78
-rw-r--r--xineDevice.h9
-rw-r--r--xineOsd.c18
3 files changed, 104 insertions, 1 deletions
diff --git a/xineDevice.c b/xineDevice.c
index 0129c21..f08b61b 100644
--- a/xineDevice.c
+++ b/xineDevice.c
@@ -4409,5 +4409,83 @@ store_frame(jumboPESdata, todo, __LINE__);
{
return theXineDevice;
}
+#if APIVERSNUM >= 10733
+ ///< Asks the output device whether it can scale the currently shown video in
+ ///< such a way that it fits into the given Rect, while retaining its proper
+ ///< aspect ratio. If the scaled video doesn't exactly fit into Rect, Alignment
+ ///< is used to determine how to align the actual rectangle with the requested
+ ///< one. The actual rectangle can be smaller, larger or the same size as the
+ ///< given Rect, and its location may differ, depending on the capabilities of
+ ///< the output device, which may not be able to display a scaled video at
+ ///< arbitrary sizes and locations. The device shall, however, do its best to
+ ///< match the requested Rect as closely as possible, preferring a size and
+ ///< location that fits completely into the requested Rect if possible.
+ ///< Returns the rectangle that can actually be used when scaling the video.
+ ///< A skin plugin using this function should rearrange its content according
+ ///< to the rectangle returned from calling this function, and should especially
+ ///< be prepared for cases where the returned rectangle is way off the requested
+ ///< Rect, or even Null. In such cases, the skin may want to fall back to
+ ///< working with full screen video.
+ ///< If this device can't scale the video, a Null rectangle is returned (this
+ ///< is also the default implementation).
+ cRect cXineDevice::CanScaleVideo(const cRect &Rect, int Alignment/* = taCenter*/)
+ {
+ // first implementation: we can always scale, we're a soft device ;-), ignore alignment for now
+
+ // we need to store the value for the case we have to call ScaleVideo ourselves in vdr-xine
+ vidWinRect = Rect;
+ return vidWinRect;
+ }
+
+ ///< Scales the currently shown video in such a way that it fits into the given
+ ///< Rect. Rect should be one retrieved through a previous call to
+ ///< CanScaleVideo() (otherwise results may be undefined).
+ ///< Even if video output is scaled, the functions GetVideoSize() and
+ ///< GetOsdSize() must still return the same values as if in full screen mode!
+ ///< If this device can't scale the video, nothing happens.
+ ///< To restore full screen video, call this function with a Null rectangle.
+ void cXineDevice::ScaleVideo(const cRect &Rect/* = cRect::Null*/)
+ {
+ // refresh stored value
+ vidWinRect = Rect;
+ // let our specialized code do the actual resizing / repositioning, get accurate parameters first
+ int videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, osdWidth, osdHeight;
+ double videoAspect, pixelAspect;
+ m_xineLib.execFuncVideoSize(videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, &videoAspect);
+ GetOsdSize(osdWidth, osdHeight, pixelAspect);
+ tArea vidWinArea;
+ vidWinArea.x1 = vidWinRect.X();
+ vidWinArea.y1 = vidWinRect.Y();
+ vidWinArea.x2 = vidWinRect.X() + vidWinRect.Width();
+ vidWinArea.y2 = vidWinRect.Y() + vidWinRect.Height();
+ if (vidWinRect == cRect::Null) {
+ // will just resize to full size
+ vidWinArea.bpp = 0;
+ } else {
+ vidWinArea.bpp = 12;
+ // make corrections
+ double aspectFactor = (double(osdWidth) / double(osdHeight)) / videoAspect;
+ int output_width = vidWinRect.Height() * (videoAspect * aspectFactor);
+ int output_height = vidWinRect.Width() / (videoAspect * aspectFactor);
+ if (double(vidWinRect.Width())/double(vidWinRect.Height()) > videoAspect * aspectFactor) {
+ output_height = vidWinRect.Height();
+ vidWinArea.x1 += (vidWinRect.Width() - output_width) / 2;
+ }
+ else if (double(vidWinRect.Width())/double(vidWinRect.Height()) < videoAspect * aspectFactor) {
+ output_width = vidWinRect.Width();
+ vidWinArea.y1 += (vidWinRect.Height() - output_height) / 2;
+ }
+ vidWinArea.x2 = vidWinArea.x1 + output_width;
+ vidWinArea.y2 = vidWinArea.y1 + output_height;
+ }
+ m_xineLib.SetVideoWindow(videoWidth, videoHeight, vidWinArea);
+ }
+
+ const cRect & cXineDevice::GetScaleRect()
+ {
+ // just return the stored value
+ return vidWinRect;
+ }
+#endif // APIVERSNUM >= 10733
};
diff --git a/xineDevice.h b/xineDevice.h
index 9a98837..5570e9f 100644
--- a/xineDevice.h
+++ b/xineDevice.h
@@ -162,7 +162,14 @@ namespace PluginXine
#else
void OnFreeOsd(cOsd *const osd);
#endif
-
+#if APIVERSNUM >= 10733
+ virtual cRect CanScaleVideo(const cRect &Rect, int Alignment = taCenter);
+ virtual void ScaleVideo(const cRect &Rect = cRect::Null);
+ const cRect & GetScaleRect();
+ private:
+ cRect vidWinRect;
+ public:
+#endif // APIVERSNUM >= 10733
cXineLib m_xineLib;
cMutex m_osdMutex;
diff --git a/xineOsd.c b/xineOsd.c
index 38ba2e7..186aab4 100644
--- a/xineOsd.c
+++ b/xineOsd.c
@@ -105,11 +105,20 @@ namespace PluginXine
#else
+#if APIVERSNUM >= 10733
+
+ // scale to the size and position stored by the last call to cDevice::CanScaleVideo
+ m_xineDevice.ScaleVideo(m_xineDevice.GetScaleRect());
+
+#else
+
#ifdef SET_VIDEO_WINDOW
m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin, dontOptimize);
#endif
+
+#endif // APIVERSNUM >= 10733
int videoLeft = frameLeft;
int videoTop = frameTop;
@@ -175,6 +184,7 @@ namespace PluginXine
cXineOsd::~cXineOsd()
{
+
#if APIVERSNUM < 10509
HideOsd();
#else
@@ -410,12 +420,20 @@ namespace PluginXine
int maxOsdWidth, maxOsdHeight;
GetMaxOsdSize(maxOsdWidth, maxOsdHeight);
+#if APIVERSNUM >= 10733
+
+ // scale to the size and position stored by the last call to cDevice::CanScaleVideo
+ m_xineDevice.ScaleVideo(m_xineDevice.GetScaleRect());
+
+#else
#ifdef SET_VIDEO_WINDOW
m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin);
#endif
+#endif // APIVERSUM >= 10733
+
int videoLeft = -1;
int videoTop = -1;
int videoWidth = -1;