diff -uNr mash-code/mash/Makefile.in mash-code_pymash/mash/Makefile.in --- mash-code/mash/Makefile.in 2002-02-12 07:17:29.000000000 +0900 +++ mash-code_pymash/mash/Makefile.in 2003-09-04 03:39:49.000000000 +0900 @@ -109,6 +109,8 @@ @V_INCLUDE@ @V_INCLUDE_AUDIO@ @V_INCLUDE_GSM@ \ @V_INCLUDE_VIDEO@ @PSVP_INCLUDES@ @V_FX_INC@ +PYTHON_INCLUDE = @PYTHON_INCLUDE@ + #FIXME NLAYER define / MB_DEBUG DEFINE = @V_DEFINE@ @V_DEFINE_VIDEO@ -DSIGRET=@V_SIGRET@ -DNLAYER=8 -DED_YBITS=$(ED_YBITS) \ -DAUDIO_FRAMESIZE=160 \ @@ -562,6 +564,29 @@ mv $@ bin/smash-$(VER) (cd bin; ln -s smash-$(VER) smash) +#### +#### PyMash +#### + +pymash: python/_openmash_core$(SHLIB_SUFFIX) import + +SRC_OPENMASH_CORE = openmash_core.i openmash_core.h openmash_core.cc +python/openmash_core_wrap.cc: $(SRC_OPENMASH_CORE) + swig -c++ -python -o python/openmash_core_wrap.cc -shadow openmash_core.i + +SWIG_CFLAGS = $(CFLAGS) -I$(PYTHON_INCLUDE) +python/openmash_core_wrap.o: python/openmash_core_wrap.cc + $(C++) $(SWIG_CFLAGS) -c python/openmash_core_wrap.cc -o python/openmash_core_wrap.o + +OBJ_SWIG = openmash_core.o python/openmash_core_wrap.o +python/_openmash_core$(SHLIB_SUFFIX): $(OBJ) $(OBJ_VIDEO) $(OBJ_SMASH_ONLY_CC) $(OBJ_SWIG) + $(C++) -shared $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ_SWIG) $(OBJ) \ + $(OBJ_VIDEO) $(SHLIB_LD_LIBS) $(OBJ_SMASH_ONLY_CC) $(LIB) + +#### +#### End of PyMash +#### + libsmash$(SHLIB_SUFFIX): bin/libsmash$(SHLIB_SUFFIX) bin/libsmash$(SHLIB_SUFFIX): $(OBJ) $(OBJ_VIDEO) rm -f $@ bin/libsmash-*$(SHLIB_SUFFIX) diff -uNr mash-code/mash/conf/configure.in.python mash-code_pymash/mash/conf/configure.in.python --- mash-code/mash/conf/configure.in.python 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/conf/configure.in.python 2003-09-04 03:17:59.000000000 +0900 @@ -0,0 +1,37 @@ +dnl configure.in.misc -- +dnl +dnl python setup for PyMash. autoconf scripts. +dnl +dnl Copyright (c) 2003 Argonne National Laboratory. +dnl All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that the following conditions are met: +dnl +dnl A. Redistributions of source code must retain the above copyright notice, +dnl this list of conditions and the following disclaimer. +dnl B. Redistributions in binary form must reproduce the above copyright +dnl notice, this list of conditions and the following disclaimer in the +dnl documentation and/or other materials provided with the distribution. +dnl C. Neither the names of the copyright holders nor the names of its +dnl contributors may be used to endorse or promote products derived from +dnl this software without specific prior written permission. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS +dnl IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +dnl THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE +dnl LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +dnl POSSIBILITY OF SUCH DAMAGE. +dnl +dnl $Header: $ + +AC_ARG_WITH(python-includedir, [ --with-python-includedir=path specify a pathname for the Python includedir], python_includedir=$withval, python_includedir="/usr/include/python2.3") + +PYTHON_INCLUDE=$python_includedir +AC_SUBST(PYTHON_INCLUDE) diff -uNr mash-code/mash/configure.in mash-code_pymash/mash/configure.in --- mash-code/mash/configure.in 2002-02-07 13:02:02.000000000 +0900 +++ mash-code_pymash/mash/configure.in 2003-09-04 03:01:23.000000000 +0900 @@ -57,6 +57,7 @@ builtin(include, ./conf/configure.in.real) builtin(include, ./conf/configure.in.jpegwc) builtin(include, ./conf/configure.in.ztrace) +builtin(include, ./conf/configure.in.python) AC_ARG_WITH(aix-shm, [ --with-aix-shm=path specify a pathname for the AIX shm X extension library file], lib=$withval, lib="") if test "$lib" != "" ; then diff -uNr mash-code/mash/openmash_core.cc mash-code_pymash/mash/openmash_core.cc --- mash-code/mash/openmash_core.cc 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/openmash_core.cc 2003-09-03 07:01:02.000000000 +0900 @@ -0,0 +1,76 @@ +// openmash_core.cc: Bridge for SWIG. +// $Id: $ +// +// Copyright (C) 2003 Hiroyuki Komatsu +// All rights reserved. +// This is free software with ABSOLUTELY NO WARRANTY. +// +// You can redistribute it and/or modify it under the terms of +// the GNU General Public License version 2. + +#include "openmash_core.h" + +#include +#include + +#include "mash-init.h" + +#if defined(WIN32) && !defined(NDEBUG) +# include +#endif + +OpenMash::OpenMash() +{ + init(); +} + +OpenMash::~OpenMash() +{ +} + +int +OpenMash::init() +{ + Tcl_Interp *interp = Tcl_CreateInterp(); + /* + * Tcl_Init is commented out because they also commented out Tcl_Init + * in Mash_AppInit. It doesn't seem to hurt because Tcl_Init doesn't + * really do much. If you don't call Tcl_Init, users can move smash to + * any directory without getting the "Can't find a usable init.tcl" + * error message. This feature is nice, but not calling Tcl_Init seems + * questionable. We may need to revisit this decision in the future. + * --LL + */ + Tcl_SetVar(interp, "tcl_library", "./lib/tcl8.3", TCL_GLOBAL_ONLY); +#if 0 + if (Tcl_Init(interp) == TCL_ERROR) { + WIN32_OutputErr(interp, "Tcl_Init failed!"); + return false; + } +#endif + if (Otcl_Init(interp) == TCL_ERROR) { + WIN32_OutputErr(interp, "Otcl_Init failed!"); + return false; + } + + if (Mash_TclInit(interp) == TCL_ERROR) { + WIN32_OutputErr(interp, "Mash_TclInit failed!"); + return false; + } + + return true; +} + +int +OpenMash::eval(char *command) +{ + int tcl_result = Tcl_GlobalEval(Tcl::instance().interp(), command); + return_code = (tcl_result == TCL_OK) ? true : false; + return return_code; +} + +char * +OpenMash::result() +{ + return Tcl::instance().result(); +} diff -uNr mash-code/mash/openmash_core.h mash-code_pymash/mash/openmash_core.h --- mash-code/mash/openmash_core.h 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/openmash_core.h 2003-09-03 07:01:36.000000000 +0900 @@ -0,0 +1,22 @@ +/* openmash_core.h: Header file for openmash_core.cc + * $Id: $ + * + * Copyright (C) 2003 Hiroyuki Komatsu + * All rights reserved. + * This is free software with ABSOLUTELY NO WARRANTY. + * + * You can redistribute it and/or modify it under the terms of + * the GNU General Public License version 2. + */ + +class OpenMash +{ + public: + OpenMash (); + ~OpenMash (); + int eval(char *command); + char *result(); + private: + int init(); + int return_code; +}; diff -uNr mash-code/mash/openmash_core.i mash-code_pymash/mash/openmash_core.i --- mash-code/mash/openmash_core.i 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/openmash_core.i 2003-08-27 03:33:23.000000000 +0900 @@ -0,0 +1,18 @@ +/* openmash_core.i: SWIG module description file for OpenMash. + * $Id: $ + * + * Copyright (C) 2003 Hiroyuki Komatsu + * All rights reserved. + * This is free software with ABSOLUTELY NO WARRANTY. + * + * You can redistribute it and/or modify it under the terms of + * the GNU General Public License version 2. + */ + +%module openmash_core + +%{ +#include "openmash_core.h" +%} + +%include openmash_core.h diff -uNr mash-code/mash/python/example/headless.py mash-code_pymash/mash/python/example/headless.py --- mash-code/mash/python/example/headless.py 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/python/example/headless.py 2003-09-04 02:40:36.000000000 +0900 @@ -0,0 +1,140 @@ +from openmash import OpenMash +from openmash_VideoAgent import VideoAgent +from openmash_VideoPipeline import VideoPipeline + +class HeadlessVideo: + def __init__(self, host, port, ttl = 16, key = None): + self.agent = VideoAgent(host, port, ttl) + self.pipeline = VideoPipeline(self.agent) + if key is not None: + self.agent.install_key(key) + + def run (self, device_number, codec): + devices = self.pipeline.get_input_devices() + self.pipeline.select(devices[device_number], codec) + self.pipeline.start() + + def enhance (self, channel = None, format = None, bps = None, + fps = None, quality = None): + self.pipeline.set_options(port = channel, norm = format, bps = bps, + fps = fps, quality = quality) + +#### ------------------------------------------------------------ + +if __name__ == '__main__': + import time + from optik import Option, OptionParser + + class HeadlessVideoCommand: + version = '0.0.1' + + def __init__(self, args = None): +# self.device_number = 1 +# self.channel = 'S-Video' +# self.ttl = 16 +# self.codec = 'h261' +# self.format = 'ntsc' +# self.fps = 20 +# self.key = None +# self.bps = 3000000 +# self.quality = 10 + + self._initArgs(args) + + def _initArgs(self, rawArgs = None): + optionList = [ + Option("--device", "-d", + type = 'int', + default = 1, + metavar = "DEVICE_NUMBER"), + Option("--channel", "-l", + default = 'S-Video', + metavar = "CHANNEL_NAME"), + Option("--ttl", "--defaultTTl", "-t", + type = 'int', + default = 16, + metavar = "TTL"), + Option("--framerate", "-F", + type = 'int', + default = 20, + metavar = "NUMBER", + help = "Max fps (default = 20)"), + Option("--maxbw", "-B", + type = 'int', + default = 3000000, + metavar = "NUMBER", + help = "Max bps (default = 3000000)"), + Option("--quality", "-q", + type = 'int', + default = 10, + metavar = "NUMBER", + help = "(default = 10)"), + Option("--defaultFormat", "-f", + default = 'h261', + metavar = "CODEC", + help = "(default = 'h261')"), + Option("--inputType", "--omft", + default = 'ntsc', + metavar = "FORMAT", + help = "(default = 'ntsc')"), + Option("--key", "-K", + default = None, + metavar = "KEY", + help = "Encription key") + ] + parser = OptionParser(option_list=optionList, + version="%%prog: %s" % self.version) + + (options, args) = parser.parse_args(rawArgs) + + self.device_number = vars(options)['device'] + self.channel = vars(options)['channel'] + self.ttl = vars(options)['ttl'] + self.codec = vars(options)['defaultFormat'] + self.format = vars(options)['inputType'] + self.fps = vars(options)['framerate'] + self.key = vars(options)['key'] + self.bps = vars(options)['maxbw'] + self.quality = vars(options)['quality'] + + if len(args) == 1: + (self.host, self.port) = string.split(args[0], '/') + elif len(args) == 2: + self.host = args[0] + self.port = args[1] + else: + parser.error("Invalid number of arguments") + + def main(self, *args): + headless_video = HeadlessVideo(self.host, self.port, self.ttl, + self.key) + headless_video.run(self.device_number, self.codec) + headless_video.enhance(channel = self.channel, + format = self.format, + bps = self.bps, + fps = self.fps, + quality = self.quality) + + while True: + OpenMash.update() + time.sleep(0.1) +# OpenMash.loop() + + +#### ------------------------------------------------------------ + + headless_video_command = HeadlessVideoCommand() + headless_video_command.main() + + +# from openmash import OpenMash +# from openmash_VideoAgent import VideoAgent +# from openmash_VideoPipeline import VideoPipeline + +# agent = VideoAgent('127.0.0.1', '9288') +# pipeline = VideoPipeline(agent) +# devices = pipeline.get_input_devices() +# pipeline.select(devices[0], 'h261') +# pipeline.start() +# OpenMash.loop() + diff -uNr mash-code/mash/python/openmash.py mash-code_pymash/mash/python/openmash.py --- mash-code/mash/python/openmash.py 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/python/openmash.py 2003-09-04 01:33:25.000000000 +0900 @@ -0,0 +1,108 @@ +# openmash.py: +# $Id: $ + +# Copyright (C) 2003 Hiroyuki Komatsu +# All rights reserved. +# This is free software with ABSOLUTELY NO WARRANTY. + +# You can redistribute it and/or modify it under the terms of +# the GNU General Public License version 2. + +import openmash_core ## Module generated by SWIG. + +class OpenMashException(Exception): + """ + The exception raised when a OpenMash-Tcl code has an error. + """ + + def __init__(self, command, error_message): + self.command = command + self.error_message = error_message + + def __str__(self): + return ("OpenMash Error for \"%s\":\n%s" % + (self.command, self.error_message)) + +class OpenMash: + _interpreter = openmash_core.OpenMash() + _interpreter.eval('Import enable') + + def eval (self, command, *args): + """ + OpenMash.eval (command/String, *args/Array(String or Integer)) + => result/String + + Executes the command with the args and returns the result as a string. + [Example] + eval('expr', 1, '+', 2) + => '3' + """ + + command_line = OpenMash._command_line(command, *args) + return_code = OpenMash._interpreter.eval(command_line) + result = OpenMash._interpreter.result() + + if return_code == True: + return result + else: + raise OpenMashException(command, result) + eval = classmethod(eval) + + def update (self): + """ + OpenMash.update() + => void + + Sends 'update' to Mash interpreter + """ + OpenMash.eval("update") + update = classmethod(update) + + def loop (self): + """ + OpenMash.loop() + => void + + Sends 'vwait forever' to Mash interpreter and goes into the forever + loop. + """ + OpenMash.eval("vwait forever") + loop = classmethod(loop) + + def _command_line (self, command, *args): + """ + OpenMash._command_line (command/String, *args/Array(String or Integer)) + => command_line/String + + = Private Method = + + Combines a _command_line from the command and the args. + [Example] + command_line('expr', 1, '+', 2) + => 'expr 1 + 2' + """ + command_line = command + for arg in args: + command_line += (" %s" % arg) + return command_line + _command_line = classmethod(_command_line) + + def import_classes (self, *classnames): + OpenMash.eval('import', *classnames) + import_classes = classmethod(import_classes) + + +class OpenMashClass: + def __init__ (self, class_name, *args): + self._instance = OpenMash.eval('new', class_name, *args) + + def instance (self): + """ + instance() + => instance/String(TclObject) + """ + return self._instance + + def method (self, method, *args): + result = OpenMash.eval(self.instance(), method, *args) + return result diff -uNr mash-code/mash/python/openmash_VideoAgent.py mash-code_pymash/mash/python/openmash_VideoAgent.py --- mash-code/mash/python/openmash_VideoAgent.py 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/python/openmash_VideoAgent.py 2003-09-03 03:11:45.000000000 +0900 @@ -0,0 +1,28 @@ +# openmash_VideoAgent.py: Python Wrapper for OpenMash / VideoAgent +# $Id: $ +# +# Copyright (C) 2003 Hiroyuki Komatsu +# All rights reserved. +# This is free software with ABSOLUTELY NO WARRANTY. +# +# You can redistribute it and/or modify it under the terms of +# the GNU General Public License version 2. + +from openmash import OpenMash, OpenMashClass + +class VideoAgent (OpenMashClass): + OpenMash.import_classes('VideoAgent') + + def __init__(self, host, port, defaultTTL = 16): + ### FIXME: We might not be able to hidden Application class. + ### FIXME: (2003-08-26) + application = OpenMashClass('Application', 'VideoAgent') + application.method('add_default', 'defaultTTL', defaultTTL) + + OpenMashClass.__init__(self, 'VideoAgent', application.instance(), + "%s/%s" % (host, port)) +# video_agent = OpenMashClass +# self._instance = video_agent + + def install_key (self, key): + self.method('install-key', key) diff -uNr mash-code/mash/python/openmash_VideoPipeline.py mash-code_pymash/mash/python/openmash_VideoPipeline.py --- mash-code/mash/python/openmash_VideoPipeline.py 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/python/openmash_VideoPipeline.py 2003-08-27 06:38:18.000000000 +0900 @@ -0,0 +1,100 @@ +# openmash_VideoPipeline.py: Python Wrapper for OpenMash / VideoPipeline. +# $Id: $ +# +# Copyright (C) 2003 Hiroyuki Komatsu +# All rights reserved. +# This is free software with ABSOLUTELY NO WARRANTY. +# +# You can redistribute it and/or modify it under the terms of +# the GNU General Public License version 2. + +from openmash import OpenMash, OpenMashClass +import string + +class VideoPipeline (OpenMashClass): + OpenMash.import_classes('VideoPipeline') + + def __init__(self, video_agent): + """ + __init__(vide_agent/VideoAgent) + + Initializes a instance of VideoPipeline. + """ + OpenMashClass.__init__(self, 'VideoPipeline', video_agent.instance()) +# video_pipeline = OpenMashClass('VideoPipeline', video_agent.instance()) +# self._instance = video_pipeline + + def get_input_devices (self): + """ + get_input_devices() + => devices/List + + Returns aviaable input devices. + """ + devices_string = self.method('input_devices') + + ### FIXME: string.split is not care about escapes by quotations. + ### FIXME: (2003-08-26) + devices_list = string.split(devices_string) + return devices_list + + + def select (self, device, codec): + """ + select (device/String, codec/String) + => Void + + Selects the device and the codec for this video pipeline. + """ + self.method('select', device, codec) + + + def start (self): + """ + start () + => Void + + Starts the session. + """ + self.method('start') + + + def set_options (self, port = None, norm = None, quality = None, + fps = None, bps = None): + """ + [Example] + set_options(norm = 'ntsc', bps = 3000000) + """ + port or self.set_port(port) + norm or self.set_norm(norm) + quality or self.set_quality(quality) + fps or self.set_fps(fps) + bps or self.set_bps(bps) + + + def set_port (self, port): + """ + [Example] + set_port('S-Video') + """ + self.method('set_port', port) + + + def set_norm (self, norm): + """ + [Example] + set_norm('ntsc') + """ + self.method('set_norm', norm) + + + def set_quality (self, quality): + self.method('set_quality', quality) + + + def set_fps (self, fps): + self.method('set_fps', fps) + + + def set_bps (self, bps): + self.method('set_bps', bps) diff -uNr mash-code/mash/python/openmash_core.py mash-code_pymash/mash/python/openmash_core.py --- mash-code/mash/python/openmash_core.py 1970-01-01 09:00:00.000000000 +0900 +++ mash-code_pymash/mash/python/openmash_core.py 2003-09-04 03:19:20.000000000 +0900 @@ -0,0 +1,54 @@ +# This file was created automatically by SWIG. +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. +import _openmash_core +def _swig_setattr(self,class_type,name,value): + if (name == "this"): + if isinstance(value, class_type): + self.__dict__[name] = value.this + if hasattr(value,"thisown"): self.__dict__["thisown"] = value.thisown + del value.thisown + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + self.__dict__[name] = value + +def _swig_getattr(self,class_type,name): + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 + + +class OpenMash(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, OpenMash, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, OpenMash, name) + def __init__(self,*args): + _swig_setattr(self, OpenMash, 'this', apply(_openmash_core.new_OpenMash,args)) + _swig_setattr(self, OpenMash, 'thisown', 1) + def __del__(self, destroy= _openmash_core.delete_OpenMash): + try: + if self.thisown: destroy(self) + except: pass + def eval(*args): return apply(_openmash_core.OpenMash_eval,args) + def result(*args): return apply(_openmash_core.OpenMash_result,args) + def __repr__(self): + return "" % (self.this,) + +class OpenMashPtr(OpenMash): + def __init__(self,this): + _swig_setattr(self, OpenMash, 'this', this) + if not hasattr(self,"thisown"): _swig_setattr(self, OpenMash, 'thisown', 0) + _swig_setattr(self, OpenMash,self.__class__,OpenMash) +_openmash_core.OpenMash_swigregister(OpenMashPtr) + +