From patchwork Sun Dec 23 22:01:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucian Muresan X-Patchwork-Id: 15979 Received: from localhost ([127.0.0.1] helo=www.linuxtv.org) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1Tmtcb-0008Of-4j; Sun, 23 Dec 2012 23:02:13 +0100 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1TmtcA-0008FG-DC for vdr@linuxtv.org; Sun, 23 Dec 2012 23:02:10 +0100 X-tubIT-Incoming-IP: 209.85.215.173 Received: from mail-ea0-f173.google.com ([209.85.215.173]) by mail.tu-berlin.de (exim-4.75/mailfrontend-3) with esmtps [TLSv1:RC4-SHA:128] for id 1TmtcA-0000Zo-DS; Sun, 23 Dec 2012 23:01:46 +0100 Received: by mail-ea0-f173.google.com with SMTP id i13so2743510eaa.32 for ; Sun, 23 Dec 2012 14:01:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:message-id:date:from:user-agent:mime-version:to :subject:content-type; bh=aJMbVWeFfVc2TIxnUfwVw3EXXHSbPFHxjLOCxZ+UpcY=; b=Bp6RClzg68RsX+l7UEYhB7kgN9wcWnlVszVaLU1yWQkGorjcxFFVRix9OtQjUzEHuF fsdvtABXYnxNmPnt2C+l5Nzh7JubdR2166uuZiUiBEX01sLyqYkLo0zdnc/zHNcfvXXP ivtGvU80k3pNP7I4Vg8VjRcutGCPzYJ3Gl0TN4BbJ9GsQg8C2V3C9UgmTMVvq9j0NF5o sv7dZpFX7cJHp4pQ2P5aunPVE282ur2FgaF1YOt8gpUQA3XYOnxAwanhseeIdUrOYEy3 C9qIoA/lqSIN40ddFnNJ3E4uBqHxcyPd0zgEtrR4JZrxj/Pa0Wm8cIuMIjBdFtR9X7F9 h0NA== X-Received: by 10.14.223.200 with SMTP id v48mr50726086eep.24.1356300104828; Sun, 23 Dec 2012 14:01:44 -0800 (PST) Received: from [192.168.178.24] (p549533CB.dip.t-dialin.net. [84.149.51.203]) by mx.google.com with ESMTPS id k4sm37317329eep.15.2012.12.23.14.01.42 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 23 Dec 2012 14:01:43 -0800 (PST) Message-ID: <50D77F4A.8060004@users.sourceforge.net> Date: Sun, 23 Dec 2012 23:01:46 +0100 From: Lucian Muresan User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: vdr@linuxtv.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.12.23.215119 X-PMX-Spam: Gauge=XI, Probability=11%, Report=' WEBMAIL_REPLYTO_NOT_FROM 0.5, RCVD_FROM_IP_DATE 0.1, HTML_00_01 0.05, HTML_00_10 0.05, MIME_TEXT_ONLY_MP_MIXED 0.05, BODYTEXTP_SIZE_3000_LESS 0, DKIM_SIGNATURE 0, RATWARE_LC_DIGITS_MSGID 0, WEBMAIL_SOURCE 0, __ANY_URI 0, __BAT_BOUNDARY 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __CTYPE_MULTIPART_MIXED 0, __FRAUD_WEBMAIL 0, __FRAUD_WEBMAIL_SENDER 0, __HAS_FROM 0, __HAS_MSGID 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MOZILLA_MSGID 0, __MOZILLA_USER_AGENT 0, __PHISH_SPEAR_STRUCTURE_1 0, __RDNS_GMAIL 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_MAILTO 0, __URI_NS , __USER_AGENT 0, __YOUTUBE_RCVD 0' X-LSpam-Score: -0.8 (/) X-LSpam-Report: No, score=-0.8 required=5.0 tests=BAYES_00=-1.9, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RDNS_NONE=0.793, T_DKIM_INVALID=0.01 autolearn=no Subject: [vdr] [PATCH] vdr-xine-0.9.4 vdr-1.7.33 video scaling API (YAEPG-Hack now obsolete) X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: vdr-bounces@linuxtv.org Errors-To: vdr-bounces@linuxtv.org Hi, attached you'll find a patch against vdr-xine-0.9.4 that makes use of the new video scaling API introduced in vdr-1.7.33, yielding correct aspect ratio when scaling. How can it be used? Well, have a look at yaepg-hd patched with [1], but even more exciting when the video output plugin supports true color OSD (unfortunately vdr-xine can do this only in non-X11-overlay mode) is the new true color skin nOpacity [2]. BTW, Reinhard, do you still plan on maintaining vdr-xine? I was wondering because the homepage of the plugin is no longer accessible... [1] https://github.com/lucianm/gen2ovl-googoo2/tree/master/media-plugins/vdr-yaepghd/files [2] http://www.vdr-portal.de/board16-video-disk-recorder/board55-vdr-plugins/p1112090-nopacity-0-0-4/#post1112090 Regards & Happy Christmas, Lucian P.S. Just for convenience, I also attached the obligatory PmtParser Patch. 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 2012-12-23 22:06:02.578457473 +0100 @@ -4405,5 +4405,84 @@ { 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 + + // so let's just remember what the next call to ScaleVideo should actually use as a rectangle + // argument if called with cRect(-1,-1,-1,-1) + 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*/) + { + const cRect * actualRect = &Rect; + if (Rect == cRect(-1,-1,-1,-1)) { + // actual rectangle was stored here by the previous call to CanScaleVideo + actualRect = &vidWinRect; + } else { + actualRect = &Rect; + // remember the value, just for the case we were called explicitly with a real value + vidWinRect = *actualRect; + } + // 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 = actualRect->X(); + vidWinArea.y1 = actualRect->Y(); + vidWinArea.x2 = actualRect->X() + actualRect->Width(); + vidWinArea.y2 = actualRect->Y() + actualRect->Height(); + if (*actualRect == 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 = actualRect->Height() * (videoAspect * aspectFactor); + int output_height = actualRect->Width() / (videoAspect * aspectFactor); + if (double(actualRect->Width())/double(actualRect->Height()) > videoAspect * aspectFactor) { + output_height = actualRect->Height(); + vidWinArea.x1 += (actualRect->Width() - output_width) / 2; + } + else if (double(actualRect->Width())/double(actualRect->Height()) < videoAspect * aspectFactor) { + output_width = actualRect->Width(); + vidWinArea.y1 += (actualRect->Height() - output_height) / 2; + } + vidWinArea.x2 = vidWinArea.x1 + output_width; + vidWinArea.y2 = vidWinArea.y1 + output_height; + } + m_xineLib.SetVideoWindow(videoWidth, videoHeight, vidWinArea); + } +#endif }; 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 2012-12-23 22:03:34.530316428 +0100 @@ -162,7 +162,13 @@ #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); + private: + cRect vidWinRect; + public: +#endif 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 2012-12-23 22:03:16.702299730 +0100 @@ -105,11 +105,21 @@ #else +#if APIVERSNUM >= 10733 + + // scale to the size and position stored by the last call to cDevice::CanScaleVideo + // by passing a cRect(-1,-1,-1,-1) as by our convention + m_xineDevice.ScaleVideo(cRect(-1,-1,-1,-1)); + +#else + #ifdef SET_VIDEO_WINDOW m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin, dontOptimize); #endif + +#endif // APIVERSNUM >= 10733 int videoLeft = frameLeft; int videoTop = frameTop; @@ -175,6 +185,13 @@ cXineOsd::~cXineOsd() { +#if APIVERSNUM >= 10733 + + // re-scale to full size when distroying the Osd + m_xineDevice.ScaleVideo(); + +#endif + #if APIVERSNUM < 10509 HideOsd(); #else @@ -410,11 +427,21 @@ int maxOsdWidth, maxOsdHeight; GetMaxOsdSize(maxOsdWidth, maxOsdHeight); +#if APIVERSNUM >= 10733 + + // scale to the size and position stored by the last call to cDevice::CanScaleVideo + // by passing a cRect(-1,-1,-1,-1) as by our convention + m_xineDevice.ScaleVideo(cRect(-1,-1,-1,-1)); + +#else + #ifdef SET_VIDEO_WINDOW m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin); #endif + +#endif // APIVERSNUM >= 10733 int videoLeft = -1; int videoTop = -1; 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 2012-12-22 18:42:36.389557075 +0100 @@ -1200,7 +1200,11 @@ int pid = TsPid(Data); if (pid == 0) patPmtParser.ParsePat(Data, TS_SIZE); +#if APIVERSNUM >= 10732 + else if (patPmtParser.IsPmtPid(pid)) +#else else if (pid == patPmtParser.PmtPid()) +#endif patPmtParser.ParsePmt(Data, TS_SIZE); else if (pid == patPmtParser.Vpid()) {