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.

184 lines
6.1KB

  1. /*
  2. * Copyright (c) 2004 Ville Saari
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/avassert.h"
  21. #include "avfilter.h"
  22. #include "formats.h"
  23. #include "internal.h"
  24. #include "video.h"
  25. #undef pixel
  26. #undef accumulator
  27. #if DEPTH == 8
  28. #define pixel uint8_t
  29. #define accumulator int
  30. #else
  31. #define pixel uint16_t
  32. #define accumulator int64_t
  33. #endif
  34. #define fn3(a,b) a##_##b
  35. #define fn2(a,b) fn3(a,b)
  36. #define fn(a) fn2(a, DEPTH)
  37. /*
  38. * This macro interpolates the value of both fields at a point halfway
  39. * between lines and takes the squared difference. In field resolution
  40. * the point is a quarter pixel below a line in one field and a quarter
  41. * pixel above a line in other.
  42. *
  43. * (The result is actually multiplied by 25)
  44. */
  45. #define DIFF(a, as, b, bs) ((t) = ((*(a) - (b)[bs]) << 2) + (a)[(as) << 1] - (b)[-(bs)], (t) * (t))
  46. /*
  47. * Find which field combination has the smallest average squared difference
  48. * between the fields.
  49. */
  50. static enum PhaseMode fn(analyze_plane)(void *ctx, enum PhaseMode mode, AVFrame *old, AVFrame *new)
  51. {
  52. double bdiff, tdiff, pdiff;
  53. if (mode == AUTO) {
  54. mode = new->interlaced_frame ? new->top_field_first ?
  55. TOP_FIRST : BOTTOM_FIRST : PROGRESSIVE;
  56. } else if (mode == AUTO_ANALYZE) {
  57. mode = new->interlaced_frame ? new->top_field_first ?
  58. TOP_FIRST_ANALYZE : BOTTOM_FIRST_ANALYZE : FULL_ANALYZE;
  59. }
  60. if (mode <= BOTTOM_FIRST) {
  61. bdiff = pdiff = tdiff = 65536.0;
  62. } else {
  63. const double factor = 1. / (25. * (1 << (DEPTH - 8)) * (1 << (DEPTH - 8)));
  64. const int ns = new->linesize[0] / sizeof(pixel);
  65. const int os = old->linesize[0] / sizeof(pixel);
  66. const pixel *nptr = (pixel *)new->data[0];
  67. const pixel *optr = (pixel *)old->data[0];
  68. const int h = new->height;
  69. const int w = new->width;
  70. accumulator bdif, tdif, pdif;
  71. double scale;
  72. int top = 0, t;
  73. const pixel *rend, *end = nptr + (h - 2) * ns;
  74. bdiff = pdiff = tdiff = 0.0;
  75. nptr += ns;
  76. optr += os;
  77. while (nptr < end) {
  78. pdif = tdif = bdif = 0;
  79. switch (mode) {
  80. case TOP_FIRST_ANALYZE:
  81. if (top) {
  82. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  83. pdif += DIFF(nptr, ns, nptr, ns);
  84. tdif += DIFF(nptr, ns, optr, os);
  85. }
  86. } else {
  87. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  88. pdif += DIFF(nptr, ns, nptr, ns);
  89. tdif += DIFF(optr, os, nptr, ns);
  90. }
  91. }
  92. break;
  93. case BOTTOM_FIRST_ANALYZE:
  94. if (top) {
  95. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  96. pdif += DIFF(nptr, ns, nptr, ns);
  97. bdif += DIFF(optr, os, nptr, ns);
  98. }
  99. } else {
  100. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  101. pdif += DIFF(nptr, ns, nptr, ns);
  102. bdif += DIFF(nptr, ns, optr, os);
  103. }
  104. }
  105. break;
  106. case ANALYZE:
  107. if (top) {
  108. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  109. tdif += DIFF(nptr, ns, optr, os);
  110. bdif += DIFF(optr, os, nptr, ns);
  111. }
  112. } else {
  113. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  114. bdif += DIFF(nptr, ns, optr, os);
  115. tdif += DIFF(optr, os, nptr, ns);
  116. }
  117. }
  118. break;
  119. case FULL_ANALYZE:
  120. if (top) {
  121. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  122. pdif += DIFF(nptr, ns, nptr, ns);
  123. tdif += DIFF(nptr, ns, optr, os);
  124. bdif += DIFF(optr, os, nptr, ns);
  125. }
  126. } else {
  127. for (rend = nptr + w; nptr < rend; nptr++, optr++) {
  128. pdif += DIFF(nptr, ns, nptr, ns);
  129. bdif += DIFF(nptr, ns, optr, os);
  130. tdif += DIFF(optr, os, nptr, ns);
  131. }
  132. }
  133. break;
  134. default:
  135. av_assert0(0);
  136. }
  137. pdiff += (double)pdif;
  138. tdiff += (double)tdif;
  139. bdiff += (double)bdif;
  140. nptr += ns - w;
  141. optr += os - w;
  142. top ^= 1;
  143. }
  144. scale = 1.0 / (w * (h - 3)) * factor;
  145. pdiff *= scale;
  146. tdiff *= scale;
  147. bdiff *= scale;
  148. if (mode == TOP_FIRST_ANALYZE) {
  149. bdiff = 65536.0;
  150. } else if (mode == BOTTOM_FIRST_ANALYZE) {
  151. tdiff = 65536.0;
  152. } else if (mode == ANALYZE) {
  153. pdiff = 65536.0;
  154. }
  155. if (bdiff < pdiff && bdiff < tdiff) {
  156. mode = BOTTOM_FIRST;
  157. } else if (tdiff < pdiff && tdiff < bdiff) {
  158. mode = TOP_FIRST;
  159. } else {
  160. mode = PROGRESSIVE;
  161. }
  162. }
  163. av_log(ctx, AV_LOG_DEBUG, "mode=%c tdiff=%f bdiff=%f pdiff=%f\n",
  164. mode == BOTTOM_FIRST ? 'b' : mode == TOP_FIRST ? 't' : 'p',
  165. tdiff, bdiff, pdiff);
  166. return mode;
  167. }