videolevels: use more of the video library
But gst_video_format_get_component_depth is broken in 0.10.36, so manually get bpp for now.
This commit is contained in:
@@ -43,8 +43,6 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gst/video/video.h>
|
||||
|
||||
/* GstVideoLevels signals and args */
|
||||
enum
|
||||
{
|
||||
@@ -78,28 +76,18 @@ GST_ELEMENT_DETAILS ("Video videolevels adjustment",
|
||||
|
||||
/* the capabilities of the inputs and outputs */
|
||||
static GstStaticPadTemplate gst_videolevels_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-gray, "
|
||||
"bpp = (int) [1, 16], "
|
||||
"depth = (int) 16, "
|
||||
"endianness = (int) {LITTLE_ENDIAN, BIG_ENDIAN}, "
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", "
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", "
|
||||
"framerate = " GST_VIDEO_FPS_RANGE)
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN") ";"
|
||||
GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN"))
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_videolevels_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-gray, "
|
||||
"bpp = (int) 8, "
|
||||
"depth = (int) 8, "
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", "
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", "
|
||||
"framerate = " GST_VIDEO_FPS_RANGE)
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8)
|
||||
);
|
||||
|
||||
#define GST_TYPE_VIDEOLEVELS_AUTO (gst_videolevels_auto_get_type())
|
||||
@@ -434,40 +422,29 @@ static gboolean
|
||||
gst_videolevels_set_caps (GstBaseTransform * base, GstCaps * incaps,
|
||||
GstCaps * outcaps)
|
||||
{
|
||||
GstVideoLevels *levels;
|
||||
GstVideoLevels *levels = GST_VIDEOLEVELS (base);
|
||||
GstStructure *structure;
|
||||
gboolean res;
|
||||
|
||||
levels = GST_VIDEOLEVELS (base);
|
||||
|
||||
GST_DEBUG_OBJECT (levels,
|
||||
"set_caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps);
|
||||
|
||||
GST_DEBUG_OBJECT (incaps, "incaps");
|
||||
GST_DEBUG_OBJECT (outcaps, "outcaps");
|
||||
/* retrieve caps info */
|
||||
res = gst_video_format_parse_caps (incaps, &levels->format_in, &levels->width,
|
||||
&levels->height);
|
||||
res &= gst_video_format_parse_caps (outcaps, &levels->format_out, NULL, NULL);
|
||||
|
||||
/* retrieve input caps info */
|
||||
/* FIXME: gst_video_format_get_component_depth is broken in 0.10.36
|
||||
levels->bpp_in = gst_video_format_get_component_depth (levels->format_in, 0);
|
||||
levels->bpp_out = gst_video_format_get_component_depth (levels->format_out, 0); */
|
||||
structure = gst_caps_get_structure (incaps, 0);
|
||||
res = gst_structure_get (structure,
|
||||
"width", G_TYPE_INT, &levels->width,
|
||||
"height", G_TYPE_INT, &levels->height,
|
||||
"bpp", G_TYPE_INT, &levels->bpp_in,
|
||||
"depth", G_TYPE_INT, &levels->depth_in,
|
||||
"endianness", G_TYPE_INT, &levels->endianness_in, NULL);
|
||||
if (!res)
|
||||
return FALSE;
|
||||
|
||||
/* retrieve output bpp and depth */
|
||||
res &= gst_structure_get_int (structure, "bpp", &levels->bpp_in);
|
||||
structure = gst_caps_get_structure (outcaps, 0);
|
||||
res = gst_structure_get (structure,
|
||||
"bpp", G_TYPE_INT, &levels->bpp_out,
|
||||
"depth", G_TYPE_INT, &levels->depth_out, NULL);
|
||||
if (!res)
|
||||
return FALSE;
|
||||
|
||||
levels->stride_in = GST_ROUND_UP_4 (levels->width * levels->depth_in / 8);
|
||||
levels->stride_out = GST_ROUND_UP_4 (levels->width * levels->depth_out / 8);
|
||||
res &= gst_structure_get_int (structure, "bpp", &levels->bpp_out);
|
||||
|
||||
if (!res) {
|
||||
GST_ERROR_OBJECT (levels, "Failed to parse caps");
|
||||
}
|
||||
//gst_videolevels_calculate_tables (levels);
|
||||
|
||||
return res;
|
||||
@@ -488,27 +465,14 @@ static gboolean
|
||||
gst_videolevels_get_unit_size (GstBaseTransform * base, GstCaps * caps,
|
||||
guint * size)
|
||||
{
|
||||
GstStructure *structure;
|
||||
gint width;
|
||||
gint height;
|
||||
gint depth;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
/* get proposed caps width, height, and depth to determine frame size */
|
||||
if (gst_structure_get_int (structure, "width", &width) &&
|
||||
gst_structure_get_int (structure, "height", &height) &&
|
||||
gst_structure_get_int (structure, "depth", &depth)) {
|
||||
guint stride = GST_ROUND_UP_4 (width * depth / 8); /* need 4-byte alignment */
|
||||
*size = stride * height;
|
||||
GST_DEBUG ("Get unit size %dx%d, stride %u, %u bytes", width, height,
|
||||
stride, *size);
|
||||
return TRUE;
|
||||
if (!gst_video_get_size_from_caps (caps, size)) {
|
||||
GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
|
||||
("Unable to determine frame size from caps"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
|
||||
("Incomplete caps, some required field missing"));
|
||||
return FALSE;
|
||||
GST_DEBUG ("Frame size is %d bytes", *size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -542,12 +506,12 @@ gst_videolevels_transform (GstBaseTransform * base, GstBuffer * inbuf,
|
||||
videolevels->auto_adjust = 0;
|
||||
g_object_notify (G_OBJECT (videolevels), "auto");
|
||||
} else if (videolevels->auto_adjust == 2) {
|
||||
GST_DEBUG_OBJECT (videolevels, "Auto adjusting levels (every %d ns)",
|
||||
videolevels->interval);
|
||||
elapsed =
|
||||
GST_CLOCK_DIFF (videolevels->last_auto_timestamp, inbuf->timestamp);
|
||||
if (videolevels->last_auto_timestamp == GST_CLOCK_TIME_NONE
|
||||
|| elapsed >= (GstClockTimeDiff) videolevels->interval || elapsed < 0) {
|
||||
GST_DEBUG_OBJECT (videolevels, "Auto adjusting levels (%d ns since last)",
|
||||
elapsed);
|
||||
gst_videolevels_auto_adjust (videolevels, input);
|
||||
videolevels->last_auto_timestamp = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
}
|
||||
@@ -576,16 +540,10 @@ gst_videolevels_reset (GstVideoLevels * videolevels)
|
||||
{
|
||||
videolevels->width = 0;
|
||||
videolevels->height = 0;
|
||||
|
||||
videolevels->stride_in = 0;
|
||||
videolevels->format_in = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
videolevels->format_out = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
videolevels->bpp_in = 0;
|
||||
videolevels->depth_in = 0;
|
||||
videolevels->endianness_in = 0;
|
||||
|
||||
videolevels->stride_out = 0;
|
||||
videolevels->bpp_out = 0;
|
||||
videolevels->depth_out = 0;
|
||||
videolevels->endianness_out = 0;
|
||||
|
||||
videolevels->lower_input = DEFAULT_PROP_LOWIN;
|
||||
videolevels->upper_input = DEFAULT_PROP_HIGHIN;
|
||||
@@ -670,13 +628,14 @@ gst_videolevels_calculate_tables (GstVideoLevels * videolevels)
|
||||
#define GINT_CLAMP(x, low, high) ((gint)(CLAMP((x),(low),(high))))
|
||||
#define GUINT8_CLAMP(x, low, high) ((guint8)(CLAMP((x),(low),(high))))
|
||||
|
||||
/* TODO: use orc */
|
||||
/* TODO: use orc/lut */
|
||||
void
|
||||
gst_videolevels_convert_uint16le_to_uint8 (GstVideoLevels * videolevels,
|
||||
guint16 * in, guint8 * out)
|
||||
{
|
||||
gint i;
|
||||
const gint size = videolevels->stride_in / 2 * videolevels->height;
|
||||
const gint size = gst_video_format_get_size (videolevels->format_out,
|
||||
videolevels->width, videolevels->height);
|
||||
gdouble m;
|
||||
gdouble b;
|
||||
const guint16 max_in = (1 << videolevels->bpp_in) - 1;
|
||||
@@ -701,13 +660,14 @@ gst_videolevels_convert_uint16le_to_uint8 (GstVideoLevels * videolevels,
|
||||
out[i] = GUINT8_CLAMP (m * GUINT16_FROM_LE (in[i]) + b, low_out, high_out);
|
||||
}
|
||||
|
||||
/* TODO: use orc */
|
||||
/* TODO: use orc/lut */
|
||||
void
|
||||
gst_videolevels_convert_uint16be_to_uint8 (GstVideoLevels * videolevels,
|
||||
guint16 * in, guint8 * out)
|
||||
{
|
||||
gint i;
|
||||
const gint size = videolevels->stride_in / 2 * videolevels->height;
|
||||
const gint size = gst_video_format_get_size (videolevels->format_out,
|
||||
videolevels->width, videolevels->height);
|
||||
gdouble m;
|
||||
gdouble b;
|
||||
const guint16 max_in = (1 << videolevels->bpp_in) - 1;
|
||||
@@ -746,10 +706,12 @@ gboolean
|
||||
gst_videolevels_do_levels (GstVideoLevels * videolevels, gpointer indata,
|
||||
gpointer outdata)
|
||||
{
|
||||
if (videolevels->endianness_in == G_LITTLE_ENDIAN)
|
||||
if (videolevels->format_in == GST_VIDEO_FORMAT_GRAY16_LE)
|
||||
gst_videolevels_convert_uint16le_to_uint8 (videolevels, indata, outdata);
|
||||
else
|
||||
else if (videolevels->format_in == GST_VIDEO_FORMAT_GRAY16_BE)
|
||||
gst_videolevels_convert_uint16be_to_uint8 (videolevels, indata, outdata);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
//guint8 * dst = outdata;
|
||||
@@ -787,6 +749,18 @@ gst_videolevels_calculate_histogram (GstVideoLevels * videolevels,
|
||||
gint r;
|
||||
gint c;
|
||||
gfloat factor;
|
||||
gint stride = gst_video_format_get_row_stride (videolevels->format_in, 0,
|
||||
videolevels->width);
|
||||
gint endianness;
|
||||
|
||||
/* TODO: add gst_video_format_get_endianness to video library */
|
||||
if (videolevels->format_in == GST_VIDEO_FORMAT_GRAY16_BE)
|
||||
endianness = G_BIG_ENDIAN;
|
||||
else if (videolevels->format_in == GST_VIDEO_FORMAT_GRAY16_LE)
|
||||
endianness = G_LITTLE_ENDIAN;
|
||||
else
|
||||
endianness = G_BYTE_ORDER;
|
||||
|
||||
|
||||
factor = nbins / (gfloat) (1 << videolevels->bpp_in);
|
||||
|
||||
@@ -801,29 +775,21 @@ gst_videolevels_calculate_histogram (GstVideoLevels * videolevels,
|
||||
memset (hist, 0, sizeof (gint) * nbins);
|
||||
|
||||
GST_DEBUG ("Calculating histogram");
|
||||
if (videolevels->endianness_in == G_BYTE_ORDER) {
|
||||
if (endianness == G_BYTE_ORDER) {
|
||||
for (r = 0; r < videolevels->height; r++) {
|
||||
for (c = 0; c < videolevels->width; c++) {
|
||||
/* GST_DEBUG ("(%d, %d) = %d, hist[%d] = %d", r, c, data [c + r * videolevels->stride_in / 2], GINT_CLAMP (data [c + r * videolevels->stride_in / 2] * factor, 0, nbins - 1),
|
||||
hist [GINT_CLAMP (data [c + r * videolevels->stride_in / 2] * factor, 0, nbins - 1)] + 1);*/
|
||||
hist[GINT_CLAMP (data[c + r * videolevels->stride_in / 2] * factor, 0,
|
||||
nbins - 1)]++;
|
||||
hist[GINT_CLAMP (data[c + r * stride / 2] * factor, 0, nbins - 1)]++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (r = 0; r < videolevels->height; r++) {
|
||||
for (c = 0; c < videolevels->width; c++) {
|
||||
hist[GINT_CLAMP (GUINT16_FROM_BE (data[c +
|
||||
r * videolevels->stride_in / 2]) * factor, 0,
|
||||
nbins - 1)]++;
|
||||
r * stride / 2]) * factor, 0, nbins - 1)]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for (r = 0; r < videolevels->nbins; r++ ) {
|
||||
// GST_DEBUG ("hist[%5d] = %d",r, hist[r]);
|
||||
//}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user