ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/opts.c
Revision: 23
Committed: Mon Jul 7 23:06:52 2008 UTC (12 years, 4 months ago) by wdelano
File size: 13607 byte(s)
Log Message:
changes for win32
Line File contents
1 /*===========================================================================*
2 * opts.c *
3 * *
4 * Special C code to handle TUNEing options *
5 * *
6 * EXPORTED PROCEDURES: *
7 * Tune_Init *
8 * CollectQuantStats *
9 * *
10 *===========================================================================*/
11
12
13 /*
14 * Copyright (c) 1995 The Regents of the University of California.
15 * All rights reserved.
16 *
17 * Permission to use, copy, modify, and distribute this software and its
18 * documentation for any purpose, without fee, and without written agreement is
19 * hereby granted, provided that the above copyright notice and the following
20 * two paragraphs appear in all copies of this software.
21 *
22 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
23 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
24 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
25 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
28 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
30 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
31 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
32 */
33
34 /*==============*
35 * HEADER FILES *
36 *==============*/
37
38 #include <stdio.h>
39 #include <string.h>
40 #include <malloc.h>
41 #include <math.h>
42
43 #include "opts.h"
44
45 /*==============*
46 * EXTERNALS *
47 *==============*/
48
49 extern char outputFileName[];
50 extern boolean pureDCT;
51 extern int32 qtable[], niqtable[];
52 extern int ZAG[];
53 extern boolean printSNR, decodeRefFrames;
54
55 void init_idctref _ANSI_ARGS_((void));
56 void init_fdct _ANSI_ARGS_((void));
57
58
59 /*===================*
60 * GLOBALS MADE HERE *
61 *===================*/
62
63 boolean tuneingOn = FALSE;
64 int block_bound = 128;
65 boolean collect_quant = FALSE;
66 int collect_quant_detailed = 0;
67 FILE *collect_quant_fp;
68 int kill_dim = FALSE;
69 int kill_dim_break, kill_dim_end;
70 float kill_dim_slope;
71 int SearchCompareMode = DEFAULT_SEARCH;
72 boolean squash_small_differences = FALSE;
73 int SquashMaxLum, SquashMaxChr;
74 float LocalDCTRateScale = 1.0, LocalDCTDistortScale = 1.0;
75 boolean IntraPBAllowed = TRUE;
76 boolean WriteDistortionNumbers = FALSE;
77 int collect_distortion_detailed = 0;
78 FILE *distortion_fp;
79 FILE *fp_table_rate[31], *fp_table_dist[31];
80 boolean DoLaplace = FALSE;
81 double **L1, **L2, **Lambdas;
82 int LaplaceNum, LaplaceCnum;
83 boolean BSkipBlocks = TRUE;
84
85 /*====================*
86 * Internal Prototypes*
87 *====================*/
88 void SetupCollectQuantStats _ANSI_ARGS_((char *charPtr));
89 void SetupSquashSmall _ANSI_ARGS_ ((char *charPtr));
90 void SetupKillDimAreas _ANSI_ARGS_((char *charPtr));
91 void SetupLocalDCT _ANSI_ARGS_((char *charPtr));
92 void SetupWriteDistortions _ANSI_ARGS_((char *charPtr));
93 void SetupLaplace _ANSI_ARGS_((void));
94 void CalcLambdas _ANSI_ARGS_((void));
95 void Mpost_UnQuantZigBlockLaplace _ANSI_ARGS_((FlatBlock in, Block out, int qscale, boolean iblock));
96
97 /* define this as it too much of a pain to find toupper on different arch'es */
98 #define ASCII_TOUPPER(c) ((c>='a') && (c<='z')) ? c-'a'+'A' : c
99
100 /*=====================*
101 * EXPORTED PROCEDURES *
102 *=====================*/
103
104 /*===========================================================================*
105 *
106 * Tune_Init
107 *
108 * Do any setup needed before coding stream
109 *
110 * RETURNS: nothing
111 *
112 * SIDE EFFECTS: varies
113 *
114 *===========================================================================*/
115 void Tune_Init()
116 {
117 int i;
118
119 /* Just check for each, and do whats needed */
120 if (collect_quant) {
121 if (!pureDCT) {
122 pureDCT = TRUE;
123 init_idctref();
124 init_fdct();
125 }
126 fprintf(collect_quant_fp, "# %s\n", outputFileName);
127 fprintf(collect_quant_fp, "#");
128 for (i=0; i<64; i++)
129 fprintf(collect_quant_fp, " %d", qtable[i]);
130 fprintf(collect_quant_fp, "\n#");
131 for (i=0; i<64; i++)
132 fprintf(collect_quant_fp, " %d", niqtable[i]);
133 fprintf(collect_quant_fp, "\n# %d %d %d\n\n",
134 GetIQScale(), GetPQScale(), GetBQScale());
135
136 }
137
138 if (DoLaplace) {
139 if (!pureDCT) {
140 pureDCT = TRUE;
141 init_idctref();
142 init_fdct();
143 }
144 decodeRefFrames = TRUE;
145 printSNR = TRUE;
146 }
147
148 }
149
150 /*===========================================================================*
151 *
152 * ParseTuneParam
153 *
154 * Handle the strings following TUNE
155 *
156 * RETURNS: nothing
157 *
158 * SIDE EFFECTS: varies
159 *
160 *===========================================================================*/
161 void ParseTuneParam(charPtr)
162 char *charPtr;
163 {
164 switch (ASCII_TOUPPER(*charPtr)) {
165 case 'B':
166 if (1 != sscanf(charPtr+2, "%d", &block_bound)) {
167 fprintf(stderr, "Invalid tuning parameter (b) in parameter file.\n");
168 }
169 break;
170 case 'C':
171 SetupCollectQuantStats(charPtr+2);
172 break;
173 case 'D':
174 SetupLocalDCT(SkipSpacesTabs(charPtr+1));
175 break;
176 case 'K':
177 SetupKillDimAreas(SkipSpacesTabs(charPtr+1));
178 break;
179 case 'L':
180 SetupLaplace();
181 break;
182 case 'N':
183 SearchCompareMode = NO_DC_SEARCH;
184 break;
185 case 'Q':
186 SearchCompareMode = DO_Mean_Squared_Distortion;
187 break;
188 case 'S':
189 SetupSquashSmall(SkipSpacesTabs(charPtr+1));
190 break;
191 case 'W':
192 SetupWriteDistortions(SkipSpacesTabs(charPtr+1));
193 break;
194 case 'U':
195 BSkipBlocks = FALSE;
196 break;
197 case 'Z':
198 IntraPBAllowed = FALSE;
199 break;
200 default:
201 fprintf(stderr, "Unknown tuning (%s) in parameter file.\n",charPtr);
202 break;
203 }
204 }
205
206
207 /*===============*
208 * Internals *
209 *===============*/
210
211 /*===========================================================================*
212 *
213 * SetupCollectQuantStats
214 *
215 * Setup variables to collect statistics on quantization values
216 *
217 * RETURNS: nothing
218 *
219 * SIDE EFFECTS: sets collect_quant and collect_quant_fp
220 *
221 *===========================================================================*/
222 void SetupCollectQuantStats(charPtr)
223 char *charPtr;
224 {
225 char fname[256], *cp;
226
227 cp = charPtr;
228 while ( (*cp != ' ') && (*cp != '\t') && (*cp != '\n')) {
229 cp++;
230 }
231
232 strncpy(fname, charPtr, cp-charPtr);
233 fname[cp-charPtr] = '\0';
234 collect_quant = TRUE;
235 if ((collect_quant_fp = fopen(fname,"w")) == NULL) {
236 fprintf(stderr, "Error opening %s for quant statistics\n", fname);
237 fprintf(stderr, "Using stdout (ick!)\n");
238 collect_quant_fp = stdout;
239 }
240
241 cp = SkipSpacesTabs(cp);
242 if (*cp != '\n') {
243 switch (*cp) {
244 case 'c':
245 collect_quant_detailed = 1;
246 break;
247 default:
248 fprintf(stderr, "Unknown TUNE parameter setting format %s\n", cp);
249 }}
250 }
251
252
253
254
255 /*===========================================================================*
256 *
257 * SetupKillDimAreas
258 *
259 * Do a transform on small lum values
260 *
261 * RETURNS: nothing
262 *
263 * SIDE EFFECTS: sets kill_dim, kill_dim_break, kill_dim_end
264 *
265 *===========================================================================*/
266 void SetupKillDimAreas(charPtr)
267 char *charPtr;
268 {
269 int items_scanned;
270
271 kill_dim = TRUE;
272 items_scanned = sscanf(charPtr, "%d %d %f",
273 &kill_dim_break, &kill_dim_end, &kill_dim_slope);
274 if (items_scanned != 3) {
275 kill_dim_slope = 0.25;
276 items_scanned = sscanf(charPtr, "%d %d",
277 &kill_dim_break, &kill_dim_end);
278 if (items_scanned != 2) {
279 /* Use defaults */
280 kill_dim_break = 20;
281 kill_dim_end = 25;
282 }
283 }
284 /* check values */
285 if (kill_dim_break > kill_dim_end) {
286 fprintf(stderr, "TUNE parameter k: break > end is illegal.\n");
287 exit(-1);
288 }
289 if (kill_dim_slope < 0) {
290 fprintf(stderr, "TUNE parameter k: slope < 0 is illegal.\n");
291 exit(-1);
292 }
293 }
294
295
296
297 /*===========================================================================*
298 *
299 * SetupSquashSmall
300 *
301 * Setup encoder to squash small changes in Y or Cr/Cb values
302 *
303 * RETURNS: nothing
304 *
305 * SIDE EFFECTS: sets squash_max_differences SquashMaxLum SquashMaxChr
306 *
307 *===========================================================================*/
308 void SetupSquashSmall(charPtr)
309 char *charPtr;
310 {
311 squash_small_differences = TRUE;
312
313 if (sscanf(charPtr, "%d %d", &SquashMaxLum, &SquashMaxChr) == 1) {
314 /* Only set one, do both */
315 SquashMaxChr = SquashMaxLum;
316 }
317 }
318
319
320 /*===========================================================================*
321 *
322 * SetupLocalDCT
323 *
324 * Setup encoder to use DCT for rate-distortion estimat ein Psearches
325 *
326 * RETURNS: nothing
327 *
328 * SIDE EFFECTS: sets SearchCompareMode and
329 * can change LocalDCTRateScale, LocalDCTDistortScale
330 *
331 *===========================================================================*/
332 void SetupLocalDCT(charPtr)
333 char *charPtr;
334 {
335 int num_scales=0;
336
337 SearchCompareMode = LOCAL_DCT;
338
339 /* Set scaling factors if present */
340 num_scales = sscanf(charPtr, "%f %f", &LocalDCTRateScale, &LocalDCTDistortScale);
341 if (num_scales == 1) {
342 fprintf(stderr, "Invalid number of scaling factors for local DCT\n");
343 fprintf(stderr, "Must specify Rate Scale and Distorion scale (both floats)\n");
344 fprintf(stderr, "Continuing with 1.0 1.0\n");
345 LocalDCTRateScale = 1.0;
346 LocalDCTDistortScale = 1.0;
347 }
348 }
349
350
351 /*===========================================================================*
352 *
353 * SetupLaplace
354 *
355 * Setup encoder to find distrubution for I-frames, and use for -snr
356 *
357 * RETURNS: nothing
358 *
359 * SIDE EFFECTS: sets DoLaplace, L1, L2, and Lambdas
360 *
361 *===========================================================================*/
362 void SetupLaplace()
363 {
364 int i;
365
366 DoLaplace = TRUE;
367 LaplaceNum = 0;
368 L1 = (double **)malloc(sizeof(double *)*3);
369 L2 = (double **)malloc(sizeof(double *)*3);
370 Lambdas = (double **)malloc(sizeof(double *)*3);
371 if (L1 == NULL || L2 == NULL || Lambdas == NULL) {
372 fprintf(stderr,"Out of memory!!!\n");
373 exit(1);
374 }
375 for (i = 0; i < 3; i++) {
376 L1[i] = (double *)calloc(64, sizeof(double));
377 L2[i] = (double *)calloc(64, sizeof(double));
378 Lambdas[i] = (double *)malloc(sizeof(double) * 64);
379 if (L1[i] == NULL || L2[i] == NULL || Lambdas[i] == NULL) {
380 fprintf(stderr,"Out of memory!!!\n");
381 exit(1);
382 }
383 }
384 }
385
386 void CalcLambdas()
387 {
388 int i,j,n;
389 double var;
390
391 n = LaplaceNum;
392 for (i = 0; i < 3; i++) {
393 for (j = 0; j < 64; j++) {
394 var = (n*L1[i][j] + L2[i][j]*L2[i][j]) / (n*(n-1));
395 Lambdas[i][j] = sqrt(2.0) / sqrt(var);
396 }
397 }
398 }
399
400
401 /*===========================================================================*
402 *
403 * Mpost_UnQuantZigBlockLaplace
404 *
405 * unquantize and zig-zag (decode) a single block, using the distrib to get vals
406 * Iblocks only now
407 *
408 * RETURNS: nothing
409 *
410 * SIDE EFFECTS: none
411 *
412 *===========================================================================*/
413 void
414 Mpost_UnQuantZigBlockLaplace(in, out, qscale, iblock)
415 FlatBlock in;
416 Block out;
417 int qscale;
418 boolean iblock;
419 {
420 register int index;
421 int position;
422 register int qentry;
423 int level, coeff;
424 double low, high;
425 double mid,lam;
426
427 /* qtable[0] must be 8 */
428 out[0][0] = (int16)(in[0] * 8);
429
430 for ( index = 1; index < DCTSIZE_SQ; index++ ) {
431 position = ZAG[index];
432 level = in[index];
433
434 if (level == 0) {
435 ((int16 *)out)[position] = 0;
436 continue;
437 }
438 qentry = qtable[position] * qscale;
439 coeff = (level*qentry)/8;
440 low = ((ABS(level)-.5)*qentry)/8;
441 high = ((ABS(level)+.5)*qentry)/8;
442 lam = Lambdas[LaplaceCnum][position];
443 mid = (1.0/lam) * log(0.5*(exp(-lam*low)+exp(-lam*high)));
444 mid = ABS(mid);
445 if (mid - floor(mid) > .4999) {
446 mid = ceil(mid);
447 } else {
448 mid = floor(mid);
449 }
450 if (level<0) {mid = -mid;}
451 /*printf("(%2.1lf-%2.1lf): old: %d vs %d\n",low,high,coeff,(int) mid);*/
452 coeff = mid;
453 if ( (coeff & 1) == 0 ) {
454 if ( coeff < 0 ) {
455 coeff++;
456 } else if ( coeff > 0 ) {
457 coeff--;
458 }
459 }
460 ((int16 *)out)[position] = coeff;
461 }
462 }
463
464 void
465 SetupWriteDistortions(charPtr)
466 char *charPtr;
467 {
468 char fname[256], *cp;
469 int i;
470
471 WriteDistortionNumbers = TRUE;
472 cp = charPtr;
473 while ( (*cp != ' ') && (*cp != '\t') && (*cp != '\n')) {
474 cp++;
475 }
476
477 strncpy(fname, charPtr, cp-charPtr);
478 fname[cp-charPtr] = '\0';
479 collect_quant = TRUE;
480 if ((distortion_fp = fopen(fname,"w")) == NULL) {
481 fprintf(stderr, "Error opening %s for quant statistics\n", fname);
482 fprintf(stderr, "Using stdout (ick!)\n");
483 distortion_fp = stdout;
484 }
485
486 cp = SkipSpacesTabs(cp);
487 if (*cp != '\n') {
488 switch (*cp) {
489 case 'c':
490 collect_distortion_detailed = TRUE;
491 break;
492 case 't': {
493 char scratch[256];
494 collect_distortion_detailed = 2;
495 for (i = 1; i < 32; i++) {
496 sprintf(scratch, "%srate%d", fname, i);
497 fp_table_rate[i-1] = fopen(scratch, "w");
498 sprintf(scratch, "%sdist%d", fname, i);
499 fp_table_dist[i-1] = fopen(scratch, "w");
500 }}
501 break;
502 default:
503 fprintf(stderr, "Unknown TUNE parameter setting format %s\n", cp);
504 }}
505 }
506
507 int mse(blk1, blk2)
508 Block blk1, blk2;
509 {
510 register int index, error, tmp;
511 int16 *bp1, *bp2;
512
513 bp1 = (int16 *)blk1;
514 bp2 = (int16 *)blk2;
515 error = 0;
516 for ( index = 0; index < DCTSIZE_SQ; index++ ) {
517 tmp = *bp1++ - *bp2++;
518 error += tmp*tmp;
519 }
520 return error;
521 }