eq2.c

来自「linux下的MPEG1」· C语言 代码 · 共 632 行 · 第 1/2 页

C
632
字号
/* * Copyright (C) 2000-2006 the xine project *  * This file is part of xine, a free video player. *  * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA * * $Id: eq2.c,v 1.18 2007/03/22 23:32:05 dgp85 Exp $ * * mplayer's eq2 (soft video equalizer) * Software equalizer (brightness, contrast, gamma, saturation) * * Hampa Hug <hampa@hampa.ch> (original LUT gamma/contrast/brightness filter) * Daniel Moreno <comac@comac.darktech.org> (saturation, R/G/B gamma support) * Richard Felker (original MMX contrast/brightness code (vf_eq.c)) */#include "xine_internal.h"#include "post.h"#include "xineutils.h"#include <math.h>#include <pthread.h>/* Per channel parameters */typedef struct eq2_param_t {  unsigned char lut[256];  int           lut_clean;  void (*adjust) (struct eq2_param_t *par, unsigned char *dst, unsigned char *src,    unsigned w, unsigned h, unsigned dstride, unsigned sstride);  double        c;  double        b;  double        g;} eq2_param_t;typedef struct vf_priv_s {  eq2_param_t param[3];  double        contrast;  double        brightness;  double        saturation;  double        gamma;  double        rgamma;  double        ggamma;  double        bgamma;  unsigned      buf_w[3];  unsigned      buf_h[3];  unsigned char *buf[3];} vf_eq2_t;staticvoid create_lut (eq2_param_t *par){  unsigned i;  double   g, v;  g = par->g;  if ((g < 0.001) || (g > 1000.0)) {    g = 1.0;  }  g = 1.0 / g;  for (i = 0; i < 256; i++) {    v = (double) i / 255.0;    v = par->c * (v - 0.5) + 0.5 + par->b;    if (v <= 0.0) {      par->lut[i] = 0;    }    else {      v = pow (v, g);      if (v >= 1.0) {        par->lut[i] = 255;      }      else {        par->lut[i] = (unsigned char) (256.0 * v);      }    }  }  par->lut_clean = 1;}#if defined(ARCH_X86) || defined(ARCH_X86_64)staticvoid affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src,  unsigned w, unsigned h, unsigned dstride, unsigned sstride){  unsigned i;  int      contrast, brightness;  unsigned dstep, sstep;  int      pel;  short    brvec[4];  short    contvec[4];    contrast = (int) (par->c * 256 * 16);  brightness = ((int) (100.0 * par->b + 100.0) * 511) / 200 - 128 - contrast / 32;  brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness;  contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast;  sstep = sstride - w;  dstep = dstride - w;  while (h-- > 0) {    asm volatile (      "movq (%5), %%mm3 \n\t"      "movq (%6), %%mm4 \n\t"      "pxor %%mm0, %%mm0 \n\t"      "movl %4, %%eax\n\t"      ASMALIGN(4)      "1: \n\t"      "movq (%0), %%mm1 \n\t"      "movq (%0), %%mm2 \n\t"      "punpcklbw %%mm0, %%mm1 \n\t"      "punpckhbw %%mm0, %%mm2 \n\t"      "psllw $4, %%mm1 \n\t"      "psllw $4, %%mm2 \n\t"      "pmulhw %%mm4, %%mm1 \n\t"      "pmulhw %%mm4, %%mm2 \n\t"      "paddw %%mm3, %%mm1 \n\t"      "paddw %%mm3, %%mm2 \n\t"      "packuswb %%mm2, %%mm1 \n\t"      "add $8, %0 \n\t"      "movq %%mm1, (%1) \n\t"      "add $8, %1 \n\t"      "decl %%eax \n\t"      "jnz 1b \n\t"      : "=r" (src), "=r" (dst)      : "0" (src), "1" (dst), "r" (w >> 3), "r" (brvec), "r" (contvec)      : "%eax"    );    for (i = w & 7; i > 0; i--) {      pel = ((*src++ * contrast) >> 12) + brightness;      if (pel & 768) {        pel = (-pel) >> 31;      }      *dst++ = pel;    }    src += sstep;    dst += dstep;  }  asm volatile ( "emms \n\t" ::: "memory" );}#endifstaticvoid apply_lut (eq2_param_t *par, unsigned char *dst, unsigned char *src,  unsigned w, unsigned h, unsigned dstride, unsigned sstride){  unsigned      i, j;  unsigned char *lut;  if (!par->lut_clean) {    create_lut (par);  }  lut = par->lut;  for (j = 0; j < h; j++) {    for (i = 0; i < w; i++) {      dst[i] = lut[src[i]];    }    src += sstride;    dst += dstride;  }}staticvoid check_values (eq2_param_t *par){  /* yuck! floating point comparisons... */  if ((par->c == 1.0) && (par->b == 0.0) && (par->g == 1.0)) {    par->adjust = NULL;  }#if defined(ARCH_X86) || defined(ARCH_X86_64)  else if (par->g == 1.0 && (xine_mm_accel() & MM_ACCEL_X86_MMX) ) {    par->adjust = &affine_1d_MMX;  }#endif  else {    par->adjust = &apply_lut;  }}staticvoid set_contrast (vf_eq2_t *eq2, double c){  eq2->contrast = c;  eq2->param[0].c = c;  eq2->param[0].lut_clean = 0;  check_values (&eq2->param[0]);}staticvoid set_brightness (vf_eq2_t *eq2, double b){  eq2->brightness = b;  eq2->param[0].b = b;  eq2->param[0].lut_clean = 0;  check_values (&eq2->param[0]);}staticvoid set_gamma (vf_eq2_t *eq2, double g){  eq2->gamma = g;  eq2->param[0].g = eq2->gamma * eq2->ggamma;  eq2->param[1].g = sqrt (eq2->bgamma / eq2->ggamma);  eq2->param[2].g = sqrt (eq2->rgamma / eq2->ggamma);  eq2->param[0].lut_clean = 0;  eq2->param[1].lut_clean = 0;  eq2->param[2].lut_clean = 0;  check_values (&eq2->param[0]);  check_values (&eq2->param[1]);  check_values (&eq2->param[2]);}staticvoid set_saturation (vf_eq2_t *eq2, double s){  eq2->saturation = s;  eq2->param[1].c = s;  eq2->param[2].c = s;  eq2->param[1].lut_clean = 0;  eq2->param[2].lut_clean = 0;  check_values (&eq2->param[1]);  check_values (&eq2->param[2]);}/* plugin class initialization function */void *eq2_init_plugin(xine_t *xine, void *);typedef struct post_plugin_eq2_s post_plugin_eq2_t;/* * this is the struct used by "parameters api"  */typedef struct eq2_parameters_s {  double gamma;  double contrast;  double brightness;  double saturation;  double rgamma;  double ggamma;  double bgamma;} eq2_parameters_t;/* * description of params struct */START_PARAM_DESCR( eq2_parameters_t )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, gamma, NULL, 0, 5, 0,             "gamma" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, brightness, NULL, -1, 1, 0,             "brightness" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, contrast, NULL, 0, 2, 0,             "contrast" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, saturation, NULL, 0, 2, 0,             "saturation" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, rgamma, NULL, 0, 5, 0,             "rgamma" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, ggamma, NULL, 0, 5, 0,             "ggamma" )PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, bgamma, NULL, 0, 5, 0,             "bgamma" )END_PARAM_DESCR( param_descr )/* plugin structure */struct post_plugin_eq2_s {  post_plugin_t post;  /* private data */  eq2_parameters_t   params;  xine_post_in_t     params_input;    vf_eq2_t           eq2;  pthread_mutex_t    lock;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?