1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/*
2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuCopyright (c) 2011 Stanislav Vitvitskiy
3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuPermission is hereby granted, free of charge, to any person obtaining a copy of this
5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhusoftware and associated documentation files (the "Software"), to deal in the Software
6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuwithout restriction, including without limitation the rights to use, copy, modify,
7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhumerge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupermit persons to whom the Software is furnished to do so, subject to the following
9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuconditions:
10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuThe above copyright notice and this permission notice shall be included in all copies or
12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhusubstantial portions of the Software.
13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui ZhuOR OTHER DEALINGS IN THE SOFTWARE.
20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu*/
21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.googlecode.mp4parser.h264.read;
22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.h264.BTree;
25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.IOException;
27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.InputStream;
28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport static com.googlecode.mp4parser.h264.Debug.println;
30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class CAVLCReader extends BitstreamReader {
33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public CAVLCReader(InputStream is) throws IOException {
35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        super(is);
36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public long readNBit(int n, String message) throws IOException {
39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        long val = readNBit(n);
40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        trace(message, String.valueOf(val));
42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return val;
44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    /**
47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     * Read unsigned exp-golomb code
48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     *
49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     * @return
50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     * @throws java.io.IOException
51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     * @throws java.io.IOException
52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu     */
53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    private int readUE() throws IOException {
54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int cnt = 0;
55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        while (read1Bit() == 0)
56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            cnt++;
57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int res = 0;
59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (cnt > 0) {
60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            long val = readNBit(cnt);
61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            res = (int) ((1 << cnt) - 1 + val);
63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return res;
66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    /*
69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu      * (non-Javadoc)
70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu      *
71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu      * @see
72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu      * ua.org.jplayer.javcodec.h264.H264BitInputStream#readUE(java.lang.String)
73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu      */
74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readUE(String message) throws IOException {
75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int res = readUE();
76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        trace(message, String.valueOf(res));
78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return res;
80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readSE(String message) throws IOException {
83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int val = readUE();
84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int sign = ((val & 0x1) << 1) - 1;
86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        val = ((val >> 1) + (val & 0x1)) * sign;
87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        trace(message, String.valueOf(val));
89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return val;
91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public boolean readBool(String message) throws IOException {
94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        boolean res = read1Bit() == 0 ? false : true;
96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        trace(message, res ? "1" : "0");
98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return res;
100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readU(int i, String string) throws IOException {
103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return (int) readNBit(i, string);
104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public byte[] read(int payloadSize) throws IOException {
107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        byte[] result = new byte[payloadSize];
108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (int i = 0; i < payloadSize; i++) {
109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result[i] = (byte) readByte();
110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return result;
112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public boolean readAE() {
115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        // TODO: do it!!
116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        throw new UnsupportedOperationException("Stan");
117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readTE(int max) throws IOException {
120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (max > 1)
121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return readUE();
122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return ~read1Bit() & 0x1;
123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readAEI() {
126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        // TODO: do it!!
127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        throw new UnsupportedOperationException("Stan");
128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readME(String string) throws IOException {
131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return readUE(string);
132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public Object readCE(BTree bt, String message) throws IOException {
135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        while (true) {
136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int bit = read1Bit();
137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            bt = bt.down(bit);
138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (bt == null) {
139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                throw new RuntimeException("Illegal code");
140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            Object i = bt.getValue();
142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (i != null) {
143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                trace(message, i.toString());
144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                return i;
145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readZeroBitCount(String message) throws IOException {
150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int count = 0;
151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        while (read1Bit() == 0)
152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            count++;
153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        trace(message, String.valueOf(count));
155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return count;
157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void readTrailingBits() throws IOException {
160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        read1Bit();
161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        readRemainingByte();
162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    private void trace(String message, String val) {
165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        StringBuilder traceBuilder = new StringBuilder();
166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int spaces;
167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        String pos = String.valueOf(bitsRead - debugBits.length());
168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        spaces = 8 - pos.length();
169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        traceBuilder.append("@" + pos);
171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (int i = 0; i < spaces; i++)
173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            traceBuilder.append(' ');
174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        traceBuilder.append(message);
176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        spaces = 100 - traceBuilder.length() - debugBits.length();
177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (int i = 0; i < spaces; i++)
178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            traceBuilder.append(' ');
179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        traceBuilder.append(debugBits);
180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        traceBuilder.append(" (" + val + ")");
181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        debugBits.clear();
182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        println(traceBuilder.toString());
184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu}