Synchronization

In some circumstances, it is necessary to have a number of individual Players (or perhaps Processors) as part of a single application. An example of such a situation might be an AV conference over RTP, particularly if there are multiple participants. Each participant is likely to send separate audio and video streams. Hence, recipients require a number of Players: one for each stream. Imagine such a three-way conference; each participant requires four Players, one audio player, and one video player for each of the two participants from which they are receiving. Figure 9.11 shows such a situation. Each player is controlled individually.

Figure 9.11. A three-way AV conference from the perspective of one of the participants showing the players needed in order to render the media being streamed to it.


Controlling all those players individually not only is tedious, but also often doesn't match the desired solution. Generally it is easier (both as a user and programmer) to centralize the control. Actions on the one centralized controller (Player) should then automatically propagate to all those it oversees. For instance, selecting Stop should stop all players. The JMF provides such a feature through the Player class.

A Player (Processors are also a type of Player) object is capable of controlling one or more additional Controllers (Players or Processors). Actions (methods) on the central Player are also propagated to all Controllers that the Player controls. For instance, invoking prefetch() on the central Player would cause prefetch() to be called on all Controllers that the Player controls. Figure 9.12 shows the previous scenario of a three-way AV conference from the perspective of one of the participants. However in this case, rather than controlling each Player separately, the Player for participant B's video is also the central control for all Players. Any actions carried out on that Player (such as stopping it) also affect the other players.

Figure 9.12. In this case, control of the players is centralized through one of their numbers.


A Player object is given control over another Controller with Player's addController() method. Similarly you can remove a Controller object from a Player with the removeController() method. The following code fragment shows two Players being constructed, and player1 is given control over player2. They are both brought to the realized state by invoking realize() on the central Player, which is player1.

Player player1 = Manager.createPlayer(...);
Player player2 = Manager.createPlayer(...);
player1.addController(player2);
player1.realize();

Several features of the synchronized control are worth noting:

  • The added controller assumes the centralized Player object's TimeBase.

  • The Player object's duration is the maximum of its own duration and that of all Controller objects under its direction.

  • The start latency of the Player is the maximum of the Player's own start latency and that of all Controller objects under its direction. This ensures that all Controllers will start simultaneously using the syncStart() method.

  • The Player object only posts completion events (for example, PrefetchCompleteEvent) when all managed Controllers have also posted the event.

  • All Controller methods invoked on the central Player object are propagated to all Controllers under its direction.

  • Although Controllers are under the central direction of a Player, they shouldn't have their methods invoked individually. All method invocation should occur by way of the central Player object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset