summaryrefslogtreecommitdiff
path: root/src/test/FXTest.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/FXTest.py')
-rw-r--r--src/test/FXTest.py483
1 files changed, 483 insertions, 0 deletions
diff --git a/src/test/FXTest.py b/src/test/FXTest.py
new file mode 100644
index 0000000..de677a0
--- /dev/null
+++ b/src/test/FXTest.py
@@ -0,0 +1,483 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# libavg - Media Playback Engine.
+# Copyright (C) 2003-2014 Ulrich von Zadow
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Current versions can be found at www.libavg.de
+#
+
+from libavg import avg, utils, player
+from testcase import *
+
+
+class FXTestCase(AVGTestCase):
+ def __init__(self, testFuncName):
+ AVGTestCase.__init__(self, testFuncName)
+
+ def testImageNullFX(self):
+ def activateFX():
+ for node in self.nodes[0]:
+ node.setEffect(avg.NullFXNode())
+
+ def newNode():
+ self.newNode = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(64,0))
+ self.newNode.setEffect(avg.NullFXNode())
+
+ def newFX():
+ self.newNode.setEffect(avg.NullFXNode())
+
+ def addBgNode():
+ node = avg.RectNode(pos=(0,0), size=(64,96), fillopacity=1, opacity=0,
+ fillcolor="FFFFFF")
+ root.insertChild(node, 0)
+
+ def emptyImageFX():
+ node = avg.ImageNode(parent=root, href="", pos=(64,0))
+ node.setEffect(avg.NullFXNode())
+
+ # Initial setup is 3x2 images:
+ # rows: no alpha, alpha, alpha & opacity 0.6
+ # cols: no FX, FX
+ # The two cols should look the same.
+ root = self.loadEmptyScene()
+ self.nodes = []
+ for fx in (False, True):
+ curNodes = []
+ self.nodes.append(curNodes)
+ def configureNode(node, fx):
+ curNodes.append(node)
+ if fx:
+ node.x = 32
+ node.setEffect(avg.NullFXNode())
+
+ node = avg.ImageNode(parent=root, href="rgb24-32x32.png", pos=(0,0))
+ configureNode(node, fx)
+ node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,32))
+ configureNode(node, fx)
+ node = avg.ImageNode(parent=root, href="rgb24alpha-32x32.png", pos=(0,64),
+ opacity=0.6)
+ configureNode(node, fx)
+
+ self.start(False,
+ (lambda: self.compareImage("testImageNullFX1"),
+ addBgNode,
+ lambda: self.compareImage("testImageNullFX2"),
+ activateFX,
+ lambda: self.compareImage("testImageNullFX2"),
+ newNode,
+ lambda: self.compareImage("testImageNullFX3"),
+ newFX,
+ lambda: self.compareImage("testImageNullFX3"),
+ emptyImageFX,
+ lambda: utils.initFXCache(10),
+ ))
+
+ def testVideoNullFX(self):
+ root = self.loadEmptyScene()
+ player.setFakeFPS(25)
+ node = avg.VideoNode(parent=root, href="mjpeg-48x48.avi",
+ threaded=False)
+ node.setEffect(avg.NullFXNode())
+ node.play()
+ self.start(False, (lambda: self.compareImage("testVideoNullFX"),))
+
+ def testWordsNullFX(self):
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(parent=root, text="testtext", font="Bitstream Vera Sans")
+ node.setEffect(avg.NullFXNode())
+ node = avg.WordsNode(parent=root, text="testtext", pos=(0,20),
+ font="Bitstream Vera Sans")
+ self.start(True,
+ (lambda: self.compareImage("testWordsNullFX"),
+ ))
+
+ def testCanvasNullFX(self):
+ def setOuterOpacity():
+ node.opacity=0.6
+
+ def setInnerOpacity():
+ innerNode = canvas.getElementByID("test")
+ innerNode.opacity = 0.0
+
+ root = self.loadEmptyScene()
+ canvas = self.__createOffscreenCanvas()
+ node = avg.ImageNode(parent=root, href="canvas:offscreen")
+ node.setEffect(avg.NullFXNode())
+ self.start(False,
+ (lambda: self.compareImage("testCanvasNullFX1"),
+ setOuterOpacity,
+ lambda: self.compareImage("testCanvasNullFX2"),
+ setInnerOpacity,
+ lambda: self.compareImage("testCanvasNullFX3"),
+ ))
+
+ def testNodeInCanvasNullFX(self):
+ root = self.loadEmptyScene()
+ canvas = self.__createOffscreenCanvas()
+ avg.ImageNode(parent=root, href="canvas:offscreen")
+ node = canvas.getElementByID("test")
+ node.setEffect(avg.NullFXNode())
+ rect = avg.RectNode(size=(100,100), strokewidth=0, fillcolor="FF0000",
+ fillopacity=1)
+ canvas.getRootNode().insertChild(rect, 0)
+
+ self.start(False,
+ (lambda: self.compareImage("testNodeInCanvasNullFX1"),
+ ))
+
+ def testRenderPipeline(self):
+ sys.stderr.write("\n")
+ for useSrcCanvas in (False, True):
+ for useDestCanvas in (False, True):
+ for useFX in (False, True):
+ for useColorConv in (False, True):
+ sys.stderr.write(" "+str(useSrcCanvas)+" "+str(useDestCanvas)+
+ " "+str(useFX)+" "+str(useColorConv)+"\n")
+ root = self.loadEmptyScene()
+ if useSrcCanvas:
+ srcCanvas = player.createCanvas(id="src", size=(160,120),
+ mediadir="media")
+ avg.ImageNode(href="rgb24alpha-64x64.png",
+ parent=srcCanvas.getRootNode())
+ srcImg = avg.ImageNode(href="canvas:src")
+ else:
+ srcImg = avg.ImageNode(href="rgb24alpha-64x64.png")
+ if useFX:
+ srcImg.setEffect(avg.NullFXNode())
+ if useColorConv:
+ srcImg.contrast = (1.01, 1.0, 1.0)
+ if useDestCanvas:
+ destCanvas = player.createCanvas(id="dest",
+ size=(160,120), mediadir="media")
+ destCanvas.getRootNode().appendChild(srcImg)
+ avg.ImageNode(href="canvas:dest", parent=root)
+ else:
+ root.appendChild(srcImg)
+ self.start(False,
+ (lambda: self.compareImage("testRenderPipeline"),
+ ))
+
+ def testBlurFX(self):
+
+ def setRadius(radius):
+ self.effect.radius = radius
+
+ def removeFX():
+ self.node.setEffect(None)
+
+ def reAddFX():
+ self.node.setEffect(self.effect)
+
+ def addNewFX():
+ effect = avg.BlurFXNode(8)
+ self.node.setEffect(effect)
+
+ root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24-64x64.png")
+ self.effect = avg.BlurFXNode()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.node.setEffect(self.effect),
+ lambda: self.compareImage("testBlurFX1"),
+ lambda: setRadius(8),
+ lambda: self.compareImage("testBlurFX2"),
+ removeFX,
+ lambda: self.compareImage("testBlurFX3"),
+ reAddFX,
+ lambda: self.compareImage("testBlurFX2"),
+ removeFX,
+ addNewFX,
+ lambda: self.compareImage("testBlurFX2"),
+ lambda: setRadius(300),
+ ))
+
+ def testHueSatFX(self):
+
+ def resetFX():
+ self.effect = avg.HueSatFXNode()
+ self.node.setEffect(self.effect)
+
+ def setParam(param, value):
+ assert(hasattr(self.effect, param))
+ setattr(self.effect, param, value)
+
+ root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=root, pos=(10,10), href="rgb24alpha-64x64.png")
+ resetFX()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.compareImage("testHueSatFX1"),
+ lambda: setParam('saturation', -50),
+ lambda: self.compareImage("testHueSatFX2"),
+ lambda: setParam('saturation', -100),
+ lambda: self.compareImage("testHueSatFX3"),
+ lambda: setParam('saturation', -150),
+ lambda: self.compareImage("testHueSatFX3"),
+ resetFX,
+ lambda: setParam('hue', 180),
+ lambda: self.compareImage("testHueSatFX4"),
+ lambda: setParam('hue', -180),
+ lambda: self.compareImage("testHueSatFX4"),
+ ))
+
+ def testInvertFX(self):
+
+ def resetFX():
+ self.effect = avg.InvertFXNode()
+ self.node.setEffect(self.effect)
+
+ def redAlphaScene():
+ self.redRect = avg.RectNode(parent=self.root, pos=(5, 5), fillcolor='FF0000',
+ fillopacity=1, opacity=0, size=(72, 72))
+ self.node = avg.ImageNode(parent=self.root, pos=(10,10),
+ href="rgb24alpha-64x64.png")
+ resetFX()
+
+ self.root = self.loadEmptyScene()
+ self.node = avg.ImageNode(parent=self.root, pos=(10,10), href="hsl.png")
+ resetFX()
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: self.compareImage("testInvertFX1"),
+ redAlphaScene,
+ lambda: self.compareImage("testInvertFX2"),
+ ))
+
+ def testShadowFX(self):
+
+ def setParams(offset, radius, opacity, color):
+ effect.offset = offset
+ effect.radius = radius
+ effect.opacity = opacity
+ effect.color = color
+
+ root = self.loadEmptyScene()
+ rect = avg.RectNode(parent=root, pos=(9.5,9.5), color="0000FF")
+ node = avg.ImageNode(parent=root, pos=(10,10), href="shadow.png")
+ rect.size = node.size + (1, 1)
+ effect = avg.ShadowFXNode((0,0), 1, 1, "FFFFFF")
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testShadowFX1"),
+ lambda: setParams((0,0), 3, 2, "00FFFF"),
+ lambda: self.compareImage("testShadowFX2"),
+ lambda: setParams((2,2), 0.1, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX3"),
+ lambda: setParams((-2,-2), 0.1, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX4"),
+ lambda: setParams((-2,-2), 3, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX5"),
+ lambda: setParams((0,0), 0, 1, "FFFFFF"),
+ lambda: self.compareImage("testShadowFX6"),
+ ))
+
+ def testWordsShadowFX(self):
+
+ def setParams(offset, radius, opacity, color):
+ effect.offset = offset
+ effect.radius = radius
+ effect.opacity = opacity
+ effect.color = color
+
+ root = self.loadEmptyScene()
+ node = avg.WordsNode(parent=root, pos=(10,10), text="testtext",
+ font="Bitstream Vera Sans")
+ effect = avg.ShadowFXNode()
+ setParams((0,0), 1.5, 1.5, "FF0000")
+ self.start(True,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testWordsShadowFX1"),
+ lambda: setParams((2,2), 2, 2, "00FFFF"),
+ lambda: self.compareImage("testWordsShadowFX2"),
+ ))
+
+ def testGamma(self):
+ def setGamma(val):
+ node.gamma = val
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", gamma=(0.5,0.5,0.5))
+ self.assertEqual(node.gamma, (0.5,0.5,0.5))
+ self.start(False,
+ (lambda: self.compareImage("testGamma1"),
+ lambda: setGamma((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.gamma, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testGamma2"),
+ ))
+
+ def testIntensity(self):
+ def setIntensity(val):
+ node.intensity = val
+
+ def showVideo():
+ node.unlink(True)
+ self.videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False,
+ href="mpeg1-48x48.mov", intensity=(0.5,0.5,0.5))
+ self.videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", intensity=(0.5,0.5,0.5))
+ self.assertEqual(node.intensity, (0.5,0.5,0.5))
+ player.setFakeFPS(10)
+ self.start(False,
+ (lambda: self.compareImage("testIntensity1"),
+ lambda: setIntensity((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.intensity, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testIntensity2"),
+ showVideo,
+ lambda: self.compareImage("testIntensity3"),
+ ))
+ player.setFakeFPS(-1)
+ self.videoNode = None
+
+ def testWordsIntensity(self):
+ root = self.loadEmptyScene()
+ avg.WordsNode(parent=root, fontsize=24, font="Bitstream Vera Sans",
+ intensity=(0.5,0.5,0.5), text="brightness",
+ width=140)
+ self.start(True,
+ (lambda: self.compareImage("testWordsIntensity"),
+ ))
+
+
+ def testContrast(self):
+ def setContrast(val):
+ node.contrast = val
+
+ def showVideo():
+ node.unlink(True)
+ videoNode = avg.VideoNode(parent=root, size=(96,96), threaded=False,
+ href="mpeg1-48x48.mov", contrast=(0.5,0.5,0.5))
+ videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="colorramp.png", contrast=(0.5,0.5,0.5))
+ self.assertEqual(node.contrast, (0.5,0.5,0.5))
+ player.setFakeFPS(10)
+ self.start(False,
+ (lambda: self.compareImage("testContrast1"),
+ lambda: setContrast((1.5,2.0,2.5)),
+ lambda: self.assertEqual(node.contrast, (1.5,2.0,2.5)),
+ lambda: self.compareImage("testContrast2"),
+ showVideo,
+ lambda: self.compareImage("testContrast3"),
+ ))
+ player.setFakeFPS(-1)
+
+ def testFXUpdate(self):
+ # This tests if the FX render-on-demand functionality doesn't forget updates.
+ def changeTexture():
+ node.href = "colorramp.png"
+
+ def addMaskTex():
+ node.maskhref = "mask.png"
+
+ def changeMaskTex():
+ node.maskhref = "mask2.png"
+
+ def changeMaskPos():
+ node.maskpos = (10, 10)
+
+ def changeFX():
+ effect.radius = 2
+
+ def addVideo():
+ node.unlink(True)
+ videoNode = avg.VideoNode(parent=root, threaded=False, size=(96,96),
+ href="mpeg1-48x48.mov")
+ effect = avg.BlurFXNode()
+ effect.radius = 0
+ videoNode.setEffect(effect)
+ videoNode.play()
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="rgb24alpha-64x64.png")
+ effect = avg.BlurFXNode()
+ effect.radius = 0
+ player.setFakeFPS(25)
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ changeTexture,
+ lambda: self.compareImage("testFXUpdateTex"),
+ addMaskTex,
+ lambda: self.compareImage("testFXUpdateMaskTex1"),
+ changeMaskTex,
+ lambda: self.compareImage("testFXUpdateMaskTex2"),
+ changeMaskPos,
+ lambda: self.compareImage("testFXUpdateMaskPos"),
+ changeFX,
+ lambda: self.compareImage("testFXUpdateFX"),
+ addVideo,
+ None,
+ lambda: self.compareImage("testFXUpdateVideo"),
+ ))
+
+ def testChromaKeyFX(self):
+
+ def setParams(htol, ltol, stol):
+ effect.htolerance = htol
+ effect.ltolerance = ltol
+ effect.stolerance = stol
+
+ root = self.loadEmptyScene()
+ node = avg.ImageNode(parent=root, href="rgb24-64x64.png")
+ effect = avg.ChromaKeyFXNode()
+ setParams(0.01, 0.01, 0.01)
+ self.start(False,
+ (self.skipIfMinimalShader,
+ lambda: node.setEffect(effect),
+ lambda: self.compareImage("testChromaKeyFX1"),
+ lambda: setParams(0.2, 0.2, 0.2),
+ lambda: self.compareImage("testChromaKeyFX2"),
+ lambda: effect.__setattr__("color", "FF0000"),
+ lambda: self.compareImage("testChromaKeyFX3"),
+ lambda: effect.__setattr__("spillthreshold", 1),
+ lambda: self.compareImage("testChromaKeyFX4"),
+ ))
+
+ def __createOffscreenCanvas(self):
+ canvas = player.createCanvas(id="offscreen", size=(160,120), mediadir="media")
+ root = canvas.getRootNode()
+ avg.ImageNode(href="rgb24-32x32.png", parent=root)
+ avg.ImageNode(id="test", pos=(32,0), href="rgb24alpha-32x32.png", parent=root)
+ return canvas
+
+
+def fxTestSuite(tests):
+ availableTests = [
+ "testImageNullFX",
+ "testVideoNullFX",
+ "testWordsNullFX",
+ "testCanvasNullFX",
+ "testNodeInCanvasNullFX",
+ "testRenderPipeline",
+ "testBlurFX",
+ "testHueSatFX",
+ "testInvertFX",
+ "testShadowFX",
+ "testWordsShadowFX",
+ "testGamma",
+ "testIntensity",
+ "testWordsIntensity",
+ "testContrast",
+ "testFXUpdate",
+ "testChromaKeyFX",
+ ]
+ return createAVGTestSuite(availableTests, FXTestCase, tests)