Hello, On 12/25/2012 09:02 PM, Reinhard Nissl wrote:
Hi,
[..]
I appreciate your patches and will have a look at it during the next days.
after some clarifications of the new API, thanks to Klaus and "Johns" the author of the softhddevice output device plugin, here is a new version of the scaling API patch for vdr-xine.
Regards, Lucian
diff -Naur xine-0.9.4_orig/xineDevice.c xine-0.9.4/xineDevice.c --- xine-0.9.4_orig/xineDevice.c 2011-02-27 19:14:19.000000000 +0100 +++ xine-0.9.4/xineDevice.c 2013-01-03 21:54:57.585874032 +0100 @@ -4405,5 +4405,83 @@ { 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 -Naur xine-0.9.4_orig/xineDevice.h xine-0.9.4/xineDevice.h --- xine-0.9.4_orig/xineDevice.h 2011-02-27 15:28:58.000000000 +0100 +++ xine-0.9.4/xineDevice.h 2013-01-03 21:55:07.480878044 +0100 @@ -162,7 +162,14 @@ #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 -Naur xine-0.9.4_orig/xineOsd.c xine-0.9.4/xineOsd.c --- xine-0.9.4_orig/xineOsd.c 2011-03-15 21:00:18.000000000 +0100 +++ xine-0.9.4/xineOsd.c 2013-01-03 21:54:10.282851266 +0100 @@ -105,11 +105,20 @@ #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 @@ cXineOsd::~cXineOsd() { + #if APIVERSNUM < 10509 HideOsd(); #else
_______________________________________________ vdr mailing list vdr@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr