[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