mirror of
https://github.com/samsonjs/media.git
synced 2026-03-25 09:25:53 +00:00
More changes based on internal review
This commit is contained in:
parent
71db918f91
commit
4822033a6c
3 changed files with 69 additions and 64 deletions
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package androidx.media3.extractor;
|
||||
|
||||
import static com.google.common.primitives.Ints.checkedCast;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
|
@ -24,6 +23,7 @@ import androidx.media3.common.C;
|
|||
import androidx.media3.common.ParserException;
|
||||
import androidx.media3.common.util.ParsableBitArray;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
|
@ -50,14 +50,15 @@ public final class MpeghUtil {
|
|||
* Parses an MHAS packet header. See ISO_IEC_23008-3;2022, 14.2.1, Table 222. The reading position
|
||||
* of {@code data} will be modified.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the MHAS packet header.
|
||||
* @param data The data to parse, positioned at the start of the MHAS packet header. Must be
|
||||
* byte-aligned.
|
||||
* @return The {@link MhasPacketHeader} info.
|
||||
* @throws ParserException if a valid {@link MhasPacketHeader} cannot be parsed.
|
||||
*/
|
||||
public static MhasPacketHeader parseMhasPacketHeader(ParsableBitArray data)
|
||||
throws ParserException {
|
||||
int dataStartPos = data.getPosition();
|
||||
@MhasPacketHeader.Type int packetType = checkedCast(readEscapedValue(data, 3, 8, 8));
|
||||
int dataStartPos = data.getBytePosition();
|
||||
@MhasPacketHeader.Type int packetType = Ints.checkedCast(readEscapedValue(data, 3, 8, 8));
|
||||
long packetLabel = readEscapedValue(data, 2, 8, 32);
|
||||
|
||||
if (packetLabel > 0x10) {
|
||||
|
|
@ -81,9 +82,9 @@ public final class MpeghUtil {
|
|||
}
|
||||
}
|
||||
|
||||
int packetLength = checkedCast(readEscapedValue(data, 11, 24, 24));
|
||||
int packetLength = Ints.checkedCast(readEscapedValue(data, 11, 24, 24));
|
||||
|
||||
int headerLength = (data.getPosition() - dataStartPos) / C.BITS_PER_BYTE;
|
||||
int headerLength = data.getBytePosition() - dataStartPos;
|
||||
|
||||
return new MhasPacketHeader(packetType, packetLabel, packetLength, headerLength);
|
||||
}
|
||||
|
|
@ -170,37 +171,13 @@ public final class MpeghUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains an escaped value from an MPEG-H bit stream. See ISO_IEC_23003-3;2020, 5.2, Table 19.
|
||||
* The reading position of {@code data} will be modified.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the escaped value.
|
||||
* @param bits1 number of bits to be parsed.
|
||||
* @param bits2 number of bits to be parsed.
|
||||
* @param bits3 number of bits to be parsed.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static long readEscapedValue(ParsableBitArray data, int bits1, int bits2, int bits3) {
|
||||
long value = data.readBitsToLong(bits1);
|
||||
|
||||
if (value == (1L << bits1) - 1) {
|
||||
long valueAdd = data.readBitsToLong(bits2);
|
||||
value += valueAdd;
|
||||
|
||||
if (valueAdd == (1L << bits2) - 1) {
|
||||
valueAdd = data.readBitsToLong(bits3);
|
||||
value += valueAdd;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the necessary info of the Mpegh3daConfig from an MPEG-H bit stream. See
|
||||
* ISO_IEC_23008-3;2022, 5.2.2.1, Table 15. The reading position of {@code data} will be modified.
|
||||
* ISO_IEC_23008-3;2022, 5.2.2.1, Table 15. The reading position of {@code data} will be modified
|
||||
* to be just after the end of the payload of an Mpegh3daConfig packet.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the payload of an Mpegh3daConfig
|
||||
* packet.
|
||||
* packet. Must be byte-aligned.
|
||||
* @return The {@link Mpegh3daConfig}.
|
||||
* @throws ParserException if a valid {@link Mpegh3daConfig} cannot be parsed.
|
||||
*/
|
||||
|
|
@ -228,12 +205,12 @@ public final class MpeghUtil {
|
|||
|
||||
if (data.readBit()) { // usacConfigExtensionPresent
|
||||
// Mpegh3daConfigExtension
|
||||
int numConfigExtensions = checkedCast(readEscapedValue(data, 2, 4, 8) + 1);
|
||||
int numConfigExtensions = Ints.checkedCast(readEscapedValue(data, 2, 4, 8) + 1);
|
||||
for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
|
||||
int usacConfigExtType = checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
int usacConfigExtLength = checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
int usacConfigExtType = Ints.checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
int usacConfigExtLength = Ints.checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
|
||||
if (usacConfigExtType == 7 /*ID_CONFIG_EXT_COMPATIBLE_PROFILELVL_SET*/) {
|
||||
if (usacConfigExtType == 7 /* ID_CONFIG_EXT_COMPATIBLE_PROFILELVL_SET */) {
|
||||
int numCompatibleSets = data.readBits(4) + 1;
|
||||
data.skipBits(4); // reserved
|
||||
compatibleProfileLevelSet = new byte[numCompatibleSets];
|
||||
|
|
@ -343,7 +320,8 @@ public final class MpeghUtil {
|
|||
|
||||
/**
|
||||
* Skips the SpeakerConfig3d from an MPEG-H bit stream. See ISO_IEC_23008-3;2022, 5.2.2.2, Table
|
||||
* 18. The reading position of {@code data} will be modified.
|
||||
* 18. The reading position of {@code data} will be modified to be just after the end of the
|
||||
* SpeakerConfig3d field.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the SpeakerConfig3d field.
|
||||
*/
|
||||
|
|
@ -354,7 +332,7 @@ public final class MpeghUtil {
|
|||
return;
|
||||
}
|
||||
|
||||
int numberOfSpeakers = checkedCast(readEscapedValue(data, 5, 8, 16) + 1);
|
||||
int numberOfSpeakers = Ints.checkedCast(readEscapedValue(data, 5, 8, 16) + 1);
|
||||
if (speakerLayoutType == 1) {
|
||||
data.skipBits(7 * numberOfSpeakers); // cicpSpeakerIdx per speaker
|
||||
} else if (speakerLayoutType == 2) {
|
||||
|
|
@ -364,7 +342,8 @@ public final class MpeghUtil {
|
|||
|
||||
/**
|
||||
* Skips the mpegh3daFlexibleSpeakerConfig from an MPEG-H bit stream. See ISO_IEC_23008-3;2022,
|
||||
* 5.2.2.2, Table 19. The reading position of {@code data} will be modified.
|
||||
* 5.2.2.2, Table 19. The reading position of {@code data} will be modified to be just after the
|
||||
* end of the Mpegh3daFlexibleSpeakerConfig field.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the Mpegh3daFlexibleSpeakerConfig
|
||||
* field.
|
||||
|
|
@ -408,7 +387,8 @@ public final class MpeghUtil {
|
|||
|
||||
/**
|
||||
* Obtains the necessary info of Signals3d from an MPEG-H bit stream. See ISO_IEC_23008-3;2022,
|
||||
* 5.2.2.1, Table 17. The reading position of {@code data} will be modified.
|
||||
* 5.2.2.1, Table 17. The reading position of {@code data} will be modified to be just after the
|
||||
* end of the Signals3d field.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the Signals3d field.
|
||||
* @return The number of overall signals in the bit stream.
|
||||
|
|
@ -419,7 +399,7 @@ public final class MpeghUtil {
|
|||
|
||||
for (int grp = 0; grp < numberOfSignalGroupsInBitstream + 1; grp++) {
|
||||
int signalGroupType = data.readBits(3);
|
||||
int bsNumberOfSignals = checkedCast(readEscapedValue(data, 5, 8, 16));
|
||||
int bsNumberOfSignals = Ints.checkedCast(readEscapedValue(data, 5, 8, 16));
|
||||
|
||||
numberOfSignals += bsNumberOfSignals + 1;
|
||||
if (signalGroupType == 0 /*SignalGroupTypeChannels*/
|
||||
|
|
@ -434,7 +414,8 @@ public final class MpeghUtil {
|
|||
|
||||
/**
|
||||
* Skips the Mpegh3daDecoderConfig from an MPEG-H bit stream. See ISO_IEC_23008-3;2022, 5.2.2.3,
|
||||
* Table 21. The reading position of {@code data} will be modified.
|
||||
* Table 21. The reading position of {@code data} will be modified to be just after the end of the
|
||||
* Mpegh3daDecoderConfig field.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the Mpegh3daDecoderConfig field.
|
||||
* @param numSignals The number of overall signals.
|
||||
|
|
@ -443,7 +424,7 @@ public final class MpeghUtil {
|
|||
private static void skipMpegh3daDecoderConfig(
|
||||
ParsableBitArray data, int numSignals, int sbrRatioIndex) {
|
||||
|
||||
int numElements = checkedCast((readEscapedValue(data, 4, 8, 16) + 1));
|
||||
int numElements = Ints.checkedCast((readEscapedValue(data, 4, 8, 16) + 1));
|
||||
data.skipBit(); // elementLengthPresent
|
||||
|
||||
for (int elemIdx = 0; elemIdx < numElements; elemIdx++) {
|
||||
|
|
@ -498,7 +479,7 @@ public final class MpeghUtil {
|
|||
break;
|
||||
case 3 /*ID_USAC_EXT*/:
|
||||
readEscapedValue(data, 4, 8, 16); // usacExtElementType
|
||||
int usacExtElementConfigLength = checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
int usacExtElementConfigLength = Ints.checkedCast(readEscapedValue(data, 4, 8, 16));
|
||||
|
||||
if (data.readBit()) { // usacExtElementDefaultLengthPresent
|
||||
readEscapedValue(data, 8, 16, 0) /*+1*/; // usacExtElementDefaultLength
|
||||
|
|
@ -517,7 +498,8 @@ public final class MpeghUtil {
|
|||
|
||||
/**
|
||||
* Obtains the necessary info of the Mpegh3daCoreConfig from an MPEG-H bit stream. See
|
||||
* ISO_IEC_23008-3;2022, 5.2.2.3, Table 24. The reading position of {@code data} will be modified.
|
||||
* ISO_IEC_23008-3;2022, 5.2.2.3, Table 24. The reading position of {@code data} will be modified
|
||||
* to be just after the end of the Mpegh3daCoreConfig field.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the Mpegh3daCoreConfig field.
|
||||
* @return The enhanced noise filling flag.
|
||||
|
|
@ -553,6 +535,32 @@ public final class MpeghUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains an escaped value from an MPEG-H bit stream. See ISO_IEC_23003-3;2020, 5.2, Table 19.
|
||||
* The reading position of {@code data} will be modified to be just after the end of the escaped
|
||||
* value.
|
||||
*
|
||||
* @param data The data to parse, positioned at the start of the escaped value.
|
||||
* @param bits1 number of bits to be parsed.
|
||||
* @param bits2 number of bits to be parsed.
|
||||
* @param bits3 number of bits to be parsed.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static long readEscapedValue(ParsableBitArray data, int bits1, int bits2, int bits3) {
|
||||
long value = data.readBitsToLong(bits1);
|
||||
|
||||
if (value == (1L << bits1) - 1) {
|
||||
long valueAdd = data.readBitsToLong(bits2);
|
||||
value += valueAdd;
|
||||
|
||||
if (valueAdd == (1L << bits2) - 1) {
|
||||
valueAdd = data.readBitsToLong(bits3);
|
||||
value += valueAdd;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private MpeghUtil() {}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -170,7 +170,11 @@ public final class MpeghReader implements ElementaryStreamReader {
|
|||
}
|
||||
break;
|
||||
case STATE_READING_PACKET_PAYLOAD:
|
||||
maybeCopyToDataScratchBuffer(data);
|
||||
if (shouldParsePacket(header.packetType)) {
|
||||
// prepare data scratch buffer
|
||||
dataScratchBytes.reset(header.packetLength);
|
||||
copyToDataScratchBuffer(data);
|
||||
}
|
||||
writeSampleData(data);
|
||||
if (payloadBytesRead == header.packetLength) {
|
||||
dataScratchBytes.setPosition(0);
|
||||
|
|
@ -251,18 +255,12 @@ public final class MpeghReader implements ElementaryStreamReader {
|
|||
*/
|
||||
private void parseHeader() throws ParserException {
|
||||
headerScratchBytes.setPosition(0);
|
||||
ParsableBitArray bitArray = new ParsableBitArray(headerScratchBytes.getData());
|
||||
|
||||
// parse the MHAS packet header
|
||||
header = MpeghUtil.parseMhasPacketHeader(bitArray);
|
||||
header = MpeghUtil.parseMhasPacketHeader(new ParsableBitArray(headerScratchBytes.getData()));
|
||||
|
||||
payloadBytesRead = 0;
|
||||
frameBytes += header.packetLength + header.headerLength;
|
||||
|
||||
if (shouldParsePacket(header.packetType)) {
|
||||
// prepare data scratch buffer
|
||||
dataScratchBytes.reset(header.packetLength);
|
||||
}
|
||||
headerDataFinished = true;
|
||||
}
|
||||
|
||||
|
|
@ -288,15 +286,13 @@ public final class MpeghReader implements ElementaryStreamReader {
|
|||
* @param data A {@link ParsableByteArray} from which to read the sample data. Its position will
|
||||
* not be changed.
|
||||
*/
|
||||
private void maybeCopyToDataScratchBuffer(ParsableByteArray data) {
|
||||
if (shouldParsePacket(header.packetType)) {
|
||||
// read bytes from header scratch buffer into the data scratch buffer
|
||||
if (headerScratchBytes.getPosition() != MpeghUtil.MAX_MHAS_PACKET_HEADER_SIZE) {
|
||||
copyData(headerScratchBytes, dataScratchBytes, header.packetLength);
|
||||
}
|
||||
// read bytes from input data into the data scratch buffer
|
||||
copyData(data, dataScratchBytes, header.packetLength);
|
||||
private void copyToDataScratchBuffer(ParsableByteArray data) {
|
||||
// read bytes from the end of the header scratch buffer into the data scratch buffer
|
||||
if (headerScratchBytes.getPosition() != MpeghUtil.MAX_MHAS_PACKET_HEADER_SIZE) {
|
||||
copyData(headerScratchBytes, dataScratchBytes, header.packetLength);
|
||||
}
|
||||
// read bytes from input data into the data scratch buffer
|
||||
copyData(data, dataScratchBytes, header.packetLength);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -336,7 +332,7 @@ public final class MpeghReader implements ElementaryStreamReader {
|
|||
*/
|
||||
private void writeSampleData(ParsableByteArray data) {
|
||||
int bytesToRead;
|
||||
// read bytes from header scratch buffer and write them into the output
|
||||
// read bytes from the end of the header scratch buffer and write them into the output
|
||||
if (headerScratchBytes.getPosition() != MpeghUtil.MAX_MHAS_PACKET_HEADER_SIZE) {
|
||||
bytesToRead = min(headerScratchBytes.bytesLeft(), header.packetLength - payloadBytesRead);
|
||||
output.sampleData(headerScratchBytes, bytesToRead);
|
||||
|
|
@ -352,7 +348,7 @@ public final class MpeghReader implements ElementaryStreamReader {
|
|||
* Parses the config and sets the output format.
|
||||
*
|
||||
* @param bitArray The data to parse, positioned at the start of the {@link
|
||||
* MpeghUtil.Mpegh3daConfig} field.
|
||||
* MpeghUtil.Mpegh3daConfig} field. Must be byte-aligned.
|
||||
* @throws ParserException if a valid {@link MpeghUtil.Mpegh3daConfig} cannot be parsed.
|
||||
*/
|
||||
private void parseConfig(ParsableBitArray bitArray) throws ParserException {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ public final class TsExtractorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
|
||||
public void sampleWithH264() throws Exception {
|
||||
ExtractorAsserts.assertBehavior(
|
||||
getExtractorFactory(subtitlesParsedDuringExtraction),
|
||||
|
|
|
|||
Loading…
Reference in a new issue