28 |
|
|
29 |
#include "../xvid.h" |
#include "../xvid.h" |
30 |
#include "../portab.h" |
#include "../portab.h" |
31 |
|
#include "../utils/emms.h" |
32 |
|
|
33 |
/***************************************************************************** |
/***************************************************************************** |
34 |
* Private data type |
* Private data type |
47 |
static int lumi_plg_info(xvid_plg_info_t *info); |
static int lumi_plg_info(xvid_plg_info_t *info); |
48 |
static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle); |
static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle); |
49 |
static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy); |
static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy); |
50 |
static int lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data); |
static int lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data); |
51 |
static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data); |
static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data); |
52 |
|
|
53 |
/***************************************************************************** |
/***************************************************************************** |
65 |
case XVID_PLG_DESTROY: |
case XVID_PLG_DESTROY: |
66 |
return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1)); |
return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1)); |
67 |
case XVID_PLG_BEFORE : |
case XVID_PLG_BEFORE : |
68 |
return(lumi_plg_before((lumi_data_t *)handle, (xvid_plg_data_t *)param1)); |
return 0; |
69 |
|
case XVID_PLG_FRAME : |
70 |
|
return(lumi_plg_frame((lumi_data_t *)handle, (xvid_plg_data_t *)param1)); |
71 |
case XVID_PLG_AFTER : |
case XVID_PLG_AFTER : |
72 |
return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1)); |
return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1)); |
73 |
} |
} |
157 |
int max_quant); |
int max_quant); |
158 |
|
|
159 |
static int |
static int |
160 |
lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data) |
lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data) |
161 |
{ |
{ |
162 |
int i, j; |
int i, j; |
163 |
|
|
164 |
float global = 0.0f; |
float global = 0.0f; |
|
uint32_t mid_range = 0; |
|
165 |
|
|
166 |
const float DarkAmpl = 14 / 2; |
const float DarkAmpl = 14 / 4; |
167 |
const float BrightAmpl = 10 / 2; |
const float BrightAmpl = 10 / 3; |
168 |
const float DarkThres = 70; |
float DarkThres = 90; |
169 |
const float BrightThres = 200; |
float BrightThres = 200; |
170 |
|
|
171 |
const float GlobalDarkThres = 60; |
const float GlobalDarkThres = 60; |
172 |
const float GlobalBrightThres = 170; |
const float GlobalBrightThres = 170; |
173 |
|
|
174 |
const float MidRangeThres = 20; |
if (data->type == XVID_TYPE_BVOP) return 0; |
|
const float UpperLimit = 200; |
|
|
const float LowerLimit = 25; |
|
175 |
|
|
176 |
/* Do this for all macroblocks individually */ |
/* Do this for all macroblocks individually */ |
177 |
for (j = 0; j < data->mb_height; j++) { |
for (j = 0; j < data->mb_height; j++) { |
178 |
for (i = 0; i < data->mb_width; i++) { |
for (i = 0; i < data->mb_width; i++) { |
179 |
int k, l; |
int k, l, sum = 0; |
180 |
unsigned char *ptr; |
unsigned char *ptr; |
181 |
|
|
182 |
/* Initialize the current quant value to the frame quant */ |
/* Initialize the current quant value to the frame quant */ |
183 |
handle->quant[j*data->mb_width + i] = (float)data->quant; |
handle->quant[j*data->mb_width + i] = (float)data->quant; |
184 |
|
|
|
/* Reset the val value */ |
|
|
handle->val[j*data->mb_width + i] = 0.0f; |
|
|
|
|
185 |
/* Next steps compute the luminance-masking */ |
/* Next steps compute the luminance-masking */ |
186 |
|
|
187 |
/* Get the MB address */ |
/* Get the MB address */ |
191 |
/* Accumulate luminance */ |
/* Accumulate luminance */ |
192 |
for (k = 0; k < 16; k++) |
for (k = 0; k < 16; k++) |
193 |
for (l = 0; l < 16; l++) |
for (l = 0; l < 16; l++) |
194 |
handle->val[j*data->mb_width + i] += ptr[k*data->current.stride[0] + l]; |
sum += ptr[k*data->current.stride[0] + l]; |
195 |
|
|
196 |
/* Normalize its value */ |
handle->val[j*data->mb_width + i] = (float)sum/256.0f; |
|
handle->val[j*data->mb_width + i] /= 256.0f; |
|
197 |
|
|
198 |
/* Accumulate the global frame luminance */ |
/* Accumulate the global frame luminance */ |
199 |
global += handle->val[j*data->mb_width + i]; |
global += (float)sum/256.0f; |
|
|
|
|
/* Count the number of middle luminance blocks */ |
|
|
if ((handle->val[j*data->mb_width + i] > LowerLimit) && |
|
|
(handle->val[j*data->mb_width + i] < UpperLimit)) |
|
|
mid_range++; |
|
200 |
} |
} |
201 |
} |
} |
202 |
|
|
203 |
/* Normalize the global luminance accumulator */ |
/* Normalize the global luminance accumulator */ |
204 |
global /= data->mb_width*data->mb_height; |
global /= data->mb_width*data->mb_height; |
205 |
|
|
206 |
|
DarkThres = DarkThres*global/127.0; |
207 |
|
BrightThres = BrightThres*global/127.0; |
208 |
|
|
209 |
|
|
210 |
/* Apply luminance masking only to frames where the global luminance is |
/* Apply luminance masking only to frames where the global luminance is |
211 |
* higher than DarkThreshold and lower than Bright Threshold, or where |
* higher than DarkThreshold and lower than Bright Threshold */ |
212 |
* "middle" luminance blocks are lower than its corresponding threshold */ |
if ((global < GlobalBrightThres) && (global > GlobalDarkThres)) { |
|
if (((global < GlobalBrightThres) && (global > GlobalDarkThres)) || |
|
|
(mid_range < MidRangeThres)) { |
|
213 |
|
|
214 |
/* Apply the luminance masking formulas to all MBs */ |
/* Apply the luminance masking formulas to all MBs */ |
215 |
for (i = 0; i < data->mb_height; i++) { |
for (i = 0; i < data->mb_height; i++) { |
216 |
for (j = 0; j < data->mb_width; j++) { |
for (j = 0; j < data->mb_width; j++) { |
217 |
if (handle->val[i*data->mb_width + j] < DarkThres) |
if (handle->val[i*data->mb_width + j] < DarkThres) |
218 |
handle->quant[i*data->mb_width + j] += DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres; |
handle->quant[i*data->mb_width + j] *= 1 + DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres; |
219 |
else if (handle->val[i*data->mb_width + j] > BrightThres) |
else if (handle->val[i*data->mb_width + j] > BrightThres) |
220 |
handle->quant[i*data->mb_width + j] += BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres); |
handle->quant[i*data->mb_width + j] *= 1 + BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres); |
221 |
} |
} |
222 |
} |
} |
223 |
} |
} |
227 |
data->dquant, |
data->dquant, |
228 |
data->mb_width*data->mb_height, |
data->mb_width*data->mb_height, |
229 |
data->quant, |
data->quant, |
230 |
data->quant*2); |
data->quant + data->quant/2); |
231 |
|
|
232 |
/* Plugin job finished */ |
/* Plugin job finished */ |
233 |
return(0); |
return(0); |