|
|
|
@ -71,20 +71,26 @@ typedef struct { |
|
|
|
|
|
|
|
|
|
/* only used by rgbtest */ |
|
|
|
|
uint8_t rgba_map[4]; |
|
|
|
|
|
|
|
|
|
/* only used by haldclut */ |
|
|
|
|
int level; |
|
|
|
|
} TestSourceContext; |
|
|
|
|
|
|
|
|
|
#define OFFSET(x) offsetof(TestSourceContext, x) |
|
|
|
|
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM |
|
|
|
|
|
|
|
|
|
#define COMMON_OPTIONS \ |
|
|
|
|
#define SIZE_OPTIONS \ |
|
|
|
|
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
|
|
|
|
|
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
|
|
|
|
|
|
|
|
|
|
#define COMMON_OPTIONS_NOSIZE \ |
|
|
|
|
{ "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
|
|
|
|
|
{ "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
|
|
|
|
|
{ "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
|
|
|
|
|
{ "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
|
|
|
|
|
{ "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS }, |
|
|
|
|
|
|
|
|
|
#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE |
|
|
|
|
|
|
|
|
|
static const AVOption options[] = { |
|
|
|
|
COMMON_OPTIONS |
|
|
|
@ -269,6 +275,135 @@ AVFilter avfilter_vsrc_color = { |
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_COLOR_FILTER */ |
|
|
|
|
|
|
|
|
|
#if CONFIG_HALDCLUTSRC_FILTER |
|
|
|
|
|
|
|
|
|
static const AVOption haldclutsrc_options[] = { |
|
|
|
|
{ "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 8, FLAGS }, |
|
|
|
|
COMMON_OPTIONS |
|
|
|
|
{ NULL } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
AVFILTER_DEFINE_CLASS(haldclutsrc); |
|
|
|
|
|
|
|
|
|
static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame) |
|
|
|
|
{ |
|
|
|
|
int i, j, k, x = 0, y = 0, is16bit = 0, step; |
|
|
|
|
uint32_t alpha = 0; |
|
|
|
|
const TestSourceContext *hc = ctx->priv; |
|
|
|
|
int level = hc->level; |
|
|
|
|
float scale; |
|
|
|
|
const int w = frame->width; |
|
|
|
|
const int h = frame->height; |
|
|
|
|
const uint8_t *data = frame->data[0]; |
|
|
|
|
const int linesize = frame->linesize[0]; |
|
|
|
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
|
|
|
|
uint8_t rgba_map[4]; |
|
|
|
|
|
|
|
|
|
av_assert0(w == h && w == level*level*level); |
|
|
|
|
|
|
|
|
|
ff_fill_rgba_map(rgba_map, frame->format); |
|
|
|
|
|
|
|
|
|
switch (frame->format) { |
|
|
|
|
case AV_PIX_FMT_RGB48: |
|
|
|
|
case AV_PIX_FMT_BGR48: |
|
|
|
|
case AV_PIX_FMT_RGBA64: |
|
|
|
|
case AV_PIX_FMT_BGRA64: |
|
|
|
|
is16bit = 1; |
|
|
|
|
alpha = 0xffff; |
|
|
|
|
break; |
|
|
|
|
case AV_PIX_FMT_RGBA: |
|
|
|
|
case AV_PIX_FMT_BGRA: |
|
|
|
|
case AV_PIX_FMT_ARGB: |
|
|
|
|
case AV_PIX_FMT_ABGR: |
|
|
|
|
alpha = 0xff; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit); |
|
|
|
|
scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1); |
|
|
|
|
|
|
|
|
|
#define LOAD_CLUT(nbits) do { \ |
|
|
|
|
uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \
|
|
|
|
|
dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \
|
|
|
|
|
dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \
|
|
|
|
|
dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \
|
|
|
|
|
if (step == 4) \
|
|
|
|
|
dst[rgba_map[3]] = alpha; \
|
|
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
level *= level; |
|
|
|
|
for (k = 0; k < level; k++) { |
|
|
|
|
for (j = 0; j < level; j++) { |
|
|
|
|
for (i = 0; i < level; i++) { |
|
|
|
|
if (!is16bit) |
|
|
|
|
LOAD_CLUT(8); |
|
|
|
|
else |
|
|
|
|
LOAD_CLUT(16); |
|
|
|
|
if (++x == w) { |
|
|
|
|
x = 0; |
|
|
|
|
y++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_cold int haldclutsrc_init(AVFilterContext *ctx) |
|
|
|
|
{ |
|
|
|
|
TestSourceContext *hc = ctx->priv; |
|
|
|
|
hc->fill_picture_fn = haldclutsrc_fill_picture; |
|
|
|
|
hc->draw_once = 1; |
|
|
|
|
return init(ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int haldclutsrc_query_formats(AVFilterContext *ctx) |
|
|
|
|
{ |
|
|
|
|
static const enum AVPixelFormat pix_fmts[] = { |
|
|
|
|
AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, |
|
|
|
|
AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, |
|
|
|
|
AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, |
|
|
|
|
AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, |
|
|
|
|
AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, |
|
|
|
|
AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, |
|
|
|
|
AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, |
|
|
|
|
AV_PIX_FMT_NONE, |
|
|
|
|
}; |
|
|
|
|
ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int haldclutsrc_config_props(AVFilterLink *outlink) |
|
|
|
|
{ |
|
|
|
|
AVFilterContext *ctx = outlink->src; |
|
|
|
|
TestSourceContext *hc = ctx->priv; |
|
|
|
|
|
|
|
|
|
hc->w = hc->h = hc->level * hc->level * hc->level; |
|
|
|
|
return config_props(outlink); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const AVFilterPad haldclutsrc_outputs[] = { |
|
|
|
|
{ |
|
|
|
|
.name = "default", |
|
|
|
|
.type = AVMEDIA_TYPE_VIDEO, |
|
|
|
|
.request_frame = request_frame, |
|
|
|
|
.config_props = haldclutsrc_config_props, |
|
|
|
|
}, |
|
|
|
|
{ NULL } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
AVFilter avfilter_vsrc_haldclutsrc = { |
|
|
|
|
.name = "haldclutsrc", |
|
|
|
|
.description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."), |
|
|
|
|
.priv_class = &haldclutsrc_class, |
|
|
|
|
.priv_size = sizeof(TestSourceContext), |
|
|
|
|
.init = haldclutsrc_init, |
|
|
|
|
.uninit = uninit, |
|
|
|
|
.query_formats = haldclutsrc_query_formats, |
|
|
|
|
.inputs = NULL, |
|
|
|
|
.outputs = haldclutsrc_outputs, |
|
|
|
|
}; |
|
|
|
|
#endif /* CONFIG_HALDCLUTSRC_FILTER */ |
|
|
|
|
|
|
|
|
|
#if CONFIG_NULLSRC_FILTER |
|
|
|
|
|
|
|
|
|
#define nullsrc_options options |
|
|
|
|