1 #include "colormodels.h"
10 unsigned int EffectTV::fastrand_val = 0;
12 EffectTV::EffectTV(int w, int h)
16 background = (unsigned char*)new uint16_t[w * h];
17 diff = new unsigned char[w * h];
18 diff2 = new unsigned char[w * h];
30 int EffectTV::yuv_init()
34 for(i = 0; i < 256; i++)
36 YtoRGB[i] = (int)( 1.164 * (i - 16));
37 VtoR[i] = (int)( 1.596 * (i - 128));
38 VtoG[i] = (int)(-0.813 * (i - 128));
39 UtoG[i] = (int)(-0.391 * (i - 128));
40 UtoB[i] = (int)( 2.018 * (i - 128));
41 RtoY[i] = (int)( 0.257 * i);
42 RtoU[i] = (int)(-0.148 * i);
43 RtoV[i] = (int)( 0.439 * i);
44 GtoY[i] = (int)( 0.504 * i);
45 GtoU[i] = (int)(-0.291 * i);
46 GtoV[i] = (int)(-0.368 * i);
47 BtoY[i] = (int)( 0.098 * i);
48 BtoV[i] = (int)(-0.071 * i);
49 //printf("EffectTV::yuv_init %d %d %d\n", RtoY[i], GtoY[i], BtoY[i]);
55 #define FRAME_TO_EFFECTTV(type, components) \
57 for(int i = 0; i < width; i++) \
59 uint32_t *row = tmp + i * width * sizeof(uint32_t); \
60 type *input_row = ((type**)frame->get_rows())[i]; \
62 for(int j = 0; j < width; j++) \
64 if(sizeof(type) == 1) \
66 row[j * sizeof(uint32_t)] = ((uint32_t)input_row[0]) << 16; \
67 row[j * sizeof(uint32_t)] |= ((uint32_t)input_row[1]) << 8; \
68 row[j * sizeof(uint32_t)] |= input_row[2]; \
72 row[j * sizeof(uint32_t)] = ((uint32_t)input_row[0]) << 8; \
73 row[j * sizeof(uint32_t)] |= ((uint32_t)input_row[1]); \
74 row[j * sizeof(uint32_t)] |= input_row[2] >> 8; \
76 input_row += components; \
83 void EffectTV::frame_to_effecttv(VFrame *frame, uint32_t *tmp)
85 int width = frame->get_w();
86 int height = frame->get_h();
88 switch(frame->get_color_model())
92 FRAME_TO_EFFECTTV(uint8_t, 3);
97 FRAME_TO_EFFECTTV(uint8_t, 4);
102 FRAME_TO_EFFECTTV(uint16_t, 3);
105 case BC_RGBA16161616:
106 case BC_YUVA16161616:
107 FRAME_TO_EFFECTTV(uint16_t, 4);
114 #define EFFECTTV_TO_FRAME(type, components) \
116 for(int i = 0; i < width; i++) \
118 uint32_t *row = tmp + i * width * sizeof(uint32_t); \
119 type *output_row = ((type**)frame->get_rows())[i]; \
121 for(int j = 0; j < width; j++) \
123 if(sizeof(type) == 1) \
125 output_row[0] = (row[j * sizeof(uint32_t)] & 0xff0000) >> 16; \
126 output_row[1] = (row[j * sizeof(uint32_t)] & 0xff00) >> 8; \
127 output_row[2] = row[j * sizeof(uint32_t)] & 0xff; \
128 if(components == 4) output_row[3] = 0xff; \
132 output_row[0] = (row[j * sizeof(uint32_t)] & 0xff0000) >> 8; \
133 output_row[1] = row[j * sizeof(uint32_t)] & 0xff00; \
134 output_row[2] = (row[j * sizeof(uint32_t)] & 0xff) << 8; \
135 if(components == 4) output_row[3] = 0xffff; \
137 output_row += components; \
144 void EffectTV::effecttv_to_frame(VFrame *frame, uint32_t *tmp)
146 int width = frame->get_w();
147 int height = frame->get_h();
149 switch(frame->get_color_model())
153 EFFECTTV_TO_FRAME(uint8_t, 3);
158 EFFECTTV_TO_FRAME(uint8_t, 4);
163 EFFECTTV_TO_FRAME(uint16_t, 3);
166 case BC_RGBA16161616:
167 case BC_YUVA16161616:
168 EFFECTTV_TO_FRAME(uint16_t, 4);
175 void EffectTV::image_set_threshold_y(int threshold)
177 y_threshold = threshold * 7; /* fake-Y value is timed by 7 */
182 /* Background image is refreshed every frame */
183 #define IMAGE_BGSUBTRACT_UPDATE_Y(result, \
195 q = (int16_t *)background; \
198 for(i = 0; i < h; i++) \
200 p = (type*)input_rows[j]; \
202 for(j = 0; j < w; j++) \
204 if(sizeof(type) == 2) \
206 R = p[0] >> (8 - 1); \
207 G = p[1] >> (8 - 2); \
217 v = (R + G + B) - (int)(*q); \
218 *q = (int16_t)(R + G + B); \
219 *r = ((v + y_threshold) >> 24) | ((y_threshold - v) >> 24); \
236 unsigned char* EffectTV::image_bgsubtract_update_y(unsigned char **input_rows,
237 unsigned char **output_rows,
247 IMAGE_BGSUBTRACT_UPDATE_Y(diff,
254 IMAGE_BGSUBTRACT_UPDATE_Y(diff,
261 IMAGE_BGSUBTRACT_UPDATE_Y(diff,
266 case BC_RGBA16161616:
267 case BC_YUVA16161616:
268 IMAGE_BGSUBTRACT_UPDATE_Y(diff,
283 #define IMAGE_BGSUBTRACT_Y(type, components) \
289 for(i = 0; i < h; i++) \
291 p = (type*)input_rows[i]; \
293 for(j = 0; j < w; j++) \
295 if(sizeof(type) == 2) \
297 R = p[0] >> (8 - 1); \
298 G = p[1] >> (8 - 2); \
308 v = (R + G + B) - (int)(*q); \
309 *r = ((v + y_threshold) >> 24) | ((y_threshold - v) >> 24); \
319 unsigned char* EffectTV::image_bgsubtract_y(unsigned char **input_rows, int color_model)
325 q = (int16_t *)background;
334 IMAGE_BGSUBTRACT_Y(uint8_t, 3);
338 IMAGE_BGSUBTRACT_Y(uint8_t, 4);
342 IMAGE_BGSUBTRACT_Y(uint16_t, 3);
344 case BC_RGBA16161616:
345 case BC_YUVA16161616:
346 IMAGE_BGSUBTRACT_Y(uint16_t, 4);
357 /* The origin of subtraction function is;
358 * diff(src, dest) = (abs(src - dest) > threshold) ? 0xff : 0;
360 * This functions is transformed to;
361 * (threshold > (src - dest) > -threshold) ? 0 : 0xff;
363 * (v + threshold)>>24 is 0xff when v is less than -threshold.
364 * (v - threshold)>>24 is 0xff when v is less than threshold.
365 * So, ((v + threshold)>>24) | ((threshold - v)>>24) will become 0xff when
366 * abs(src - dest) > threshold.
375 unsigned char* EffectTV::image_diff_filter(unsigned char *diff)
378 unsigned char *src, *dest;
380 unsigned int sum1, sum2, sum3;
385 dest = diff2 + width + 1;
386 for(y = 1; y < height - 1; y++)
388 sum1 = src[0] + src[width] + src[width * 2];
389 sum2 = src[1] + src[width + 1] + src[width * 2 + 1];
392 for(x = 1; x < width - 1; x++)
394 sum3 = src[0] + src[width] + src[width * 2];
395 count = sum1 + sum2 + sum3;
398 *dest++ = (0xff * 3 - count) >> 24;
413 #define IMAGE_BGSET_Y(type, components) \
419 int width = frame->get_w(); \
420 int height = frame->get_h(); \
422 q = (int16_t *)background; \
426 for(i = 0; i < height; i++) \
428 p = (type*)frame->get_rows()[i]; \
430 for(j = 0; j < width; j++) \
432 if(sizeof(type) == 2) \
434 R = p[0] >> (8 - 1); \
435 G = p[1] >> (8 - 2); \
445 *q = (int16_t)(R + G + B); \
458 void EffectTV::image_bgset_y(VFrame *frame)
460 switch(frame->get_color_model())
464 IMAGE_BGSET_Y(uint8_t, 3);
468 IMAGE_BGSET_Y(uint8_t, 4);
472 IMAGE_BGSET_Y(uint16_t, 3);
474 case BC_RGBA16161616:
475 case BC_YUVA16161616:
476 IMAGE_BGSET_Y(uint16_t, 4);