Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2016/03/07 22:18:09... | ... |
@@ -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" |
... | ... |
@@ -99,10 +100,11 @@ static const AVOption vectorscope_options[] = { |
99 | 99 |
{ "color", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "graticule" }, |
100 | 100 |
{ "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS}, |
101 | 101 |
{ "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS}, |
102 |
- { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 3, FLAGS, "flags"}, |
|
103 |
- { "f", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 3, FLAGS, "flags"}, |
|
102 |
+ { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"}, |
|
103 |
+ { "f", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"}, |
|
104 | 104 |
{ "white", "draw white point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "flags" }, |
105 | 105 |
{ "black", "draw black point", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "flags" }, |
106 |
+ { "name", "draw point name", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "flags" }, |
|
106 | 107 |
{ "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS}, |
107 | 108 |
{ "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS}, |
108 | 109 |
{ "lthreshold", "set low threshold", OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS}, |
... | ... |
@@ -769,9 +771,14 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p |
769 | 769 |
} |
770 | 770 |
} |
771 | 771 |
|
772 |
+const static char *positions_name[] = { |
|
773 |
+ "R", "B", "Cy", "Yl", "G", "M", |
|
774 |
+}; |
|
775 |
+ |
|
772 | 776 |
const static uint16_t positions[][14][3] = { |
773 |
- { { 210, 16, 146 }, { 170, 166, 16 }, { 145, 54, 34 }, |
|
774 |
- { 106, 202, 222 }, { 81, 90, 240 }, { 41, 240, 110 }, |
|
777 |
+ { |
|
778 |
+ { 81, 90, 240 }, { 41, 240, 110 }, { 170, 166, 16 }, |
|
779 |
+ { 210, 16, 146 }, { 145, 54, 34 }, { 106, 202, 222 }, |
|
775 | 780 |
{ 162, 44, 142 }, { 131, 156, 44 }, { 112, 72, 58 }, |
776 | 781 |
{ 84, 184, 198 }, { 65, 100, 212 }, { 35, 212, 114 }, |
777 | 782 |
{ 235, 128, 128 }, { 16, 128, 128 } }, |
... | ... |
@@ -780,8 +787,8 @@ const static uint16_t positions[][14][3] = { |
780 | 780 |
{ 28, 212, 120 }, { 51, 109, 212 }, { 63, 193, 204 }, |
781 | 781 |
{ 133, 63, 52 }, { 145, 147, 44 }, { 168, 44, 136 }, |
782 | 782 |
{ 235, 128, 128 }, { 16, 128, 128 } }, |
783 |
- { { 210*2, 16*2, 146*2 }, { 170*2, 166*2, 16*2 }, { 145*2, 54*2, 34*2 }, |
|
784 |
- { 106*2, 202*2, 222*2 }, { 81*2, 90*2, 240*2 }, { 41*2, 240*2, 110*2 }, |
|
783 |
+ { { 81*2, 90*2, 240*2 }, { 41*2, 240*2, 110*2 }, { 170*2, 166*2, 16*2 }, |
|
784 |
+ { 210*2, 16*2, 146*2 }, { 145*2, 54*2, 34*2 }, { 106*2, 202*2, 222*2 }, |
|
785 | 785 |
{ 162*2, 44*2, 142*2 }, { 131*2, 156*2, 44*2 }, { 112*2, 72*2, 58*2 }, |
786 | 786 |
{ 84*2, 184*2, 198*2 }, { 65*2, 100*2, 212*2 }, { 35*2, 212*2, 114*2 }, |
787 | 787 |
{ 470, 256, 256 }, { 32, 256, 256 } }, |
... | ... |
@@ -790,8 +797,8 @@ const static uint16_t positions[][14][3] = { |
790 | 790 |
{ 28*2, 212*2, 120*2 }, { 51*2, 109*2, 212*2 }, { 63*2, 193*2, 204*2 }, |
791 | 791 |
{ 133*2, 63*2, 52*2 }, { 145*2, 147*2, 44*2 }, { 168*2, 44*2, 136*2 }, |
792 | 792 |
{ 470, 256, 256 }, { 32, 256, 256 } }, |
793 |
- { { 210*4, 16*4, 146*4 }, { 170*4, 166*4, 16*4 }, { 145*4, 54*4, 34*4 }, |
|
794 |
- { 106*4, 202*4, 222*4 }, { 81*4, 90*4, 240*4 }, { 41*4, 240*4, 110*4 }, |
|
793 |
+ { { 81*4, 90*4, 240*4 }, { 41*4, 240*4, 110*4 }, { 170*4, 166*4, 16*4 }, |
|
794 |
+ { 210*4, 16*4, 146*4 }, { 145*4, 54*4, 34*4 }, { 106*4, 202*4, 222*4 }, |
|
795 | 795 |
{ 162*4, 44*4, 142*4 }, { 131*4, 156*4, 44*4 }, { 112*4, 72*4, 58*4 }, |
796 | 796 |
{ 84*4, 184*4, 198*4 }, { 65*4, 100*4, 212*4 }, { 35*4, 212*4, 114*4 }, |
797 | 797 |
{ 940, 512, 512 }, { 64, 512, 512 } }, |
... | ... |
@@ -800,18 +807,18 @@ const static uint16_t positions[][14][3] = { |
800 | 800 |
{ 28*4, 212*4, 120*4 }, { 51*4, 109*4, 212*4 }, { 63*4, 193*4, 204*4 }, |
801 | 801 |
{ 133*4, 63*4, 52*4 }, { 145*4, 147*4, 44*4 }, { 168*4, 44*4, 136*4 }, |
802 | 802 |
{ 940, 512, 512 }, { 64, 512, 512 } }, |
803 |
- { { 210*8, 16*8, 146*8 }, { 170*8, 166*8, 16*8 }, { 145*8, 54*8, 34*8 }, |
|
804 |
- { 106*8, 202*8, 222*8 }, { 81*8, 90*8, 240*8 }, { 41*8, 240*8, 110*8 }, |
|
805 |
- { 162*8, 44*8, 142*8 }, { 131*8, 156*8, 44*8 }, { 112*8, 72*8, 58*8 }, |
|
806 |
- { 84*8, 184*8, 198*8 }, { 65*8, 100*8, 212*8 }, { 35*8, 212*8, 114*8 }, |
|
803 |
+ { { 81*8, 90*4, 240*8 }, { 41*8, 240*8, 110*8 }, { 170*8, 166*8, 16*8 }, |
|
804 |
+ { 210*8, 16*4, 146*8 }, { 145*8, 54*8, 34*8 }, { 106*8, 202*8, 222*8 }, |
|
805 |
+ { 162*8, 44*4, 142*8 }, { 131*8, 156*8, 44*8 }, { 112*8, 72*8, 58*8 }, |
|
806 |
+ { 84*8, 184*4, 198*8 }, { 65*8, 100*8, 212*8 }, { 35*8, 212*8, 114*8 }, |
|
807 | 807 |
{ 1880, 1024, 1024 }, { 128, 1024, 1024 } }, |
808 | 808 |
{ { 63*8, 102*8, 240*8 }, { 32*8, 240*8, 118*8 }, { 188*8, 154*8, 16*8 }, |
809 | 809 |
{ 219*8, 16*8, 138*8 }, { 173*8, 42*8, 26*8 }, { 78*8, 214*8, 230*8 }, |
810 | 810 |
{ 28*8, 212*8, 120*8 }, { 51*8, 109*8, 212*8 }, { 63*8, 193*8, 204*8 }, |
811 | 811 |
{ 133*8, 63*8, 52*8 }, { 145*8, 147*8, 44*8 }, { 168*8, 44*8, 136*8 }, |
812 | 812 |
{ 1880, 1024, 1024 }, { 128, 1024, 1024 } }, |
813 |
- { { 210*16, 16*16, 146*16 }, { 170*16, 166*16, 16*16 }, { 145*16, 54*16, 34*16 }, |
|
814 |
- { 106*16, 202*16, 222*16 }, { 81*16, 90*16, 240*16 }, { 41*16, 240*16, 110*16 }, |
|
813 |
+ { { 81*16, 90*16, 240*16 }, { 41*16, 240*16, 110*16 }, { 170*16, 166*16, 16*16 }, |
|
814 |
+ { 210*16, 16*16, 146*16 }, { 145*16, 54*16, 34*16 }, { 106*16, 202*16, 222*16 }, |
|
815 | 815 |
{ 162*16, 44*16, 142*16 }, { 131*16, 156*16, 44*16 }, { 112*16, 72*16, 58*16 }, |
816 | 816 |
{ 84*16, 184*16, 198*16 }, { 65*16, 100*16, 212*16 }, { 35*16, 212*16, 114*16 }, |
817 | 817 |
{ 3760, 2048, 2048 }, { 256, 2048, 2048 } }, |
... | ... |
@@ -872,6 +879,58 @@ static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, in |
872 | 872 |
{ |
873 | 873 |
} |
874 | 874 |
|
875 |
+static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4]) |
|
876 |
+{ |
|
877 |
+ const uint8_t *font; |
|
878 |
+ int font_height; |
|
879 |
+ int i, plane; |
|
880 |
+ |
|
881 |
+ font = avpriv_cga_font, font_height = 8; |
|
882 |
+ |
|
883 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
884 |
+ for (i = 0; txt[i]; i++) { |
|
885 |
+ int char_y, mask; |
|
886 |
+ int v = color[plane]; |
|
887 |
+ |
|
888 |
+ uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8); |
|
889 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
890 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
891 |
+ if (font[txt[i] * font_height + char_y] & mask) |
|
892 |
+ p[0] = p[0] * o2 + v * o1; |
|
893 |
+ p++; |
|
894 |
+ } |
|
895 |
+ p += out->linesize[plane] - 8; |
|
896 |
+ } |
|
897 |
+ } |
|
898 |
+ } |
|
899 |
+} |
|
900 |
+ |
|
901 |
+static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4]) |
|
902 |
+{ |
|
903 |
+ const uint8_t *font; |
|
904 |
+ int font_height; |
|
905 |
+ int i, plane; |
|
906 |
+ |
|
907 |
+ font = avpriv_cga_font, font_height = 8; |
|
908 |
+ |
|
909 |
+ for (plane = 0; plane < 4 && out->data[plane]; plane++) { |
|
910 |
+ for (i = 0; txt[i]; i++) { |
|
911 |
+ int char_y, mask; |
|
912 |
+ int v = color[plane]; |
|
913 |
+ |
|
914 |
+ uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8); |
|
915 |
+ for (char_y = 0; char_y < font_height; char_y++) { |
|
916 |
+ for (mask = 0x80; mask; mask >>= 1) { |
|
917 |
+ if (font[txt[i] * font_height + char_y] & mask) |
|
918 |
+ p[0] = p[0] * o2 + v * o1; |
|
919 |
+ p++; |
|
920 |
+ } |
|
921 |
+ p += out->linesize[plane] / 2 - 8; |
|
922 |
+ } |
|
923 |
+ } |
|
924 |
+ } |
|
925 |
+} |
|
926 |
+ |
|
875 | 927 |
static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P) |
876 | 928 |
{ |
877 | 929 |
const int max = s->size - 1; |
... | ... |
@@ -913,6 +972,31 @@ static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, |
913 | 913 |
if (out->data[3]) |
914 | 914 |
draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o); |
915 | 915 |
} |
916 |
+ |
|
917 |
+ for (i = 0; i < 6 && s->flags & 4; i++) { |
|
918 |
+ uint16_t color[4] = { 0, 0, 0, 0 }; |
|
919 |
+ int x = positions[P][i][X]; |
|
920 |
+ int y = positions[P][i][Y]; |
|
921 |
+ int d = positions[P][i][D]; |
|
922 |
+ |
|
923 |
+ color[D] = d; |
|
924 |
+ color[X] = x; |
|
925 |
+ color[Y] = y; |
|
926 |
+ color[3] = max; |
|
927 |
+ |
|
928 |
+ if (x > max / 2) |
|
929 |
+ x += 8; |
|
930 |
+ else |
|
931 |
+ x -= 14; |
|
932 |
+ if (y > max / 2) |
|
933 |
+ y += 8; |
|
934 |
+ else |
|
935 |
+ y -= 14; |
|
936 |
+ |
|
937 |
+ x = av_clip(x, 0, out->width - 9); |
|
938 |
+ y = av_clip(y, 0, out->height - 9); |
|
939 |
+ draw_htext16(out, x, y, o, 1. - o, positions_name[i], color); |
|
940 |
+ } |
|
916 | 941 |
} |
917 | 942 |
|
918 | 943 |
static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P) |
... | ... |
@@ -955,6 +1039,30 @@ static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, i |
955 | 955 |
if (out->data[3]) |
956 | 956 |
draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o); |
957 | 957 |
} |
958 |
+ |
|
959 |
+ for (i = 0; i < 6 && s->flags & 4; i++) { |
|
960 |
+ uint8_t color[4] = { 0, 0, 0, 255 }; |
|
961 |
+ int x = positions[P][i][X]; |
|
962 |
+ int y = positions[P][i][Y]; |
|
963 |
+ int d = positions[P][i][D]; |
|
964 |
+ |
|
965 |
+ color[D] = d; |
|
966 |
+ color[X] = x; |
|
967 |
+ color[Y] = y; |
|
968 |
+ |
|
969 |
+ if (x > 128) |
|
970 |
+ x += 8; |
|
971 |
+ else |
|
972 |
+ x -= 14; |
|
973 |
+ if (y > 128) |
|
974 |
+ y += 8; |
|
975 |
+ else |
|
976 |
+ y -= 14; |
|
977 |
+ |
|
978 |
+ x = av_clip(x, 0, out->width - 9); |
|
979 |
+ y = av_clip(y, 0, out->height - 9); |
|
980 |
+ draw_htext(out, x, y, o, 1. - o, positions_name[i], color); |
|
981 |
+ } |
|
958 | 982 |
} |
959 | 983 |
|
960 | 984 |
static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P) |
... | ... |
@@ -996,6 +1104,25 @@ static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, |
996 | 996 |
if (out->data[3]) |
997 | 997 |
draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o); |
998 | 998 |
} |
999 |
+ |
|
1000 |
+ for (i = 0; i < 6 && s->flags & 4; i++) { |
|
1001 |
+ const uint16_t color[4] = { 128 * m, 0, 0, max }; |
|
1002 |
+ int x = positions[P][i][X]; |
|
1003 |
+ int y = positions[P][i][Y]; |
|
1004 |
+ |
|
1005 |
+ if (x > max / 2) |
|
1006 |
+ x += 8; |
|
1007 |
+ else |
|
1008 |
+ x -= 14; |
|
1009 |
+ if (y > max / 2) |
|
1010 |
+ y += 8; |
|
1011 |
+ else |
|
1012 |
+ y -= 14; |
|
1013 |
+ |
|
1014 |
+ x = av_clip(x, 0, out->width - 9); |
|
1015 |
+ y = av_clip(y, 0, out->height - 9); |
|
1016 |
+ draw_htext16(out, x, y, o, 1. - o, positions_name[i], color); |
|
1017 |
+ } |
|
999 | 1018 |
} |
1000 | 1019 |
|
1001 | 1020 |
static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P) |
... | ... |
@@ -1035,6 +1162,25 @@ static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, i |
1035 | 1035 |
if (out->data[3]) |
1036 | 1036 |
draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o); |
1037 | 1037 |
} |
1038 |
+ |
|
1039 |
+ for (i = 0; i < 6 && s->flags & 4; i++) { |
|
1040 |
+ const uint8_t color[4] = { 128, 0, 0, 255 }; |
|
1041 |
+ int x = positions[P][i][X]; |
|
1042 |
+ int y = positions[P][i][Y]; |
|
1043 |
+ |
|
1044 |
+ if (x > 128) |
|
1045 |
+ x += 8; |
|
1046 |
+ else |
|
1047 |
+ x -= 14; |
|
1048 |
+ if (y > 128) |
|
1049 |
+ y += 8; |
|
1050 |
+ else |
|
1051 |
+ y -= 14; |
|
1052 |
+ |
|
1053 |
+ x = av_clip(x, 0, out->width - 9); |
|
1054 |
+ y = av_clip(y, 0, out->height - 9); |
|
1055 |
+ draw_htext(out, x, y, o, 1. - o, positions_name[i], color); |
|
1056 |
+ } |
|
1038 | 1057 |
} |
1039 | 1058 |
|
1040 | 1059 |
static int filter_frame(AVFilterLink *inlink, AVFrame *in) |