next up previous contents index
Next: Network Communication Up: Local Data Flow Previous: Media Elements

Intra-Application Data Flow

Figure gif illustrates the method invocations that shape the local, intra-application data flow.

 
Figure:  The local intra-application data flow and involved method invocations.

  

Producer and Consumer objects are active multimedia objects in the sense of Gibbsgif, that is, to each Producer or Consumer is assigned an exclusive thread of control. Besides, Producers and Consumers are required to have a Start(), Stop() and Finish() method.

   A Producer's only task is to generate multimedia data. The distribution of this data is handled by an associated StreamExporter object: a Producer calls the exportChunk() method of its StreamExporter for each generated media element. In turn, the StreamExporter distributes the media elements among the various Consumers by calling the importChunk() method of every registered Stream object. A Stream object queues the imported media elements until the Consumer extracts the elements by calling a get() method. Thereby, the activities of the Producer and Consumers become asynchronous. To avoid memory overflow, the Stream object can implement flow control algorithms, which can, if necessary, drop Chunks or refuse new Chunks. The decision, which Chunk to drop or refuse, depends highly only the media type. For example, the deletion of MPEG I-frames renders following B- and P-frames useless, hence no I-frames should get lost.

A Consumer object that desires to import a multimedia data stream from a particular StreamExporter invokes the importStream() method of the StreamManager, passing the desired StreamExporter and Stream class as arguments. The StreamManager instantiates a Stream object of the requested class and registers it with the StreamExporter. The registration causes the StreamExporter to export any new media elements from that time on to the new Stream object, too. The consumer obtains the newly instantiated Stream object as a result of the importStream() method invocation, and can now receive new media elements by repeatedly invoking one of the get() methods of its Stream object.

The get() methods of a Stream object differ in their semantics. All the get() methods extract the first Chunk element of the Stream's internal media element queue if a Chunk is available, or block the caller until a new Chunks arrives. The differences lie in the type of the returned media elements and the time-related behaviour: the returned object can either be simple Chunk object or a media element object of a more complex class; furthermore, a get() method may or may not delay the caller for the purpose of playout synchronisation.

    As mentioned above, TimedObjects are used to facilitate inter- and intra-stream playout synchronisation. The necessary timing information is extracted from the timestamps of the Chunks, from which the TimedObjects are constructed. To map the timestamps to instants measurable in local wall-clock time, each Stream contains a Clock object, whose timestamp--to--wall-clock-time ratio is controlled by the StreamExporter's Master_Clock object. Each Clock may have an individual playout offset delay, however. Inter-stream synchronisation is achieved by adjusting the playout delay of one Stream's Clock to the playout delay of another related Stream. This adjustment requires a mapping between the Chunks' timestamps and the points of time of the generation of the Chunks. For example, RTCP sender reports provide this correspondence by means of an RTP timestamp and an NTP timestamp, which both denominate the same point of time, as described in Section gif.



next up previous contents index
Next: Network Communication Up: Local Data Flow Previous: Media Elements



tspeuker@cip.informatik.uni-erlangen.de