... | ... |
@@ -14867,7 +14867,8 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c |
14867 | 14867 |
@anchor{smptehdbars} |
14868 | 14868 |
@anchor{testsrc} |
14869 | 14869 |
@anchor{testsrc2} |
14870 |
-@section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2 |
|
14870 |
+@anchor{yuvtestsrc} |
|
14871 |
+@section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc |
|
14871 | 14872 |
|
14872 | 14873 |
The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors. |
14873 | 14874 |
|
... | ... |
@@ -14900,6 +14901,9 @@ The @code{testsrc2} source is similar to testsrc, but supports more |
14900 | 14900 |
pixel formats instead of just @code{rgb24}. This allows using it as an |
14901 | 14901 |
input for other tests without requiring a format conversion. |
14902 | 14902 |
|
14903 |
+The @code{yuvtestsrc} source generates an YUV test pattern. You should |
|
14904 |
+see a y, cb and cr stripe from top to bottom. |
|
14905 |
+ |
|
14903 | 14906 |
The sources accept the following parameters: |
14904 | 14907 |
|
14905 | 14908 |
@table @option |
... | ... |
@@ -315,6 +315,7 @@ OBJS-$(CONFIG_SMPTEBARS_FILTER) += vsrc_testsrc.o |
315 | 315 |
OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o |
316 | 316 |
OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o |
317 | 317 |
OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o |
318 |
+OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o |
|
318 | 319 |
|
319 | 320 |
# multimedia filters |
320 | 321 |
OBJS-$(CONFIG_ADRAWGRAPH_FILTER) += f_drawgraph.o |
... | ... |
@@ -330,6 +330,7 @@ void avfilter_register_all(void) |
330 | 330 |
REGISTER_FILTER(SMPTEHDBARS, smptehdbars, vsrc); |
331 | 331 |
REGISTER_FILTER(TESTSRC, testsrc, vsrc); |
332 | 332 |
REGISTER_FILTER(TESTSRC2, testsrc2, vsrc); |
333 |
+ REGISTER_FILTER(YUVTESTSRC, yuvtestsrc, vsrc); |
|
333 | 334 |
|
334 | 335 |
REGISTER_FILTER(NULLSINK, nullsink, vsink); |
335 | 336 |
|
... | ... |
@@ -1070,6 +1070,182 @@ AVFilter ff_vsrc_rgbtestsrc = { |
1070 | 1070 |
|
1071 | 1071 |
#endif /* CONFIG_RGBTESTSRC_FILTER */ |
1072 | 1072 |
|
1073 |
+#if CONFIG_YUVTESTSRC_FILTER |
|
1074 |
+ |
|
1075 |
+#define yuvtestsrc_options options |
|
1076 |
+AVFILTER_DEFINE_CLASS(yuvtestsrc); |
|
1077 |
+ |
|
1078 |
+static void yuvtest_fill_picture8(AVFilterContext *ctx, AVFrame *frame) |
|
1079 |
+{ |
|
1080 |
+ int x, y, w = frame->width, h = frame->height / 3; |
|
1081 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
|
1082 |
+ const int factor = 1 << desc->comp[0].depth; |
|
1083 |
+ const int mid = 1 << (desc->comp[0].depth - 1); |
|
1084 |
+ uint8_t *ydst = frame->data[0]; |
|
1085 |
+ uint8_t *udst = frame->data[1]; |
|
1086 |
+ uint8_t *vdst = frame->data[2]; |
|
1087 |
+ int ylinesize = frame->linesize[0]; |
|
1088 |
+ int ulinesize = frame->linesize[1]; |
|
1089 |
+ int vlinesize = frame->linesize[2]; |
|
1090 |
+ |
|
1091 |
+ for (y = 0; y < h; y++) { |
|
1092 |
+ for (x = 0; x < w; x++) { |
|
1093 |
+ int c = factor * x / w; |
|
1094 |
+ |
|
1095 |
+ ydst[x] = c; |
|
1096 |
+ udst[x] = mid; |
|
1097 |
+ vdst[x] = mid; |
|
1098 |
+ } |
|
1099 |
+ |
|
1100 |
+ ydst += ylinesize; |
|
1101 |
+ udst += ulinesize; |
|
1102 |
+ vdst += vlinesize; |
|
1103 |
+ } |
|
1104 |
+ |
|
1105 |
+ h += h; |
|
1106 |
+ for (; y < h; y++) { |
|
1107 |
+ for (x = 0; x < w; x++) { |
|
1108 |
+ int c = factor * x / w; |
|
1109 |
+ |
|
1110 |
+ ydst[x] = mid; |
|
1111 |
+ udst[x] = c; |
|
1112 |
+ vdst[x] = mid; |
|
1113 |
+ } |
|
1114 |
+ |
|
1115 |
+ ydst += ylinesize; |
|
1116 |
+ udst += ulinesize; |
|
1117 |
+ vdst += vlinesize; |
|
1118 |
+ } |
|
1119 |
+ |
|
1120 |
+ for (; y < frame->height; y++) { |
|
1121 |
+ for (x = 0; x < w; x++) { |
|
1122 |
+ int c = factor * x / w; |
|
1123 |
+ |
|
1124 |
+ ydst[x] = mid; |
|
1125 |
+ udst[x] = mid; |
|
1126 |
+ vdst[x] = c; |
|
1127 |
+ } |
|
1128 |
+ |
|
1129 |
+ ydst += ylinesize; |
|
1130 |
+ udst += ulinesize; |
|
1131 |
+ vdst += vlinesize; |
|
1132 |
+ } |
|
1133 |
+} |
|
1134 |
+ |
|
1135 |
+static void yuvtest_fill_picture16(AVFilterContext *ctx, AVFrame *frame) |
|
1136 |
+{ |
|
1137 |
+ int x, y, w = frame->width, h = frame->height / 3; |
|
1138 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
|
1139 |
+ const int factor = 1 << desc->comp[0].depth; |
|
1140 |
+ const int mid = 1 << (desc->comp[0].depth - 1); |
|
1141 |
+ uint16_t *ydst = (uint16_t *)frame->data[0]; |
|
1142 |
+ uint16_t *udst = (uint16_t *)frame->data[1]; |
|
1143 |
+ uint16_t *vdst = (uint16_t *)frame->data[2]; |
|
1144 |
+ int ylinesize = frame->linesize[0] / 2; |
|
1145 |
+ int ulinesize = frame->linesize[1] / 2; |
|
1146 |
+ int vlinesize = frame->linesize[2] / 2; |
|
1147 |
+ |
|
1148 |
+ for (y = 0; y < h; y++) { |
|
1149 |
+ for (x = 0; x < w; x++) { |
|
1150 |
+ int c = factor * x / w; |
|
1151 |
+ |
|
1152 |
+ ydst[x] = c; |
|
1153 |
+ udst[x] = mid; |
|
1154 |
+ vdst[x] = mid; |
|
1155 |
+ } |
|
1156 |
+ |
|
1157 |
+ ydst += ylinesize; |
|
1158 |
+ udst += ulinesize; |
|
1159 |
+ vdst += vlinesize; |
|
1160 |
+ } |
|
1161 |
+ |
|
1162 |
+ h += h; |
|
1163 |
+ for (; y < h; y++) { |
|
1164 |
+ for (x = 0; x < w; x++) { |
|
1165 |
+ int c = factor * x / w; |
|
1166 |
+ |
|
1167 |
+ ydst[x] = mid; |
|
1168 |
+ udst[x] = c; |
|
1169 |
+ vdst[x] = mid; |
|
1170 |
+ } |
|
1171 |
+ |
|
1172 |
+ ydst += ylinesize; |
|
1173 |
+ udst += ulinesize; |
|
1174 |
+ vdst += vlinesize; |
|
1175 |
+ } |
|
1176 |
+ |
|
1177 |
+ for (; y < frame->height; y++) { |
|
1178 |
+ for (x = 0; x < w; x++) { |
|
1179 |
+ int c = factor * x / w; |
|
1180 |
+ |
|
1181 |
+ ydst[x] = mid; |
|
1182 |
+ udst[x] = mid; |
|
1183 |
+ vdst[x] = c; |
|
1184 |
+ } |
|
1185 |
+ |
|
1186 |
+ ydst += ylinesize; |
|
1187 |
+ udst += ulinesize; |
|
1188 |
+ vdst += vlinesize; |
|
1189 |
+ } |
|
1190 |
+} |
|
1191 |
+ |
|
1192 |
+static av_cold int yuvtest_init(AVFilterContext *ctx) |
|
1193 |
+{ |
|
1194 |
+ TestSourceContext *test = ctx->priv; |
|
1195 |
+ |
|
1196 |
+ test->draw_once = 1; |
|
1197 |
+ return init(ctx); |
|
1198 |
+} |
|
1199 |
+ |
|
1200 |
+static int yuvtest_query_formats(AVFilterContext *ctx) |
|
1201 |
+{ |
|
1202 |
+ static const enum AVPixelFormat pix_fmts[] = { |
|
1203 |
+ AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, |
|
1204 |
+ AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, |
|
1205 |
+ AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, |
|
1206 |
+ AV_PIX_FMT_YUV444P16, |
|
1207 |
+ AV_PIX_FMT_NONE |
|
1208 |
+ }; |
|
1209 |
+ |
|
1210 |
+ AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); |
|
1211 |
+ if (!fmts_list) |
|
1212 |
+ return AVERROR(ENOMEM); |
|
1213 |
+ return ff_set_common_formats(ctx, fmts_list); |
|
1214 |
+} |
|
1215 |
+ |
|
1216 |
+static int yuvtest_config_props(AVFilterLink *outlink) |
|
1217 |
+{ |
|
1218 |
+ TestSourceContext *test = outlink->src->priv; |
|
1219 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); |
|
1220 |
+ |
|
1221 |
+ test->fill_picture_fn = desc->comp[0].depth > 8 ? yuvtest_fill_picture16 : yuvtest_fill_picture8; |
|
1222 |
+ return config_props(outlink); |
|
1223 |
+} |
|
1224 |
+ |
|
1225 |
+static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = { |
|
1226 |
+ { |
|
1227 |
+ .name = "default", |
|
1228 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
1229 |
+ .request_frame = request_frame, |
|
1230 |
+ .config_props = yuvtest_config_props, |
|
1231 |
+ }, |
|
1232 |
+ { NULL } |
|
1233 |
+}; |
|
1234 |
+ |
|
1235 |
+AVFilter ff_vsrc_yuvtestsrc = { |
|
1236 |
+ .name = "yuvtestsrc", |
|
1237 |
+ .description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."), |
|
1238 |
+ .priv_size = sizeof(TestSourceContext), |
|
1239 |
+ .priv_class = &yuvtestsrc_class, |
|
1240 |
+ .init = yuvtest_init, |
|
1241 |
+ .uninit = uninit, |
|
1242 |
+ .query_formats = yuvtest_query_formats, |
|
1243 |
+ .inputs = NULL, |
|
1244 |
+ .outputs = avfilter_vsrc_yuvtestsrc_outputs, |
|
1245 |
+}; |
|
1246 |
+ |
|
1247 |
+#endif /* CONFIG_YUVTESTSRC_FILTER */ |
|
1248 |
+ |
|
1073 | 1249 |
#if CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER |
1074 | 1250 |
|
1075 | 1251 |
static const uint8_t rainbow[7][4] = { |