Talk to me: Finding the magic number when debugging DASH streams on Samsung 2017 SmartTVs

Spoiler alert: What lies between 237.58 and 237.59 ? No, my cat did not walk over my keyboard and just entered some random numbers (I don’t even have a cat). Somewhere in between these two numbers lies a magical number. At least a magical number when debugging DASH streams on Samsung 2017 devices.

I can’t hear you over the voices in my head

Ok, let’s wind back a bit. Quite recently one of our customer approached us with an odd problem. They produced a set of MPEG-DASH test streams for different platforms. On Samsung 2017 TV devices the unencrypted and the encrypted versions of these streams behaved differently when running in dash.js: For some reason there was no sound in the unencrypted version of the content. Isn’t this usually the other way around? Typically, something is not working in the encrypted content. Consequently, when we first heard about this we were a bit skeptical and started our tests. And what can we say? They are right!

The issue is easy to reproduce. Simply take a stream from the DASH-IF Live simulator, for instance https://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd. Build a small Tizen application including dash.js, throw that stream on a Samsung 2017 and you will hear …. nothing! No sound at all, the video, however, is playing fine. Consequently, there has to be data in the audio SourceBuffer of the Media Source Extensions. Otherwise, playback wouldn’t start at all.

206.879.537.681 is a magic number

At this point, we will spare you all the details about our first attempts comparing different codec profiles, levels and so on and get straight to the point: Our test devices don’t like large timestamps in the media segments. What do we consider large? Well, a number between 237.58 and 237.59, of course.

Let’s dive a bit deeper into DASH terminology. The MPD@availabilityStartTime is the anchor time for dynamic media presentations (live streams). Typically, the presentation time zero maps to the wallclock time that is defined in MPD@availabilityStartTime. Many packagers simply use the UNIX epoch availabilityStartTime="1970-01-01T00:00:00Z"

That leads to high timestamps in the media segments depending on the timescale value. Taking the DASH-IF Live Simulator MPD from above we find a value such as 79603623840768 for the baseMediaDecodeTime of an audio segment in the tfdt box. This is precisely what seems to cause the problems on our Samsung 2017 device. Once the timestamps reach a certain value (between 237.58 and 237.59) we don’t hear sound anymore.

Wait! I think I can hear something!

Now how can we fix this? There are basically two ways, a rather simple one and a complicated one. The simple one is to adjust the MPD@availabilityStartTime in our packager and let it produce segments with smaller timestamps. For the DASH-IF Live simulator we can simply add the target time to the URL, for example: https://livesim.dashif.org/livesim/ast_1658390879/testpic_2s/Manifest.mpd. This leads to availabilityStartTime="2022-07-21T08:07:58Z"

And voilà, we got sound again (at least for some time). The timestamps in the segments are much smaller now, for instance 865632256. In general, the magic formula to find the right MPD@availabilityStartTime could look this:

App.prototype.generateUrl = function(threshold) {
	var basicSourceFirstPart = 'https://livesim.dashif.org/livesim/';
	var basicSourceLastPart = '/testpic_2s/Manifest.mpd';
	var timescale = 48000;
	var valueInSeconds = parseInt(threshold / timescale);
	var now = parseInt(Date.now() / 1000);
	var ast = Math.max(now-valueInSeconds, 0);

	return basicSourceFirstPart + 'ast_' + ast + basicSourceLastPart;
}

The threshold needs to be smaller than 237.59, don’t forget to take the runtime of your content into account.

For means of completion, let’s briefly discuss the other option to overcome this issue. In theory, we could keep availabilityStartTime="1970-01-01T00:00:00Z" in our manifest and simply rewrite the timestamps in the media segments. However, by rewriting the timestamps we are also changing the position of the segments in the buffer. To account for this we can adjust the @presentationTimeOffset in the MPD. A client is positioning the media segment in the buffer the following way:

Sourcebuffer.timestampOffset = Period@start - MPD@presentationTimeOffset
Position in the buffer = Sourcebuffer.timestampOffset + Segment.baseMediaDecodeTime + Segment.compositionOffset

By setting the @presentationTimeOffset to a negative value we could shift the segments with lowered timestamps to their original position. However, this is just a theory we had, we did not confirm that this approach really works.

That concludes our journey into the world of magic numbers and the fun that can be stream debugging. If you have any question regarding our DASH activities or dash.js in particular, feel free to check out our website and contact us.

Leave a Reply

Your email address will not be published.