Fixes by Michael Niedermayer <michaelni@gmx.at>
Unified · Split
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Copyright (C) 2006-2010 Michael Niedermayer <michaelni@gmx.at> |
| 3 | + * 2010 James Darnley <james.darnley@gmail.com> | |
| 3 | 4 | * |
| 4 | 5 | * This file is part of Libav. |
| 5 | 6 | * |
| @@ -56,25 +57,6 @@ typedef struct { · 50 unmodified lines | ||
| 56 | 57 | const AVPixFmtDescriptor *csp; |
| 57 | 58 | } YADIFContext; |
| 58 | 59 | |
| 59 | −static void filter_line_c(uint8_t *dst, | |
| 60 | − uint8_t *prev, uint8_t *cur, uint8_t *next, | |
| 61 | − int w, int prefs, int mrefs, int parity, int mode) | |
| 62 | −{ | |
| 63 | − int x; | |
| 64 | − uint8_t *prev2 = parity ? prev : cur ; | |
| 65 | − uint8_t *next2 = parity ? cur : next; | |
| 66 | − for (x = 0; x < w; x++) { | |
| 67 | − int c = cur[mrefs]; | |
| 68 | − int d = (prev2[0] + next2[0])>>1; | |
| 69 | − int e = cur[prefs]; | |
| 70 | − int temporal_diff0 = FFABS(prev2[0] - next2[0]); | |
| 71 | − int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; | |
| 72 | − int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; | |
| 73 | − int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); | |
| 74 | − int spatial_pred = (c+e)>>1; | |
| 75 | − int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e) | |
| 76 | − + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1; | |
| 77 | − | |
| 78 | 60 | #define CHECK(j)\ |
| 79 | 61 | { int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\ |
| 80 | 62 | + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ |
| @@ -83,39 +65,68 @@ static void filter_line_c(uint8_t *dst, · 2 unmodified lines | ||
| 83 | 65 | spatial_score= score;\ |
| 84 | 66 | spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\ |
| 85 | 67 | |
| 86 | − CHECK(-1) CHECK(-2) }} }} | |
| 87 | − CHECK( 1) CHECK( 2) }} }} | |
| 88 | − | |
| 89 | − if (mode < 2) { | |
| 90 | − int b = (prev2[2*mrefs] + next2[2*mrefs])>>1; | |
| 91 | − int f = (prev2[2*prefs] + next2[2*prefs])>>1; | |
| 92 | −#if 0 | |
| 93 | − int a = cur[-3*refs]; | |
| 94 | − int g = cur[+3*refs]; | |
| 95 | − int max = FFMAX3(d-e, d-c, FFMIN3(FFMAX(b-c,f-e),FFMAX(b-c,b-a),FFMAX(f-g,f-e)) ); | |
| 96 | − int min = FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) ); | |
| 97 | −#else | |
| 98 | − int max = FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); | |
| 99 | − int min = FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); | |
| 100 | −#endif | |
| 68 | +#define FILTER \ | |
| 69 | + for (x = 0; x < w; x++) { \ | |
| 70 | + int c = cur[mrefs]; \ | |
| 71 | + int d = (prev2[0] + next2[0])>>1; \ | |
| 72 | + int e = cur[prefs]; \ | |
| 73 | + int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ | |
| 74 | + int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \ | |
| 75 | + int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \ | |
| 76 | + int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); \ | |
| 77 | + int spatial_pred = (c+e)>>1; \ | |
| 78 | + int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e) \ | |
| 79 | + + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1; \ | |
| 80 | + \ | |
| 81 | + CHECK(-1) CHECK(-2) }} }} \ | |
| 82 | + CHECK( 1) CHECK( 2) }} }} \ | |
| 83 | + \ | |
| 84 | + if (mode < 2) { \ | |
| 85 | + int b = (prev2[2*mrefs] + next2[2*mrefs])>>1; \ | |
| 86 | + int f = (prev2[2*prefs] + next2[2*prefs])>>1; \ | |
| 87 | + int max = FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); \ | |
| 88 | + int min = FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); \ | |
| 89 | + \ | |
| 90 | + diff = FFMAX3(diff, min, -max); \ | |
| 91 | + } \ | |
| 92 | + \ | |
| 93 | + if (spatial_pred > d + diff) \ | |
| 94 | + spatial_pred = d + diff; \ | |
| 95 | + else if (spatial_pred < d - diff) \ | |
| 96 | + spatial_pred = d - diff; \ | |
| 97 | + \ | |
| 98 | + dst[0] = spatial_pred; \ | |
| 99 | + \ | |
| 100 | + dst++; \ | |
| 101 | + cur++; \ | |
| 102 | + prev++; \ | |
| 103 | + next++; \ | |
| 104 | + prev2++; \ | |
| 105 | + next2++; \ | |
| 106 | + } | |
| 101 | 107 | |
| 102 | − diff = FFMAX3(diff, min, -max); | |
| 103 | − } | |
| 108 | +static void filter_line_c(uint8_t *dst, | |
| 109 | + uint8_t *prev, uint8_t *cur, uint8_t *next, | |
| 110 | + int w, int prefs, int mrefs, int parity, int mode) | |
| 111 | +{ | |
| 112 | + int x; | |
| 113 | + uint8_t *prev2 = parity ? prev : cur ; | |
| 114 | + uint8_t *next2 = parity ? cur : next; | |
| 104 | 115 | |
| 105 | − if (spatial_pred > d + diff) | |
| 106 | − spatial_pred = d + diff; | |
| 107 | − else if (spatial_pred < d - diff) | |
| 108 | − spatial_pred = d - diff; | |
| 116 | + FILTER | |
| 117 | +} | |
| 109 | 118 | |
| 110 | − dst[0] = spatial_pred; | |
| 119 | +static void filter_line_c_16bit(uint16_t *dst, | |
| 120 | + uint16_t *prev, uint16_t *cur, uint16_t *next, | |
| 121 | + int w, int prefs, int mrefs, int parity, int mode) | |
| 122 | +{ | |
| 123 | + int x; | |
| 124 | + uint16_t *prev2 = parity ? prev : cur ; | |
| 125 | + uint16_t *next2 = parity ? cur : next; | |
| 126 | + mrefs /= 2; | |
| 127 | + prefs /= 2; | |
| 111 | 128 | |
| 112 | − dst++; | |
| 113 | − cur++; | |
| 114 | − prev++; | |
| 115 | − next++; | |
| 116 | − prev2++; | |
| 117 | − next2++; | |
| 118 | − } | |
| 129 | + FILTER | |
| 119 | 130 | } |
| 120 | 131 | |
| 121 | 132 | static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, |
| @@ -128,6 +139,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, · 6 unmodified lines | ||
| 128 | 139 | int w = dstpic->video->w; |
| 129 | 140 | int h = dstpic->video->h; |
| 130 | 141 | int refs = yadif->cur->linesize[i]; |
| 142 | + int df = (yadif->csp->comp[i].depth_minus1+1) / 8; | |
| 131 | 143 | |
| 132 | 144 | if (i) { |
| 133 | 145 | /* Why is this not part of the per-plane description thing? */ |
| @@ -145,7 +157,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, · 11 unmodified lines | ||
| 145 | 157 | yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode); |
| 146 | 158 | } else { |
| 147 | 159 | memcpy(&dstpic->data[i][y*dstpic->linesize[i]], |
| 148 | − &yadif->cur->data[i][y*refs], w); | |
| 160 | + &yadif->cur->data[i][y*refs], w*df); | |
| 149 | 161 | } |
| 150 | 162 | } |
| 151 | 163 | } |
| @@ -191,6 +203,8 @@ static void return_frame(AVFilterContext *ctx, int is_second) · 39 unmodified lines | ||
| 191 | 203 | |
| 192 | 204 | if (!yadif->csp) |
| 193 | 205 | yadif->csp = &av_pix_fmt_descriptors[link->format]; |
| 206 | + if (yadif->csp->comp[0].depth_minus1 == 15) | |
| 207 | + yadif->filter_line = filter_line_c_16bit; | |
| 194 | 208 | |
| 195 | 209 | filter(ctx, yadif->out, tff ^ !is_second, tff); |
| 196 | 210 | |
| @@ -311,8 +325,12 @@ static int query_formats(AVFilterContext *ctx) · 114 unmodified lines | ||
| 311 | 325 | PIX_FMT_YUVJ420P, |
| 312 | 326 | PIX_FMT_YUVJ422P, |
| 313 | 327 | PIX_FMT_YUVJ444P, |
| 328 | + AV_NE( PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE ), | |
| 314 | 329 | PIX_FMT_YUV440P, |
| 315 | 330 | PIX_FMT_YUVJ440P, |
| 331 | + AV_NE( PIX_FMT_YUV420P16BE, PIX_FMT_YUV420P16LE ), | |
| 332 | + AV_NE( PIX_FMT_YUV422P16BE, PIX_FMT_YUV422P16LE ), | |
| 333 | + AV_NE( PIX_FMT_YUV444P16BE, PIX_FMT_YUV444P16LE ), | |
| 316 | 334 | PIX_FMT_NONE |
| 317 | 335 | }; |
| 318 | 336 | |