From: yeom <yeom> Date: Thu, 11 Aug 2011 23:48:35 +0000 (+0000) Subject: get rid of the stream parsing that occurs in the Layer III decoder. BitStream.readFra... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=88cc6f37e1158f55870e1b55100e91a09b8d1556;p=IRC.git get rid of the stream parsing that occurs in the Layer III decoder. BitStream.readFrame() returns a Header that has every information required by a single self-stabilizing loop iteration. --- diff --git a/Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java b/Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java new file mode 100644 index 00000000..046be7e8 --- /dev/null +++ b/Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java @@ -0,0 +1,17 @@ +public class BitStreamWrapper { + + private static Bitstream stream; + + public static void init(InputStream in) { + stream = new Bitstream(in); + } + + public static Header readFrame() { + return stream.readFrame(); + } + + public static int get_bits(int number_of_bits) { + return stream.get_bits(number_of_bits); + } + +} diff --git a/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java b/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java index 82c595cd..daf25e22 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java +++ b/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java @@ -139,6 +139,10 @@ public final class Bitstream implements BitstreamErrors { @LOC("FF") private boolean firstframe = true; + private BitReserve br; + private int main_data_begin; + private int frame_start; + /** * Construct a IBitstream that reads data from a given InputStream. * @@ -157,6 +161,9 @@ public final class Bitstream implements BitstreamErrors { closeFrame(); // current_frame_number = -1; // last_frame_number = -1; + + br = new BitReserve(); + } /** @@ -370,6 +377,47 @@ public final class Bitstream implements BitstreamErrors { return get_bits(n); } + public int peek_bits(int number_of_bits) { + + int peekbitindex = bitindex; + int peekPointer = wordpointer; + + int returnvalue = 0; + int sum = peekbitindex + number_of_bits; + + if (peekPointer < 0) { + peekPointer = 0; + } + + if (sum <= 32) { + // all bits contained in *wordpointer + returnvalue = (framebuffer[peekPointer] >>> (32 - sum)) & bitmask[number_of_bits]; + // returnvalue = (wordpointer[0] >> (32 - sum)) & + // bitmask[number_of_bits]; + if ((peekbitindex += number_of_bits) == 32) { + peekbitindex = 0; + peekPointer++; // added by me! + } + return returnvalue; + } + + // E.B : Check that ? + // ((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; + // wordpointer++; // Added by me! + // ((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; + int Right = (framebuffer[peekPointer] & 0x0000FFFF); + peekPointer++; + int Left = (framebuffer[peekPointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16) & 0x0000FFFF); + + returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 + // - bitindex)) + returnvalue &= bitmask[number_of_bits]; + peekbitindex = sum - 32; + return returnvalue; + + } + public int readCheckedBits(int n) { // REVIEW: implement CRC check. return get_bits(n); @@ -505,7 +553,7 @@ public final class Bitstream implements BitstreamErrors { */ @LATTICE("OUT<RL,RL<THIS,THIS<IN,OUT*,THISLOC=THIS,RETURNLOC=OUT") public int get_bits(@LOC("IN") int number_of_bits) { - + @LOC("OUT") int returnvalue = 0; @LOC("THIS,Bitstream.BI") int sum = bitindex + number_of_bits; @@ -613,4 +661,70 @@ public final class Bitstream implements BitstreamErrors { } return totalBytesRead; } + + public SideInfoBuffer getSideInfoBuffer(int channelType) { + + if (wordpointer < 0) + wordpointer = 0; + + SideInfoBuffer sib = new SideInfoBuffer(); + + // first, store main_data_begin from the side inforamtion + main_data_begin = peek_bits(9); + System.out.println("main_data_begin=" + main_data_begin); + + int max; + if (channelType == 1) { // mono + max = wordpointer + 4; + } else { + max = wordpointer + 8; + } + + try { + for (; wordpointer < max; wordpointer++) { + sib.setBuffer(wordpointer, framebuffer[wordpointer]); + } + } catch (ArrayIndexOutOfBoundsException e) { + System.out.print("wordpointer=" + wordpointer); + System.out.println("framebuffer length=" + framebuffer.length); + } + + return sib; + } + + public BitReserve getBitReserve(int nSlots) { + + int flush_main; + int bytes_to_discard; + int i; + + for (i = 0; i < nSlots; i++) + br.hputbuf(get_bits(8)); + + int main_data_end = br.hsstell() >>> 3; // of previous frame + + if ((flush_main = (br.hsstell() & 7)) != 0) { + br.hgetbits(8 - flush_main); + main_data_end++; + } + + bytes_to_discard = frame_start - main_data_end - main_data_begin; + + frame_start += nSlots; + + if (bytes_to_discard < 0) { + System.out.println("HERE?"); + return null; + } + + if (main_data_end > 4096) { + frame_start -= 4096; + br.rewindNbytes(4096); + } + + for (; bytes_to_discard > 0; bytes_to_discard--) + br.hgetbits(8); + + return br; + } } diff --git a/Robust/src/Tests/ssJava/mp3decoder/Decoder.java b/Robust/src/Tests/ssJava/mp3decoder/Decoder.java index e871eec9..363e2dec 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/Decoder.java +++ b/Robust/src/Tests/ssJava/mp3decoder/Decoder.java @@ -248,8 +248,7 @@ public class Decoder implements DecoderErrors { case 3: if (l3decoder == null) { l3decoder = - new LayerIIIDecoder(stream, header, filter1, filter2, output, - OutputChannels.BOTH_CHANNELS); + new LayerIIIDecoder(header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS); } return l3decoder; diff --git a/Robust/src/Tests/ssJava/mp3decoder/Header.java b/Robust/src/Tests/ssJava/mp3decoder/Header.java index f4cef5c7..4ffcada4 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/Header.java +++ b/Robust/src/Tests/ssJava/mp3decoder/Header.java @@ -112,6 +112,9 @@ public final class Header { @LOC("T") private int _headerstring = -1; // E.B + private SideInfoBuffer sib; + private BitReserve br; + Header() { } @@ -802,4 +805,21 @@ public final class Header { public int intensity_stereo_bound() { return h_intensity_stereo_bound; } + + public void setSideInfoBuf(SideInfoBuffer sib) { + this.sib = sib; + } + + public void setBitReserve(BitReserve br) { + this.br = br; + } + + public SideInfoBuffer getSideInfoBuffer() { + return sib; + } + + public BitReserve getBitReserve() { + return br; + } + } diff --git a/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java b/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java index 50491701..055484bb 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java +++ b/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java @@ -72,8 +72,6 @@ final class LayerIIIDecoder implements FrameDecoder { private float[][] k; @LOC("NZ") private int[] nonzero; - @LOC("ST") - private Bitstream stream; @LOC("HD") private Header header; @LOC("FT") @@ -114,9 +112,8 @@ final class LayerIIIDecoder implements FrameDecoder { // REVIEW: these constructor arguments should be moved to the // decodeFrame() method, where possible, so that one @LATTICE("THIS<VAR,THIS<I,THIS<J,J<CH,I*,J*,CH*,THISLOC=THIS,GLOBALLOC=THIS") - public LayerIIIDecoder(@LOC("VAR") Bitstream stream0, @LOC("VAR") Header header0, - @LOC("VAR") SynthesisFilter filtera, @LOC("VAR") SynthesisFilter filterb, - @LOC("VAR") Obuffer buffer0, @LOC("VAR") int which_ch0) { + public LayerIIIDecoder(@LOC("VAR") Header header0, @LOC("VAR") SynthesisFilter filtera, + @LOC("VAR") SynthesisFilter filterb, @LOC("VAR") Obuffer buffer0, @LOC("VAR") int which_ch0) { huffcodetab.inithuff(); is_1d = new int[SBLIMIT * SSLIMIT + 4]; @@ -209,7 +206,6 @@ final class LayerIIIDecoder implements FrameDecoder { scalefac_buffer = new int[54]; // END OF scalefac_buffer - stream = stream0; header = header0; filter1 = filtera; filter2 = filterb; @@ -309,43 +305,9 @@ final class LayerIIIDecoder implements FrameDecoder { @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int bytes_to_discard; @LOC("C") int i; - get_side_info(); - - for (i = 0; i < nSlots; i++) { - br.hputbuf(stream.get_bits(8)); - // LOC(stream.get_bits)=DELTA[Loc[decode.THIS],Loc[LayerIIIDecoder.ST]] - // param should be higher than br - } - - main_data_end = br.hsstell() >>> 3; - - if ((flush_main = (br.hsstell() & 7)) != 0) { // flush_main < br - br.hgetbits(8 - flush_main); // br < flush_main - main_data_end++; // main_data_end* - } - - // bytes_to_discard < GLB(frame_start,main_data_end,si) - bytes_to_discard = frame_start - main_data_end - si.main_data_begin; - - // frame_start should be * - frame_start += nSlots; - - if (bytes_to_discard < 0) { - return; - } - - if (main_data_end > 4096) { // main_data_end should be > than 'frame_start' - // and 'br' - frame_start -= 4096; - br.rewindNbytes(4096); - } - - for (; bytes_to_discard > 0; bytes_to_discard--) { - // bytes_to_discard > br - br.hgetbits(8); - } - - // doing something from here + // modifications for linear type + get_side_info(header.getSideInfoBuffer()); + br = header.getBitReserve(); // here 'gr' and 'max_gr' should be higher than 'ch','channels', and more for (gr = 0; gr < max_gr; gr++) { // two granules per channel @@ -459,47 +421,48 @@ final class LayerIIIDecoder implements FrameDecoder { * Reads the side info from the stream, assuming the entire. frame has been * read already. Mono : 136 bits (= 17 bytes) Stereo : 256 bits (= 32 bytes) */ - @LATTICE("OUT<THIS,THISLOC=THIS,RETURNLOC=OUT") - private boolean get_side_info() { - - @LOC("THIS,LayerIIIDecoder.CH0") int ch; - @LOC("THIS,LayerIIIDecoder.CH0") int gr; - + private boolean get_side_info(SideInfoBuffer sib) { + int ch, gr; + // System.out.println("#get_side_info"); if (header.version() == Header.MPEG1) { - si.main_data_begin = stream.get_bits(9); - if (channels == 1) { - si.private_bits = stream.get_bits(5); - } else { - si.private_bits = stream.get_bits(3); - } + si.main_data_begin = sib.get_bits(9); + if (channels == 1) + si.private_bits = sib.get_bits(5); + else + si.private_bits = sib.get_bits(3); for (ch = 0; ch < channels; ch++) { - si.ch[ch].scfsi[0] = stream.get_bits(1); - si.ch[ch].scfsi[1] = stream.get_bits(1); - si.ch[ch].scfsi[2] = stream.get_bits(1); - si.ch[ch].scfsi[3] = stream.get_bits(1); + si.ch[ch].scfsi[0] = sib.get_bits(1); + si.ch[ch].scfsi[1] = sib.get_bits(1); + si.ch[ch].scfsi[2] = sib.get_bits(1); + si.ch[ch].scfsi[3] = sib.get_bits(1); } + // System.out.println("BEFORE GR,CH"); + for (gr = 0; gr < 2; gr++) { + // System.out.println("GR=" + gr); for (ch = 0; ch < channels; ch++) { - si.ch[ch].gr[gr].part2_3_length = stream.get_bits(12); - si.ch[ch].gr[gr].big_values = stream.get_bits(9); - si.ch[ch].gr[gr].global_gain = stream.get_bits(8); - si.ch[ch].gr[gr].scalefac_compress = stream.get_bits(4); - si.ch[ch].gr[gr].window_switching_flag = stream.get_bits(1); + // System.out.println("CH"); + si.ch[ch].gr[gr].part2_3_length = sib.get_bits(12); + si.ch[ch].gr[gr].big_values = sib.get_bits(9); + si.ch[ch].gr[gr].global_gain = sib.get_bits(8); + si.ch[ch].gr[gr].scalefac_compress = sib.get_bits(4); + si.ch[ch].gr[gr].window_switching_flag = sib.get_bits(1); if ((si.ch[ch].gr[gr].window_switching_flag) != 0) { - si.ch[ch].gr[gr].block_type = stream.get_bits(2); - si.ch[ch].gr[gr].mixed_block_flag = stream.get_bits(1); + si.ch[ch].gr[gr].block_type = sib.get_bits(2); + si.ch[ch].gr[gr].mixed_block_flag = sib.get_bits(1); - si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5); - si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5); + si.ch[ch].gr[gr].table_select[0] = sib.get_bits(5); + si.ch[ch].gr[gr].table_select[1] = sib.get_bits(5); - si.ch[ch].gr[gr].subblock_gain[0] = stream.get_bits(3); - si.ch[ch].gr[gr].subblock_gain[1] = stream.get_bits(3); - si.ch[ch].gr[gr].subblock_gain[2] = stream.get_bits(3); + si.ch[ch].gr[gr].subblock_gain[0] = sib.get_bits(3); + si.ch[ch].gr[gr].subblock_gain[1] = sib.get_bits(3); + si.ch[ch].gr[gr].subblock_gain[2] = sib.get_bits(3); - // Set region_count parameters since they are implicit in this case. + // Set region_count parameters since they are implicit + // in this case. if (si.ch[ch].gr[gr].block_type == 0) { // Side info bad: block_type == 0 in split block @@ -511,47 +474,48 @@ final class LayerIIIDecoder implements FrameDecoder { } si.ch[ch].gr[gr].region1_count = 20 - si.ch[ch].gr[gr].region0_count; } else { - si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5); - si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5); - si.ch[ch].gr[gr].table_select[2] = stream.get_bits(5); - si.ch[ch].gr[gr].region0_count = stream.get_bits(4); - si.ch[ch].gr[gr].region1_count = stream.get_bits(3); + si.ch[ch].gr[gr].table_select[0] = sib.get_bits(5); + si.ch[ch].gr[gr].table_select[1] = sib.get_bits(5); + si.ch[ch].gr[gr].table_select[2] = sib.get_bits(5); + si.ch[ch].gr[gr].region0_count = sib.get_bits(4); + si.ch[ch].gr[gr].region1_count = sib.get_bits(3); si.ch[ch].gr[gr].block_type = 0; } - si.ch[ch].gr[gr].preflag = stream.get_bits(1); - si.ch[ch].gr[gr].scalefac_scale = stream.get_bits(1); - si.ch[ch].gr[gr].count1table_select = stream.get_bits(1); + si.ch[ch].gr[gr].preflag = sib.get_bits(1); + si.ch[ch].gr[gr].scalefac_scale = sib.get_bits(1); + si.ch[ch].gr[gr].count1table_select = sib.get_bits(1); } } } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF - si.main_data_begin = stream.get_bits(8); + si.main_data_begin = sib.get_bits(8); if (channels == 1) - si.private_bits = stream.get_bits(1); + si.private_bits = sib.get_bits(1); else - si.private_bits = stream.get_bits(2); + si.private_bits = sib.get_bits(2); for (ch = 0; ch < channels; ch++) { - si.ch[ch].gr[0].part2_3_length = stream.get_bits(12); - si.ch[ch].gr[0].big_values = stream.get_bits(9); - si.ch[ch].gr[0].global_gain = stream.get_bits(8); - si.ch[ch].gr[0].scalefac_compress = stream.get_bits(9); - si.ch[ch].gr[0].window_switching_flag = stream.get_bits(1); + si.ch[ch].gr[0].part2_3_length = sib.get_bits(12); + si.ch[ch].gr[0].big_values = sib.get_bits(9); + si.ch[ch].gr[0].global_gain = sib.get_bits(8); + si.ch[ch].gr[0].scalefac_compress = sib.get_bits(9); + si.ch[ch].gr[0].window_switching_flag = sib.get_bits(1); if ((si.ch[ch].gr[0].window_switching_flag) != 0) { - si.ch[ch].gr[0].block_type = stream.get_bits(2); - si.ch[ch].gr[0].mixed_block_flag = stream.get_bits(1); - si.ch[ch].gr[0].table_select[0] = stream.get_bits(5); - si.ch[ch].gr[0].table_select[1] = stream.get_bits(5); + si.ch[ch].gr[0].block_type = sib.get_bits(2); + si.ch[ch].gr[0].mixed_block_flag = sib.get_bits(1); + si.ch[ch].gr[0].table_select[0] = sib.get_bits(5); + si.ch[ch].gr[0].table_select[1] = sib.get_bits(5); - si.ch[ch].gr[0].subblock_gain[0] = stream.get_bits(3); - si.ch[ch].gr[0].subblock_gain[1] = stream.get_bits(3); - si.ch[ch].gr[0].subblock_gain[2] = stream.get_bits(3); + si.ch[ch].gr[0].subblock_gain[0] = sib.get_bits(3); + si.ch[ch].gr[0].subblock_gain[1] = sib.get_bits(3); + si.ch[ch].gr[0].subblock_gain[2] = sib.get_bits(3); - // Set region_count parameters since they are implicit in this case. + // Set region_count parameters since they are implicit in + // this case. if (si.ch[ch].gr[0].block_type == 0) { // Side info bad: block_type == 0 in split block @@ -564,16 +528,16 @@ final class LayerIIIDecoder implements FrameDecoder { } } else { - si.ch[ch].gr[0].table_select[0] = stream.get_bits(5); - si.ch[ch].gr[0].table_select[1] = stream.get_bits(5); - si.ch[ch].gr[0].table_select[2] = stream.get_bits(5); - si.ch[ch].gr[0].region0_count = stream.get_bits(4); - si.ch[ch].gr[0].region1_count = stream.get_bits(3); + si.ch[ch].gr[0].table_select[0] = sib.get_bits(5); + si.ch[ch].gr[0].table_select[1] = sib.get_bits(5); + si.ch[ch].gr[0].table_select[2] = sib.get_bits(5); + si.ch[ch].gr[0].region0_count = sib.get_bits(4); + si.ch[ch].gr[0].region1_count = sib.get_bits(3); si.ch[ch].gr[0].block_type = 0; } - si.ch[ch].gr[0].scalefac_scale = stream.get_bits(1); - si.ch[ch].gr[0].count1table_select = stream.get_bits(1); + si.ch[ch].gr[0].scalefac_scale = sib.get_bits(1); + si.ch[ch].gr[0].count1table_select = sib.get_bits(1); } // for(ch=0; ch<channels; ch++) } // if (header.version() == MPEG1) return true; diff --git a/Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java b/Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java new file mode 100644 index 00000000..d3a3e1d5 --- /dev/null +++ b/Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java @@ -0,0 +1,85 @@ +public class SideInfoBuffer { + + /** + * The frame buffer that holds the data for the current frame. + */ + private final int[] framebuffer = new int[BUFFER_INT_SIZE]; + + /** + * Maximum size of the frame buffer. + */ + private static final int BUFFER_INT_SIZE = 433; + + /** + * Index into <code>framebuffer</code> where the next bits are retrieved. + */ + private int wordpointer; + + /** + * Number (0-31, from MSB to LSB) of next bit for get_bits() + */ + private int bitindex; + + private int main_data_begin; + + public int getMain_data_begin() { + return main_data_begin; + } + + public void setMain_data_begin(int main_data_begin) { + this.main_data_begin = main_data_begin; + } + + private final int bitmask[] = { + 0, // dummy + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, + 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, + 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, + 0x0000FFFF, 0x0001FFFF }; + + public int get_bits(int number_of_bits) { + int returnvalue = 0; + int sum = bitindex + number_of_bits; + // System.out.println("bitindex=" + bitindex + " wordpointer=" + // + wordpointer); + // E.B + // There is a problem here, wordpointer could be -1 ?! + if (wordpointer < 0) + wordpointer = 0; + // E.B : End. + + if (sum <= 32) { + // all bits contained in *wordpointer + returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) + & bitmask[number_of_bits]; + // returnvalue = (wordpointer[0] >> (32 - sum)) & + // bitmask[number_of_bits]; + if ((bitindex += number_of_bits) == 32) { + bitindex = 0; + wordpointer++; // added by me! + } + return returnvalue; + } + + // E.B : Check that ? + // ((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; + // wordpointer++; // Added by me! + // ((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; + int Right = (framebuffer[wordpointer] & 0x0000FFFF); + wordpointer++; + int Left = (framebuffer[wordpointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) + | ((Left >>> 16) & 0x0000FFFF); + + returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 + // - bitindex)) + returnvalue &= bitmask[number_of_bits]; + bitindex = sum - 32; + return returnvalue; + } + + public void setBuffer(int idx, int value) { + framebuffer[idx] = value; + } + +}