The BTimeSource class represents a clock to which nodes can be slaved. By slaving all your nodes to a single master time source, they can be kept in sync with each other.

If a node can, either by design or as a side benefit of the underlying hardware, provide reliable timing services, it might make sense for it to be derived from BTimeSource as well as from whatever other classes it might be derived from, such as BBufferProducer or BBufferConsumer. Doing so will allow other nodes to be slaved to your node's conception of time.

Note that although a BTimeSource is implemented as a real object (and is therefore not a purely abstract class), other nodes won't call your BTimeSource's member functions directly—instead, your BTimeSource will provide data that other nodes will then read.

There are invisible system implementations of the BTimeSource protocol that serve as stand-ins for other nodes, so if you call BMediaRoster::SetTimeSourceFor() to make one of your nodes (which is derived from BTimeSource) a time source for some other node, the other node might see a system stand-in object, not the actual BTimeSource-derived object.

This abstraction layer serves a valuable purpose: it enforces the desire to prevent any two nodes from having to know anything about each other beyond the Media Kit protocols defined in this chapter; this sort of low-level interdependency is discouraged, because it decreases interoperability.

Keeping Time

Although it can be confusing at first, keep in mind that a node derived from both BTimeSource and BBufferProducer (or BBufferConsumer)—which is therefore a time source, as well as a producer or consumer of buffers—has to deal with two different time concepts. As a BTimeSource, it needs to understand requests in real time, while as a BBufferProducer or BBufferConsumer, it needs to accept requests in performance time.

Real time refers to the actual passage of time, as reported by system_time() or the BTimeSource::RealTime() function. It's measured in microseconds.

Performance time runs in "time units" which aren't necessarily directly related to real time. Since your code will have to deal with both kinds of time, you need to be sure to convert between the two time systems when it's necessary to do so. Use the BTimeSource::RealTimeFor() function to do this.

For example, to calculate a timeout value, given a desired performance time, and an estimated latency on the connection, you might use the following code:

bigtime_t timeout = TimeSource()->RealTimeFor(performance_time,
         estimated_latency) - TimeSource()->RealTime();

This code converts the performance_time into the driving time source's units, then subtracts the current real time, which results in the desired timeout value.

Creative Commons License
Legal Notice
This work is licensed under a Creative Commons Attribution-Non commercial-No Derivative Works 3.0 License.