Streamer elements are implemented as Dynamic Shared Objects (DSOs, also commonly referred to as libraries in Linux), which are loaded by the Streamer process in runtime. The very fact that the element is not "alone" in the process in which it executes has some implications on what the element can and cannot do. When designing a Streamer element it is imperative to be aware of the limitations imposed by the environment in which the element will execute.
The element must be cautious about using some of the syscalls provided by the Linux operating system. Some of the syscalls affect the process as a whole and not only the element that might call them. One example is the signal() syscall which installs a signal handler for the process. This may affect the operation of the entire Streamer process, and is therefore by definition not a good idea.
The Streamer process is carefully designed to be single threaded. This is great for performance, stability, robustness, and other system properties. But it is also important to notice that all elements share this single thread. One element must not under any circumstance block this thread on a syscall. If the element has to do I/O, it has to be non-blocking. The IEvent interface is available to assist elements with non-blocking I/O.
It is not recommended for an element to start other threads. If the element has other threads running internally, it is of great importance that these threads do not call functions in Streamer interfaces. The Streamer core only expects calls from elements when the core has called a function in one of the element interfaces. The Streamer core is carefully designed to execute in a single-thread environment, and elements must not break that important property. Threads may also cause conflicts with other parts of the process. Especially threads in combination with signals are often problematic.
An element design based on event handling and the IEvent interface is almost always superior to a design based on multiple threads. There are rare situations with legacy code that cannot be used unless serviced by multiple threads, but other than that staying single threaded is generally a great advantage.
The Streamer creates and destroys elements on demand as it pleases. In practice, the Streamer keeps most of the elements in the pipeline for the duration of a media session, which is the time between opening an URL and closing it. One consequence of this is that when the user zaps quickly from one TV channel to the next, elements get a lifetime of some second or so. This makes it inefficient to collect a lot of state information in the element itself. If the element requires a lot of persistent state information to operate, consider managing that information in a separate process (running all the time the system is not in stand-by mode) and let the element connect to that process using some non-blocking I/O mechanism.
A Linux set-top box is not a Linux PC. The set-top box is an embedded software environment with limited hardware resources at its disposal. Things running nicely on a Linux PC do not necessarily run well on the set-top box. It is important to acknowledge the fact that the set-top box in general, and the Streamer process in particular, is a real-time system. If the system is unable to deliver results in time, the user experience will suffer, regardless of the quality of other aspects of the result.
All elements that process the data stream in the pipeline share a great responsibility to process the stream as efficiently as possible and thereby keeping the load on the CPU as low as possible. If one element in the pipeline is slow, that will affect the speed of the data flow in the entire pipeline.
The speed of the data flow through the pipeline is normally controlled by the HAL video and audio decoders, which derive their decoding speed from clock reference points embedded in the data stream. In general, the Streamer pipeline must be able to push data to these decoders at a rate which is greater than the rate at which the decoders consume the stream. The Streamer itself cannot make this promise, since it just moves stream data from one element to the next and all time-consuming processing is performed by elements supplied in external code modules which the Streamer loads in run-time.
Computing power not consumed by the Streamer and the elements in the pipeline is useful for other parts of the system. For example, the user might want to navigate an Electronic Program Guide (EPG) while having a TV channel running in a window on screen. If an element in the pipeline is slow, it will affect the performance of the EPG as well. Taking the whole picture into account, it is important to always optimize stream processing performed by the elements as much as possible.