videobalance: Use libgstvideo for format specific things

This commit is contained in:
Sebastian Dröge 2010-04-18 22:17:02 +02:00
parent fe4f9ea16b
commit 2cb7ac0192
2 changed files with 54 additions and 34 deletions

View file

@ -1,6 +1,7 @@
/* GStreamer /* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2003> David Schleef <ds@schleef.org> * Copyright (C) <2003> David Schleef <ds@schleef.org>
* Copyright (C) <2010> Sebastian Dröge <sebastian.droege@collabora.co.uk>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -48,7 +49,6 @@
#include <math.h> #include <math.h>
#include <gst/controller/gstcontroller.h> #include <gst/controller/gstcontroller.h>
#include <gst/video/video.h>
#include <gst/interfaces/colorbalance.h> #include <gst/interfaces/colorbalance.h>
#ifndef M_PI #ifndef M_PI
@ -183,28 +183,24 @@ gst_video_balance_update_properties (GstVideoBalance * videobalance)
gst_video_balance_update_tables (videobalance); gst_video_balance_update_tables (videobalance);
} }
/* 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)
#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))
static void static void
gst_video_balance_planar411_ip (GstVideoBalance * videobalance, guint8 * data, gst_video_balance_planar_yuv (GstVideoBalance * videobalance, guint8 * data)
gint width, gint height)
{ {
gint x, y; gint x, y;
guint8 *ydata; guint8 *ydata;
guint8 *udata, *vdata; guint8 *udata, *vdata;
gint ystride, ustride, vstride; gint ystride, ustride, vstride;
GstVideoFormat format;
gint width, height;
gint width2, height2; gint width2, height2;
ydata = data + GST_VIDEO_I420_Y_OFFSET (width, height); format = videobalance->format;
ystride = GST_VIDEO_I420_Y_ROWSTRIDE (width); width = videobalance->width;
height = videobalance->height;
ydata =
data + gst_video_format_get_component_offset (format, 0, width, height);
ystride = gst_video_format_get_row_stride (format, 0, width);
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
guint8 *yptr; guint8 *yptr;
@ -216,13 +212,15 @@ gst_video_balance_planar411_ip (GstVideoBalance * videobalance, guint8 * data,
} }
} }
width2 = width >> 1; width2 = gst_video_format_get_component_width (format, 1, width);
height2 = height >> 1; height2 = gst_video_format_get_component_height (format, 1, height);
udata = data + GST_VIDEO_I420_U_OFFSET (width, height); udata =
vdata = data + GST_VIDEO_I420_V_OFFSET (width, height); data + gst_video_format_get_component_offset (format, 1, width, height);
ustride = GST_VIDEO_I420_U_ROWSTRIDE (width); vdata =
vstride = GST_VIDEO_I420_V_ROWSTRIDE (width); data + gst_video_format_get_component_offset (format, 2, width, height);
ustride = gst_video_format_get_row_stride (format, 1, width);
vstride = gst_video_format_get_row_stride (format, 1, width);
for (y = 0; y < height2; y++) { for (y = 0; y < height2; y++) {
guint8 *uptr, *vptr; guint8 *uptr, *vptr;
@ -247,24 +245,34 @@ gst_video_balance_set_caps (GstBaseTransform * base, GstCaps * incaps,
GstCaps * outcaps) GstCaps * outcaps)
{ {
GstVideoBalance *videobalance = GST_VIDEO_BALANCE (base); GstVideoBalance *videobalance = GST_VIDEO_BALANCE (base);
GstStructure *structure;
gboolean res;
GST_DEBUG_OBJECT (videobalance, GST_DEBUG_OBJECT (videobalance,
"in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps); "in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps);
structure = gst_caps_get_structure (incaps, 0); videobalance->process = NULL;
res = gst_structure_get_int (structure, "width", &videobalance->width); if (!gst_video_format_parse_caps (incaps, &videobalance->format,
res &= gst_structure_get_int (structure, "height", &videobalance->height); &videobalance->width, &videobalance->height))
if (!res) goto invalid_caps;
goto done;
videobalance->size = videobalance->size =
GST_VIDEO_I420_SIZE (videobalance->width, videobalance->height); gst_video_format_get_size (videobalance->format, videobalance->width,
videobalance->height);
done: switch (videobalance->format) {
return res; case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
videobalance->process = gst_video_balance_planar_yuv;
break;
default:
break;
}
return videobalance->process != NULL;
invalid_caps:
GST_ERROR_OBJECT (videobalance, "Invalid caps: %" GST_PTR_FORMAT, incaps);
return FALSE;
} }
static void static void
@ -291,6 +299,9 @@ gst_video_balance_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
guint8 *data; guint8 *data;
guint size; guint size;
if (!videobalance->process)
goto not_negotiated;
/* if no change is needed, we are done */ /* if no change is needed, we are done */
if (base->passthrough) if (base->passthrough)
goto done; goto done;
@ -298,11 +309,10 @@ gst_video_balance_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
data = GST_BUFFER_DATA (outbuf); data = GST_BUFFER_DATA (outbuf);
size = GST_BUFFER_SIZE (outbuf); size = GST_BUFFER_SIZE (outbuf);
if (size < videobalance->size) if (size != videobalance->size)
goto wrong_size; goto wrong_size;
gst_video_balance_planar411_ip (videobalance, data, videobalance->process (videobalance, data);
videobalance->width, videobalance->height);
done: done:
return GST_FLOW_OK; return GST_FLOW_OK;
@ -315,6 +325,9 @@ wrong_size:
videobalance->size)); videobalance->size));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
not_negotiated:
GST_ERROR_OBJECT (videobalance, "Not negotiated yet");
return GST_FLOW_NOT_NEGOTIATED;
} }
static void static void

View file

@ -21,6 +21,8 @@
#ifndef __GST_VIDEO_BALANCE_H__ #ifndef __GST_VIDEO_BALANCE_H__
#define __GST_VIDEO_BALANCE_H__ #define __GST_VIDEO_BALANCE_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h> #include <gst/video/gstvideofilter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -47,6 +49,8 @@ typedef struct _GstVideoBalanceClass GstVideoBalanceClass;
struct _GstVideoBalance { struct _GstVideoBalance {
GstVideoFilter videofilter; GstVideoFilter videofilter;
/* < private > */
/* channels for interface */ /* channels for interface */
GList *channels; GList *channels;
@ -57,12 +61,15 @@ struct _GstVideoBalance {
gdouble saturation; gdouble saturation;
/* format */ /* format */
GstVideoFormat format;
gint width; gint width;
gint height; gint height;
gint size; gint size;
/* tables */ /* tables */
guint8 *tabley, **tableu, **tablev; guint8 *tabley, **tableu, **tablev;
void (*process) (GstVideoBalance *balance, guint8 *data);
}; };
struct _GstVideoBalanceClass { struct _GstVideoBalanceClass {