vf_eq.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <inttypes.h>
  22. #include "config.h"
  23. #include "mp_msg.h"
  24. #include "cpudetect.h"
  25. #include "img_format.h"
  26. #include "mp_image.h"
  27. #include "vf.h"
  28. #include "libvo/video_out.h"
  29. static struct vf_priv_s {
  30. unsigned char *buf;
  31. int brightness;
  32. int contrast;
  33. };
  34. #if HAVE_MMX
  35. static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  36. int w, int h, int brightness, int contrast)
  37. {
  38. int i;
  39. int pel;
  40. int dstep = dstride-w;
  41. int sstep = sstride-w;
  42. short brvec[4];
  43. short contvec[4];
  44. contrast = ((contrast+100)*256*16)/100;
  45. brightness = ((brightness+100)*511)/200-128 - contrast/32;
  46. brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness;
  47. contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast;
  48. while (h--) {
  49. __asm__ volatile (
  50. "movq (%5), %%mm3 \n\t"
  51. "movq (%6), %%mm4 \n\t"
  52. "pxor %%mm0, %%mm0 \n\t"
  53. "movl %4, %%eax\n\t"
  54. ASMALIGN(4)
  55. "1: \n\t"
  56. "movq (%0), %%mm1 \n\t"
  57. "movq (%0), %%mm2 \n\t"
  58. "punpcklbw %%mm0, %%mm1 \n\t"
  59. "punpckhbw %%mm0, %%mm2 \n\t"
  60. "psllw $4, %%mm1 \n\t"
  61. "psllw $4, %%mm2 \n\t"
  62. "pmulhw %%mm4, %%mm1 \n\t"
  63. "pmulhw %%mm4, %%mm2 \n\t"
  64. "paddw %%mm3, %%mm1 \n\t"
  65. "paddw %%mm3, %%mm2 \n\t"
  66. "packuswb %%mm2, %%mm1 \n\t"
  67. "add $8, %0 \n\t"
  68. "movq %%mm1, (%1) \n\t"
  69. "add $8, %1 \n\t"
  70. "decl %%eax \n\t"
  71. "jnz 1b \n\t"
  72. : "=r" (src), "=r" (dest)
  73. : "0" (src), "1" (dest), "r" (w>>3), "r" (brvec), "r" (contvec)
  74. : "%eax"
  75. );
  76. for (i = w&7; i; i--)
  77. {
  78. pel = ((*src++* contrast)>>12) + brightness;
  79. if(pel&768) pel = (-pel)>>31;
  80. *dest++ = pel;
  81. }
  82. src += sstep;
  83. dest += dstep;
  84. }
  85. __asm__ volatile ( "emms \n\t" ::: "memory" );
  86. }
  87. #endif
  88. static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  89. int w, int h, int brightness, int contrast)
  90. {
  91. int i;
  92. int pel;
  93. int dstep = dstride-w;
  94. int sstep = sstride-w;
  95. contrast = ((contrast+100)*256*256)/100;
  96. brightness = ((brightness+100)*511)/200-128 - contrast/512;
  97. while (h--) {
  98. for (i = w; i; i--)
  99. {
  100. pel = ((*src++* contrast)>>16) + brightness;
  101. if(pel&768) pel = (-pel)>>31;
  102. *dest++ = pel;
  103. }
  104. src += sstep;
  105. dest += dstep;
  106. }
  107. }
  108. static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride,
  109. int w, int h, int brightness, int contrast);
  110. /* FIXME: add packed yuv version of process */
  111. static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
  112. {
  113. mp_image_t *dmpi;
  114. dmpi=vf_get_image(vf->next, mpi->imgfmt,
  115. MP_IMGTYPE_EXPORT, 0,
  116. mpi->w, mpi->h);
  117. dmpi->stride[0] = mpi->stride[0];
  118. dmpi->planes[1] = mpi->planes[1];
  119. dmpi->planes[2] = mpi->planes[2];
  120. dmpi->stride[1] = mpi->stride[1];
  121. dmpi->stride[2] = mpi->stride[2];
  122. if (!vf->priv->buf) vf->priv->buf = malloc(mpi->stride[0]*mpi->h);
  123. if ((vf->priv->brightness == 0) && (vf->priv->contrast == 0))
  124. dmpi->planes[0] = mpi->planes[0];
  125. else {
  126. dmpi->planes[0] = vf->priv->buf;
  127. process(dmpi->planes[0], dmpi->stride[0],
  128. mpi->planes[0], mpi->stride[0],
  129. mpi->w, mpi->h, vf->priv->brightness,
  130. vf->priv->contrast);
  131. }
  132. return vf_next_put_image(vf,dmpi, pts);
  133. }
  134. static int control(struct vf_instance *vf, int request, void* data)
  135. {
  136. vf_equalizer_t *eq;
  137. switch (request) {
  138. case VFCTRL_SET_EQUALIZER:
  139. eq = data;
  140. if (!strcmp(eq->item,"brightness")) {
  141. vf->priv->brightness = eq->value;
  142. return CONTROL_TRUE;
  143. }
  144. else if (!strcmp(eq->item,"contrast")) {
  145. vf->priv->contrast = eq->value;
  146. return CONTROL_TRUE;
  147. }
  148. break;
  149. case VFCTRL_GET_EQUALIZER:
  150. eq = data;
  151. if (!strcmp(eq->item,"brightness")) {
  152. eq->value = vf->priv->brightness;
  153. return CONTROL_TRUE;
  154. }
  155. else if (!strcmp(eq->item,"contrast")) {
  156. eq->value = vf->priv->contrast;
  157. return CONTROL_TRUE;
  158. }
  159. break;
  160. }
  161. return vf_next_control(vf, request, data);
  162. }
  163. static int query_format(struct vf_instance *vf, unsigned int fmt)
  164. {
  165. switch (fmt) {
  166. case IMGFMT_YVU9:
  167. case IMGFMT_IF09:
  168. case IMGFMT_YV12:
  169. case IMGFMT_I420:
  170. case IMGFMT_IYUV:
  171. case IMGFMT_CLPL:
  172. case IMGFMT_Y800:
  173. case IMGFMT_Y8:
  174. case IMGFMT_NV12:
  175. case IMGFMT_NV21:
  176. case IMGFMT_444P:
  177. case IMGFMT_422P:
  178. case IMGFMT_411P:
  179. return vf_next_query_format(vf, fmt);
  180. }
  181. return 0;
  182. }
  183. static void uninit(struct vf_instance *vf)
  184. {
  185. free(vf->priv->buf);
  186. free(vf->priv);
  187. }
  188. static int vf_open(vf_instance_t *vf, char *args)
  189. {
  190. vf->control=control;
  191. vf->query_format=query_format;
  192. vf->put_image=put_image;
  193. vf->uninit=uninit;
  194. vf->priv = malloc(sizeof(struct vf_priv_s));
  195. memset(vf->priv, 0, sizeof(struct vf_priv_s));
  196. if (args) sscanf(args, "%d:%d", &vf->priv->brightness, &vf->priv->contrast);
  197. process = process_C;
  198. #if HAVE_MMX
  199. if(gCpuCaps.hasMMX) process = process_MMX;
  200. #endif
  201. return 1;
  202. }
  203. const vf_info_t vf_info_eq = {
  204. "soft video equalizer",
  205. "eq",
  206. "Richard Felker",
  207. "",
  208. vf_open,
  209. };