[xiph-commits] r8259 - in experimental/dholth/oggpy: . tests
dholth at motherfish-iii.xiph.org
dholth at motherfish-iii.xiph.org
Mon Nov 22 18:13:15 PST 2004
Author: dholth
Date: 2004-11-22 18:13:15 -0800 (Mon, 22 Nov 2004)
New Revision: 8259
Added:
experimental/dholth/oggpy/config.py
experimental/dholth/oggpy/pygame_bridge.cc
Modified:
experimental/dholth/oggpy/MANIFEST.in
experimental/dholth/oggpy/Makefile
experimental/dholth/oggpy/README
experimental/dholth/oggpy/setup.py
experimental/dholth/oggpy/tests/theoratest.py
experimental/dholth/oggpy/theorapy.pyste
Log:
patch-26
Modified: experimental/dholth/oggpy/MANIFEST.in
===================================================================
--- experimental/dholth/oggpy/MANIFEST.in 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/MANIFEST.in 2004-11-23 02:13:15 UTC (rev 8259)
@@ -4,3 +4,4 @@
include tests/encode.py
include tests/oggtext.py
include tests/test.py
+include config.py
Modified: experimental/dholth/oggpy/Makefile
===================================================================
--- experimental/dholth/oggpy/Makefile 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/Makefile 2004-11-23 02:13:15 UTC (rev 8259)
@@ -15,7 +15,7 @@
theorapy.cpp: oggcc.cc oggcc.h theoracc.h theorapy.pyste
pyste --module=theorapy --out=theorapy.cpp -I. \
- -I$(PYTHON_HEADER_DIR) -I$(BOOST_HEADER_DIR) -I$(HOME)/include/theora theorapy.pyste
+ -I$(PYTHON_HEADER_DIR) -I$(BOOST_HEADER_DIR) -I/usr/include/ theorapy.pyste
module: theorapy.cpp oggpy.cpp vorbispy.cpp
python ./setup.py build
Modified: experimental/dholth/oggpy/README
===================================================================
--- experimental/dholth/oggpy/README 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/README 2004-11-23 02:13:15 UTC (rev 8259)
@@ -1,33 +1,49 @@
What's this?
============
-If you've downloaded this, you're probably wondering two things - what's
-it for, and why doesn't it compile?
+This is oggpy. It's a capable wrapper that will let you manipulate ogg,
+vorbis, and theora from your Python code.
+
+Motivation
+==========
+
I wrote this wrapper because I was frustrated with the official ogg/vorbis
-wrapper and to teach myself about Boost.Python. When encoding the
+wrapper and to teach myself about Boost.Python. When encoding, the
official ogg/vorbis Python wrapper could only write its output to a file.
No tostring() method. Well, mine has a tostring() method, and it's
written in a more concise and understandable way thanks to the magic
-of Boost.Python. Ideally, by combining this wrapper and shoutpy, it will
-be possible to write a program like ices (re-encode and stream ogg/vorbis)
-in Python.
+of Boost.Python.
-Incidentally, there's a separately usable C++ wrapper here too.
+By combining this wrapper and shoutpy, it's possible to write a
+reencoding source for icecast. An almost-working example is given in
+tests/reencode.py
-This is a very early release. By downloading this software, you're
+Incidentally there's a separately usable C++ wrapper here too.
+
+This is still an early release. By downloading this software, you're
participating in the receiving end of the 'release early, release often'
-open source philosophy.
+open source philosophy, so I'd very much appreciate your feedback.
-Send your feedback to dholth at fastmail.fm.
+Send feedback to dholth at fastmail.fm.
-Thanks,
+Thanks, I hope you enjoy this wrapper.
-Daniel Holth
+- Daniel Holth
+
Compiling
=========
+If you're using gentoo, you will want to emerge the following packages first:
+ boost libogg libvorbis
+ ACCEPT_KEYWORDS=~x86 emerge theora (to manipulate theora streams)
+ pygame (to display theora)
+
+Then use setup.py build as normal.
+
+Hopefully I'll figure out an ebuild for this.
+
To compile this software, use setup.py.
Edit the setup:
@@ -39,9 +55,8 @@
(Possibly):
python setup.py install
-Basic necessities will include editing setup.py to point to your
-Boost.Python include directory, and possibly removing theora
-support.
+If Python is having trouble finding your libraries, edit config.py .
+For example, Boost.Python has a number of different library names.
Boost.Python 1.31 or CVS is necessary; 1.30 won't work because it lacks
a str:: constructor used in vorbispy_wrappers.cc
Added: experimental/dholth/oggpy/config.py
===================================================================
--- experimental/dholth/oggpy/config.py 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/config.py 2004-11-23 02:13:15 UTC (rev 8259)
@@ -0,0 +1,21 @@
+# Local configuration for ogpgy.
+# Daniel Holth <dholth at fastmail.fm>, 2004
+# Works in gentoo.
+
+common_libraries = ["ogg"]
+common_libraries.extend(("boost_python",))
+# libraries.extend(("boost_python-gcc-mt-1_31",)) # this name may also work for you
+
+common_include_dirs = ["."]
+
+oggpy_libraries = common_libraries
+oggpy_include_dirs = common_include_dirs
+
+vorbispy_libraries = common_libraries + ["vorbis", "vorbisenc"]
+vorbispy_include_dirs = common_include_dirs
+
+theorapy_libraries = common_libraries + ["theora"]
+theorapy_include_dirs = common_include_dirs
+
+bridge_libraries = common_libraries + ["SDL", "theora"]
+bridge_include_dirs = common_include_dirs + ["/usr/include/SDL"]
Added: experimental/dholth/oggpy/pygame_bridge.cc
===================================================================
--- experimental/dholth/oggpy/pygame_bridge.cc 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/pygame_bridge.cc 2004-11-23 02:13:15 UTC (rev 8259)
@@ -0,0 +1,185 @@
+/* Bridge from theorapy to pygame */
+/* */
+/* For questions regarding this program contact */
+/* Daniel Holth <dholth at fastmail.fm> */
+
+/**
+ * Render theora video to a pygame surface
+ *
+ * @author Daniel Holth
+ */
+
+extern "C" {
+#include <pygame/pygame.h>
+}
+
+#include <boost/python/detail/wrap_python.hpp>
+#include <boost/python.hpp>
+#include "theoracc.h"
+
+using namespace boost::python;
+
+class pygame_bridge {
+ private:
+ /// References to the Python objects:
+ object info;
+ object surface;
+
+ theora_info *ti;
+
+ SDL_Surface *surf;
+ SDL_Overlay *yuv_overlay;
+ SDL_Rect rect;
+
+ int frame_width, frame_height;
+
+ protected:
+ /// Make sure overlay is the correct size
+ int check_overlay(ogg::theora::info &info);
+
+ public:
+ pygame_bridge() { this->ti = NULL; this->surf = NULL; this->yuv_overlay = NULL; }
+
+ int set_info(ogg::theora::info &info)
+ {
+ // this->info = info; // not a python object
+ this->ti = info.get_data();
+ return this->check_overlay(info);
+ }
+
+ int is_surface(PyObject *surf) { return PySurface_Check(surf); }
+
+ /// Make surface for testing.
+ PyObject *make_surface()
+ {
+ SDL_Surface *surf = NULL;
+ PyObject *pysurf = NULL;
+
+ surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 128, 128, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ if(!surf)
+ {
+ SDL_FreeSurface(surf);
+ }
+ else
+ {
+ pysurf = PySurface_New(surf);
+ }
+
+
+ return pysurf;
+ }
+
+ int set_surface(boost::python::object surface);
+ int render(ogg::theora::yuv_image &image);
+};
+
+
+/* This function is based on code from OggTheora's player_example.c *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ */
+static void video_write(yuv_buffer &yuv, theora_info &ti, SDL_Surface *screen, SDL_Overlay *yuv_overlay, SDL_Rect *rect)
+{
+ int i;
+ int crop_offset;
+
+ /* Lock SDL_yuv_overlay */
+ if ( SDL_MUSTLOCK(screen) ) {
+ if ( SDL_LockSurface(screen) < 0 ) return;
+ }
+ if (SDL_LockYUVOverlay(yuv_overlay) < 0) return;
+
+ /* let's draw the data (*yuv[3]) on a SDL screen (*screen) */
+ /* deal with border stride */
+ /* reverse u and v for SDL */
+ /* and crop input properly, respecting the encoded frame rect */
+ crop_offset=ti.offset_x+yuv.y_stride*ti.offset_y;
+ for(i=0;i<yuv_overlay->h;i++)
+ memcpy(yuv_overlay->pixels[0]+yuv_overlay->pitches[0]*i,
+ yuv.y+crop_offset+yuv.y_stride*i,
+ yuv_overlay->w);
+ crop_offset=(ti.offset_x/2)+(yuv.uv_stride)*(ti.offset_y/2);
+ for(i=0;i<yuv_overlay->h/2;i++){
+ memcpy(yuv_overlay->pixels[1]+yuv_overlay->pitches[1]*i,
+ yuv.v+crop_offset+yuv.uv_stride*i,
+ yuv_overlay->w/2);
+ memcpy(yuv_overlay->pixels[2]+yuv_overlay->pitches[2]*i,
+ yuv.u+crop_offset+yuv.uv_stride*i,
+ yuv_overlay->w/2);
+ }
+
+ /* Unlock SDL_yuv_overlay */
+ if ( SDL_MUSTLOCK(screen) ) {
+ SDL_UnlockSurface(screen);
+ }
+ SDL_UnlockYUVOverlay(yuv_overlay);
+
+
+ /* Show, baby, show! */
+ SDL_DisplayYUVOverlay(yuv_overlay, rect);
+}
+
+
+int pygame_bridge::check_overlay(ogg::theora::info &image)
+{
+ theora_info *ti = image.get_data();
+
+ if(this->yuv_overlay == NULL)
+ {
+ this->yuv_overlay = SDL_CreateYUVOverlay(ti->frame_width, ti->frame_height, SDL_YV12_OVERLAY, this->surf);
+
+ if(this->yuv_overlay != NULL)
+ {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = ti->frame_width;
+ rect.h = ti->frame_height;
+
+ SDL_DisplayYUVOverlay(this->yuv_overlay, &(this->rect));
+ }
+ }
+
+ return (this->yuv_overlay == NULL) ? 0 : 1;
+}
+
+
+int pygame_bridge::render(ogg::theora::yuv_image &image)
+{
+ video_write(*(image.get_data()), *(this->ti), this->surf, this->yuv_overlay, &(this->rect));
+ return 1;
+}
+
+
+int pygame_bridge::set_surface(object display)
+// int pygame_bridge::set_surface(PyObject *surfobj)
+{
+ PyObject* surfobj;
+ surfobj = display.ptr();
+
+ if(PySurface_Check(surfobj))
+ {
+ // this->surface = display;
+ this->surf = PySurface_AsSurface(surfobj);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+BOOST_PYTHON_MODULE_INIT(pygame_bridge)
+{
+
+ class_< pygame_bridge > ("bridge", "Connect theorapy's yuv_image to pygame")
+ .def("set_info", &pygame_bridge::set_info, "Set theora info to use (do this first")
+ .def("set_surface", &pygame_bridge::set_surface, "Set SDL surface for image display")
+ .def("render", &pygame_bridge::render, "Blit a frame to the SDL surface")
+ .def("is_surface", &pygame_bridge::is_surface, "Do we think it's a SDL surface?")
+ .def("make_surface", &pygame_bridge::make_surface, "Create something that's definiely a surface.")
+ ;
+
+ // Must import needed APIs:
+ import_pygame_base();
+ import_pygame_rect();
+ import_pygame_surface();
+}
Modified: experimental/dholth/oggpy/setup.py
===================================================================
--- experimental/dholth/oggpy/setup.py 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/setup.py 2004-11-23 02:13:15 UTC (rev 8259)
@@ -1,25 +1,16 @@
#!/usr/bin/env python
-# oggpy
+# oggpy, by Daniel Holth <dholth at fastmail.fm>, 2004
from distutils.core import setup
from distutils.extension import Extension
import os.path
import sys
-extra_include_dirs = [".", "/home/dholth/include/theora", "/usr/include/SDL"]
+# local configuration
+import config
-if sys.version[0:3] == "2.3":
- boost = "/home/dholth/opt/include/boost-1_31" # boost.python include path
- boostlib = "boost_python-gcc-1_31" # boost.python library name
-else:
- boost = "/usr/include/boost"
- boostlib = "boost_python"
+description = """oggpy provides capable python bindings of ogg, vorbis and theora."""
-if(os.path.exists(boost)):
- extra_include_dirs.append(boost)
-
-description = """oggpy provides alternative python bindings to ogg, vorbis and theora."""
-
classifiers="""\
Development Status :: 2 - Pre-Alpha
License :: OSI Approved :: MIT License
@@ -28,10 +19,11 @@
Programming Language :: Python
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Multimedia :: Sound/Audio
+Topic :: Multimedia :: Video
"""
setup(name="oggpy",
- version="0.4",
+ version="0.5",
description="Boost.Python and C++ wrappers of ogg, vorbis and theora",
long_description=description,
author="Daniel Holth",
@@ -43,29 +35,24 @@
ext_modules=[
Extension("oggpy", ["oggcc.cc", "oggpy.cpp", "oggpy_wrappers.cc"],
- libraries=["ogg", boostlib],
- include_dirs=extra_include_dirs, depends=["oggcc.h"]),
+ libraries=config.oggpy_libraries,
+ include_dirs=config.oggpy_include_dirs,
+ depends=["oggcc.h"]),
Extension("vorbispy", ["oggcc.cc", "vorbispy.cpp", "vorbispy_wrappers.cc"],
- libraries=["ogg", "vorbis", "vorbisenc", boostlib],
- include_dirs=extra_include_dirs, depends=["oggcc.h", "vorbiscc.h", "vorbispy_wrappers.h"]),
+ libraries=config.vorbispy_libraries,
+ include_dirs=config.vorbispy_include_dirs,
+ depends=["oggcc.h", "vorbiscc.h", "vorbispy_wrappers.h"]),
Extension("theorapy", ["oggcc.cc", "theorapy.cpp"],
- libraries=["ogg", "theora", boostlib],
- include_dirs=extra_include_dirs, depends=["oggcc.h", "theoracc.h"])
+ libraries=config.theorapy_libraries,
+ include_dirs=config.theorapy_include_dirs,
+ depends=["oggcc.h", "theoracc.h"])
-# If we want to statically link libboost_python we would have to put
-# everything in one file; this doesn't work right away due to name
-# collisions.
-# , Extension("panogg",
-# ["panogg.cc", "oggpy/_oggpy.cpp", "oggpy/_theorapy.cpp",
-# "oggpy/_vorbispy.cpp", "vorbispy_wrappers.cc", "oggpy_wrappers.cc"],
-# libraries=["ogg", "theora", "vorbis", "vorbisenc", boostlib],
-# include_dirs=extra_include_dirs, depends=["oggcc.h", "theoracc.h"])
- # It works.
+ # It works!
, Extension("pygame_bridge", ["pygame_bridge.cc"],
- libraries=["SDL", "ogg", "theora", boostlib],
- include_dirs=extra_include_dirs)
+ libraries=config.bridge_libraries,
+ include_dirs=config.bridge_include_dirs)
]
)
Modified: experimental/dholth/oggpy/tests/theoratest.py
===================================================================
--- experimental/dholth/oggpy/tests/theoratest.py 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/tests/theoratest.py 2004-11-23 02:13:15 UTC (rev 8259)
@@ -90,7 +90,7 @@
theora += 1
- elif theora > 3:
+ if theora > 3:
# print theora
theora += 1
assert(td.decode_packetin(op) == 0)
@@ -101,8 +101,8 @@
yield yuv
- else:
- break
+ #else:
+ # break
if __name__ == "__main__":
Modified: experimental/dholth/oggpy/theorapy.pyste
===================================================================
--- experimental/dholth/oggpy/theorapy.pyste 2004-11-23 02:11:20 UTC (rev 8258)
+++ experimental/dholth/oggpy/theorapy.pyste 2004-11-23 02:13:15 UTC (rev 8259)
@@ -5,5 +5,5 @@
exclude(theorapy.state.get_data)
exclude(theorapy.yuv_image.get_data)
-Enum("theora_colorspace", "theora.h")
+Enum("theora_colorspace", "theora/theora.h")
# Enum("ogg::theora::theora_errors", "theoracc.h")
More information about the commits
mailing list