Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2016/03/06 17:46:34... | ... |
@@ -13175,6 +13175,14 @@ Display green graticule showing legal broadcast ranges. |
13175 | 13175 |
|
13176 | 13176 |
@item opacity, o |
13177 | 13177 |
Set graticule opacity. |
13178 |
+ |
|
13179 |
+@item flags, fl |
|
13180 |
+Set graticule flags. |
|
13181 |
+ |
|
13182 |
+@table @samp |
|
13183 |
+@item numbers |
|
13184 |
+Draw numbers above lines. By default enabled. |
|
13185 |
+@end table |
|
13178 | 13186 |
@end table |
13179 | 13187 |
|
13180 | 13188 |
@section xbr |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#include "libavutil/opt.h" |
24 | 24 |
#include "libavutil/parseutils.h" |
25 | 25 |
#include "libavutil/pixdesc.h" |
26 |
+#include "libavutil/xga_font_data.h" |
|
26 | 27 |
#include "avfilter.h" |
27 | 28 |
#include "formats.h" |
28 | 29 |
#include "internal.h" |
... | ... |
@@ -57,6 +58,7 @@ typedef struct WaveformContext { |
57 | 57 |
int *emin[4][4]; |
58 | 58 |
int *peak; |
59 | 59 |
int filter; |
60 |
+ int flags; |
|
60 | 61 |
int bits; |
61 | 62 |
int max; |
62 | 63 |
int size; |
... | ... |
@@ -104,6 +106,9 @@ static const AVOption waveform_options[] = { |
104 | 104 |
{ "green", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "graticule" }, |
105 | 105 |
{ "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS }, |
106 | 106 |
{ "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS }, |
107 |
+ { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 1, FLAGS, "flags" }, |
|
108 |
+ { "fl", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 1, FLAGS, "flags" }, |
|
109 |
+ { "numbers", "draw numbers", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "flags" }, |
|
107 | 110 |
{ NULL } |
108 | 111 |
}; |
109 | 112 |
|
... | ... |
@@ -1236,6 +1241,108 @@ static void blend_hline16(uint16_t *dst, int width, float o1, float o2, int v) |
1236 | 1236 |
} |
1237 | 1237 |
} |
1238 | 1238 |
|
1239 |
+static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4]) |
|
1240 |
+{ |
|
1241 |
+ const uint8_t *font; |
|
1242 |
+ int font_height; |
|
1243 |
+ int i, plane; |
|
1244 |
+ |
|
1245 |
+ font = avpriv_cga_font, font_height = 8; |
|
1246 |
+ |
|
1247 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
1248 |
+ for (i = 0; txt[i]; i++) { |
|
1249 |
+ int char_y, mask; |
|
1250 |
+ int v = color[plane]; |
|
1251 |
+ |
|
1252 |
+ uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8); |
|
1253 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
1254 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
1255 |
+ if (font[txt[i] * font_height + char_y] & mask) |
|
1256 |
+ p[0] = p[0] * o2 + v * o1; |
|
1257 |
+ p++; |
|
1258 |
+ } |
|
1259 |
+ p += out->linesize[plane] - 8; |
|
1260 |
+ } |
|
1261 |
+ } |
|
1262 |
+ } |
|
1263 |
+} |
|
1264 |
+ |
|
1265 |
+static void draw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4]) |
|
1266 |
+{ |
|
1267 |
+ const uint8_t *font; |
|
1268 |
+ int font_height; |
|
1269 |
+ int i, plane; |
|
1270 |
+ |
|
1271 |
+ font = avpriv_cga_font, font_height = 8; |
|
1272 |
+ |
|
1273 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
1274 |
+ for (i = 0; txt[i]; i++) { |
|
1275 |
+ int char_y, mask; |
|
1276 |
+ int v = color[plane] * mult; |
|
1277 |
+ |
|
1278 |
+ uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8); |
|
1279 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
1280 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
1281 |
+ if (font[txt[i] * font_height + char_y] & mask) |
|
1282 |
+ p[0] = p[0] * o2 + v * o1; |
|
1283 |
+ p++; |
|
1284 |
+ } |
|
1285 |
+ p += out->linesize[plane] / 2 - 8; |
|
1286 |
+ } |
|
1287 |
+ } |
|
1288 |
+ } |
|
1289 |
+} |
|
1290 |
+ |
|
1291 |
+static void draw_vtext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4]) |
|
1292 |
+{ |
|
1293 |
+ const uint8_t *font; |
|
1294 |
+ int font_height; |
|
1295 |
+ int i, plane; |
|
1296 |
+ |
|
1297 |
+ font = avpriv_cga_font, font_height = 8; |
|
1298 |
+ |
|
1299 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
1300 |
+ for (i = 0; txt[i]; i++) { |
|
1301 |
+ int char_y, mask; |
|
1302 |
+ int v = color[plane]; |
|
1303 |
+ |
|
1304 |
+ for (char_y = font_height - 1; char_y >= 0; char_y--) { |
|
1305 |
+ uint8_t *p = out->data[plane] + (y + i * 10) * out->linesize[plane] + x; |
|
1306 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
1307 |
+ if (font[txt[i] * font_height + font_height - 1 - char_y] & mask) |
|
1308 |
+ p[char_y] = p[char_y] * o2 + v * o1; |
|
1309 |
+ p += out->linesize[plane]; |
|
1310 |
+ } |
|
1311 |
+ } |
|
1312 |
+ } |
|
1313 |
+ } |
|
1314 |
+} |
|
1315 |
+ |
|
1316 |
+static void draw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4]) |
|
1317 |
+{ |
|
1318 |
+ const uint8_t *font; |
|
1319 |
+ int font_height; |
|
1320 |
+ int i, plane; |
|
1321 |
+ |
|
1322 |
+ font = avpriv_cga_font, font_height = 8; |
|
1323 |
+ |
|
1324 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
1325 |
+ for (i = 0; txt[i]; i++) { |
|
1326 |
+ int char_y, mask; |
|
1327 |
+ int v = color[plane] * mult; |
|
1328 |
+ |
|
1329 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
1330 |
+ uint16_t *p = (uint16_t *)(out->data[plane] + (y + i * 10) * out->linesize[plane]) + x; |
|
1331 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
1332 |
+ if (font[txt[i] * font_height + font_height - 1 - char_y] & mask) |
|
1333 |
+ p[char_y] = p[char_y] * o2 + v * o1; |
|
1334 |
+ p += out->linesize[plane] / 2; |
|
1335 |
+ } |
|
1336 |
+ } |
|
1337 |
+ } |
|
1338 |
+ } |
|
1339 |
+} |
|
1340 |
+ |
|
1239 | 1341 |
static void graticule_none(WaveformContext *s, AVFrame *out) |
1240 | 1342 |
{ |
1241 | 1343 |
} |
... | ... |
@@ -1244,12 +1351,13 @@ static void graticule_green_row(WaveformContext *s, AVFrame *out) |
1244 | 1244 |
{ |
1245 | 1245 |
const float o1 = s->opacity; |
1246 | 1246 |
const float o2 = 1. - o1; |
1247 |
- int c, p, l, offset = 0; |
|
1247 |
+ int k = 0, c, p, l, offset = 0; |
|
1248 | 1248 |
|
1249 | 1249 |
for (c = 0; c < s->ncomp; c++) { |
1250 |
- if (!((1 << c) & s->pcomp)) |
|
1250 |
+ if (!((1 << c) & s->pcomp) || (!s->display && k > 0)) |
|
1251 | 1251 |
continue; |
1252 | 1252 |
|
1253 |
+ k++; |
|
1253 | 1254 |
for (p = 0; p < s->ncomp; p++) { |
1254 | 1255 |
const int v = green_yuva_color[p]; |
1255 | 1256 |
for (l = 0; l < FF_ARRAY_ELEMS(lines[0]); l++) { |
... | ... |
@@ -1260,6 +1368,14 @@ static void graticule_green_row(WaveformContext *s, AVFrame *out) |
1260 | 1260 |
} |
1261 | 1261 |
} |
1262 | 1262 |
|
1263 |
+ for (l = 0; l < FF_ARRAY_ELEMS(lines[0]) && (s->flags & 1); l++) { |
|
1264 |
+ const int x = offset + (s->mirror ? 255 - lines[c][l] : lines[c][l]) - 10; |
|
1265 |
+ char text[16]; |
|
1266 |
+ |
|
1267 |
+ snprintf(text, sizeof(text), "%d", lines[c][l]); |
|
1268 |
+ draw_vtext(out, x, 2, o1, o2, text, green_yuva_color); |
|
1269 |
+ } |
|
1270 |
+ |
|
1263 | 1271 |
offset += 256 * s->display; |
1264 | 1272 |
} |
1265 | 1273 |
} |
... | ... |
@@ -1269,22 +1385,31 @@ static void graticule16_green_row(WaveformContext *s, AVFrame *out) |
1269 | 1269 |
const float o1 = s->opacity; |
1270 | 1270 |
const float o2 = 1. - o1; |
1271 | 1271 |
const int mult = s->size / 256; |
1272 |
- int c, p, l, offset = 0; |
|
1272 |
+ int k = 0, c, p, l, offset = 0; |
|
1273 | 1273 |
|
1274 | 1274 |
for (c = 0; c < s->ncomp; c++) { |
1275 |
- if (!((1 << c) & s->pcomp)) |
|
1275 |
+ if (!((1 << c) & s->pcomp) || (!s->display && k > 0)) |
|
1276 | 1276 |
continue; |
1277 | 1277 |
|
1278 |
+ k++; |
|
1278 | 1279 |
for (p = 0; p < s->ncomp; p++) { |
1279 | 1280 |
const int v = green_yuva_color[p] * mult; |
1280 | 1281 |
for (l = 0; l < FF_ARRAY_ELEMS(lines[0]); l++) { |
1281 |
- int x = offset + (s->mirror ? 255 - lines[c][l] : lines[c][l]) * mult; |
|
1282 |
+ int x = offset + (s->mirror ? s->size - 1 - lines[c][l] * mult : lines[c][l] * mult); |
|
1282 | 1283 |
uint16_t *dst = (uint16_t *)(out->data[p]) + x; |
1283 | 1284 |
|
1284 | 1285 |
blend_vline16(dst, out->height, out->linesize[p], o1, o2, v); |
1285 | 1286 |
} |
1286 | 1287 |
} |
1287 | 1288 |
|
1289 |
+ for (l = 0; l < FF_ARRAY_ELEMS(lines[0]) && (s->flags & 1); l++) { |
|
1290 |
+ const int x = offset + (s->mirror ? s->size - 1 - lines[c][l] * mult : lines[c][l] * mult) - 10; |
|
1291 |
+ char text[16]; |
|
1292 |
+ |
|
1293 |
+ snprintf(text, sizeof(text), "%d", lines[c][l] * mult); |
|
1294 |
+ draw_vtext16(out, x, 2, mult, o1, o2, text, green_yuva_color); |
|
1295 |
+ } |
|
1296 |
+ |
|
1288 | 1297 |
offset += s->size * s->display; |
1289 | 1298 |
} |
1290 | 1299 |
} |
... | ... |
@@ -1293,12 +1418,13 @@ static void graticule_green_column(WaveformContext *s, AVFrame *out) |
1293 | 1293 |
{ |
1294 | 1294 |
const float o1 = s->opacity; |
1295 | 1295 |
const float o2 = 1. - o1; |
1296 |
- int c, p, l, offset = 0; |
|
1296 |
+ int k = 0, c, p, l, offset = 0; |
|
1297 | 1297 |
|
1298 | 1298 |
for (c = 0; c < s->ncomp; c++) { |
1299 |
- if (!((1 << c) & s->pcomp)) |
|
1299 |
+ if ((!((1 << c) & s->pcomp) || (!s->display && k > 0))) |
|
1300 | 1300 |
continue; |
1301 | 1301 |
|
1302 |
+ k++; |
|
1302 | 1303 |
for (p = 0; p < s->ncomp; p++) { |
1303 | 1304 |
const int v = green_yuva_color[p]; |
1304 | 1305 |
for (l = 0; l < FF_ARRAY_ELEMS(lines[0]); l++) { |
... | ... |
@@ -1309,6 +1435,15 @@ static void graticule_green_column(WaveformContext *s, AVFrame *out) |
1309 | 1309 |
} |
1310 | 1310 |
} |
1311 | 1311 |
|
1312 |
+ for (l = 0; l < FF_ARRAY_ELEMS(lines[0]) && (s->flags & 1); l++) { |
|
1313 |
+ const int y = offset + (s->mirror ? 255 - lines[c][l] : lines[c][l]) - 10; |
|
1314 |
+ char text[16]; |
|
1315 |
+ |
|
1316 |
+ snprintf(text, sizeof(text), "%d", lines[c][l]); |
|
1317 |
+ draw_htext(out, 2, y, |
|
1318 |
+ o1, o2, text, green_yuva_color); |
|
1319 |
+ } |
|
1320 |
+ |
|
1312 | 1321 |
offset += 256 * s->display; |
1313 | 1322 |
} |
1314 | 1323 |
} |
... | ... |
@@ -1318,22 +1453,32 @@ static void graticule16_green_column(WaveformContext *s, AVFrame *out) |
1318 | 1318 |
const float o1 = s->opacity; |
1319 | 1319 |
const float o2 = 1. - o1; |
1320 | 1320 |
const int mult = s->size / 256; |
1321 |
- int c, p, l, offset = 0; |
|
1321 |
+ int k = 0, c, p, l, offset = 0; |
|
1322 | 1322 |
|
1323 | 1323 |
for (c = 0; c < s->ncomp; c++) { |
1324 |
- if (!((1 << c) & s->pcomp)) |
|
1324 |
+ if ((!((1 << c) & s->pcomp) || (!s->display && k > 0))) |
|
1325 | 1325 |
continue; |
1326 | 1326 |
|
1327 |
+ k++; |
|
1327 | 1328 |
for (p = 0; p < s->ncomp; p++) { |
1328 | 1329 |
const int v = green_yuva_color[p] * mult; |
1329 | 1330 |
for (l = 0; l < FF_ARRAY_ELEMS(lines[0]); l++) { |
1330 |
- int y = offset + (s->mirror ? 255 - lines[c][l] : lines[c][l]) * mult; |
|
1331 |
+ int y = offset + (s->mirror ? s->size - 1 - lines[c][l] * mult : lines[c][l] * mult); |
|
1331 | 1332 |
uint16_t *dst = (uint16_t *)(out->data[p] + y * out->linesize[p]); |
1332 | 1333 |
|
1333 | 1334 |
blend_hline16(dst, out->width, o1, o2, v); |
1334 | 1335 |
} |
1335 | 1336 |
} |
1336 | 1337 |
|
1338 |
+ for (l = 0; l < FF_ARRAY_ELEMS(lines[0]) && (s->flags & 1); l++) { |
|
1339 |
+ const int y = offset + (s->mirror ? s->size - 1 - lines[c][l] * mult : lines[c][l] * mult) - 10; |
|
1340 |
+ char text[16]; |
|
1341 |
+ |
|
1342 |
+ snprintf(text, sizeof(text), "%d", lines[c][l] * mult); |
|
1343 |
+ draw_htext16(out, 2, y, |
|
1344 |
+ mult, o1, o2, text, green_yuva_color); |
|
1345 |
+ } |
|
1346 |
+ |
|
1337 | 1347 |
offset += s->size * s->display; |
1338 | 1348 |
} |
1339 | 1349 |
} |