mirror of
https://github.com/androidx/media.git
synced 2025-05-12 01:59:50 +08:00
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 (cherry picked from commit 12157a6b1aba2c59c54e6b7d34bad396008b5f29)
This commit is contained in:
parent
e29e775732
commit
4382aa0b34
@ -23,9 +23,7 @@ import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
|
|||||||
import androidx.media3.extractor.text.SubtitleDecoder;
|
import androidx.media3.extractor.text.SubtitleDecoder;
|
||||||
import androidx.media3.extractor.text.SubtitleParser;
|
import androidx.media3.extractor.text.SubtitleParser;
|
||||||
import androidx.media3.extractor.text.cea.Cea608Decoder;
|
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.Cea708Decoder;
|
||||||
import androidx.media3.extractor.text.cea.Cea708Parser;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** A factory for {@link SubtitleDecoder} instances. */
|
/** A factory for {@link SubtitleDecoder} instances. */
|
||||||
@ -82,13 +80,11 @@ public interface SubtitleDecoderFactory {
|
|||||||
case MimeTypes.APPLICATION_CEA608:
|
case MimeTypes.APPLICATION_CEA608:
|
||||||
case MimeTypes.APPLICATION_MP4CEA608:
|
case MimeTypes.APPLICATION_MP4CEA608:
|
||||||
return new Cea608Decoder(
|
return new Cea608Decoder(
|
||||||
new Cea608Parser(
|
mimeType,
|
||||||
mimeType,
|
format.accessibilityChannel,
|
||||||
format.accessibilityChannel,
|
Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
case MimeTypes.APPLICATION_CEA708:
|
case MimeTypes.APPLICATION_CEA708:
|
||||||
return new Cea708Decoder(
|
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
|
||||||
new Cea708Parser(format.accessibilityChannel, format.initializationData));
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,12 @@ import java.nio.ByteBuffer;
|
|||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class Cea608Decoder extends CeaDecoder {
|
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 =
|
private static final CuesWithTiming EMPTY_CUES =
|
||||||
new CuesWithTiming(
|
new CuesWithTiming(
|
||||||
ImmutableList.of(), /* startTimeUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET);
|
ImmutableList.of(), /* startTimeUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET);
|
||||||
@ -49,10 +55,15 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance.
|
* 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) {
|
public Cea608Decoder(String mimeType, int accessibilityChannel, long validDataChannelTimeoutMs) {
|
||||||
this.cea608Parser = parser;
|
this.cea608Parser = new Cea608Parser(mimeType, accessibilityChannel, validDataChannelTimeoutMs);
|
||||||
lastCueUpdateUs = C.TIME_UNSET;
|
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
|
// format must happen during rendering), or re-add it to DefaultSubtitleParserFactory (if we're
|
||||||
// able to solve the re-ordering issue during extraction).
|
// able to solve the re-ordering issue during extraction).
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class Cea608Parser implements SubtitleParser {
|
/* package */ final class Cea608Parser implements SubtitleParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CueReplacementBehavior} for consecutive {@link CuesWithTiming} emitted by this
|
* 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.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
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.common.util.UnstableApi;
|
||||||
import androidx.media3.extractor.text.CuesWithTiming;
|
import androidx.media3.extractor.text.CuesWithTiming;
|
||||||
import androidx.media3.extractor.text.CuesWithTimingSubtitle;
|
import androidx.media3.extractor.text.CuesWithTimingSubtitle;
|
||||||
@ -28,6 +30,7 @@ import androidx.media3.extractor.text.SubtitleInputBuffer;
|
|||||||
import androidx.media3.extractor.text.SubtitleParser.OutputOptions;
|
import androidx.media3.extractor.text.SubtitleParser.OutputOptions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** A {@link SubtitleDecoder} for CEA-708 (also known as "EIA-708"). */
|
/** A {@link SubtitleDecoder} for CEA-708 (also known as "EIA-708"). */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -40,10 +43,13 @@ public final class Cea708Decoder extends CeaDecoder {
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance.
|
* 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) {
|
public Cea708Decoder(int accessibilityChannel, @Nullable List<byte[]> initializationData) {
|
||||||
this.cea708Parser = parser;
|
this.cea708Parser = new Cea708Parser(accessibilityChannel, initializationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// format must happen during rendering), or re-add it to DefaultSubtitleParserFactory (if we're
|
||||||
// able to solve the re-ordering issue during extraction).
|
// able to solve the re-ordering issue during extraction).
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class Cea708Parser implements SubtitleParser {
|
/* package */ final class Cea708Parser implements SubtitleParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CueReplacementBehavior} for consecutive {@link CuesWithTiming} emitted by this
|
* The {@link CueReplacementBehavior} for consecutive {@link CuesWithTiming} emitted by this
|
||||||
|
@ -45,10 +45,9 @@ public class Cea608DecoderTest {
|
|||||||
public void paintOnEmitsSubtitlesImmediately() throws Exception {
|
public void paintOnEmitsSubtitlesImmediately() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 1,
|
||||||
/* accessibilityChannel= */ 1,
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
Bytes.concat(
|
Bytes.concat(
|
||||||
// 'paint on' control character
|
// 'paint on' control character
|
||||||
@ -85,10 +84,9 @@ public class Cea608DecoderTest {
|
|||||||
public void paintOnEmitsSubtitlesImmediately_reordersOutOfOrderSamples() throws Exception {
|
public void paintOnEmitsSubtitlesImmediately_reordersOutOfOrderSamples() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 1,
|
||||||
/* accessibilityChannel= */ 1,
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
Bytes.concat(
|
Bytes.concat(
|
||||||
// 'paint on' control character
|
// 'paint on' control character
|
||||||
@ -127,10 +125,9 @@ public class Cea608DecoderTest {
|
|||||||
public void rollUpEmitsSubtitlesImmediately() throws Exception {
|
public void rollUpEmitsSubtitlesImmediately() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 1, // field 1, channel 1
|
||||||
/* accessibilityChannel= */ 1, // field 1, channel 1
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
Bytes.concat(
|
Bytes.concat(
|
||||||
// 'roll up 2 rows' control character
|
// 'roll up 2 rows' control character
|
||||||
@ -182,10 +179,9 @@ public class Cea608DecoderTest {
|
|||||||
public void onlySelectedFieldIsUsed() throws Exception {
|
public void onlySelectedFieldIsUsed() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 1, // field 1, channel 1
|
||||||
/* accessibilityChannel= */ 1, // field 1, channel 1
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
// field 1 (0xFC header): 'test subtitle'
|
// field 1 (0xFC header): 'test subtitle'
|
||||||
// field 2 (0xFD header): 'wrong field!'
|
// field 2 (0xFD header): 'wrong field!'
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
@ -223,10 +219,9 @@ public class Cea608DecoderTest {
|
|||||||
public void onlySelectedChannelIsUsed() throws Exception {
|
public void onlySelectedChannelIsUsed() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 2, // field 1, channel 2
|
||||||
/* accessibilityChannel= */ 2, // field 1, channel 2
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
// field 1 (0xFC header), channel 1: 'wrong channel'
|
// field 1 (0xFC header), channel 1: 'wrong channel'
|
||||||
// field 1 (0xFC header), channel 2: 'test subtitle'
|
// field 1 (0xFC header), channel 2: 'test subtitle'
|
||||||
// field 2 (0xFD header), channel 1: 'wrong field!'
|
// field 2 (0xFD header), channel 1: 'wrong field!'
|
||||||
@ -317,10 +312,9 @@ public class Cea608DecoderTest {
|
|||||||
public void serviceSwitchOnField1Handled() throws Exception {
|
public void serviceSwitchOnField1Handled() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 1, // field 1, channel 1
|
||||||
/* accessibilityChannel= */ 1, // field 1, channel 1
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
// field 1 (0xFC header): 'test' then service switch
|
// field 1 (0xFC header): 'test' then service switch
|
||||||
// field 2 (0xFD header): 'wrong!'
|
// field 2 (0xFD header): 'wrong!'
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
@ -349,10 +343,9 @@ public class Cea608DecoderTest {
|
|||||||
public void serviceSwitchOnField2Handled() throws Exception {
|
public void serviceSwitchOnField2Handled() throws Exception {
|
||||||
Cea608Decoder decoder =
|
Cea608Decoder decoder =
|
||||||
new Cea608Decoder(
|
new Cea608Decoder(
|
||||||
new Cea608Parser(
|
MimeTypes.APPLICATION_CEA608,
|
||||||
MimeTypes.APPLICATION_CEA608,
|
/* accessibilityChannel= */ 3, // field 2, channel 1
|
||||||
/* accessibilityChannel= */ 3, // field 2, channel 1
|
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS);
|
||||||
Cea608Parser.MIN_DATA_CHANNEL_TIMEOUT_MS));
|
|
||||||
// field 1 (0xFC header): 'wrong!'
|
// field 1 (0xFC header): 'wrong!'
|
||||||
// field 2 (0xFD header): 'test' then service switch
|
// field 2 (0xFD header): 'test' then service switch
|
||||||
byte[] sample1 =
|
byte[] sample1 =
|
||||||
|
@ -60,8 +60,8 @@ public class Cea708DecoderTest {
|
|||||||
public void singleServiceAndWindowDefinition() throws Exception {
|
public void singleServiceAndWindowDefinition() throws Exception {
|
||||||
Cea708Decoder cea708Decoder =
|
Cea708Decoder cea708Decoder =
|
||||||
new Cea708Decoder(
|
new Cea708Decoder(
|
||||||
new Cea708Parser(
|
|
||||||
/* accessibilityChannel= */ Format.NO_VALUE, /* initializationData= */ null));
|
/* accessibilityChannel= */ Format.NO_VALUE, /* initializationData= */ null);
|
||||||
byte[] windowDefinition =
|
byte[] windowDefinition =
|
||||||
TestUtil.createByteArray(
|
TestUtil.createByteArray(
|
||||||
0x98, // DF0 command (define window 0)
|
0x98, // DF0 command (define window 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user