r39769 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r39768‎ | r39769 | r39770 >
Date:15:48, 21 August 2008
Author:maikmerten
Status:old
Tags:
Comment:
Uh, hello, first commit here. This is a rather big patch to make jheora more spec-compliant
- basically complete rewrite how quantization matrices are computed (interpolation, scaling etc.)
- handle 4MV for partially coded macro blocks according to spec. This enables playback of Thusnelda-encoded streams.
- first parts of per-block quantizer handling (read which quantizers are used within a frame)
- less copying of quant matrices, compute all 384 matrices *once*, thus don't recompute used matrices per-frame
Modified paths:
  • /trunk/cortado/src/com/fluendo/jheora/DCTDecode.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jheora/Decode.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jheora/Filter.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jheora/Info.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jheora/Playback.java (modified) (history)
  • /trunk/cortado/src/com/fluendo/jheora/Quant.java (modified) (history)

Diff [purge]

Index: trunk/cortado/src/com/fluendo/jheora/DCTDecode.java
@@ -105,13 +105,16 @@
106106 /* Select the appropriate inverse Q matrix and line stride */
107107 if ( FragmentNumber<(int)pbi.YPlaneFragments ){
108108 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]];
110111 }else if(FragmentNumber < pbi.YPlaneFragments + pbi.UVPlaneFragments) {
111112 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]];
113115 } else {
114116 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]];
116119 }
117120
118121 /* Set up pointer into the quantisation buffer. */
@@ -174,9 +177,11 @@
175178
176179 /* Select appropriate dequantiser matrix. */
177180 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]];
179183 else
180 - dequant_coeffs = pbi.dequant_Inter_Y_coeffs;
 184+ // inter Y
 185+ dequant_coeffs = pbi.info.dequant_tables[1][0][pbi.frameQIS[0]];
181186 }else{
182187 ReconPixelsPerLine = pbi.UVStride;
183188 MvShift = 2;
@@ -186,14 +191,18 @@
187192
188193 if(FragmentNumber < pbi.YPlaneFragments + pbi.UVPlaneFragments) {
189194 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]];
191197 else
192 - dequant_coeffs = pbi.dequant_Inter_U_coeffs;
 198+ // inter U
 199+ dequant_coeffs = pbi.info.dequant_tables[1][1][pbi.frameQIS[0]];
193200 } else {
194201 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]];
196204 else
197 - dequant_coeffs = pbi.dequant_Inter_V_coeffs;
 205+ // inter V
 206+ dequant_coeffs = pbi.info.dequant_tables[1][2][pbi.frameQIS[0]];
198207 }
199208 }
200209
Index: trunk/cortado/src/com/fluendo/jheora/Decode.java
@@ -136,10 +136,22 @@
137137
138138 /* Quality (Q) index */
139139 DctQMask = (int) opb.readB(6);
 140+ pbi.frameQIS[0] = DctQMask;
 141+ pbi.frameNQIS = 1;
140142
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+
144156 if ( (pbi.FrameType == Constants.BASE_FRAME) ){
145157 /* Read the type / coding method for the key frame. */
146158 pbi.KeyFrameType = (byte)opb.readB(1);
@@ -147,7 +159,7 @@
148160 }
149161
150162 /* Set this frame quality value from Q Index */
151 - pbi.ThisFrameQualityValue = pbi.QThreshTable[DctQMask];
 163+ //pbi.ThisFrameQualityValue = pbi.QThreshTable[pbi.frameQ];
152164
153165 /* Read in the updated block map */
154166 pbi.frArray.quadDecodeDisplayFragments( pbi );
@@ -349,15 +361,51 @@
350362 MVect5.y = MVC.extract(opb);
351363 }
352364 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+
353370 /* 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+ }
362410 /* Calculate the U and V plane MVs as the average of the
363411 Y plane MVs. */
364412 /* First .x component */
@@ -371,11 +419,6 @@
372420 MVect4.y = y;
373421 MVect5.y = y;
374422
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;
380423 }
381424 else if ( CodingMethod == CodingMode.CODE_INTER_LAST_MV ){
382425 /* Use the last coded Inter motion vector. */
@@ -613,6 +656,10 @@
614657 }
615658 }
616659
 660+ public void decodeBlockLevelQi() {
 661+
 662+ }
 663+
