<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1924990957;
        mso-list-type:hybrid;
        mso-list-template-ids:-1699290914 68812815 68812825 68812827 68812815 68812825 68812827 68812815 68812825 68812827;}
@list l0:level1
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:53.4pt;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:89.4pt;
        text-indent:-18.0pt;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:125.4pt;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:161.4pt;
        text-indent:-18.0pt;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:197.4pt;
        text-indent:-18.0pt;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:233.4pt;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:269.4pt;
        text-indent:-18.0pt;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:305.4pt;
        text-indent:-18.0pt;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:341.4pt;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="HR" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hi all,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">During the testing of our RTSP implementation which is using gst-rtsp-server we noticed that not all RTSP clients will have audio/video synchronized, and that making some changes will fix the sync in one client while
 breaking the sync in another one.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">The pipeline used in gst-rtsp-server looks like this, although this can be modified based on the requested configuration:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">appsrc is-live=true do-timestamp=true min-latency=0 ! h264parse ! rtph264pay name=pay0 pt=96<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">appsrc is-live=true do-timestamp=true min-latency=0  ! audioconvert ! audioresample ! mulawenc ! rtppcmupay name=pay1 pt=0<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Video appsrc is getting buffers from another pipeline where we are dynamically adding/removing branch for RTSP as needed, simplified pipeline which is providing video looks like this:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">v4l2src do-timestamp=true ! tee ! queue ! videorate drop-only=true ! imxvideoconvert_g2d  ! vpuenc_h264 ! appsink<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Audio appsrc is also getting buffers from another pipeline where we are dynamically adding/removing branch for RTSP as needed:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">appsrc is-live=true min-latency=0  ! tee ! queue  ! appsink<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Appsrc in this pipeline is getting buffers directly from our application, the reason for this audio only pipeline is that we want to avoid accessing audio from RTSP multiple times, the only purpose of this pipeline is
 to duplicate buffers via tee element for as many times as RTSP needs it (we have more than one media factory/mount point). In this case we are manually timestamping audio buffers like in the example from
