You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
7.6KB

  1. /*
  2. * Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
  3. *
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #ifndef AVFILTER_DESHAKE_KERNEL_H
  22. #define AVFILTER_DESHAKE_KERNEL_H
  23. #include "libavutil/opencl.h"
  24. const char *ff_kernel_deshake_opencl = AV_OPENCL_KERNEL(
  25. inline unsigned char pixel(global const unsigned char *src, float x, float y,
  26. int w, int h,int stride, unsigned char def)
  27. {
  28. return (x < 0 || y < 0 || x >= w || y >= h) ? def : src[(int)x + (int)y * stride];
  29. }
  30. unsigned char interpolate_nearest(float x, float y, global const unsigned char *src,
  31. int width, int height, int stride, unsigned char def)
  32. {
  33. return pixel(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
  34. }
  35. unsigned char interpolate_bilinear(float x, float y, global const unsigned char *src,
  36. int width, int height, int stride, unsigned char def)
  37. {
  38. int x_c, x_f, y_c, y_f;
  39. int v1, v2, v3, v4;
  40. if (x < -1 || x > width || y < -1 || y > height) {
  41. return def;
  42. } else {
  43. x_f = (int)x;
  44. x_c = x_f + 1;
  45. y_f = (int)y;
  46. y_c = y_f + 1;
  47. v1 = pixel(src, x_c, y_c, width, height, stride, def);
  48. v2 = pixel(src, x_c, y_f, width, height, stride, def);
  49. v3 = pixel(src, x_f, y_c, width, height, stride, def);
  50. v4 = pixel(src, x_f, y_f, width, height, stride, def);
  51. return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
  52. v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
  53. }
  54. }
  55. unsigned char interpolate_biquadratic(float x, float y, global const unsigned char *src,
  56. int width, int height, int stride, unsigned char def)
  57. {
  58. int x_c, x_f, y_c, y_f;
  59. unsigned char v1, v2, v3, v4;
  60. float f1, f2, f3, f4;
  61. if (x < - 1 || x > width || y < -1 || y > height)
  62. return def;
  63. else {
  64. x_f = (int)x;
  65. x_c = x_f + 1;
  66. y_f = (int)y;
  67. y_c = y_f + 1;
  68. v1 = pixel(src, x_c, y_c, width, height, stride, def);
  69. v2 = pixel(src, x_c, y_f, width, height, stride, def);
  70. v3 = pixel(src, x_f, y_c, width, height, stride, def);
  71. v4 = pixel(src, x_f, y_f, width, height, stride, def);
  72. f1 = 1 - sqrt((x_c - x) * (y_c - y));
  73. f2 = 1 - sqrt((x_c - x) * (y - y_f));
  74. f3 = 1 - sqrt((x - x_f) * (y_c - y));
  75. f4 = 1 - sqrt((x - x_f) * (y - y_f));
  76. return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
  77. }
  78. }
  79. inline const float clipf(float a, float amin, float amax)
  80. {
  81. if (a < amin) return amin;
  82. else if (a > amax) return amax;
  83. else return a;
  84. }
  85. inline int mirror(int v, int m)
  86. {
  87. while ((unsigned)v > (unsigned)m) {
  88. v = -v;
  89. if (v < 0)
  90. v += 2 * m;
  91. }
  92. return v;
  93. }
  94. kernel void avfilter_transform(global unsigned char *src,
  95. global unsigned char *dst,
  96. global float *matrix,
  97. global float *matrix2,
  98. int interpolate,
  99. int fillmethod,
  100. int src_stride_lu,
  101. int dst_stride_lu,
  102. int src_stride_ch,
  103. int dst_stride_ch,
  104. int height,
  105. int width,
  106. int ch,
  107. int cw)
  108. {
  109. int global_id = get_global_id(0);
  110. global unsigned char *dst_y = dst;
  111. global unsigned char *dst_u = dst_y + height * dst_stride_lu;
  112. global unsigned char *dst_v = dst_u + ch * dst_stride_ch;
  113. global unsigned char *src_y = src;
  114. global unsigned char *src_u = src_y + height * src_stride_lu;
  115. global unsigned char *src_v = src_u + ch * src_stride_ch;
  116. global unsigned char *tempdst;
  117. global unsigned char *tempsrc;
  118. int x;
  119. int y;
  120. float x_s;
  121. float y_s;
  122. int tempsrc_stride;
  123. int tempdst_stride;
  124. int temp_height;
  125. int temp_width;
  126. int curpos;
  127. unsigned char def = 0;
  128. if (global_id < width*height) {
  129. y = global_id/width;
  130. x = global_id%width;
  131. x_s = x * matrix[0] + y * matrix[1] + matrix[2];
  132. y_s = x * matrix[3] + y * matrix[4] + matrix[5];
  133. tempdst = dst_y;
  134. tempsrc = src_y;
  135. tempsrc_stride = src_stride_lu;
  136. tempdst_stride = dst_stride_lu;
  137. temp_height = height;
  138. temp_width = width;
  139. } else if ((global_id >= width*height)&&(global_id < width*height + ch*cw)) {
  140. y = (global_id - width*height)/cw;
  141. x = (global_id - width*height)%cw;
  142. x_s = x * matrix2[0] + y * matrix2[1] + matrix2[2];
  143. y_s = x * matrix2[3] + y * matrix2[4] + matrix2[5];
  144. tempdst = dst_u;
  145. tempsrc = src_u;
  146. tempsrc_stride = src_stride_ch;
  147. tempdst_stride = dst_stride_ch;
  148. temp_height = height;
  149. temp_width = width;
  150. temp_height = ch;
  151. temp_width = cw;
  152. } else {
  153. y = (global_id - width*height - ch*cw)/cw;
  154. x = (global_id - width*height - ch*cw)%cw;
  155. x_s = x * matrix2[0] + y * matrix2[1] + matrix2[2];
  156. y_s = x * matrix2[3] + y * matrix2[4] + matrix2[5];
  157. tempdst = dst_v;
  158. tempsrc = src_v;
  159. tempsrc_stride = src_stride_ch;
  160. tempdst_stride = dst_stride_ch;
  161. temp_height = ch;
  162. temp_width = cw;
  163. }
  164. curpos = y * tempdst_stride + x;
  165. switch (fillmethod) {
  166. case 0: //FILL_BLANK
  167. def = 0;
  168. break;
  169. case 1: //FILL_ORIGINAL
  170. def = tempsrc[y*tempsrc_stride+x];
  171. break;
  172. case 2: //FILL_CLAMP
  173. y_s = clipf(y_s, 0, temp_height - 1);
  174. x_s = clipf(x_s, 0, temp_width - 1);
  175. def = tempsrc[(int)y_s * tempsrc_stride + (int)x_s];
  176. break;
  177. case 3: //FILL_MIRROR
  178. y_s = mirror(y_s,temp_height - 1);
  179. x_s = mirror(x_s,temp_width - 1);
  180. def = tempsrc[(int)y_s * tempsrc_stride + (int)x_s];
  181. break;
  182. }
  183. switch (interpolate) {
  184. case 0: //INTERPOLATE_NEAREST
  185. tempdst[curpos] = interpolate_nearest(x_s, y_s, tempsrc, temp_width, temp_height, tempsrc_stride, def);
  186. break;
  187. case 1: //INTERPOLATE_BILINEAR
  188. tempdst[curpos] = interpolate_bilinear(x_s, y_s, tempsrc, temp_width, temp_height, tempsrc_stride, def);
  189. break;
  190. case 2: //INTERPOLATE_BIQUADRATIC
  191. tempdst[curpos] = interpolate_biquadratic(x_s, y_s, tempsrc, temp_width, temp_height, tempsrc_stride, def);
  192. break;
  193. default:
  194. return;
  195. }
  196. }
  197. );
  198. #endif /* AVFILTER_DESHAKE_KERNEL_H */