Avnu / OpenAvnu

OpenAvnu - an Avnu sponsored repository for Time Sensitive Network (TSN and AVB) technology
464 stars 289 forks source link

[Q]Media clock implementation #817

Open JXter opened 5 years ago

JXter commented 5 years ago

As I understand, for AVB systems media clock recovery is importnat for proper synchronization. I have a few questions on this feature.

  1. Is there any standard document, which says how to recover the media clock? These are some of the functions in OpenAvnu codebase, I would like to know the correct way to implement these functions. void halAdjustMCRNSec(S32 adjNSec); void halAdjustMCRGranularityNSec(U32 adjGranularityNSec);

  2. Is providing embedded media clock and sharing a common media clock same(in terms of synchronization accuracy)?

3.The embedded media clock should be used for adjusting the media clock running on listener or it provides the media clock as such?

  1. While running harness application, I have observed that avtp timestamps of multiple(continuous) packets are same. Timestamp should be the one corresponding to the first sample, but getting same timestamps gives me the idea that all these samples are created at the same time. Is it the way its suppossed to be?

  2. Is there any standard document saying the eligibily criteria for a media clock and whether it should be running on both talker and listener(physical clcok)?

Thank you

pinealservo commented 5 years ago

Media clock recovery is a tricky subject and as far as I've seen one of the most misunderstood parts of AVB. Synchronizing the media clocks of multiple devices that are going to be working with the same streams is critical for any A/V system, not just AVB, but it's typically done in a way that's simpler but less flexible than the mechanism AVB provides.

Rather than repeat it all here, I'm going to refer you to section 3.3 of our Avnu document describing API best practices: https://avnu.org/wp-content/uploads/2014/05/AVnu_SWAPIs-v1.3-SWAVI-Updates_Final_Approved_Clean.pdf

As that document describes, doing media clock recovery (from the embedded sample timestamps) is typically done with some combination of hardware and software. The implementations I'm familiar with will sample the local media clock edges with a high-resolution timer that can be referenced to gPTP time, and then use some kind of adjustment mechanism (often a fine-grained PWM output that's filtered and fed to a voltage-controlled adjustable clock generator or VCXO) to pull the local oscillator into synchronization with the remote one. A media clock master would not necessarily make adjustments, but it would need to be able to generate accurate timestamps of its own media clock if it transmits any live-recorded media.

Due to the hardware/software interface and the Linux-based nature of this project, there's currently no working implementation of media clock recovery that will work on a generic platform. The AVTP Pipeline code has hooks for it, but there's no general Linux API to plug them into. I worked on an add-on card for a Boundary Devices i.MX 6SoloX-based single-board computer that performed clock recovery, with a TI adjustable clock generation chip and one of the SoC's PWM outputs, but did not get a chance to finish the software or hook it up to the stack. It was able to use standard PTP and PWM APIs for the feedback loop, but the granularity and latency of the measurements and control signals was such that it needed some fairly robust control algorithms to keep the system locked and stable, and I hadn't quite got those ironed out.

What I did get implemented for AVTP Pipeline was a way to simulate the timestamps of a local media clock; this is the mcl module which stands for Media Clock Synthesis. This should allow streaming stored media in a way that allows complaint AVB endpoints to recover and sync to the clock implied by the timestamps. This can't just pick the nominal frequency and increment timestamps appropriately because you have to actually timestamp each set of samples with their real presentation time, because an endpoint with full clock recovery will do its best to try to actually play the sample at that real gPTP time. AVTP Pipeline uses the system clock for its control loop, so it will be actually generating samples at that rate on average rather than the nominal gPTP-synchronized rate, and you'll eventually be lying rather badly about when the samples need to be played and the endpoint will get unhappy.

It's been a while and I don't recall the details exactly, but there are a lot of configuration options in the AVTP Pipeline configuration that have to do with how the rawsock implementation you choose to use is going to interact with the media and packetizing plugins. Not every AVTP format does timestamping the same way, so you have to ensure that the settings are appropriate for how you've chosen to do your streaming and shaping. You can also set up a rate ratio offset from nominal with which to generate the media clock synthesis timestamps; this should be set up to match the actual offset that your system runs at and really needs to be hooked up to a self-sychronizing process to keep it accurate. As it is now, it will drift over time as the rate ratio is not perfect and doesn't match changes over time due to temperature fluctuation, etc.

Unfortunately, it's really easy to not get the timestamps right and to generate completely bogus ones that will really confuse endpoints that do clock recovery and expect good timestamps. Semi-unfortunately, a lot of endpoints implementations I've seen will fall back to doing something like FIFO-level-based clock adjustment, which can lead talker endpoint implementors to never actually get their timestamp generation worked out properly. As AVTP Pipeline doesn't have a standard mechanism for clock recovery, it doesn't do anything at present, but if you pipe its output into PulseAudio it will probably do adaptive resampling based on FIFO levels to keep things playing regardless. Otherwise, you'll get occasional clicks and pops or just stream teardowns due to FIFO problems.

If you want to work on clock recovery and need an open source reference implementation to look at, I'd recommend checking out the XMOS AVB endpoint source code, which you can find on github. There's a bit of a learning curve involved with the quirks of their XC language extensions, and their code is modular enough that tracing execution can be a bit difficult when you're not familiar with it, but as pretty much the whole stack is there including a lot of things that would normally be in hardware, there's pretty good visibility into how it works without having to deal with kernel APIs, audio stacks, device drivers, etc. If you can get an XMOS-based AVB dev board, they're also handy for making custom validation tools and the like for testing other implementations.

Anyway, hopefully you can extract some useful info from that.

JXter commented 5 years ago

Thanks Levi, As I understand, there are multiple ways to do media clock recovery and based on the requirements one can choose. I will look into the XMOS implementation for more info on implementation.

One thing I would like you to confirm is, with avtp timestamp field itself one can do media clock recovery at the listener?(The avtp_timestamp may be obtained in different ways based on subtype).

I have seen a variable SYT_INTERVAL, which I assume is constant or preconfigured for a stream or is not communicated between talker and listener with any packet. (in case of audio)

andrew-elder commented 5 years ago

@JXter - yes, you can do media clock recovery from any AVTP stream.