<a href="https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html?gi-language=c">
https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html?gi-language=c</a> , i.e.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer) = gst_util_uint64_scale (audioGenerator->num_samples, GST_SECOND, audioGenerator->samplerate);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">gst-rtsp-pipeline is grabbing buffers from the two pipelines more or less the same as in the example
<a href="https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-appsrc2.c">
https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-appsrc2.c</a> but without manually setting the timestamps since we are letting the appsrc do that by setting the do-timestamp=true as described in
<a href="https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html?gi-language=c#inserting-data-with-appsrc">
https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html?gi-language=c#inserting-data-with-appsrc</a><b>
</b>.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Audio and video branches are dynamically added on the “media-configure” callback according to the configuration linked to mounting point.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">All media factories which we use have the “shared” property set to true.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<ol style="margin-top:0cm" start="1" type="1">
<li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">This implementation works perfectly fine in VLC for audio/video sync, however in one VMS audio was constantly late for around 1 second.<o:p></o:p></span></li></ol>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">One thing worth mentioning is that this specific VMS is pushing its own configuration via ONVIF which will result in having 2 different ONVIF media profiles (see
<a href="https://www.onvif.org/specs/srv/media/ONVIF-Media-Service-Spec.pdf?26d877&26d877">
https://www.onvif.org/specs/srv/media/ONVIF-Media-Service-Spec.pdf?26d877&26d877</a> for details if you are interested), where one of those will be used for video, and the second one for audio.
<br>
For the gst-rtsp-server this means that there will be 2 separate RTSP requests with 2 different URLs and that for the first one the pipeline will be<br>
appsrc is-live=true do-timestamp=true min-latency=0 ! h264parse ! rtph264pay name=pay0 pt=96<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">and for the scond one the pipeline will be<br>
appsrc is-live=true do-timestamp=true min-latency=0  ! audioconvert ! audioresample ! mulawenc ! rtppcmupay name=pay1 pt=0<br>
So the RTP streams are negotiated and started independently of one another over separate RTSP sessions.<br>
After some experimentation audio/video sync was fixed by setting the “max-size-time” property of the queue element in the audio pipeline (not the gst-rtsp-server pipeline but the pipeline providing audio buffers) to 100ms.<br>
Setting the “leaky” property of the queue element seems to have no effect at all in this situation.
<br>
My understanding is that for some reason the gst-rtsp-server  pipeline was not grabbing the buffers and sending them fast enough, at least when compared to the video pipeline?<br>
Since the RTP streams, and gst-rtsp-server pipelines, are independent from one another I don’t really see what can be done to synchronize them on the gst-rtsp-server level?<br>
<br>
<o:p></o:p></span></p>
<ol style="margin-top:0cm" start="2" type="1">
<li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">VMS number 2 is initially in sync but after 5-10 minutes audio starts to be late, this is the same with or without changes described under 1.<br>
After some more experimentation this was solved by setting the “max-size-time” property of the queue element in the audio pipeline to 20ms, and by setting the "max-buffers" to 20 and "drop" to true for the appsink element in the audio pipeline.<br>
VMS number 1 is still working fine, but now in VLC the video is starting to be late.<br>
Why and how can the queue and appsink elements from the originating pipeline affect audio/video synchronization in gst-rtsp-server pipeline?<br>
Does this has anything to do with latency of all involved pipelines? I also tried to query max-latency of audio/video pipelines and set those values as “max-latency” on appropriate appsrc elements but that did not seem to have any effect.<br>
<br>
<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">VMS number 3 is always having audio from between 5 to 10 seconds late, absolutely nothing I’ve tried had any impact on this.<br>
In this case VMS is establishing 2 RTSP sessions but is using the same URL.<br>
Since the media factory is share, could that have any effect on the audio/video sync or timestamping of the buffers?<br>
<br>
<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">Regarding “do-timestamp” of the appsrc, this does the same as if we would manually set the timestamps like this in the “need-data” callback?<o:p></o:p></span></li></ol>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">// PTS/DTS = absolute (current) time - base (start) time<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">GstClockTime pts, dts;<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">GstClock *appsrcClock =  gst_element_get_clock (appsrc);<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US">pts = dts = gst_clock_get_time (appsrcClock) - gst_element_get_base_time(appsrc);<br>
GST_BUFFER_PTS (buffer) = pts;<br>
GST_BUFFER_DTS (buffer) = dts;<br>
In the case of appsrc for the originating audio pipeline, using the “do-timestamp” or trying to set the timestamps as in the code above did not work (audio could not be heard), are there some specific situations where the “do-timestamp” should not be used?<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:53.4pt"><span lang="EN-US"><o:p> </o:p></span></p>
<ol style="margin-top:0cm" start="5" type="1">
<li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">My understanding is that the buffers always need to be re-timestamped in the gst-rtsp-server pipeline, because for example the pipeline from which we are grabbing
 the buffers might be already running for some time and those buffers already have timestamps which reflect that. Can the values or the way timestamps are set (for example if they are set by “do-timestamp” or manually) of the original timestamps in any way
 affect the “new” timestamps generated in gst-rtsp-server pipeline?<br>
<br>
<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:17.4pt;mso-list:l0 level1 lfo1"><span lang="EN-US">Beside the buffer timestamps, is there anything else that we need to take care of so that audio and video are in sync?<br>
What is confusing to me is that the audio/video sync is working depending on the client, if it was not working at all I would know that there’s definitely a problem in our implementation.<br>
I’ve found a similar problem discussed in the mail list but without concrete solution
<a href="http://gstreamer-devel.966125.n4.nabble.com/Issues-trying-to-synchronise-video-appsrc-with-audio-td4667004.html">
http://gstreamer-devel.966125.n4.nabble.com/Issues-trying-to-synchronise-video-appsrc-with-audio-td4667004.html</a>
<br>
<br>
<o:p></o:p></span></li></ol>
<p class="MsoNormal"><span lang="EN-US">Regards,<br>
Mihael.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
<br clear="both">
DISCLAIMER:<BR>
This e-mail may contain confidential and privileged material for the sole use of the intended recipient. Any review, use, distribution or disclosure by others is strictly prohibited. If you are not the intended recipient (or authorized to receive for the recipient), please contact the sender by reply e-mail and delete all copies of this message.<BR>
No employee of Zenitel has the authority to conclude via e-mail any binding contract without an explicit written consent of their supervisor, and Zenitel does not take responsibility for it&#x02019;s content, and will not enter into an agreement, without this written consent.<BR>
</body>
</html>