-
Notifications
You must be signed in to change notification settings - Fork 33
Handling data in MMALSharp
When you begin using MMALSharp you will want to familiarise yourself with the ways in which you can handle data with the library. MMALSharp introduces two ways in which you can interact with the data produced by the Raspberry Pi camera and the native MMAL library, namely Capture Handlers and Callback Handlers.
I will begin by introducing you to what are known as Capture Handlers as these are the most common data handling types you will come across when using MMALSharp. Capture Handlers are classes which either feed user provided data into a component or store data produced by the components in your pipeline.
You assign Capture Handlers for use with a port using the ConfigureInputPort
and ConfigureOutputPort
methods against an IInputPort
or IOutputPort
instance. Once a handler has been assigned to a port it becomes a "Processing Port" and MMALSharp will know to either feed from or store data to it. We will now discuss Input and Ouput Capture Handlers in more detail below.
Capture Handlers which feed data into components implement the IInputCaptureHandler
interface and will typically be used when you have a source file which you would like to run through an encoder or decoder component. In such a scenario, your data is fed into MMAL buffer headers and into the input port you have configured to use your Capture Handler with. From here, each connected component in your pipeline will interact with the data you're feeding in.
These data handling types are the most common you'll come across in MMALSharp as the output handlers are typically responsible for storing the final data produced by the components. Output Capture Handlers implement the IOutputCaptureHandler
interface and expose a Process
method which is called by the library each time a MMAL buffer is returned on a output port. This Process
method is then passed a ImageContext
object which contains, but not limited to: a byte array containing the frame data and whether this data represents the end of a frame.
Callback Handlers were added to the library to abstract the managed operations away from the native callback functions. Each time a buffer is returned to a processing port's native callback function the registered Callback Handler is then called to carry out additional logic which may be required. Input and Output Callback Handlers are the objects which in turn contain a reference to the Capture Handlers, therefore it is your responsibility to handle that interaction if you decide to register your own implementation.
As a user of MMALSharp, registering your own custom Callback Handler could be useful if you want to gain access to the additional properties exposed by the IBuffer
instance passed to it via the Callback
method.
Callback Handlers currently implement one of the following interfaces: IInputCallbackHandler
, IOutputCallbackHandler
or IConnectionCallbackHandler
and as their names suggest, are used with either Input and Output port callbacks or Connections.
In order to register your own callback handler use the relevant RegisterCallbackHandler
method(s) against a IInputPort
, IOutputPort
or IConnection
instance.
Note: When registering your own Callback Handler for Ports it is important to do this after calling the ConfigureInputPort
/ConfigureOutputPort
methods because these themselves register a default Callback Handler for the port and would override your registration.
Connection Callback Handlers come into play when creating connections between your components and setting useCallback
to true when calling the ConnectTo
method on a IOutputPort
instance. When this parameter is set, the NativeConnectionCallback
method in the MMALConnectionImpl
class which represents the connection between two components will be called when MMAL buffers are passed between them. This functionality has a caveat though: performance. Enabling this should be considered advanced functionality and should only be used when you want to carry out debugging of buffer headers between components. This facility is disabled by default.