gamma: Use libgstvideo for format specific values and make gamma processing more generic

Allows us to easily add support for new color formats later.
This commit is contained in:
Sebastian Dröge 2010-04-17 18:13:46 +02:00
parent 18273152b3
commit 155e48fb90
2 changed files with 47 additions and 27 deletions

View file

@ -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;
#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))
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);
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

View file

@ -24,6 +24,8 @@
#ifndef __GST_VIDEO_GAMMA_H__
#define __GST_VIDEO_GAMMA_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
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