FS-10050 polish
This commit is contained in:
parent
be245edf5e
commit
91d62b7cc6
|
@ -412,12 +412,12 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
|
|||
LIBS="$LIBS -m64"
|
||||
fi
|
||||
elif test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -fPIC)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -fPIC)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -fPIC -ffast-math)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -fPIC -ffast-math)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -Werror)
|
||||
elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -fPIC)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -fPIC)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -fPIC -ffast-math)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -fPIC -ffast-math)
|
||||
AC_SUBST([AM_MOD_AVMD_CXXFLAGS], [-std=gnu99]) # FS-8809, needed for MAP_POPULATE
|
||||
if test "$ac_cv_gcc_supports_w_no_unused_result" = yes; then
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -Werror)
|
||||
|
|
|
@ -77,6 +77,24 @@ typedef struct switch_rgb_color_s {
|
|||
uint8_t b;
|
||||
} switch_rgb_color_t;
|
||||
|
||||
typedef struct switch_hsl_color_s {
|
||||
double h;
|
||||
double s;
|
||||
double l;
|
||||
} switch_hsl_color_t;
|
||||
|
||||
typedef struct {
|
||||
double l;
|
||||
double a;
|
||||
double b;
|
||||
} switch_lab_color_t;
|
||||
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} switch_xyz_color_t;
|
||||
|
||||
/**\brief Representation of a rectangle on a surface */
|
||||
typedef struct switch_image_rect {
|
||||
unsigned int x; /**< leftmost column */
|
||||
|
@ -391,7 +409,7 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src
|
|||
/*!\brief chromakey an img, img must be RGBA and return modified img */
|
||||
|
||||
SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold);
|
||||
SWITCH_DECLARE(void) switch_img_chromakey_multi(switch_image_t *img, switch_rgb_color_t *mask, int *thresholds, int count);
|
||||
SWITCH_DECLARE(void) switch_img_chromakey_multi(switch_image_t *img, switch_image_t *cache_img, switch_rgb_color_t *mask, int *thresholds, int count);
|
||||
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
|
|
@ -43,8 +43,10 @@ SWITCH_MODULE_DEFINITION(mod_video_filter, mod_video_filter_load, mod_video_filt
|
|||
typedef struct chromakey_context_s {
|
||||
int threshold;
|
||||
switch_image_t *bgimg;
|
||||
switch_image_t *backup_img;
|
||||
switch_image_t *bgimg_scaled;
|
||||
switch_image_t *last_img;
|
||||
void *data;
|
||||
switch_size_t datalen;
|
||||
switch_file_handle_t vfh;
|
||||
switch_rgb_color_t bgcolor;
|
||||
switch_rgb_color_t mask[MAX_MASK];
|
||||
|
@ -69,6 +71,9 @@ static void uninit_context(chromakey_context_t *context)
|
|||
switch_core_file_close(&context->vfh);
|
||||
memset(&context->vfh, 0, sizeof(context->vfh));
|
||||
}
|
||||
|
||||
switch_img_free(&context->last_img);
|
||||
switch_safe_free(context->data);
|
||||
}
|
||||
|
||||
static void parse_params(chromakey_context_t *context, int start, int argc, char **argv, const char **function, switch_media_bug_flag_t *flags)
|
||||
|
@ -76,6 +81,9 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
|
|||
int n = argc - start;
|
||||
int i = start;
|
||||
|
||||
switch_core_session_request_video_refresh(context->session);
|
||||
switch_core_media_gen_key_frame(context->session);
|
||||
|
||||
switch_mutex_lock(context->command_mutex);
|
||||
|
||||
if (n > 0 && argv[i]) { // color
|
||||
|
@ -183,7 +191,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
chromakey_context_t *context = (chromakey_context_t *)user_data;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_image_t *img = NULL;
|
||||
void *data = NULL;
|
||||
switch_size_t bytes;
|
||||
|
||||
if (!switch_channel_ready(channel)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
@ -194,17 +202,27 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
}
|
||||
|
||||
if (switch_mutex_trylock(context->command_mutex) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_img_patch(frame->img, context->backup_img, 0, 0);
|
||||
switch_img_patch(frame->img, context->last_img, 0, 0);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
data = malloc(frame->img->d_w * frame->img->d_h * 4);
|
||||
switch_assert(data);
|
||||
bytes = frame->img->d_w * frame->img->d_h * 4;
|
||||
|
||||
if (bytes > context->datalen) {
|
||||
context->data = realloc(context->data, bytes);
|
||||
context->datalen = bytes;
|
||||
}
|
||||
|
||||
switch_assert(context->data);
|
||||
|
||||
switch_img_to_raw(frame->img, context->data, frame->img->d_w * 4, SWITCH_IMG_FMT_ARGB);
|
||||
img = switch_img_wrap(NULL, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h, 1, context->data);
|
||||
|
||||
switch_img_to_raw(frame->img, data, frame->img->d_w * 4, SWITCH_IMG_FMT_ARGB);
|
||||
img = switch_img_wrap(NULL, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h, 1, data);
|
||||
switch_assert(img);
|
||||
switch_img_chromakey_multi(img, context->mask, context->thresholds, context->mask_len);
|
||||
switch_img_chromakey_multi(img, context->last_img, context->mask, context->thresholds, context->mask_len);
|
||||
|
||||
switch_img_free(&context->last_img);
|
||||
switch_img_copy(img, &context->last_img);
|
||||
|
||||
if (context->bgimg) {
|
||||
if (context->bgimg_scaled && (context->bgimg_scaled->d_w != frame->img->d_w || context->bgimg_scaled->d_h != frame->img->d_h)) {
|
||||
|
@ -261,10 +279,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
}
|
||||
|
||||
switch_img_patch(frame->img, img, 0, 0);
|
||||
switch_img_free(&context->backup_img);
|
||||
switch_img_copy(frame->img, &context->backup_img);
|
||||
switch_img_free(&img);
|
||||
free(data);
|
||||
|
||||
switch_mutex_unlock(context->command_mutex);
|
||||
|
||||
|
@ -313,7 +328,7 @@ SWITCH_STANDARD_APP(chromakey_start_function)
|
|||
char *argv[4] = { 0 };
|
||||
int argc;
|
||||
char *lbuf;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING | SMBF_READ_VIDEO_PATCH;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING;// SMBF_READ_VIDEO_PATCH;
|
||||
const char *function = "chromakey";
|
||||
chromakey_context_t *context;
|
||||
|
||||
|
|
|
@ -318,24 +318,21 @@ SWITCH_DECLARE(void) switch_img_patch(switch_image_t *IMG, switch_image_t *img,
|
|||
|
||||
for (i = 0; i < max_h; i++) {
|
||||
for (j = 0; j < max_w; j++) {
|
||||
alpha = img->planes[SWITCH_PLANE_PACKED][i * img->stride[SWITCH_PLANE_PACKED] + j * 4];
|
||||
rgb = (switch_rgb_color_t *)(img->planes[SWITCH_PLANE_PACKED] + i * img->stride[SWITCH_PLANE_PACKED] + j * 4);
|
||||
alpha = rgb->a;
|
||||
|
||||
if (alpha > 0) {
|
||||
if (alpha == 255) {
|
||||
switch_img_draw_pixel(IMG, x + j, y + i, rgb);
|
||||
} else if (alpha != 0) {
|
||||
switch_rgb_color_t RGB = { 0 };
|
||||
|
||||
switch_img_get_rgb_pixel(IMG, &RGB, x + j, y + i);
|
||||
rgb = (switch_rgb_color_t *)(img->planes[SWITCH_PLANE_PACKED] + i * img->stride[SWITCH_PLANE_PACKED] + j * 4);
|
||||
|
||||
if (alpha < 255) {
|
||||
RGB.a = 255;
|
||||
RGB.r = ((RGB.r * (255 - alpha)) >> 8) + ((rgb->r * alpha) >> 8);
|
||||
RGB.g = ((RGB.g * (255 - alpha)) >> 8) + ((rgb->g * alpha) >> 8);
|
||||
RGB.b = ((RGB.b * (255 - alpha)) >> 8) + ((rgb->b * alpha) >> 8);
|
||||
|
||||
switch_img_draw_pixel(IMG, x + j, y + i, &RGB);
|
||||
} else {
|
||||
switch_img_draw_pixel(IMG, x + j, y + i, rgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -543,33 +540,360 @@ SWITCH_DECLARE(switch_image_t *) switch_img_copy_rect(switch_image_t *img, uint3
|
|||
#endif
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_img_chromakey_multi(switch_image_t *img, switch_rgb_color_t *mask, int *thresholds, int count)
|
||||
|
||||
static inline void switch_core_rgb2xyz(switch_rgb_color_t *rgb, switch_xyz_color_t *xyz)
|
||||
{
|
||||
uint8_t *pixel, *last_pixel = NULL;
|
||||
double r, g, b;
|
||||
|
||||
r = (double)rgb->r / 255;
|
||||
g = (double)rgb->g / 255;
|
||||
b = (double)rgb->b / 255;
|
||||
|
||||
if ( r > 0.04045 ) {
|
||||
r = ( ( r + 0.055 ) / 1.055 );
|
||||
r = pow(r, 2.4);
|
||||
} else {
|
||||
r = r / 12.92;
|
||||
}
|
||||
|
||||
if ( g > 0.04045 ) {
|
||||
g = ( ( g + 0.055 ) / 1.055 );
|
||||
g = pow(g, 2.4);
|
||||
} else {
|
||||
g = g / 12.92;
|
||||
}
|
||||
|
||||
if ( b > 0.04045 ) {
|
||||
b = ( ( b + 0.055 ) / 1.055 );
|
||||
b = pow(b, 2.4);
|
||||
} else {
|
||||
b = b / 12.92;
|
||||
}
|
||||
|
||||
r = r * 100;
|
||||
g = g * 100;
|
||||
b = b * 100;
|
||||
|
||||
//Observer. = 2degrees, Illuminant = D65
|
||||
xyz->x = r * 0.4124 + g * 0.3576 + b * 0.1805;
|
||||
xyz->y = r * 0.2126 + g * 0.7152 + b * 0.0722;
|
||||
xyz->z = r * 0.0193 + g * 0.1192 + b * 0.9505;
|
||||
|
||||
}
|
||||
|
||||
#define SVMAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define SVMAX3(a,b,c) (SVMAX((a), SVMAX((b),(c))))
|
||||
#define SVMIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define SVMIN3(a,b,c) (SVMIN((a), SVMIN((b),(c))))
|
||||
|
||||
|
||||
static inline void switch_core_rgb2hsl(switch_rgb_color_t *rgb, switch_hsl_color_t *hsl)
|
||||
{
|
||||
double r, g, b, max, min;
|
||||
|
||||
r = (double)rgb->r / 255;
|
||||
g = (double)rgb->g / 255;
|
||||
b = (double)rgb->b / 255;
|
||||
|
||||
max = SVMAX3(r, g, b);
|
||||
min = SVMIN3(r, g, b);
|
||||
|
||||
hsl->l = (max + min) / 2;
|
||||
|
||||
if (max != min) {
|
||||
double d = max - min;
|
||||
|
||||
hsl->s = hsl->l > 0.5f ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
if (max == r) {
|
||||
hsl->h = (g - b) / (max - min);
|
||||
} else if(max == g) {
|
||||
hsl->h = 2.0 + ((b - r) / (max - min));
|
||||
} else {
|
||||
hsl->h = 4.0 + ((r - g) / (max - min));
|
||||
}
|
||||
} else {
|
||||
hsl->h = hsl->s = 0;
|
||||
}
|
||||
|
||||
hsl->h = round(hsl->h * 60);
|
||||
if (hsl->h < 0) hsl->h += 360;
|
||||
|
||||
hsl->s *= 100;
|
||||
hsl->l *= 100;
|
||||
|
||||
}
|
||||
|
||||
static inline void switch_core_rgb2lab(switch_rgb_color_t *rgb, switch_lab_color_t *lab)
|
||||
{
|
||||
double x,y,z;
|
||||
double r = rgb->r;
|
||||
double g = rgb->g;
|
||||
double b = rgb->b;
|
||||
|
||||
r=r>10.31475 ? 1.474000611989649e-6 * pow(r+14.025 , 2.4) : r * 0.0003035269835488375;
|
||||
g=g>10.31475 ? 1.474000611989649e-6 * pow(g+14.025 , 2.4) : g * 0.0003035269835488375;
|
||||
b=b>10.31475 ? 1.474000611989649e-6 * pow(b+14.025 , 2.4) : b * 0.0003035269835488375;
|
||||
x=r * 0.43394994055572506 + g * 0.3762097699033109 + b * 0.18984028954096394;
|
||||
y=r * 0.2126729 + g * 0.7151522 + b * 0.0721750;
|
||||
z=r * 0.017756582753965265 + g * 0.10946796102238182 + b * 0.8727754562236529;
|
||||
|
||||
|
||||
x = x > 0.008856452 ? pow(x , 0.3333333333333333) : 7.787037037037037 * x + 0.13793103448275862;
|
||||
y = y > 0.008856452 ? pow(y , 0.3333333333333333) : 7.787037037037037 * y + 0.13793103448275862;
|
||||
z = z > 0.008856452 ? pow(z , 0.3333333333333333) : 7.787037037037037 * z + 0.13793103448275862;
|
||||
|
||||
lab->l = 116 * y - 16;
|
||||
lab->a = 500 * (x - y);
|
||||
lab->b = 200 * (y - z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Computes the CIEDE2000 color-difference between two Lab colors
|
||||
/// Based on the article:
|
||||
/// The CIEDE2000 Color-Difference Formula: Implementation Notes,
|
||||
/// Supplementary Test Data, and Mathematical Observations,", G. Sharma,
|
||||
/// W. Wu, E. N. Dalal, submitted to Color Research and Application,
|
||||
/// January 2004.
|
||||
/// Available at http://www.ece.rochester.edu/~/gsharma/ciede2000/
|
||||
/// Based on the C++ implementation by Ofir Pele, The Hebrew University of Jerusalem 2010.
|
||||
//
|
||||
static inline double switch_CIEDE2000(switch_lab_color_t *lab1, switch_lab_color_t *lab2)
|
||||
{
|
||||
double Lstd = lab1->l;
|
||||
double astd = lab1->a;
|
||||
double bstd = lab1->b;
|
||||
double pi = M_PI;
|
||||
|
||||
double Lsample = lab2->l;
|
||||
double asample = lab2->a;
|
||||
double bsample = lab2->b;
|
||||
|
||||
//double _kL = 1.0;
|
||||
//double _kC = 1.0;
|
||||
//double _kH = 1.0;
|
||||
|
||||
double Cabstd= sqrt(astd*astd+bstd*bstd);
|
||||
double Cabsample= sqrt(asample*asample+bsample*bsample);
|
||||
|
||||
double Cabarithmean= (Cabstd + Cabsample)/2.0;
|
||||
|
||||
double G= 0.5*( 1.0 - sqrt( pow(Cabarithmean,7.0)/(pow(Cabarithmean,7.0) + pow(25.0,7.0))));
|
||||
|
||||
double apstd= (1.0+G)*astd; // aprime in paper
|
||||
double apsample= (1.0+G)*asample; // aprime in paper
|
||||
double Cpsample= sqrt(apsample*apsample+bsample*bsample);
|
||||
|
||||
double Cpstd= sqrt(apstd*apstd+bstd*bstd);
|
||||
// Compute product of chromas
|
||||
double Cpprod= (Cpsample*Cpstd);
|
||||
|
||||
|
||||
double hpsample, dL, dC, dhp, dH, Lp, Cp;
|
||||
double hp, Lpm502, Sl, Sc, T, Sh, delthetarad, Rc, RT;
|
||||
|
||||
// Ensure hue is between 0 and 2pi
|
||||
double hpstd= atan2(bstd,apstd);
|
||||
if (hpstd<0) hpstd+= 2.0*pi; // rollover ones that come -ve
|
||||
|
||||
hpsample= atan2(bsample,apsample);
|
||||
if (hpsample<0) hpsample+= 2.0*pi;
|
||||
if ( (fabs(apsample)+fabs(bsample))==0.0) hpsample= 0.0;
|
||||
|
||||
dL= (Lsample-Lstd);
|
||||
dC= (Cpsample-Cpstd);
|
||||
|
||||
// Computation of hue difference
|
||||
dhp= (hpsample-hpstd);
|
||||
if (dhp>pi) dhp-= 2.0*pi;
|
||||
if (dhp<-pi) dhp+= 2.0*pi;
|
||||
// set chroma difference to zero if the product of chromas is zero
|
||||
if (Cpprod == 0.0) dhp= 0.0;
|
||||
|
||||
// Note that the defining equations actually need
|
||||
// signed Hue and chroma differences which is different
|
||||
// from prior color difference formulae
|
||||
|
||||
dH= 2.0*sqrt(Cpprod)*sin(dhp/2.0);
|
||||
//%dH2 = 4*Cpprod.*(sin(dhp/2)).^2;
|
||||
|
||||
// weighting functions
|
||||
Lp= (Lsample+Lstd)/2.0;
|
||||
Cp= (Cpstd+Cpsample)/2.0;
|
||||
|
||||
// Average Hue Computation
|
||||
// This is equivalent to that in the paper but simpler programmatically.
|
||||
// Note average hue is computed in radians and converted to degrees only
|
||||
// where needed
|
||||
hp= (hpstd+hpsample)/2.0;
|
||||
// Identify positions for which abs hue diff exceeds 180 degrees
|
||||
if ( fabs(hpstd-hpsample) > pi ) hp-= pi;
|
||||
// rollover ones that come -ve
|
||||
if (hp<0) hp+= 2.0*pi;
|
||||
|
||||
// Check if one of the chroma values is zero, in which case set
|
||||
// mean hue to the sum which is equivalent to other value
|
||||
if (Cpprod==0.0) hp= hpsample+hpstd;
|
||||
|
||||
Lpm502= (Lp-50.0)*(Lp-50.0);;
|
||||
Sl= 1.0+0.015*Lpm502/sqrt(20.0+Lpm502);
|
||||
Sc= 1.0+0.045*Cp;
|
||||
T= 1.0 - 0.17*cos(hp - pi/6.0) + 0.24*cos(2.0*hp) + 0.32*cos(3.0*hp+pi/30.0) - 0.20*cos(4.0*hp-63.0*pi/180.0);
|
||||
Sh= 1.0 + 0.015*Cp*T;
|
||||
delthetarad= (30.0*pi/180.0)*exp(- pow(( (180.0/pi*hp-275.0)/25.0),2.0));
|
||||
Rc= 2.0*sqrt(pow(Cp,7.0)/(pow(Cp,7.0) + pow(25.0,7.0)));
|
||||
RT= -sin(2.0*delthetarad)*Rc;
|
||||
|
||||
// The CIE 00 color difference
|
||||
return sqrt( pow((dL/Sl),2.0) + pow((dC/Sc),2.0) + pow((dH/Sh),2.0) + RT*(dC/Sc)*(dH/Sh) );
|
||||
}
|
||||
|
||||
|
||||
static inline int switch_color_distance(switch_rgb_color_t *c1, switch_rgb_color_t *c2)
|
||||
{
|
||||
int cr, cg, cb;
|
||||
int cr2, cg2, cb2;
|
||||
double a, b;
|
||||
int aa, bb, r;
|
||||
|
||||
|
||||
cr = c1->r - c2->r;
|
||||
cg = c1->g - c2->g;
|
||||
cb = c1->b - c2->b;
|
||||
|
||||
if (!cr && !cg && !cb) return 0;
|
||||
|
||||
cr2 = c1->r/2 - c2->r/2;
|
||||
cg2 = c1->g/2 - c2->g/2;
|
||||
cb2 = c1->b/2 - c2->b/2;
|
||||
|
||||
a = sqrt((2*cr*cr) + (4*cg*cg) + (3*cb*cb));
|
||||
b = sqrt((2*cr2*cr2) + (4*cg2*cg2) + (3*cb2*cb2));
|
||||
|
||||
aa = (int)a;
|
||||
bb = (int)b*5;
|
||||
|
||||
r = (((bb*2)+(aa))/3)/10;
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
static inline int switch_color_distance_multi(switch_rgb_color_t *c1, switch_rgb_color_t *clist, int count, int *thresholds)
|
||||
{
|
||||
int x = 0, hits = 0;
|
||||
|
||||
for (x = 0; x < count; x++) {
|
||||
int distance = switch_color_distance(c1, &clist[x]);
|
||||
|
||||
if (distance <= thresholds[x]) {
|
||||
hits++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static inline int switch_color_distance_cheap(switch_rgb_color_t *c1, switch_rgb_color_t *c2)
|
||||
{
|
||||
int r = c1->r - c2->r;
|
||||
int g = c1->g - c2->g;
|
||||
int b = c1->b - c2->b;
|
||||
|
||||
if (!r && !g && !b) return 0;
|
||||
|
||||
return (3*abs(r)) + (4*abs(g)) + (3*abs(b));
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_img_chromakey_multi(switch_image_t *img, switch_image_t *cache_img, switch_rgb_color_t *mask, int *thresholds, int count)
|
||||
{
|
||||
uint8_t *pixel, *last_pixel = NULL, *cache_pixel = NULL, *end_pixel = NULL;
|
||||
int last_hits = 0;
|
||||
|
||||
#ifdef DEBUG_CHROMA
|
||||
int other_img_cached = 0, color_cached = 0, checked = 0, hit_total = 0, total_pixel = 0, delta_hits = 0;
|
||||
#endif
|
||||
|
||||
|
||||
switch_assert(img);
|
||||
|
||||
if (img->fmt != SWITCH_IMG_FMT_ARGB) return;
|
||||
|
||||
pixel = img->planes[SWITCH_PLANE_PACKED];
|
||||
|
||||
for (; pixel < (img->planes[SWITCH_PLANE_PACKED] + img->d_w * img->d_h * 4); pixel += 4) {
|
||||
if (cache_img && (cache_img->d_w != img->d_w || cache_img->d_h != img->d_h)) {
|
||||
cache_img = NULL;
|
||||
}
|
||||
|
||||
if (cache_img) {
|
||||
cache_pixel = cache_img->planes[SWITCH_PLANE_PACKED];
|
||||
}
|
||||
|
||||
end_pixel = (img->planes[SWITCH_PLANE_PACKED] + img->d_w * img->d_h * 4);
|
||||
|
||||
for (; pixel < end_pixel; pixel += 4) {
|
||||
switch_rgb_color_t *color = (switch_rgb_color_t *)pixel;
|
||||
switch_rgb_color_t *last_color = (switch_rgb_color_t *)last_pixel;
|
||||
int hits = 0;
|
||||
|
||||
if (last_pixel && (*(uint32_t *)pixel & 0xFFFFFF) == (*(uint32_t *)last_pixel & 0xFFFFFF)) {
|
||||
hits = last_hits;
|
||||
} else {
|
||||
hits = switch_color_distance_multi(color, mask, count, thresholds);
|
||||
#ifdef DEBUG_CHROMA
|
||||
total_pixel++;
|
||||
#endif
|
||||
|
||||
if (cache_img && cache_pixel) {
|
||||
switch_rgb_color_t *cache_color = (switch_rgb_color_t *)cache_pixel;
|
||||
|
||||
if (switch_color_distance_cheap(color, cache_color) < 5) {
|
||||
#ifdef DEBUG_CHROMA
|
||||
other_img_cached++;
|
||||
#endif
|
||||
*pixel = *cache_pixel;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
last_hits = hits;
|
||||
last_pixel = pixel;
|
||||
|
||||
if (last_color && switch_color_distance_cheap(color, last_color) < 5) {
|
||||
|
||||
hits = last_hits;
|
||||
#ifdef DEBUG_CHROMA
|
||||
color_cached++;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!hits) {
|
||||
hits = switch_color_distance_multi(color, mask, count, thresholds);
|
||||
|
||||
#ifdef DEBUG_CHROMA
|
||||
checked++;
|
||||
#endif
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (cache_pixel) {
|
||||
cache_pixel += 4;
|
||||
}
|
||||
|
||||
if (hits) {
|
||||
#ifdef DEBUG_CHROMA
|
||||
hit_total++;
|
||||
#endif
|
||||
*pixel = 0;
|
||||
}
|
||||
|
||||
last_pixel = pixel;
|
||||
last_hits = hits;
|
||||
}
|
||||
#ifdef DEBUG_CHROMA
|
||||
printf("total %d: other img cache %d color cache %d Checked %d Hit Total %d Delta hits: %d\n", total_pixel, other_img_cached, color_cached, checked, hit_total, delta_hits);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -845,35 +1169,6 @@ static inline void switch_color_rgb2yuv(switch_rgb_color_t *rgb, switch_yuv_colo
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline int switch_color_distance(switch_rgb_color_t *c1, switch_rgb_color_t *c2)
|
||||
{
|
||||
//int rmean = ( c1->r + c2->r ) / 2;
|
||||
int r = c1->r - c2->r;
|
||||
int g = c1->g - c2->g;
|
||||
int b = c1->b - c2->b;
|
||||
|
||||
return sqrt((2*r*r) + (4*g*g) + (3*b*b));
|
||||
//return (3*abs(r)) + (4*abs(g)) + (3*abs(b)) / 3;
|
||||
//return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
|
||||
}
|
||||
|
||||
static inline int switch_color_distance_multi(switch_rgb_color_t *c1, switch_rgb_color_t *clist, int count, int *thresholds)
|
||||
{
|
||||
int x = 0, hits = 0;
|
||||
|
||||
for (x = 0; x < count; x++) {
|
||||
int distance = switch_color_distance(c1, &clist[x]);
|
||||
|
||||
if (distance <= thresholds[x]) {
|
||||
hits++;
|
||||
}
|
||||
}
|
||||
|
||||
return hits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CLAMP(val) MAX(0, MIN(val, 255))
|
||||
|
||||
#ifdef SWITCH_HAVE_YUV
|
||||
|
|
|
@ -6672,12 +6672,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) {
|
||||
pt = 200000;
|
||||
pt = 100000;
|
||||
}
|
||||
|
||||
if (rtp_session->vb) {
|
||||
if (switch_jb_poll(rtp_session->vb)) {
|
||||
pt = 0;
|
||||
pt = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6687,7 +6687,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
|
||||
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
|
||||
|
||||
|
||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
|
||||
return_cng_frame();
|
||||
}
|
||||
|
@ -7196,8 +7195,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
do_continue:
|
||||
|
||||
if (!bytes && !rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
|
||||
|
||||
if (sleep_mss) {
|
||||
switch_yield(sleep_mss);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue