videomeasure: Fix indention, line endings and use LRN's real name

This commit is contained in:
Sebastian Dröge 2009-09-10 11:58:02 +02:00
parent e9297ba3eb
commit bdbd944c52
6 changed files with 2173 additions and 2233 deletions

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -25,12 +25,12 @@
#include "gstvideomeasure_ssim.h"
#include "gstvideomeasure_collector.h"
GstEvent *gst_event_new_measured (guint64 framenumber, GstClockTime timestamp,
const gchar *metric, const GValue *mean, const GValue *lowest,
const GValue *highest)
GstEvent *
gst_event_new_measured (guint64 framenumber, GstClockTime timestamp,
const gchar * metric, const GValue * mean, const GValue * lowest,
const GValue * highest)
{
GstStructure *str = gst_structure_new(
GST_EVENT_VIDEO_MEASURE,
GstStructure *str = gst_structure_new (GST_EVENT_VIDEO_MEASURE,
"event", G_TYPE_STRING, "frame-measured",
"offset", G_TYPE_UINT64, framenumber,
"timestamp", GST_TYPE_CLOCK_TIME, timestamp,
@ -54,8 +54,7 @@ plugin_init (GstPlugin * plugin)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif
res = gst_element_register (plugin, "ssim", GST_RANK_NONE,
GST_TYPE_SSIM);
res = gst_element_register (plugin, "ssim", GST_RANK_NONE, GST_TYPE_SSIM);
res &= gst_element_register (plugin, "measurecollector", GST_RANK_NONE,
GST_TYPE_MEASURE_COLLECTOR);

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -57,36 +57,34 @@ static const GstElementDetails measure_collector_details =
GST_ELEMENT_DETAILS ("Video measure collector",
"Filter/Effect/Video",
"Collect measurements from a measuring element",
"LRN <lrn _at_ gmail _dot_ com>");
"Руслан Ижбулатов <lrn _at_ gmail _dot_ com>");
static GstStaticPadTemplate gst_measure_collector_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate gst_measure_collector_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GST_STATIC_CAPS_ANY);
//static GstBaseTransformClass *parent_class = NULL;
static void gst_measure_collector_finalize (GObject * object);
static gboolean gst_measure_collector_event (GstBaseTransform * base,
GstEvent * event);
static void gst_measure_collector_save_csv(GstMeasureCollector *mc);
static void gst_measure_collector_save_csv (GstMeasureCollector * mc);
static void gst_measure_collector_post_message (GstMeasureCollector *mc);
static void gst_measure_collector_post_message (GstMeasureCollector * mc);
GST_BOILERPLATE (GstMeasureCollector, gst_measure_collector, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM);
static void
gst_measure_collector_collect (GstMeasureCollector *mc, GstEvent *gstevent)
gst_measure_collector_collect (GstMeasureCollector * mc, GstEvent * gstevent)
{
const GstStructure *str;
const gchar *event, *metric;
@ -98,14 +96,12 @@ gst_measure_collector_collect (GstMeasureCollector *mc, GstEvent *gstevent)
event = gst_structure_get_string (str, "event");
metric = gst_structure_get_string (str, "metric");
if (strcmp (event, "frame-measured") == 0 && metric != NULL)
{
if (strcmp (event, "frame-measured") == 0 && metric != NULL) {
GstStructure *cpy;
cpy = gst_structure_copy (str);
framenumber_v = gst_structure_get_value (str, "offset");
if (framenumber_v)
{
if (framenumber_v) {
if (G_VALUE_TYPE (framenumber_v) == G_TYPE_UINT64)
framenumber = g_value_get_uint64 (framenumber_v);
else if (G_VALUE_TYPE (framenumber_v) == G_TYPE_INT64)
@ -127,7 +123,7 @@ gst_measure_collector_collect (GstMeasureCollector *mc, GstEvent *gstevent)
}
static void
gst_measure_collector_post_message (GstMeasureCollector *mc)
gst_measure_collector_post_message (GstMeasureCollector * mc)
{
GstBaseTransform *trans;
GstMessage *m;
@ -137,16 +133,15 @@ gst_measure_collector_post_message (GstMeasureCollector *mc)
g_return_if_fail (mc->metric);
if (strcmp (mc->metric, "SSIM") == 0)
{
if (strcmp (mc->metric, "SSIM") == 0) {
gfloat dresult = 0;
g_free (mc->result);
mc->result = g_new0 (GValue, 1);
g_value_init (mc->result, G_TYPE_FLOAT);
for (i = 0; i < mc->measurements->len; i++)
{
for (i = 0; i < mc->measurements->len; i++) {
const GValue *v;
GstStructure *str = (GstStructure *) g_ptr_array_index (mc->measurements, i);
GstStructure *str =
(GstStructure *) g_ptr_array_index (mc->measurements, i);
v = gst_structure_get_value (str, "mean");
dresult += g_value_get_float (v);
}
@ -155,8 +150,7 @@ gst_measure_collector_post_message (GstMeasureCollector *mc)
m = gst_message_new_element (GST_OBJECT_CAST (mc),
gst_structure_new ("GstMeasureCollector",
"measure-result", G_TYPE_VALUE, mc->result,
NULL));
"measure-result", G_TYPE_VALUE, mc->result, NULL));
gst_element_post_message (GST_ELEMENT_CAST (mc), m);
}
@ -224,7 +218,8 @@ gst_measure_collector_event (GstBaseTransform * base, GstEvent * event)
return parent_class->event (base, event);
}
static void gst_measure_collector_save_csv(GstMeasureCollector *mc)
static void
gst_measure_collector_save_csv (GstMeasureCollector * mc)
{
gchar *name_local;
FILE *file;
@ -243,7 +238,7 @@ static void gst_measure_collector_save_csv(GstMeasureCollector *mc)
if (mc->filename == NULL || mc->filename[0] == '\0')
goto no_filename;
name_local = g_filename_from_utf8 ((const gchar*) mc->filename,
name_local = g_filename_from_utf8 ((const gchar *) mc->filename,
-1, NULL, NULL, NULL);
/* open the file */
@ -256,40 +251,38 @@ static void gst_measure_collector_save_csv(GstMeasureCollector *mc)
* we use g_fopen. */
file = fopen (name_local, "wb");
g_free(name_local);
g_free (name_local);
if (file == NULL)
goto open_failed;
str = (GstStructure *) g_ptr_array_index (mc->measurements, 0);
for (j = 0; j < gst_structure_n_fields (str); j++)
{
for (j = 0; j < gst_structure_n_fields (str); j++) {
const gchar *fieldname;
fieldname = gst_structure_nth_field_name (str, j);
if (G_LIKELY (j > 0))
fprintf(file, ";", fieldname);
fprintf(file, "%s", fieldname);
fprintf (file, ";", fieldname);
fprintf (file, "%s", fieldname);
}
for (i = 0; i < mc->measurements->len; i++)
{
fprintf(file, "\n");
for (i = 0; i < mc->measurements->len; i++) {
fprintf (file, "\n");
str = (GstStructure *) g_ptr_array_index (mc->measurements, i);
for (j = 0; j < gst_structure_n_fields (str); j++)
{
for (j = 0; j < gst_structure_n_fields (str); j++) {
const gchar *fieldname;
fieldname = gst_structure_nth_field_name (str, j);
if (G_LIKELY (j > 0))
fprintf(file, ";", fieldname);
if (G_LIKELY (g_value_transform (gst_structure_get_value (str, fieldname), &tmp)))
fprintf(file, "%s", g_value_get_string (&tmp));
fprintf (file, ";", fieldname);
if (G_LIKELY (g_value_transform (gst_structure_get_value (str, fieldname),
&tmp)))
fprintf (file, "%s", g_value_get_string (&tmp));
else
fprintf(file, "<untranslatable>");
fprintf (file, "<untranslatable>");
}
}
fclose(file);
fclose (file);
/* ERRORS */
empty:
@ -306,8 +299,7 @@ not_good_filename:
{
GST_ELEMENT_ERROR (mc, RESOURCE, NOT_FOUND,
(_("Given file name \"%s\" can't be converted to local file name \
encoding."),
mc->filename), (NULL));
encoding."), mc->filename), (NULL));
return;
}
open_failed:
@ -333,7 +325,7 @@ gst_measure_collector_base_init (gpointer g_class)
}
static void
gst_measure_collector_class_init (GstMeasureCollectorClass *klass)
gst_measure_collector_class_init (GstMeasureCollectorClass * klass)
{
GObjectClass *gobject_class;
GstBaseTransformClass *trans_class;
@ -358,19 +350,17 @@ gst_measure_collector_class_init (GstMeasureCollectorClass *klass)
g_object_class_install_property (gobject_class, PROP_FILENAME,
g_param_spec_string ("filename", "Output file name",
"A name of a file into which element will write the measurement \
information",
"", G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
information", "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
trans_class->event =
GST_DEBUG_FUNCPTR (gst_measure_collector_event);
trans_class->event = GST_DEBUG_FUNCPTR (gst_measure_collector_event);
trans_class->passthrough_on_same_caps = TRUE;
}
static void
gst_measure_collector_init (GstMeasureCollector *instance,
GstMeasureCollectorClass *g_class)
gst_measure_collector_init (GstMeasureCollector * instance,
GstMeasureCollectorClass * g_class)
{
GstMeasureCollector *measurecollector;
@ -396,9 +386,9 @@ gst_measure_collector_finalize (GObject * object)
gint i;
GstMeasureCollector *mc = GST_MEASURE_COLLECTOR (object);
for (i = 0; i < mc->measurements->len; i++)
{
gst_structure_free ((GstStructure *) g_ptr_array_index (mc->measurements, i));
for (i = 0; i < mc->measurements->len; i++) {
gst_structure_free ((GstStructure *) g_ptr_array_index (mc->measurements,
i));
}
g_ptr_array_free (mc->measurements, TRUE);

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -133,14 +133,13 @@ gst_ssim_get_type (void)
ssim_type = g_type_register_static (GST_TYPE_ELEMENT, "GstSSim",
&ssim_info, 0);
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "ssim", 0,
"SSIM calculator");
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "ssim", 0, "SSIM calculator");
}
return ssim_type;
}
static void
gst_ssim_post_message (GstSSim *ssim, GstBuffer *buffer, gfloat mssim,
gst_ssim_post_message (GstSSim * ssim, GstBuffer * buffer, gfloat mssim,
gfloat lowest, gfloat highest)
{
GstMessage *m;
@ -154,8 +153,7 @@ gst_ssim_post_message (GstSSim *ssim, GstBuffer *buffer, gfloat mssim,
"timestamp", GST_TYPE_CLOCK_TIME, GST_BUFFER_TIMESTAMP (buffer),
"mean", G_TYPE_FLOAT, mssim,
"lowest", G_TYPE_FLOAT, lowest,
"highest", G_TYPE_FLOAT, highest,
NULL));
"highest", G_TYPE_FLOAT, highest, NULL));
GST_DEBUG_OBJECT (GST_OBJECT (ssim), "Frame %" G_GINT64_FORMAT
" @ %" GST_TIME_FORMAT " mean SSIM is %f, l-h is %f-%f", offset,
@ -170,7 +168,7 @@ gst_ssim_src_getcaps (GstPad * pad)
GstCaps *result;
gchar *capstr;
result = gst_caps_copy( gst_pad_get_pad_template_caps (pad));
result = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
capstr = gst_caps_to_string (result);
GST_DEBUG ("getsrccaps - return static caps: %s", capstr);
g_free (capstr);
@ -199,14 +197,12 @@ gst_ssim_sink_getcaps (GstPad * pad)
}
static void
calculate_mu (GstSSim *ssim, gfloat *outmu, guint8 *buf)
calculate_mu (GstSSim * ssim, gfloat * outmu, guint8 * buf)
{
gint oy, ox, iy, ix;
for (oy = 0; oy < ssim->height; oy++)
{
for (ox = 0; ox < ssim->width; ox++)
{
for (oy = 0; oy < ssim->height; oy++) {
for (ox = 0; ox < ssim->width; ox++) {
gfloat mu = 0;
gfloat elsumm;
gint weight_y_base, weight_x_base;
@ -232,14 +228,12 @@ calculate_mu (GstSSim *ssim, gfloat *outmu, guint8 *buf)
wghstart_y = ssim->windows[source_offset].y_weight_start;
winend_y = ssim->windows[source_offset].y_window_end;
winlen_x = winend_x - winstart_x + 1;
winstride_x = sizeof(gfloat) * winlen_x;
winstride_x = sizeof (gfloat) * winlen_x;
elsumm = ssim->windows[source_offset].element_summ;
switch (ssim->windowtype)
{
switch (ssim->windowtype) {
case 0:
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
pixel_offset = iy * ssim->width;
for (ix = winstart_x; ix <= winend_x; ix++)
mu += buf[pixel_offset + ix];
@ -251,13 +245,11 @@ calculate_mu (GstSSim *ssim, gfloat *outmu, guint8 *buf)
weight_y_base = wghstart_y - winstart_y;
weight_x_base = wghstart_x - winstart_x;
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
pixel_offset = iy * ssim->width;
weight_offset = (weight_y_base + iy) * ssim->windowsize +
weight_x_base;
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
weight = ssim->weights[weight_offset + ix];
mu += weight * buf[pixel_offset + ix];
}
@ -272,18 +264,16 @@ calculate_mu (GstSSim *ssim, gfloat *outmu, guint8 *buf)
}
static void
calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
guint8 *out, gfloat *mean, gfloat *lowest, gfloat *highest)
calcssim_without_mu (GstSSim * ssim, guint8 * org, gfloat * orgmu, guint8 * mod,
guint8 * out, gfloat * mean, gfloat * lowest, gfloat * highest)
{
gint oy, ox, iy, ix;
gfloat cumulative_ssim = 0;
*lowest = G_MAXFLOAT;
*highest = -G_MAXFLOAT;
for (oy = 0; oy < ssim->height; oy++)
{
for (ox = 0; ox < ssim->width; ox++)
{
for (oy = 0; oy < ssim->height; oy++) {
for (ox = 0; ox < ssim->width; ox++) {
gfloat mu_o = 128, mu_m = 128;
gdouble sigma_o = 0, sigma_m = 0, sigma_om = 0;
gfloat tmp1 = 0, tmp2 = 0;
@ -312,17 +302,14 @@ calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
weight_y_base = wghstart_y - winstart_y;
weight_x_base = wghstart_x - winstart_x;
switch (ssim->windowtype)
{
switch (ssim->windowtype) {
case 0:
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
guint8 *org_with_offset, *mod_with_offset;
pixel_offset = iy * ssim->width;
org_with_offset = &org[pixel_offset];
mod_with_offset = &mod[pixel_offset];
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
tmp1 = org_with_offset[ix] - mu_o;
sigma_o += tmp1 * tmp1;
tmp2 = mod_with_offset[ix] - mu_m;
@ -336,8 +323,7 @@ calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
weight_y_base = wghstart_y - winstart_y;
weight_x_base = wghstart_x - winstart_x;
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
guint8 *org_with_offset, *mod_with_offset;
gfloat *weights_with_offset;
gfloat wt1, wt2;
@ -347,8 +333,7 @@ calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
org_with_offset = &org[pixel_offset];
mod_with_offset = &mod[pixel_offset];
weights_with_offset = &ssim->weights[weight_offset];
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
weight = weights_with_offset[ix];
tmp1 = org_with_offset[ix] - mu_o;
tmp2 = mod_with_offset[ix] - mu_m;
@ -365,8 +350,8 @@ calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
sigma_m = sqrt (sigma_m / elsumm);
sigma_om = sigma_om / elsumm;
tmp1 = (2 * mu_o * mu_m + ssim->const1) * (2 * sigma_om + ssim->const2) /
( (mu_o * mu_o + mu_m * mu_m + ssim->const1) *
(sigma_o * sigma_o + sigma_m * sigma_m + ssim->const2) );
((mu_o * mu_o + mu_m * mu_m + ssim->const1) *
(sigma_o * sigma_o + sigma_m * sigma_m + ssim->const2));
/* SSIM can go negative, that's why it is
127 + index * 128 instead of index * 255 */
@ -380,18 +365,16 @@ calcssim_without_mu (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
}
static void
calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
guint8 *out, gfloat *mean, gfloat *lowest, gfloat *highest)
calcssim_canonical (GstSSim * ssim, guint8 * org, gfloat * orgmu, guint8 * mod,
guint8 * out, gfloat * mean, gfloat * lowest, gfloat * highest)
{
gint oy, ox, iy, ix;
gfloat cumulative_ssim = 0;
*lowest = G_MAXFLOAT;
*highest = -G_MAXFLOAT;
for (oy = 0; oy < ssim->height; oy++)
{
for (ox = 0; ox < ssim->width; ox++)
{
for (oy = 0; oy < ssim->height; oy++) {
for (ox = 0; ox < ssim->width; ox++) {
gfloat mu_o = 0, mu_m = 0;
gdouble sigma_o = 0, sigma_m = 0, sigma_om = 0;
gfloat tmp1, tmp2;
@ -419,27 +402,22 @@ calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
wghstart_y = ssim->windows[source_offset].y_weight_start;
winend_y = ssim->windows[source_offset].y_window_end;
winlen_x = winend_x - winstart_x + 1;
winstride_x = sizeof(gfloat) * winlen_x;
winstride_x = sizeof (gfloat) * winlen_x;
elsumm = ssim->windows[source_offset].element_summ;
switch (ssim->windowtype)
{
switch (ssim->windowtype) {
case 0:
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
pixel_offset = iy * ssim->width;
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
mu_m += mod[pixel_offset + ix];
}
}
mu_m = mu_m / elsumm;
mu_o = orgmu[oy * ssim->width + ox];
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
pixel_offset = iy * ssim->width;
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
tmp1 = org[pixel_offset + ix] - mu_o;
tmp2 = mod[pixel_offset + ix] - mu_m;
sigma_o += tmp1 * tmp1;
@ -453,13 +431,11 @@ calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
weight_y_base = wghstart_y - winstart_y;
weight_x_base = wghstart_x - winstart_x;
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
pixel_offset = iy * ssim->width;
weight_offset = (weight_y_base + iy) * ssim->windowsize +
weight_x_base;
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
weight = ssim->weights[weight_offset + ix];
mu_o += weight * org[pixel_offset + ix];
mu_m += weight * mod[pixel_offset + ix];
@ -467,8 +443,7 @@ calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
}
mu_m = mu_m / elsumm;
mu_o = orgmu[oy * ssim->width + ox];
for (iy = winstart_y; iy <= winend_y; iy++)
{
for (iy = winstart_y; iy <= winend_y; iy++) {
gfloat *weights_with_offset;
guint8 *org_with_offset, *mod_with_offset;
gfloat wt1, wt2;
@ -478,8 +453,7 @@ calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
weights_with_offset = &ssim->weights[weight_offset];
org_with_offset = &org[pixel_offset];
mod_with_offset = &mod[pixel_offset];
for (ix = winstart_x; ix <= winend_x; ix++)
{
for (ix = winstart_x; ix <= winend_x; ix++) {
weight = weights_with_offset[ix];
tmp1 = org_with_offset[ix] - mu_o;
tmp2 = mod_with_offset[ix] - mu_m;
@ -496,8 +470,8 @@ calcssim_canonical (GstSSim *ssim, guint8 *org, gfloat *orgmu, guint8 *mod,
sigma_m = sqrt (sigma_m / elsumm);
sigma_om = sigma_om / elsumm;
tmp1 = (2 * mu_o * mu_m + ssim->const1) * (2 * sigma_om + ssim->const2) /
( (mu_o * mu_o + mu_m * mu_m + ssim->const1) *
(sigma_o * sigma_o + sigma_m * sigma_m + ssim->const2) );
((mu_o * mu_o + mu_m * mu_m + ssim->const1) *
(sigma_o * sigma_o + sigma_m * sigma_m + ssim->const2));
/* SSIM can go negative, that's why it is
127 + index * 128 instead of index * 255 */
@ -540,10 +514,11 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
/* Sink caps are stored only once. At the moment it doesn't feel
* right to measure streams with variable caps.
*/
if (G_UNLIKELY (!ssim->sinkcaps))
{
if (G_UNLIKELY (!ssim->sinkcaps)) {
GstStructure *newstr;
GValue list = { 0, }, fourcc = { 0, };
GValue list = { 0, }
, fourcc = {
0,};
g_value_init (&list, GST_TYPE_LIST);
g_value_init (&fourcc, GST_TYPE_FOURCC);
@ -566,8 +541,7 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
g_value_unset (&fourcc);
}
if (G_UNLIKELY (!ssim->srccaps))
{
if (G_UNLIKELY (!ssim->srccaps)) {
GstStructure *newstr;
newstr = gst_structure_new ("video/x-raw-gray", NULL);
@ -593,21 +567,18 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
direction = gst_pad_get_direction (otherpad);
GST_DEBUG_OBJECT (ssim, "checking caps on pad %p", otherpad);
if (direction == GST_PAD_SINK)
{
if (direction == GST_PAD_SINK) {
gchar *capstr;
capstr = gst_caps_to_string (GST_PAD_CAPS (otherpad));
GST_DEBUG_OBJECT (ssim, "old caps on pad %p,%s were %s", otherpad,
GST_PAD_NAME (otherpad), capstr);
g_free(capstr);
g_free (capstr);
gst_caps_replace (&GST_PAD_CAPS (otherpad), ssim->sinkcaps);
capstr = gst_caps_to_string (ssim->sinkcaps);
GST_DEBUG_OBJECT (ssim, "new caps on pad %p,%s are %s", otherpad,
GST_PAD_NAME (otherpad), capstr);
g_free(capstr);
}
else if (direction == GST_PAD_SRC)
{
g_free (capstr);
} else if (direction == GST_PAD_SRC) {
gst_caps_replace (&GST_PAD_CAPS (otherpad), ssim->srccaps);
}
pads = g_list_next (pads);
@ -616,8 +587,7 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
/* parse caps now */
media_type = gst_structure_get_name (capsstr);
GST_DEBUG_OBJECT (ssim, "media type is %s", media_type);
if (strcmp (media_type, "video/x-raw-yuv") == 0)
{
if (strcmp (media_type, "video/x-raw-yuv") == 0) {
ssim->width = width;
ssim->height = height;
ssim->frame_rate = fps_n;
@ -632,8 +602,7 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
* Only YUV formats are supported. There's no sense in calculating the
* index for R, G or B channels separately.
*/
switch (fourcc)
{
switch (fourcc) {
case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
@ -642,9 +611,7 @@ gst_ssim_setcaps (GstPad * pad, GstCaps * caps)
goto not_supported;
}
}
else
{
} else {
goto not_supported;
}
@ -959,8 +926,7 @@ gst_ssim_src_event (GstPad * pad, GstEvent * event)
{
GstSSimOutputContext *c;
gint i = 0;
for (i = 0; i < ssim->src->len; i++)
{
for (i = 0; i < ssim->src->len; i++) {
c = (GstSSimOutputContext *) g_ptr_array_index (ssim->src, i);
c->segment_pending = TRUE;
}
@ -1010,7 +976,8 @@ gst_ssim_sink_event (GstPad * pad, GstEvent * event)
GST_DEBUG ("NEWSEGMENTEVENT: update(%d), rate(%f), app_rate(%f), "
"format(%d), start(%" GST_TIME_FORMAT ") stop(%" GST_TIME_FORMAT ") "
"position(%" GST_TIME_FORMAT ")", update, rate, applied_rate, format,
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS(position));
GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
GST_TIME_ARGS (position));
break;
}
case GST_EVENT_FLUSH_STOP:
@ -1023,8 +990,7 @@ gst_ssim_sink_event (GstPad * pad, GstEvent * event)
{
GstSSimOutputContext *c;
gint i = 0;
for (i = 0; i < ssim->src->len; i++)
{
for (i = 0; i < ssim->src->len; i++) {
c = (GstSSimOutputContext *) g_ptr_array_index (ssim->src, i);
c->segment_pending = TRUE;
}
@ -1129,8 +1095,7 @@ gst_ssim_class_init (GstSSimClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WINDOW_SIZE,
g_param_spec_int ("window-size", "Window size",
"Size of a window.",
1, 22, 11, G_PARAM_READWRITE));
"Size of a window.", 1, 22, 11, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GAUSS_SIGMA,
g_param_spec_float ("gauss-sigma", "Deviation (for Gauss function)",
@ -1147,7 +1112,7 @@ gst_ssim_class_init (GstSSimClass * klass)
gst_element_class_set_details_simple (gstelement_class, "SSim",
"Filter/Converter/Video",
"Calculate Y-SSIM for n+2 YUV video streams",
"LRN <lrn1986 _at_ gmail _dot_ com>");
"Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>");
parent_class = g_type_class_peek_parent (klass);
@ -1220,8 +1185,7 @@ gst_ssim_request_new_pad (GstElement * element, GstPadTemplate * templ,
/* increment pad counter */
padcount = g_atomic_int_exchange_and_add (&ssim->padcount, 1);
if (num >= 0)
{
if (num >= 0) {
GstSSimOutputContext *c;
GObject *asobject;
template = gst_static_pad_template_get (&gst_ssim_src_template);
@ -1337,24 +1301,27 @@ gst_ssim_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
typedef gfloat (*GstSSimWeightFunc) (GstSSim *ssim, gint y, gint x);
typedef gfloat (*GstSSimWeightFunc) (GstSSim * ssim, gint y, gint x);
gfloat gst_ssim_weight_func_none (GstSSim *ssim, gint y, gint x)
gfloat
gst_ssim_weight_func_none (GstSSim * ssim, gint y, gint x)
{
return 1;
}
gfloat gst_ssim_weight_func_gauss (GstSSim *ssim, gint y, gint x)
gfloat
gst_ssim_weight_func_gauss (GstSSim * ssim, gint y, gint x)
{
gfloat coord = sqrt (x * x + y * y);
return exp ( -1 * (coord * coord) / (2 * ssim->sigma * ssim->sigma) ) /
return exp (-1 * (coord * coord) / (2 * ssim->sigma * ssim->sigma)) /
(ssim->sigma * sqrt (2 * G_PI));
}
gboolean gst_ssim_regenerate_windows (GstSSim *ssim)
gboolean
gst_ssim_regenerate_windows (GstSSim * ssim)
{
gint windowiseven;
gint y,x, y2, x2;
gint y, x, y2, x2;
GstSSimWeightFunc func;
gfloat normal_summ = 0;
gint normal_count = 0;
@ -1369,8 +1336,7 @@ gboolean gst_ssim_regenerate_windows (GstSSim *ssim)
ssim->windows = g_new (GstSSimWindowCache, ssim->height * ssim->width);
switch (ssim->windowtype)
{
switch (ssim->windowtype) {
case 0:
func = (GstSSimWeightFunc) gst_ssim_weight_func_none;
break;
@ -1384,29 +1350,24 @@ gboolean gst_ssim_regenerate_windows (GstSSim *ssim)
func = (GstSSimWeightFunc) gst_ssim_weight_func_gauss;
}
for (y = 0; y < ssim->windowsize; y++)
{
for (y = 0; y < ssim->windowsize; y++) {
gint yoffset = y * ssim->windowsize;
for (x = 0; x < ssim->windowsize; x++)
{
ssim->weights[yoffset + x] = func(ssim, x - ssim->windowsize / 2 +
for (x = 0; x < ssim->windowsize; x++) {
ssim->weights[yoffset + x] = func (ssim, x - ssim->windowsize / 2 +
windowiseven, y - ssim->windowsize / 2 + windowiseven);
normal_summ += ssim->weights[yoffset + x];
normal_count++;
}
}
for (y = 0; y < ssim->height; y++)
{
for (x = 0; x < ssim->width; x++)
{
for (y = 0; y < ssim->height; y++) {
for (x = 0; x < ssim->width; x++) {
GstSSimWindowCache win;
gint element_count = 0;
win.x_window_start = x - ssim->windowsize / 2 + windowiseven;
win.x_weight_start = 0;
if (win.x_window_start < 0)
{
if (win.x_window_start < 0) {
win.x_weight_start = -win.x_window_start;
win.x_window_start = 0;
}
@ -1417,8 +1378,7 @@ gboolean gst_ssim_regenerate_windows (GstSSim *ssim)
win.y_window_start = y - ssim->windowsize / 2 + windowiseven;
win.y_weight_start = 0;
if (win.y_window_start < 0)
{
if (win.y_window_start < 0) {
win.y_weight_start = -win.y_window_start;
win.y_window_start = 0;
}
@ -1432,12 +1392,9 @@ gboolean gst_ssim_regenerate_windows (GstSSim *ssim)
(win.x_window_end - win.x_window_start + 1);
if (element_count == normal_count)
win.element_summ = normal_summ;
else
{
for (y2 = win.y_weight_start; y2 < ssim->windowsize; y2++)
{
for (x2 = win.x_weight_start; x2 < ssim->windowsize; x2++)
{
else {
for (y2 = win.y_weight_start; y2 < ssim->windowsize; y2++) {
for (x2 = win.x_weight_start; x2 < ssim->windowsize; x2++) {
win.element_summ += ssim->weights[y2 * ssim->windowsize + x2];
}
}
@ -1472,14 +1429,12 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
ssim = GST_SSIM (user_data);
if (G_UNLIKELY (ssim->windows == NULL))
{
if (G_UNLIKELY (ssim->windows == NULL)) {
GST_DEBUG_OBJECT (ssim, "Regenerating windows");
gst_ssim_regenerate_windows (ssim);
}
switch (ssim->ssimtype)
{
switch (ssim->ssimtype) {
case 0:
ssim->func = (GstSSimFunction) calcssim_canonical;
break;
@ -1490,8 +1445,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
return GST_FLOW_ERROR;
}
for (collected = pads->data; collected; collected =
g_slist_next (collected)) {
for (collected = pads->data; collected; collected = g_slist_next (collected)) {
GstCollectData *collect_data;
GstBuffer *inbuf;
@ -1499,12 +1453,10 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
inbuf = gst_collect_pads_peek (pads, collect_data);
if (inbuf == NULL)
{
if (inbuf == NULL) {
GST_LOG_OBJECT (ssim, "channel %p: no bytes available", collect_data);
ready = FALSE;
}
else
} else
gst_buffer_unref (inbuf);
}
@ -1518,8 +1470,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
goto eos;
/* Mu is just a blur, we can calculate it once */
if (ssim->ssimtype == 0)
{
if (ssim->ssimtype == 0) {
orgmu = g_new (gfloat, ssim->width * ssim->height);
for (collected = pads->data; collected;
@ -1528,15 +1479,14 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
collect_data = (GstCollectData *) collected->data;
if (collect_data->pad == ssim->orig)
{
if (collect_data->pad == ssim->orig) {
orgbuf = gst_collect_pads_pop (pads, collect_data);;
GST_DEBUG_OBJECT (ssim, "Original stream - flags(0x%x), timestamp(%"
GST_TIME_FORMAT "), duration(%" GST_TIME_FORMAT ")",
GST_BUFFER_FLAGS (orgbuf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (orgbuf)),
GST_TIME_ARGS(GST_BUFFER_DURATION (orgbuf)));
GST_TIME_ARGS (GST_BUFFER_DURATION (orgbuf)));
calculate_mu (ssim, orgmu, GST_BUFFER_DATA (orgbuf));
break;
@ -1546,8 +1496,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
GST_LOG_OBJECT (ssim, "starting to cycle through streams");
for (collected = pads->data; collected;
collected = g_slist_next (collected)) {
for (collected = pads->data; collected; collected = g_slist_next (collected)) {
GstCollectData *collect_data;
GstBuffer *inbuf;
guint8 *indata;
@ -1555,8 +1504,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
collect_data = (GstCollectData *) collected->data;
if (collect_data->pad != ssim->orig)
{
if (collect_data->pad != ssim->orig) {
inbuf = gst_collect_pads_pop (pads, collect_data);
indata = GST_BUFFER_DATA (inbuf);
@ -1572,10 +1520,15 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
GstSSimOutputContext *c;
GstEvent *measured;
guint64 offset;
GValue vmean = { 0 }, vlowest = { 0 }, vhighest = { 0 };
GValue vmean = { 0 }
, vlowest = {
0}
, vhighest = {
0};
c = (GstSSimOutputContext *) g_object_get_data (
G_OBJECT (collect_data->pad), "ssim-match-output-context");
c = (GstSSimOutputContext *)
g_object_get_data (G_OBJECT (collect_data->pad),
"ssim-match-output-context");
GST_DEBUG_OBJECT (ssim, "Output context is %" GST_PTR_FORMAT
", pad will be %" GST_PTR_FORMAT, c, c->pad);
@ -1598,7 +1551,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
* as the input video
*/
/* set timestamps on the output buffer */
gst_buffer_copy_metadata(outbuf, inbuf, (GstBufferCopyFlags)
gst_buffer_copy_metadata (outbuf, inbuf, (GstBufferCopyFlags)
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
g_value_init (&vmean, G_TYPE_FLOAT);
@ -1650,7 +1603,7 @@ gst_ssim_collected (GstCollectPads * pads, gpointer user_data)
measured = gst_event_new_measured (offset,
GST_BUFFER_TIMESTAMP (inbuf), "SSIM", &vmean, &vlowest, &vhighest);
gst_pad_push_event(c->pad, measured);
gst_pad_push_event (c->pad, measured);
empty = FALSE;
@ -1681,8 +1634,7 @@ eos:
{
gint i;
GST_DEBUG_OBJECT (ssim, "no data available, must be EOS");
for (i = 0; i < ssim->src->len; i++)
{
for (i = 0; i < ssim->src->len; i++) {
GstSSimOutputContext *c =
(GstSSimOutputContext *) g_ptr_array_index (ssim->src, i);
gst_pad_push_event (c->pad, gst_event_new_eos ());
@ -1709,8 +1661,7 @@ gst_ssim_change_state (GstElement * element, GstStateChange transition)
{
GstSSimOutputContext *c;
gint i = 0;
for (i = 0; i < ssim->src->len; i++)
{
for (i = 0; i < ssim->src->len; i++) {
c = (GstSSimOutputContext *) g_ptr_array_index (ssim->src, i);
c->segment_pending = TRUE;
}

View file

@ -1,5 +1,5 @@
/* GStreamer
* Copyright (C) <2009> LRN <lrn1986 _at_ gmail _dot_ com>
* Copyright (C) <2009> Руслан Ижбулатов <lrn1986 _at_ gmail _dot_ com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public