Skip to content

Enable embedded CEA-708 support#7370

Closed
jruesga wants to merge 2 commits intogoogle:dev-v2from
jruesga:embedded-cea-708-support
Closed

Enable embedded CEA-708 support#7370
jruesga wants to merge 2 commits intogoogle:dev-v2from
jruesga:embedded-cea-708-support

Conversation

@jruesga
Copy link
Contributor

@jruesga jruesga commented May 13, 2020

Currently, DashMediaPeriod only takes into account as CEA-608 accessibility tags as embedded closed captions tracks CEA-608. CEA-708 closed captions format is parsed when is present on its own AdaptationSet, but not when is embedded as an accessibility tag in a video AdaptationSet.

Embedded CEA-708 support is added by parsing accessibility tags like the example below:

<Accessibility schemeIdUri="urn:scte:dash:cc:cea-708:2015" value="1=lang:eng;2=lang:deu"/>
<Accessibility schemeIdUri="urn:scte:dash:cc:cea-708:2015" value="1=lang:eng;2=lang:eng,war:1,er:1"/>

Creates a new CEA-708 track for accessibility tags with schemeIdUri urn:scte:dash:cc:cea-708:2015 and extract accessibilityChannel and language from value attribute.

Currently, DashMediaPeriod only takes into account as CEA-608 accessibility tags as embedded
closed captions tracks CEA-608. CEA-708 closed captions format is parsed when is present on
its own AdaptationSet, but not when is embedded as an accessibility tag in a video AdaptaticonSet.

Embedded CEA-708 support is added by parsing accessibility tags like the example below:

  <Accessibility schemeIdUri="urn:scte:dash:cc:cea-708:2015" value="1=lang:eng;2=lang:deu"/>
  <Accessibility schemeIdUri="urn:scte:dash:cc:cea-708:2015" value="1=lang:eng;2=lang:eng,war:1,er:1"/>

so it creates a new CEA-708 track for accessibility tags with schemeIdUri = urn:scte:dash:cc:cea-708:2015
and extract accessibilityChannel and language from value attribute.

Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@jruesga
Copy link
Contributor Author

jruesga commented May 13, 2020

@googlebot I signed it!

@krocard krocard requested a review from ojw28 May 13, 2020 18:58
@krocard krocard removed the request for review from ojw28 May 13, 2020 18:59
@ojw28
Copy link
Contributor

ojw28 commented May 15, 2020

I'm not sure why the CLA check is unhappy. Marking with the cla: yes label based on manual verification.

@ojw28 ojw28 added cla: yes and removed cla: no labels May 15, 2020
@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

ℹ️ Googlers: Go here for more info.

Copy link
Contributor

@ojw28 ojw28 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at the comments. Thanks!

}

private static Format[] getCea608TrackFormats(
private static Format[] getClosedCaptionsTrackFormats(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of the enum through this code is IMO making it quite a bit harder to read than it needs to be. Can't you just do something like (warning, untested):


  private static Format[] getClosedCaptionTrackFormats(
      List<AdaptationSet> adaptationSets, int[] adaptationSetIndices) {
    for (int i : adaptationSetIndices) {
      AdaptationSet adaptationSet = adaptationSets.get(i);
      List<Descriptor> descriptors = adaptationSets.get(i).accessibilityDescriptors;
      for (int j = 0; j < descriptors.size(); j++) {
        Descriptor descriptor = descriptors.get(j);
        if ("urn:scte:dash:cc:cea-608:2015".equals(descriptor.schemeIdUri)) {
          Format cea608Format =
              new Format.Builder()
                  .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                  .setId(adaptationSet.id + ":cea608")
                  .build();
          return parseClosedCaptionDescriptor(
              descriptor, CEA608_SERVICE_DESCRIPTOR_REGEX, cea608Format);
        } else if ("urn:scte:dash:cc:cea-708:2015".equals(descriptor.schemeIdUri)) {
          Format cea708Format =
              new Format.Builder()
                  .setSampleMimeType(MimeTypes.APPLICATION_CEA708)
                  .setId(adaptationSet.id + ":cea708")
                  .build();
          return parseClosedCaptionDescriptor(
              descriptor, CEA708_SERVICE_DESCRIPTOR_REGEX, cea708Format);
        }
      }
    }
    return new Format[0];
  }

  private static Format[] parseClosedCaptionDescriptor(
      Descriptor descriptor, Pattern serviceDescriptorRegex, Format baseFormat) {
    @Nullable String value = descriptor.value;
    if (value == null) {
      // There are embedded closed caption tracks, but service information is not declared.
      return new Format[] {baseFormat};
    }
    String[] services = Util.split(value, ";");
    Format[] formats = new Format[services.length];
    for (int i = 0; i < services.length; i++) {
      Matcher matcher = serviceDescriptorRegex.matcher(services[i]);
      if (!matcher.matches()) {
        // If we can't parse service information for all services, assume a single track.
        return new Format[] {baseFormat};
      }
      int accessibilityChannel = Integer.parseInt(matcher.group(1));
      formats[i] =
          baseFormat
              .buildUpon()
              .setId(baseFormat.id + ":" + accessibilityChannel)
              .setAccessibilityChannel(accessibilityChannel)
              .setLanguage(matcher.group(2))
              .build();
    }
    return formats;
  }

and get rid of the enum and all the little helper methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return formats;
}
for (Descriptor descriptor : descriptors) {
return parseClosedCaptionsDescriptor(adaptationSet.id, descriptor);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be irrelevant if you can go with my proposal above, but this shouldn't return if parsedClosedCaptionsDescriptor returned null. Else parsing will fail if there's a descriptor for something other than 608/708 before the descriptor you're looking for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
@googlebot

This comment has been minimized.

andrewlewis pushed a commit that referenced this pull request May 18, 2020
This is the rename-only part of #7370

PiperOrigin-RevId: 312057896
ojw28 added a commit that referenced this pull request May 18, 2020
@ojw28
Copy link
Contributor

ojw28 commented May 18, 2020

I'm not sure why it's not been picked up, but this was merged in 3db703a. Thanks!

@ojw28 ojw28 closed this May 18, 2020
@google google locked and limited conversation to collaborators Jul 18, 2020
@jruesga jruesga deleted the embedded-cea-708-support branch July 3, 2021 23:18
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants