Mercurial > mplayer.hg
view libmpcodecs/vf_eq2.c @ 7732:328bbac6224c
Fixes:
- missing check in init
- missing brackets causing failure
- nas_aformat_to_auformat not working properly
- fix hang that was finally reproducible with high disk activity
- don't cut of audio on uninit(), wait for buffer to empty
It also simplifies the event_handler, making it more readable and
implements Sidik Isani's suggestion to make the buffer size dependent on
bytes per second. I've been using it for two days and found no further
problems.
patch by Tobias Diedrich <td@sim.uni-hannover.de>
author | arpi |
---|---|
date | Sun, 13 Oct 2002 22:00:15 +0000 |
parents | b667328dc62e |
children | 610976c39408 |
line wrap: on
line source
/* * vf_eq2.c * * LUT-based software equalizer (brightness, contrast, gamma) * * Hampa Hug <hhug@student.ethz.ch> * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "../config.h" #include "../mp_msg.h" #include "img_format.h" #include "mp_image.h" #include "vf.h" typedef struct vf_priv_s { unsigned char *buf; int buf_w; int buf_h; double contrast; double bright; double gamma; unsigned char lut[256]; } vf_eq2_t; static void create_lut (vf_eq2_t *eq2) { unsigned i; double c, b, g; double v; c = eq2->contrast; b = eq2->bright; g = eq2->gamma; if ((g < 0.001) || (g > 1000.0)) { g = 1.0; } fprintf (stderr, "vf_eq2: c=%.2f b=%.2f g=%.4f\n", c, b, g); g = 1.0 / g; for (i = 0; i < 256; i++) { v = (double) i / 255.0; v = c * (v - 0.5) + 0.5 + b; if (v <= 0.0) { eq2->lut[i] = 0; } else { v = pow (v, g); if (v >= 1.0) { eq2->lut[i] = 255; } else { eq2->lut[i] = (unsigned char) (256.0 * v); } } } } /* could inline this */ static void process (unsigned char *dst, int dstride, unsigned char *src, int sstride, int w, int h, unsigned char lut[256]) { int i, j; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { *(dst++) = lut[*(src++)]; } src += sstride - w; dst += dstride - w; } } static int put_image (vf_instance_t *vf, mp_image_t *src) { mp_image_t *dst; vf_eq2_t *eq2; eq2 = vf->priv; if ((eq2->buf == NULL) || (eq2->buf_w != src->stride[0]) || (eq2->buf_h != src->h)) { eq2->buf = (unsigned char *) realloc (eq2->buf, src->stride[0] * src->h); eq2->buf_w = src->stride[0]; eq2->buf_h = src->h; } dst = vf_get_image (vf->next, src->imgfmt, MP_IMGTYPE_EXPORT, 0, src->w, src->h); dst->stride[0] = src->stride[0]; dst->stride[1] = src->stride[1]; dst->stride[2] = src->stride[2]; dst->planes[0] = vf->priv->buf; dst->planes[1] = src->planes[1]; dst->planes[2] = src->planes[2]; process ( dst->planes[0], dst->stride[0], src->planes[0], src->stride[0], src->w, src->h, eq2->lut ); return vf_next_put_image (vf, dst); } static int control (vf_instance_t *vf, int request, void *data) { vf_equalizer_t *eq; switch (request) { case VFCTRL_SET_EQUALIZER: eq = (vf_equalizer_t *) data; if (strcmp (eq->item, "gamma") == 0) { vf->priv->gamma = exp (log (8.0) * eq->value / 100.0); create_lut (vf->priv); return CONTROL_TRUE; } else if (strcmp (eq->item, "contrast") == 0) { vf->priv->contrast = (1.0 / 100.0) * (eq->value + 100); create_lut (vf->priv); return CONTROL_TRUE; } else if (strcmp (eq->item, "brightness") == 0) { vf->priv->bright = (1.0 / 100.0) * eq->value; create_lut (vf->priv); return CONTROL_TRUE; } break; case VFCTRL_GET_EQUALIZER: eq = (vf_equalizer_t *) data; if (strcmp (eq->item, "gamma") == 0) { eq->value = (int) (100.0 * log (vf->priv->gamma) / log (8.0)); return CONTROL_TRUE; } else if (strcmp (eq->item, "contrast") == 0) { eq->value = (int) (100.0 * vf->priv->contrast) - 100; return CONTROL_TRUE; } else if (strcmp (eq->item, "brightness") == 0) { eq->value = (int) (100.0 * vf->priv->bright); return CONTROL_TRUE; } break; } return vf_next_control (vf, request, data); } static int query_format (vf_instance_t *vf, unsigned fmt) { switch (fmt) { case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_CLPL: case IMGFMT_Y800: case IMGFMT_Y8: case IMGFMT_NV12: case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: return vf_next_query_format (vf, fmt); } return 0; } static void uninit (vf_instance_t *vf) { if (vf->priv != NULL) { free (vf->priv->buf); free (vf->priv); } } static int open (vf_instance_t *vf, char *args) { vf_eq2_t *eq2; vf->control = control; vf->query_format = query_format; vf->put_image = put_image; vf->uninit = uninit; vf->priv = (vf_eq2_t *) malloc (sizeof (vf_eq2_t)); eq2 = vf->priv; eq2->buf = NULL; eq2->buf_w = 0; eq2->buf_h = 0; eq2->gamma = 1.0; eq2->contrast = 1.0; eq2->bright = 0.0; if (args != NULL) { sscanf (args, "%lf:%lf:%lf", &eq2->gamma, &eq2->contrast, &eq2->bright); } create_lut (eq2); return 1; } vf_info_t vf_info_eq2 = { "LUT-based software equalizer", "eq2", "Hampa Hug", "", &open };