diff options
| author | Lucian Muresan <lucianm@users.sourceforge.net> | 2015-10-07 19:34:10 +0200 |
|---|---|---|
| committer | Tobias Grimm <etobi@debian.org> | 2015-10-07 19:37:51 +0200 |
| commit | c9ae571d6375286dc081024b9d3dcc0cf15f2f3d (patch) | |
| tree | 30be7678b24a51eef89b4e9bf58cc061d174a183 | |
| parent | c18a8256c6e347da7f53d577802a194c9f45c605 (diff) | |
| download | vdr-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.c | 78 | ||||
| -rw-r--r-- | xineDevice.h | 9 | ||||
| -rw-r--r-- | xineOsd.c | 18 |
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; @@ -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; |
