Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * This file is part of MPlayer.
  3.  *
  4.  * MPlayer is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * MPlayer is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
  16.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <inttypes.h>
  23.  
  24. #include "config.h"
  25. #include "mp_msg.h"
  26. #include "cpudetect.h"
  27.  
  28. #include "img_format.h"
  29. #include "mp_image.h"
  30. #include "vf.h"
  31.  
  32. #include "libvo/video_out.h"
  33.  
  34. struct vf_priv_s {
  35.         unsigned char *buf;
  36.         int brightness;
  37.         int contrast;
  38. };
  39.  
  40. #if HAVE_MMX
  41. static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  42.                     int w, int h, int brightness, int contrast)
  43. {
  44.         int i;
  45.         int pel;
  46.         int dstep = dstride-w;
  47.         int sstep = sstride-w;
  48.         short brvec[4];
  49.         short contvec[4];
  50.  
  51.         contrast = ((contrast+100)*256*16)/100;
  52.         brightness = ((brightness+100)*511)/200-128 - contrast/32;
  53.  
  54.         brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness;
  55.         contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast;
  56.  
  57.         while (h--) {
  58.                 __asm__ volatile (
  59.                         "movq (%5), %%mm3 \n\t"
  60.                         "movq (%6), %%mm4 \n\t"
  61.                         "pxor %%mm0, %%mm0 \n\t"
  62.                         "movl %4, %%eax\n\t"
  63.                         ASMALIGN(4)
  64.                         "1: \n\t"
  65.                         "movq (%0), %%mm1 \n\t"
  66.                         "movq (%0), %%mm2 \n\t"
  67.                         "punpcklbw %%mm0, %%mm1 \n\t"
  68.                         "punpckhbw %%mm0, %%mm2 \n\t"
  69.                         "psllw $4, %%mm1 \n\t"
  70.                         "psllw $4, %%mm2 \n\t"
  71.                         "pmulhw %%mm4, %%mm1 \n\t"
  72.                         "pmulhw %%mm4, %%mm2 \n\t"
  73.                         "paddw %%mm3, %%mm1 \n\t"
  74.                         "paddw %%mm3, %%mm2 \n\t"
  75.                         "packuswb %%mm2, %%mm1 \n\t"
  76.                         "add $8, %0 \n\t"
  77.                         "movq %%mm1, (%1) \n\t"
  78.                         "add $8, %1 \n\t"
  79.                         "decl %%eax \n\t"
  80.                         "jnz 1b \n\t"
  81.                         : "=r" (src), "=r" (dest)
  82.                         : "0" (src), "1" (dest), "r" (w>>3), "r" (brvec), "r" (contvec)
  83.                         : "%eax"
  84.                 );
  85.  
  86.                 for (i = w&7; i; i--)
  87.                 {
  88.                         pel = ((*src++* contrast)>>12) + brightness;
  89.                         if(pel&768) pel = (-pel)>>31;
  90.                         *dest++ = pel;
  91.                 }
  92.  
  93.                 src += sstep;
  94.                 dest += dstep;
  95.         }
  96.         __asm__ volatile ( "emms \n\t" ::: "memory" );
  97. }
  98. #endif
  99.  
  100. static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  101.                     int w, int h, int brightness, int contrast)
  102. {
  103.         int i;
  104.         int pel;
  105.         int dstep = dstride-w;
  106.         int sstep = sstride-w;
  107.  
  108.         contrast = ((contrast+100)*256*256)/100;
  109.         brightness = ((brightness+100)*511)/200-128 - contrast/512;
  110.  
  111.         while (h--) {
  112.                 for (i = w; i; i--)
  113.                 {
  114.                         pel = ((*src++* contrast)>>16) + brightness;
  115.                         if(pel&768) pel = (-pel)>>31;
  116.                         *dest++ = pel;
  117.                 }
  118.                 src += sstep;
  119.                 dest += dstep;
  120.         }
  121. }
  122.  
  123. static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  124.                        int w, int h, int brightness, int contrast);
  125.  
  126. /* FIXME: add packed yuv version of process */
  127.  
  128. static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
  129. {
  130.         mp_image_t *dmpi;
  131.  
  132.         dmpi=ff_vf_get_image(vf->next, mpi->imgfmt,
  133.                           MP_IMGTYPE_EXPORT, 0,
  134.                           mpi->w, mpi->h);
  135.  
  136.         dmpi->stride[0] = mpi->stride[0];
  137.         dmpi->planes[1] = mpi->planes[1];
  138.         dmpi->planes[2] = mpi->planes[2];
  139.         dmpi->stride[1] = mpi->stride[1];
  140.         dmpi->stride[2] = mpi->stride[2];
  141.  
  142.         if (!vf->priv->buf) vf->priv->buf = malloc(mpi->stride[0]*mpi->h);
  143.  
  144.         if ((vf->priv->brightness == 0) && (vf->priv->contrast == 0))
  145.                 dmpi->planes[0] = mpi->planes[0];
  146.         else {
  147.                 dmpi->planes[0] = vf->priv->buf;
  148.                 process(dmpi->planes[0], dmpi->stride[0],
  149.                         mpi->planes[0], mpi->stride[0],
  150.                         mpi->w, mpi->h, vf->priv->brightness,
  151.                         vf->priv->contrast);
  152.         }
  153.  
  154.         return ff_vf_next_put_image(vf,dmpi, pts);
  155. }
  156.  
  157. static int control(struct vf_instance *vf, int request, void* data)
  158. {
  159.         vf_equalizer_t *eq;
  160.  
  161.         switch (request) {
  162.         case VFCTRL_SET_EQUALIZER:
  163.                 eq = data;
  164.                 if (!strcmp(eq->item,"brightness")) {
  165.                         vf->priv->brightness = eq->value;
  166.                         return CONTROL_TRUE;
  167.                 }
  168.                 else if (!strcmp(eq->item,"contrast")) {
  169.                         vf->priv->contrast = eq->value;
  170.                         return CONTROL_TRUE;
  171.                 }
  172.                 break;
  173.         case VFCTRL_GET_EQUALIZER:
  174.                 eq = data;
  175.                 if (!strcmp(eq->item,"brightness")) {
  176.                         eq->value = vf->priv->brightness;
  177.                         return CONTROL_TRUE;
  178.                 }
  179.                 else if (!strcmp(eq->item,"contrast")) {
  180.                         eq->value = vf->priv->contrast;
  181.                         return CONTROL_TRUE;
  182.                 }
  183.                 break;
  184.         }
  185.         return ff_vf_next_control(vf, request, data);
  186. }
  187.  
  188. static int query_format(struct vf_instance *vf, unsigned int fmt)
  189. {
  190.         switch (fmt) {
  191.         case IMGFMT_YVU9:
  192.         case IMGFMT_IF09:
  193.         case IMGFMT_YV12:
  194.         case IMGFMT_I420:
  195.         case IMGFMT_IYUV:
  196.         case IMGFMT_CLPL:
  197.         case IMGFMT_Y800:
  198.         case IMGFMT_Y8:
  199.         case IMGFMT_NV12:
  200.         case IMGFMT_NV21:
  201.         case IMGFMT_444P:
  202.         case IMGFMT_422P:
  203.         case IMGFMT_411P:
  204.                 return ff_vf_next_query_format(vf, fmt);
  205.         }
  206.         return 0;
  207. }
  208.  
  209. static void uninit(struct vf_instance *vf)
  210. {
  211.         free(vf->priv->buf);
  212.         free(vf->priv);
  213. }
  214.  
  215. static int vf_open(vf_instance_t *vf, char *args)
  216. {
  217.         vf->control=control;
  218.         vf->query_format=query_format;
  219.         vf->put_image=put_image;
  220.         vf->uninit=uninit;
  221.  
  222.     vf->priv = malloc(sizeof(struct vf_priv_s));
  223.     memset(vf->priv, 0, sizeof(struct vf_priv_s));
  224.     if (args) sscanf(args, "%d:%d", &vf->priv->brightness, &vf->priv->contrast);
  225.  
  226.         process = process_C;
  227. #if HAVE_MMX
  228.         if(ff_gCpuCaps.hasMMX) process = process_MMX;
  229. #endif
  230.  
  231.         return 1;
  232. }
  233.  
  234. const vf_info_t ff_vf_info_eq = {
  235.         "soft video equalizer",
  236.         "eq",
  237.         "Richard Felker",
  238.         "",
  239.         vf_open,
  240. };
  241.