{"id":280,"date":"2015-05-14T19:44:05","date_gmt":"2015-05-14T17:44:05","guid":{"rendered":"https:\/\/coaxion.net\/blog\/?p=280"},"modified":"2015-05-14T20:13:09","modified_gmt":"2015-05-14T18:13:09","slug":"ptp-network-clock-support-in-gstreamer","status":"publish","type":"post","link":"https:\/\/coaxion.net\/blog\/2015\/05\/ptp-network-clock-support-in-gstreamer\/","title":{"rendered":"PTP network clock support in GStreamer"},"content":{"rendered":"<p>In the last days I was working at <a href=\"http:\/\/www.centricular.com\" target=\"_blank\">Centricular<\/a> on adding PTP clock support to <a href=\"http:\/\/gstreamer.freedesktop.org\" target=\"_blank\">GStreamer<\/a>. This is now mostly done, and the results of this work are public but not yet merged into the GStreamer code base. This will need some further testing and code review, see the related bug report <a href=\"https:\/\/bugzilla.gnome.org\/show_bug.cgi?id=749391\" target=\"_blank\">here<\/a>.<\/p>\n<p>You can find the current version of the code <a href=\"http:\/\/cgit.freedesktop.org\/~slomo\/gstreamer\/log\/?h=ptp\" target=\"_blank\">here<\/a> in my freedesktop.org GIT repository. See at the very bottom for some further hints at how you can run it.<\/p>\n<p>So what does that mean, how does it relate to GStreamer?<\/p>\n<h4>Precision Time Protocol<\/h4>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Precision_Time_Protocol\" target=\"_blank\">PTP<\/a> is the Precision Time Protocol, which is a network protocol standardized by the IEEE (IEEE1588:2008) to synchronize the clocks between different devices in a network. It&#8217;s similar to the better-known <a href=\"https:\/\/en.wikipedia.org\/wiki\/Network_Time_Protocol\" target=\"_blank\">Network Time Protocol<\/a> (NTP, IETF RFC 5905), which is probably used by millions of computers down there to automatically set the local clock. Different to NTP, PTP promises to give much more accurate results, up to microsecond (or even nanosecond with PTP-aware network hardware) precision inside appropriate networks. PTP is part of a few broadcasting and professional media standards, like <a href=\"https:\/\/en.wikipedia.org\/wiki\/AES67\" target=\"_blank\">AES67<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ravenna_%28networking%29\" target=\"_blank\">RAVENNA<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Audio_Video_Bridging\" target=\"_blank\">AVB<\/a>, SMPTE ST 2059-2 and others for inter-device synchronization.<\/p>\n<p>PTP comes in 3 different versions, the old PTPv1 (IEEE1588-2002), PTPv2 (IEEE1588-2008) and IEEE 802.1AS-2011. I&#8217;ve implemented PTPv2 via UDPv4 for now, but this work can be extended to other variants later.<\/p>\n<h4>GStreamer network synchronization support<\/h4>\n<p>So what does that mean for GStreamer? We are now able to synchronize to a PTP clock in the network, which allows multiple devices to accurately synchronize media to the same clock. This is useful in all scenarios where you want to play the same media on different devices, and want them all to be completely synchronized. You can probably imagine quite a few use cases for this yourself now, especially in the context of the &#8220;Internet of Things&#8221; but also for more normal things like video walls or just having multiple screens display the same thing in the same room.<\/p>\n<p>This was already possible previously with the GStreamer network clock, but that clock implements a custom protocol that only other GStreamer applications can understand currently. See for example <a href=\"http:\/\/noraisin.net\/diary\/?p=954\" target=\"_blank\">here<\/a>, <a href=\"http:\/\/gstreamer.freedesktop.org\/data\/doc\/gstreamer\/head\/gstreamer-libs\/html\/GstNetClientClock.html\" target=\"_blank\">here<\/a> or <a href=\"https:\/\/github.com\/thaytan\/aurena\" target=\"_blank\">here<\/a>. With the PTP clock we now get another network clock that speaks a standardized protocol and can interoperate with other software and hardware.<\/p>\n<h4>Performance, WiFi and other unreliable networks<\/h4>\n<p>When running the code, you will probably notice that PTP works very well in controlled and reliable networks (2-20 microseconds accuracy is what I got here). But it&#8217;s not that accurate in wireless networks or in general unreliable networks. It seems like in those networks the custom GStreamer network clock protocol works more reliable currently, partially by design.<\/p>\n<h4>Future<\/h4>\n<p>As a next step, at <a href=\"http:\/\/www.centricular.com\" target=\"_blank\">Centricular<\/a> we&#8217;re going to look at implementing support for <a href=\"https:\/\/tools.ietf.org\/html\/rfc7273\" target=\"_blank\">RFC7273<\/a> in GStreamer, which allows to signal media clocks for <a href=\"https:\/\/tools.ietf.org\/html\/rfc3550\" target=\"_blank\">RTP<\/a>. This is part of e.g. AES67 and RAVENNA and would allow multiple RTP receivers to be perfectly synchronized against a PTP clock without any further configuration. And just for completeness, we&#8217;re probably going to release a NTP based GStreamer clock in the near future too.<\/p>\n<h4>Running the code<\/h4>\n<p>If you want to test my code, you can run it for example against <a href=\"http:\/\/ptpd.sourceforge.net\" target=\"_blank\">PTPd<\/a>. And if you want to test the accuracy of the clock, you can measure it with the <a href=\"http:\/\/code.centricular.com\/ptp-clock-reflector\/\" target=\"_blank\">ptp-clock-reflector<\/a> (or <a href=\"https:\/\/github.com\/sdroege\/ptp-clock-reflector\" target=\"_blank\">here<\/a>, instructions in the README) that I wrote for testing. The latter allows you to measure the accuracy, and in a local wired network I got around 2-20 microseconds accuracy. A GStreamer example application can be found <a href=\"http:\/\/cgit.freedesktop.org\/~slomo\/gstreamer\/tree\/tests\/examples\/ptp\/ptp-print-times.c?h=ptp\" target=\"_blank\">here<\/a>, which just prints the local and remote PTP clock times. Other than that you can use it just like any other clock on any GStreamer pipeline you can imagine.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last days I was working at Centricular on adding PTP clock support to GStreamer. This is now mostly done, and the results of this work are public but not yet merged into the GStreamer code base. This will need some further testing and code review, see the related bug report here. You can &hellip; <a href=\"https:\/\/coaxion.net\/blog\/2015\/05\/ptp-network-clock-support-in-gstreamer\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">PTP network clock support in GStreamer<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,5],"tags":[],"class_list":["post-280","post","type-post","status-publish","format-standard","hentry","category-free-software","category-gstreamer"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/comments?post=280"}],"version-history":[{"count":14,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/280\/revisions"}],"predecessor-version":[{"id":295,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/280\/revisions\/295"}],"wp:attachment":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/media?parent=280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/categories?post=280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/tags?post=280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}