vf_dsize.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 "img_format.h"
  25. #include "mp_image.h"
  26. #include "vf.h"
  27. struct vf_priv_s {
  28. int w, h;
  29. int method; // aspect method, 0 -> downscale, 1-> upscale. +2 -> original aspect.
  30. int round;
  31. float aspect;
  32. };
  33. static int config(struct vf_instance *vf,
  34. int width, int height, int d_width, int d_height,
  35. unsigned int flags, unsigned int outfmt)
  36. {
  37. if (vf->priv->aspect < 0.001) { // did the user input aspect or w,h params
  38. if (vf->priv->w == 0) vf->priv->w = d_width;
  39. if (vf->priv->h == 0) vf->priv->h = d_height;
  40. if (vf->priv->w == -1) vf->priv->w = width;
  41. if (vf->priv->h == -1) vf->priv->h = height;
  42. if (vf->priv->w == -2) vf->priv->w = vf->priv->h * (double)d_width / d_height;
  43. if (vf->priv->w == -3) vf->priv->w = vf->priv->h * (double)width / height;
  44. if (vf->priv->h == -2) vf->priv->h = vf->priv->w * (double)d_height / d_width;
  45. if (vf->priv->h == -3) vf->priv->h = vf->priv->w * (double)height / width;
  46. if (vf->priv->method > -1) {
  47. double aspect = (vf->priv->method & 2) ? ((double)height / width) : ((double)d_height / d_width);
  48. if ((vf->priv->h > vf->priv->w * aspect) ^ (vf->priv->method & 1)) {
  49. vf->priv->h = vf->priv->w * aspect;
  50. } else {
  51. vf->priv->w = vf->priv->h / aspect;
  52. }
  53. }
  54. if (vf->priv->round > 1) { // round up
  55. vf->priv->w += (vf->priv->round - 1 - (vf->priv->w - 1) % vf->priv->round);
  56. vf->priv->h += (vf->priv->round - 1 - (vf->priv->h - 1) % vf->priv->round);
  57. }
  58. d_width = vf->priv->w;
  59. d_height = vf->priv->h;
  60. } else {
  61. if (vf->priv->aspect * height > width) {
  62. d_width = height * vf->priv->aspect + .5;
  63. d_height = height;
  64. } else {
  65. d_height = width / vf->priv->aspect + .5;
  66. d_width = width;
  67. }
  68. }
  69. return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
  70. }
  71. static void uninit(vf_instance_t *vf) {
  72. free(vf->priv);
  73. vf->priv = NULL;
  74. }
  75. static int vf_open(vf_instance_t *vf, char *args)
  76. {
  77. vf->config = config;
  78. vf->draw_slice = vf_next_draw_slice;
  79. vf->uninit = uninit;
  80. //vf->default_caps = 0;
  81. vf->priv = calloc(sizeof(struct vf_priv_s), 1);
  82. vf->priv->aspect = 0.;
  83. vf->priv->w = -1;
  84. vf->priv->h = -1;
  85. vf->priv->method = -1;
  86. vf->priv->round = 1;
  87. if (args) {
  88. if (strchr(args, '/')) {
  89. int w, h;
  90. sscanf(args, "%d/%d", &w, &h);
  91. vf->priv->aspect = (float)w/h;
  92. } else if (strchr(args, '.')) {
  93. sscanf(args, "%f", &vf->priv->aspect);
  94. } else {
  95. sscanf(args, "%d:%d:%d:%d", &vf->priv->w, &vf->priv->h, &vf->priv->method, &vf->priv->round);
  96. }
  97. }
  98. if ((vf->priv->aspect < 0.) || (vf->priv->w < -3) || (vf->priv->h < -3) ||
  99. ((vf->priv->w < -1) && (vf->priv->h < -1)) ||
  100. (vf->priv->method < -1) || (vf->priv->method > 3) ||
  101. (vf->priv->round < 0)) {
  102. mp_msg(MSGT_VFILTER, MSGL_ERR, "[dsize] Illegal value(s): aspect: %f w: %d h: %d aspect_method: %d round: %d\n", vf->priv->aspect, vf->priv->w, vf->priv->h, vf->priv->method, vf->priv->round);
  103. free(vf->priv); vf->priv = NULL;
  104. return -1;
  105. }
  106. return 1;
  107. }
  108. const vf_info_t vf_info_dsize = {
  109. "reset displaysize/aspect",
  110. "dsize",
  111. "Rich Felker",
  112. "",
  113. vf_open,
  114. NULL
  115. };