androidx / androidx/media

Repeated characters in CEA 608 captions

Open
#887 11 comments 0 reactions 1 assignee View on GitHub

@icbaker is already working on this.

Since Dec 13, 2023.

bug
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

Version

Media3 1.2.0

More version details

Happens on earlier versions as well.

Devices that reproduce the issue

Not dependent on any device. Reproducible e.g. on Pixel 6a or Pixel 6 emulator with Android 12/13/14

Devices that do not reproduce the issue

/

Reproducible in the demo app?

Yes

Reproduction steps
  1. Load stream (will share via e-mail)
  2. Enable en subtitle
  3. Observe subtitles
Expected result

Subtitles displayed normally, e.g. Pork chops!

Actual result

This is a potential duplicate of https://github.com/google/ExoPlayer/issues/10209#issue-1210059727. If you think I should rather add these findings to the existing issue in the ExoPlayer repository please let me know.

The asset is a DASH stream with the following Acessibility tag:

<Accessibility schemeIdUri="urn:scte:dash:cc:cea-608:2015" value="CC1=eng;CC3=spa" />

While the tag advertises two CC subtitle tracks, the CC3 (spanish) track is actually not present.
While this is obviously not ideal, the resulting Behaviour in ExoPlayer is quite unexpected:

Cues have repeating characters in pairs of two:
PoPorkrk c chohopsps!! instead of Pork chops!

In addition to this, the following error is reported in logcat without crashing:

  java.lang.IllegalStateException: Different languages combined in one TrackGroup: 'en' (track 0) and 'es' (track 1)
  at androidx.media3.common.TrackGroup.logErrorMessage(TrackGroup.java:234)
  at androidx.media3.common.TrackGroup.verifyCorrectness(TrackGroup.java:201)
  at androidx.media3.common.TrackGroup.<init>(TrackGroup.java:94)
  at androidx.media3.exoplayer.dash.DashMediaPeriod.buildPrimaryAndEmbeddedTrackGroupInfos(DashMediaPeriod.java:716)
  at androidx.media3.exoplayer.dash.DashMediaPeriod.buildTrackGroups(DashMediaPeriod.java:523)
  at androidx.media3.exoplayer.dash.DashMediaPeriod.<init>(DashMediaPeriod.java:158)
  at androidx.media3.exoplayer.dash.DashMediaSource.createPeriod(DashMediaSource.java:544)
  at androidx.media3.exoplayer.source.MaskingMediaPeriod.createPeriod(MaskingMediaPeriod.java:130)
  at androidx.media3.exoplayer.source.MaskingMediaSource.onChildSourceInfoRefreshed(MaskingMediaSource.java:196)
  at androidx.media3.exoplayer.source.WrappingMediaSource.onChildSourceInfoRefreshed(WrappingMediaSource.java:132)
  at androidx.media3.exoplayer.source.WrappingMediaSource.onChildSourceInfoRefreshed(WrappingMediaSource.java:47)
  at androidx.media3.exoplayer.source.CompositeMediaSource.lambda$prepareChildSource$0$androidx-media3-exoplayer-source-CompositeMediaSource(CompositeMediaSource.java:117)
  at androidx.media3.exoplayer.source.CompositeMediaSource$$ExternalSyntheticLambda0.onSourceInfoRefreshed(Unknown Source:4)
  at androidx.media3.exoplayer.source.BaseMediaSource.refreshSourceInfo(BaseMediaSource.java:90)
  at androidx.media3.exoplayer.dash.DashMediaSource.processManifest(DashMediaSource.java:905)
  at androidx.media3.exoplayer.dash.DashMediaSource.onManifestLoadCompleted(DashMediaSource.java:683)
  at androidx.media3.exoplayer.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:1362)
  at androidx.media3.exoplayer.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:1357)
  at androidx.media3.exoplayer.upstream.Loader$LoadTask.handleMessage(Loader.java:480)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:201)
  at android.os.Looper.loop(Looper.java:288)
  at android.os.HandlerThread.run(HandlerThread.java:67)

But I don't think that this is the root cause of the problem but rather a general issue in how multiple embedded CEA 608 tracks are represented. See https://github.com/androidx/media/commit/76700e9d84b58df11b0dd4ff749c6b5597ea34cc for reference.

When looking into this topic in a bit more detail, it seems like the Cea608Decoder.decode function is called twice with the same inputBuffer. As each call decodes two characters (ccData1 and ccData2), the result is the repeating pattern of two characters. If the Accessibility tag only contains a single CC track, it is only called once.

Another observation is that the TextRenderer that holds the Cea608Decoder has the wrong Format (Spanish when English is selected) in the formatHolder property. IMO this has to do with how ChunkSampleStream.selectEmbeddedTrack selects the track solely base on trackType which is obviously TRACK_TYPE_TEXT for both embeddedTrackFormats as they are both subtitle tracks.

The first embeddedSampleQueues it encounters is - by coincidence - the Spanish one.
Worth mentioning that forcing the correct embeddedSampleQueues to be used does not fix the problem, probably because they both contain the same content as they are filled with the same samples in CeaUtil.consume called from the FragmentedMp4Extractor.

Media

Stream was shared via e-mail.

Bug Report
  • You will email the zip file produced by adb bugreport to android-media-github@google.com after filing this issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.