1package com.googlecode.mp4parser.boxes.piff;
2
3import com.coremedia.iso.IsoTypeReader;
4import com.coremedia.iso.IsoTypeWriter;
5import com.googlecode.mp4parser.AbstractFullBox;
6
7import java.nio.ByteBuffer;
8import java.util.ArrayList;
9import java.util.List;
10
11/**
12 * The syntax of the fields defined in this section, specified in ABNF [RFC5234], is as follows:
13 * TfrfBox = TfrfBoxLength TfrfBoxType [TfrfBoxLongLength] TfrfBoxUUID TfrfBoxFields
14 * TfrfBoxChildren
15 * TfrfBoxType = "u" "u" "i" "d"
16 * TfrfBoxLength = BoxLength
17 * TfrfBoxLongLength = LongBoxLength
18 * TfrfBoxUUID = %xD4 %x80 %x7E %xF2 %xCA %x39 %x46 %x95
19 * %x8E %x54 %x26 %xCB %x9E %x46 %xA7 %x9F
20 * TfrfBoxFields = TfrfBoxVersion
21 * TfrfBoxFlags
22 * FragmentCount
23 * (1* TfrfBoxDataFields32) / (1* TfrfBoxDataFields64)
24 * TfrfBoxVersion = %x00 / %x01
25 * TfrfBoxFlags = 24*24 RESERVED_BIT
26 * FragmentCount = UINT8
27 * TfrfBoxDataFields32 = FragmentAbsoluteTime32
28 * FragmentDuration32
29 * TfrfBoxDataFields64 = FragmentAbsoluteTime64
30 * FragmentDuration64
31 * FragmentAbsoluteTime64 = UNSIGNED_INT32
32 * FragmentDuration64 = UNSIGNED_INT32
33 * FragmentAbsoluteTime64 = UNSIGNED_INT64
34 * FragmentDuration64 = UNSIGNED_INT64
35 * TfrfBoxChildren = *( VendorExtensionUUIDBox )
36 */
37public class TfrfBox extends AbstractFullBox {
38    public List<Entry> entries = new ArrayList<Entry>();
39
40    public TfrfBox() {
41        super("uuid");
42    }
43
44    @Override
45    public byte[] getUserType() {
46        return new byte[]{(byte) 0xd4, (byte) 0x80, (byte) 0x7e, (byte) 0xf2, (byte) 0xca, (byte) 0x39, (byte) 0x46,
47                (byte) 0x95, (byte) 0x8e, (byte) 0x54, 0x26, (byte) 0xcb, (byte) 0x9e, (byte) 0x46, (byte) 0xa7, (byte) 0x9f};
48    }
49
50    @Override
51    protected long getContentSize() {
52        return 5 + entries.size() * (getVersion() == 0x01 ? 16 : 8);
53    }
54
55    @Override
56    protected void getContent(ByteBuffer byteBuffer) {
57        writeVersionAndFlags(byteBuffer);
58        IsoTypeWriter.writeUInt8(byteBuffer, entries.size());
59
60        for (Entry entry : entries) {
61            if (getVersion() == 0x01) {
62                IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteTime);
63                IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteDuration);
64            } else {
65                IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteTime);
66                IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteDuration);
67            }
68        }
69    }
70
71    @Override
72    public void _parseDetails(ByteBuffer content) {
73        parseVersionAndFlags(content);
74        int fragmentCount = IsoTypeReader.readUInt8(content);
75
76        for (int i = 0; i < fragmentCount; i++) {
77            Entry entry = new Entry();
78            if (getVersion() == 0x01) {
79                entry.fragmentAbsoluteTime = IsoTypeReader.readUInt64(content);
80                entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt64(content);
81            } else {
82                entry.fragmentAbsoluteTime = IsoTypeReader.readUInt32(content);
83                entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt32(content);
84            }
85            entries.add(entry);
86        }
87    }
88
89
90    public long getFragmentCount() {
91        return entries.size();
92    }
93
94    public List<Entry> getEntries() {
95        return entries;
96    }
97
98    @Override
99    public String toString() {
100        final StringBuilder sb = new StringBuilder();
101        sb.append("TfrfBox");
102        sb.append("{entries=").append(entries);
103        sb.append('}');
104        return sb.toString();
105    }
106
107    public class Entry {
108        long fragmentAbsoluteTime;
109        long fragmentAbsoluteDuration;
110
111        public long getFragmentAbsoluteTime() {
112            return fragmentAbsoluteTime;
113        }
114
115        public long getFragmentAbsoluteDuration() {
116            return fragmentAbsoluteDuration;
117        }
118
119        @Override
120        public String toString() {
121            final StringBuilder sb = new StringBuilder();
122            sb.append("Entry");
123            sb.append("{fragmentAbsoluteTime=").append(fragmentAbsoluteTime);
124            sb.append(", fragmentAbsoluteDuration=").append(fragmentAbsoluteDuration);
125            sb.append('}');
126            return sb.toString();
127        }
128    }
129}
130