Make Cea608Parser and Cea708Parser package-private

It's likely that we will merge these back into their `XXXDecoder`
implementations, but this smaller change allows us to avoid including
these public symbols in the upcoming release.

#minor-release

PiperOrigin-RevId: 601432629
This commit is contained in:
ibaker 2024-01-25 06:40:59 -08:00 committed by Copybara-Service
parent f9eb8626eb
commit 12157a6b1a
7 changed files with 52 additions and 46 deletions

View File

@ -23,9 +23,7 @@ import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
import androidx.media3.extractor.text.SubtitleDecoder;
import androidx.media3.extractor.text.SubtitleParser;
import androidx.media3.extractor.text.cea.Cea608Decoder;
import androidx.media3.extractor.text.cea.Cea608Parser;
import androidx.media3.extractor.text.cea.Cea708Decoder;
import androidx.media3.extractor.text.cea.Cea708Parser;
import java.util.Objects;
/** A factory for {@link SubtitleDecoder} instances. */
@ -82,13 +80,11 @@ public interface SubtitleDecoderFactory {
case MimeTypes.APPLICATION_CEA608:
case MimeTypes.APPLICATION_MP4CEA608:
return new Cea608Decoder(
new Cea608Parser(
mimeType,
format.accessibilityChannel,
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
mimeType,
format.accessibilityChannel,
Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS);
case MimeTypes.APPLICATION_CEA708:
return new Cea708Decoder(
new Cea708Parser(format.accessibilityChannel, format.initializationData));
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
default:
break;
}

View File

@ -36,6 +36,12 @@ import java.nio.ByteBuffer;
@UnstableApi
public final class Cea608Decoder extends CeaDecoder {
/**
* The minimum value for the {@code validDataChannelTimeoutMs} constructor parameter permitted by
* ANSI/CTA-608-E R-2014 Annex C.9.
*/
public static final long MIN_DATA_CHANNEL_TIMEOUT_MS = Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS;
private static final CuesWithTiming EMPTY_CUES =
new CuesWithTiming(
ImmutableList.of(), /* startTimeUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET);
@ -49,10 +55,15 @@ public final class Cea608Decoder extends CeaDecoder {
/**
* Constructs an instance.
*
* @param parser A {@link Cea608Parser} to parse the subtitle data.
* @param mimeType The MIME type of the CEA-608 data.
* @param accessibilityChannel The Accessibility channel, or {@link Format#NO_VALUE} if unknown.
* @param validDataChannelTimeoutMs The timeout (in milliseconds) permitted by ANSI/CTA-608-E
* R-2014 Annex C.9 to clear "stuck" captions where no removal control code is received. The
* timeout should be at least {@link #MIN_DATA_CHANNEL_TIMEOUT_MS} or {@link C#TIME_UNSET} for
* no timeout. This applies an upper-bound on the duration of a single caption.
*/
public Cea608Decoder(Cea608Parser parser) {
this.cea608Parser = parser;
public Cea608Decoder(String mimeType, int accessibilityChannel, long validDataChannelTimeoutMs) {
this.cea608Parser = new Cea608Parser(mimeType, accessibilityChannel, validDataChannelTimeoutMs);
lastCueUpdateUs = C.TIME_UNSET;
}

View File

@ -51,7 +51,7 @@ import java.util.List;
// format must happen during rendering), or re-add it to DefaultSubtitleParserFactory (if we're
// able to solve the re-ordering issue during extraction).
@UnstableApi
public final class Cea608Parser implements SubtitleParser {
/* package */ final class Cea608Parser implements SubtitleParser {
/**
* The {@link CueReplacementBehavior} for consecutive {@link CuesWithTiming} emitted by this

View File

@ -19,6 +19,8 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.util.CodecSpecificDataUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.extractor.text.CuesWithTiming;
import androidx.media3.extractor.text.CuesWithTimingSubtitle;
@ -28,6 +30,7 @@ import androidx.media3.extractor.text.SubtitleInputBuffer;
import androidx.media3.extractor.text.SubtitleParser.OutputOptions;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
import java.util.List;
/** A {@link SubtitleDecoder} for CEA-708 (also known as "EIA-708"). */
@UnstableApi
@ -40,10 +43,13 @@ public final class Cea708Decoder extends CeaDecoder {
/**
* Constructs an instance.
*
* @param parser A {@link Cea708Parser} to parse the subtitle data.
* @param accessibilityChannel The accessibility channel, or {@link Format#NO_VALUE} if unknown.
* @param initializationData Optional initialization data for the decoder. If present, it must
* conform to the structure created by {@link
* CodecSpecificDataUtil#buildCea708InitializationData}.
*/
public Cea708Decoder(Cea708Parser parser) {
this.cea708Parser = parser;
public Cea708Decoder(int accessibilityChannel, @Nullable List<byte[]> initializationData) {
this.cea708Parser = new Cea708Parser(accessibilityChannel, initializationData);
}
@Override

View File

@ -52,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
// format must happen during rendering), or re-add it to DefaultSubtitleParserFactory (if we're
// able to solve the re-ordering issue during extraction).
@UnstableApi
public final class Cea708Parser implements SubtitleParser {
/* package */ final class Cea708Parser implements SubtitleParser {
/**
* The {@link CueReplacementBehavior} for consecutive {@link CuesWithTiming} emitted by this

View File

@ -45,10 +45,9 @@ public class Cea608DecoderTest {
public void paintOnEmitsSubtitlesImmediately() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1,
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1,
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
byte[] sample1 =
Bytes.concat(
// 'paint on' control character
@ -85,10 +84,9 @@ public class Cea608DecoderTest {
public void paintOnEmitsSubtitlesImmediately_reordersOutOfOrderSamples() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1,
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1,
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
byte[] sample1 =
Bytes.concat(
// 'paint on' control character
@ -127,10 +125,9 @@ public class Cea608DecoderTest {
public void rollUpEmitsSubtitlesImmediately() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
byte[] sample1 =
Bytes.concat(
// 'roll up 2 rows' control character
@ -182,10 +179,9 @@ public class Cea608DecoderTest {
public void onlySelectedFieldIsUsed() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
// field 1 (0xFC header): 'test subtitle'
// field 2 (0xFD header): 'wrong field!'
byte[] sample1 =
@ -223,10 +219,9 @@ public class Cea608DecoderTest {
public void onlySelectedChannelIsUsed() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 2, // field 1, channel 2
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 2, // field 1, channel 2
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
// field 1 (0xFC header), channel 1: 'wrong channel'
// field 1 (0xFC header), channel 2: 'test subtitle'
// field 2 (0xFD header), channel 1: 'wrong field!'
@ -317,10 +312,9 @@ public class Cea608DecoderTest {
public void serviceSwitchOnField1Handled() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 1, // field 1, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
// field 1 (0xFC header): 'test' then service switch
// field 2 (0xFD header): 'wrong!'
byte[] sample1 =
@ -349,10 +343,9 @@ public class Cea608DecoderTest {
public void serviceSwitchOnField2Handled() throws Exception {
Cea608Decoder decoder =
new Cea608Decoder(
new Cea608Parser(
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 3, // field 2, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
MimeTypes.APPLICATION_CEA608,
/* accessibilityChannel= */ 3, // field 2, channel 1
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
// field 1 (0xFC header): 'wrong!'
// field 2 (0xFD header): 'test' then service switch
byte[] sample1 =

View File

@ -60,8 +60,8 @@ public class Cea708DecoderTest {
public void singleServiceAndWindowDefinition() throws Exception {
Cea708Decoder cea708Decoder =
new Cea708Decoder(
new Cea708Parser(
/* accessibilityChannel= */ Format.NO_VALUE, /* initializationData= */ null));
/* accessibilityChannel= */ Format.NO_VALUE, /* initializationData= */ null);
byte[] windowDefinition =
TestUtil.createByteArray(
0x98, // DF0 command (define window 0)