Index: trunk/cortado/src/com/fluendo/jheora/DCTDecode.java |
— | — | @@ -105,13 +105,16 @@ |
106 | 106 | /* Select the appropriate inverse Q matrix and line stride */ |
107 | 107 | if ( FragmentNumber<(int)pbi.YPlaneFragments ){ |
108 | 108 | ReconPixelsPerLine = pbi.YStride; |
109 | | - dequant_coeffs = pbi.dequant_Y_coeffs; |
| 109 | + // intra Y |
| 110 | + dequant_coeffs = pbi.info.dequant_tables[0][0][pbi.frameQIS[0]]; |
110 | 111 | }else if(FragmentNumber < pbi.YPlaneFragments + pbi.UVPlaneFragments) { |
111 | 112 | ReconPixelsPerLine = pbi.UVStride; |
112 | | - dequant_coeffs = pbi.dequant_U_coeffs; |
| 113 | + // intra U |
| 114 | + dequant_coeffs = pbi.info.dequant_tables[0][1][pbi.frameQIS[0]]; |
113 | 115 | } else { |
114 | 116 | ReconPixelsPerLine = pbi.UVStride; |
115 | | - dequant_coeffs = pbi.dequant_V_coeffs; |
| 117 | + // intra V |
| 118 | + dequant_coeffs = pbi.info.dequant_tables[0][2][pbi.frameQIS[0]]; |
116 | 119 | } |
117 | 120 | |
118 | 121 | /* Set up pointer into the quantisation buffer. */ |
— | — | @@ -174,9 +177,11 @@ |
175 | 178 | |
176 | 179 | /* Select appropriate dequantiser matrix. */ |
177 | 180 | if ( codingMode == CodingMode.CODE_INTRA ) |
178 | | - dequant_coeffs = pbi.dequant_Y_coeffs; |
| 181 | + // intra Y |
| 182 | + dequant_coeffs = pbi.info.dequant_tables[0][0][pbi.frameQIS[0]]; |
179 | 183 | else |
180 | | - dequant_coeffs = pbi.dequant_Inter_Y_coeffs; |
| 184 | + // inter Y |
| 185 | + dequant_coeffs = pbi.info.dequant_tables[1][0][pbi.frameQIS[0]]; |
181 | 186 | }else{ |
182 | 187 | ReconPixelsPerLine = pbi.UVStride; |
183 | 188 | MvShift = 2; |
— | — | @@ -186,14 +191,18 @@ |
187 | 192 | |
188 | 193 | if(FragmentNumber < pbi.YPlaneFragments + pbi.UVPlaneFragments) { |
189 | 194 | if ( codingMode == CodingMode.CODE_INTRA ) |
190 | | - dequant_coeffs = pbi.dequant_U_coeffs; |
| 195 | + // intra U |
| 196 | + dequant_coeffs = pbi.info.dequant_tables[0][1][pbi.frameQIS[0]]; |
191 | 197 | else |
192 | | - dequant_coeffs = pbi.dequant_Inter_U_coeffs; |
| 198 | + // inter U |
| 199 | + dequant_coeffs = pbi.info.dequant_tables[1][1][pbi.frameQIS[0]]; |
193 | 200 | } else { |
194 | 201 | if ( codingMode == CodingMode.CODE_INTRA ) |
195 | | - dequant_coeffs = pbi.dequant_V_coeffs; |
| 202 | + // intra V |
| 203 | + dequant_coeffs = pbi.info.dequant_tables[0][2][pbi.frameQIS[0]]; |
196 | 204 | else |
197 | | - dequant_coeffs = pbi.dequant_Inter_V_coeffs; |
| 205 | + // inter V |
| 206 | + dequant_coeffs = pbi.info.dequant_tables[1][2][pbi.frameQIS[0]]; |
198 | 207 | } |
199 | 208 | } |
200 | 209 | |
Index: trunk/cortado/src/com/fluendo/jheora/Decode.java |
— | — | @@ -136,10 +136,22 @@ |
137 | 137 | |
138 | 138 | /* Quality (Q) index */ |
139 | 139 | DctQMask = (int) opb.readB(6); |
| 140 | + pbi.frameQIS[0] = DctQMask; |
| 141 | + pbi.frameNQIS = 1; |
140 | 142 | |
141 | | - /* spare bit for possible additional Q indicies - should be 0 */ |
142 | | - opb.readB(1); |
143 | | - |
| 143 | + /* look if there are additional frame quality indices */ |
| 144 | + int moreQs = opb.readB(1); |
| 145 | + if(moreQs > 0) { |
| 146 | + pbi.frameQIS[1] = (int) opb.readB(6); |
| 147 | + pbi.frameNQIS = 2; |
| 148 | + |
| 149 | + moreQs = opb.readB(1); |
| 150 | + if(moreQs > 0) { |
| 151 | + pbi.frameQIS[2] = (int) opb.readB(6); |
| 152 | + pbi.frameNQIS = 3; |
| 153 | + } |
| 154 | + } |
| 155 | + |
144 | 156 | if ( (pbi.FrameType == Constants.BASE_FRAME) ){ |
145 | 157 | /* Read the type / coding method for the key frame. */ |
146 | 158 | pbi.KeyFrameType = (byte)opb.readB(1); |
— | — | @@ -147,7 +159,7 @@ |
148 | 160 | } |
149 | 161 | |
150 | 162 | /* Set this frame quality value from Q Index */ |
151 | | - pbi.ThisFrameQualityValue = pbi.QThreshTable[DctQMask]; |
| 163 | + //pbi.ThisFrameQualityValue = pbi.QThreshTable[pbi.frameQ]; |
152 | 164 | |
153 | 165 | /* Read in the updated block map */ |
154 | 166 | pbi.frArray.quadDecodeDisplayFragments( pbi ); |
— | — | @@ -349,15 +361,51 @@ |
350 | 362 | MVect5.y = MVC.extract(opb); |
351 | 363 | } |
352 | 364 | else if ( CodingMethod == CodingMode.CODE_INTER_FOURMV ){ |
| 365 | + |
| 366 | + /* Update last MV and prior last mv */ |
| 367 | + PriorLastInterMV.x = LastInterMV.x; |
| 368 | + PriorLastInterMV.y = LastInterMV.y; |
| 369 | + |
353 | 370 | /* Extrac the 4 Y MVs */ |
354 | | - x = MVect0.x = MVC.extract(opb); |
355 | | - y = MVect0.y = MVC.extract(opb); |
356 | | - x += MVect1.x = MVC.extract(opb); |
357 | | - y += MVect1.y = MVC.extract(opb); |
358 | | - x += MVect2.x = MVC.extract(opb); |
359 | | - y += MVect2.y = MVC.extract(opb); |
360 | | - x += MVect3.x = MVC.extract(opb); |
361 | | - y += MVect3.y = MVC.extract(opb); |
| 371 | + if(pbi.display_fragments[FragIndex] != 0) { |
| 372 | + x = MVect0.x = MVC.extract(opb); |
| 373 | + y = MVect0.y = MVC.extract(opb); |
| 374 | + LastInterMV.x = MVect0.x; |
| 375 | + LastInterMV.y = MVect0.y; |
| 376 | + } else { |
| 377 | + x = MVect0.x = 0; |
| 378 | + y = MVect0.y = 0; |
| 379 | + } |
| 380 | + |
| 381 | + if(pbi.display_fragments[FragIndex + 1] != 0) { |
| 382 | + x += MVect1.x = MVC.extract(opb); |
| 383 | + y += MVect1.y = MVC.extract(opb); |
| 384 | + LastInterMV.x = MVect1.x; |
| 385 | + LastInterMV.y = MVect1.y; |
| 386 | + } else { |
| 387 | + x += MVect1.x = 0; |
| 388 | + y += MVect1.y = 0; |
| 389 | + } |
| 390 | + |
| 391 | + if(pbi.display_fragments[FragIndex + pbi.HFragments] != 0) { |
| 392 | + x += MVect2.x = MVC.extract(opb); |
| 393 | + y += MVect2.y = MVC.extract(opb); |
| 394 | + LastInterMV.x = MVect2.x; |
| 395 | + LastInterMV.y = MVect2.y; |
| 396 | + } else { |
| 397 | + x += MVect2.x = 0; |
| 398 | + y += MVect2.y = 0; |
| 399 | + } |
| 400 | + |
| 401 | + if(pbi.display_fragments[FragIndex + pbi.HFragments + 1] != 0) { |
| 402 | + x += MVect3.x = MVC.extract(opb); |
| 403 | + y += MVect3.y = MVC.extract(opb); |
| 404 | + LastInterMV.x = MVect3.x; |
| 405 | + LastInterMV.y = MVect3.y; |
| 406 | + } else { |
| 407 | + x += MVect3.x = 0; |
| 408 | + y += MVect3.y = 0; |
| 409 | + } |
362 | 410 | /* Calculate the U and V plane MVs as the average of the |
363 | 411 | Y plane MVs. */ |
364 | 412 | /* First .x component */ |
— | — | @@ -371,11 +419,6 @@ |
372 | 420 | MVect4.y = y; |
373 | 421 | MVect5.y = y; |
374 | 422 | |
375 | | - /* Update last MV and prior last mv */ |
376 | | - PriorLastInterMV.x = LastInterMV.x; |
377 | | - PriorLastInterMV.y = LastInterMV.y; |
378 | | - LastInterMV.x = MVect3.x; |
379 | | - LastInterMV.y = MVect3.y; |
380 | 423 | } |
381 | 424 | else if ( CodingMethod == CodingMode.CODE_INTER_LAST_MV ){ |
382 | 425 | /* Use the last coded Inter motion vector. */ |
— | — | @@ -613,6 +656,10 @@ |
614 | 657 | } |
615 | 658 | } |
616 | 659 | |
| 660 | + public void decodeBlockLevelQi() { |
| 661 | + |
| 662 | + } |
| 663 | + |
617 | 664 | public int loadAndDecode() |
618 | 665 | { |
619 | 666 | int loadFrameOK; |
— | — | @@ -622,13 +669,7 @@ |
623 | 670 | |
624 | 671 | if (loadFrameOK != 0){ |
625 | 672 | //System.out.println("Load: "+loadFrameOK+" "+pbi.ThisFrameQualityValue+" "+pbi.LastFrameQualityValue); |
626 | | - |
627 | | - if ( (pbi.ThisFrameQualityValue != pbi.LastFrameQualityValue) ){ |
628 | | - /* Initialise DCT tables. */ |
629 | | - Quant.UpdateQ( pbi, pbi.ThisFrameQualityValue ); |
630 | | - pbi.LastFrameQualityValue = pbi.ThisFrameQualityValue; |
631 | | - } |
632 | | - |
| 673 | + |
633 | 674 | /* Decode the data into the fragment buffer. */ |
634 | 675 | /* Bail out immediately if a decode error has already been reported. */ |
635 | 676 | if (pbi.DecoderErrorCode != 0) |
Index: trunk/cortado/src/com/fluendo/jheora/Filter.java |
— | — | @@ -145,13 +145,8 @@ |
146 | 146 | |
147 | 147 | /* Set the limit value for the loop filter based upon the current |
148 | 148 | quantizer. */ |
149 | | - QIndex = Constants.Q_TABLE_SIZE - 1; |
150 | | - while ( QIndex >= 0 ) { |
151 | | - if ( (QIndex == 0) || |
152 | | - ( pbi.QThreshTable[QIndex] >= pbi.ThisFrameQualityValue) ) |
153 | | - break; |
154 | | - QIndex --; |
155 | | - } |
| 149 | + |
| 150 | + QIndex = pbi.frameQIS[0]; |
156 | 151 | |
157 | 152 | FLimit = LoopFilterLimits[QIndex]; |
158 | 153 | if ( FLimit == 0 ) return; |
Index: trunk/cortado/src/com/fluendo/jheora/Playback.java |
— | — | @@ -53,12 +53,16 @@ |
54 | 54 | int QualitySetting; |
55 | 55 | int FrameQIndex; /* Quality specified as a |
56 | 56 | table index */ |
57 | | - int ThisFrameQualityValue; /* Quality value for this frame */ |
58 | | - int LastFrameQualityValue; /* Last Frame's Quality */ |
| 57 | + //int ThisFrameQualityValue; /* Quality value for this frame */ |
| 58 | + //int LastFrameQualityValue; /* Last Frame's Quality */ |
59 | 59 | int CodedBlockIndex; /* Number of Coded Blocks */ |
60 | 60 | int CodedBlocksThisFrame; /* Index into coded blocks */ |
61 | 61 | int FrameSize; /* The number of bytes in the frame. */ |
| 62 | + |
| 63 | + int[] frameQIS = new int[3]; |
| 64 | + int frameNQIS; /* number of quality indices this frame uses */ |
62 | 65 | |
| 66 | + |
63 | 67 | /**********************************************************************/ |
64 | 68 | /* Frame Size & Index Information */ |
65 | 69 | |
— | — | @@ -148,63 +152,21 @@ |
149 | 153 | FrArray frArray = new FrArray(); |
150 | 154 | Filter filter = new Filter(); |
151 | 155 | |
152 | | - int[] QThreshTable = new int[Constants.Q_TABLE_SIZE]; |
153 | | - short[] DcScaleFactorTable = new short[Constants.Q_TABLE_SIZE]; |
154 | | - short[] Y_coeffs = new short[64]; |
155 | | - short[] U_coeffs = new short[64]; |
156 | | - short[] V_coeffs = new short[64]; |
157 | | - short[] Inter_Y_coeffs = new short[64]; |
158 | | - short[] Inter_U_coeffs = new short[64]; |
159 | | - short[] Inter_V_coeffs = new short[64]; |
| 156 | + |
| 157 | + /* quality index for each block */ |
| 158 | + byte[] blockQ; |
160 | 159 | |
161 | 160 | /* Dequantiser and rounding tables */ |
162 | | - short[] dequant_InterUV_coeffs; |
163 | 161 | int[] quant_index = new int[64]; |
164 | | - int[] quant_Y_coeffs = new int[64]; |
165 | | - int[] quant_UV_coeffs = new int[64]; |
166 | 162 | |
167 | 163 | HuffEntry[] HuffRoot_VP3x = new HuffEntry[Huffman.NUM_HUFF_TABLES]; |
168 | 164 | int[][] HuffCodeArray_VP3x; |
169 | 165 | byte[][] HuffCodeLengthArray_VP3x; |
170 | 166 | byte[] ExtraBitLengths_VP3x; |
| 167 | + |
171 | 168 | |
172 | | - /* Quantiser and rounding tables */ |
173 | | - short[] dequant_Y_coeffs; |
174 | | - short[] dequant_U_coeffs; |
175 | | - short[] dequant_V_coeffs; |
176 | | - short[] dequant_Inter_Y_coeffs; |
177 | | - short[] dequant_Inter_U_coeffs; |
178 | | - short[] dequant_Inter_V_coeffs; |
179 | | - short[] dequant_coeffs; |
180 | | - |
181 | | - public void clearTmpBuffers() |
182 | | - { |
183 | | - dequant_Y_coeffs = null; |
184 | | - dequant_U_coeffs = null; |
185 | | - dequant_V_coeffs = null; |
186 | | - dequant_Inter_Y_coeffs = null; |
187 | | - dequant_Inter_U_coeffs = null; |
188 | | - dequant_Inter_V_coeffs = null; |
189 | | - } |
190 | | - |
191 | | - private void initTmpBuffers() |
192 | | - { |
193 | | - |
194 | | - /* clear any existing info */ |
195 | | - clearTmpBuffers(); |
196 | | - |
197 | | - /* Adjust the position of all of our temporary */ |
198 | | - dequant_Y_coeffs = new short[64]; |
199 | | - dequant_U_coeffs = new short[64]; |
200 | | - dequant_V_coeffs = new short[64]; |
201 | | - dequant_Inter_Y_coeffs = new short[64]; |
202 | | - dequant_Inter_U_coeffs = new short[64]; |
203 | | - dequant_Inter_V_coeffs = new short[64]; |
204 | | - } |
205 | | - |
206 | 169 | public void clear() |
207 | 170 | { |
208 | | - clearTmpBuffers(); |
209 | 171 | if (opb != null) { |
210 | 172 | opb = null; |
211 | 173 | } |
— | — | @@ -225,8 +187,6 @@ |
226 | 188 | { |
227 | 189 | info = ci; |
228 | 190 | |
229 | | - initTmpBuffers(); |
230 | | - |
231 | 191 | DecoderErrorCode = 0; |
232 | 192 | KeyFrameType = DCT_KEY_FRAME; |
233 | 193 | FramesHaveBeenSkipped = 0; |
— | — | @@ -234,10 +194,9 @@ |
235 | 195 | FrInit.InitFrameDetails(this); |
236 | 196 | |
237 | 197 | keyframe_granule_shift = ilog(ci.keyframe_frequency_force-1); |
238 | | - LastFrameQualityValue = 0; |
| 198 | + //LastFrameQualityValue = 0; |
239 | 199 | |
240 | 200 | /* Initialise version specific quantiser and in-loop filter values */ |
241 | | - copyQTables(ci); |
242 | 201 | filter.copyFilterTables(ci); |
243 | 202 | |
244 | 203 | /* Huffman setup */ |
— | — | @@ -305,16 +264,4 @@ |
306 | 265 | HuffRoot_VP3x[i] = ci.HuffRoot[i].copy(); |
307 | 266 | } |
308 | 267 | } |
309 | | - |
310 | | - public void copyQTables(Info ci) { |
311 | | - System.arraycopy(ci.QThreshTable, 0, QThreshTable, 0, Constants.Q_TABLE_SIZE); |
312 | | - System.arraycopy(ci.DcScaleFactorTable, 0, DcScaleFactorTable, |
313 | | - 0, Constants.Q_TABLE_SIZE); |
314 | | - System.arraycopy(ci.Y_coeffs, 0, Y_coeffs, 0, 64); |
315 | | - System.arraycopy(ci.U_coeffs, 0, U_coeffs, 0, 64); |
316 | | - System.arraycopy(ci.V_coeffs, 0, V_coeffs, 0, 64); |
317 | | - System.arraycopy(ci.Inter_Y_coeffs, 0, Inter_Y_coeffs, 0, 64); |
318 | | - System.arraycopy(ci.Inter_U_coeffs, 0, Inter_U_coeffs, 0, 64); |
319 | | - System.arraycopy(ci.Inter_V_coeffs, 0, Inter_V_coeffs, 0, 64); |
320 | | - } |
321 | 268 | } |
Index: trunk/cortado/src/com/fluendo/jheora/Quant.java |
— | — | @@ -2,6 +2,7 @@ |
3 | 3 | * Copyright (C) 2004 Fluendo S.L. |
4 | 4 | * |
5 | 5 | * Written by: 2004 Wim Taymans <wim@fluendo.com> |
| 6 | + * 2008 Maik Merten <maikmerten@googlemail.com> |
6 | 7 | * |
7 | 8 | * Many thanks to |
8 | 9 | * The Xiph.Org Foundation http://www.xiph.org/ |
— | — | @@ -28,8 +29,7 @@ |
29 | 30 | |
30 | 31 | public class Quant |
31 | 32 | { |
32 | | - private static final int MIN_DEQUANT_VAL = 2; |
33 | | - private static final int IDCT_SCALE_FACTOR = 2; /* Shift left bits to improve IDCT precision */ |
| 33 | + |
34 | 34 | private static int ilog (long v) |
35 | 35 | { |
36 | 36 | int ret=0; |
— | — | @@ -41,334 +41,278 @@ |
42 | 42 | return ret; |
43 | 43 | } |
44 | 44 | |
45 | | - private static int _read_qtable_range(Info ci, Buffer opb, int N) |
46 | | - { |
47 | | - int range; |
48 | | - int qi = 0; |
| 45 | + public static int readQTables(Info ci, Buffer opb) { |
| 46 | + /* Variable names according to Theora spec where it makes sense. |
| 47 | + * I *know* this may violate Java coding style rules, but I consider |
| 48 | + * readability against the Theora spec to be more important */ |
| 49 | + |
| 50 | + long NBITS,value; |
| 51 | + int x, bmi, NBMS; |
49 | 52 | |
50 | | - opb.readB(ilog(N-1)); /* qi=0 index */ |
51 | | - while(qi<63) { |
52 | | - range = opb.readB(ilog(62-qi)); /* range to next code q matrix */ |
53 | | - range++; |
54 | | - if(range<=0) |
55 | | - return Result.BADHEADER; |
56 | | - qi+=range; |
57 | | - opb.readB(ilog(N-1)); /* next index */ |
| 53 | + /* A 2 × 3 array containing the number of quant ranges for a |
| 54 | + given qti and pli , respectively. This is at most 63. */ |
| 55 | + int[][] NQRS = new int[2][3]; |
| 56 | + |
| 57 | + /* A 2 × 3 × 63 array of the sizes of each quant range for a |
| 58 | + given qti and pli , respectively. Only the first NQRS[qti ][pli ] |
| 59 | + values are used. */ |
| 60 | + int[][][] QRSIZES = new int[2][3][63]; |
| 61 | + |
| 62 | + /* A 2 × 3 × 64 array of the bmi ’s used for each quant |
| 63 | + range for a given qti and pli, respectively. Only the first |
| 64 | + (NQRS[qti ][pli ] + 1) values are used. */ |
| 65 | + int[][][] QRBMIS = new int[2][3][64]; |
| 66 | + |
| 67 | + int qri, qi, qtj, plj; |
| 68 | + |
| 69 | + |
| 70 | + /* 1. Read a 4-bit unsigned integer. Assign NBITS the value read, plus one. */ |
| 71 | + NBITS = opb.readB(4); NBITS++; |
| 72 | + |
| 73 | + /* 2. For each consecutive value of qi from 0 to 63, inclusive: |
| 74 | + (a) Read an NBITS-bit unsigned integer as ACSCALE[qi ]. */ |
| 75 | + for(x=0; x < 64; x++) { |
| 76 | + value = opb.readB((int)NBITS); |
| 77 | + if(NBITS<0) return Result.BADHEADER; |
| 78 | + ci.AcScaleFactorTable[x]=(int)value; |
58 | 79 | } |
59 | | - |
60 | | - return 0; |
61 | | - } |
62 | | - |
63 | | - public static int readQTables(Info ci, Buffer opb) { |
64 | | - long bits,value; |
65 | | - int x,y, N; |
66 | | - //System.out.println("Reading Q tables..."); |
67 | | - /* AC scale table */ |
68 | | - bits = opb.readB(4); bits++; |
| 80 | + |
| 81 | + /* 3. Read a 4-bit unsigned integer. Assign NBITS the value read, plus one. */ |
| 82 | + NBITS = opb.readB(4); NBITS++; |
| 83 | + |
| 84 | + /* 4. For each consecutive value of qi from 0 to 63, inclusive: |
| 85 | + (a) Read an NBITS-bit unsigned integer as DCSCALE[qi ]. */ |
69 | 86 | for(x=0; x<Constants.Q_TABLE_SIZE; x++) { |
70 | | - value = opb.readB((int)bits); |
71 | | - if(bits<0)return Result.BADHEADER; |
72 | | - ci.QThreshTable[x]=(int)value; |
73 | | - //System.out.print(value+" "); |
74 | | - } |
75 | | - /* DC scale table */ |
76 | | - bits = opb.readB(4); bits++; |
77 | | - for(x=0; x<Constants.Q_TABLE_SIZE; x++) { |
78 | | - value = opb.readB((int)bits); |
79 | | - if(bits<0)return Result.BADHEADER; |
| 87 | + value = opb.readB((int)NBITS); |
| 88 | + if(NBITS<0) return Result.BADHEADER; |
80 | 89 | ci.DcScaleFactorTable[x]=(short)value; |
81 | 90 | } |
82 | | - /* base matricies */ |
83 | | - N = opb.readB(9); N++; |
84 | | - //System.out.println(" max q matrix index "+N); |
85 | 91 | |
86 | | - ci.qmats= new short[N*64]; |
87 | | - ci.MaxQMatrixIndex = N; |
88 | | - for(y=0; y<N; y++) { |
89 | | - //System.out.println("q matrix "+ y+": "); |
| 92 | + /* 5. Read a 9-bit unsigned integer. Assign NBMS the value decoded, plus |
| 93 | + one. NBMS MUST be no greater than 384. */ |
| 94 | + NBMS = opb.readB(9); NBMS++; |
| 95 | + if(NBMS > 384) { |
| 96 | + return Result.BADHEADER; |
| 97 | + } |
| 98 | + ci.MaxQMatrixIndex = NBMS; |
| 99 | + |
| 100 | + /* 6. For each consecutive value of bmi from 0 to (NBMS - 1), inclusive: |
| 101 | + (a) For each consecutive value of ci from 0 to 63, inclusive: |
| 102 | + i. Read an 8-bit unsigned integer as BMS[bmi ][ci ]. */ |
| 103 | + |
| 104 | + ci.qmats= new short[NBMS*64]; |
| 105 | + for(bmi=0; bmi<NBMS; bmi++) { |
90 | 106 | for(x=0; x<64; x++) { |
91 | 107 | value = opb.readB(8); |
92 | | - if(bits<0)return Result.BADHEADER; |
93 | | - ci.qmats[(y<<6)+x]=(short)value; |
94 | | - //System.out.print(value+" "); |
95 | | - //if((x+1)%8==0)System.out.println(); |
| 108 | + if(NBITS<0)return Result.BADHEADER; |
| 109 | + ci.qmats[(bmi<<6)+x]=(short)value; |
96 | 110 | } |
97 | | - //System.out.println(); |
98 | 111 | } |
99 | | - /* table mapping */ |
100 | | - { |
101 | | - int flag, ret; |
102 | | - /* intra Y */ |
103 | | - //System.out.print("\n Intra Y:"); |
104 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
105 | | - /* intra U */ |
106 | | - //System.out.print("\n Intra U:"); |
107 | | - flag = opb.readB(1); |
108 | | - if(flag<0) return Result.BADHEADER; |
109 | | - if(flag != 0) { |
110 | | - /* explicitly coded */ |
111 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
112 | | - } else { |
113 | | - /* same as previous */ |
114 | | - //System.out.print("same as above"); |
115 | | - } |
116 | | - /* intra V */ |
117 | | - //System.out.print("\n Intra V:"); |
118 | | - flag = opb.readB(1); |
119 | | - if(flag<0) return Result.BADHEADER; |
120 | | - if(flag != 0) { |
121 | | - /* explicitly coded */ |
122 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
123 | | - } else { |
124 | | - /* same as previous */ |
125 | | - //System.out.print("same as above"); |
126 | | - } |
127 | | - /* inter Y */ |
128 | | - //System.out.print("\n Inter Y:"); |
129 | | - flag = opb.readB(1); |
130 | | - if(flag<0) return Result.BADHEADER; |
131 | | - if(flag != 0) { |
132 | | - /* explicitly coded */ |
133 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
134 | | - } else { |
135 | | - flag = opb.readB(1); |
136 | | - if(flag<0) return Result.BADHEADER; |
137 | | - if(flag != 0) { |
138 | | - /* same as corresponding intra */ |
139 | | - //System.out.print("same as intra"); |
| 112 | + |
| 113 | + /* 7. For each consecutive value of qti from 0 to 1, inclusive: */ |
| 114 | + for(int qti = 0; qti <= 1; ++qti) { |
| 115 | + /* (a) For each consecutive value of pli from 0 to 2, inclusive: */ |
| 116 | + for(int pli = 0; pli <= 2; ++pli) { |
| 117 | + int NEWQR; |
| 118 | + if(qti > 0 || pli > 0) { |
| 119 | + /* i. If qti > 0 or pli > 0, read a 1-bit unsigned integer as NEWQR. */ |
| 120 | + NEWQR = opb.readB(1); |
140 | 121 | } else { |
141 | | - /* same as previous */ |
142 | | - //System.out.print("same as above"); |
| 122 | + /* ii. Else, assign NEWQR the value one. */ |
| 123 | + NEWQR = 1; |
143 | 124 | } |
144 | | - } |
145 | | - /* inter U */ |
146 | | - //System.out.print("\n Inter U:"); |
147 | | - flag = opb.readB(1); |
148 | | - if(flag<0) return Result.BADHEADER; |
149 | | - if(flag != 0) { |
150 | | - /* explicitly coded */ |
151 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
152 | | - } else { |
153 | | - flag = opb.readB(1); |
154 | | - if(flag<0) return Result.BADHEADER; |
155 | | - if(flag != 0) { |
156 | | - /* same as corresponding intra */ |
157 | | - //System.out.print("same as intra"); |
| 125 | + |
| 126 | + if(NEWQR == 0) { |
| 127 | + /* If NEWQR is zero, then we are copying a previously defined set |
| 128 | + of quant ranges. In that case: */ |
| 129 | + |
| 130 | + int RPQR; |
| 131 | + if(qti > 0) { |
| 132 | + /* A. If qti > 0, read a 1-bit unsigned integer as RPQR. */ |
| 133 | + RPQR = opb.readB(1); |
| 134 | + } else { |
| 135 | + /* B. Else, assign RPQR the value zero. */ |
| 136 | + RPQR = 0; |
| 137 | + } |
| 138 | + |
| 139 | + if(RPQR == 1) { |
| 140 | + /* C. If RPQR is one, assign qtj the value (qti - 1) and assign plj |
| 141 | + the value pli . This selects the set of quant ranges defined |
| 142 | + for the same color plane as this one, but for the previous |
| 143 | + quantization type. */ |
| 144 | + qtj = qti - 1; |
| 145 | + plj = pli; |
| 146 | + } else { |
| 147 | + /* D. Else assign qtj the value (3 * qti + pli - 1)//3 and assign plj |
| 148 | + the value (pli + 2)%3. This selects the most recent set of |
| 149 | + quant ranges defined. */ |
| 150 | + qtj = (3 * qti + pli - 1) / 3; |
| 151 | + plj = (pli + 2) % 3; |
| 152 | + } |
| 153 | + |
| 154 | + /* E. Assign NQRS[qti ][pli ] the value NQRS[qtj ][plj ]. */ |
| 155 | + NQRS[qti][pli] = NQRS[qtj][plj]; |
| 156 | + |
| 157 | + /* F. Assign QRSIZES[qti ][pli ] the values in QRSIZES[qtj ][plj ]. */ |
| 158 | + QRSIZES[qti][pli] = QRSIZES[qtj][plj]; |
| 159 | + |
| 160 | + /* G. Assign QRBMIS[qti ][pli ] the values in QRBMIS[qtj ][plj ]. */ |
| 161 | + QRBMIS[qti][pli] = QRBMIS[qtj][plj]; |
| 162 | + |
158 | 163 | } else { |
159 | | - /* same as previous */ |
160 | | - //System.out.print("same as above"); |
| 164 | + /* Else, NEWQR is one, which indicates that we are defining a new |
| 165 | + set of quant ranges. In that case: */ |
| 166 | + |
| 167 | + /*A. Assign qri the value zero. */ |
| 168 | + qri = 0; |
| 169 | + |
| 170 | + /*B. Assign qi the value zero. */ |
| 171 | + qi = 0; |
| 172 | + |
| 173 | + /* C. Read an ilog(NBMS - 1)-bit unsigned integer as |
| 174 | + QRBMIS[qti ][pli ][qri ]. If this is greater than or equal to |
| 175 | + NBMS, stop. The stream is undecodable. */ |
| 176 | + QRBMIS[qti][pli][qri] = opb.readB(ilog(NBMS - 1)); |
| 177 | + if(QRBMIS[qti][pli][qri] >= NBMS) { |
| 178 | + System.out.println("bad header (1)"); |
| 179 | + return Result.BADHEADER; |
| 180 | + } |
| 181 | + |
| 182 | + do { |
| 183 | + /* D. Read an ilog(62 - qi )-bit unsigned integer. Assign |
| 184 | + QRSIZES[qti ][pli ][qri ] the value read, plus one. */ |
| 185 | + QRSIZES[qti][pli][qri] = opb.readB(ilog(62 - qi)) + 1; |
| 186 | + |
| 187 | + /* E. Assign qi the value qi + QRSIZES[qti ][pli ][qri ]. */ |
| 188 | + qi = qi + QRSIZES[qti][pli][qri]; |
| 189 | + |
| 190 | + /* F. Assign qri the value qri + 1. */ |
| 191 | + qri = qri + 1; |
| 192 | + |
| 193 | + /* G. Read an ilog(NBMS - 1)-bit unsigned integer as |
| 194 | + QRBMIS[qti ][pli ][qri ]. */ |
| 195 | + QRBMIS[qti][pli][qri] = opb.readB(ilog(NBMS - 1)); |
| 196 | + |
| 197 | + /* H. If qi is less than 63, go back to step 7(a)ivD. */ |
| 198 | + } while(qi < 63); |
| 199 | + |
| 200 | + /* I. If qi is greater than 63, stop. The stream is undecodable. */ |
| 201 | + if(qi > 63) { |
| 202 | + System.out.println("bad header (2): " + qi); |
| 203 | + return Result.BADHEADER; |
| 204 | + } |
| 205 | + |
| 206 | + /* J. Assign NQRS[qti ][pli ] the value qri . */ |
| 207 | + NQRS[qti][pli] = qri; |
161 | 208 | } |
162 | 209 | } |
163 | | - /* inter V */ |
164 | | - //System.out.print("n Inter V:"); |
165 | | - flag = opb.readB(1); |
166 | | - if(flag<0) return Result.BADHEADER; |
167 | | - if(flag != 0) { |
168 | | - /* explicitly coded */ |
169 | | - if((ret=_read_qtable_range(ci,opb,N))<0) return ret; |
170 | | - } else { |
171 | | - flag = opb.readB(1); |
172 | | - if(flag<0) return Result.BADHEADER; |
173 | | - if(flag != 0) { |
174 | | - /* same as corresponding intra */ |
175 | | - //System.out.print("same as intra"); |
176 | | - } else { |
177 | | - /* same as previous */ |
178 | | - //System.out.print("same as above"); |
| 210 | + } |
| 211 | + |
| 212 | + /* Compute all 384 matrices */ |
| 213 | + for(int coding = 0; coding < 2; ++coding) { |
| 214 | + for(int plane = 0; plane < 3; ++plane) { |
| 215 | + for(int quality = 0; quality < 64; ++quality) { |
| 216 | + short[] scaledmat = compQuantMatrix(ci.AcScaleFactorTable, ci.DcScaleFactorTable, ci.qmats, NQRS, QRSIZES, QRBMIS, coding, plane, quality); |
| 217 | + for(int coeff = 0; coeff < 64; ++coeff) { |
| 218 | + int j = Constants.dequant_index[coeff]; |
| 219 | + ci.dequant_tables[coding][plane][quality][coeff] = scaledmat[j]; |
| 220 | + } |
179 | 221 | } |
180 | 222 | } |
181 | | - //System.out.println(); |
182 | 223 | } |
183 | | - |
184 | | - /* ignore the range table and reference the matricies we use */ |
185 | | - |
186 | | - if(N == 3) { |
187 | | - System.arraycopy(ci.qmats, 0, ci.Y_coeffs, 0, 64); |
188 | | - System.arraycopy(ci.qmats, 64, ci.U_coeffs, 0, 64); |
189 | | - System.arraycopy(ci.qmats, 64, ci.V_coeffs, 0, 64); |
190 | | - System.arraycopy(ci.qmats, 2*64, ci.Inter_Y_coeffs, 0, 64); |
191 | | - System.arraycopy(ci.qmats, 2*64, ci.Inter_U_coeffs, 0, 64); |
192 | | - System.arraycopy(ci.qmats, 2*64, ci.Inter_V_coeffs, 0, 64); |
193 | | - } else if(N == 6) { |
194 | | - System.arraycopy(ci.qmats, 0, ci.Y_coeffs, 0, 64); |
195 | | - System.arraycopy(ci.qmats, 64, ci.U_coeffs, 0, 64); |
196 | | - System.arraycopy(ci.qmats, 2*64, ci.V_coeffs, 0, 64); |
197 | | - System.arraycopy(ci.qmats, 3*64, ci.Inter_Y_coeffs, 0, 64); |
198 | | - System.arraycopy(ci.qmats, 4*64, ci.Inter_U_coeffs, 0, 64); |
199 | | - System.arraycopy(ci.qmats, 5*64, ci.Inter_V_coeffs, 0, 64); |
200 | | - } else return Result.BADHEADER; |
201 | 224 | |
202 | 225 | return 0; |
203 | 226 | } |
| 227 | + |
| 228 | + static short[] compQuantMatrix(int[] ACSCALE, short[] DCSCALE, short[] BMS, int[][] NQRS, |
| 229 | + int[][][] QRSIZES, int[][][] QRBMIS, int qti, int pli, int qi) { |
204 | 230 | |
205 | | - static void BuildQuantIndex_Generic(Playback pbi){ |
206 | | - int i,j; |
207 | | - |
208 | | - /* invert the dequant index into the quant index */ |
209 | | - for ( i = 0; i < Constants.BLOCK_SIZE; i++ ){ |
210 | | - j = Constants.dequant_index[i]; |
211 | | - pbi.quant_index[j] = i; |
| 231 | + /* Variable names according to Theora spec where it makes sense. |
| 232 | + * I *know* this may violate Java coding style rules, but I consider |
| 233 | + * readability against the Theora spec to be more important */ |
| 234 | + |
| 235 | + short[] QMAT = new short[64]; |
| 236 | + int qri, qrj; |
| 237 | + /* 1. Assign qri the index of a quant range such that |
| 238 | + \qi \ge \sum_{\qrj=0}^{\qri-1} QRSIZES[\qti][\pli][\qrj], |
| 239 | + and |
| 240 | + \qi \le \sum_{\qrj=0}^{\qri} QRSIZES[\qti][\pli][\qrj], |
| 241 | + */ |
| 242 | + for(qri = 0; qri < 63; ++qri) { |
| 243 | + int sum1 = 0; |
| 244 | + for(qrj = 0; qrj < qri; ++qrj) { |
| 245 | + sum1 += QRSIZES[qti][pli][qrj]; |
| 246 | + } |
| 247 | + |
| 248 | + int sum2 = 0; |
| 249 | + for(qrj = 0; qrj <= qri; ++qrj) { |
| 250 | + sum2 += QRSIZES[qti][pli][qrj]; |
| 251 | + } |
| 252 | + |
| 253 | + if(qi >= sum1 && qi <= sum2) |
| 254 | + break; |
212 | 255 | } |
213 | | - } |
214 | | - |
215 | | - static void init_dequantizer (Playback pbi, |
216 | | - int scale_factor, |
217 | | - byte QIndex ){ |
218 | | - int i, j; |
219 | | - |
220 | | - |
221 | | - short[] Y_coeffs; |
222 | | - short[] U_coeffs; |
223 | | - short[] V_coeffs; |
224 | | - short[] Inter_Y_coeffs; |
225 | | - short[] Inter_U_coeffs; |
226 | | - short[] Inter_V_coeffs; |
227 | | - short[] DcScaleFactorTable; |
228 | | - short[] UVDcScaleFactorTable; |
229 | | - |
230 | | - Y_coeffs = pbi.Y_coeffs; |
231 | | - U_coeffs = pbi.U_coeffs; |
232 | | - V_coeffs = pbi.V_coeffs; |
233 | | - Inter_Y_coeffs = pbi.Inter_Y_coeffs; |
234 | | - Inter_U_coeffs = pbi.Inter_U_coeffs; |
235 | | - Inter_V_coeffs = pbi.Inter_V_coeffs; |
236 | | - |
237 | | - |
238 | | - DcScaleFactorTable = pbi.DcScaleFactorTable; |
239 | | - UVDcScaleFactorTable = pbi.DcScaleFactorTable; |
240 | | - |
241 | | - /* invert the dequant index into the quant index |
242 | | - the dxer has a different order than the cxer. */ |
243 | | - BuildQuantIndex_Generic(pbi); |
244 | | - |
245 | | - /* Reorder dequantisation coefficients into dct zigzag order. */ |
246 | | - for ( i = 0; i < Constants.BLOCK_SIZE; i++ ) { |
247 | | - j = pbi.quant_index[i]; |
248 | | - pbi.dequant_Y_coeffs[j] = Y_coeffs[i]; |
249 | | - pbi.dequant_U_coeffs[j] = U_coeffs[i]; |
250 | | - pbi.dequant_V_coeffs[j] = V_coeffs[i]; |
251 | | - pbi.dequant_Inter_Y_coeffs[j] = Inter_Y_coeffs[i]; |
252 | | - pbi.dequant_Inter_U_coeffs[j] = Inter_U_coeffs[i]; |
253 | | - pbi.dequant_Inter_V_coeffs[j] = Inter_V_coeffs[i]; |
254 | | - |
| 256 | + |
| 257 | + /* 2. Assign QISTART the value |
| 258 | + \sum_{\qrj=0}^{\qri-1} QRSIZES[\qti][\pli][\qrj]. |
| 259 | + */ |
| 260 | + int QISTART = 0; |
| 261 | + for(qrj = 0; qrj < qri; ++qrj) { |
| 262 | + QISTART += QRSIZES[qti][pli][qrj]; |
255 | 263 | } |
256 | | - |
257 | | - /* Intra Y */ |
258 | | - pbi.dequant_Y_coeffs[0] = (short) |
259 | | - ((DcScaleFactorTable[QIndex] * pbi.dequant_Y_coeffs[0])/100); |
260 | | - if ( pbi.dequant_Y_coeffs[0] < MIN_DEQUANT_VAL * 2 ) |
261 | | - pbi.dequant_Y_coeffs[0] = MIN_DEQUANT_VAL * 2; |
262 | | - pbi.dequant_Y_coeffs[0] = (short) |
263 | | - (pbi.dequant_Y_coeffs[0] << IDCT_SCALE_FACTOR); |
264 | | - |
265 | | - /* Intra U */ |
266 | | - pbi.dequant_U_coeffs[0] = (short) |
267 | | - ((UVDcScaleFactorTable[QIndex] * pbi.dequant_U_coeffs[0])/100); |
268 | | - if ( pbi.dequant_U_coeffs[0] < MIN_DEQUANT_VAL * 2 ) |
269 | | - pbi.dequant_U_coeffs[0] = MIN_DEQUANT_VAL * 2; |
270 | | - pbi.dequant_U_coeffs[0] = (short) |
271 | | - (pbi.dequant_U_coeffs[0] << IDCT_SCALE_FACTOR); |
272 | | - |
273 | | - /* Intra V */ |
274 | | - pbi.dequant_V_coeffs[0] = (short) |
275 | | - ((UVDcScaleFactorTable[QIndex] * pbi.dequant_V_coeffs[0])/100); |
276 | | - if ( pbi.dequant_V_coeffs[0] < MIN_DEQUANT_VAL * 2 ) |
277 | | - pbi.dequant_V_coeffs[0] = MIN_DEQUANT_VAL * 2; |
278 | | - pbi.dequant_V_coeffs[0] = (short) |
279 | | - (pbi.dequant_V_coeffs[0] << IDCT_SCALE_FACTOR); |
280 | | - |
281 | | - /* Inter Y */ |
282 | | - pbi.dequant_Inter_Y_coeffs[0] = (short) |
283 | | - ((DcScaleFactorTable[QIndex] * pbi.dequant_Inter_Y_coeffs[0])/100); |
284 | | - if ( pbi.dequant_Inter_Y_coeffs[0] < MIN_DEQUANT_VAL * 4 ) |
285 | | - pbi.dequant_Inter_Y_coeffs[0] = MIN_DEQUANT_VAL * 4; |
286 | | - pbi.dequant_Inter_Y_coeffs[0] = (short) |
287 | | - (pbi.dequant_Inter_Y_coeffs[0] << IDCT_SCALE_FACTOR); |
288 | | - |
289 | | - /* Inter U */ |
290 | | - pbi.dequant_Inter_U_coeffs[0] = (short) |
291 | | - ((UVDcScaleFactorTable[QIndex] * pbi.dequant_Inter_U_coeffs[0])/100); |
292 | | - if ( pbi.dequant_Inter_U_coeffs[0] < MIN_DEQUANT_VAL * 4 ) |
293 | | - pbi.dequant_Inter_U_coeffs[0] = MIN_DEQUANT_VAL * 4; |
294 | | - pbi.dequant_Inter_U_coeffs[0] = (short) |
295 | | - (pbi.dequant_Inter_U_coeffs[0] << IDCT_SCALE_FACTOR); |
296 | | - |
297 | | - /* Inter V */ |
298 | | - pbi.dequant_Inter_V_coeffs[0] = (short) |
299 | | - ((UVDcScaleFactorTable[QIndex] * pbi.dequant_Inter_V_coeffs[0])/100); |
300 | | - if ( pbi.dequant_Inter_V_coeffs[0] < MIN_DEQUANT_VAL * 4 ) |
301 | | - pbi.dequant_Inter_V_coeffs[0] = MIN_DEQUANT_VAL * 4; |
302 | | - pbi.dequant_Inter_V_coeffs[0] = (short) |
303 | | - (pbi.dequant_Inter_V_coeffs[0] << IDCT_SCALE_FACTOR); |
304 | | - |
305 | | - for ( i = 1; i < 64; i++ ){ |
306 | | - /* now scale coefficients by required compression factor */ |
307 | | - pbi.dequant_Y_coeffs[i] = (short) |
308 | | - (( scale_factor * pbi.dequant_Y_coeffs[i] ) / 100); |
309 | | - if ( pbi.dequant_Y_coeffs[i] < MIN_DEQUANT_VAL ) |
310 | | - pbi.dequant_Y_coeffs[i] = MIN_DEQUANT_VAL; |
311 | | - pbi.dequant_Y_coeffs[i] = (short) |
312 | | - (pbi.dequant_Y_coeffs[i] << IDCT_SCALE_FACTOR); |
313 | | - |
314 | | - pbi.dequant_U_coeffs[i] = (short) |
315 | | - (( scale_factor * pbi.dequant_U_coeffs[i] ) / 100); |
316 | | - if ( pbi.dequant_U_coeffs[i] < MIN_DEQUANT_VAL ) |
317 | | - pbi.dequant_U_coeffs[i] = MIN_DEQUANT_VAL; |
318 | | - pbi.dequant_U_coeffs[i] = (short) |
319 | | - (pbi.dequant_U_coeffs[i] << IDCT_SCALE_FACTOR); |
320 | 264 | |
321 | | - pbi.dequant_V_coeffs[i] = (short) |
322 | | - (( scale_factor * pbi.dequant_V_coeffs[i] ) / 100); |
323 | | - if ( pbi.dequant_V_coeffs[i] < MIN_DEQUANT_VAL ) |
324 | | - pbi.dequant_V_coeffs[i] = MIN_DEQUANT_VAL; |
325 | | - pbi.dequant_V_coeffs[i] = (short) |
326 | | - (pbi.dequant_V_coeffs[i] << IDCT_SCALE_FACTOR); |
327 | | - |
328 | | - pbi.dequant_Inter_Y_coeffs[i] = (short) |
329 | | - (( scale_factor * pbi.dequant_Inter_Y_coeffs[i] ) / 100); |
330 | | - if ( pbi.dequant_Inter_Y_coeffs[i] < (MIN_DEQUANT_VAL * 2) ) |
331 | | - pbi.dequant_Inter_Y_coeffs[i] = MIN_DEQUANT_VAL * 2; |
332 | | - pbi.dequant_Inter_Y_coeffs[i] = (short) |
333 | | - (pbi.dequant_Inter_Y_coeffs[i] << IDCT_SCALE_FACTOR); |
334 | | - |
335 | | - pbi.dequant_Inter_U_coeffs[i] = (short) |
336 | | - (( scale_factor * pbi.dequant_Inter_U_coeffs[i] ) / 100); |
337 | | - if ( pbi.dequant_Inter_U_coeffs[i] < (MIN_DEQUANT_VAL * 2) ) |
338 | | - pbi.dequant_Inter_U_coeffs[i] = MIN_DEQUANT_VAL * 2; |
339 | | - pbi.dequant_Inter_U_coeffs[i] = (short) |
340 | | - (pbi.dequant_Inter_U_coeffs[i] << IDCT_SCALE_FACTOR); |
341 | | - |
342 | | - pbi.dequant_Inter_V_coeffs[i] = (short) |
343 | | - (( scale_factor * pbi.dequant_Inter_V_coeffs[i] ) / 100); |
344 | | - if ( pbi.dequant_Inter_V_coeffs[i] < (MIN_DEQUANT_VAL * 2) ) |
345 | | - pbi.dequant_Inter_V_coeffs[i] = MIN_DEQUANT_VAL * 2; |
346 | | - pbi.dequant_Inter_V_coeffs[i] = (short) |
347 | | - (pbi.dequant_Inter_V_coeffs[i] << IDCT_SCALE_FACTOR); |
348 | | - |
349 | | - |
| 265 | + /* 3. Assign QIEND the value |
| 266 | + \sum_{\qrj=0}^{\qri} QRSIZES[\qti][\pli][\qrj]. |
| 267 | + */ |
| 268 | + int QIEND = 0; |
| 269 | + for(qrj = 0; qrj <= qri; ++qrj) { |
| 270 | + QIEND += QRSIZES[qti][pli][qrj]; |
350 | 271 | } |
351 | | - } |
352 | | - |
353 | | - public static void UpdateQ(Playback pbi, int NewQ ){ |
354 | | - int qscale; |
355 | | - |
356 | | - /* Do bounds checking. */ |
357 | | - qscale = NewQ; |
358 | | - if ( qscale < pbi.QThreshTable[Constants.Q_TABLE_SIZE-1] ) |
359 | | - qscale = pbi.QThreshTable[Constants.Q_TABLE_SIZE-1]; |
360 | | - else if ( qscale > pbi.QThreshTable[0] ) |
361 | | - qscale = pbi.QThreshTable[0]; |
362 | | - |
363 | | - /* Set the inter/intra descision control variables. */ |
364 | | - pbi.FrameQIndex = Constants.Q_TABLE_SIZE - 1; |
365 | | - while ( (int) pbi.FrameQIndex >= 0 ) { |
366 | | - if ( (pbi.FrameQIndex == 0) || |
367 | | - ( pbi.QThreshTable[pbi.FrameQIndex] >= NewQ) ) |
368 | | - break; |
369 | | - pbi.FrameQIndex --; |
| 272 | + |
| 273 | + /* 4. Assign bmi the value QRBMIS[qti ][pli ][qri ]. */ |
| 274 | + int bmi = QRBMIS[qti][pli][qri]; |
| 275 | + |
| 276 | + /* 5. Assign bmj the value QRBMIS[qti ][pli ][qri + 1]. */ |
| 277 | + int bmj = QRBMIS[qti][pli][qri + 1]; |
| 278 | + |
| 279 | + int[] BM = new int[64]; |
| 280 | + int QMIN; |
| 281 | + /* 6. For each consecutive value of ci from 0 to 63, inclusive: */ |
| 282 | + for(int ci = 0; ci < 64; ++ci) { |
| 283 | + /* (a) Assign BM[ci ] the value |
| 284 | + (2 ∗ (QIEND − qi ) ∗ BMS[bmi ][ci ] |
| 285 | + + 2 ∗ (qi − QISTART) ∗ BMS[bmj ][ci ] |
| 286 | + + QRSIZES[qti ][pli ][qri ])//(2 ∗ QRSIZES[qti ][pli ][qri ]) */ |
| 287 | + BM[ci] = (2 * (QIEND - qi) * BMS[(bmi<<6) + ci] |
| 288 | + + 2 * (qi - QISTART) * BMS[(bmj<<6) + ci] |
| 289 | + + QRSIZES[qti][pli][qri]) / (2 * QRSIZES[qti][pli][qri]); |
| 290 | + |
| 291 | + /* (b) Assign QMIN the value given by Table 6.18 according to qti and ci . */ |
| 292 | + if(ci == 0 && qti == 0) |
| 293 | + QMIN = 16; |
| 294 | + else if(ci > 0 && qti == 0) |
| 295 | + QMIN = 8; |
| 296 | + else if(ci == 0 && qti == 1) |
| 297 | + QMIN = 32; |
| 298 | + else |
| 299 | + QMIN = 16; |
| 300 | + |
| 301 | + int QSCALE; |
| 302 | + if(ci == 0) { |
| 303 | + /* (c) If ci equals zero, assign QSCALE the value DCSCALE[qi ]. */ |
| 304 | + QSCALE = DCSCALE[qi]; |
| 305 | + } else { |
| 306 | + /* (d) Else, assign QSCALE the value ACSCALE[qi ]. */ |
| 307 | + QSCALE = ACSCALE[qi]; |
| 308 | + } |
| 309 | + |
| 310 | + /*(e) Assign QMAT[ci ] the value |
| 311 | + max(QMIN, min((QSCALE ∗ BM[ci ]//100) ∗ 4, 4096)). */ |
| 312 | + |
| 313 | + QMAT[ci] = (short)Math.max(QMIN, Math.min((QSCALE * BM[ci]/100) * 4,4096)); |
370 | 314 | } |
371 | | - |
372 | | - /* Re-initialise the q tables for forward and reverse transforms. */ |
373 | | - init_dequantizer (pbi, qscale, (byte)pbi.FrameQIndex ); |
| 315 | + |
| 316 | + return QMAT; |
374 | 317 | } |
375 | | -} |
| 318 | + |
| 319 | +} |
\ No newline at end of file |
Index: trunk/cortado/src/com/fluendo/jheora/Info.java |
— | — | @@ -50,16 +50,12 @@ |
51 | 51 | public long keyframe_frequency_force; |
52 | 52 | |
53 | 53 | /* codec_setup_info */ |
54 | | - int[] QThreshTable = new int[Constants.Q_TABLE_SIZE]; |
| 54 | + short[][][][] dequant_tables = new short[2][3][64][64]; |
| 55 | + int[] AcScaleFactorTable = new int[Constants.Q_TABLE_SIZE]; |
55 | 56 | short[] DcScaleFactorTable = new short[Constants.Q_TABLE_SIZE]; |
56 | 57 | int MaxQMatrixIndex; |
57 | 58 | short[] qmats; |
58 | | - short[] Y_coeffs = new short[64]; |
59 | | - short[] U_coeffs = new short[64]; |
60 | | - short[] V_coeffs = new short[64]; |
61 | | - short[] Inter_Y_coeffs = new short[64]; |
62 | | - short[] Inter_U_coeffs = new short[64]; |
63 | | - short[] Inter_V_coeffs = new short[64]; |
| 59 | + |
64 | 60 | HuffEntry[] HuffRoot = new HuffEntry[Huffman.NUM_HUFF_TABLES]; |
65 | 61 | byte[] LoopFilterLimitValues = new byte[Constants.Q_TABLE_SIZE]; |
66 | 62 | |