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:
parent
f9eb8626eb
commit
12157a6b1a
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user