[FFmpeg-devel] [PATCH] lavfi/curves: add support for more rgb formats
Clément Bœsch
ubitux at gmail.com
Thu Apr 25 23:30:54 CEST 2013
On Thu, Apr 25, 2013 at 09:19:01PM +0000, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> libavfilter/vf_curves.c | 72 ++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 53 insertions(+), 19 deletions(-)
>
> diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
> index 626b4ea..482a046 100644
> --- a/libavfilter/vf_curves.c
> +++ b/libavfilter/vf_curves.c
> @@ -24,11 +24,18 @@
> #include "libavutil/file.h"
> #include "libavutil/intreadwrite.h"
> #include "libavutil/avassert.h"
> +#include "libavutil/pixdesc.h"
> #include "avfilter.h"
> +#include "drawutils.h"
> #include "formats.h"
> #include "internal.h"
> #include "video.h"
>
> +#define R 0
> +#define G 1
> +#define B 2
> +#define A 3
> +
> struct keypoint {
> double x, y;
> struct keypoint *next;
> @@ -58,6 +65,8 @@ typedef struct {
> char *comp_points_str_all;
> uint8_t graph[NB_COMP + 1][256];
> char *psfile;
> + uint8_t rgba_map[4];
> + int step;
> } CurvesContext;
>
> #define OFFSET(x) offsetof(CurvesContext, x)
> @@ -242,27 +251,27 @@ static int interpolate(AVFilterContext *ctx, uint8_t *y, const struct keypoint *
> point = point->next;
> }
>
> -#define B 0 /* sub diagonal (below main) */
> -#define M 1 /* main diagonal (center) */
> -#define A 2 /* sup diagonal (above main) */
> +#define BD 0 /* sub diagonal (below main) */
> +#define MD 1 /* main diagonal (center) */
> +#define AD 2 /* sup diagonal (above main) */
>
> /* left side of the polynomials into a tridiagonal matrix. */
> - matrix[0][M] = matrix[n - 1][M] = 1;
> + matrix[0][MD] = matrix[n - 1][MD] = 1;
> for (i = 1; i < n - 1; i++) {
> - matrix[i][B] = h[i-1];
> - matrix[i][M] = 2 * (h[i-1] + h[i]);
> - matrix[i][A] = h[i];
> + matrix[i][BD] = h[i-1];
> + matrix[i][MD] = 2 * (h[i-1] + h[i]);
> + matrix[i][AD] = h[i];
> }
>
> /* tridiagonal solving of the linear system */
> for (i = 1; i < n; i++) {
> - double den = matrix[i][M] - matrix[i][B] * matrix[i-1][A];
> + double den = matrix[i][MD] - matrix[i][BD] * matrix[i-1][AD];
> double k = den ? 1./den : 1.;
> - matrix[i][A] *= k;
> - r[i] = (r[i] - matrix[i][B] * r[i - 1]) * k;
> + matrix[i][AD] *= k;
> + r[i] = (r[i] - matrix[i][BD] * r[i - 1]) * k;
> }
> for (i = n - 2; i >= 0; i--)
> - r[i] = r[i] - matrix[i][A] * r[i + 1];
> + r[i] = r[i] - matrix[i][AD] * r[i + 1];
>
> /* compute the graph with x=[0..255] */
> i = 0;
> @@ -441,20 +450,43 @@ static av_cold int init(AVFilterContext *ctx)
>
> static int query_formats(AVFilterContext *ctx)
> {
> - static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE};
> + 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_NONE
> + };
> ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
> return 0;
> }
>
> +static int config_input(AVFilterLink *inlink)
> +{
> + CurvesContext *curves = inlink->dst->priv;
> + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
> +
> + ff_fill_rgba_map(curves->rgba_map, inlink->format);
> + curves->step = av_get_padded_bits_per_pixel(desc) >> 3;
> +
> + return 0;
> +}
> +
> static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> {
> - int x, y, i, direct = 0;
> + int x, y, direct = 0;
> AVFilterContext *ctx = inlink->dst;
> CurvesContext *curves = ctx->priv;
> AVFilterLink *outlink = inlink->dst->outputs[0];
> AVFrame *out;
> uint8_t *dst;
> const uint8_t *src;
> + const int step = curves->step;
> + const uint8_t r = curves->rgba_map[R];
> + const uint8_t g = curves->rgba_map[G];
> + const uint8_t b = curves->rgba_map[B];
> + const uint8_t a = curves->rgba_map[A];
>
> if (av_frame_is_writable(in)) {
> direct = 1;
> @@ -472,12 +504,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> src = in ->data[0];
>
> for (y = 0; y < inlink->h; y++) {
> - uint8_t *dstp = dst;
> - const uint8_t *srcp = src;
> -
> - for (x = 0; x < inlink->w; x++)
> - for (i = 0; i < NB_COMP; i++, dstp++, srcp++)
> - *dstp = curves->graph[i][*srcp];
> + for (x = 0; x < inlink->w * step; x += step) {
> + dst[x + r] = curves->graph[R][src[x + r]];
> + dst[x + g] = curves->graph[G][src[x + g]];
> + dst[x + b] = curves->graph[B][src[x + b]];
> + if (!direct && step == 4)
> + dst[x + a] = src[x + a];
> + }
> dst += out->linesize[0];
> src += in ->linesize[0];
> }
> @@ -493,6 +526,7 @@ static const AVFilterPad curves_inputs[] = {
> .name = "default",
> .type = AVMEDIA_TYPE_VIDEO,
> .filter_frame = filter_frame,
> + .config_props = config_input,
> },
> { NULL }
> };
LGTM, thanks!
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130425/814cb6b1/attachment.asc>
More information about the ffmpeg-devel
mailing list