Skip to content

Commit

Permalink
Split pool into port-pool
Browse files Browse the repository at this point in the history
Only port-pool's are used at the minute and they're a sufficiently
different beast to warrant their own class.
  • Loading branch information
waveform80 committed May 10, 2016
1 parent a7bb4a6 commit 91e57d1
Showing 1 changed file with 52 additions and 47 deletions.
99 changes: 52 additions & 47 deletions picamera/mmalobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ def _data_callback(port, buf):
finally:
buf.release()
if port._callback:
port._pool.send_buffer(port)
port._pool.send_buffer()


class MMALControlPort(object):
Expand Down Expand Up @@ -460,7 +460,7 @@ def disable(self):

def send_buffer(self, buf):
"""
Send the *buf* :class:`MMALBuffer` to the port.
Send :class:`MMALBuffer` *buf* to the port.
"""
mmal_check(
mmal.mmal_port_send_buffer(self._port, buf._buf),
Expand Down Expand Up @@ -639,7 +639,7 @@ def enable(self, callback=None):
assert self._pool is None
try:
self._callback = callback
self._pool = MMALPool.for_port(self)
self._pool = MMALPortPool(self)
self._port[0].userdata = ct.cast(
ct.pointer(ct.py_object(self)),
ct.c_void_p)
Expand All @@ -651,6 +651,7 @@ def enable(self, callback=None):
except:
self._pool.close()
self._pool = None
raise
else:
super(MMALPort, self).enable()

Expand Down Expand Up @@ -984,47 +985,16 @@ def __repr__(self):

class MMALPool(object):
"""
Represents an MMAL pool of buffer headers. This can be constructed from an
existing MMAL pool pointer, or via a couple of class methods
:meth:`for_port` and :meth:`for_buffers`.
Construct an MMAL pool containing *num* buffer headers of *size* bytes.
"""
def __init__(self, pool, port=None):
def __init__(self, port):
self._pool = pool
self._port = port

def close(self):
if self._pool is not None:
if self._port is None:
mmal.mmal_pool_destroy(self._pool)
else:
mmal.mmal_port_pool_destroy(self._port._port, self._pool)
self._port = None
mmal.mmal_pool_destroy(self._pool)
self._pool = None

@classmethod
def for_port(cls, port):
"""
Construct an MMAL pool for the number and size of buffers required by
the :class:`MMALPort` *port*.
"""
pool = mmal.mmal_port_pool_create(
port._port, port._port[0].buffer_num, port._port[0].buffer_size)
if not pool:
raise PiCameraRuntimeError(
'failed to create buffer header pool for port %s' % port.name)
return MMALPool(pool, port)

@classmethod
def for_buffers(cls, num, size):
"""
Construct an MMAL pool containing *num* buffer headers of *size* bytes.
"""
pool = mmal.mmal_pool_create(num, size)
if not pool:
raise PiCameraRuntimeError(
'failed to create buffer header pool of size %dx%d' % (num, size))
return MMALPool(pool)

def get_buffer(self):
"""
Get the next buffer from the pool.
Expand All @@ -1034,26 +1004,61 @@ def get_buffer(self):
raise PiCameraRuntimeError('failed to get a buffer from the pool')
return MMALBuffer(buf)

def send_buffer(self, port=None):
def send_buffer(self, port):
"""
Get a buffer from the pool and send it to *port*. If *port* is
``None``, send it to the port the pool was created for.
Get a buffer from the pool and send it to *port*.
"""
if port is None:
port = self._port
port.send_buffer(self.get_buffer())

def send_all_buffers(self, port=None):
def send_all_buffers(self, port):
"""
Send all buffers from the pool to *port*. If *port* is ``None``, send
them to the port the pool was created for.
Send all buffers from the pool to *port*.
"""
if port is None:
port = self._port
for i in range(mmal.mmal_queue_length(self._pool[0].queue)):
port.send_buffer(self.get_buffer())


class MMALPortPool(MMALPool):
"""
Construct an MMAL pool for the number and size of buffers required by
the :class:`MMALPort` *port*.
"""

def __init__(self, port):
pool = mmal.mmal_port_pool_create(
port._port, port._port[0].buffer_num, port._port[0].buffer_size)
if not pool:
raise PiCameraRuntimeError(
'failed to create buffer header pool for port %s' % port.name)
self._pool = pool
self._port = port

def close(self):
if self._pool:
mmal.mmal_port_pool_destroy(self._port._port, self._pool)
self._port = None
self._pool = None

@property
def port(self):
return self._port

def send_buffer(self):
"""
Get a buffer from the pool and send it to the port the pool is
associated with.
"""
self._port.send_buffer(self.get_buffer())

def send_all_buffers(self, port):
"""
Send all buffers from the pool to the port the pool is associated
with.
"""
for i in range(mmal.mmal_queue_length(self._pool[0].queue)):
self._port.send_buffer(self.get_buffer())


class MMALConnection(object):
"""
Represents an MMAL internal connection between two components. The
Expand Down

0 comments on commit 91e57d1

Please sign in to comment.