/*
* Everything happens around the current pixel [0].
*
* A note on terminology:
* - "prefs" is the positive stride.
* - "mrefs" is the negative stride.
* - "cur" is the pointer into the current frame.
* - "prev" is the pointer into the previous frame.
* - "next" is the pointer into the next frame.
* - "prev2" and "next2" deal with the parity of deinterlacing between top and
* bottom fields. They are pointers into one of the above frames.
*
* The temporal score is... TODO
*
* The spatial check is based on this diagram.
* [-w-3][-w-2][-w-1][ -w][-w+1][-w+2][-w+3]
* [ 0]
* [+w-3][+w-2][+w-1][ -w][+w+1][+w+2][+w+3]
*
* The spatial scores are calulated as the sum of the absolute differences
* between the pixels marked with the red lines in the diagram at
* http://users.telenet.be/darnley/ffmpeg/yadif.png That means the first score
* is: ABS( [-w-1] - [+w-1] ) + ABS( [-w] - [+w] ) + ABS( [-w+1] - [+w+1] )
*
* The first check is performed to get the spatial score with the spatial
* predicted pixel being ([-w] + [+w]) / 2.
*
* The second check is then performed.
*
* If the score is lower than the previous spatial score then: it becomes the
* new spatial score; the new spatial predicted pixel becomes
* ([-w-1] + [+w+1]) / 2; and the third check is performed.
*
* If the score from this third check is less than the updated spatial score
* then: it becomes the new spatial score; and the new spatial predicted pixel
* becomes ([-w-2] + [+w+2]) / 2.
*
* The fourth check is performed (regardless of previous outcomes).
*
* If the score is lower than the previous spatial score then: it becomes the
* new spatial score; the new spatial predicted pixel becomes
* ([-w+1] + [+w-1]) / 2; and the fifth check is performed.
*
* If the score from this fifth check is less than the updated spatial score
* then: it becomes the new spatial score; and the new spatial predicted pixel
* becomes ([-w+2] + [+w-2]) / 2.
*
* The extra spatial check... TODO
*
* Predicted pixel selection... TODO
*/
for (x = start; x < end; x++) {
int c = cur[mrefs];
int d = (prev2[0] + next2[0])>>1;
int e = cur[prefs];
int temporal_diff0 = FFABS(prev2[0] - next2[0]);
int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1;
int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1;
int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2);
int spatial_pred = (c+e) >> 1;
int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e)
+ FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1;
{
int score = FFABS(cur[mrefs - 2] - cur[prefs])
+ FFABS(cur[mrefs - 1] - cur[prefs + 1])
+ FFABS(cur[mrefs] - cur[prefs + 2]);
if (score < spatial_score) {
spatial_score = score;
spatial_pred = (cur[mrefs - 1] + cur[prefs + 1])>>1;
{
int score = FFABS(cur[mrefs - 3] - cur[prefs + 1])
+ FFABS(cur[mrefs - 2] - cur[prefs + 2])
+ FFABS(cur[mrefs - 1] - cur[prefs + 3]);
if (score < spatial_score) {
spatial_score = score;
spatial_pred = (cur[mrefs - 2] + cur[prefs + 2])>>1;
}
}
}
}
{
int score = FFABS(cur[mrefs] - cur[prefs - 2])
+ FFABS(cur[mrefs + 1] - cur[prefs - 1])
+ FFABS(cur[mrefs + 2] - cur[prefs]);
if (score < spatial_score) {
spatial_score = score;
spatial_pred = (cur[mrefs + 1] + cur[prefs - 1])>>1;
{
int score = FFABS(cur[mrefs + 1] - cur[prefs - 3])
+ FFABS(cur[mrefs + 2] - cur[prefs - 2])
+ FFABS(cur[mrefs + 3] - cur[prefs - 1]);
if (score < spatial_score) {
spatial_score = score;
spatial_pred = (cur[mrefs + 2] + cur[prefs - 2])>>1;
}
}
}
}
if (!(mode&2)) {
int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1;
int f = (prev2[2 * prefs] + next2[2 * prefs])>>1;
int max = FFMAX3(d - e, d - c, FFMIN(b - c, f - e));
int min = FFMIN3(d - e, d - c, FFMAX(b - c, f - e));
diff = FFMAX3(diff, min, -max);
}
if (spatial_pred > d + diff)
spatial_pred = d + diff;
else if (spatial_pred < d - diff)
spatial_pred = d - diff;
dst[0] = spatial_pred;
dst++;
cur++;
prev++;
next++;
prev2++;
next2++;
}