Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2015/06/29 16:38:16... | ... |
@@ -12023,6 +12023,9 @@ The expression can use the following variables: |
12023 | 12023 |
@item VOLUME |
12024 | 12024 |
Current max volume of channel in dB. |
12025 | 12025 |
@end table |
12026 |
+ |
|
12027 |
+@item t |
|
12028 |
+If set, displays channel names. Default is enabled. |
|
12026 | 12029 |
@end table |
12027 | 12030 |
|
12028 | 12031 |
@section showwaves |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#include "libavutil/intreadwrite.h" |
24 | 24 |
#include "libavutil/opt.h" |
25 | 25 |
#include "libavutil/parseutils.h" |
26 |
+#include "libavutil/xga_font_data.h" |
|
26 | 27 |
#include "avfilter.h" |
27 | 28 |
#include "formats.h" |
28 | 29 |
#include "audio.h" |
... | ... |
@@ -38,6 +39,7 @@ typedef struct ShowVolumeContext { |
38 | 38 |
|
39 | 39 |
AVFrame *out; |
40 | 40 |
AVExpr *c_expr; |
41 |
+ int draw_text; |
|
41 | 42 |
} ShowVolumeContext; |
42 | 43 |
|
43 | 44 |
#define OFFSET(x) offsetof(ShowVolumeContext, x) |
... | ... |
@@ -51,6 +53,7 @@ static const AVOption showvolume_options[] = { |
51 | 51 |
{ "h", "set channel height", OFFSET(h), AV_OPT_TYPE_INT, {.i64=20}, 1, 100, FLAGS }, |
52 | 52 |
{ "f", "set fade", OFFSET(f), AV_OPT_TYPE_INT, {.i64=20}, 1, 255, FLAGS }, |
53 | 53 |
{ "c", "set volume color expression", OFFSET(color), AV_OPT_TYPE_STRING, {.str="if(gte(VOLUME,-2), if(gte(VOLUME,-1),0xff, 0xffff),0xff00)"}, 0, 0, FLAGS }, |
54 |
+ { "t", "display channel names", OFFSET(draw_text), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, |
|
54 | 55 |
{ NULL } |
55 | 56 |
}; |
56 | 57 |
|
... | ... |
@@ -133,6 +136,29 @@ static int config_output(AVFilterLink *outlink) |
133 | 133 |
return 0; |
134 | 134 |
} |
135 | 135 |
|
136 |
+static void drawtext(AVFrame *pic, int x, int y, const char *txt) |
|
137 |
+{ |
|
138 |
+ const uint8_t *font; |
|
139 |
+ int font_height; |
|
140 |
+ int i; |
|
141 |
+ |
|
142 |
+ font = avpriv_cga_font, font_height = 8; |
|
143 |
+ |
|
144 |
+ for (i = 0; txt[i]; i++) { |
|
145 |
+ int char_y, mask; |
|
146 |
+ uint8_t *p = pic->data[0] + y*pic->linesize[0] + (x + i*8)*4; |
|
147 |
+ |
|
148 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
149 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
150 |
+ if (font[txt[i] * font_height + char_y] & mask) |
|
151 |
+ AV_WN32(p, ~AV_RN32(p)); |
|
152 |
+ p += 4; |
|
153 |
+ } |
|
154 |
+ p += pic->linesize[0] - 8*4; |
|
155 |
+ } |
|
156 |
+ } |
|
157 |
+} |
|
158 |
+ |
|
136 | 159 |
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
137 | 160 |
{ |
138 | 161 |
AVFilterContext *ctx = inlink->dst; |
... | ... |
@@ -183,6 +209,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
183 | 183 |
for (k = 0; k < s->w * max; k++) |
184 | 184 |
AV_WN32A(dst + k * 4, color); |
185 | 185 |
} |
186 |
+ |
|
187 |
+ if (s->h >= 8 && s->draw_text) |
|
188 |
+ drawtext(s->out, 2, c * (s->h + s->b) + (s->h - 8) / 2, |
|
189 |
+ av_get_channel_name(av_channel_layout_extract_channel(insamples->channel_layout, c))); |
|
186 | 190 |
} |
187 | 191 |
|
188 | 192 |
av_frame_free(&insamples); |