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