1 /* predictor.c
2 * The predictors that attempt to minimize the difference between last and
3 * current values.
4 * Copyright (C) 2000 Wayde Milas (wmilas@rarcoa.com)
5 *
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include "types.h"
25 #include "predictor.h"
26
zero_predictor_table(PREDICTORTABLE * predTable,OPTIONSTRUCT * options)27 void zero_predictor_table(PREDICTORTABLE *predTable, OPTIONSTRUCT *options)
28 {
29 int loop;
30
31 predTable->mid_K = malloc(sizeof(int) * MAX_KHISTORY);
32 if(options->encoderVersion == RICE_DUAL_K ||
33 options->encoderVersion == RICE_DUAL_K_BLOCK)
34 predTable->ave_K = malloc(sizeof(int) * MAX_KHISTORY);
35 else
36 predTable->ave_K = NULL;
37
38 predTable->newKLookUP = malloc(sizeof(double) * (K_LOOKUP_SIZE+1));
39
40 for(loop=0; loop < 3;loop++) {
41 predTable->mid_I[loop] = 0;
42 predTable->ave_I[loop] = 0;
43 }
44
45 for(loop=0;loop < MAX_KHISTORY;loop++) {
46 predTable->mid_K[loop]=INITIAL_K;
47 if(options->encoderVersion == RICE_DUAL_K ||
48 options->encoderVersion == RICE_DUAL_K_BLOCK)
49 predTable->ave_K[loop]=INITIAL_K;
50 }
51
52 for(loop=0;loop <= K_LOOKUP_SIZE;loop++) predTable->newKLookUP[loop] = -1;
53
54 predTable->diffAve=predTable->diffMid=0;
55 predTable->lowDiffAve=0;
56 predTable->highDiffAve=0;
57 predTable->sumDiffAve=0;
58 predTable->countDiffAve=0;
59 predTable->lowDiffMid=0;
60 predTable->highDiffMid=0;
61 predTable->sumDiffMid=0;
62 predTable->countDiffMid=0;
63 predTable->midM = MAX_M;
64 predTable->aveM = MAX_M;
65 predTable->midLowK=0;
66 predTable->aveLowK=0;
67 predTable->midHighK=0;
68 predTable->aveHighK=0;
69 predTable->midSumK=0;
70 predTable->aveSumK=0;
71 predTable->midCountK=0;
72 predTable->aveCountK=0;
73 predTable->kBlockPointer=0;
74
75 predTable->preLog10_2 = log10(2);
76 }
77
frame_difference_calc(PREDICTORTABLE * predictor,unsigned short predA,unsigned short predM,long mid,long ave,int op)78 void frame_difference_calc(PREDICTORTABLE *predictor, unsigned short predA,
79 unsigned short predM, long mid, long ave, int op)
80 {
81 if(predA == ZEROO_PREDICTOR)
82 predictor->diffAve = -ave;
83 else if(predA == FIRSTO_PREDICTOR)
84 predictor->diffAve = predictor->ave_I[0] - ave;
85 else if(predA == SECONDO_PREDICTOR)
86 predictor->diffAve = ((2*predictor->ave_I[0]) -
87 predictor->ave_I[1]) - ave;
88 else
89 predictor->diffAve = ((3*predictor->ave_I[0]) -
90 (3*predictor->ave_I[1]) + predictor->ave_I[2]) - ave;
91
92 if(predM == ZEROO_PREDICTOR)
93 predictor->diffMid = -mid;
94 else if(predM == FIRSTO_PREDICTOR)
95 predictor->diffMid = predictor->mid_I[0] - mid;
96 else if(predM == SECONDO_PREDICTOR)
97 predictor->diffMid = ((2*predictor->mid_I[0]) -
98 predictor->mid_I[1]) - mid;
99 else
100 predictor->diffMid = ((3*predictor->mid_I[0]) -
101 (3*predictor->mid_I[1]) + predictor->mid_I[2]) - mid;
102
103 predictor->mid_I[3] = predictor->mid_I[2];
104 predictor->mid_I[2] = predictor->mid_I[1];
105 predictor->mid_I[1] = predictor->mid_I[0];
106 if(op == COMPRESS) {
107 predictor->mid_I[0] = mid;
108 }
109 else {
110 predictor->mid_I[0] = predictor->diffMid;
111 }
112 predictor->ave_I[3] = predictor->ave_I[2];
113 predictor->ave_I[2] = predictor->ave_I[1];
114 predictor->ave_I[1] = predictor->ave_I[0];
115 if(op == COMPRESS) {
116 predictor->ave_I[0] = ave;
117 }
118 else {
119 predictor->ave_I[0] = predictor->diffAve;
120 }
121 }
difference_calc(PREDICTORTABLE * predictor,unsigned short pred,long mid,long ave,int op)122 void difference_calc(PREDICTORTABLE *predictor, unsigned short pred,
123 long mid, long ave, int op)
124 {
125 int hold[4], last, i, smallest, bestPred;
126
127 if(pred == ZEROO_PREDICTOR) {
128 predictor->diffMid = -mid;
129 predictor->diffAve = -ave;
130 }
131 else if(pred == FIRSTO_PREDICTOR) {
132 predictor->diffMid = predictor->mid_I[0] - mid;
133 predictor->diffAve = predictor->ave_I[0] - ave;
134 }
135 else if(pred == SECONDO_PREDICTOR) {
136 predictor->diffMid = ((2*predictor->mid_I[0]) - predictor->mid_I[1]) - mid;
137 predictor->diffAve = ((2*predictor->ave_I[0]) - predictor->ave_I[1]) - ave;
138 }
139 else if(pred == THIRDO_PREDICTOR) {
140 predictor->diffMid = ((3*predictor->mid_I[0]) -
141 (3*predictor->mid_I[1]) + predictor->mid_I[2]) - mid;
142 predictor->diffAve = ((3*predictor->ave_I[0]) -
143 (3*predictor->ave_I[1]) + predictor->ave_I[2]) - ave;
144 }
145 else if(pred == L_HISTORY_PREDICTOR) {
146 last = predictor->mid_I[0];
147 hold[0] = 0 - last;
148 hold[1] = predictor->mid_I[1] - last;
149 hold[2] = ((2*predictor->mid_I[1]) - predictor->mid_I[2]) - last;
150 hold[3] = ((3*predictor->mid_I[1]) - (3*predictor->mid_I[2]) +
151 predictor->mid_I[3]) - last;
152
153 smallest = (abs(hold[0]));
154 bestPred = 0;
155 i = 1;
156 while(i < 4) {
157 if(abs(hold[i]) < smallest) {
158 smallest = abs(hold[i]);
159 bestPred = i;
160 }
161 i++;
162 }
163
164 if(bestPred == 0)
165 predictor->diffMid = -mid;
166 else if(bestPred == 1)
167 predictor->diffMid = predictor->mid_I[0] -mid;
168 else if(bestPred == 2)
169 predictor->diffMid = ((2*predictor->mid_I[0]) - predictor->mid_I[1]) -
170 mid;
171 else
172 predictor->diffMid = ((3*predictor->mid_I[0]) -
173 (3*predictor->mid_I[1]) + predictor->mid_I[2]) - mid;
174
175 last = predictor->ave_I[0];
176 hold[0] = 0 - last;
177 hold[1] = predictor->ave_I[1] - last;
178 hold[2] = ((2*predictor->ave_I[1]) - predictor->ave_I[2]) - last;
179 hold[3] = ((3*predictor->ave_I[1]) - (3*predictor->ave_I[2]) +
180 predictor->ave_I[3]) - last;
181
182 smallest = (abs(hold[0]));
183 bestPred = 0;
184 i = 1;
185 while(i < 4) {
186 if(abs(hold[i]) < smallest) {
187 smallest = abs(hold[i]);
188 bestPred = i;
189 }
190 i++;
191 }
192
193 if(bestPred == 0)
194 predictor->diffAve = -ave;
195 else if(bestPred == 1)
196 predictor->diffAve = predictor->ave_I[0] -ave;
197 else if(bestPred == 2)
198 predictor->diffAve = ((2*predictor->ave_I[0]) - predictor->ave_I[1]) -
199 ave;
200 else
201 predictor->diffAve = ((3*predictor->ave_I[0]) -
202 (3*predictor->ave_I[1]) + predictor->ave_I[2]) - ave;
203 }
204
205 predictor->mid_I[3] = predictor->mid_I[2];
206 predictor->mid_I[2] = predictor->mid_I[1];
207 predictor->mid_I[1] = predictor->mid_I[0];
208 if(op == COMPRESS) {
209 predictor->mid_I[0] = mid;
210 }
211 else {
212 predictor->mid_I[0] = predictor->diffMid;
213 }
214 predictor->ave_I[3] = predictor->ave_I[2];
215 predictor->ave_I[2] = predictor->ave_I[1];
216 predictor->ave_I[1] = predictor->ave_I[0];
217 if(op == COMPRESS) {
218 predictor->ave_I[0] = ave;
219 }
220 else {
221 predictor->ave_I[0] = predictor->diffAve;
222 }
223 }
224
precompute_predictor(KEXISBLOCKSTRUCT * kexisBlock,PCMBLOCKSTRUCT * pcmBlock,int * A,int * M)225 void precompute_predictor(KEXISBLOCKSTRUCT *kexisBlock,
226 PCMBLOCKSTRUCT *pcmBlock, int *A, int *M)
227 {
228 int loop, loop2, choiceM=0, choiceA=0;
229 long left, right, mid, ave;
230 double m[4], a[4], bestMid, bestAve;
231 PREDICTORTABLE *predictor, pred[4];
232
233 predictor = &kexisBlock->predictor;
234 // copy the state info over;
235 for(loop=0;loop<4;loop++) {
236 for(loop2=0;loop2<4;loop2++) {
237 pred[loop2].mid_I[loop] = predictor->mid_I[loop];
238 pred[loop2].ave_I[loop] = predictor->ave_I[loop];
239 }
240 a[loop] = 0;
241 m[loop] = 0;
242 }
243 for(loop=0;loop<pcmBlock->size;loop+=2) {
244 left = pcmBlock->data[loop];
245 right = pcmBlock->data[loop+1];
246 mid = left - right;
247 ave = right + (mid/2);
248
249 for(loop2=0;loop2<4;loop2++) {
250 difference_calc(&(pred[loop2]), loop2+1, mid, ave, COMPRESS);
251
252 a[loop2] += abs(pred[loop2].diffAve);
253 m[loop2] += abs(pred[loop2].diffMid);
254 }
255 }
256
257 bestAve = a[0]; choiceA=0;
258 bestMid = m[0]; choiceM=0;
259 for(loop=1;loop<4;loop++) {
260 if(a[loop] < bestAve) {
261 bestAve = a[loop];
262 choiceA = loop;
263 }
264 if(m[loop] < bestMid) {
265 bestMid = m[loop];
266 choiceM = loop;
267 }
268 }
269
270 *A = choiceA+1;
271 *M = choiceM+1;
272 }
273
collect_prediction_stats(KEXISBLOCKSTRUCT * kexisBlock,long dMid,long dAve)274 void collect_prediction_stats(KEXISBLOCKSTRUCT *kexisBlock, long dMid,
275 long dAve)
276 {
277 if(dAve < kexisBlock->predictor.lowDiffAve)
278 kexisBlock->predictor.lowDiffAve = dAve;
279
280 if(dAve > kexisBlock->predictor.highDiffAve)
281 kexisBlock->predictor.highDiffAve = dAve;
282
283 if(dMid < kexisBlock->predictor.lowDiffMid)
284 kexisBlock->predictor.lowDiffMid = dMid;
285
286 if(dMid > kexisBlock->predictor.highDiffMid)
287 kexisBlock->predictor.highDiffMid = dMid;
288
289 kexisBlock->predictor.countDiffMid++;
290 kexisBlock->predictor.sumDiffMid += abs(dMid);
291
292 kexisBlock->predictor.countDiffAve++;
293 kexisBlock->predictor.sumDiffAve += abs(dAve);
294 }
295