vf_rectangle.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 "mp_image.h"
  22. #include "mp_msg.h"
  23. #include "vf.h"
  24. #include "libvo/fastmemcpy.h"
  25. #include "libavutil/common.h"
  26. struct vf_priv_s {
  27. int x, y, w, h;
  28. };
  29. static int
  30. config(struct vf_instance *vf,
  31. int width, int height, int d_width, int d_height,
  32. unsigned int flags, unsigned int outfmt)
  33. {
  34. if (vf->priv->w < 0 || width < vf->priv->w)
  35. vf->priv->w = width;
  36. if (vf->priv->h < 0 || height < vf->priv->h)
  37. vf->priv->h = height;
  38. if (vf->priv->x < 0)
  39. vf->priv->x = (width - vf->priv->w) / 2;
  40. if (vf->priv->y < 0)
  41. vf->priv->y = (height - vf->priv->h) / 2;
  42. if (vf->priv->w + vf->priv->x > width
  43. || vf->priv->h + vf->priv->y > height) {
  44. mp_msg(MSGT_VFILTER,MSGL_WARN,"rectangle: bad position/width/height - rectangle area is out of the original!\n");
  45. return 0;
  46. }
  47. return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
  48. }
  49. static int
  50. control(struct vf_instance *vf, int request, void *data)
  51. {
  52. const int *const tmp = data;
  53. switch(request){
  54. case VFCTRL_CHANGE_RECTANGLE:
  55. switch (tmp[0]){
  56. case 0:
  57. vf->priv->w += tmp[1];
  58. return 1;
  59. break;
  60. case 1:
  61. vf->priv->h += tmp[1];
  62. return 1;
  63. break;
  64. case 2:
  65. vf->priv->x += tmp[1];
  66. return 1;
  67. break;
  68. case 3:
  69. vf->priv->y += tmp[1];
  70. return 1;
  71. break;
  72. default:
  73. mp_msg(MSGT_VFILTER,MSGL_FATAL,"Unknown param %d \n", tmp[0]);
  74. return 0;
  75. }
  76. }
  77. return vf_next_control(vf, request, data);
  78. return 0;
  79. }
  80. static int
  81. put_image(struct vf_instance *vf, mp_image_t* mpi, double pts){
  82. mp_image_t* dmpi;
  83. unsigned int bpp = mpi->bpp / 8;
  84. int x, y, w, h;
  85. dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP,
  86. MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
  87. mpi->w, mpi->h);
  88. memcpy_pic(dmpi->planes[0],mpi->planes[0],mpi->w*bpp, mpi->h,
  89. dmpi->stride[0],mpi->stride[0]);
  90. if(mpi->flags&MP_IMGFLAG_PLANAR && mpi->flags&MP_IMGFLAG_YUV){
  91. memcpy_pic(dmpi->planes[1],mpi->planes[1],
  92. mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
  93. dmpi->stride[1],mpi->stride[1]);
  94. memcpy_pic(dmpi->planes[2],mpi->planes[2],
  95. mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
  96. dmpi->stride[2],mpi->stride[2]);
  97. }
  98. /* Draw the rectangle */
  99. mp_msg(MSGT_VFILTER,MSGL_INFO, "rectangle: -vf rectangle=%d:%d:%d:%d \n", vf->priv->w, vf->priv->h, vf->priv->x, vf->priv->y);
  100. x = FFMIN(vf->priv->x, dmpi->width);
  101. x = FFMAX(x, 0);
  102. w = vf->priv->x + vf->priv->w - 1 - x;
  103. w = FFMIN(w, dmpi->width - x);
  104. w = FFMAX(w, 0);
  105. y = FFMIN(vf->priv->y, dmpi->height);
  106. y = FFMAX(y, 0);
  107. h = vf->priv->y + vf->priv->h - 1 - y;
  108. h = FFMIN(h, dmpi->height - y);
  109. h = FFMAX(h, 0);
  110. if (0 <= vf->priv->y && vf->priv->y <= dmpi->height) {
  111. unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
  112. unsigned int count = w * bpp;
  113. while (count--)
  114. p[count] = 0xff - p[count];
  115. }
  116. if (h != 1 && vf->priv->y + vf->priv->h - 1 <= mpi->height) {
  117. unsigned char *p = dmpi->planes[0] + (vf->priv->y + vf->priv->h - 1) * dmpi->stride[0] + x * bpp;
  118. unsigned int count = w * bpp;
  119. while (count--)
  120. p[count] = 0xff - p[count];
  121. }
  122. if (0 <= vf->priv->x && vf->priv->x <= dmpi->width) {
  123. unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
  124. unsigned int count = h;
  125. while (count--) {
  126. unsigned int i = bpp;
  127. while (i--)
  128. p[i] = 0xff - p[i];
  129. p += dmpi->stride[0];
  130. }
  131. }
  132. if (w != 1 && vf->priv->x + vf->priv->w - 1 <= mpi->width) {
  133. unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + (vf->priv->x + vf->priv->w - 1) * bpp;
  134. unsigned int count = h;
  135. while (count--) {
  136. unsigned int i = bpp;
  137. while (i--)
  138. p[i] = 0xff - p[i];
  139. p += dmpi->stride[0];
  140. }
  141. }
  142. return vf_next_put_image(vf, dmpi, pts);
  143. }
  144. static int
  145. vf_open(vf_instance_t *vf, char *args) {
  146. vf->config = config;
  147. vf->control = control;
  148. vf->put_image = put_image;
  149. vf->priv = malloc(sizeof(struct vf_priv_s));
  150. vf->priv->x = -1;
  151. vf->priv->y = -1;
  152. vf->priv->w = -1;
  153. vf->priv->h = -1;
  154. if (args)
  155. sscanf(args, "%d:%d:%d:%d",
  156. &vf->priv->w, &vf->priv->h, &vf->priv->x, &vf->priv->y);
  157. return 1;
  158. }
  159. const vf_info_t vf_info_rectangle = {
  160. "draw rectangle",
  161. "rectangle",
  162. "Kim Minh Kaplan",
  163. "",
  164. vf_open,
  165. NULL
  166. };