[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