From 155e48fb908bf37c772a26fbd6e8c3b117504c3e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 17 Apr 2010 18:13:46 +0200 Subject: [PATCH] gamma: Use libgstvideo for format specific values and make gamma processing more generic Allows us to easily add support for new color formats later. --- gst/videofilter/gstgamma.c | 67 ++++++++++++++++++++++++++++------------------ gst/videofilter/gstgamma.h | 7 ++++- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/gst/videofilter/gstgamma.c b/gst/videofilter/gstgamma.c index 44b4a09..5446014 100644 --- a/gst/videofilter/gstgamma.c +++ b/gst/videofilter/gstgamma.c @@ -89,7 +89,6 @@ static gboolean gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps, static GstFlowReturn gst_gamma_transform_ip (GstBaseTransform * transform, GstBuffer * buf); -static void gst_gamma_planar411_ip (GstGamma * gamma, guint8 * data, gint size); static void gst_gamma_calculate_tables (GstGamma * gamma); GST_BOILERPLATE (GstGamma, gst_gamma, GstVideoFilter, GST_TYPE_VIDEO_FILTER); @@ -197,45 +196,54 @@ gst_gamma_calculate_tables (GstGamma * gamma) } } -/* Useful macros */ -#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width)) -#define GST_VIDEO_I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2) -#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2) +static void +gst_gamma_planar_ip (GstGamma * gamma, guint8 * data) +{ + gint size; + + data = + data + gst_video_format_get_component_offset (gamma->format, 0, + gamma->width, gamma->height); + size = + gst_video_format_get_row_stride (gamma->format, 0, + gamma->width) * gst_video_format_get_component_height (gamma->format, 0, + gamma->height); -#define GST_VIDEO_I420_Y_OFFSET(w,h) (0) -#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h))) -#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2)) -#define GST_VIDEO_I420_SIZE(w,h) (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2)) + oil_tablelookup_u8 (data, 1, data, 1, gamma->gamma_table, 1, size); +} static gboolean gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { GstGamma *gamma = GST_GAMMA (base); - GstStructure *structure; - gboolean res; GST_DEBUG_OBJECT (gamma, "setting caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps); - structure = gst_caps_get_structure (incaps, 0); + if (!gst_video_format_parse_caps (incaps, &gamma->format, &gamma->width, + &gamma->height)) + goto invalid_caps; - res = gst_structure_get_int (structure, "width", &gamma->width); - res &= gst_structure_get_int (structure, "height", &gamma->height); - if (!res) - goto done; + gamma->size = + gst_video_format_get_size (gamma->format, gamma->width, gamma->height); - gamma->size = GST_VIDEO_I420_SIZE (gamma->width, gamma->height); + switch (gamma->format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + gamma->process = gst_gamma_planar_ip; + break; + default: + goto invalid_caps; + break; + } -done: - return res; -} + return TRUE; -static void -gst_gamma_planar411_ip (GstGamma * gamma, guint8 * data, gint size) -{ - oil_tablelookup_u8 (data, 1, data, 1, gamma->gamma_table, 1, size); +invalid_caps: + GST_ERROR_OBJECT (gamma, "Invalid caps: %" GST_PTR_FORMAT, incaps); + return FALSE; } static GstFlowReturn @@ -246,6 +254,9 @@ gst_gamma_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) guint size; GstClockTime timestamp, stream_time; + if (!gamma->process) + goto not_negotiated; + timestamp = GST_BUFFER_TIMESTAMP (outbuf); stream_time = gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp); @@ -266,8 +277,7 @@ gst_gamma_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) goto wrong_size; GST_OBJECT_LOCK (gamma); - gst_gamma_planar411_ip (gamma, data, - gamma->height * GST_VIDEO_I420_Y_ROWSTRIDE (gamma->width)); + gamma->process (gamma, data); GST_OBJECT_UNLOCK (gamma); done: @@ -280,6 +290,11 @@ wrong_size: (NULL), ("Invalid buffer size %d, expected %d", size, gamma->size)); return GST_FLOW_ERROR; } +not_negotiated: + { + GST_ERROR_OBJECT (gamma, "Not negotiated yet"); + return GST_FLOW_NOT_NEGOTIATED; + } } static gboolean diff --git a/gst/videofilter/gstgamma.h b/gst/videofilter/gstgamma.h index 099c15f..8680dba 100644 --- a/gst/videofilter/gstgamma.h +++ b/gst/videofilter/gstgamma.h @@ -24,6 +24,8 @@ #ifndef __GST_VIDEO_GAMMA_H__ #define __GST_VIDEO_GAMMA_H__ +#include +#include #include G_BEGIN_DECLS @@ -52,15 +54,18 @@ struct _GstGamma GstVideoFilter videofilter; /* format */ + GstVideoFormat format; gint width; gint height; gint size; /* properties */ - double gamma; + gdouble gamma; /* tables */ guint8 gamma_table[256]; + + void (*process) (GstGamma *gamma, guint8 *data); }; struct _GstGammaClass -- 2.7.4