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 /* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -25,12 +25,12 @@
#include "gstvideomeasure_ssim.h" #include "gstvideomeasure_ssim.h"
#include "gstvideomeasure_collector.h" #include "gstvideomeasure_collector.h"
GstEvent *gst_event_new_measured (guint64 framenumber, GstClockTime timestamp, GstEvent *
const gchar *metric, const GValue *mean, const GValue *lowest, gst_event_new_measured (guint64 framenumber, GstClockTime timestamp,
const GValue *highest) const gchar * metric, const GValue * mean, const GValue * lowest,
const GValue * highest)
{ {
GstStructure *str = gst_structure_new( GstStructure *str = gst_structure_new (GST_EVENT_VIDEO_MEASURE,
GST_EVENT_VIDEO_MEASURE,
"event", G_TYPE_STRING, "frame-measured", "event", G_TYPE_STRING, "frame-measured",
"offset", G_TYPE_UINT64, framenumber, "offset", G_TYPE_UINT64, framenumber,
"timestamp", GST_TYPE_CLOCK_TIME, timestamp, "timestamp", GST_TYPE_CLOCK_TIME, timestamp,
@ -54,8 +54,7 @@ plugin_init (GstPlugin * plugin)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif #endif
res = gst_element_register (plugin, "ssim", GST_RANK_NONE, res = gst_element_register (plugin, "ssim", GST_RANK_NONE, GST_TYPE_SSIM);
GST_TYPE_SSIM);
res &= gst_element_register (plugin, "measurecollector", GST_RANK_NONE, res &= gst_element_register (plugin, "measurecollector", GST_RANK_NONE,
GST_TYPE_MEASURE_COLLECTOR); GST_TYPE_MEASURE_COLLECTOR);

View file

@ -1,5 +1,5 @@
/* GStreamer /* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

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

View file

@ -1,5 +1,5 @@
/* GStreamer /* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

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

View file

@ -1,5 +1,5 @@
/* GStreamer /* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public