| @@ -70,6 +70,9 @@ typedef struct TestSourceContext { · 69 unmodified lines |
| 70 | /* only used by testsrc2 */ | 70 | /* only used by testsrc2 */ |
| 71 | int alpha; | 71 | int alpha; |
| 72 | | 72 | |
| | 73 | /* only used by colorspectrum */ |
| | 74 | int type; |
| | 75 | |
| 73 | /* only used by color */ | 76 | /* only used by color */ |
| 74 | FFDrawContext draw; | 77 | FFDrawContext draw; |
| 75 | FFDrawColor color; | 78 | FFDrawColor color; |
| @@ -1791,3 +1794,92 @@ const AVFilter ff_vsrc_allrgb = { · 1715 unmodified lines |
| 1791 | }; | 1794 | }; |
| 1792 | | 1795 | |
| 1793 | #endif /* CONFIG_ALLRGB_FILTER */ | 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 */ |