15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Copyright (c) 2011 Stanislav Vitvitskiy
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Permission is hereby granted, free of charge, to any person obtaining a copy of this
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)software and associated documentation files (the "Software"), to deal in the Software
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)without restriction, including without limitation the rights to use, copy, modify,
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)permit persons to whom the Software is furnished to do so, subject to the following
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)conditions:
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)The above copyright notice and this permission notice shall be included in all copies or
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisubstantial portions of the Software.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OR OTHER DEALINGS IN THE SOFTWARE.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package com.googlecode.mp4parser.h264.read;
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochimport com.googlecode.mp4parser.h264.CharCache;
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochimport java.io.IOException;
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport java.io.InputStream;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A dummy implementation of H264 RBSP reading
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @author Stanislav Vitvitskiy
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class BitstreamReader {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private InputStream is;
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    private int curByte;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private int nextByte;
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int nBit;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    protected static int bitsRead;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected CharCache debugBits = new CharCache(50);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    public BitstreamReader(InputStream is) throws IOException {
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        this.is = is;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        curByte = is.read();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nextByte = is.read();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    /*
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      * (non-Javadoc)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#read1Bit()
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public int read1Bit() throws IOException {
54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        if (nBit == 8) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            advance();
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if (curByte == -1) {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                return -1;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int res = (curByte >> (7 - nBit)) & 1;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        nBit++;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        debugBits.append(res == 0 ? '0' : '1');
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++bitsRead;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return res;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readNBit(int)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public long readNBit(int n) throws IOException {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (n > 64)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw new IllegalArgumentException("Can not readByte more then 64 bit");
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long val = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < n; i++) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            val <<= 1;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            val |= read1Bit();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return val;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void advance() throws IOException {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        curByte = nextByte;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nextByte = is.read();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nBit = 0;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readByte()
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int readByte() throws IOException {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nBit > 0) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            advance();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        int res = curByte;
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        advance();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return res;
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#moreRBSPData()
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean moreRBSPData() throws IOException {
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if (nBit == 8) {
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            advance();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int tail = 1 << (8 - nBit - 1);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int mask = ((tail << 1) - 1);
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        boolean hasTail = (curByte & mask) == tail;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return !(curByte == -1 || (nextByte == -1 && hasTail));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    public long getBitPosition() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return (bitsRead * 8 + (nBit % 8));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /*
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readRemainingByte()
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public long readRemainingByte() throws IOException {
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return readNBit(8 - nBit);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#next_bits(int)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int peakNextBits(int n) throws IOException {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (n > 8)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw new IllegalArgumentException("N should be less then 8");
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nBit == 8) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            advance();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (curByte == -1) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return -1;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        int[] bits = new int[16 - nBit];
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int cnt = 0;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = nBit; i < 8; i++) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            bits[cnt++] = (curByte >> (7 - i)) & 0x1;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < 8; i++) {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            bits[cnt++] = (nextByte >> (7 - i)) & 0x1;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int result = 0;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < n; i++) {
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            result <<= 1;
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            result |= bits[i];
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return result;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    /*
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#byte_aligned()
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      */
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean isByteAligned() {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return (nBit % 8) == 0;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /*
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * (non-Javadoc)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#close()
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      */
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void close() throws IOException {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int getCurBit() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return nBit;
193    }
194}