Image for post
Image for post

Debugging Problem

This is a story of how I debugged a non-crash playback issue and hope this helps someone solve these kinds of problems.

Ticket assignment

audio and video stop for a very short amount of time (like 500ms) when switching from a lower resolution to a higher resolution.

One day this ticked was assigned to me, and I started an investigation.

EventLogger and DebugTextViewHelper

EventLogger

Image for post
Image for post
setting an EventLogger

DebugViewHelper

Image for post
Image for post
DebugView Overlay
Image for post
Image for post
setting a DebugViewHelper

looking at the logs from EventLogger, I found that c2.android.aac.decoder was reinitialized for some reason when a resolution switch happened, and at that time the playback stall happened.

Image for post
Image for post
EventLogger Log

To know the reason why the audio decoder is reinitialized, I started looking for the conditions of decoder initialization from ExoPlayer source code and finally found it.

canKeepCodec function determines whether or not decoder should be initialized. Our media of ~240p was monaural sound and 360p~ was stereo sound andcanKeepCodec returns KEEP_CODEC_RESULT_NO when the channel count is different.

Image for post
Image for post
reinitialization codec

Systrace

To take a deeper look, you can use systrace, which allows you to collect and inspect timing information across all processes running on your device at the system level, and ExoPlayer embeds their own information by default. While ExoPlayer is playing some media, you can start tracing using this command below.

python .../platform-tools/systrace/systrace.py --app=your.package.name

If you want to know systrace more, this youtube video is very helpful.

Android Performance: An Overview

And this is what I got when audio decoder reinitialization happened. 10

Image for post
Image for post
systrace

The thin blue bars are releaseOutputBuffer and these are timings when video frames are rendered on a provided surface, so if you play some 30fps video you will see the blue bar every 33.3ms.

When the audio decoder reinitialization happens, there is a time gap of 500ms until the next frame is rendered on the ExoPlayerImplIn thread. Considering ExoPlayer retrieves audio output buffer and video output buffer with the same single thread, audio decoder reinitialization may delay next video frame rendering.

After fixed to use the same channel count across all resolutions, playback stalls never happened. 🚀

References

Written by

Android Engineer at AbemaTV Github: https://github.com/takusemba

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store