GStreamer Plugin Writer's Guide (0.8.3.2) | ||
---|---|---|
<<< Previous | Supporting Dynamic Parameters | Next >>> |
This is the most critical aspect of the dparams subsystem as it relates to elements. In a traditional audio processing loop, a for loop will usually iterate over each sample in the buffer, processing one sample at a time until the buffer is finished. A simplified loop with no error checking might look something like this.
static void example_chain (GstPad *pad, GstBuffer *buf) { ... gfloat *float_data; int j; GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad)); int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat); float_data = (gfloat *)GST_BUFFER_DATA(buf); ... for (j = 0; j < num_samples; j++) { float_data[j] *= example->volume; } ... } |
To make this dparams aware, a couple of changes are needed.
static void example_chain (GstPad *pad, GstBuffer *buf) { ... int j = 0; GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad)); int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat); gfloat *float_data = (gfloat *)GST_BUFFER_DATA(buf); int frame_countdown = GST_DPMAN_PREPROCESS(example->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf)); ... while (GST_DPMAN_PROCESS_COUNTDOWN(example->dpman, frame_countdown, j)) { float_data[j++] *= example->volume; } ... } |
The biggest changes here are 2 new macros, GST_DPMAN_PREPROCESS and GST_DPMAN_PROCESS_COUNTDOWN. You will also notice that the for loop has become a while loop. GST_DPMAN_PROCESS_COUNTDOWN is called as the condition for the while loop so that any required dparams can be updated in the middle of a buffer if required. This is because one of the required behaviours of dparams is that they can be sample accurate. This means that parameters change at the exact timestamp that they are supposed to - not after the buffer has finished being processed.
It may be alarming to see a macro as the condition for a while loop, but it is actually very efficient. The macro expands to the following.
#define GST_DPMAN_PROCESS_COUNTDOWN(dpman, frame_countdown, frame_count) \ (frame_countdown-- || \ (frame_countdown = GST_DPMAN_PROCESS(dpman, frame_count))) |
So as long as frame_countdown is greater than 0, GST_DPMAN_PROCESS will not be called at all. Also in many cases, GST_DPMAN_PROCESS will do nothing and simply return 0, meaning that there is no more data in the buffer to process.
The macro GST_DPMAN_PREPROCESS will do the following:
Update any dparams which are due to be updated.
Calculate how many samples should be processed before the next required update
Return the number of samples until next update, or the number of samples in the buffer - whichever is less.
A brief explanation of dparam manager modes might be useful here even though it doesn't generally affect the way your element is written. There are different ways media applications will be used which require that an element's parameters be updated in differently. These include:
Timelined - all parameter changes are known in advance before the pipeline is run.
Realtime low-latency - Nothing is known ahead of time about when a parameter might change. Changes need to be propagated to the element as soon as possible.
If you are in a realtime low-latency situation then the "synchronous" mode is appropriate. During GST_DPMAN_PREPROCESS this mode will poll all dparams for required updates and propagate them. GST_DPMAN_PROCESS will do nothing in this mode. To then achieve the desired latency, the size of the buffers needs to be reduced so that the dparams will be polled for updates at the desired frequency.
In a timelined situation, the "asynchronous" mode will be required. This mode hasn't actually been implemented yet but will be described anyway. The GST_DPMAN_PREPROCESS call will precalculate when and how often each dparam needs to update for the duration of the current buffer. From then on GST_DPMAN_PROCESS will propagate the calculated updates each time it is called until end of the buffer. If the application is rendering to disk in non-realtime, the render could be sped up by increasing the buffer size. In the "asynchronous" mode this could be done without affecting the sample accuracy of the parameter updates
All of the explanation so far has presumed that the buffer contains audio data with many samples. Video should be regarded differently since a video buffer often contains only 1 frame. In this case some of the complexity of dparams isn't required but the other benefits still make it useful for video parameters. If a buffer only contains one frame of video, only a single call to GST_DPMAN_PREPROCESS should be required. For more than one frame per buffer, treat it the same as the audio case.
<<< Previous | Home | Next >>> |
Defining Parameter Specificiations | Up | MIDI |