diff options
author | Dimitri John Ledkov <xnox@ubuntu.com> | 2014-06-24 20:05:13 +0100 |
---|---|---|
committer | Dimitri John Ledkov <xnox@ubuntu.com> | 2014-06-24 20:05:13 +0100 |
commit | dd22bd15f6ed3e5eb5c77ab427029be50fe20148 (patch) | |
tree | d9491ee40d80688b7f5b1f20504f022686827a57 /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.am | 5 | ||||
-rwxr-xr-x | src/utils/avg_audioplayer.py | 49 | ||||
-rwxr-xr-x | src/utils/avg_checkpolygonspeed.py | 145 | ||||
-rwxr-xr-x | src/utils/avg_checkspeed.py | 141 | ||||
-rwxr-xr-x | src/utils/avg_checktouch.py | 57 | ||||
-rwxr-xr-x | src/utils/avg_checkvsync.py | 44 | ||||
-rwxr-xr-x | src/utils/avg_chromakey.py | 189 | ||||
-rwxr-xr-x | src/utils/avg_jitterfilter.py | 111 | ||||
-rwxr-xr-x | src/utils/avg_showcamera.py | 201 | ||||
-rwxr-xr-x | src/utils/avg_showfile.py | 38 | ||||
-rwxr-xr-x | src/utils/avg_showfont.py | 68 | ||||
-rwxr-xr-x | src/utils/avg_showsvg.py | 63 | ||||
-rwxr-xr-x | src/utils/avg_videoinfo.py | 275 | ||||
-rwxr-xr-x | src/utils/avg_videoplayer.py | 143 |
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()) + |