Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Michael Niedermayer authored on 2017/06/30 19:16:04... | ... |
@@ -41,6 +41,7 @@ typedef struct GEQContext { |
41 | 41 |
int hsub, vsub; ///< chroma subsampling |
42 | 42 |
int planes; ///< number of planes |
43 | 43 |
int is_rgb; |
44 |
+ int bps; |
|
44 | 45 |
} GEQContext; |
45 | 46 |
|
46 | 47 |
enum { Y = 0, U, V, A, G, B, R }; |
... | ... |
@@ -74,7 +75,7 @@ static inline double getpix(void *priv, double x, double y, int plane) |
74 | 74 |
GEQContext *geq = priv; |
75 | 75 |
AVFrame *picref = geq->picref; |
76 | 76 |
const uint8_t *src = picref->data[plane]; |
77 |
- const int linesize = picref->linesize[plane]; |
|
77 |
+ int linesize = picref->linesize[plane]; |
|
78 | 78 |
const int w = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(picref->width, geq->hsub) : picref->width; |
79 | 79 |
const int h = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(picref->height, geq->vsub) : picref->height; |
80 | 80 |
|
... | ... |
@@ -87,8 +88,16 @@ static inline double getpix(void *priv, double x, double y, int plane) |
87 | 87 |
x -= xi; |
88 | 88 |
y -= yi; |
89 | 89 |
|
90 |
- return (1-y)*((1-x)*src[xi + yi * linesize] + x*src[xi + 1 + yi * linesize]) |
|
91 |
- + y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]); |
|
90 |
+ if (geq->bps > 8) { |
|
91 |
+ const uint16_t *src16 = (const uint16_t*)src; |
|
92 |
+ linesize /= 2; |
|
93 |
+ |
|
94 |
+ return (1-y)*((1-x)*src16[xi + yi * linesize] + x*src16[xi + 1 + yi * linesize]) |
|
95 |
+ + y *((1-x)*src16[xi + (yi+1) * linesize] + x*src16[xi + 1 + (yi+1) * linesize]); |
|
96 |
+ } else { |
|
97 |
+ return (1-y)*((1-x)*src[xi + yi * linesize] + x*src[xi + 1 + yi * linesize]) |
|
98 |
+ + y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]); |
|
99 |
+ } |
|
92 | 100 |
} |
93 | 101 |
|
94 | 102 |
//TODO: cubic interpolate |
... | ... |
@@ -129,8 +138,11 @@ static av_cold int geq_init(AVFilterContext *ctx) |
129 | 129 |
if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]); |
130 | 130 |
} |
131 | 131 |
|
132 |
- if (!geq->expr_str[A]) |
|
133 |
- geq->expr_str[A] = av_strdup("255"); |
|
132 |
+ if (!geq->expr_str[A]) { |
|
133 |
+ char bps_string[8]; |
|
134 |
+ snprintf(bps_string, sizeof(bps_string), "%d", (1<<geq->bps) - 1); |
|
135 |
+ geq->expr_str[A] = av_strdup(bps_string); |
|
136 |
+ } |
|
134 | 137 |
if (!geq->expr_str[G]) |
135 | 138 |
geq->expr_str[G] = av_strdup("g(X,Y)"); |
136 | 139 |
if (!geq->expr_str[B]) |
... | ... |
@@ -171,10 +183,27 @@ static int geq_query_formats(AVFilterContext *ctx) |
171 | 171 |
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, |
172 | 172 |
AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, |
173 | 173 |
AV_PIX_FMT_GRAY8, |
174 |
+ AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9, |
|
175 |
+ AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9, |
|
176 |
+ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10, |
|
177 |
+ AV_PIX_FMT_YUV440P10, |
|
178 |
+ AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10, |
|
179 |
+ AV_PIX_FMT_GRAY10, |
|
180 |
+ AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, |
|
181 |
+ AV_PIX_FMT_GRAY12, |
|
182 |
+ AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, |
|
183 |
+ AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV420P16, |
|
184 |
+ AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P16, |
|
185 |
+ AV_PIX_FMT_GRAY16, |
|
174 | 186 |
AV_PIX_FMT_NONE |
175 | 187 |
}; |
176 | 188 |
static const enum AVPixelFormat rgb_pix_fmts[] = { |
177 | 189 |
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, |
190 |
+ AV_PIX_FMT_GBRP9, |
|
191 |
+ AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, |
|
192 |
+ AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, |
|
193 |
+ AV_PIX_FMT_GBRP14, |
|
194 |
+ AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, |
|
178 | 195 |
AV_PIX_FMT_NONE |
179 | 196 |
}; |
180 | 197 |
AVFilterFormats *fmts_list; |
... | ... |
@@ -198,6 +227,8 @@ static int geq_config_props(AVFilterLink *inlink) |
198 | 198 |
geq->hsub = desc->log2_chroma_w; |
199 | 199 |
geq->vsub = desc->log2_chroma_h; |
200 | 200 |
geq->planes = desc->nb_components; |
201 |
+ geq->bps = desc->comp[0].depth; |
|
202 |
+ |
|
201 | 203 |
return 0; |
202 | 204 |
} |
203 | 205 |
|
... | ... |
@@ -223,6 +254,7 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in) |
223 | 223 |
for (plane = 0; plane < geq->planes && out->data[plane]; plane++) { |
224 | 224 |
int x, y; |
225 | 225 |
uint8_t *dst = out->data[plane]; |
226 |
+ uint16_t *dst16 = (uint16_t*)out->data[plane]; |
|
226 | 227 |
const int linesize = out->linesize[plane]; |
227 | 228 |
const int w = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(inlink->w, geq->hsub) : inlink->w; |
228 | 229 |
const int h = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(inlink->h, geq->vsub) : inlink->h; |
... | ... |
@@ -234,11 +266,19 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in) |
234 | 234 |
|
235 | 235 |
for (y = 0; y < h; y++) { |
236 | 236 |
values[VAR_Y] = y; |
237 |
- for (x = 0; x < w; x++) { |
|
238 |
- values[VAR_X] = x; |
|
239 |
- dst[x] = av_expr_eval(geq->e[plane], values, geq); |
|
237 |
+ if (geq->bps > 8) { |
|
238 |
+ for (x = 0; x < w; x++) { |
|
239 |
+ values[VAR_X] = x; |
|
240 |
+ dst16[x] = av_expr_eval(geq->e[plane], values, geq); |
|
241 |
+ } |
|
242 |
+ dst16 += linesize / 2; |
|
243 |
+ } else { |
|
244 |
+ for (x = 0; x < w; x++) { |
|
245 |
+ values[VAR_X] = x; |
|
246 |
+ dst[x] = av_expr_eval(geq->e[plane], values, geq); |
|
247 |
+ } |
|
248 |
+ dst += linesize; |
|
240 | 249 |
} |
241 |
- dst += linesize; |
|
242 | 250 |
} |
243 | 251 |
} |
244 | 252 |
|