/* * 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++; }