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