Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2015/09/03 22:53:05... | ... |
@@ -54,6 +54,7 @@ typedef struct WaveformContext { |
54 | 54 |
int *emin[4][4]; |
55 | 55 |
int *peak; |
56 | 56 |
int filter; |
57 |
+ int bits; |
|
57 | 58 |
int size; |
58 | 59 |
void (*waveform)(struct WaveformContext *s, AVFrame *in, AVFrame *out, |
59 | 60 |
int component, int intensity, int offset, int column); |
... | ... |
@@ -68,8 +69,8 @@ static const AVOption waveform_options[] = { |
68 | 68 |
{ "m", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" }, |
69 | 69 |
{ "row", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" }, |
70 | 70 |
{ "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" }, |
71 |
- { "intensity", "set intensity", OFFSET(intensity), AV_OPT_TYPE_INT, {.i64=10}, 1, 255, FLAGS }, |
|
72 |
- { "i", "set intensity", OFFSET(intensity), AV_OPT_TYPE_INT, {.i64=10}, 1, 255, FLAGS }, |
|
71 |
+ { "intensity", "set intensity", OFFSET(intensity), AV_OPT_TYPE_INT, {.i64=10}, 1, 1023, FLAGS }, |
|
72 |
+ { "i", "set intensity", OFFSET(intensity), AV_OPT_TYPE_INT, {.i64=10}, 1, 1023, FLAGS }, |
|
73 | 73 |
{ "mirror", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, |
74 | 74 |
{ "r", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, |
75 | 75 |
{ "display", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display" }, |
... | ... |
@@ -99,6 +100,7 @@ AVFILTER_DEFINE_CLASS(waveform); |
99 | 99 |
|
100 | 100 |
static const enum AVPixelFormat lowpass_pix_fmts[] = { |
101 | 101 |
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, |
102 |
+ AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, |
|
102 | 103 |
AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, |
103 | 104 |
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, |
104 | 105 |
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, |
... | ... |
@@ -106,6 +108,10 @@ static const enum AVPixelFormat lowpass_pix_fmts[] = { |
106 | 106 |
AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, |
107 | 107 |
AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, |
108 | 108 |
AV_PIX_FMT_GRAY8, |
109 |
+ AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9, |
|
110 |
+ AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9, |
|
111 |
+ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10, |
|
112 |
+ AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10, |
|
109 | 113 |
AV_PIX_FMT_NONE |
110 | 114 |
}; |
111 | 115 |
|
... | ... |
@@ -115,7 +121,10 @@ static const enum AVPixelFormat flat_pix_fmts[] = { |
115 | 115 |
|
116 | 116 |
static const enum AVPixelFormat color_pix_fmts[] = { |
117 | 117 |
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, |
118 |
- AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE |
|
118 |
+ AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, |
|
119 |
+ AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, |
|
120 |
+ AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, |
|
121 |
+ AV_PIX_FMT_NONE |
|
119 | 122 |
}; |
120 | 123 |
|
121 | 124 |
static int query_formats(AVFilterContext *ctx) |
... | ... |
@@ -139,6 +148,57 @@ static int query_formats(AVFilterContext *ctx) |
139 | 139 |
return ff_set_common_formats(ctx, fmts_list); |
140 | 140 |
} |
141 | 141 |
|
142 |
+static void envelope_instant16(WaveformContext *s, AVFrame *out, int plane, int component) |
|
143 |
+{ |
|
144 |
+ const int dst_linesize = out->linesize[component] / 2; |
|
145 |
+ const int bg = s->bg_color[component] * (s->size / 256); |
|
146 |
+ const int limit = s->size - 1; |
|
147 |
+ const int is_chroma = (component == 1 || component == 2); |
|
148 |
+ const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0); |
|
149 |
+ const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0); |
|
150 |
+ const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h); |
|
151 |
+ const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w); |
|
152 |
+ const int start = s->estart[plane]; |
|
153 |
+ const int end = s->eend[plane]; |
|
154 |
+ uint16_t *dst; |
|
155 |
+ int x, y; |
|
156 |
+ |
|
157 |
+ if (s->mode) { |
|
158 |
+ for (x = 0; x < dst_w; x++) { |
|
159 |
+ for (y = start; y < end; y++) { |
|
160 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + x; |
|
161 |
+ if (dst[0] != bg) { |
|
162 |
+ dst[0] = limit; |
|
163 |
+ break; |
|
164 |
+ } |
|
165 |
+ } |
|
166 |
+ for (y = end - 1; y >= start; y--) { |
|
167 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + x; |
|
168 |
+ if (dst[0] != bg) { |
|
169 |
+ dst[0] = limit; |
|
170 |
+ break; |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ } |
|
174 |
+ } else { |
|
175 |
+ for (y = 0; y < dst_h; y++) { |
|
176 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize; |
|
177 |
+ for (x = start; x < end; x++) { |
|
178 |
+ if (dst[x] != bg) { |
|
179 |
+ dst[x] = limit; |
|
180 |
+ break; |
|
181 |
+ } |
|
182 |
+ } |
|
183 |
+ for (x = end - 1; x >= start; x--) { |
|
184 |
+ if (dst[x] != bg) { |
|
185 |
+ dst[x] = limit; |
|
186 |
+ break; |
|
187 |
+ } |
|
188 |
+ } |
|
189 |
+ } |
|
190 |
+ } |
|
191 |
+} |
|
192 |
+ |
|
142 | 193 |
static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int component) |
143 | 194 |
{ |
144 | 195 |
const int dst_linesize = out->linesize[component]; |
... | ... |
@@ -189,10 +249,83 @@ static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int co |
189 | 189 |
} |
190 | 190 |
} |
191 | 191 |
|
192 |
+static void envelope_peak16(WaveformContext *s, AVFrame *out, int plane, int component) |
|
193 |
+{ |
|
194 |
+ const int dst_linesize = out->linesize[component] / 2; |
|
195 |
+ const int bg = s->bg_color[component] * (s->size / 256); |
|
196 |
+ const int limit = s->size - 1; |
|
197 |
+ const int is_chroma = (component == 1 || component == 2); |
|
198 |
+ const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0); |
|
199 |
+ const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0); |
|
200 |
+ const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h); |
|
201 |
+ const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w); |
|
202 |
+ const int start = s->estart[plane]; |
|
203 |
+ const int end = s->eend[plane]; |
|
204 |
+ int *emax = s->emax[plane][component]; |
|
205 |
+ int *emin = s->emin[plane][component]; |
|
206 |
+ uint16_t *dst; |
|
207 |
+ int x, y; |
|
208 |
+ |
|
209 |
+ if (s->mode) { |
|
210 |
+ for (x = 0; x < dst_w; x++) { |
|
211 |
+ for (y = start; y < end && y < emin[x]; y++) { |
|
212 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + x; |
|
213 |
+ if (dst[0] != bg) { |
|
214 |
+ emin[x] = y; |
|
215 |
+ break; |
|
216 |
+ } |
|
217 |
+ } |
|
218 |
+ for (y = end - 1; y >= start && y >= emax[x]; y--) { |
|
219 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + x; |
|
220 |
+ if (dst[0] != bg) { |
|
221 |
+ emax[x] = y; |
|
222 |
+ break; |
|
223 |
+ } |
|
224 |
+ } |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ if (s->envelope == 3) |
|
228 |
+ envelope_instant16(s, out, plane, component); |
|
229 |
+ |
|
230 |
+ for (x = 0; x < dst_w; x++) { |
|
231 |
+ dst = (uint16_t *)out->data[component] + emin[x] * dst_linesize + x; |
|
232 |
+ dst[0] = limit; |
|
233 |
+ dst = (uint16_t *)out->data[component] + emax[x] * dst_linesize + x; |
|
234 |
+ dst[0] = limit; |
|
235 |
+ } |
|
236 |
+ } else { |
|
237 |
+ for (y = 0; y < dst_h; y++) { |
|
238 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize; |
|
239 |
+ for (x = start; x < end && x < emin[y]; x++) { |
|
240 |
+ if (dst[x] != bg) { |
|
241 |
+ emin[y] = x; |
|
242 |
+ break; |
|
243 |
+ } |
|
244 |
+ } |
|
245 |
+ for (x = end - 1; x >= start && x >= emax[y]; x--) { |
|
246 |
+ if (dst[x] != bg) { |
|
247 |
+ emax[y] = x; |
|
248 |
+ break; |
|
249 |
+ } |
|
250 |
+ } |
|
251 |
+ } |
|
252 |
+ |
|
253 |
+ if (s->envelope == 3) |
|
254 |
+ envelope_instant16(s, out, plane, component); |
|
255 |
+ |
|
256 |
+ for (y = 0; y < dst_h; y++) { |
|
257 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + emin[y]; |
|
258 |
+ dst[0] = limit; |
|
259 |
+ dst = (uint16_t *)out->data[component] + y * dst_linesize + emax[y]; |
|
260 |
+ dst[0] = limit; |
|
261 |
+ } |
|
262 |
+ } |
|
263 |
+} |
|
264 |
+ |
|
192 | 265 |
static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int component) |
193 | 266 |
{ |
194 | 267 |
const int dst_linesize = out->linesize[component]; |
195 |
- const uint8_t bg = s->bg_color[component]; |
|
268 |
+ const int bg = s->bg_color[component]; |
|
196 | 269 |
const int is_chroma = (component == 1 || component == 2); |
197 | 270 |
const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0); |
198 | 271 |
const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0); |
... | ... |
@@ -261,6 +394,17 @@ static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int compo |
261 | 261 |
} |
262 | 262 |
} |
263 | 263 |
|
264 |
+static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component) |
|
265 |
+{ |
|
266 |
+ if (s->envelope == 0) { |
|
267 |
+ return; |
|
268 |
+ } else if (s->envelope == 1) { |
|
269 |
+ envelope_instant16(s, out, plane, component); |
|
270 |
+ } else { |
|
271 |
+ envelope_peak16(s, out, plane, component); |
|
272 |
+ } |
|
273 |
+} |
|
274 |
+ |
|
264 | 275 |
static void envelope(WaveformContext *s, AVFrame *out, int plane, int component) |
265 | 276 |
{ |
266 | 277 |
if (s->envelope == 0) { |
... | ... |
@@ -272,6 +416,14 @@ static void envelope(WaveformContext *s, AVFrame *out, int plane, int component) |
272 | 272 |
} |
273 | 273 |
} |
274 | 274 |
|
275 |
+static void update16(uint16_t *target, int max, int intensity, int limit) |
|
276 |
+{ |
|
277 |
+ if (*target <= max) |
|
278 |
+ *target += intensity; |
|
279 |
+ else |
|
280 |
+ *target = limit; |
|
281 |
+} |
|
282 |
+ |
|
275 | 283 |
static void update(uint8_t *target, int max, int intensity) |
276 | 284 |
{ |
277 | 285 |
if (*target <= max) |
... | ... |
@@ -280,6 +432,56 @@ static void update(uint8_t *target, int max, int intensity) |
280 | 280 |
*target = 255; |
281 | 281 |
} |
282 | 282 |
|
283 |
+static void lowpass16(WaveformContext *s, AVFrame *in, AVFrame *out, |
|
284 |
+ int component, int intensity, int offset, int column) |
|
285 |
+{ |
|
286 |
+ const int plane = s->desc->comp[component].plane; |
|
287 |
+ const int mirror = s->mirror; |
|
288 |
+ const int is_chroma = (component == 1 || component == 2); |
|
289 |
+ const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0); |
|
290 |
+ const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0); |
|
291 |
+ const int src_linesize = in->linesize[plane] / 2; |
|
292 |
+ const int dst_linesize = out->linesize[plane] / 2; |
|
293 |
+ const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1); |
|
294 |
+ const int limit = s->size - 1; |
|
295 |
+ const int max = limit - intensity; |
|
296 |
+ const int src_h = FF_CEIL_RSHIFT(in->height, shift_h); |
|
297 |
+ const int src_w = FF_CEIL_RSHIFT(in->width, shift_w); |
|
298 |
+ const uint16_t *src_data = (const uint16_t *)in->data[plane]; |
|
299 |
+ uint16_t *dst_data = (uint16_t *)out->data[plane] + (column ? (offset >> shift_h) * dst_linesize : offset >> shift_w); |
|
300 |
+ uint16_t * const dst_bottom_line = dst_data + dst_linesize * ((s->size >> shift_h) - 1); |
|
301 |
+ uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data); |
|
302 |
+ const uint16_t *p; |
|
303 |
+ int y; |
|
304 |
+ |
|
305 |
+ if (!column && mirror) |
|
306 |
+ dst_data += s->size >> shift_w; |
|
307 |
+ |
|
308 |
+ for (y = 0; y < src_h; y++) { |
|
309 |
+ const uint16_t *src_data_end = src_data + src_w; |
|
310 |
+ uint16_t *dst = dst_line; |
|
311 |
+ |
|
312 |
+ for (p = src_data; p < src_data_end; p++) { |
|
313 |
+ uint16_t *target; |
|
314 |
+ int v = FFMIN(*p, limit); |
|
315 |
+ |
|
316 |
+ if (column) { |
|
317 |
+ target = dst++ + dst_signed_linesize * (v >> shift_h); |
|
318 |
+ } else { |
|
319 |
+ if (mirror) |
|
320 |
+ target = dst_data - (v >> shift_w) - 1; |
|
321 |
+ else |
|
322 |
+ target = dst_data + (v >> shift_w); |
|
323 |
+ } |
|
324 |
+ update16(target, max, intensity, limit); |
|
325 |
+ } |
|
326 |
+ src_data += src_linesize; |
|
327 |
+ dst_data += dst_linesize; |
|
328 |
+ } |
|
329 |
+ |
|
330 |
+ envelope16(s, out, plane, plane); |
|
331 |
+} |
|
332 |
+ |
|
283 | 333 |
static void lowpass(WaveformContext *s, AVFrame *in, AVFrame *out, |
284 | 334 |
int component, int intensity, int offset, int column) |
285 | 335 |
{ |
... | ... |
@@ -777,6 +979,97 @@ static void achroma(WaveformContext *s, AVFrame *in, AVFrame *out, |
777 | 777 |
envelope(s, out, plane, (plane + 2) % s->ncomp); |
778 | 778 |
} |
779 | 779 |
|
780 |
+static void color16(WaveformContext *s, AVFrame *in, AVFrame *out, |
|
781 |
+ int component, int intensity, int offset, int column) |
|
782 |
+{ |
|
783 |
+ const int plane = s->desc->comp[component].plane; |
|
784 |
+ const int mirror = s->mirror; |
|
785 |
+ const int limit = s->size - 1; |
|
786 |
+ const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0]; |
|
787 |
+ const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp]; |
|
788 |
+ const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp]; |
|
789 |
+ const int c0_linesize = in->linesize[ plane + 0 ] / 2; |
|
790 |
+ const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2; |
|
791 |
+ const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2; |
|
792 |
+ const int d0_linesize = out->linesize[ plane + 0 ] / 2; |
|
793 |
+ const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2; |
|
794 |
+ const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2; |
|
795 |
+ const int src_h = in->height; |
|
796 |
+ const int src_w = in->width; |
|
797 |
+ int x, y; |
|
798 |
+ |
|
799 |
+ if (s->mode) { |
|
800 |
+ const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1); |
|
801 |
+ const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1); |
|
802 |
+ const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1); |
|
803 |
+ uint16_t *d0_data = (uint16_t *)out->data[plane] + offset * d0_linesize; |
|
804 |
+ uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset * d1_linesize; |
|
805 |
+ uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset * d2_linesize; |
|
806 |
+ uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1); |
|
807 |
+ uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data); |
|
808 |
+ uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1); |
|
809 |
+ uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data); |
|
810 |
+ uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1); |
|
811 |
+ uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data); |
|
812 |
+ |
|
813 |
+ for (y = 0; y < src_h; y++) { |
|
814 |
+ for (x = 0; x < src_w; x++) { |
|
815 |
+ const int c0 = FFMIN(c0_data[x], limit); |
|
816 |
+ const int c1 = c1_data[x]; |
|
817 |
+ const int c2 = c2_data[x]; |
|
818 |
+ |
|
819 |
+ *(d0 + d0_signed_linesize * c0 + x) = c0; |
|
820 |
+ *(d1 + d1_signed_linesize * c0 + x) = c1; |
|
821 |
+ *(d2 + d2_signed_linesize * c0 + x) = c2; |
|
822 |
+ } |
|
823 |
+ |
|
824 |
+ c0_data += c0_linesize; |
|
825 |
+ c1_data += c1_linesize; |
|
826 |
+ c2_data += c2_linesize; |
|
827 |
+ d0_data += d0_linesize; |
|
828 |
+ d1_data += d1_linesize; |
|
829 |
+ d2_data += d2_linesize; |
|
830 |
+ } |
|
831 |
+ } else { |
|
832 |
+ uint16_t *d0_data = (uint16_t *)out->data[plane] + offset; |
|
833 |
+ uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset; |
|
834 |
+ uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset; |
|
835 |
+ |
|
836 |
+ if (mirror) { |
|
837 |
+ d0_data += s->size - 1; |
|
838 |
+ d1_data += s->size - 1; |
|
839 |
+ d2_data += s->size - 1; |
|
840 |
+ } |
|
841 |
+ |
|
842 |
+ for (y = 0; y < src_h; y++) { |
|
843 |
+ for (x = 0; x < src_w; x++) { |
|
844 |
+ const int c0 = FFMIN(c0_data[x], limit); |
|
845 |
+ const int c1 = c1_data[x]; |
|
846 |
+ const int c2 = c2_data[x]; |
|
847 |
+ |
|
848 |
+ if (mirror) { |
|
849 |
+ *(d0_data - c0) = c0; |
|
850 |
+ *(d1_data - c0) = c1; |
|
851 |
+ *(d2_data - c0) = c2; |
|
852 |
+ } else { |
|
853 |
+ *(d0_data + c0) = c0; |
|
854 |
+ *(d1_data + c0) = c1; |
|
855 |
+ *(d2_data + c0) = c2; |
|
856 |
+ } |
|
857 |
+ } |
|
858 |
+ |
|
859 |
+ c0_data += c0_linesize; |
|
860 |
+ c1_data += c1_linesize; |
|
861 |
+ c2_data += c2_linesize; |
|
862 |
+ d0_data += d0_linesize; |
|
863 |
+ d1_data += d1_linesize; |
|
864 |
+ d2_data += d2_linesize; |
|
865 |
+ } |
|
866 |
+ } |
|
867 |
+ |
|
868 |
+ envelope16(s, out, plane, plane); |
|
869 |
+} |
|
870 |
+ |
|
780 | 871 |
static void color(WaveformContext *s, AVFrame *in, AVFrame *out, |
781 | 872 |
int component, int intensity, int offset, int column) |
782 | 873 |
{ |
... | ... |
@@ -877,11 +1170,12 @@ static int config_input(AVFilterLink *inlink) |
877 | 877 |
|
878 | 878 |
s->desc = av_pix_fmt_desc_get(inlink->format); |
879 | 879 |
s->ncomp = s->desc->nb_components; |
880 |
+ s->bits = s->desc->comp[0].depth_minus1 + 1; |
|
880 | 881 |
|
881 | 882 |
switch (s->filter) { |
882 | 883 |
case LOWPASS: |
883 | 884 |
s->size = 256; |
884 |
- s->waveform = lowpass; break; |
|
885 |
+ s->waveform = s->bits > 8 ? lowpass16 : lowpass; break; |
|
885 | 886 |
case FLAT: |
886 | 887 |
s->size = 256 * 3; |
887 | 888 |
s->waveform = flat; break; |
... | ... |
@@ -896,12 +1190,16 @@ static int config_input(AVFilterLink *inlink) |
896 | 896 |
s->waveform = achroma; break; |
897 | 897 |
case COLOR: |
898 | 898 |
s->size = 256; |
899 |
- s->waveform = color; break; |
|
899 |
+ s->waveform = s->bits > 8 ? color16 : color; break; |
|
900 | 900 |
} |
901 | 901 |
|
902 |
+ s->size = s->size << (s->bits - 8); |
|
903 |
+ |
|
902 | 904 |
switch (inlink->format) { |
903 | 905 |
case AV_PIX_FMT_GBRAP: |
904 | 906 |
case AV_PIX_FMT_GBRP: |
907 |
+ case AV_PIX_FMT_GBRP9: |
|
908 |
+ case AV_PIX_FMT_GBRP10: |
|
905 | 909 |
s->bg_color = black_gbrp_color; |
906 | 910 |
break; |
907 | 911 |
default: |
... | ... |
@@ -976,7 +1274,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
976 | 976 |
WaveformContext *s = ctx->priv; |
977 | 977 |
AVFilterLink *outlink = ctx->outputs[0]; |
978 | 978 |
AVFrame *out; |
979 |
- int i, k; |
|
979 |
+ int i, j, k; |
|
980 | 980 |
|
981 | 981 |
out = ff_get_video_buffer(outlink, outlink->w, outlink->h); |
982 | 982 |
if (!out) { |
... | ... |
@@ -989,10 +1287,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
989 | 989 |
const int is_chroma = (k == 1 || k == 2); |
990 | 990 |
const int dst_h = FF_CEIL_RSHIFT(outlink->h, (is_chroma ? s->desc->log2_chroma_h : 0)); |
991 | 991 |
const int dst_w = FF_CEIL_RSHIFT(outlink->w, (is_chroma ? s->desc->log2_chroma_w : 0)); |
992 |
- for (i = 0; i < dst_h ; i++) |
|
993 |
- memset(out->data[s->desc->comp[k].plane] + |
|
994 |
- i * out->linesize[s->desc->comp[k].plane], |
|
995 |
- s->bg_color[k], dst_w); |
|
992 |
+ if (s->bits <= 8) { |
|
993 |
+ for (i = 0; i < dst_h ; i++) |
|
994 |
+ memset(out->data[s->desc->comp[k].plane] + |
|
995 |
+ i * out->linesize[s->desc->comp[k].plane], |
|
996 |
+ s->bg_color[k], dst_w); |
|
997 |
+ } else { |
|
998 |
+ const int mult = s->size / 256; |
|
999 |
+ uint16_t *dst = (uint16_t *)out->data[s->desc->comp[k].plane]; |
|
1000 |
+ |
|
1001 |
+ for (i = 0; i < dst_h ; i++) { |
|
1002 |
+ for (j = 0; j < dst_w; j++) |
|
1003 |
+ dst[j] = s->bg_color[k] * mult; |
|
1004 |
+ dst += out->linesize[s->desc->comp[k].plane] / 2; |
|
1005 |
+ } |
|
1006 |
+ } |
|
996 | 1007 |
} |
997 | 1008 |
|
998 | 1009 |
for (k = 0, i = 0; k < s->ncomp; k++) { |