Skip to content

Fix stale decryptOnlyCodecFormat used for non-DRM periods - #3390

Open
kmate-dolby wants to merge 1 commit into
androidx:mainfrom
DolbyLaboratories:main-dlb/wrong-period-format-used-for-non-DRM-periods
Open

Fix stale decryptOnlyCodecFormat used for non-DRM periods#3390
kmate-dolby wants to merge 1 commit into
androidx:mainfrom
DolbyLaboratories:main-dlb/wrong-period-format-used-for-non-DRM-periods

Conversation

@kmate-dolby

Copy link
Copy Markdown

When an audio stream is played back directly (passthrough or offload) but is DRM protected, MediaCodecAudioRenderer still instantiates a MediaCodec that is used only to decrypt the samples. In that case getMediaCodecConfiguration() stores the input format in decryptOnlyCodecFormat, and onOutputFormatChanged() uses it to configure the AudioSink with the original (encoded) format instead of the codec's raw output.

decryptOnlyCodecFormat is only ever assigned in
getMediaCodecConfiguration(), which runs from initCodec() and is therefore only reached for periods that actually create a codec. It was never cleared when the codec was released, so it lived for as long as the renderer did.

As a result, for a DRM, non-DRM, DRM period sequence the non-DRM period is played through codec bypass and does not initialize a codec, so getMediaCodecConfiguration() is not called. onOutputFormatChanged() then still sees the decryptOnlyCodecFormat left over from the previous DRM period and configures the AudioSink with that stale format instead of the current one. Because the two formats can differ (for example in channel count), the sink is configured with the wrong input format.

Fix this by clearing decryptOnlyCodecFormat when the codec is released, by overriding resetCodecStateForRelease() in MediaCodecAudioRenderer.

When an audio stream is played back directly (passthrough or
offload) but is DRM protected, MediaCodecAudioRenderer still
instantiates a MediaCodec that is used only to decrypt the
samples. In that case getMediaCodecConfiguration() stores the
input format in decryptOnlyCodecFormat, and onOutputFormatChanged()
uses it to configure the AudioSink with the original (encoded)
format instead of the codec's raw output.

decryptOnlyCodecFormat is only ever assigned in
getMediaCodecConfiguration(), which runs from initCodec() and is
therefore only reached for periods that actually create a codec.
It was never cleared when the codec was released, so it lived for
as long as the renderer did.

As a result, for a DRM, non-DRM, DRM period sequence the non-DRM
period is played through codec bypass and does not initialize a
codec, so getMediaCodecConfiguration() is not called.
onOutputFormatChanged() then still sees the decryptOnlyCodecFormat
left over from the previous DRM period and configures the AudioSink
with that stale format instead of the current one. Because the two
formats can differ (for example in channel count), the sink is
configured with the wrong input format.

Fix this by clearing decryptOnlyCodecFormat when the codec is
released, by overriding resetCodecStateForRelease() in
MediaCodecAudioRenderer.
@tianyif tianyif self-assigned this Aug 28, 2026
@kmate-dolby

Copy link
Copy Markdown
Author

Hi @tianyif, thank you for self assigning. Anything I can do to help you review my proposed fix? Thank you in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants