Parent Directory | Revision Log
Revision 224 -
(view)
(download)
Original Path: trunk/xvidcore/src/quant/adapt_quant.c
1 : | Isibaar | 3 | #include "../portab.h" |
2 : | #include "adapt_quant.h" | ||
3 : | |||
4 : | edgomez | 195 | #include <stdlib.h> /* free, malloc */ |
5 : | edgomez | 18 | |
6 : | Isibaar | 3 | #define MAX(a,b) (((a) > (b)) ? (a) : (b)) |
7 : | #define RDIFF(a,b) ((int)(a+0.5)-(int)(b+0.5)) | ||
8 : | |||
9 : | edgomez | 195 | int |
10 : | normalize_quantizer_field(float *in, | ||
11 : | int *out, | ||
12 : | int num, | ||
13 : | int min_quant, | ||
14 : | int max_quant) | ||
15 : | Isibaar | 3 | { |
16 : | int i; | ||
17 : | int finished; | ||
18 : | edgomez | 195 | |
19 : | do { | ||
20 : | Isibaar | 3 | finished = 1; |
21 : | edgomez | 195 | for (i = 1; i < num; i++) { |
22 : | if (RDIFF(in[i], in[i - 1]) > 2) { | ||
23 : | Isibaar | 3 | in[i] -= (float) 0.5; |
24 : | finished = 0; | ||
25 : | edgomez | 195 | } else if (RDIFF(in[i], in[i - 1]) < -2) { |
26 : | in[i - 1] -= (float) 0.5; | ||
27 : | Isibaar | 3 | finished = 0; |
28 : | } | ||
29 : | edgomez | 195 | |
30 : | if (in[i] > max_quant) { | ||
31 : | edgomez | 18 | in[i] = (float) max_quant; |
32 : | finished = 0; | ||
33 : | } | ||
34 : | edgomez | 195 | if (in[i] < min_quant) { |
35 : | edgomez | 18 | in[i] = (float) min_quant; |
36 : | finished = 0; | ||
37 : | } | ||
38 : | edgomez | 195 | if (in[i - 1] > max_quant) { |
39 : | in[i - 1] = (float) max_quant; | ||
40 : | edgomez | 18 | finished = 0; |
41 : | } | ||
42 : | edgomez | 195 | if (in[i - 1] < min_quant) { |
43 : | in[i - 1] = (float) min_quant; | ||
44 : | edgomez | 18 | finished = 0; |
45 : | } | ||
46 : | Isibaar | 3 | } |
47 : | edgomez | 195 | } while (!finished); |
48 : | |||
49 : | Isibaar | 3 | out[0] = 0; |
50 : | for (i = 1; i < num; i++) | ||
51 : | edgomez | 195 | out[i] = RDIFF(in[i], in[i - 1]); |
52 : | |||
53 : | Isibaar | 3 | return (int) (in[0] + 0.5); |
54 : | } | ||
55 : | |||
56 : | edgomez | 195 | int |
57 : | adaptive_quantization(unsigned char *buf, | ||
58 : | int stride, | ||
59 : | int *intquant, | ||
60 : | int framequant, | ||
61 : | int min_quant, | ||
62 : | int max_quant, | ||
63 : | int mb_width, | ||
64 : | int mb_height) // no qstride because normalization | ||
65 : | Isibaar | 3 | { |
66 : | edgomez | 195 | int i, j, k, l; |
67 : | |||
68 : | Isibaar | 3 | static float *quant; |
69 : | unsigned char *ptr; | ||
70 : | float *val; | ||
71 : | uManiac | 224 | float global = 0., maxval = 0.; |
72 : | Isibaar | 3 | |
73 : | uManiac | 224 | const float DarkThres = 0.25; |
74 : | const float DarkAmpl = 7.0; | ||
75 : | |||
76 : | const float BrightThres = 4.0; | ||
77 : | const float BrightAmpl = 5.0; | ||
78 : | Isibaar | 3 | |
79 : | uManiac | 224 | const char LowestVal = 10; |
80 : | Isibaar | 3 | |
81 : | uManiac | 224 | const float GlobalBrightThres = 220.0; |
82 : | const float GlobalDarkThres = 20.0; | ||
83 : | float global_quant = 1.0; | ||
84 : | Isibaar | 3 | |
85 : | edgomez | 195 | if (!quant) |
86 : | if (!(quant = (float *) malloc(mb_width * mb_height * sizeof(float)))) | ||
87 : | Isibaar | 3 | return -1; |
88 : | |||
89 : | edgomez | 195 | val = (float *) malloc(mb_width * mb_height * sizeof(float)); |
90 : | Isibaar | 3 | |
91 : | edgomez | 195 | for (k = 0; k < mb_height; k++) { |
92 : | for (l = 0; l < mb_width; l++) // do this for all macroblocks individually | ||
93 : | Isibaar | 3 | { |
94 : | edgomez | 195 | quant[k * mb_width + l] = (float) framequant; |
95 : | |||
96 : | Isibaar | 3 | // calculate luminance-masking |
97 : | edgomez | 195 | ptr = &buf[16 * k * stride + 16 * l]; // address of MB |
98 : | Isibaar | 3 | |
99 : | edgomez | 195 | val[k * mb_width + l] = 0.; |
100 : | |||
101 : | for (i = 0; i < 16; i++) | ||
102 : | for (j = 0; j < 16; j++) | ||
103 : | uManiac | 224 | { |
104 : | if( ptr[i * stride + j] < LowestVal ) | ||
105 : | ptr[i * stride + j] = 0; | ||
106 : | edgomez | 195 | val[k * mb_width + l] += ptr[i * stride + j]; |
107 : | uManiac | 224 | } |
108 : | edgomez | 195 | val[k * mb_width + l] /= 256.; |
109 : | uManiac | 224 | global += val[k * mb_width + l]; |
110 : | if( val[k * mb_width + l] > maxval ) | ||
111 : | maxval = val[k * mb_width + l]; | ||
112 : | Isibaar | 3 | } |
113 : | } | ||
114 : | |||
115 : | uManiac | 224 | global /= mb_width * mb_height; |
116 : | maxval /= global; | ||
117 : | if( global < GlobalDarkThres ) | ||
118 : | global_quant *= -1.0; | ||
119 : | else if ( global < GlobalBrightThres ) | ||
120 : | global_quant = 0.0; | ||
121 : | Isibaar | 3 | |
122 : | uManiac | 224 | for (k = 0; k < mb_height; k++) { |
123 : | for (l = 0; l < mb_width; l++) // do this for all macroblocks individually | ||
124 : | { | ||
125 : | val[k * mb_width + l] /= global; | ||
126 : | if (val[k * mb_width + l] < DarkThres) | ||
127 : | quant[k * mb_width + l] += global_quant + | ||
128 : | DarkAmpl * (DarkThres - val[k * mb_width + l]) / DarkThres; | ||
129 : | else if (val[k * mb_width + l] > BrightThres) | ||
130 : | quant[k * mb_width + l] += global_quant + | ||
131 : | BrightAmpl * (val[k * mb_width + l] - BrightThres) / (maxval - BrightThres); | ||
132 : | Isibaar | 3 | } |
133 : | } | ||
134 : | free(val); | ||
135 : | edgomez | 195 | return normalize_quantizer_field(quant, intquant, mb_width * mb_height, |
136 : | min_quant, max_quant); | ||
137 : | edgomez | 18 | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |