Merge pull request #6797 from DolbyLaboratories:dev-v2-ac4-drm
PiperOrigin-RevId: 289092332
This commit is contained in:
commit
3e08e42168
@ -61,6 +61,7 @@
|
|||||||
on earlier releases, but only when embedded in a non-FLAC container such as
|
on earlier releases, but only when embedded in a non-FLAC container such as
|
||||||
Matroska or MP4.
|
Matroska or MP4.
|
||||||
* Javadocs: Add favicon for easier identification in browser tabs
|
* Javadocs: Add favicon for easier identification in browser tabs
|
||||||
|
* FMP4: Add support for encrypted AC-4 tracks.
|
||||||
|
|
||||||
### 2.11.1 (2019-12-20) ###
|
### 2.11.1 (2019-12-20) ###
|
||||||
|
|
||||||
|
@ -1265,14 +1265,19 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
sampleSize -= Atom.HEADER_SIZE;
|
sampleSize -= Atom.HEADER_SIZE;
|
||||||
input.skipFully(Atom.HEADER_SIZE);
|
input.skipFully(Atom.HEADER_SIZE);
|
||||||
}
|
}
|
||||||
sampleBytesWritten = currentTrackBundle.outputSampleEncryptionData();
|
|
||||||
sampleSize += sampleBytesWritten;
|
|
||||||
if (MimeTypes.AUDIO_AC4.equals(currentTrackBundle.track.format.sampleMimeType)) {
|
if (MimeTypes.AUDIO_AC4.equals(currentTrackBundle.track.format.sampleMimeType)) {
|
||||||
|
// AC4 samples need to be prefixed with a clear sample header.
|
||||||
|
sampleBytesWritten =
|
||||||
|
currentTrackBundle.outputSampleEncryptionData(sampleSize, Ac4Util.SAMPLE_HEADER_SIZE);
|
||||||
Ac4Util.getAc4SampleHeader(sampleSize, scratch);
|
Ac4Util.getAc4SampleHeader(sampleSize, scratch);
|
||||||
currentTrackBundle.output.sampleData(scratch, Ac4Util.SAMPLE_HEADER_SIZE);
|
currentTrackBundle.output.sampleData(scratch, Ac4Util.SAMPLE_HEADER_SIZE);
|
||||||
sampleBytesWritten += Ac4Util.SAMPLE_HEADER_SIZE;
|
sampleBytesWritten += Ac4Util.SAMPLE_HEADER_SIZE;
|
||||||
sampleSize += Ac4Util.SAMPLE_HEADER_SIZE;
|
} else {
|
||||||
|
sampleBytesWritten =
|
||||||
|
currentTrackBundle.outputSampleEncryptionData(sampleSize, /* clearHeaderSize= */ 0);
|
||||||
}
|
}
|
||||||
|
sampleSize += sampleBytesWritten;
|
||||||
parserState = STATE_READING_SAMPLE_CONTINUE;
|
parserState = STATE_READING_SAMPLE_CONTINUE;
|
||||||
sampleCurrentNalBytesRemaining = 0;
|
sampleCurrentNalBytesRemaining = 0;
|
||||||
}
|
}
|
||||||
@ -1471,8 +1476,11 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
*/
|
*/
|
||||||
private static final class TrackBundle {
|
private static final class TrackBundle {
|
||||||
|
|
||||||
|
private static final int SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH = 8;
|
||||||
|
|
||||||
public final TrackOutput output;
|
public final TrackOutput output;
|
||||||
public final TrackFragment fragment;
|
public final TrackFragment fragment;
|
||||||
|
public final ParsableByteArray scratch;
|
||||||
|
|
||||||
public Track track;
|
public Track track;
|
||||||
public DefaultSampleValues defaultSampleValues;
|
public DefaultSampleValues defaultSampleValues;
|
||||||
@ -1487,6 +1495,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
public TrackBundle(TrackOutput output) {
|
public TrackBundle(TrackOutput output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
fragment = new TrackFragment();
|
fragment = new TrackFragment();
|
||||||
|
scratch = new ParsableByteArray();
|
||||||
encryptionSignalByte = new ParsableByteArray(1);
|
encryptionSignalByte = new ParsableByteArray(1);
|
||||||
defaultInitializationVector = new ParsableByteArray();
|
defaultInitializationVector = new ParsableByteArray();
|
||||||
}
|
}
|
||||||
@ -1555,9 +1564,13 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
/**
|
/**
|
||||||
* Outputs the encryption data for the current sample.
|
* Outputs the encryption data for the current sample.
|
||||||
*
|
*
|
||||||
|
* @param sampleSize The size of the current sample in bytes, excluding any additional clear
|
||||||
|
* header that will be prefixed to the sample by the extractor.
|
||||||
|
* @param clearHeaderSize The size of a clear header that will be prefixed to the sample by the
|
||||||
|
* extractor, or 0.
|
||||||
* @return The number of written bytes.
|
* @return The number of written bytes.
|
||||||
*/
|
*/
|
||||||
public int outputSampleEncryptionData() {
|
public int outputSampleEncryptionData(int sampleSize, int clearHeaderSize) {
|
||||||
TrackEncryptionBox encryptionBox = getEncryptionBoxIfEncrypted();
|
TrackEncryptionBox encryptionBox = getEncryptionBoxIfEncrypted();
|
||||||
if (encryptionBox == null) {
|
if (encryptionBox == null) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1576,23 +1589,61 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
vectorSize = initVectorData.length;
|
vectorSize = initVectorData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean subsampleEncryption = fragment.sampleHasSubsampleEncryptionTable(currentSampleIndex);
|
boolean haveSubsampleEncryptionTable =
|
||||||
|
fragment.sampleHasSubsampleEncryptionTable(currentSampleIndex);
|
||||||
|
boolean writeSubsampleEncryptionData = haveSubsampleEncryptionTable || clearHeaderSize != 0;
|
||||||
|
|
||||||
// Write the signal byte, containing the vector size and the subsample encryption flag.
|
// Write the signal byte, containing the vector size and the subsample encryption flag.
|
||||||
encryptionSignalByte.data[0] = (byte) (vectorSize | (subsampleEncryption ? 0x80 : 0));
|
encryptionSignalByte.data[0] =
|
||||||
|
(byte) (vectorSize | (writeSubsampleEncryptionData ? 0x80 : 0));
|
||||||
encryptionSignalByte.setPosition(0);
|
encryptionSignalByte.setPosition(0);
|
||||||
output.sampleData(encryptionSignalByte, 1);
|
output.sampleData(encryptionSignalByte, 1);
|
||||||
// Write the vector.
|
// Write the vector.
|
||||||
output.sampleData(initializationVectorData, vectorSize);
|
output.sampleData(initializationVectorData, vectorSize);
|
||||||
// If we don't have subsample encryption data, we're done.
|
|
||||||
if (!subsampleEncryption) {
|
if (!writeSubsampleEncryptionData) {
|
||||||
return 1 + vectorSize;
|
return 1 + vectorSize;
|
||||||
}
|
}
|
||||||
// Write the subsample encryption data.
|
|
||||||
|
if (!haveSubsampleEncryptionTable) {
|
||||||
|
// The sample is fully encrypted, except for the additional clear header that the extractor
|
||||||
|
// is going to prefix. We need to synthesize subsample encryption data that takes the header
|
||||||
|
// into account.
|
||||||
|
scratch.reset(SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH);
|
||||||
|
// subsampleCount = 1 (unsigned short)
|
||||||
|
scratch.data[0] = (byte) 0;
|
||||||
|
scratch.data[1] = (byte) 1;
|
||||||
|
// clearDataSize = clearHeaderSize (unsigned short)
|
||||||
|
scratch.data[2] = (byte) ((clearHeaderSize >> 8) & 0xFF);
|
||||||
|
scratch.data[3] = (byte) (clearHeaderSize & 0xFF);
|
||||||
|
// encryptedDataSize = sampleSize (unsigned short)
|
||||||
|
scratch.data[4] = (byte) ((sampleSize >> 24) & 0xFF);
|
||||||
|
scratch.data[5] = (byte) ((sampleSize >> 16) & 0xFF);
|
||||||
|
scratch.data[6] = (byte) ((sampleSize >> 8) & 0xFF);
|
||||||
|
scratch.data[7] = (byte) (sampleSize & 0xFF);
|
||||||
|
output.sampleData(scratch, SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH);
|
||||||
|
return 1 + vectorSize + SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
ParsableByteArray subsampleEncryptionData = fragment.sampleEncryptionData;
|
ParsableByteArray subsampleEncryptionData = fragment.sampleEncryptionData;
|
||||||
int subsampleCount = subsampleEncryptionData.readUnsignedShort();
|
int subsampleCount = subsampleEncryptionData.readUnsignedShort();
|
||||||
subsampleEncryptionData.skipBytes(-2);
|
subsampleEncryptionData.skipBytes(-2);
|
||||||
int subsampleDataLength = 2 + 6 * subsampleCount;
|
int subsampleDataLength = 2 + 6 * subsampleCount;
|
||||||
|
|
||||||
|
if (clearHeaderSize != 0) {
|
||||||
|
// We need to account for the additional clear header by adding clearHeaderSize to
|
||||||
|
// clearDataSize for the first subsample specified in the subsample encryption data.
|
||||||
|
scratch.reset(subsampleDataLength);
|
||||||
|
scratch.readBytes(subsampleEncryptionData.data, /* offset= */ 0, subsampleDataLength);
|
||||||
|
subsampleEncryptionData.skipBytes(subsampleDataLength);
|
||||||
|
|
||||||
|
int clearDataSize = (scratch.data[2] & 0xFF) << 8 | (scratch.data[3] & 0xFF);
|
||||||
|
int adjustedClearDataSize = clearDataSize + clearHeaderSize;
|
||||||
|
scratch.data[2] = (byte) ((adjustedClearDataSize >> 8) & 0xFF);
|
||||||
|
scratch.data[3] = (byte) (adjustedClearDataSize & 0xFF);
|
||||||
|
subsampleEncryptionData = scratch;
|
||||||
|
}
|
||||||
|
|
||||||
output.sampleData(subsampleEncryptionData, subsampleDataLength);
|
output.sampleData(subsampleEncryptionData, subsampleDataLength);
|
||||||
return 1 + vectorSize + subsampleDataLength;
|
return 1 + vectorSize + subsampleDataLength;
|
||||||
}
|
}
|
||||||
|
BIN
library/core/src/test/assets/mp4/sample_ac4_protected.mp4
Normal file
BIN
library/core/src/test/assets/mp4/sample_ac4_protected.mp4
Normal file
Binary file not shown.
145
library/core/src/test/assets/mp4/sample_ac4_protected.mp4.0.dump
Normal file
145
library/core/src/test/assets/mp4/sample_ac4_protected.mp4.0.dump
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 760000
|
||||||
|
getPosition(0) = [[timeUs=0, position=950]]
|
||||||
|
numberOfTracks = 1
|
||||||
|
track 0:
|
||||||
|
format:
|
||||||
|
bitrate = -1
|
||||||
|
id = 1
|
||||||
|
containerMimeType = null
|
||||||
|
sampleMimeType = audio/ac4
|
||||||
|
maxInputSize = -1
|
||||||
|
width = -1
|
||||||
|
height = -1
|
||||||
|
frameRate = -1.0
|
||||||
|
rotationDegrees = 0
|
||||||
|
pixelWidthHeightRatio = 1.0
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 48000
|
||||||
|
pcmEncoding = -1
|
||||||
|
encoderDelay = 0
|
||||||
|
encoderPadding = 0
|
||||||
|
subsampleOffsetUs = 9223372036854775807
|
||||||
|
selectionFlags = 0
|
||||||
|
language = und
|
||||||
|
drmInitData = -1683793742
|
||||||
|
metadata = null
|
||||||
|
initializationData:
|
||||||
|
total output bytes = 7936
|
||||||
|
sample count = 19
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 96EFFFF3
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 1:
|
||||||
|
time = 40000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 899279C6
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 2:
|
||||||
|
time = 80000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 9EA9F45
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 3:
|
||||||
|
time = 120000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 82D362A9
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 4:
|
||||||
|
time = 160000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash B8705CFB
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 5:
|
||||||
|
time = 200000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 58B5628E
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 6:
|
||||||
|
time = 240000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 87F3C13B
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 7:
|
||||||
|
time = 280000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 54333DC5
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 8:
|
||||||
|
time = 320000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 1C49C4B3
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 9:
|
||||||
|
time = 360000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 5FDC324F
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 10:
|
||||||
|
time = 400000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash B2A7F444
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 11:
|
||||||
|
time = 440000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 512, hash 5FD06C1E
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 12:
|
||||||
|
time = 480000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 537, hash 7ABBDCB
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 13:
|
||||||
|
time = 520000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 616, hash 3F657E23
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 14:
|
||||||
|
time = 560000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 453, hash 8FCF0529
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 15:
|
||||||
|
time = 600000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 383, hash 7F8C9E19
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 16:
|
||||||
|
time = 640000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 3727858D
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 17:
|
||||||
|
time = 680000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 391, hash E2931212
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 18:
|
||||||
|
time = 720000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 63017D46
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
tracksEnded = true
|
109
library/core/src/test/assets/mp4/sample_ac4_protected.mp4.1.dump
Normal file
109
library/core/src/test/assets/mp4/sample_ac4_protected.mp4.1.dump
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 760000
|
||||||
|
getPosition(0) = [[timeUs=0, position=950]]
|
||||||
|
numberOfTracks = 1
|
||||||
|
track 0:
|
||||||
|
format:
|
||||||
|
bitrate = -1
|
||||||
|
id = 1
|
||||||
|
containerMimeType = null
|
||||||
|
sampleMimeType = audio/ac4
|
||||||
|
maxInputSize = -1
|
||||||
|
width = -1
|
||||||
|
height = -1
|
||||||
|
frameRate = -1.0
|
||||||
|
rotationDegrees = 0
|
||||||
|
pixelWidthHeightRatio = 1.0
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 48000
|
||||||
|
pcmEncoding = -1
|
||||||
|
encoderDelay = 0
|
||||||
|
encoderPadding = 0
|
||||||
|
subsampleOffsetUs = 9223372036854775807
|
||||||
|
selectionFlags = 0
|
||||||
|
language = und
|
||||||
|
drmInitData = -1683793742
|
||||||
|
metadata = null
|
||||||
|
initializationData:
|
||||||
|
total output bytes = 5632
|
||||||
|
sample count = 13
|
||||||
|
sample 0:
|
||||||
|
time = 240000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 87F3C13B
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 1:
|
||||||
|
time = 280000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 54333DC5
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 2:
|
||||||
|
time = 320000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 1C49C4B3
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 3:
|
||||||
|
time = 360000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash 5FDC324F
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 4:
|
||||||
|
time = 400000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 384, hash B2A7F444
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 5:
|
||||||
|
time = 440000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 512, hash 5FD06C1E
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 6:
|
||||||
|
time = 480000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 537, hash 7ABBDCB
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 7:
|
||||||
|
time = 520000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 616, hash 3F657E23
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 8:
|
||||||
|
time = 560000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 453, hash 8FCF0529
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 9:
|
||||||
|
time = 600000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 383, hash 7F8C9E19
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 10:
|
||||||
|
time = 640000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 3727858D
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 11:
|
||||||
|
time = 680000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 391, hash E2931212
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 12:
|
||||||
|
time = 720000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 63017D46
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
tracksEnded = true
|
@ -0,0 +1,73 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 760000
|
||||||
|
getPosition(0) = [[timeUs=0, position=950]]
|
||||||
|
numberOfTracks = 1
|
||||||
|
track 0:
|
||||||
|
format:
|
||||||
|
bitrate = -1
|
||||||
|
id = 1
|
||||||
|
containerMimeType = null
|
||||||
|
sampleMimeType = audio/ac4
|
||||||
|
maxInputSize = -1
|
||||||
|
width = -1
|
||||||
|
height = -1
|
||||||
|
frameRate = -1.0
|
||||||
|
rotationDegrees = 0
|
||||||
|
pixelWidthHeightRatio = 1.0
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 48000
|
||||||
|
pcmEncoding = -1
|
||||||
|
encoderDelay = 0
|
||||||
|
encoderPadding = 0
|
||||||
|
subsampleOffsetUs = 9223372036854775807
|
||||||
|
selectionFlags = 0
|
||||||
|
language = und
|
||||||
|
drmInitData = -1683793742
|
||||||
|
metadata = null
|
||||||
|
initializationData:
|
||||||
|
total output bytes = 3200
|
||||||
|
sample count = 7
|
||||||
|
sample 0:
|
||||||
|
time = 480000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 537, hash 7ABBDCB
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 1:
|
||||||
|
time = 520000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 616, hash 3F657E23
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 2:
|
||||||
|
time = 560000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 453, hash 8FCF0529
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 3:
|
||||||
|
time = 600000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 383, hash 7F8C9E19
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 4:
|
||||||
|
time = 640000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 3727858D
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 5:
|
||||||
|
time = 680000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 391, hash E2931212
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
sample 6:
|
||||||
|
time = 720000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 63017D46
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
tracksEnded = true
|
@ -0,0 +1,37 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 760000
|
||||||
|
getPosition(0) = [[timeUs=0, position=950]]
|
||||||
|
numberOfTracks = 1
|
||||||
|
track 0:
|
||||||
|
format:
|
||||||
|
bitrate = -1
|
||||||
|
id = 1
|
||||||
|
containerMimeType = null
|
||||||
|
sampleMimeType = audio/ac4
|
||||||
|
maxInputSize = -1
|
||||||
|
width = -1
|
||||||
|
height = -1
|
||||||
|
frameRate = -1.0
|
||||||
|
rotationDegrees = 0
|
||||||
|
pixelWidthHeightRatio = 1.0
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 48000
|
||||||
|
pcmEncoding = -1
|
||||||
|
encoderDelay = 0
|
||||||
|
encoderPadding = 0
|
||||||
|
subsampleOffsetUs = 9223372036854775807
|
||||||
|
selectionFlags = 0
|
||||||
|
language = und
|
||||||
|
drmInitData = -1683793742
|
||||||
|
metadata = null
|
||||||
|
initializationData:
|
||||||
|
total output bytes = 410
|
||||||
|
sample count = 1
|
||||||
|
sample 0:
|
||||||
|
time = 720000
|
||||||
|
flags = 1073741825
|
||||||
|
data = length 410, hash 63017D46
|
||||||
|
crypto mode = 1
|
||||||
|
encryption key = length 16, hash 9FDDEA52
|
||||||
|
tracksEnded = true
|
@ -57,6 +57,12 @@ public final class FragmentedMp4ExtractorTest {
|
|||||||
getExtractorFactory(Collections.emptyList()), "mp4/sample_ac4_fragmented.mp4");
|
getExtractorFactory(Collections.emptyList()), "mp4/sample_ac4_fragmented.mp4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSampleWithProtectedAc4Track() throws Exception {
|
||||||
|
ExtractorAsserts.assertBehavior(
|
||||||
|
getExtractorFactory(Collections.emptyList()), "mp4/sample_ac4_protected.mp4");
|
||||||
|
}
|
||||||
|
|
||||||
private static ExtractorFactory getExtractorFactory(final List<Format> closedCaptionFormats) {
|
private static ExtractorFactory getExtractorFactory(final List<Format> closedCaptionFormats) {
|
||||||
return () -> new FragmentedMp4Extractor(0, null, null, null, closedCaptionFormats);
|
return () -> new FragmentedMp4Extractor(0, null, null, null, closedCaptionFormats);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user