summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
committerDimitri John Ledkov <xnox@ubuntu.com>2014-06-24 20:05:13 +0100
commitdd22bd15f6ed3e5eb5c77ab427029be50fe20148 (patch)
treed9491ee40d80688b7f5b1f20504f022686827a57 /src/utils
libavg (1.8.1-1) unstable; urgency=medium
* New upstream release (Closes: #739664) * Mark libdc1394-22-dev as linux-any build-dependency. * Add libvdpau-dev build-dependency. * Add libavresample-dev build-dependency. # imported from the archive
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/Makefile.am5
-rwxr-xr-xsrc/utils/avg_audioplayer.py49
-rwxr-xr-xsrc/utils/avg_checkpolygonspeed.py145
-rwxr-xr-xsrc/utils/avg_checkspeed.py141
-rwxr-xr-xsrc/utils/avg_checktouch.py57
-rwxr-xr-xsrc/utils/avg_checkvsync.py44
-rwxr-xr-xsrc/utils/avg_chromakey.py189
-rwxr-xr-xsrc/utils/avg_jitterfilter.py111
-rwxr-xr-xsrc/utils/avg_showcamera.py201
-rwxr-xr-xsrc/utils/avg_showfile.py38
-rwxr-xr-xsrc/utils/avg_showfont.py68
-rwxr-xr-xsrc/utils/avg_showsvg.py63
-rwxr-xr-xsrc/utils/avg_videoinfo.py275
-rwxr-xr-xsrc/utils/avg_videoplayer.py143
14 files changed, 1529 insertions, 0 deletions
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
new file mode 100644
index 0000000..7527ad7
--- /dev/null
+++ b/src/utils/Makefile.am
@@ -0,0 +1,5 @@
+bin_SCRIPTS = avg_audioplayer.py avg_chromakey.py avg_showcamera.py avg_showfile.py \
+ avg_showfont.py avg_videoinfo.py avg_videoplayer.py avg_checkvsync.py \
+ avg_checktouch.py avg_showsvg.py avg_checkspeed.py \
+ avg_checkpolygonspeed.py avg_jitterfilter.py
+pkgpyexec_PYTHON = $(bin_SCRIPTS)
diff --git a/src/utils/avg_audioplayer.py b/src/utils/avg_audioplayer.py
new file mode 100755
index 0000000..1355bbf
--- /dev/null
+++ b/src/utils/avg_audioplayer.py
@@ -0,0 +1,49 @@
+#!/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
+
+import sys
+from libavg import avg, app, player
+
+
+class AudioPlayerDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog <filename>")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+ self._audioFName = args[0]
+
+ def onInit(self):
+ self._node = avg.SoundNode(parent=self, href=self._audioFName)
+ self._node.play()
+ self._words = avg.WordsNode(parent=self, pos=(10, 22), fontsize=10)
+
+ def onFrame(self):
+ curTime = self._node.getCurTime()
+ self._words.text = "Time: "+str(curTime/1000.0)
+
+
+if __name__ == "__main__":
+ app.App().run(AudioPlayerDiv(), app_resolution="320x200")
+
diff --git a/src/utils/avg_checkpolygonspeed.py b/src/utils/avg_checkpolygonspeed.py
new file mode 100755
index 0000000..409d3a3
--- /dev/null
+++ b/src/utils/avg_checkpolygonspeed.py
@@ -0,0 +1,145 @@
+#!/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
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+from libavg import *
+
+import random
+import math
+import time
+
+R = 40.0
+g_Trigger = True
+
+
+class SpeedDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ usage = '%prog [options]\n' \
+ 'Checks libavg performance by creating lots of polygon nodes. ' \
+ 'Displays a frame time graph and executes for 20 secs.'
+ parser.set_usage(usage)
+
+ parser.add_option('--hole-polygon', '-y', dest='hole',
+ action='store_true', default=False,
+ help='generate polygons with holes')
+ parser.add_option('--create-nodes', '-c', dest='create',
+ action='store_true', default=False,
+ help='destroy and recreate all nodes every 400 ms')
+ parser.add_option('--move', '-m', dest='move',
+ action='store_true', default=False,
+ help='move nodes every frame')
+ parser.add_option('--vsync', '-s', dest='vsync',
+ action='store_true', default=False,
+ help='sync output to vertical refresh')
+ parser.add_option('--num-objs', '-n', dest='numObjs',
+ type='int', default=40,
+ help='number of polygons to create [Default: 40]')
+ parser.add_option('--num-points', '-x', dest='numPoints',
+ type='int', default=10,
+ help='number of points in each polygon [Default: 10]')
+ parser.add_option('--profile', '-p', dest='profile',
+ action='store_true', default=False,
+ help='enable profiling output, note that profiling makes things slower')
+
+ def onArgvParsed(self, options, args, parser):
+ self.__optHole = options.hole
+ self.__optCreate = options.create
+ self.__optMove = options.move
+ self.__optVsync = options.vsync
+ self.__optNumObjs = options.numObjs
+ if self.__optNumObjs < 1:
+ self.__optNumObjs = 40
+ self.__optNumPoints = options.numPoints
+ if self.__optNumPoints < 10:
+ self.__optNumPoints = 10
+ elif self.__optNumPoints % 2 != 0:
+ self.__optNumPoints -= 1
+
+ log = avg.logger
+ log.configureCategory(log.Category.CONFIG, log.Severity.DBG)
+ if options.profile:
+ log.configureCategory(log.Category.PROFILE, log.Severity.DBG)
+
+ def onInit(self):
+ if not self.__optVsync:
+ player.setFramerate(1000)
+
+ tstart = time.time()
+ self.__createNodes()
+ print 'Time to create nodes: %f' % (time.time()-tstart)
+ app.instance.debugPanel.toggleWidget(app.debugpanel.FrametimeGraphWidget)
+ if self.__optCreate:
+ player.setInterval(400, self.__createNodes)
+ # Ignore the first frame for the 20 sec-limit so long startup times don't
+ # break things.
+ player.setTimeout(0, lambda: player.setTimeout(20000, player.stop))
+
+ def onFrame(self):
+ if self.__optMove:
+ self.__moveNodes()
+
+ def __createNodes(self):
+ self.__nodes = []
+ for i in xrange(self.__optNumObjs):
+ pos = (random.randrange(800-64), random.randrange(600-64))
+ polyPos = self.__calPolyCords(pos, R)
+ holes = []
+ if self.__optHole:
+ holes = (self.__calPolyCords(pos, R/2), )
+ node = avg.PolygonNode(parent=self, pos=polyPos, fillopacity=1, holes=holes)
+ self.__nodes.append(node)
+ if self.__optCreate:
+ player.setTimeout(300, self.__deleteNodes)
+
+ def __deleteNodes(self):
+ for node in self.__nodes:
+ node.unlink(True)
+ self.__nodes = []
+
+ def __moveNodes(self):
+ global g_Trigger
+ for node in self.__nodes:
+ newPos = []
+ if g_Trigger:
+ newPos = [(i[0]+1, i[1]+1) for i in node.pos]
+ else:
+ newPos = [(i[0]-1, i[1]-1) for i in node.pos]
+ node.pos = newPos
+ g_Trigger = not g_Trigger
+
+ def __calPolyCords(self, offset, r):
+ r2 = r/2
+ alpha = math.radians(360.0 / (self.__optNumPoints/2))
+ beta = alpha/2
+ result = []
+ for i in xrange(self.__optNumPoints/2):
+ result.append((r*math.cos(i*alpha) + offset[0],
+ r*math.sin(i*alpha) + offset[1]))
+ result.append((r2*math.cos(i*alpha+beta) + offset[0],
+ r2*math.sin(i*alpha+beta) + offset[1]))
+ return result
+
+
+if __name__ == '__main__':
+ app.App().run(SpeedDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_checkspeed.py b/src/utils/avg_checkspeed.py
new file mode 100755
index 0000000..87619df
--- /dev/null
+++ b/src/utils/avg_checkspeed.py
@@ -0,0 +1,141 @@
+#!/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
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+from libavg import *
+
+import random
+
+
+class SpeedDiv(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ usage = '%prog [options]\n' \
+ 'Checks libavg performance by creating lots of nodes. ' \
+ 'Displays a frame time graph and executes for 20 secs.'
+ parser.set_usage(usage)
+
+ parser.add_option('--use-fx', '-f', dest='useFX',
+ action='store_true', default=False,
+ help='display everything using a NullFX to test FX overhead')
+ parser.add_option('--video', '-i', dest='video',
+ action='store_true', default=False,
+ help='show videos instead of images')
+ parser.add_option('--audio', '-a', dest='audio',
+ action='store_true', default=False,
+ help='when showing videos, use videos with an audio channel')
+ parser.add_option('--create-nodes', '-c', dest='create',
+ action='store_true', default=False,
+ help='destroy and recreate all nodes every 400 ms')
+ parser.add_option('--move', '-m', dest='move',
+ action='store_true', default=False,
+ help='move nodes every frame')
+ parser.add_option('--blur', '-b', dest='blur',
+ action='store_true', default=False,
+ help='apply a BlurFXNode to the nodes')
+ parser.add_option('--color', '-o', dest='color',
+ action='store_true', default=False,
+ help='apply gamma to the nodes, causing the color correction shader to activate')
+ parser.add_option('--vsync', '-s', dest='vsync',
+ action='store_true', default=False,
+ help='sync output to vertical refresh')
+ parser.add_option('--num-objs', '-n', dest='numObjs',
+ type='int', default=-1,
+ help='number of objects to create [Default: 200 images or 40 videos]')
+ parser.add_option('--profile', '-p', dest='profile',
+ action='store_true', default=False,
+ help='enable profiling output, note that profiling makes things slower')
+
+ def onArgvParsed(self, options, args, parser):
+ self.__optUseFX = options.useFX
+ self.__optVideo = options.video
+ self.__optAudio = options.audio
+ self.__optCreate = options.create
+ self.__optMove = options.move
+ self.__optBlur = options.blur
+ self.__optColor = options.color
+ self.__optVsync = options.vsync
+ self.__optNumObjs = options.numObjs
+ if self.__optNumObjs < 1:
+ if self.__optVideo:
+ self.__optNumObjs = 40
+ else:
+ self.__optNumObjs = 200
+
+ log = avg.logger
+ log.configureCategory(log.Category.CONFIG, log.Severity.DBG)
+ if options.profile:
+ log.configureCategory(log.Category.PROFILE, log.Severity.DBG)
+
+ def onInit(self):
+ if not self.__optVsync:
+ player.setFramerate(1000)
+
+ self.mediadir = utils.getMediaDir(None, 'data')
+ self.__createNodes()
+ app.instance.debugPanel.toggleWidget(app.debugpanel.FrametimeGraphWidget)
+ if self.__optCreate:
+ player.setInterval(400, self.__createNodes)
+ # Ignore the first frame for the 20 sec-limit so long startup times don't
+ # break things.
+ player.setTimeout(0, lambda: player.setTimeout(20000, player.stop))
+
+ def onFrame(self):
+ if self.__optMove:
+ self.__moveNodes()
+
+ def __createNodes(self):
+ self.__nodes = []
+ for i in xrange(self.__optNumObjs):
+ pos = (random.randrange(800-64), random.randrange(600-64))
+ if self.__optVideo:
+ if self.__optAudio:
+ fname = "mpeg1-48x48-sound.avi"
+ else:
+ fname = "mpeg1-48x48.mov"
+ node = avg.VideoNode(pos=pos, href=fname, loop=True, parent=self)
+ node.play()
+ else:
+ node = avg.ImageNode(pos=pos, href="rgb24alpha-64x64.png", parent=self)
+ if self.__optUseFX:
+ node.setEffect(avg.NullFXNode())
+ if self.__optBlur:
+ node.setEffect(avg.BlurFXNode(10))
+ if self.__optColor:
+ node.gamma = (1.1, 1.1, 1.1)
+ self.__nodes.append(node)
+ if self.__optCreate:
+ player.setTimeout(300, self.__deleteNodes)
+
+ def __deleteNodes(self):
+ for node in self.__nodes:
+ node.unlink(True)
+ self.__nodes = []
+
+ def __moveNodes(self):
+ for node in self.__nodes:
+ node.pos = (random.randrange(800-64), random.randrange(600-64))
+
+
+if __name__ == '__main__':
+ app.App().run(SpeedDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_checktouch.py b/src/utils/avg_checktouch.py
new file mode 100755
index 0000000..15c0ccd
--- /dev/null
+++ b/src/utils/avg_checktouch.py
@@ -0,0 +1,57 @@
+#!/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 *
+
+
+class TouchApp(app.MainDiv):
+ def onArgvParsed(self, options, args, parser):
+ if self.settings.getBoolean("app_fullscreen"):
+ self.settings.set("app_resolution", "") # use screen resolution
+
+ def onInit(self):
+ self.subscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+ app.instance.debugPanel.toggleTouchVisualization()
+
+ def __onDown(self, event):
+# if event.source == avg.MOUSE:
+# print event.type, event.button
+# else:
+# print event.type
+ if (event.contact):
+ event.contact.subscribe(avg.Contact.CURSOR_MOTION, self.__onContact)
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onContact)
+ contact = event.contact
+# print "new contact: ", contact.id, event.pos, contact.age, \
+# contact.distancefromstart, contact.motionangle, contact.motionvec, \
+# contact.distancetravelled
+
+ def __onContact(self, event):
+ contact = event.contact
+# print event.type, contact.id, event.pos, contact.age, \
+# contact.distancefromstart, contact.motionangle, contact.motionvec, \
+# contact.distancetravelled, event.speed
+
+
+if __name__ == "__main__":
+ app.App().run(TouchApp(), app_resolution="800x600", multitouch_enabled="true")
+
diff --git a/src/utils/avg_checkvsync.py b/src/utils/avg_checkvsync.py
new file mode 100755
index 0000000..5dc89ce
--- /dev/null
+++ b/src/utils/avg_checkvsync.py
@@ -0,0 +1,44 @@
+#!/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
+#
+# Original author of this file is Robert Parcus <betoparcus@gmail.com>
+
+
+from libavg import avg, app
+
+
+class VSyncDiv(app.MainDiv):
+ def onInit(self):
+ self.__line = avg.LineNode(color='FFFFFF', parent=self)
+ self.__x = 0
+
+ def onFrame(self):
+ self.__x += 1
+ if self.__x == self.width:
+ self.__x = 0
+ self.__line.pos1 = (self.__x, 0)
+ self.__line.pos2 = (self.__x, self.height)
+
+
+if __name__ == '__main__':
+ app.App().run(VSyncDiv(), app_resolution='800x600')
+
diff --git a/src/utils/avg_chromakey.py b/src/utils/avg_chromakey.py
new file mode 100755
index 0000000..f572488
--- /dev/null
+++ b/src/utils/avg_chromakey.py
@@ -0,0 +1,189 @@
+#!/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, app, widget
+from libavg import parsecamargs
+
+GUI_SIZE=(300, 526)
+
+
+class FXSlider(avg.DivNode):
+ def __init__(self, row, min, max, fxNode, fxAttrName, caption, isInt, parent=None,
+ **kwargs):
+ super(FXSlider, self).__init__(**kwargs)
+ if parent:
+ parent.appendChild(self)
+ avg.RectNode(pos=(0,8), size=(280,38), color="808080", strokewidth=2, parent=self)
+ textBgRect = avg.RectNode(pos=(8,2), fillcolor="000000", fillopacity=1,
+ strokewidth=0, parent=self)
+ caption = avg.WordsNode(pos=(10,0), text=caption, parent=self)
+ textBgRect.size = caption.getMediaSize() + (4,2)
+ self.__words = avg.WordsNode(pos=(240,23), parent=self)
+ self.__slider = widget.Slider(width=220, range=(min,max), pos=(15,20), parent=self)
+ self.__slider.subscribe(self.__slider.THUMB_POS_CHANGED, self.__onSliderMove)
+ self.pos = (0, row*46)
+ self.__fxNode = fxNode
+ self.__fxAttrName = fxAttrName
+ self.__caption = caption
+ self.__isInt = isInt
+ self.__slider.thumbPos = getattr(self.__fxNode, fxAttrName)
+ self.__onSliderMove(self.__slider.thumbPos)
+
+ def __onSliderMove(self, thumbPos):
+ if self.__isInt:
+ setattr(self.__fxNode, self.__fxAttrName, int(thumbPos))
+ self.__words.text = "%i"%thumbPos
+ else:
+ setattr(self.__fxNode, self.__fxAttrName, thumbPos)
+ self.__words.text = "%.2f"%thumbPos
+
+
+def colorToString(colorTuple):
+ s = "%02X%02X%02X"%colorTuple[:-1]
+ return s
+
+
+class Chromakey(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage(usage)
+ parsecamargs.addOptions(parser)
+
+ def onArgvParsed(self, options, args, parser):
+ if options.driver is None:
+ parser.print_help()
+ print
+ print "ERROR: at least '--driver' must be specified"
+ exit(1)
+
+ self.__optWidth = options.width
+ self.__optHeight = options.height
+ self.__optsCam = {
+ "driver": options.driver,
+ "device": options.device,
+ "unit": options.unit,
+ "fw800": options.fw800,
+ "pixelformat": options.pixelFormat,
+ "framerate": options.framerate}
+
+ self.settings.set("app_resolution", "%dx%d"
+ %(GUI_SIZE[0]+options.width, max(GUI_SIZE[1], options.height)))
+
+ def onInit(self):
+ avg.RectNode(size=(self.__optWidth,self.__optHeight), fillcolor="FF0000",
+ fillopacity=1, strokewidth=0, parent=self)
+ self.__camNode = avg.CameraNode(
+ capturewidth=self.__optWidth, captureheight=self.__optHeight,
+ width=self.__optWidth, height=self.__optHeight, parent=self,
+ **self.__optsCam)
+ self.__camNode.play()
+ self.__filter = avg.ChromaKeyFXNode()
+ self.__camNode.setEffect(self.__filter)
+ self.__filter.color = "0000FF"
+ self.__filter.htolerance = 0.05
+ self.__filter.stolerance = 1.0
+ self.__filter.ltolerance = 1.0
+ self.__filter.softness = 0.0
+
+ self.__createGUI()
+
+ def __createGUI(self):
+ self.__guiDiv = avg.DivNode(pos=(self.__optWidth+10,10), parent=self)
+
+ self.__colorWords = avg.WordsNode(pos=(0,14), parent=self.__guiDiv)
+ self.__colorWords.text = "Key Color: "+self.__filter.color
+ self.__colorRect = avg.RectNode(pos=(200,12), size=(20, 20),
+ fillcolor=self.__filter.color, fillopacity=1,
+ color="FFFFFF", parent=self.__guiDiv)
+ self.__camNode.subscribe(avg.Node.CURSOR_DOWN, self.__onColorDown)
+
+ FXSlider(1, 0.0, 1.0, self.__filter, "htolerance", "Hue Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(2, 0.0, 1.0, self.__filter, "stolerance", "Saturation Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(3, 0.0, 1.0, self.__filter, "ltolerance", "Lightness Tolerance",
+ False, parent=self.__guiDiv)
+ FXSlider(4, 0.0, 1.0, self.__filter, "softness", "Softness",
+ False, parent=self.__guiDiv)
+ FXSlider(5, 0, 8, self.__filter, "erosion", "Erosion",
+ True, parent=self.__guiDiv)
+ FXSlider(6, 0.0, 1.0, self.__filter, "spillthreshold", "Spill Suppression",
+ False, parent=self.__guiDiv)
+
+ button = widget.TextButton(pos=(0,332), text="Whitebalance", size=(100,22),
+ parent=self.__guiDiv)
+ button.subscribe(button.CLICKED, self.__onWhitebalance)
+ button = widget.TextButton(pos=(110,332), text="Dump Config", size=(100,22),
+ parent=self.__guiDiv)
+ button.subscribe(button.CLICKED, self.__dumpConfig)
+
+ FXSlider(9, 0, 500, self.__camNode, "shutter", "Shutter",
+ True, parent=self.__guiDiv)
+ FXSlider(10, 128, 1023, self.__camNode, "gain", "Gain",
+ True, parent=self.__guiDiv)
+
+ def __onColorDown(self, event):
+ pos = self.__camNode.getRelPos(event.pos)
+ bmp = self.__camNode.getBitmap()
+ color = bmp.getPixel(pos)
+ colorString = colorToString(color)
+ self.__filter.color = colorString
+ self.__colorWords.text = "Key Color: "+colorString
+ self.__colorRect.fillcolor = colorString
+
+ def __onWhitebalance(self):
+ self.__camNode.setWhitebalance(
+ self.__camNode.getWhitebalanceU(), self.__camNode.getWhitebalanceV())
+ self.__camNode.doOneShotWhitebalance()
+
+ def __dumpConfig(self):
+ print "Camera:"
+ print " device=", self.__camNode.device
+ print " shutter=", self.__camNode.shutter
+ print " gain=", self.__camNode.gain
+ print " White Balance: (u=", self.__camNode.getWhitebalanceU(), ", v=", \
+ self.__camNode.getWhitebalanceV()
+
+ print "Chromakey:"
+ print " color=", self.__filter.color
+ print " htolerance=", self.__filter.htolerance
+ print " stolerance=", self.__filter.stolerance
+ print " ltolerance=", self.__filter.ltolerance
+ print " softness=", self.__filter.softness
+ print " erosion=", self.__filter.erosion
+ print " spillthreshold=", self.__filter.spillthreshold
+
+
+usage = """%prog [options]
+
+avg_chromakey.py is a configuration utility for the libavg chromakey filter.
+The chromakey filter allows implementation of green- or bluescreens with
+libavg.
+
+This utility shows a camera image with chromakey applied to it and allows the
+user to adjust the camera and filter parameters. The parameters can be dumped
+to the console for easy inclusion in libavg scripts.
+"""
+
+
+if __name__ == "__main__":
+ app.App().run(Chromakey())
+
diff --git a/src/utils/avg_jitterfilter.py b/src/utils/avg_jitterfilter.py
new file mode 100755
index 0000000..6b0f2cb
--- /dev/null
+++ b/src/utils/avg_jitterfilter.py
@@ -0,0 +1,111 @@
+#!/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, app, player, filter, widget
+
+
+class LabledSlider(avg.DivNode):
+ def __init__(self, label, range, formatStr, parent=None, **kwargs):
+ super(LabledSlider, self).__init__(**kwargs)
+ self.registerInstance(self, parent)
+ self.__formatStr = formatStr
+
+ fontStyle = widget.Skin.default.fonts["stdFont"]
+ avg.WordsNode(text=label, fontstyle=fontStyle, color="FFFFFF", parent=self)
+ self.__slider = widget.Slider(width=300, range=range, pos=(15,20), parent=self)
+ self.__slider.subscribe(self.__slider.THUMB_POS_CHANGED, self.__onSliderMove)
+ self.__valueDisplay = avg.WordsNode(pos=(320, 18), fontstyle=fontStyle,
+ color="FFFFFF", parent=self)
+ self.__valueDisplay.text = self.__formatStr%self.__slider.thumbPos
+
+ self.publish(widget.Slider.THUMB_POS_CHANGED)
+
+ def getThumbPos(self):
+ return self.__slider.thumbPos
+ thumbPos = property(getThumbPos)
+
+ def __onSliderMove(self, thumbPos):
+ self.notifySubscribers(widget.Slider.THUMB_POS_CHANGED, [thumbPos,])
+ self.__valueDisplay.text = self.__formatStr%thumbPos
+
+
+class JitterFilter(app.MainDiv):
+ def onArgvParsed(self, options, args, parser):
+ if self.settings.getBoolean("app_fullscreen"):
+ self.settings.set("app_resolution", "") # use screen resolution
+
+ def onInit(self):
+ self.__minCutoffSlider = LabledSlider(label="Minimum Cutoff", range=(0.3, 8.0),
+ formatStr="%.1f", pos=(10,10), parent=self)
+ self.__minCutoffSlider.subscribe(widget.Slider.THUMB_POS_CHANGED,
+ self.__onSliderMove)
+ self.__cutoffSlopeSlider = LabledSlider(label="Cutoff Slope", range=(0.0, 0.05),
+ formatStr="%.3f", pos=(10,50), parent=self)
+ self.__minCutoffSlider.subscribe(widget.Slider.THUMB_POS_CHANGED,
+ self.__onSliderMove)
+ self.__onSliderMove(avg.Point2D(0,0))
+
+ self.subscribe(avg.Node.CURSOR_DOWN, self.__onDown)
+ self.__contact = None
+ self.__rawContactCircle = avg.CircleNode(r=7*player.getPixelsPerMM(),
+ color="FF0000", opacity=0, parent=self)
+ self.__filteredContactCircle = avg.CircleNode(r=7*player.getPixelsPerMM(),
+ color="00FF00", opacity=0, parent=self)
+ self.__filters = None
+
+ def __onSliderMove(self, pos):
+ self.__minCutoff = self.__minCutoffSlider.thumbPos
+ self.__cutoffSlope = self.__cutoffSlopeSlider.thumbPos
+
+ def __onDown(self, event):
+ if self.__contact is None:
+ self.__contact = event.contact
+ event.contact.subscribe(avg.Contact.CURSOR_UP, self.__onUp)
+ self.__rawContactCircle.opacity = 1
+ self.__filteredContactCircle.opacity = 1
+ self.__filters = [
+ filter.OneEuroFilter(self.__minCutoff,self.__cutoffSlope),
+ filter.OneEuroFilter(self.__minCutoff,self.__cutoffSlope)]
+ self.__onFrame = player.subscribe(player.ON_FRAME, self.__moveContact)
+
+ def __onUp(self, event):
+ self.__rawContactCircle.opacity = 0
+ self.__filteredContactCircle.opacity = 0
+ self.__contact = None
+ self.__filters = None
+ player.unsubscribe(self.__onFrame)
+
+ def __moveContact(self):
+ time = player.getFrameTime()
+ rawPos = self.__contact.events[-1].pos
+ self.__rawContactCircle.pos = rawPos
+ filteredPos = avg.Point2D(self.__filters[0].apply(rawPos.x, time),
+ self.__filters[1].apply(rawPos.y, time))
+ self.__filteredContactCircle.pos = filteredPos
+
+
+if __name__ == "__main__":
+ app.App().run(JitterFilter(),
+ app_resolution="800x600",
+ app_show_cursor="true",
+ multitouch_enabled="true")
+
diff --git a/src/utils/avg_showcamera.py b/src/utils/avg_showcamera.py
new file mode 100755
index 0000000..4c2cc18
--- /dev/null
+++ b/src/utils/avg_showcamera.py
@@ -0,0 +1,201 @@
+#!/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
+
+import time
+from libavg import avg, player
+from libavg import parsecamargs
+from libavg import app
+
+usage = """%prog [options]
+
+avg_showcamera.py shows the images captured by a camera attached to the
+system. Its main use is to find out which parameters - device names,
+image formats, framerates, etc. can be used with the camera(s)."""
+
+
+class ShowCamera(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage(usage)
+ parsecamargs.addOptions(parser)
+ parser.add_option("-l", "--list", dest="list",
+ action="store_true", default=False,
+ help="lists informations about detected cameras")
+ parser.add_option("-s", "--noinfo", dest="noinfo",
+ action="store_true", default=False,
+ help="don't show any info overlayed on the screen")
+ parser.add_option("-r", "--resetbus", dest="resetbus",
+ action="store_true", default=False,
+ help="reset the firewire bus")
+
+ def onArgvParsed(self, options, args, parser):
+ if options.list:
+ infoList = list()
+ infoList = avg.CameraNode.getCamerasInfos()
+ if (len(infoList) <= 0):
+ print "No camera available!"
+ for info in infoList:
+ print ""
+ print "##################",info.driver,"##################"
+ print "Device ID:", info.deviceID
+ print ""
+ print "----------------- FORMATS ------------------"
+ formatsList = list()
+ formatsList = info.imageFormats
+ for format in formatsList:
+ print "++++"
+ print "Pixelformat:", format.pixelFormat
+ print "Resolution:", format.size
+ print "Framerates: |",
+ framerateList = list()
+ framerateList = format.framerates
+ for framerate in framerateList:
+ print framerate, "|",
+ print ""
+ print ""
+ print "----------------- CONTROLS -----------------"
+ controlsList = list()
+ controlsList = info.controls
+ for control in controlsList:
+ print "++++", control.controlName
+ print "Min:" , control.min, "| Max:", control.max,
+ print "| Default:", control.default
+ print ""
+ exit(0)
+
+ if options.resetbus:
+ avg.logger.info("Resetting firewire bus.")
+ avg.CameraNode.resetFirewireBus()
+ time.sleep(1)
+ if not options.driver:
+ exit(0)
+
+ if options.driver is None and not options.list and not options.resetbus:
+ parser.print_help()
+ print
+ print "ERROR: at least '--driver', '--list' or '--resetbus' options " \
+ "must be specified"
+ exit(1)
+
+ self.optdict = {}
+ for attr in dir(options):
+ if attr[0] != '_':
+ self.optdict[attr] = eval("options.%s" %attr)
+
+ self.settings.set("app_resolution", "%dx%d" %(options.width, options.height))
+
+ def onInit(self):
+ self.curFrame = 0
+
+ avg.logger.info("Creating camera:")
+ avg.logger.info("driver=%(driver)s device=%(device)s" %self.optdict)
+ avg.logger.info(
+ "width=%(width)d height=%(height)d pixelformat=%(pixelFormat)s"
+ %self.optdict)
+ avg.logger.info("unit=%(unit)d framerate=%(framerate)d fw800=%(fw800)s"
+ %self.optdict)
+
+ self.camNode = avg.CameraNode(driver=self.optdict["driver"],
+ device=self.optdict["device"], unit=self.optdict["unit"],
+ fw800=self.optdict["fw800"], framerate=self.optdict["framerate"],
+ capturewidth=self.optdict["width"], captureheight=self.optdict["height"],
+ pixelformat=self.optdict["pixelFormat"], parent=self)
+
+ if not self.optdict["noinfo"]:
+ self.infoText = ("Driver=%(driver)s (dev=%(device)s unit=%(unit)d) "
+ "%(width)dx%(height)d@%(framerate)f" %self.optdict)
+ avg.WordsNode(text=self.infoText, color="ff3333", pos=(5,5), fontsize=14,
+ rawtextmode=True, parent=self)
+ self.frameText = avg.WordsNode(color="ff3333", pos=(5,25), fontsize=14,
+ parent=self)
+ else:
+ self.frameText = None
+
+ self.setupKeys()
+
+ self.camNode.play()
+ player.setTimeout(100, self.checkCamera)
+
+ def onFrame(self):
+ if self.frameText:
+ self.curFrame += 1
+ self.frameText.text = "%(cam)d/%(app)d" \
+ %{"cam":self.camNode.framenum, "app":self.curFrame}
+
+ def checkCamera(self):
+ if not(self.camNode.isAvailable()):
+ avg.logger.error("Could not open camera")
+ exit(1)
+
+ def setupKeys(self):
+ def setWhitebalance():
+ print "Setting whitebalance"
+ self.camNode.doOneShotWhitebalance()
+
+ def addWhitebalance(du = 0, dv = 0):
+ self.camNode.setWhitebalance(self.camNode.getWhitebalanceU() + du,
+ self.camNode.getWhitebalanceV() + dv)
+ print ("u:", self.camNode.getWhitebalanceU(), "v:",
+ self.camNode.getWhitebalanceV())
+
+ def addGain(gain):
+ self.camNode.gain += gain
+ print "gain:", self.camNode.gain
+
+ def addShutter(shutter):
+ self.camNode.shutter += shutter
+ print "shutter:", self.camNode.shutter
+
+ app.keyboardmanager.bindKeyDown(keystring="w",
+ handler=setWhitebalance,
+ help="Execute whitebalance")
+
+ app.keyboardmanager.bindKeyDown(keystring="1",
+ handler=lambda: addWhitebalance(du = -1),
+ help="Decrease whitebalance u")
+ app.keyboardmanager.bindKeyDown(keystring="2",
+ handler=lambda: addWhitebalance(du = 1),
+ help="Increase whitebalance u")
+ app.keyboardmanager.bindKeyDown(keystring="3",
+ handler=lambda: addWhitebalance(dv = -1),
+ help="Decrease whitebalance v")
+ app.keyboardmanager.bindKeyDown(keystring="4",
+ handler=lambda: addWhitebalance(dv = 1),
+ help="Increase whitebalance v")
+
+ app.keyboardmanager.bindKeyDown(keystring="left",
+ handler=lambda: addShutter(shutter = -1),
+ help="Decrease shutter")
+ app.keyboardmanager.bindKeyDown(keystring="right",
+ handler=lambda: addShutter(shutter = 1),
+ help="Increase shutter")
+
+ app.keyboardmanager.bindKeyDown(keystring="up",
+ handler=lambda: addGain(gain = 1),
+ help="Increase gain")
+ app.keyboardmanager.bindKeyDown(keystring="down",
+ handler=lambda: addGain(gain = -1),
+ help="Decrease gain")
+
+
+if __name__ == "__main__":
+ app.App().run(ShowCamera())
+
diff --git a/src/utils/avg_showfile.py b/src/utils/avg_showfile.py
new file mode 100755
index 0000000..748037c
--- /dev/null
+++ b/src/utils/avg_showfile.py
@@ -0,0 +1,38 @@
+#!/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
+#
+
+import sys
+from libavg import player
+
+if len(sys.argv) ==1:
+ print
+ print "avg_showfile.py displays the contents of an avg file."
+ print
+ print "Usage: avg_showfile.py <avgfile>"
+ print
+ sys.exit(1)
+
+player.loadFile(sys.argv[1])
+player.play()
+
+
diff --git a/src/utils/avg_showfont.py b/src/utils/avg_showfont.py
new file mode 100755
index 0000000..fa4c562
--- /dev/null
+++ b/src/utils/avg_showfont.py
@@ -0,0 +1,68 @@
+#!/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, app
+
+
+class ShowFont(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ self._usage = 'Usage: %s [<fontname> [<text>]] [options]\n\n' \
+ ' Shows all available variants of a font.\n' \
+ ' If <text> is given, displays the text.\n' \
+ ' If <fontname> is not given, dumps a list of all fonts available.' \
+ %parser.get_prog_name()
+ parser.set_usage(self._usage)
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) == 0:
+ fontList = avg.WordsNode.getFontFamilies()
+ print 'Available fonts:'
+ print fontList
+ print
+ print self._usage
+ print ' Option -h or --help gives a full help.'
+ exit()
+
+ self._fontname = args[0]
+ if len(args) > 1:
+ self._displayText = args[1]
+ else:
+ self._displayText = None
+
+ def onInit(self):
+ variants = avg.WordsNode.getFontVariants(self._fontname)
+ print variants
+
+ y = 10
+ for variant in variants:
+ if self._displayText:
+ text = self._displayText
+ else:
+ text = self._fontname + ": " + variant
+ avg.WordsNode(text=text, font=self._fontname, variant=variant, fontsize=24,
+ pos=(10, y), parent=self)
+ y += 50
+
+
+if __name__ == '__main__':
+ app.App().run(ShowFont())
+
diff --git a/src/utils/avg_showsvg.py b/src/utils/avg_showsvg.py
new file mode 100755
index 0000000..915ae40
--- /dev/null
+++ b/src/utils/avg_showsvg.py
@@ -0,0 +1,63 @@
+#!/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
+#
+
+import sys
+
+from libavg import avg, app
+
+
+class ShowSVG(app.MainDiv):
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog [options] <svgFileName> <elementID>")
+
+ parser.add_option("-s", "--size", dest="size",
+ type="float", default=1.0,
+ help="specify a factor for the size of the element [Default: 1.0]")
+ parser.add_option("--save-image", dest="saveImage",
+ action="store_true", default=False,
+ help="save the image rendered to a png file")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 2:
+ parser.print_help()
+ sys.exit(1)
+ self._svgFName = args[0]
+ self._svgID = args[1]
+ self._size = options.size
+ self._saveImage = options.saveImage
+
+ def onInit(self):
+ self.svg = avg.SVG(self._svgFName, True)
+ img = self.svg.createImageNode(self._svgID, {"pos":(1,1), "parent":self},
+ self._size)
+ rect = avg.RectNode(fillcolor="808080", color="FFFFFF", fillopacity=1,
+ pos=(0.5, 0.5), size=img.size+(1,1))
+ self.insertChild(rect, 0)
+ if self._saveImage:
+ bmp = self.svg.renderElement(self._svgID, self._size)
+ bmp.save(self._svgID+".png")
+
+
+if __name__ == "__main__":
+ app.App().run(ShowSVG(), app_resolution="1024x768")
+
diff --git a/src/utils/avg_videoinfo.py b/src/utils/avg_videoinfo.py
new file mode 100755
index 0000000..1d7c41a
--- /dev/null
+++ b/src/utils/avg_videoinfo.py
@@ -0,0 +1,275 @@
+#!/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 optparse import OptionParser
+import sys
+from libavg import avg
+from xml.dom import minidom
+import os
+
+parser = OptionParser(usage="%prog filename(s) [options]")
+parser.add_option("-x", "--xml", dest = "xml", action = "store_true",
+ help = "Output in XML format")
+parser.add_option("-c", "--csv", dest = "csv", action = "store_true",
+ help = "Output in csv format")
+parser.add_option("-r", "--recursion", dest = "recursion", action = "store_true",
+ help = "Recurse into subdirectories")
+options, args = parser.parse_args()
+
+def sortByName(a, b):
+ if a < b:
+ return -1
+ else:
+ return 1
+
+class OutputHandler(object):
+
+ def __init__(self, args):
+ self._node = avg.VideoNode()
+ self.__getFileNames(args)
+
+ def __getFileNames(self, args):
+ self._fileNameList = []
+ filePaths = []
+ for arg in args:
+ if arg == ".":
+ filePaths.extend(os.listdir(os.curdir))
+ if options.recursion:
+ for folder in filePaths:
+ if os.path.isdir(folder):
+ filePaths.extend(self.__getFilesInFolder(folder))
+ elif arg == ".." or os.path.isdir(arg):
+ filePaths.extend(self.__getFilesInFolder(arg))
+ else:
+ if os.path.isfile(arg):
+ filePaths.append(arg)
+
+ for file in filePaths:
+ try:
+ if os.path.isfile(file):
+ self._node.href = str(file)
+ self._node.play()
+ self._fileNameList.append(self._node.href)
+ except RuntimeError, err:
+ sys.stderr.write(str(err) + "\n")
+ self._node = avg.VideoNode()
+ self._fileNameList.sort(cmp=sortByName)
+
+ def __getFilesInFolder(self, folder):
+ folderFiles = []
+ newFiles = os.listdir(folder)
+ for newfile in newFiles:
+ if folder == "..":
+ testFile = "../"+newfile
+ else:
+ testFile = str(folder)+"/"+newfile
+ if os.path.isfile(testFile):
+ folderFiles.append(testFile)
+ if options.recursion and os.path.isdir(testFile):
+ folderFiles.extend(self.__getFilesInFolder(testFile))
+ return folderFiles
+
+
+class ConsoleOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(ConsoleOutputHandler, self).__init__(args)
+ if self._fileNameList == []:
+ print "No valid video files found."
+ printHelp()
+
+ def output(self):
+ if len(self._fileNameList) == 1:
+ self.__outputSingleFile(self._fileNameList[0])
+ else:
+ self.__outputTable()
+
+ def __outputSingleFile(self, filename):
+ self._node.href = filename
+ print "File: " + self._node.href
+ print ("Duration: " + str(self._node.getDuration()/1000.) + " s ("
+ + str(self._node.getNumFrames()) + " frames)")
+ print "Bitrate: " + str(self._node.getBitrate()) + " b/s"
+ print "Video stream: "
+ print " Codec: " + self._node.getVideoCodec()
+ print " Size: " + str(self._node.getMediaSize())
+ print " Pixel format: " + self._node.getStreamPixelFormat()
+ print " FPS: " + str(self._node.fps)
+ print " Duration: " + str(self._node.getVideoDuration()/1000.) + " s"
+ if self._node.hasAudio():
+ print "Audio stream: "
+ print " Codec: " + self._node.getAudioCodec()
+ print " Sample rate: " + str(self._node.getAudioSampleRate()) + " Hz"
+ print " Channels: " + str(self._node.getNumAudioChannels())
+ print " Duration: " + str(self._node.getAudioDuration()/1000.) + " s"
+
+ def __outputTable(self):
+ self.__filenameLen = 8
+ self.__videoCodecLen = 5
+ self.__videoFormatLen = 6
+ self.__audioCodecLen = 5
+
+ for filename in self._fileNameList:
+ self._node.href = filename
+ self._node.play()
+ self.__filenameLen = max(self.__filenameLen, len(filename))
+ curLen = len(self._node.getVideoCodec())
+ self.__videoCodecLen = max(self.__videoCodecLen, curLen)
+ curLen = len(self._node.getStreamPixelFormat())
+ self.__videoFormatLen = max(self.__videoFormatLen, curLen)
+ if self._node.hasAudio():
+ curLen = len(self._node.getAudioCodec())
+ self.__audioCodecLen = max(self.__audioCodecLen, curLen)
+
+ self.__outputTableHeader()
+
+ for filename in self._fileNameList:
+ self._node.href = filename
+ self.__outputTableLine(self._node)
+
+ def __outputTableHeader(self):
+ vFile = "Filename".ljust(self.__filenameLen+1)
+ vDuration = "Duration".ljust(9)
+ vVideoCodec = "Codec".ljust(self.__videoCodecLen +1)
+ vVideoSize = "Size".ljust(13)
+ vPixel = "Pixels".ljust(self.__videoFormatLen+1)
+ vFPS = "FPS".ljust(6)
+ vAudioCodec = "Codec".ljust(self.__audioCodecLen+1)
+ vSampleRate = "Rate".ljust(6)
+ vChannels = "Channels".ljust(8)
+
+ videoPropWidth = self.__videoFormatLen+self.__videoCodecLen+30
+ print ("| ".rjust(self.__filenameLen + 3) +
+ "Video properties".center(videoPropWidth) +
+ "| " +
+ "Audio properties".center((self.__audioCodecLen+17)))
+ print (vFile + "| " + vDuration + vVideoCodec +
+ vVideoSize + vPixel + vFPS + "| " + vAudioCodec +
+ vSampleRate + vChannels )
+ print ("| ".rjust(self.__filenameLen+3) +
+ "|".rjust(videoPropWidth+1))
+
+ def __outputTableLine(self, node):
+ vFile = node.href.ljust(self.__filenameLen + 1)
+ vDuration = str(node.getDuration()/1000.).ljust(9)
+ vVideoCodec = str(node.getVideoCodec()).ljust(self.__videoCodecLen + 1)
+ vVideoSize = str(node.getMediaSize()).ljust(13)
+ vPixel = str(node.getStreamPixelFormat()).ljust(self.__videoFormatLen + 1)
+ if node.fps%1 < 0.0000001:
+ vFPS = str(int(node.fps)).ljust(6)
+ else:
+ vFPS = str(round(node.fps, 2)).ljust(6)
+
+ if node.hasAudio():
+ vAudioCodec = str(node.getAudioCodec()).ljust(self.__audioCodecLen + 1)
+ vSampleRate = str(node.getAudioSampleRate()).ljust(6)
+ vChannels = str(node.getNumAudioChannels()).ljust(8)
+ else:
+ vAudioCodec = "no audio"
+ vSampleRate = ""
+ vChannels = ""
+
+ info = (vFile + "| " + vDuration + vVideoCodec + vVideoSize + vPixel +
+ vFPS + "| " + vAudioCodec + vSampleRate + vChannels)
+ print info
+
+class XMLOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(XMLOutputHandler, self).__init__(args)
+ self.__impl = minidom.getDOMImplementation()
+ self.__doc = self.__impl.createDocument(None, "videodict", None)
+ self.__rootElement = self.__doc.documentElement
+
+ def output(self):
+ for filename in self._fileNameList:
+ self._node.href = str(filename)
+ self.__appendXMLChild(self._node)
+ print self.__doc.toprettyxml(indent=" ",encoding="utf-8")
+
+ def __appendXMLChild(self, node):
+ node.play()
+ videoinfo = self.__doc.createElement("videoinfo")
+ videoinfo.setAttribute("file", node.href)
+ videoinfo.setAttribute("duration", str(node.getDuration()/1000.))
+ videoinfo.setAttribute("bitrate", str(node.getBitrate()))
+ self.__rootElement.appendChild(videoinfo)
+ videoNode = self.__doc.createElement("video")
+ videoNode.setAttribute("codec", node.getVideoCodec())
+ videoNode.setAttribute("size", str(node.getMediaSize()))
+ videoNode.setAttribute("pixelformat", node.getStreamPixelFormat())
+ videoNode.setAttribute("fps", str(node.fps))
+ videoinfo.appendChild(videoNode)
+ if node.hasAudio():
+ audioNode = self.__doc.createElement("audio")
+ audioNode.setAttribute("codec", node.getAudioCodec())
+ audioNode.setAttribute("samplerate", str(node.getAudioSampleRate()))
+ audioNode.setAttribute("channels", str(node.getNumAudioChannels()))
+ videoinfo.appendChild(audioNode)
+
+class CSVOutputHandler(OutputHandler):
+
+ def __init__(self, args):
+ super(CSVOutputHandler, self).__init__(args)
+
+ def output(self):
+ print ("File\tDuration(sec)\tNumber of Frames\tBitrate(b/s)\tVideo Codec\t" +
+ "Width\tHeight\tPixel format\tFPS\tAudio Codec\t" +
+ "Audio Sample rate(Hz)\t Audio channels")
+ for filename in self._fileNameList:
+ self._node.href = str(filename)
+ self.__outputNode(self._node)
+
+ def __outputNode(self, node):
+ s = (str(node.href)+'\t'+
+ str(node.getDuration()/1000.)+'\t' +
+ str(node.getNumFrames())+"\t" +
+ str(node.getBitrate()) + '\t' +
+ str(node.getVideoCodec()) + '\t' +
+ str(node.getMediaSize()[0]) + '\t' +
+ str(node.getMediaSize()[1]) + '\t' +
+ str(node.getStreamPixelFormat()) + '\t' +
+ str(node.fps) + '\t')
+ if node.hasAudio():
+ s += (
+ str(node.getAudioCodec()) + '\t' +
+ str(node.getAudioSampleRate()) + '\t' +
+ str(node.getNumAudioChannels()))
+ else:
+ s += ' \t \t'
+ print s
+
+def printHelp():
+ parser.print_help()
+ sys.exit(1)
+
+if len(sys.argv) == 1:
+ printHelp()
+
+if options.xml:
+ outputHandler = XMLOutputHandler(args)
+elif options.csv:
+ outputHandler = CSVOutputHandler(args)
+else:
+ outputHandler = ConsoleOutputHandler(args)
+outputHandler.output()
diff --git a/src/utils/avg_videoplayer.py b/src/utils/avg_videoplayer.py
new file mode 100755
index 0000000..17268ca
--- /dev/null
+++ b/src/utils/avg_videoplayer.py
@@ -0,0 +1,143 @@
+#!/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
+
+import sys
+from libavg import avg, app, player, widget
+
+
+class VideoPlayer(app.MainDiv):
+ CONTROL_WIDTH=240
+
+ def onArgvParserCreated(self, parser):
+ parser.set_usage("%prog [options] <filename>")
+ parser.add_option("-d", "--disable-accel", dest="disableAccel",
+ action="store_true", default=False,
+ help="disable vdpau acceleration")
+
+ def onArgvParsed(self, options, args, parser):
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(1)
+
+ self.node = avg.VideoNode(href=args[0], accelerated=not(options.disableAccel))
+ self.node.pause()
+
+ mediaSize = self.node.getMediaSize()
+ size = avg.Point2D(max(mediaSize.x, 320), max(mediaSize.y, 120))
+ screenSize = player.getScreenResolution()
+ size = avg.Point2D(min(size.x, screenSize.x), min(size.y, screenSize.y-80))
+ self.settings.set("app_resolution", "%dx%d" %(size.x, size.y))
+
+ def onInit(self):
+ self.node.play()
+
+ mediaSize = self.node.getMediaSize()
+ canvasSize = self.size
+ sizeRatio = min(mediaSize.x/canvasSize.x, mediaSize.y/canvasSize.y)
+ self.node.size /= sizeRatio
+
+ self.node.x = (self.width-self.node.width)/2
+ self.node.y = (self.height-self.node.height)/2
+ self.node.subscribe(avg.VideoNode.END_OF_FILE, self.onEOF)
+
+ if self.node.hasAlpha():
+ self.__makeAlphaBackground()
+ self.appendChild(self.node)
+ self.curFrameWords = avg.WordsNode(parent=self, pos=(10, 10), fontsize=10)
+ self.framesQueuedWords = avg.WordsNode(parent=self, pos=(10, 22), fontsize=10)
+
+ controlPos = ((self.width-VideoPlayer.CONTROL_WIDTH)/2, self.height-25)
+ self.videoControl = widget.MediaControl(pos=controlPos,
+ size=(VideoPlayer.CONTROL_WIDTH, 20),
+ duration=self.node.getDuration(),
+ parent=self)
+ self.videoControl.play()
+ self.videoControl.subscribe(widget.MediaControl.PLAY_CLICKED, self.onPlay)
+ self.videoControl.subscribe(widget.MediaControl.PAUSE_CLICKED, self.onPause)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_PRESSED, self.onSeekStart)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_RELEASED, self.onSeekEnd)
+ self.videoControl.subscribe(widget.MediaControl.SEEK_MOTION, self.onSeek)
+
+ self.isSeeking = False
+ self.isPaused = False
+
+ def onKeyDown(self, event):
+ curTime = self.node.getCurTime()
+ if event.keystring == "right":
+ self.node.seekToTime(curTime+10000)
+ elif event.keystring == "left":
+ if curTime > 10000:
+ self.node.seekToTime(curTime-10000)
+ else:
+ self.node.seekToTime(0)
+ return False
+
+ def onFrame(self):
+ curFrame = self.node.getCurFrame()
+ numFrames = self.node.getNumFrames()
+ self.curFrameWords.text = "Frame: %i/%i"%(curFrame, numFrames)
+ framesQueued = self.node.getNumFramesQueued()
+ self.framesQueuedWords.text = "Frames queued: "+str(framesQueued)
+ if not(self.isSeeking):
+ self.videoControl.time = self.node.getCurTime()
+
+ def onEOF(self):
+ self.videoControl.pause()
+ self.isPaused = True
+
+ def onPlay(self):
+ self.node.play()
+ self.isPaused = False
+
+ def onPause(self):
+ self.node.pause()
+ self.isPaused = True
+
+ def onSeekStart(self):
+ self.node.pause()
+ self.isSeeking = True
+
+ def onSeekEnd(self):
+ if not(self.isPaused):
+ self.node.play()
+ self.isSeeking = False
+
+ def onSeek(self, time):
+ self.node.seekToTime(int(time))
+
+ def __makeAlphaBackground(self):
+ SQUARESIZE=40
+ size = self.node.getMediaSize()
+ avg.RectNode(parent=self, size=self.node.getMediaSize(),
+ strokewidth=0, fillcolor="FFFFFF", fillopacity=1)
+ for y in xrange(0, int(size.y)/SQUARESIZE):
+ for x in xrange(0, int(size.x)/(SQUARESIZE*2)):
+ pos = avg.Point2D(x*SQUARESIZE*2, y*SQUARESIZE)
+ if y%2==1:
+ pos += (SQUARESIZE, 0)
+ avg.RectNode(parent=self, pos=pos, size=(SQUARESIZE, SQUARESIZE),
+ strokewidth=0, fillcolor="C0C0C0", fillopacity=1)
+
+
+if __name__ == "__main__":
+ app.App().run(VideoPlayer())
+