1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.googlecode.mp4parser.boxes.piff; 2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoFile; 4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeReader; 5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeWriter; 6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.util.Path; 7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.FileInputStream; 9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.FileNotFoundException; 10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.IOException; 11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.UnsupportedEncodingException; 12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.nio.ByteBuffer; 13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.ArrayList; 14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Collections; 15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.List; 16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Specifications > Microsoft PlayReady Format Specification > 2. PlayReady Media Format > 2.7. ASF GUIDs 19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * ASF_Protection_System_Identifier_Object 22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 9A04F079-9840-4286-AB92E65BE0885F95 23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * ASF_Content_Protection_System_Microsoft_PlayReady 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * F4637010-03C3-42CD-B932B48ADF3A6A54 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * ASF_StreamType_PlayReady_Encrypted_Command_Media 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 8683973A-6639-463A-ABD764F1CE3EEAE0 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Specifications > Microsoft PlayReady Format Specification > 2. PlayReady Media Format > 2.5. Data Objects > 2.5.1. Payload Extension for AES in Counter Mode 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * The sample Id is used as the IV in CTR mode. Block offset, starting at 0 and incremented by 1 after every 16 bytes, from the beginning of the sample is used as the Counter. 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * The sample ID for each sample (media object) is stored as an ASF payload extension system with the ID of ASF_Payload_Extension_Encryption_SampleID = {6698B84E-0AFA-4330-AEB2-1C0A98D7A44D}. The payload extension can be stored as a fixed size extension of 8 bytes. 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * The sample ID is always stored in big-endian byte order. 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class PlayReadyHeader extends ProtectionSpecificHeader { 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private long length; 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private List<PlayReadyRecord> records; 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public PlayReadyHeader() { 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void parse(ByteBuffer byteBuffer) { 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu Length DWORD 32 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu PlayReady Record Count WORD 16 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu PlayReady Records See Text Varies 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu length = IsoTypeReader.readUInt32BE(byteBuffer); 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int recordCount = IsoTypeReader.readUInt16BE(byteBuffer); 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu records = PlayReadyRecord.createFor(byteBuffer, recordCount); 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public ByteBuffer getData() { 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int size = 4 + 2; 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (PlayReadyRecord record : records) { 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu size += 2 + 2; 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu size += record.getValue().rewind().limit(); 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer byteBuffer = ByteBuffer.allocate(size); 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt32BE(byteBuffer, size); 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt16BE(byteBuffer, records.size()); 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (PlayReadyRecord record : records) { 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt16BE(byteBuffer, record.type); 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt16BE(byteBuffer, record.getValue().limit()); 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer tmp4debug = record.getValue(); 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byteBuffer.put(tmp4debug); 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return byteBuffer; 84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setRecords(List<PlayReadyRecord> records) { 87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.records = records; 88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<PlayReadyRecord> getRecords() { 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return Collections.unmodifiableList(records); 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final StringBuilder sb = new StringBuilder(); 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("PlayReadyHeader"); 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("{length=").append(length); 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", recordCount=").append(records.size()); 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", records=").append(records); 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append('}'); 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sb.toString(); 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static abstract class PlayReadyRecord { 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int type; 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public PlayReadyRecord(int type) { 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.type = type; 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static List<PlayReadyRecord> createFor(ByteBuffer byteBuffer, int recordCount) { 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<PlayReadyRecord> records = new ArrayList<PlayReadyRecord>(recordCount); 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < recordCount; i++) { 117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu PlayReadyRecord record; 118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int type = IsoTypeReader.readUInt16BE(byteBuffer); 119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int length = IsoTypeReader.readUInt16BE(byteBuffer); 120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu switch (type) { 121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 0x1: 122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu record = new RMHeader(); 123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 0x2: 125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu record = new DefaulPlayReadyRecord(0x02); 126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 0x3: 128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu record = new EmeddedLicenseStore(); 129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu default: 131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu record = new DefaulPlayReadyRecord(type); 132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu record.parse((ByteBuffer) byteBuffer.slice().limit(length)); 134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byteBuffer.position(byteBuffer.position() + length); 135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu records.add(record); 136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return records; 139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public abstract void parse(ByteBuffer bytes); 142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final StringBuilder sb = new StringBuilder(); 146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("PlayReadyRecord"); 147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("{type=").append(type); 148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", length=").append(getValue().limit()); 149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu// sb.append(", value=").append(Hex.encodeHex(getValue())).append('\''); 150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append('}'); 151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sb.toString(); 152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public abstract ByteBuffer getValue(); 155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static class RMHeader extends PlayReadyRecord { 157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String header; 158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public RMHeader() { 160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu super(0x01); 161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void parse(ByteBuffer bytes) { 165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu try { 166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] str = new byte[bytes.slice().limit()]; 167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bytes.get(str); 168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu header = new String(str, "UTF-16LE"); 169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } catch (UnsupportedEncodingException e) { 170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new RuntimeException(e); 171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public ByteBuffer getValue() { 176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] headerBytes; 177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu try { 178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu headerBytes = header.getBytes("UTF-16LE"); 179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } catch (UnsupportedEncodingException e) { 180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new RuntimeException(e); 181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return ByteBuffer.wrap(headerBytes); 183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setHeader(String header) { 186dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.header = header; 187dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 188dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 189dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String getHeader() { 190dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return header; 191dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 192dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 193dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 194dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 195dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final StringBuilder sb = new StringBuilder(); 196dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("RMHeader"); 197dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("{length=").append(getValue().limit()); 198dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", header='").append(header).append('\''); 199dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append('}'); 200dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sb.toString(); 201dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 202dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 203dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 204dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static class EmeddedLicenseStore extends PlayReadyRecord { 205dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer value; 206dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 207dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public EmeddedLicenseStore() { 208dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu super(0x03); 209dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 210dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 211dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 212dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void parse(ByteBuffer bytes) { 213dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.value = bytes.duplicate(); 214dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 215dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 216dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 217dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public ByteBuffer getValue() { 218dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return value; 219dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 220dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 221dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 222dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 223dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final StringBuilder sb = new StringBuilder(); 224dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("EmeddedLicenseStore"); 225dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("{length=").append(getValue().limit()); 226dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu //sb.append(", value='").append(Hex.encodeHex(getValue())).append('\''); 227dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append('}'); 228dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sb.toString(); 229dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 230dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 231dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 232dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static class DefaulPlayReadyRecord extends PlayReadyRecord { 233dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer value; 234dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 235dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public DefaulPlayReadyRecord(int type) { 236dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu super(type); 237dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 238dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 239dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 240dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void parse(ByteBuffer bytes) { 241dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.value = bytes.duplicate(); 242dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 243dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 244dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 245dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public ByteBuffer getValue() { 246dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return value; 247dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 248dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 249dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 250dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 251dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 252dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 253dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu} 254