Fixes by Michael Niedermayer <michaelni@gmx.at>
Unified · Split
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2006-2010 Michael Niedermayer <michaelni@gmx.at> | 2 | * Copyright (C) 2006-2010 Michael Niedermayer <michaelni@gmx.at> |
| 3 | * 2010 James Darnley <james.darnley@gmail.com> | ||
| 3 | * | 4 | * |
| 4 | * This file is part of Libav. | 5 | * This file is part of Libav. |
| 5 | * | 6 | * |
| @@ -56,25 +57,6 @@ typedef struct { · 50 unmodified lines | |||
| 56 | const AVPixFmtDescriptor *csp; | 57 | const AVPixFmtDescriptor *csp; |
| 57 | } YADIFContext; | 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 | #define CHECK(j)\ | 60 | #define CHECK(j)\ |
| 79 | { int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\ | 61 | { int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\ |
| 80 | + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ | 62 | + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ |
| @@ -83,39 +65,68 @@ static void filter_line_c(uint8_t *dst, · 2 unmodified lines | |||
| 83 | spatial_score= score;\ | 65 | spatial_score= score;\ |
| 84 | spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\ | 66 | spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\ |
| 85 | 67 | ||
| 86 | CHECK(-1) CHECK(-2) }} }} | 68 | #define FILTER \ |
| 87 | CHECK( 1) CHECK( 2) }} }} | 69 | for (x = 0; x < w; x++) { \ |
| 88 | 70 | int c = cur[mrefs]; \ | |
| 89 | if (mode < 2) { | 71 | int d = (prev2[0] + next2[0])>>1; \ |
| 90 | int b = (prev2[2*mrefs] + next2[2*mrefs])>>1; | 72 | int e = cur[prefs]; \ |
| 91 | int f = (prev2[2*prefs] + next2[2*prefs])>>1; | 73 | int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ |
| 92 | #if 0 | 74 | int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \ |
| 93 | int a = cur[-3*refs]; | 75 | int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \ |
| 94 | int g = cur[+3*refs]; | 76 | int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); \ |
| 95 | int max = FFMAX3(d-e, d-c, FFMIN3(FFMAX(b-c,f-e),FFMAX(b-c,b-a),FFMAX(f-g,f-e)) ); | 77 | int spatial_pred = (c+e)>>1; \ |
| 96 | int min = FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) ); | 78 | int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e) \ |
| 97 | #else | 79 | + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1; \ |
| 98 | int max = FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); | 80 | \ |
| 99 | int min = FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); | 81 | CHECK(-1) CHECK(-2) }} }} \ |
| 100 | #endif | 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); | 108 | static void filter_line_c(uint8_t *dst, |
| 103 | } | 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) | 116 | FILTER |
| 106 | spatial_pred = d + diff; | 117 | } |
| 107 | else if (spatial_pred < d - diff) | ||
| 108 | spatial_pred = d - diff; | ||
| 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++; | 129 | FILTER |
| 113 | cur++; | ||
| 114 | prev++; | ||
| 115 | next++; | ||
| 116 | prev2++; | ||
| 117 | next2++; | ||
| 118 | } | ||
| 119 | } | 130 | } |
| 120 | 131 | ||
| 121 | static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, | 132 | static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, |
| @@ -128,6 +139,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, · 6 unmodified lines | |||
| 128 | int w = dstpic->video->w; | 139 | int w = dstpic->video->w; |
| 129 | int h = dstpic->video->h; | 140 | int h = dstpic->video->h; |
| 130 | int refs = yadif->cur->linesize[i]; | 141 | int refs = yadif->cur->linesize[i]; |
| 142 | int df = (yadif->csp->comp[i].depth_minus1+1) / 8; | ||
| 131 | 143 | ||
| 132 | if (i) { | 144 | if (i) { |
| 133 | /* Why is this not part of the per-plane description thing? */ | 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 | yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode); | 157 | yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode); |
| 146 | } else { | 158 | } else { |
| 147 | memcpy(&dstpic->data[i][y*dstpic->linesize[i]], | 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 | if (!yadif->csp) | 204 | if (!yadif->csp) |
| 193 | yadif->csp = &av_pix_fmt_descriptors[link->format]; | 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 | filter(ctx, yadif->out, tff ^ !is_second, tff); | 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 | PIX_FMT_YUVJ420P, | 325 | PIX_FMT_YUVJ420P, |
| 312 | PIX_FMT_YUVJ422P, | 326 | PIX_FMT_YUVJ422P, |
| 313 | PIX_FMT_YUVJ444P, | 327 | PIX_FMT_YUVJ444P, |
| 328 | AV_NE( PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE ), | ||
| 314 | PIX_FMT_YUV440P, | 329 | PIX_FMT_YUV440P, |
| 315 | PIX_FMT_YUVJ440P, | 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 | PIX_FMT_NONE | 334 | PIX_FMT_NONE |
| 317 | }; | 335 | }; |
| 318 | 336 | ||