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 Zhuimport com.googlecode.mp4parser.h264.CharCache; 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.IOException; 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.InputStream; 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * A dummy implementation of H264 RBSP reading 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @author Stanislav Vitvitskiy 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class BitstreamReader { 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private InputStream is; 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int curByte; 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int nextByte; 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int nBit; 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu protected static int bitsRead; 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu protected CharCache debugBits = new CharCache(50); 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public BitstreamReader(InputStream is) throws IOException { 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.is = is; 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu curByte = is.read(); 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu nextByte = is.read(); 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#read1Bit() 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int read1Bit() throws IOException { 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nBit == 8) { 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu advance(); 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (curByte == -1) { 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return -1; 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int res = (curByte >> (7 - nBit)) & 1; 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu nBit++; 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu debugBits.append(res == 0 ? '0' : '1'); 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ++bitsRead; 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return res; 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readNBit(int) 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long readNBit(int n) throws IOException { 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (n > 64) 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new IllegalArgumentException("Can not readByte more then 64 bit"); 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long val = 0; 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < n; i++) { 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu val <<= 1; 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu val |= read1Bit(); 83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return val; 86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private void advance() throws IOException { 89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu curByte = nextByte; 90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu nextByte = is.read(); 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu nBit = 0; 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readByte() 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int readByte() throws IOException { 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nBit > 0) { 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu advance(); 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int res = curByte; 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu advance(); 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return res; 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#moreRBSPData() 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean moreRBSPData() throws IOException { 117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nBit == 8) { 118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu advance(); 119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int tail = 1 << (8 - nBit - 1); 121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int mask = ((tail << 1) - 1); 122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu boolean hasTail = (curByte & mask) == tail; 123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return !(curByte == -1 || (nextByte == -1 && hasTail)); 125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long getBitPosition() { 128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (bitsRead * 8 + (nBit % 8)); 129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readRemainingByte() 135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long readRemainingByte() throws IOException { 137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return readNBit(8 - nBit); 138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#next_bits(int) 144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int peakNextBits(int n) throws IOException { 146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (n > 8) 147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new IllegalArgumentException("N should be less then 8"); 148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nBit == 8) { 149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu advance(); 150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (curByte == -1) { 151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return -1; 152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int[] bits = new int[16 - nBit]; 155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int cnt = 0; 157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = nBit; i < 8; i++) { 158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bits[cnt++] = (curByte >> (7 - i)) & 0x1; 159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < 8; i++) { 162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bits[cnt++] = (nextByte >> (7 - i)) & 0x1; 163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int result = 0; 166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < n; i++) { 167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu result <<= 1; 168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu result |= bits[i]; 169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return result; 172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#byte_aligned() 178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isByteAligned() { 180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (nBit % 8) == 0; 181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /* 184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * (non-Javadoc) 185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 186dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#close() 187dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 188dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void close() throws IOException { 189dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 190dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 191dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int getCurBit() { 192dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return nBit; 193dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 194dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu}