mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
[AitDecoder] Move to ParsableBitArray
This commit is contained in:
parent
28c5043dc1
commit
98de7c460b
@ -3,16 +3,20 @@ package com.google.android.exoplayer2.metadata.dvbsi;
|
|||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
import com.google.android.exoplayer2.metadata.MetadataDecoder;
|
import com.google.android.exoplayer2.metadata.MetadataDecoder;
|
||||||
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
|
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
|
||||||
|
import com.google.android.exoplayer2.util.ParsableBitArray;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
// Unless mentioned explicitly, every references here are to
|
||||||
|
// https://www.etsi.org/deliver/etsi_ts/102800_102899/102809/01.01.01_60/ts_102809v010101p.pdf
|
||||||
public class AitDecoder implements MetadataDecoder {
|
public class AitDecoder implements MetadataDecoder {
|
||||||
// Specification of AIT can be found in 5.3.4 of TS 102 809 v1.1.1
|
// Specification of AIT can be found in 5.3.4 of TS 102 809 v1.1.1
|
||||||
// https://www.etsi.org/deliver/etsi_ts/102800_102899/102809/01.01.01_60/ts_102809v010101p.pdf
|
|
||||||
private final static int DESCRIPTOR_TRANSPORT_PROTOCOL = 0x02;
|
private final static int DESCRIPTOR_TRANSPORT_PROTOCOL = 0x02;
|
||||||
|
|
||||||
private final static int DESCRIPTOR_SIMPLE_APPLICATION_LOCATION = 0x15;
|
private final static int DESCRIPTOR_SIMPLE_APPLICATION_LOCATION = 0x15;
|
||||||
@ -21,10 +25,10 @@ public class AitDecoder implements MetadataDecoder {
|
|||||||
|
|
||||||
private TimestampAdjuster timestampAdjuster;
|
private TimestampAdjuster timestampAdjuster;
|
||||||
|
|
||||||
private final ParsableByteArray sectionData;
|
private final ParsableBitArray sectionData;
|
||||||
|
|
||||||
public AitDecoder() {
|
public AitDecoder() {
|
||||||
sectionData = new ParsableByteArray();
|
sectionData = new ParsableBitArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,8 +44,7 @@ public class AitDecoder implements MetadataDecoder {
|
|||||||
int size = buffer.limit();
|
int size = buffer.limit();
|
||||||
sectionData.reset(data, size);
|
sectionData.reset(data, size);
|
||||||
|
|
||||||
int tableId = sectionData.peekUnsignedByte();
|
int tableId = sectionData.data[0];
|
||||||
|
|
||||||
//Only this table is allowed in AIT streams
|
//Only this table is allowed in AIT streams
|
||||||
if (tableId == 0x74) {
|
if (tableId == 0x74) {
|
||||||
return parseAit(sectionData);
|
return parseAit(sectionData);
|
||||||
@ -50,80 +53,92 @@ public class AitDecoder implements MetadataDecoder {
|
|||||||
return new Metadata();
|
return new Metadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Metadata parseAit(ParsableByteArray sectionData) {
|
private Metadata parseAit(ParsableBitArray sectionData) {
|
||||||
int tmp;
|
//tableId
|
||||||
|
sectionData.skipBits(8);
|
||||||
|
|
||||||
int tableId = sectionData.readUnsignedByte();
|
//section_syntax_indication | reserved_future_use | reserved
|
||||||
|
sectionData.skipBits(4);
|
||||||
|
int sectionLength = sectionData.readBits(12);
|
||||||
|
int endOfSection = sectionData.getBytePosition() + sectionLength - 4 /* Ignore leading CRC */;
|
||||||
|
|
||||||
tmp = sectionData.readUnsignedShort();
|
// test_application_flag | application_type
|
||||||
int endOfSection = sectionData.getPosition() + (tmp & 4095) - 4 /* Ignore leading CRC */;
|
sectionData.skipBits(16);
|
||||||
|
|
||||||
tmp = sectionData.readUnsignedShort();
|
// reserved | version_number | current_next_indicator
|
||||||
int applicationType = tmp & 0x7fff;
|
sectionData.skipBits(8);
|
||||||
|
|
||||||
tmp = sectionData.readUnsignedByte();
|
// section_number
|
||||||
int versionNumber = (tmp & 0x3e) >> 1;
|
sectionData.skipBits(8);
|
||||||
boolean current = (tmp & 1) == 1;
|
// last_section_number
|
||||||
|
sectionData.skipBits(8);
|
||||||
|
|
||||||
int section_number = sectionData.readUnsignedByte();
|
// reserved_future_use
|
||||||
int last_section_number = sectionData.readUnsignedByte();
|
sectionData.skipBits(4);
|
||||||
|
int commonDescriptorsLength = sectionData.readBits(12);
|
||||||
tmp = sectionData.readUnsignedShort();
|
|
||||||
int commonDescriptorsLength = tmp & 4095;
|
|
||||||
|
|
||||||
//Since we currently only keep url and control code, which are unique per application,
|
//Since we currently only keep url and control code, which are unique per application,
|
||||||
//there is no useful information in common descriptor.
|
//there is no useful information in common descriptor.
|
||||||
sectionData.skipBytes(commonDescriptorsLength);
|
sectionData.skipBytes(commonDescriptorsLength);
|
||||||
|
|
||||||
tmp = sectionData.readUnsignedShort();
|
// reserved_future_use | application_loop_length
|
||||||
int appLoopLength = tmp & 4095;
|
sectionData.skipBits(16);
|
||||||
|
|
||||||
ArrayList<Ait> aits = new ArrayList<>();
|
ArrayList<Ait> aits = new ArrayList<>();
|
||||||
while(sectionData.getPosition() < endOfSection) {
|
while(sectionData.getBytePosition() < endOfSection) {
|
||||||
// Values that will be stored in Ait()
|
// Values that will be stored in Ait()
|
||||||
String aitUrlBase = null;
|
String aitUrlBase = null;
|
||||||
String aitUrlExtension = null;
|
String aitUrlExtension = null;
|
||||||
int aitControlCode = -1;
|
int aitControlCode = -1;
|
||||||
|
|
||||||
long application_identifier = sectionData.readUnsignedInt24() << 24L;
|
// application_identifier
|
||||||
application_identifier |= sectionData.readUnsignedInt24();
|
sectionData.skipBits(48);
|
||||||
int controlCode = sectionData.readUnsignedByte();
|
int controlCode = sectionData.readBits(8);
|
||||||
|
|
||||||
aitControlCode = controlCode;
|
aitControlCode = controlCode;
|
||||||
|
|
||||||
tmp = sectionData.readUnsignedShort();
|
// reserved_future_use
|
||||||
int sectionLength = tmp & 4095;
|
sectionData.skipBits(4);
|
||||||
int positionOfNextSection = sectionData.getPosition() + sectionLength;
|
|
||||||
while(sectionData.getPosition() < positionOfNextSection) {
|
int applicationDescriptorsLoopLength = sectionData.readBits(12);
|
||||||
int type = sectionData.readUnsignedByte();
|
int positionOfNextSection = sectionData.getBytePosition() + applicationDescriptorsLoopLength;
|
||||||
int l = sectionData.readUnsignedByte();
|
while(sectionData.getBytePosition() < positionOfNextSection) {
|
||||||
int positionOfNextSection2 = sectionData.getPosition() + l;
|
int type = sectionData.readBits(8);
|
||||||
|
int l = sectionData.readBits(8);
|
||||||
|
int positionOfNextSection2 = sectionData.getBytePosition() + l;
|
||||||
|
|
||||||
if(type == DESCRIPTOR_TRANSPORT_PROTOCOL) {
|
if(type == DESCRIPTOR_TRANSPORT_PROTOCOL) {
|
||||||
int protocolId = sectionData.readUnsignedShort();
|
// See section 5.3.6
|
||||||
int label = sectionData.readUnsignedByte();
|
int protocolId = sectionData.readBits(16);
|
||||||
|
// label
|
||||||
|
sectionData.skipBits(8);
|
||||||
|
|
||||||
if(protocolId == TRANSPORT_PROTOCOL_HTTP) {
|
if(protocolId == TRANSPORT_PROTOCOL_HTTP) {
|
||||||
while (sectionData.getPosition() < positionOfNextSection2) {
|
while (sectionData.getBytePosition() < positionOfNextSection2) {
|
||||||
int urlBaseLength = sectionData.readUnsignedByte();
|
int urlBaseLength = sectionData.readBits(8);
|
||||||
String urlBase = sectionData.readString(urlBaseLength);
|
byte[] urlBaseByteArray = new byte[urlBaseLength];
|
||||||
int extensionCount = sectionData.readUnsignedByte();
|
sectionData.readBytes(urlBaseByteArray, 0, urlBaseLength);
|
||||||
|
String urlBase = new String(urlBaseByteArray, Charset.forName("ASCII"));
|
||||||
|
|
||||||
|
int extensionCount = sectionData.readBits(8);
|
||||||
aitUrlBase = urlBase;
|
aitUrlBase = urlBase;
|
||||||
for (int i = 0; i < extensionCount; i++) {
|
for (int i = 0; i < extensionCount; i++) {
|
||||||
int len = sectionData.readUnsignedByte();
|
int len = sectionData.readBits(8);
|
||||||
sectionData.skipBytes(len);
|
sectionData.skipBytes(len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(type == DESCRIPTOR_SIMPLE_APPLICATION_LOCATION) {
|
} else if(type == DESCRIPTOR_SIMPLE_APPLICATION_LOCATION) {
|
||||||
String url = sectionData.readString(l);
|
byte[] urlByteArray = new byte[l];
|
||||||
|
sectionData.readBytes(urlByteArray, 0, l);
|
||||||
|
String url = new String(urlByteArray, Charset.forName("ASCII"));
|
||||||
aitUrlExtension = url;
|
aitUrlExtension = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionData.setPosition(positionOfNextSection2);
|
sectionData.setPosition(positionOfNextSection2*8);
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionData.setPosition(positionOfNextSection);
|
sectionData.setPosition(positionOfNextSection*8);
|
||||||
|
|
||||||
if(aitControlCode != -1 && aitUrlBase != null && aitUrlExtension != null) {
|
if(aitControlCode != -1 && aitUrlBase != null && aitUrlExtension != null) {
|
||||||
aits.add(new Ait(aitControlCode, aitUrlBase + aitUrlExtension));
|
aits.add(new Ait(aitControlCode, aitUrlBase + aitUrlExtension));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user