00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <inttypes.h>
00023 #include <math.h>
00024
00025 #include "config.h"
00026 #include "mp_msg.h"
00027 #include "cpudetect.h"
00028
00029 #include "img_format.h"
00030 #include "mp_image.h"
00031 #include "vf.h"
00032
00033 #include "libvo/video_out.h"
00034
00035 struct vf_priv_s {
00036 uint8_t *buf[2];
00037 float hue;
00038 float saturation;
00039 };
00040
00041 static void process_C(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsrc, int dststride, int srcstride,
00042 int w, int h, float hue, float sat)
00043 {
00044 int i;
00045 const int s= rint(sin(hue) * (1<<16) * sat);
00046 const int c= rint(cos(hue) * (1<<16) * sat);
00047
00048 while (h--) {
00049 for (i = 0; i<w; i++)
00050 {
00051 const int u= usrc[i] - 128;
00052 const int v= vsrc[i] - 128;
00053 int new_u= (c*u - s*v + (1<<15) + (128<<16))>>16;
00054 int new_v= (s*u + c*v + (1<<15) + (128<<16))>>16;
00055 if(new_u & 768) new_u= (-new_u)>>31;
00056 if(new_v & 768) new_v= (-new_v)>>31;
00057 udst[i]= new_u;
00058 vdst[i]= new_v;
00059 }
00060 usrc += srcstride;
00061 vsrc += srcstride;
00062 udst += dststride;
00063 vdst += dststride;
00064 }
00065 }
00066
00067 static void (*process)(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsrc, int dststride, int srcstride,
00068 int w, int h, float hue, float sat);
00069
00070
00071
00072 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
00073 {
00074 mp_image_t *dmpi;
00075
00076 dmpi=vf_get_image(vf->next, mpi->imgfmt,
00077 MP_IMGTYPE_EXPORT, 0,
00078 mpi->w, mpi->h);
00079
00080 dmpi->planes[0] = mpi->planes[0];
00081 dmpi->stride[0] = mpi->stride[0];
00082 dmpi->stride[1] = mpi->stride[1];
00083 dmpi->stride[2] = mpi->stride[2];
00084
00085 if (!vf->priv->buf[0]){
00086 vf->priv->buf[0] = malloc(mpi->stride[1]*mpi->h >> mpi->chroma_y_shift);
00087 vf->priv->buf[1] = malloc(mpi->stride[2]*mpi->h >> mpi->chroma_y_shift);
00088 }
00089
00090 if (vf->priv->hue == 0 && vf->priv->saturation == 1){
00091 dmpi->planes[1] = mpi->planes[1];
00092 dmpi->planes[2] = mpi->planes[2];
00093 }else {
00094 dmpi->planes[1] = vf->priv->buf[0];
00095 dmpi->planes[2] = vf->priv->buf[1];
00096 process(dmpi->planes[1], dmpi->planes[2],
00097 mpi->planes[1], mpi->planes[2],
00098 dmpi->stride[1],mpi->stride[1],
00099 mpi->w>> mpi->chroma_x_shift, mpi->h>> mpi->chroma_y_shift,
00100 vf->priv->hue, vf->priv->saturation);
00101 }
00102
00103 return vf_next_put_image(vf,dmpi, pts);
00104 }
00105
00106 static int control(struct vf_instance *vf, int request, void* data)
00107 {
00108 vf_equalizer_t *eq;
00109
00110 switch (request) {
00111 case VFCTRL_SET_EQUALIZER:
00112 eq = data;
00113 if (!strcmp(eq->item,"hue")) {
00114 vf->priv->hue = eq->value * M_PI / 100;
00115 return CONTROL_TRUE;
00116 } else if (!strcmp(eq->item,"saturation")) {
00117 vf->priv->saturation = (eq->value + 100)/100.0;
00118 return CONTROL_TRUE;
00119 }
00120 break;
00121 case VFCTRL_GET_EQUALIZER:
00122 eq = data;
00123 if (!strcmp(eq->item,"hue")) {
00124 eq->value = rint(vf->priv->hue *100 / M_PI);
00125 return CONTROL_TRUE;
00126 }else if (!strcmp(eq->item,"saturation")) {
00127 eq->value = rint(vf->priv->saturation*100 - 100);
00128 return CONTROL_TRUE;
00129 }
00130 break;
00131 }
00132 return vf_next_control(vf, request, data);
00133 }
00134
00135 static int query_format(struct vf_instance *vf, unsigned int fmt)
00136 {
00137 switch (fmt) {
00138 case IMGFMT_YVU9:
00139 case IMGFMT_IF09:
00140 case IMGFMT_YV12:
00141 case IMGFMT_I420:
00142 case IMGFMT_IYUV:
00143 case IMGFMT_CLPL:
00144 case IMGFMT_444P:
00145 case IMGFMT_422P:
00146 case IMGFMT_411P:
00147 return vf_next_query_format(vf, fmt);
00148 }
00149 return 0;
00150 }
00151
00152 static void uninit(struct vf_instance *vf)
00153 {
00154 free(vf->priv->buf[0]);
00155 free(vf->priv->buf[1]);
00156 free(vf->priv);
00157 }
00158
00159 static int vf_open(vf_instance_t *vf, char *args)
00160 {
00161 vf->control=control;
00162 vf->query_format=query_format;
00163 vf->put_image=put_image;
00164 vf->uninit=uninit;
00165
00166 vf->priv = malloc(sizeof(struct vf_priv_s));
00167 memset(vf->priv, 0, sizeof(struct vf_priv_s));
00168 sscanf(args, "%f:%f", &vf->priv->hue, &vf->priv->saturation);
00169 vf->priv->hue *= M_PI / 180.0;
00170
00171 process = process_C;
00172 return 1;
00173 }
00174
00175 const vf_info_t vf_info_hue = {
00176 "hue changer",
00177 "hue",
00178 "Michael Niedermayer",
00179 "",
00180 vf_open,
00181 };