617664 public int loadAndDecode()
618665 {
619666 int loadFrameOK;
@@ -622,13 +669,7 @@
623670
624671 if (loadFrameOK != 0){
625672 //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+
633674 /* Decode the data into the fragment buffer. */
634675 /* Bail out immediately if a decode error has already been reported. */
635676 if (pbi.DecoderErrorCode != 0)
Index: trunk/cortado/src/com/fluendo/jheora/Filter.java
@@ -145,13 +145,8 @@
146146
147147 /* Set the limit value for the loop filter based upon the current
148148 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];
156151
157152 FLimit = LoopFilterLimits[QIndex];
158153 if ( FLimit == 0 ) return;
Index: trunk/cortado/src/com/fluendo/jheora/Playback.java
@@ -53,12 +53,16 @@
5454 int QualitySetting;
5555 int FrameQIndex; /* Quality specified as a
5656 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 */
5959 int CodedBlockIndex; /* Number of Coded Blocks */
6060 int CodedBlocksThisFrame; /* Index into coded blocks */
6161 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 */
6265
 66+
6367 /**********************************************************************/
6468 /* Frame Size & Index Information */
6569
@@ -148,63 +152,21 @@
149153 FrArray frArray = new FrArray();
150154 Filter filter = new Filter();
151155
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;
160159
161160 /* Dequantiser and rounding tables */
162 - short[] dequant_InterUV_coeffs;
163161 int[] quant_index = new int[64];
164 - int[] quant_Y_coeffs = new int[64];
165 - int[] quant_UV_coeffs = new int[64];
166162
167163 HuffEntry[] HuffRoot_VP3x = new HuffEntry[Huffman.NUM_HUFF_TABLES];
168164 int[][] HuffCodeArray_VP3x;
169165 byte[][] HuffCodeLengthArray_VP3x;
170166 byte[] ExtraBitLengths_VP3x;
 167+
171168
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 -
206169 public void clear()
207170 {
208 - clearTmpBuffers();
209171 if (opb != null) {
210172 opb = null;
211173 }
@@ -225,8 +187,6 @@
226188 {
227189 info = ci;
228190
229 - initTmpBuffers();
230 -
231191 DecoderErrorCode = 0;
232192 KeyFrameType = DCT_KEY_FRAME;
233193 FramesHaveBeenSkipped = 0;
@@ -234,10 +194,9 @@
235195 FrInit.InitFrameDetails(this);
236196
237197 keyframe_granule_shift = ilog(ci.keyframe_frequency_force-1);
238 - LastFrameQualityValue = 0;
 198+ //LastFrameQualityValue = 0;
239199
240200 /* Initialise version specific quantiser and in-loop filter values */
241 - copyQTables(ci);
242201 filter.copyFilterTables(ci);
243202
244203 /* Huffman setup */
@@ -305,16 +264,4 @@
306265 HuffRoot_VP3x[i] = ci.HuffRoot[i].copy();
307266 }
308267 }
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 - }
321268 }
Index: trunk/cortado/src/com/fluendo/jheora/Quant.java
@@ -2,6 +2,7 @@
33 * Copyright (C) 2004 Fluendo S.L.
44 *
55 * Written by: 2004 Wim Taymans <wim@fluendo.com>
 6+ * 2008 Maik Merten <maikmerten@googlemail.com>
67 *
78 * Many thanks to
89 * The Xiph.Org Foundation http://www.xiph.org/
@@ -28,8 +29,7 @@
2930
3031 public class Quant
3132 {
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+
3434 private static int ilog (long v)
3535 {
3636 int ret=0;
@@ -41,334 +41,278 @@
4242 return ret;
4343 }
4444
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;
4952
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;
5879 }
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 ]. */
6986 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;
8089 ci.DcScaleFactorTable[x]=(short)value;
8190 }
82 - /* base matricies */
83 - N = opb.readB(9); N++;
84 - //System.out.println(" max q matrix index "+N);
8591
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++) {
90106 for(x=0; x<64; x++) {
91107 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;
96110 }
97 - //System.out.println();
98111 }
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);
140121 } else {
141 - /* same as previous */
142 - //System.out.print("same as above");
 122+ /* ii. Else, assign NEWQR the value one. */
 123+ NEWQR = 1;
143124 }
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+
158163 } 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;
161208 }
162209 }
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+ }
179221 }
180222 }
181 - //System.out.println();
182223 }
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;
201224
202225 return 0;
203226 }
 227+
 228+ static short[] compQuantMatrix(int[] ACSCALE, short[] DCSCALE, short[] BMS, int[][] NQRS,
 229+ int[][][] QRSIZES, int[][][] QRBMIS, int qti, int pli, int qi) {
204230
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;
212255 }
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];
255263 }
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);
320264
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];
350271 }
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));
370314 }
371 -
372 - /* Re-initialise the q tables for forward and reverse transforms. */
373 - init_dequantizer (pbi, qscale, (byte)pbi.FrameQIndex );
 315+
 316+ return QMAT;
374317 }
375 -}
 318+
 319+}
\ No newline at end of file
Index: trunk/cortado/src/com/fluendo/jheora/Info.java
@@ -50,16 +50,12 @@
5151 public long keyframe_frequency_force;
5252
5353 /* 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];
5556 short[] DcScaleFactorTable = new short[Constants.Q_TABLE_SIZE];
5657 int MaxQMatrixIndex;
5758 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+
6460 HuffEntry[] HuffRoot = new HuffEntry[Huffman.NUM_HUFF_TABLES];
6561 byte[] LoopFilterLimitValues = new byte[Constants.Q_TABLE_SIZE];
6662

Status & tagging log