[Pyrex] when pyrex gets tough

Lenard Lindstrom len-l at telus.net
Mon Sep 3 00:05:21 CEST 2007


David McNab wrote:
> On Sun, 2007-09-02 at 16:42 +0200, Stefan Behnel wrote:
>   
>> Any reason you're requiring tuple access and not using a wrapper class?
>>     
>
> No actual requirement for tuple access, come to think.
>
> What I do need is:
>  - ability to easily construct and discard ratios as some kind of
>    object, whether a python tuple, or a special class, or whatever
>  - ability to access the existing ratio constants from python, in some
>    form
>  - ability to pass these ratios in as arguments
>
> For (a poor) example of usage:
>
>         import yuv4mpeg
>         
>         stream1 = yuv4mpeg.Stream()
>         stream1.setFrameRate(yuv4mpeg.fpsRatioPal)
>         
>         stream2 = yuv4mpeg.Stream()
>         fpsMyWebcam = yuv4mpeg.Ratio(15, 1) # new ratio for 15fps webcam
>         stream2.setFrameRate(fpsMyWebcam)
>
> Question is - how to implement this in Pyrex?
>
> Unless I've been badly misreading the manual, there seems to be no
> straightforward way to get hold of the extern'ed ratio struct constants
> that are referenced from yuv4mpeg.h
>
> It's easy to access stuff that's #defined'd, via:
>
>         cdef extern from "yuv4mpeg.h:
>                 ...
>                 enum Y4CONSTS:
>                         ...
>                         Y4M_OK
>                         Y4M_ERR_RANGE
>                         Y4M_ERR_SYSTEM
>                         Y4M_ERR_HEADER
>                         ...
>                 ...
>
> But how do you access extern'ed variables of a struct type?
>
> I'd be thrilled to be proven wrong here, but this seems to have been one
> case where wrapping with SWIG has proven easier and quicker than
> wrapping with Pyrex.
>
> BTW - I've published the SWIG wrapper to:
>
>         http://www.freenet.org.nz/pyyuv4mpeg/
>
>
>   
This is quick and untested. There is room for optimization is needed.

cdef extern from "yuv4mpeg.h":  # or whatever the header is
    ctypedef struct y4m_ratio_t:
        int n
        int d
    y4m_ratio_t y4m_fps_NTSC_FILM
    y4m_ratio_t y4m_fps_FILM
    ....

cdef class Ratio:
    cdef y4m_ratio r
    def __init__(self, numerator, denominator):
        self.numerator = n
        self.denominator = d

    property numerator:
        def __get__(self):
            return self.r.n
        def  __set__(self, int value):
            self.r.n = value

    property denominator:
        def __get__(self):
            return self.r.d
        def  __set__(self, int value):
            if value == 0:
                raise ValueError("Zero denominator")
            self.r.d = value

    # With a partial sequence conversion to tuples, or lists, is easy
    def __len__(self):
        return 2

    def __getitem__(self, int x):
        if x == 0:
            return self.numerator
        if x == 1:
            return self.denominator
        raise IndexError("Index out of range")

    def __setitem__(self, int x, int y):
        if x == 0:
            self.numerator = y
        elif x == 1:
            self.denominator = y
        else:
            raise IndexError("Index out of range")

cdef Ratio y4m_ratio_to_Ratio(y4m_ratio *r):
    return Ratio(r[0].n, r[0].d)

# fps_NTS_FILE is accessible from Python
fps_NTSC_FILE = ytm_ratio_to_Ratio(&y4m_fps_NTSC_FILM)
....

-- 
Lenard Lindstrom
<len-l at telus.net>




More information about the Pyrex mailing list