| @@ -70,6 +70,9 @@ typedef struct TestSourceContext { · 69 unmodified lines |
| 70 | 70 | /* only used by testsrc2 */ |
| 71 | 71 | int alpha; |
| 72 | 72 | |
| 73 | + /* only used by colorspectrum */ |
| 74 | + int type; |
| 75 | + |
| 73 | 76 | /* only used by color */ |
| 74 | 77 | FFDrawContext draw; |
| 75 | 78 | FFDrawColor color; |
| @@ -1791,3 +1794,92 @@ const AVFilter ff_vsrc_allrgb = { · 1715 unmodified lines |
| 1791 | 1794 | }; |
| 1792 | 1795 | |
| 1793 | 1796 | #endif /* CONFIG_ALLRGB_FILTER */ |
| 1797 | + |
| 1798 | +#if CONFIG_COLORSPECTRUM_FILTER |
| 1799 | + |
| 1800 | +static const AVOption colorspectrum_options[] = { |
| 1801 | + COMMON_OPTIONS |
| 1802 | + { "type", "set the color spectrum type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "type" }, |
| 1803 | + { "black","fade to black", 0, AV_OPT_TYPE_CONST,{.i64=0},0, 0, FLAGS, "type" }, |
| 1804 | + { "white","fade to white", 0, AV_OPT_TYPE_CONST,{.i64=1},0, 0, FLAGS, "type" }, |
| 1805 | + { "all", "white to black", 0, AV_OPT_TYPE_CONST,{.i64=2},0, 0, FLAGS, "type" }, |
| 1806 | + { NULL } |
| 1807 | +}; |
| 1808 | + |
| 1809 | +AVFILTER_DEFINE_CLASS(colorspectrum); |
| 1810 | + |
| 1811 | +static inline float mix(float a, float b, float mix) |
| 1812 | +{ |
| 1813 | + return a * mix + b * (1.f - mix); |
| 1814 | +} |
| 1815 | + |
| 1816 | +static void hsb2rgb(const float *c, float *rgb) |
| 1817 | +{ |
| 1818 | + rgb[0] = av_clipf(fabsf(fmodf(c[0] * 6.f + 0.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); |
| 1819 | + rgb[1] = av_clipf(fabsf(fmodf(c[0] * 6.f + 4.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); |
| 1820 | + rgb[2] = av_clipf(fabsf(fmodf(c[0] * 6.f + 2.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); |
| 1821 | + rgb[0] = mix(c[3], (rgb[0] * rgb[0] * (3.f - 2.f * rgb[0])), c[1]) * c[2]; |
| 1822 | + rgb[1] = mix(c[3], (rgb[1] * rgb[1] * (3.f - 2.f * rgb[1])), c[1]) * c[2]; |
| 1823 | + rgb[2] = mix(c[3], (rgb[2] * rgb[2] * (3.f - 2.f * rgb[2])), c[1]) * c[2]; |
| 1824 | +} |
| 1825 | + |
| 1826 | +static void colorspectrum_fill_picture(AVFilterContext *ctx, AVFrame *frame) |
| 1827 | +{ |
| 1828 | + TestSourceContext *test = ctx->priv; |
| 1829 | + const float w = frame->width - 1.f; |
| 1830 | + const float h = frame->height - 1.f; |
| 1831 | + float c[4]; |
| 1832 | + |
| 1833 | + for (int y = 0; y < frame->height; y++) { |
| 1834 | + float *r = (float *)(frame->data[2] + y * frame->linesize[2]); |
| 1835 | + float *g = (float *)(frame->data[0] + y * frame->linesize[0]); |
| 1836 | + float *b = (float *)(frame->data[1] + y * frame->linesize[1]); |
| 1837 | + const float yh = y / h; |
| 1838 | + |
| 1839 | + c[1] = test->type == 2 ? yh > 0.5f ? 2.f * (yh - 0.5f) : 1.f - 2.f * yh : test->type == 1 ? 1.f - yh : yh; |
| 1840 | + c[2] = 1.f; |
| 1841 | + c[3] = test->type == 1 ? 1.f : test->type == 2 ? (yh > 0.5f ? 0.f : 1.f): 0.f; |
| 1842 | + for (int x = 0; x < frame->width; x++) { |
| 1843 | + float rgb[3]; |
| 1844 | + |
| 1845 | + c[0] = x / w; |
| 1846 | + hsb2rgb(c, rgb); |
| 1847 | + |
| 1848 | + r[x] = rgb[0]; |
| 1849 | + g[x] = rgb[1]; |
| 1850 | + b[x] = rgb[2]; |
| 1851 | + } |
| 1852 | + } |
| 1853 | +} |
| 1854 | + |
| 1855 | +static av_cold int colorspectrum_init(AVFilterContext *ctx) |
| 1856 | +{ |
| 1857 | + TestSourceContext *test = ctx->priv; |
| 1858 | + |
| 1859 | + test->draw_once = 1; |
| 1860 | + test->fill_picture_fn = colorspectrum_fill_picture; |
| 1861 | + return init(ctx); |
| 1862 | +} |
| 1863 | + |
| 1864 | +static const AVFilterPad avfilter_vsrc_colorspectrum_outputs[] = { |
| 1865 | + { |
| 1866 | + .name = "default", |
| 1867 | + .type = AVMEDIA_TYPE_VIDEO, |
| 1868 | + .config_props = config_props, |
| 1869 | + }, |
| 1870 | +}; |
| 1871 | + |
| 1872 | +const AVFilter ff_vsrc_colorspectrum = { |
| 1873 | + .name = "colorspectrum", |
| 1874 | + .description = NULL_IF_CONFIG_SMALL("Generate colors spectrum."), |
| 1875 | + .priv_size = sizeof(TestSourceContext), |
| 1876 | + .priv_class = &colorspectrum_class, |
| 1877 | + .init = colorspectrum_init, |
| 1878 | + .uninit = uninit, |
| 1879 | + .activate = activate, |
| 1880 | + .inputs = NULL, |
| 1881 | + FILTER_OUTPUTS(avfilter_vsrc_colorspectrum_outputs), |
| 1882 | + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_GBRPF32), |
| 1883 | +}; |
| 1884 | + |
| 1885 | +#endif /* CONFIG_COLORSPECTRUM_FILTER */ |