public static final int CRYPTO_MODE_AES_CBC = 2;
/**
- * Metadata describing the structure of a (at least partially) encrypted
- * input sample.
- * A buffer's data is considered to be partitioned into "subSamples",
- * each subSample starts with a (potentially empty) run of plain,
- * unencrypted bytes followed by a (also potentially empty) run of
- * encrypted bytes. If pattern encryption applies, each of the latter runs
- * is encrypted only partly, according to a repeating pattern of "encrypt"
- * and "skip" blocks. numBytesOfClearData can be null to indicate that all
- * data is encrypted. This information encapsulates per-sample metadata as
- * outlined in ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base
- * media file format files".
+ * Metadata describing the structure of an encrypted input sample.
+ * <p>
+ * A buffer's data is considered to be partitioned into "subSamples". Each subSample starts with
+ * a run of plain, unencrypted bytes followed by a run of encrypted bytes. Either of these runs
+ * may be empty. If pattern encryption applies, each of the encrypted runs is encrypted only
+ * partly, according to a repeating pattern of "encrypt" and "skip" blocks.
+ * {@link #numBytesOfClearData} can be null to indicate that all data is encrypted, and
+ * {@link #numBytesOfEncryptedData} can be null to indicate that all data is clear. At least one
+ * of {@link #numBytesOfClearData} and {@link #numBytesOfEncryptedData} must be non-null.
+ * <p>
+ * This information encapsulates per-sample metadata as outlined in ISO/IEC FDIS 23001-7:2016
+ * "Common encryption in ISO base media file format files".
+ * <p>
+ * <h3>ISO-CENC Schemes</h3>
+ * ISO/IEC FDIS 23001-7:2016 defines four possible schemes by which media may be encrypted,
+ * corresponding to each possible combination of an AES mode with the presence or absence of
+ * patterned encryption.
+ *
+ * <table style="width: 0%">
+ * <thead>
+ * <tr>
+ * <th> </th>
+ * <th>AES-CTR</th>
+ * <th>AES-CBC</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th>Without Patterns</th>
+ * <td>cenc</td>
+ * <td>cbc1</td>
+ * </tr><tr>
+ * <th>With Patterns</th>
+ * <td>cens</td>
+ * <td>cbcs</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * For {@code CryptoInfo}, the scheme is selected implicitly by the combination of the
+ * {@link #mode} field and the value set with {@link #setPattern}. For the pattern, setting the
+ * pattern to all zeroes (that is, both {@code blocksToEncrypt} and {@code blocksToSkip} are
+ * zero) is interpreted as turning patterns off completely. A scheme that does not use patterns
+ * will be selected, either cenc or cbc1. Setting the pattern to any nonzero value will choose
+ * one of the pattern-supporting schemes, cens or cbcs. The default pattern if
+ * {@link #setPattern} is never called is all zeroes.
+ * <p>
+ * <h4>HLS SAMPLE-AES Audio</h4>
+ * HLS SAMPLE-AES audio is encrypted in a manner compatible with the cbcs scheme, except that it
+ * does not use patterned encryption. However, if {@link #setPattern} is used to set the pattern
+ * to all zeroes, this will be interpreted as selecting the cbc1 scheme. The cbc1 scheme cannot
+ * successfully decrypt HLS SAMPLE-AES audio because of differences in how the IVs are handled.
+ * For this reason, it is recommended that a pattern of {@code 1} encrypted block and {@code 0}
+ * skip blocks be used with HLS SAMPLE-AES audio. This will trigger decryption to use cbcs mode
+ * while still decrypting every block.
*/
public final static class CryptoInfo {
/**
*/
public int numSubSamples;
/**
- * The number of leading unencrypted bytes in each subSample.
+ * The number of leading unencrypted bytes in each subSample. If null, all bytes are treated
+ * as encrypted and {@link #numBytesOfEncryptedData} must be specified.
*/
public int[] numBytesOfClearData;
/**
- * The number of trailing encrypted bytes in each subSample.
+ * The number of trailing encrypted bytes in each subSample. If null, all bytes are treated
+ * as clear and {@link #numBytesOfClearData} must be specified.
*/
public int[] numBytesOfEncryptedData;
/**
public int mode;
/**
- * Metadata describing an encryption pattern for the protected bytes in
- * a subsample. An encryption pattern consists of a repeating sequence
- * of crypto blocks comprised of a number of encrypted blocks followed
- * by a number of unencrypted, or skipped, blocks.
+ * Metadata describing an encryption pattern for the protected bytes in a subsample. An
+ * encryption pattern consists of a repeating sequence of crypto blocks comprised of a
+ * number of encrypted blocks followed by a number of unencrypted, or skipped, blocks.
*/
public final static class Pattern {
/**
- * Number of blocks to be encrypted in the pattern. If zero, pattern
- * encryption is inoperative.
+ * Number of blocks to be encrypted in the pattern. If both this and
+ * {@link #mSkipBlocks} are zero, pattern encryption is inoperative.
*/
private int mEncryptBlocks;
/**
- * Number of blocks to be skipped (left clear) in the pattern. If zero,
- * pattern encryption is inoperative.
+ * Number of blocks to be skipped (left clear) in the pattern. If both this and
+ * {@link #mEncryptBlocks} are zero, pattern encryption is inoperative.
*/
private int mSkipBlocks;
/**
- * Construct a sample encryption pattern given the number of blocks to
- * encrypt and skip in the pattern.
+ * Construct a sample encryption pattern given the number of blocks to encrypt and skip
+ * in the pattern. If both parameters are zero, pattern encryption is inoperative.
*/
public Pattern(int blocksToEncrypt, int blocksToSkip) {
set(blocksToEncrypt, blocksToSkip);
}
/**
- * Set the number of blocks to encrypt and skip in a sample encryption
- * pattern.
+ * Set the number of blocks to encrypt and skip in a sample encryption pattern. If both
+ * parameters are zero, pattern encryption is inoperative.
*/
public void set(int blocksToEncrypt, int blocksToSkip) {
mEncryptBlocks = blocksToEncrypt;