package com.googlecode.mp4parser.boxes.piff; import com.coremedia.iso.IsoTypeReader; import com.coremedia.iso.IsoTypeWriter; import com.googlecode.mp4parser.AbstractFullBox; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; /** * The syntax of the fields defined in this section, specified in ABNF [RFC5234], is as follows: * TfrfBox = TfrfBoxLength TfrfBoxType [TfrfBoxLongLength] TfrfBoxUUID TfrfBoxFields * TfrfBoxChildren * TfrfBoxType = "u" "u" "i" "d" * TfrfBoxLength = BoxLength * TfrfBoxLongLength = LongBoxLength * TfrfBoxUUID = %xD4 %x80 %x7E %xF2 %xCA %x39 %x46 %x95 * %x8E %x54 %x26 %xCB %x9E %x46 %xA7 %x9F * TfrfBoxFields = TfrfBoxVersion * TfrfBoxFlags * FragmentCount * (1* TfrfBoxDataFields32) / (1* TfrfBoxDataFields64) * TfrfBoxVersion = %x00 / %x01 * TfrfBoxFlags = 24*24 RESERVED_BIT * FragmentCount = UINT8 * TfrfBoxDataFields32 = FragmentAbsoluteTime32 * FragmentDuration32 * TfrfBoxDataFields64 = FragmentAbsoluteTime64 * FragmentDuration64 * FragmentAbsoluteTime64 = UNSIGNED_INT32 * FragmentDuration64 = UNSIGNED_INT32 * FragmentAbsoluteTime64 = UNSIGNED_INT64 * FragmentDuration64 = UNSIGNED_INT64 * TfrfBoxChildren = *( VendorExtensionUUIDBox ) */ public class TfrfBox extends AbstractFullBox { public List<Entry> entries = new ArrayList<Entry>(); public TfrfBox() { super("uuid"); } @Override public byte[] getUserType() { return new byte[]{(byte) 0xd4, (byte) 0x80, (byte) 0x7e, (byte) 0xf2, (byte) 0xca, (byte) 0x39, (byte) 0x46, (byte) 0x95, (byte) 0x8e, (byte) 0x54, 0x26, (byte) 0xcb, (byte) 0x9e, (byte) 0x46, (byte) 0xa7, (byte) 0x9f}; } @Override protected long getContentSize() { return 5 + entries.size() * (getVersion() == 0x01 ? 16 : 8); } @Override protected void getContent(ByteBuffer byteBuffer) { writeVersionAndFlags(byteBuffer); IsoTypeWriter.writeUInt8(byteBuffer, entries.size()); for (Entry entry : entries) { if (getVersion() == 0x01) { IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteTime); IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteDuration); } else { IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteTime); IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteDuration); } } } @Override public void _parseDetails(ByteBuffer content) { parseVersionAndFlags(content); int fragmentCount = IsoTypeReader.readUInt8(content); for (int i = 0; i < fragmentCount; i++) { Entry entry = new Entry(); if (getVersion() == 0x01) { entry.fragmentAbsoluteTime = IsoTypeReader.readUInt64(content); entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt64(content); } else { entry.fragmentAbsoluteTime = IsoTypeReader.readUInt32(content); entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt32(content); } entries.add(entry); } } public long getFragmentCount() { return entries.size(); } public List<Entry> getEntries() { return entries; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("TfrfBox"); sb.append("{entries=").append(entries); sb.append('}'); return sb.toString(); } public class Entry { long fragmentAbsoluteTime; long fragmentAbsoluteDuration; public long getFragmentAbsoluteTime() { return fragmentAbsoluteTime; } public long getFragmentAbsoluteDuration() { return fragmentAbsoluteDuration; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Entry"); sb.append("{fragmentAbsoluteTime=").append(fragmentAbsoluteTime); sb.append(", fragmentAbsoluteDuration=").append(fragmentAbsoluteDuration); sb.append('}'); return sb.toString(); } } }