summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac12
-rw-r--r--ext/cog/Makefile.am32
-rw-r--r--ext/cog/cogframe.c1002
-rw-r--r--ext/cog/cogframe.h195
-rw-r--r--ext/cog/cogorc.c2818
-rw-r--r--ext/cog/cogorc.h36
-rw-r--r--ext/cog/cogvirtframe.c1734
-rw-r--r--ext/cog/cogvirtframe.h50
-rw-r--r--ext/cog/gstcog.c75
-rw-r--r--ext/cog/gstcogcolorspace.c485
-rw-r--r--ext/cog/gstcogdownsample.c412
-rw-r--r--ext/cog/gstcogfilter.c265
-rw-r--r--ext/cog/gstcogmse.c542
-rw-r--r--ext/cog/gstcogscale.c732
-rw-r--r--ext/cog/gstcogutils.c182
-rw-r--r--ext/cog/gstcogutils.h37
-rw-r--r--ext/cog/gstcolorconvert.c864
-rw-r--r--ext/cog/gstlogoinsert.c458
18 files changed, 9931 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index c33c04b00..7f4cba042 100644
--- a/configure.ac
+++ b/configure.ac
@@ -672,6 +672,17 @@ AG_GST_CHECK_FEATURE(CELT, [celt], celt, [
AC_SUBST(CELT_LIBS)
])
+dnl *** Cog ***
+translit(dnm, m, l) AM_CONDITIONAL(USE_COG, true)
+AG_GST_CHECK_FEATURE(COG, [Cog plugin], cog, [
+ PKG_CHECK_MODULES(ORC, orc-0.4 >= 0.4.2.1, HAVE_COG="yes", [
+ HAVE_COG="no"
+ AC_MSG_RESULT(no)
+ ])
+ AC_SUBST(ORC_CFLAGS)
+ AC_SUBST(ORC_LIBS)
+])
+
dnl *** dc1394 ***
translit(dnm, m, l) AM_CONDITIONAL(USE_DC1394, true)
AG_GST_CHECK_FEATURE(DC1394, [libdc1394], dc1394, [
@@ -1798,6 +1809,7 @@ ext/apexsink/Makefile
ext/bz2/Makefile
ext/cdaudio/Makefile
ext/celt/Makefile
+ext/cog/Makefile
ext/dc1394/Makefile
ext/dirac/Makefile
ext/directfb/Makefile
diff --git a/ext/cog/Makefile.am b/ext/cog/Makefile.am
new file mode 100644
index 000000000..65d169a83
--- /dev/null
+++ b/ext/cog/Makefile.am
@@ -0,0 +1,32 @@
+plugin_LTLIBRARIES = libgstcog.la
+
+libgstcog_la_CFLAGS = \
+ $(GST_PLUGINS_BASE_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(COG_CFLAGS)
+libgstcog_la_LIBADD = \
+ $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
+ $(GST_BASE_LIBS) \
+ $(GST_LIBS) \
+ $(COG_LIBS)
+libgstcog_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(LIBM)
+libgstcog_la_LIBTOOLFLAGS = --tag=disable-static
+
+libgstcog_la_SOURCES = \
+ cogframe.c \
+ cogframe.h \
+ cogorc.c \
+ cogorc.h \
+ cogvirtframe.c \
+ cogvirtframe.h \
+ gstcog.c \
+ gstcogcolorspace.c \
+ gstcogdownsample.c \
+ gstcogfilter.c \
+ gstcogmse.c \
+ gstcogscale.c \
+ gstcogutils.c \
+ gstcogutils.h \
+ gstcolorconvert.c \
+ gstlogoinsert.c
+
diff --git a/ext/cog/cogframe.c b/ext/cog/cogframe.c
new file mode 100644
index 000000000..ec2b0783b
--- /dev/null
+++ b/ext/cog/cogframe.c
@@ -0,0 +1,1002 @@
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cog/cog.h>
+#include <cog-video/cogframe.h>
+#include <cog-video/cogvirtframe.h>
+#include <cog-video/cogorc.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * cog_frame_new:
+ *
+ * Creates a new CogFrame object. The created frame is uninitialized
+ * and has no data storage associated with it. The caller must fill
+ * in the required information.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new (void)
+{
+ CogFrame *frame;
+
+ frame = cog_malloc0 (sizeof (*frame));
+ frame->refcount = 1;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_and_alloc:
+ *
+ * Creates a new CogFrame object with the requested size and format.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_and_alloc (CogMemoryDomain * domain, CogFrameFormat format,
+ int width, int height)
+{
+ return cog_frame_new_and_alloc_extended (domain, format, width, height, 0);
+}
+
+CogFrame *
+cog_frame_new_and_alloc_extended (CogMemoryDomain * domain,
+ CogFrameFormat format, int width, int height, int extension)
+{
+ CogFrame *frame = cog_frame_new ();
+ int bytes_pp;
+ int h_shift, v_shift;
+ int chroma_width;
+ int chroma_height;
+ int ext_width;
+ int ext_height;
+
+ COG_ASSERT (width > 0);
+ COG_ASSERT (height > 0);
+
+ frame->format = format;
+ frame->width = width;
+ frame->height = height;
+ frame->domain = domain;
+ frame->extension = extension;
+
+ ext_width = width + extension * 2;
+ ext_height = height + extension * 2;
+
+ if (COG_FRAME_IS_PACKED (format)) {
+ COG_ASSERT (extension == 0);
+
+ frame->components[0].format = format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ if (format == COG_FRAME_FORMAT_AYUV) {
+ frame->components[0].stride = width * 4;
+ } else {
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
+ }
+ frame->components[0].length = frame->components[0].stride * height;
+
+ if (domain) {
+ //frame->regions[0] = cog_memory_domain_alloc (domain,
+ // frame->components[0].length);
+ } else {
+ frame->regions[0] = cog_malloc (frame->components[0].length);
+ }
+
+ frame->components[0].data = frame->regions[0];
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+ }
+
+ switch (COG_FRAME_FORMAT_DEPTH (format)) {
+ case COG_FRAME_FORMAT_DEPTH_U8:
+ bytes_pp = 1;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S16:
+ bytes_pp = 2;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S32:
+ bytes_pp = 4;
+ break;
+ default:
+ COG_ASSERT (0);
+ bytes_pp = 0;
+ break;
+ }
+
+ h_shift = COG_FRAME_FORMAT_H_SHIFT (format);
+ v_shift = COG_FRAME_FORMAT_V_SHIFT (format);
+ chroma_width = ROUND_UP_SHIFT (width, h_shift);
+ chroma_height = ROUND_UP_SHIFT (height, v_shift);
+
+ frame->components[0].format = format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_4 ((width + extension * 2) * bytes_pp);
+ frame->components[0].length =
+ frame->components[0].stride * (frame->components[0].height +
+ extension * 2);
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[1].format = format;
+ frame->components[1].width = chroma_width;
+ frame->components[1].height = chroma_height;
+ frame->components[1].stride =
+ ROUND_UP_4 ((chroma_width + extension * 2) * bytes_pp);
+ frame->components[1].length =
+ frame->components[1].stride * (frame->components[1].height +
+ extension * 2);
+ frame->components[1].v_shift = v_shift;
+ frame->components[1].h_shift = h_shift;
+
+ frame->components[2].format = format;
+ frame->components[2].width = chroma_width;
+ frame->components[2].height = chroma_height;
+ frame->components[2].stride =
+ ROUND_UP_4 ((chroma_width + extension * 2) * bytes_pp);
+ frame->components[2].length =
+ frame->components[2].stride * (frame->components[2].height +
+ extension * 2);
+ frame->components[2].v_shift = v_shift;
+ frame->components[2].h_shift = h_shift;
+
+ if (domain) {
+ //frame->regions[0] = cog_memory_domain_alloc (domain,
+ // frame->components[0].length +
+ // frame->components[1].length + frame->components[2].length);
+ } else {
+ frame->regions[0] = malloc (frame->components[0].length +
+ frame->components[1].length + frame->components[2].length);
+ }
+
+ frame->components[0].data = frame->regions[0] +
+ frame->components[0].stride * extension + bytes_pp * extension;
+ frame->components[1].data = frame->regions[0] +
+ frame->components[0].length +
+ frame->components[1].stride * extension + bytes_pp * extension;
+ frame->components[2].data = frame->regions[0] +
+ frame->components[0].length + frame->components[1].length +
+ frame->components[2].stride * extension + bytes_pp * extension;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_YUY2:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in YUY2 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_YUY2 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_YUYV;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_YUY2:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in UYVY format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_UYVY (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_UYVY;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_YUY2:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in UYVY format,
+ * although the row stride is allowed to be different than what
+ * would normally be calculated from @width.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_UYVY_full (void *data, int width, int height,
+ int stride)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_UYVY;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = stride;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_AYUV:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in AYUV format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_AYUV (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_AYUV;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = width * 4;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_v216:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in v216 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_v216 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_v216;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 4;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_v210:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in v210 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_v210 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_v210;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ((width + 47) / 48) * 128;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_I420:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in I420 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_I420 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_U8_420;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 2);
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride *
+ ROUND_UP_POW2 (frame->components[0].height, 1);
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[1].format = frame->format;
+ frame->components[1].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[1].height = ROUND_UP_SHIFT (height, 1);
+ frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
+ frame->components[1].length =
+ frame->components[1].stride * frame->components[1].height;
+ frame->components[1].data =
+ frame->components[0].data + frame->components[0].length;
+ frame->components[1].v_shift = 1;
+ frame->components[1].h_shift = 1;
+
+ frame->components[2].format = frame->format;
+ frame->components[2].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[2].height = ROUND_UP_SHIFT (height, 1);
+ frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
+ frame->components[2].length =
+ frame->components[2].stride * frame->components[2].height;
+ frame->components[2].data =
+ frame->components[1].data + frame->components[1].length;
+ frame->components[2].v_shift = 1;
+ frame->components[2].h_shift = 1;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_YV12:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in YV12 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_YV12 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_U8_420;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 2);
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride *
+ ROUND_UP_POW2 (frame->components[0].height, 1);
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[2].format = frame->format;
+ frame->components[2].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[2].height = ROUND_UP_SHIFT (height, 1);
+ frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
+ frame->components[2].length =
+ frame->components[2].stride * frame->components[2].height;
+ frame->components[2].data =
+ frame->components[0].data + frame->components[0].length;
+ frame->components[2].v_shift = 1;
+ frame->components[2].h_shift = 1;
+
+ frame->components[1].format = frame->format;
+ frame->components[1].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[1].height = ROUND_UP_SHIFT (height, 1);
+ frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
+ frame->components[1].length =
+ frame->components[1].stride * frame->components[1].height;
+ frame->components[1].data =
+ frame->components[2].data + frame->components[2].length;
+ frame->components[1].v_shift = 1;
+ frame->components[1].h_shift = 1;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_Y42B:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in Y42B format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_Y42B (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_U8_422;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 2);
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride *
+ ROUND_UP_POW2 (frame->components[0].height, 1);
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[1].format = frame->format;
+ frame->components[1].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[1].height = height;
+ frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
+ frame->components[1].length =
+ frame->components[1].stride * frame->components[1].height;
+ frame->components[1].data =
+ frame->components[0].data + frame->components[0].length;
+ frame->components[1].v_shift = 0;
+ frame->components[1].h_shift = 1;
+
+ frame->components[2].format = frame->format;
+ frame->components[2].width = ROUND_UP_SHIFT (width, 1);
+ frame->components[2].height = height;
+ frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
+ frame->components[2].length =
+ frame->components[2].stride * frame->components[2].height;
+ frame->components[2].data =
+ frame->components[1].data + frame->components[1].length;
+ frame->components[2].v_shift = 0;
+ frame->components[2].h_shift = 1;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_Y444:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in Y444 format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_Y444 (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_U8_444;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].format = frame->format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_POW2 (width, 4);
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride *
+ ROUND_UP_POW2 (frame->components[0].height, 1);
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[1].format = frame->format;
+ frame->components[1].width = width;
+ frame->components[1].height = height;
+ frame->components[1].stride = ROUND_UP_POW2 (width, 4);
+ frame->components[1].length =
+ frame->components[1].stride * frame->components[1].height;
+ frame->components[1].data =
+ frame->components[0].data + frame->components[0].length;
+ frame->components[1].v_shift = 0;
+ frame->components[1].h_shift = 0;
+
+ frame->components[2].format = frame->format;
+ frame->components[2].width = width;
+ frame->components[2].height = height;
+ frame->components[2].stride = ROUND_UP_POW2 (width, 4);
+ frame->components[2].length =
+ frame->components[2].stride * frame->components[2].height;
+ frame->components[2].data =
+ frame->components[1].data + frame->components[1].length;
+ frame->components[2].v_shift = 0;
+ frame->components[2].h_shift = 0;
+
+ return frame;
+}
+
+/**
+ * cog_frame_new_from_data_RGB:
+ *
+ * Creates a new CogFrame object with the requested size using
+ * the data pointed to by @data. The data must be in RGB format.
+ * The data must remain for the lifetime of the CogFrame object.
+ * It is recommended to use cog_frame_set_free_callback() for
+ * notification when the data is no longer needed.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_new_from_data_RGB (void *data, int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = COG_FRAME_FORMAT_RGB;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_4 (width * 3);
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+static CogFrame *
+cog_frame_new_from_data_RGB32 (void *data, int width, int height, int format)
+{
+ CogFrame *frame = cog_frame_new ();
+
+ frame->format = format;
+
+ frame->width = width;
+ frame->height = height;
+
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = width * 4;
+ frame->components[0].data = data;
+ frame->components[0].length = frame->components[0].stride * height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ return frame;
+}
+
+CogFrame *
+cog_frame_new_from_data_RGBx (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_RGBx);
+}
+
+CogFrame *
+cog_frame_new_from_data_xRGB (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_xRGB);
+}
+
+CogFrame *
+cog_frame_new_from_data_BGRx (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_BGRx);
+}
+
+CogFrame *
+cog_frame_new_from_data_xBGR (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_xBGR);
+}
+
+CogFrame *
+cog_frame_new_from_data_RGBA (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_RGBA);
+}
+
+CogFrame *
+cog_frame_new_from_data_ARGB (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_ARGB);
+}
+
+CogFrame *
+cog_frame_new_from_data_BGRA (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_BGRA);
+}
+
+CogFrame *
+cog_frame_new_from_data_ABGR (void *data, int width, int height)
+{
+ return cog_frame_new_from_data_RGB32 (data, width, height,
+ COG_FRAME_FORMAT_ABGR);
+}
+
+/**
+ * cog_frame_dup:
+ *
+ * Creates a new CogFrame object with the same dimensions and format
+ * as @frame, and copies the data from the @frame to the new object.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_dup (CogFrame * frame)
+{
+ return cog_frame_dup_extended (frame, 0);
+}
+
+CogFrame *
+cog_frame_dup_extended (CogFrame * frame, int extension)
+{
+ CogFrame *dup_frame;
+
+ dup_frame = cog_frame_new_and_alloc_extended (frame->domain,
+ frame->format, frame->width, frame->height, extension);
+ cog_frame_convert (dup_frame, frame);
+
+ return dup_frame;
+}
+
+/**
+ * cog_frame_clone:
+ *
+ * Creates a new CogFrame object with the same dimensions and format
+ * as @frame. This function leaves the data in the new object
+ * uninitialized.
+ *
+ * Returns: a new CogFrame object
+ */
+CogFrame *
+cog_frame_clone (CogMemoryDomain * domain, CogFrame * frame)
+{
+ return cog_frame_new_and_alloc (domain,
+ frame->format, frame->width, frame->height);
+}
+
+/**
+ * cog_frame_ref:
+ * @frame: a frame object
+ *
+ * Increases the reference count of @frame.
+ *
+ * Returns: the value of @frame
+ */
+CogFrame *
+cog_frame_ref (CogFrame * frame)
+{
+ frame->refcount++;
+ return frame;
+}
+
+/**
+ * cog_frame_unref:
+ * @frame: a frame object
+ *
+ * Decreases the reference count of @frame. If the new reference
+ * count is 0, the frame is freed. If a frame free callback was
+ * set, this function is called.
+ *
+ * Returns: the value of @frame
+ */
+void
+cog_frame_unref (CogFrame * frame)
+{
+ int i;
+
+ COG_ASSERT (frame->refcount > 0);
+
+ frame->refcount--;
+ if (frame->refcount == 0) {
+ if (frame->free) {
+ frame->free (frame, frame->priv);
+ }
+#ifdef HAVE_OPENGL
+ if (COG_FRAME_IS_OPENGL (frame)) {
+ cog_opengl_frame_cleanup (frame);
+ }
+#endif
+
+ for (i = 0; i < 3; i++) {
+ if (frame->regions[i]) {
+ if (frame->domain) {
+ //cog_memory_domain_memfree(frame->domain, frame->regions[i]);
+ } else {
+ free (frame->regions[i]);
+ }
+ }
+ }
+
+ if (frame->virt_frame1) {
+ cog_frame_unref (frame->virt_frame1);
+ }
+ if (frame->virt_frame2) {
+ cog_frame_unref (frame->virt_frame2);
+ }
+ if (frame->virt_priv) {
+ cog_free (frame->virt_priv);
+ }
+
+ cog_free (frame);
+ }
+}
+
+/**
+ * cog_frame_set_free_callback:
+ * @frame: a frame object
+ * @free_func: the function to call when the frame is freed
+ * @priv: callback key
+ *
+ * Sets a function that will be called when the object reference
+ * count drops to zero and the object is freed.
+ */
+void
+cog_frame_set_free_callback (CogFrame * frame,
+ CogFrameFreeFunc free_func, void *priv)
+{
+ frame->free = free_func;
+ frame->priv = priv;
+}
+
+/**
+ * cog_frame_convert:
+ * @dest: destination frame
+ * @src: source frame
+ *
+ * Copies data from the source frame to the destination frame, converting
+ * formats if necessary. Only a few conversions are supported.
+ */
+void
+cog_frame_convert (CogFrame * dest, CogFrame * src)
+{
+ CogFrame *frame;
+ CogFrameFormat dest_format;
+
+ COG_ASSERT (dest != NULL);
+ COG_ASSERT (src != NULL);
+
+ switch (dest->format) {
+ case COG_FRAME_FORMAT_YUYV:
+ case COG_FRAME_FORMAT_UYVY:
+ dest_format = COG_FRAME_FORMAT_U8_422;
+ break;
+ case COG_FRAME_FORMAT_AYUV:
+ case COG_FRAME_FORMAT_ARGB:
+ dest_format = COG_FRAME_FORMAT_U8_444;
+ break;
+ default:
+ dest_format = dest->format;
+ break;
+ }
+ cog_frame_ref (src);
+
+ frame = cog_virt_frame_new_unpack (src);
+ COG_DEBUG ("unpack %p", frame);
+
+ if (COG_FRAME_FORMAT_DEPTH (dest_format) !=
+ COG_FRAME_FORMAT_DEPTH (frame->format)) {
+ if (COG_FRAME_FORMAT_DEPTH (dest_format) == COG_FRAME_FORMAT_DEPTH_U8) {
+ frame = cog_virt_frame_new_convert_u8 (frame);
+ COG_DEBUG ("convert_u8 %p", frame);
+ } else if (COG_FRAME_FORMAT_DEPTH (dest_format) ==
+ COG_FRAME_FORMAT_DEPTH_S16) {
+ frame = cog_virt_frame_new_convert_s16 (frame);
+ COG_DEBUG ("convert_s16 %p", frame);
+ }
+ }
+
+ if ((dest_format & 3) != (frame->format & 3)) {
+ frame = cog_virt_frame_new_subsample (frame, dest_format);
+ COG_DEBUG ("subsample %p", frame);
+ }
+
+ switch (dest->format) {
+ case COG_FRAME_FORMAT_YUYV:
+ frame = cog_virt_frame_new_pack_YUY2 (frame);
+ COG_DEBUG ("pack_YUY2 %p", frame);
+ break;
+ case COG_FRAME_FORMAT_UYVY:
+ frame = cog_virt_frame_new_pack_UYVY (frame);
+ COG_DEBUG ("pack_UYVY %p", frame);
+ break;
+ case COG_FRAME_FORMAT_AYUV:
+ frame = cog_virt_frame_new_pack_AYUV (frame);
+ COG_DEBUG ("pack_AYUV %p", frame);
+ break;
+ default:
+ break;
+ }
+
+ if (dest->width < frame->width || dest->height < frame->height) {
+ COG_DEBUG ("crop %d %d to %d %d",
+ frame->width, frame->height, dest->width, dest->height);
+
+ frame = cog_virt_frame_new_crop (frame, dest->width, dest->height);
+ COG_DEBUG ("crop %p", frame);
+ }
+ if (dest->width > src->width || dest->height > src->height) {
+ frame = cog_virt_frame_new_edgeextend (frame, dest->width, dest->height);
+ COG_DEBUG ("edgeextend %p", frame);
+ }
+
+ cog_virt_frame_render (frame, dest);
+ cog_frame_unref (frame);
+
+}
+
+
+#if 0
+void
+cog_frame_md5 (CogFrame * frame, uint32_t * state)
+{
+ uint8_t *line;
+ int x, y, k;
+
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+
+ x = 0;
+ y = 0;
+ k = 0;
+ for (k = 0; k < 3; k++) {
+ for (y = 0; y < frame->components[k].height; y++) {
+ line = COG_FRAME_DATA_GET_LINE (&frame->components[k], y);
+ for (x = 0; x + 63 < frame->components[k].width; x += 64) {
+ oil_md5 (state, (uint32_t *) (line + x));
+ }
+ if (x < frame->components[k].width) {
+ uint8_t tmp[64];
+ int left;
+ left = frame->components[k].width - x;
+ memcpy (tmp, line + x, left);
+ memset (tmp + left, 0, 64 - left);
+ oil_md5 (state, (uint32_t *) tmp);
+ }
+ }
+ }
+
+ COG_DEBUG
+ ("md5 %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ state[0] & 0xff, (state[0] >> 8) & 0xff, (state[0] >> 16) & 0xff,
+ (state[0] >> 24) & 0xff, state[1] & 0xff, (state[1] >> 8) & 0xff,
+ (state[1] >> 16) & 0xff, (state[1] >> 24) & 0xff, state[2] & 0xff,
+ (state[2] >> 8) & 0xff, (state[2] >> 16) & 0xff, (state[2] >> 24) & 0xff,
+ state[3] & 0xff, (state[3] >> 8) & 0xff, (state[3] >> 16) & 0xff,
+ (state[3] >> 24) & 0xff);
+}
+#endif
+
+void
+cog_frame_split_fields (CogFrame * dest1, CogFrame * dest2, CogFrame * src)
+{
+ CogFrame src_tmp;
+
+ COG_ASSERT ((src->height & 1) == 0);
+
+ memcpy (&src_tmp, src, sizeof (src_tmp));
+
+ src_tmp.height = src->height / 2;
+ src_tmp.components[0].stride *= 2;
+ src_tmp.components[1].stride *= 2;
+ src_tmp.components[2].stride *= 2;
+
+ cog_frame_convert (dest1, &src_tmp);
+
+ src_tmp.components[0].data = COG_FRAME_DATA_GET_LINE (&src->components[0], 1);
+ src_tmp.components[1].data = COG_FRAME_DATA_GET_LINE (&src->components[1], 1);
+ src_tmp.components[2].data = COG_FRAME_DATA_GET_LINE (&src->components[2], 1);
+
+ cog_frame_convert (dest2, &src_tmp);
+}
+
+void
+cog_frame_get_subdata (CogFrame * frame, CogFrameData * fd,
+ int component, int x, int y)
+{
+ CogFrameData *comp = frame->components + component;
+
+ COG_ASSERT (COG_FRAME_FORMAT_DEPTH (comp->format) ==
+ COG_FRAME_FORMAT_DEPTH_U8);
+
+ fd->format = comp->format;
+ fd->data = COG_FRAME_DATA_GET_PIXEL_U8 (comp, x, y);
+ fd->stride = comp->stride;
+ fd->width = MAX (0, comp->width - x);
+ fd->height = MAX (0, comp->height - y);
+ fd->h_shift = comp->h_shift;
+ fd->v_shift = comp->v_shift;
+}
diff --git a/ext/cog/cogframe.h b/ext/cog/cogframe.h
new file mode 100644
index 000000000..c2ed848ab
--- /dev/null
+++ b/ext/cog/cogframe.h
@@ -0,0 +1,195 @@
+
+#ifndef __COG_FRAME_H__
+#define __COG_FRAME_H__
+
+#include <cog/cogutils.h>
+
+COG_BEGIN_DECLS
+
+typedef struct _CogFrame CogFrame;
+typedef struct _CogFrameData CogFrameData;
+typedef struct _CogUpsampledFrame CogUpsampledFrame;
+
+typedef void (*CogFrameFreeFunc)(CogFrame *frame, void *priv);
+typedef void (*CogFrameRenderFunc)(CogFrame *frame, void *dest, int component, int i);
+
+/* bit pattern:
+ * 0x100 - 0: normal, 1: indirect (packed)
+ * 0x001 - horizontal chroma subsampling: 0: 1, 1: 2
+ * 0x002 - vertical chroma subsampling: 0: 1, 1: 2
+ * 0x00c - depth: 0: u8, 1: s16, 2: s32
+ * */
+typedef enum _CogFrameFormat {
+ COG_FRAME_FORMAT_U8_444 = 0x00,
+ COG_FRAME_FORMAT_U8_422 = 0x01,
+ COG_FRAME_FORMAT_U8_420 = 0x03,
+
+ COG_FRAME_FORMAT_S16_444 = 0x04,
+ COG_FRAME_FORMAT_S16_422 = 0x05,
+ COG_FRAME_FORMAT_S16_420 = 0x07,
+
+ COG_FRAME_FORMAT_S32_444 = 0x08,
+ COG_FRAME_FORMAT_S32_422 = 0x09,
+ COG_FRAME_FORMAT_S32_420 = 0x0b,
+
+ /* indirectly supported */
+ COG_FRAME_FORMAT_YUYV = 0x100, /* YUYV order */
+ COG_FRAME_FORMAT_UYVY = 0x101, /* UYVY order */
+ COG_FRAME_FORMAT_AYUV = 0x102,
+ COG_FRAME_FORMAT_RGB = 0x104,
+ COG_FRAME_FORMAT_v216 = 0x105,
+ COG_FRAME_FORMAT_v210 = 0x106,
+ COG_FRAME_FORMAT_RGBx = 0x110,
+ COG_FRAME_FORMAT_xRGB = 0x111,
+ COG_FRAME_FORMAT_BGRx = 0x112,
+ COG_FRAME_FORMAT_xBGR = 0x113,
+ COG_FRAME_FORMAT_RGBA = 0x114,
+ COG_FRAME_FORMAT_ARGB = 0x115,
+ COG_FRAME_FORMAT_BGRA = 0x116,
+ COG_FRAME_FORMAT_ABGR = 0x117,
+} CogFrameFormat;
+
+#define COG_FRAME_FORMAT_DEPTH(format) ((format) & 0xc)
+#define COG_FRAME_FORMAT_DEPTH_U8 0x00
+#define COG_FRAME_FORMAT_DEPTH_S16 0x04
+#define COG_FRAME_FORMAT_DEPTH_S32 0x08
+
+#define COG_FRAME_FORMAT_H_SHIFT(format) ((format) & 0x1)
+#define COG_FRAME_FORMAT_V_SHIFT(format) (((format)>>1) & 0x1)
+
+#define COG_FRAME_IS_PACKED(format) (((format)>>8) & 0x1)
+
+#define COG_FRAME_CACHE_SIZE 8
+
+struct _CogFrameData {
+ CogFrameFormat format;
+ void *data;
+ int stride;
+ int width;
+ int height;
+ int length;
+ int h_shift;
+ int v_shift;
+};
+
+struct _CogFrame {
+ int refcount;
+ CogFrameFreeFunc free;
+ CogMemoryDomain *domain;
+ void *regions[3];
+ void *priv;
+
+ CogFrameFormat format;
+ int width;
+ int height;
+
+ CogFrameData components[3];
+
+ int is_virtual;
+ int cached_lines[3][COG_FRAME_CACHE_SIZE];
+ CogFrame *virt_frame1;
+ CogFrame *virt_frame2;
+ void (*render_line) (CogFrame *frame, void *dest, int component, int i);
+ void *virt_priv;
+ void *virt_priv2;
+ int param1;
+ int param2;
+
+ int extension;
+};
+
+struct _CogUpsampledFrame {
+ CogFrame *frames[4];
+ void *components[3];
+};
+
+#define COG_FRAME_DATA_GET_LINE(fd,i) (COG_OFFSET((fd)->data,(fd)->stride*(i)))
+#define COG_FRAME_DATA_GET_PIXEL_U8(fd,i,j) ((uint8_t *)COG_OFFSET((fd)->data,(fd)->stride*(j)+(i)))
+#define COG_FRAME_DATA_GET_PIXEL_S16(fd,i,j) ((int16_t *)COG_OFFSET((fd)->data,(fd)->stride*(j)+(i)*sizeof(int16_t)))
+
+CogFrame * cog_frame_new (void);
+CogFrame * cog_frame_new_and_alloc (CogMemoryDomain *domain,
+ CogFrameFormat format, int width, int height);
+CogFrame * cog_frame_new_from_data_I420 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_YV12 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_YUY2 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_UYVY (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_UYVY_full (void *data, int width, int height, int stride);
+CogFrame * cog_frame_new_from_data_AYUV (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_v216 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_v210 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_Y42B (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_Y444 (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_RGB (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_RGBx (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_xRGB (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_BGRx (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_xBGR (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_RGBA (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_ARGB (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_BGRA (void *data, int width, int height);
+CogFrame * cog_frame_new_from_data_ABGR (void *data, int width, int height);
+void cog_frame_set_free_callback (CogFrame *frame,
+ CogFrameFreeFunc free_func, void *priv);
+void cog_frame_unref (CogFrame *frame);
+CogFrame *cog_frame_ref (CogFrame *frame);
+CogFrame *cog_frame_dup (CogFrame *frame);
+CogFrame *cog_frame_clone (CogMemoryDomain *domain, CogFrame *frame);
+
+void cog_frame_convert (CogFrame *dest, CogFrame *src);
+void cog_frame_add (CogFrame *dest, CogFrame *src);
+void cog_frame_subtract (CogFrame *dest, CogFrame *src);
+void cog_frame_shift_left (CogFrame *frame, int shift);
+void cog_frame_shift_right (CogFrame *frame, int shift);
+
+//void cog_frame_downsample (CogFrame *dest, CogFrame *src);
+void cog_frame_upsample_horiz (CogFrame *dest, CogFrame *src);
+void cog_frame_upsample_vert (CogFrame *dest, CogFrame *src);
+double cog_frame_calculate_average_luma (CogFrame *frame);
+
+CogFrame * cog_frame_convert_to_444 (CogFrame *frame);
+void cog_frame_md5 (CogFrame *frame, uint32_t *state);
+
+CogFrame * cog_frame_new_and_alloc_extended (CogMemoryDomain *domain,
+ CogFrameFormat format, int width, int height, int extension);
+CogFrame *cog_frame_dup_extended (CogFrame *frame, int extension);
+void cog_frame_edge_extend (CogFrame *frame, int width, int height);
+void cog_frame_zero_extend (CogFrame *frame, int width, int height);
+void cog_frame_mark (CogFrame *frame, int value);
+void cog_frame_mc_edgeextend (CogFrame *frame);
+
+void cog_frame_data_get_codeblock (CogFrameData *dest, CogFrameData *src,
+ int x, int y, int horiz_codeblocks, int vert_codeblocks);
+
+CogUpsampledFrame * cog_upsampled_frame_new (CogFrame *frame);
+void cog_upsampled_frame_free (CogUpsampledFrame *df);
+void cog_upsampled_frame_upsample (CogUpsampledFrame *df);
+#ifdef ENABLE_MOTION_REF
+int cog_upsampled_frame_get_pixel_prec0 (CogUpsampledFrame *upframe, int k,
+ int x, int y);
+int cog_upsampled_frame_get_pixel_prec1 (CogUpsampledFrame *upframe, int k,
+ int x, int y);
+int cog_upsampled_frame_get_pixel_prec3 (CogUpsampledFrame *upframe, int k,
+ int x, int y);
+int cog_upsampled_frame_get_pixel_precN (CogUpsampledFrame *upframe, int k,
+ int x, int y, int mv_precision);
+#endif
+void cog_upsampled_frame_get_block_precN (CogUpsampledFrame *upframe, int k,
+ int x, int y, int prec, CogFrameData *dest);
+void cog_upsampled_frame_get_block_fast_precN (CogUpsampledFrame *upframe, int k,
+ int x, int y, int prec, CogFrameData *dest, CogFrameData *fd);
+void cog_upsampled_frame_get_subdata_prec0 (CogUpsampledFrame *upframe,
+ int k, int x, int y, CogFrameData *fd);
+void cog_upsampled_frame_get_subdata_prec1 (CogUpsampledFrame *upframe,
+ int k, int x, int y, CogFrameData *fd);
+
+void cog_frame_get_subdata (CogFrame *frame, CogFrameData *fd,
+ int comp, int x, int y);
+
+void cog_frame_split_fields (CogFrame *dest1, CogFrame *dest2, CogFrame *src);
+
+
+COG_END_DECLS
+
+#endif
+
diff --git a/ext/cog/cogorc.c b/ext/cog/cogorc.c
new file mode 100644
index 000000000..ed4c3ac78
--- /dev/null
+++ b/ext/cog/cogorc.c
@@ -0,0 +1,2818 @@
+
+/* autogenerated from cog.orc */
+
+#define DISABLE_ORC
+#ifndef DISABLE_ORC
+#include <orc/orc.h>
+#else
+#include <stdint.h>
+#endif
+
+#define ORC_CLAMP(x,a,b) ((x)<(a) ? (a) : ((x)>(b) ? (b) : (x)))
+#define ORC_ABS(a) ((a)<0 ? -(a) : (a))
+#define ORC_MIN(a,b) ((a)<(b) ? (a) : (b))
+#define ORC_MAX(a,b) ((a)>(b) ? (a) : (b))
+#define ORC_SB_MAX 127
+#define ORC_SB_MIN (-1-ORC_SB_MAX)
+#define ORC_UB_MAX 255
+#define ORC_UB_MIN 0
+#define ORC_SW_MAX 32767
+#define ORC_SW_MIN (-1-ORC_SW_MAX)
+#define ORC_UW_MAX 65535
+#define ORC_UW_MIN 0
+#define ORC_SL_MAX 2147483647
+#define ORC_SL_MIN (-1-ORC_SL_MAX)
+#define ORC_UL_MAX 4294967295U
+#define ORC_UL_MIN 0
+#define ORC_CLAMP_SB(x) ORC_CLAMP(x,ORC_SB_MIN,ORC_SB_MAX)
+#define ORC_CLAMP_UB(x) ORC_CLAMP(x,ORC_UB_MIN,ORC_UB_MAX)
+#define ORC_CLAMP_SW(x) ORC_CLAMP(x,ORC_SW_MIN,ORC_SW_MAX)
+#define ORC_CLAMP_UW(x) ORC_CLAMP(x,ORC_UW_MIN,ORC_UW_MAX)
+#define ORC_CLAMP_SL(x) ORC_CLAMP(x,ORC_SL_MIN,ORC_SL_MAX)
+#define ORC_CLAMP_UL(x) ORC_CLAMP(x,ORC_UL_MIN,ORC_UL_MAX)
+#define ORC_SWAP_W(x) ((((x)&0xff)<<8) | (((x)&0xff00)>>8))
+#define ORC_SWAP_L(x) ((((x)&0xff)<<24) | (((x)&0xff00)<<8) | (((x)&0xff0000)>>8) | (((x)&0xff000000)>>24))
+#define ORC_PTR_OFFSET(ptr,offset) ((void *)(((unsigned char *)(ptr)) + (offset)))
+
+
+/* cogorc_downsample_horiz_cosite_3tap */
+#ifdef DISABLE_ORC
+void
+cogorc_downsample_horiz_cosite_3tap (uint8_t * d1, uint16_t * s1, uint16_t * s2,
+ int n)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+ const int16_t *var5;
+ const int16_t var16 = 2;
+ const int16_t var17 = 2;
+ const int16_t var18 = 2;
+ int8_t var32;
+ int8_t var33;
+ int8_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+ int16_t var43;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyw */
+ var35 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var35 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var35 >> 8) & 0xff;
+ /* 3: select0wb */
+ var34 = (uint16_t) var5[i] & 0xff;
+ /* 4: convubw */
+ var38 = (uint8_t) var32;
+ /* 5: convubw */
+ var36 = (uint8_t) var33;
+ /* 6: convubw */
+ var37 = (uint8_t) var34;
+ /* 7: mullw */
+ var39 = (var36 * var16) & 0xffff;
+ /* 8: addw */
+ var40 = var38 + var37;
+ /* 9: addw */
+ var41 = var40 + var39;
+ /* 10: addw */
+ var42 = var41 + var17;
+ /* 11: shrsw */
+ var43 = var42 >> var18;
+ /* 12: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var43);
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_downsample_horiz_cosite_3tap (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+ const int16_t *var5;
+ const int16_t var16 = 2;
+ const int16_t var17 = 2;
+ const int16_t var18 = 2;
+ int8_t var32;
+ int8_t var33;
+ int8_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+ int16_t var43;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyw */
+ var35 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var35 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var35 >> 8) & 0xff;
+ /* 3: select0wb */
+ var34 = (uint16_t) var5[i] & 0xff;
+ /* 4: convubw */
+ var38 = (uint8_t) var32;
+ /* 5: convubw */
+ var36 = (uint8_t) var33;
+ /* 6: convubw */
+ var37 = (uint8_t) var34;
+ /* 7: mullw */
+ var39 = (var36 * var16) & 0xffff;
+ /* 8: addw */
+ var40 = var38 + var37;
+ /* 9: addw */
+ var41 = var40 + var39;
+ /* 10: addw */
+ var42 = var41 + var17;
+ /* 11: shrsw */
+ var43 = var42 >> var18;
+ /* 12: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var43);
+ }
+
+}
+
+void
+cogorc_downsample_horiz_cosite_3tap (uint8_t * d1, uint16_t * s1, uint16_t * s2,
+ int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_downsample_horiz_cosite_3tap");
+ orc_program_set_backup_function (p,
+ _backup_cogorc_downsample_horiz_cosite_3tap);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 2, "s1");
+ orc_program_add_source (p, 2, "s2");
+ orc_program_add_constant (p, 2, 2, "c1");
+ orc_program_add_constant (p, 2, 2, "c2");
+ orc_program_add_constant (p, 2, 2, "c3");
+ orc_program_add_temporary (p, 1, "t1");
+ orc_program_add_temporary (p, 1, "t2");
+ orc_program_add_temporary (p, 1, "t3");
+ orc_program_add_temporary (p, 2, "t4");
+ orc_program_add_temporary (p, 2, "t5");
+ orc_program_add_temporary (p, 2, "t6");
+
+ orc_program_append (p, "copyw", ORC_VAR_T4, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_T1, ORC_VAR_T4, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_T2, ORC_VAR_T4, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_T3, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T4, ORC_VAR_T1, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T5, ORC_VAR_T2, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T6, ORC_VAR_T3, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T5, ORC_VAR_T5, ORC_VAR_C1);
+ orc_program_append (p, "addw", ORC_VAR_T4, ORC_VAR_T4, ORC_VAR_T6);
+ orc_program_append (p, "addw", ORC_VAR_T4, ORC_VAR_T4, ORC_VAR_T5);
+ orc_program_append (p, "addw", ORC_VAR_T4, ORC_VAR_T4, ORC_VAR_C2);
+ orc_program_append (p, "shrsw", ORC_VAR_T4, ORC_VAR_T4, ORC_VAR_C3);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T4, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_downsample_vert_halfsite_2tap */
+#ifdef DISABLE_ORC
+void
+cogorc_downsample_vert_halfsite_2tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+
+ for (i = 0; i < n; i++) {
+ /* 0: avgub */
+ var0[i] = ((uint8_t) var4[i] + (uint8_t) var5[i] + 1) >> 1;
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_downsample_vert_halfsite_2tap (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: avgub */
+ var0[i] = ((uint8_t) var4[i] + (uint8_t) var5[i] + 1) >> 1;
+ }
+
+}
+
+void
+cogorc_downsample_vert_halfsite_2tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_downsample_vert_halfsite_2tap");
+ orc_program_set_backup_function (p,
+ _backup_cogorc_downsample_vert_halfsite_2tap);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+
+ orc_program_append (p, "avgub", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_S2);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_downsample_vert_halfsite_3tap */
+#ifdef DISABLE_ORC
+void
+cogorc_downsample_vert_halfsite_3tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ uint8_t * s3, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int16_t var16 = 2;
+ const int16_t var17 = 2;
+ const int16_t var18 = 2;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 2: convubw */
+ var34 = (uint8_t) var6[i];
+ /* 3: mullw */
+ var35 = (var33 * var16) & 0xffff;
+ /* 4: addw */
+ var36 = var32 + var34;
+ /* 5: addw */
+ var37 = var36 + var35;
+ /* 6: addw */
+ var38 = var37 + var17;
+ /* 7: shrsw */
+ var39 = var38 >> var18;
+ /* 8: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var39);
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_downsample_vert_halfsite_3tap (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int16_t var16 = 2;
+ const int16_t var17 = 2;
+ const int16_t var18 = 2;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 2: convubw */
+ var34 = (uint8_t) var6[i];
+ /* 3: mullw */
+ var35 = (var33 * var16) & 0xffff;
+ /* 4: addw */
+ var36 = var32 + var34;
+ /* 5: addw */
+ var37 = var36 + var35;
+ /* 6: addw */
+ var38 = var37 + var17;
+ /* 7: shrsw */
+ var39 = var38 >> var18;
+ /* 8: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var39);
+ }
+
+}
+
+void
+cogorc_downsample_vert_halfsite_3tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ uint8_t * s3, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_downsample_vert_halfsite_3tap");
+ orc_program_set_backup_function (p,
+ _backup_cogorc_downsample_vert_halfsite_3tap);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_constant (p, 2, 2, "c1");
+ orc_program_add_constant (p, 2, 2, "c2");
+ orc_program_add_constant (p, 2, 2, "c3");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+ orc_program_add_temporary (p, 2, "t3");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T3, ORC_VAR_S3, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C1);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T3);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C2);
+ orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C3);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_downsample_vert_halfsite_4tap */
+#ifdef DISABLE_ORC
+void
+cogorc_downsample_vert_halfsite_4tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ uint8_t * s3, uint8_t * s4, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t *var7;
+ const int16_t var16 = 26;
+ const int16_t var17 = 6;
+ const int16_t var18 = 32;
+ const int16_t var19 = 6;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+ var7 = (void *) s4;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 2: convubw */
+ var34 = (uint8_t) var6[i];
+ /* 3: convubw */
+ var35 = (uint8_t) var7[i];
+ /* 4: addw */
+ var36 = var33 + var34;
+ /* 5: mullw */
+ var37 = (var36 * var16) & 0xffff;
+ /* 6: addw */
+ var38 = var32 + var35;
+ /* 7: mullw */
+ var39 = (var38 * var17) & 0xffff;
+ /* 8: addw */
+ var40 = var37 + var39;
+ /* 9: addw */
+ var41 = var40 + var18;
+ /* 10: shrsw */
+ var42 = var41 >> var19;
+ /* 11: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var42);
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_downsample_vert_halfsite_4tap (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t *var7;
+ const int16_t var16 = 26;
+ const int16_t var17 = 6;
+ const int16_t var18 = 32;
+ const int16_t var19 = 6;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+ var7 = ex->arrays[7];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 2: convubw */
+ var34 = (uint8_t) var6[i];
+ /* 3: convubw */
+ var35 = (uint8_t) var7[i];
+ /* 4: addw */
+ var36 = var33 + var34;
+ /* 5: mullw */
+ var37 = (var36 * var16) & 0xffff;
+ /* 6: addw */
+ var38 = var32 + var35;
+ /* 7: mullw */
+ var39 = (var38 * var17) & 0xffff;
+ /* 8: addw */
+ var40 = var37 + var39;
+ /* 9: addw */
+ var41 = var40 + var18;
+ /* 10: shrsw */
+ var42 = var41 >> var19;
+ /* 11: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var42);
+ }
+
+}
+
+void
+cogorc_downsample_vert_halfsite_4tap (uint8_t * d1, uint8_t * s1, uint8_t * s2,
+ uint8_t * s3, uint8_t * s4, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_downsample_vert_halfsite_4tap");
+ orc_program_set_backup_function (p,
+ _backup_cogorc_downsample_vert_halfsite_4tap);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_source (p, 1, "s4");
+ orc_program_add_constant (p, 2, 26, "c1");
+ orc_program_add_constant (p, 2, 6, "c2");
+ orc_program_add_constant (p, 2, 32, "c3");
+ orc_program_add_constant (p, 2, 6, "c4");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+ orc_program_add_temporary (p, 2, "t3");
+ orc_program_add_temporary (p, 2, "t4");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T3, ORC_VAR_S3, ORC_VAR_D1);
+ orc_program_append (p, "convubw", ORC_VAR_T4, ORC_VAR_S4, ORC_VAR_D1);
+ orc_program_append (p, "addw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T3);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C1);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T4);
+ orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C2);
+ orc_program_append (p, "addw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T1);
+ orc_program_append (p, "addw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C3);
+ orc_program_append (p, "shrsw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C4);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+ ex->arrays[ORC_VAR_S4] = s4;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_upsample_horiz_cosite */
+#ifdef DISABLE_ORC
+void
+cogorc_upsample_horiz_cosite (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n)
+{
+ int i;
+ int16_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ int8_t var32;
+ int8_t var33;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyb */
+ var32 = var4[i];
+ /* 1: avgub */
+ var33 = ((uint8_t) var32 + (uint8_t) var5[i] + 1) >> 1;
+ /* 2: mergebw */
+ var0[i] = ((uint8_t) var32) | ((uint8_t) var33 << 8);
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_upsample_horiz_cosite (OrcExecutor * ex)
+{
+ int i;
+ int16_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ int8_t var32;
+ int8_t var33;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyb */
+ var32 = var4[i];
+ /* 1: avgub */
+ var33 = ((uint8_t) var32 + (uint8_t) var5[i] + 1) >> 1;
+ /* 2: mergebw */
+ var0[i] = ((uint8_t) var32) | ((uint8_t) var33 << 8);
+ }
+
+}
+
+void
+cogorc_upsample_horiz_cosite (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_upsample_horiz_cosite");
+ orc_program_set_backup_function (p, _backup_cogorc_upsample_horiz_cosite);
+ orc_program_add_destination (p, 2, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_temporary (p, 1, "t1");
+ orc_program_add_temporary (p, 1, "t2");
+
+ orc_program_append (p, "copyb", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "avgub", ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S2);
+ orc_program_append (p, "mergebw", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_T2);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_upsample_vert_avgub */
+#ifdef DISABLE_ORC
+void
+cogorc_upsample_vert_avgub (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+
+ for (i = 0; i < n; i++) {
+ /* 0: avgub */
+ var0[i] = ((uint8_t) var4[i] + (uint8_t) var5[i] + 1) >> 1;
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_upsample_vert_avgub (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: avgub */
+ var0[i] = ((uint8_t) var4[i] + (uint8_t) var5[i] + 1) >> 1;
+ }
+
+}
+
+void
+cogorc_upsample_vert_avgub (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_upsample_vert_avgub");
+ orc_program_set_backup_function (p, _backup_cogorc_upsample_vert_avgub);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+
+ orc_program_append (p, "avgub", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_S2);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_yuyv_y */
+#ifdef DISABLE_ORC
+void
+orc_unpack_yuyv_y (uint8_t * d1, uint16_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select0wb */
+ var0[i] = (uint16_t) var4[i] & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_yuyv_y (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select0wb */
+ var0[i] = (uint16_t) var4[i] & 0xff;
+ }
+
+}
+
+void
+orc_unpack_yuyv_y (uint8_t * d1, uint16_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_yuyv_y");
+ orc_program_set_backup_function (p, _backup_orc_unpack_yuyv_y);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 2, "s1");
+
+ orc_program_append (p, "select0wb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_yuyv_u */
+#ifdef DISABLE_ORC
+void
+orc_unpack_yuyv_u (uint8_t * d1, uint32_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select0lw */
+ var32 = (uint32_t) var4[i] & 0xffff;
+ /* 1: select1wb */
+ var0[i] = ((uint16_t) var32 >> 8) & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_yuyv_u (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select0lw */
+ var32 = (uint32_t) var4[i] & 0xffff;
+ /* 1: select1wb */
+ var0[i] = ((uint16_t) var32 >> 8) & 0xff;
+ }
+
+}
+
+void
+orc_unpack_yuyv_u (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_yuyv_u");
+ orc_program_set_backup_function (p, _backup_orc_unpack_yuyv_u);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select0lw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_yuyv_v */
+#ifdef DISABLE_ORC
+void
+orc_unpack_yuyv_v (uint8_t * d1, uint32_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select1lw */
+ var32 = ((uint32_t) var4[i] >> 16) & 0xffff;
+ /* 1: select1wb */
+ var0[i] = ((uint16_t) var32 >> 8) & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_yuyv_v (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select1lw */
+ var32 = ((uint32_t) var4[i] >> 16) & 0xffff;
+ /* 1: select1wb */
+ var0[i] = ((uint16_t) var32 >> 8) & 0xff;
+ }
+
+}
+
+void
+orc_unpack_yuyv_v (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_yuyv_v");
+ orc_program_set_backup_function (p, _backup_orc_unpack_yuyv_v);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select1lw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_pack_yuyv */
+#ifdef DISABLE_ORC
+void
+orc_pack_yuyv (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
+{
+ int i;
+ int32_t *var0;
+ const int16_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ int8_t var32;
+ int8_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyw */
+ var36 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var36 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var36 >> 8) & 0xff;
+ /* 3: mergebw */
+ var34 = ((uint8_t) var32) | ((uint8_t) var5[i] << 8);
+ /* 4: mergebw */
+ var35 = ((uint8_t) var33) | ((uint8_t) var6[i] << 8);
+ /* 5: mergewl */
+ var0[i] = ((uint16_t) var34) | ((uint16_t) var35 << 16);
+ }
+
+}
+
+#else
+static void
+_backup_orc_pack_yuyv (OrcExecutor * ex)
+{
+ int i;
+ int32_t *var0;
+ const int16_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ int8_t var32;
+ int8_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyw */
+ var36 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var36 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var36 >> 8) & 0xff;
+ /* 3: mergebw */
+ var34 = ((uint8_t) var32) | ((uint8_t) var5[i] << 8);
+ /* 4: mergebw */
+ var35 = ((uint8_t) var33) | ((uint8_t) var6[i] << 8);
+ /* 5: mergewl */
+ var0[i] = ((uint16_t) var34) | ((uint16_t) var35 << 16);
+ }
+
+}
+
+void
+orc_pack_yuyv (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_pack_yuyv");
+ orc_program_set_backup_function (p, _backup_orc_pack_yuyv);
+ orc_program_add_destination (p, 4, "d1");
+ orc_program_add_source (p, 2, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_temporary (p, 1, "t1");
+ orc_program_add_temporary (p, 1, "t2");
+ orc_program_add_temporary (p, 2, "t3");
+ orc_program_add_temporary (p, 2, "t4");
+ orc_program_add_temporary (p, 2, "t5");
+
+ orc_program_append (p, "copyw", ORC_VAR_T5, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_T1, ORC_VAR_T5, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_T2, ORC_VAR_T5, ORC_VAR_D1);
+ orc_program_append (p, "mergebw", ORC_VAR_T3, ORC_VAR_T1, ORC_VAR_S2);
+ orc_program_append (p, "mergebw", ORC_VAR_T4, ORC_VAR_T2, ORC_VAR_S3);
+ orc_program_append (p, "mergewl", ORC_VAR_D1, ORC_VAR_T3, ORC_VAR_T4);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_uyvy_y */
+#ifdef DISABLE_ORC
+void
+orc_unpack_uyvy_y (uint8_t * d1, uint16_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select1wb */
+ var0[i] = ((uint16_t) var4[i] >> 8) & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_uyvy_y (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select1wb */
+ var0[i] = ((uint16_t) var4[i] >> 8) & 0xff;
+ }
+
+}
+
+void
+orc_unpack_uyvy_y (uint8_t * d1, uint16_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_uyvy_y");
+ orc_program_set_backup_function (p, _backup_orc_unpack_uyvy_y);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 2, "s1");
+
+ orc_program_append (p, "select1wb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_uyvy_u */
+#ifdef DISABLE_ORC
+void
+orc_unpack_uyvy_u (uint8_t * d1, uint32_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select0lw */
+ var32 = (uint32_t) var4[i] & 0xffff;
+ /* 1: select0wb */
+ var0[i] = (uint16_t) var32 & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_uyvy_u (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select0lw */
+ var32 = (uint32_t) var4[i] & 0xffff;
+ /* 1: select0wb */
+ var0[i] = (uint16_t) var32 & 0xff;
+ }
+
+}
+
+void
+orc_unpack_uyvy_u (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_uyvy_u");
+ orc_program_set_backup_function (p, _backup_orc_unpack_uyvy_u);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select0lw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_unpack_uyvy_v */
+#ifdef DISABLE_ORC
+void
+orc_unpack_uyvy_v (uint8_t * d1, uint32_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: select1lw */
+ var32 = ((uint32_t) var4[i] >> 16) & 0xffff;
+ /* 1: select0wb */
+ var0[i] = (uint16_t) var32 & 0xff;
+ }
+
+}
+
+#else
+static void
+_backup_orc_unpack_uyvy_v (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int32_t *var4;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: select1lw */
+ var32 = ((uint32_t) var4[i] >> 16) & 0xffff;
+ /* 1: select0wb */
+ var0[i] = (uint16_t) var32 & 0xff;
+ }
+
+}
+
+void
+orc_unpack_uyvy_v (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_unpack_uyvy_v");
+ orc_program_set_backup_function (p, _backup_orc_unpack_uyvy_v);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select1lw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_pack_uyvy */
+#ifdef DISABLE_ORC
+void
+orc_pack_uyvy (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
+{
+ int i;
+ int32_t *var0;
+ const int16_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ int8_t var32;
+ int8_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyw */
+ var36 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var36 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var36 >> 8) & 0xff;
+ /* 3: mergebw */
+ var34 = ((uint8_t) var5[i]) | ((uint8_t) var32 << 8);
+ /* 4: mergebw */
+ var35 = ((uint8_t) var6[i]) | ((uint8_t) var33 << 8);
+ /* 5: mergewl */
+ var0[i] = ((uint16_t) var34) | ((uint16_t) var35 << 16);
+ }
+
+}
+
+#else
+static void
+_backup_orc_pack_uyvy (OrcExecutor * ex)
+{
+ int i;
+ int32_t *var0;
+ const int16_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ int8_t var32;
+ int8_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyw */
+ var36 = var4[i];
+ /* 1: select0wb */
+ var32 = (uint16_t) var36 & 0xff;
+ /* 2: select1wb */
+ var33 = ((uint16_t) var36 >> 8) & 0xff;
+ /* 3: mergebw */
+ var34 = ((uint8_t) var5[i]) | ((uint8_t) var32 << 8);
+ /* 4: mergebw */
+ var35 = ((uint8_t) var6[i]) | ((uint8_t) var33 << 8);
+ /* 5: mergewl */
+ var0[i] = ((uint16_t) var34) | ((uint16_t) var35 << 16);
+ }
+
+}
+
+void
+orc_pack_uyvy (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_pack_uyvy");
+ orc_program_set_backup_function (p, _backup_orc_pack_uyvy);
+ orc_program_add_destination (p, 4, "d1");
+ orc_program_add_source (p, 2, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_temporary (p, 1, "t1");
+ orc_program_add_temporary (p, 1, "t2");
+ orc_program_add_temporary (p, 2, "t3");
+ orc_program_add_temporary (p, 2, "t4");
+ orc_program_add_temporary (p, 2, "t5");
+
+ orc_program_append (p, "copyw", ORC_VAR_T5, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_T1, ORC_VAR_T5, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_T2, ORC_VAR_T5, ORC_VAR_D1);
+ orc_program_append (p, "mergebw", ORC_VAR_T3, ORC_VAR_S2, ORC_VAR_T1);
+ orc_program_append (p, "mergebw", ORC_VAR_T4, ORC_VAR_S3, ORC_VAR_T2);
+ orc_program_append (p, "mergewl", ORC_VAR_D1, ORC_VAR_T3, ORC_VAR_T4);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_memcpy */
+#ifdef DISABLE_ORC
+void
+orc_memcpy (void *d1, void *s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyb */
+ var0[i] = var4[i];
+ }
+
+}
+
+#else
+static void
+_backup_orc_memcpy (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyb */
+ var0[i] = var4[i];
+ }
+
+}
+
+void
+orc_memcpy (void *d1, void *s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_memcpy");
+ orc_program_set_backup_function (p, _backup_orc_memcpy);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+
+ orc_program_append (p, "copyb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_addc_convert_u8_s16 */
+#ifdef DISABLE_ORC
+void
+orc_addc_convert_u8_s16 (uint8_t * d1, int16_t * s1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+ const int16_t var16 = 128;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: addw */
+ var32 = var4[i] + var16;
+ /* 1: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var32);
+ }
+
+}
+
+#else
+static void
+_backup_orc_addc_convert_u8_s16 (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int16_t *var4;
+ const int16_t var16 = 128;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: addw */
+ var32 = var4[i] + var16;
+ /* 1: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var32);
+ }
+
+}
+
+void
+orc_addc_convert_u8_s16 (uint8_t * d1, int16_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_addc_convert_u8_s16");
+ orc_program_set_backup_function (p, _backup_orc_addc_convert_u8_s16);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 2, "s1");
+ orc_program_add_constant (p, 2, 128, "c1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_C1);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_subc_convert_s16_u8 */
+#ifdef DISABLE_ORC
+void
+orc_subc_convert_s16_u8 (int16_t * d1, uint8_t * s1, int n)
+{
+ int i;
+ int16_t *var0;
+ const int8_t *var4;
+ const int16_t var16 = 128;
+ int16_t var32;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: subw */
+ var0[i] = var32 - var16;
+ }
+
+}
+
+#else
+static void
+_backup_orc_subc_convert_s16_u8 (OrcExecutor * ex)
+{
+ int i;
+ int16_t *var0;
+ const int8_t *var4;
+ const int16_t var16 = 128;
+ int16_t var32;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: subw */
+ var0[i] = var32 - var16;
+ }
+
+}
+
+void
+orc_subc_convert_s16_u8 (int16_t * d1, uint8_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_subc_convert_s16_u8");
+ orc_program_set_backup_function (p, _backup_orc_subc_convert_s16_u8);
+ orc_program_add_destination (p, 2, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_constant (p, 2, 128, "c1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "subw", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_C1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_splat_u8_ns */
+#ifdef DISABLE_ORC
+void
+orc_splat_u8_ns (uint8_t * d1, int p1, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t var24 = p1;
+
+ var0 = (void *) d1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyb */
+ var0[i] = var24;
+ }
+
+}
+
+#else
+static void
+_backup_orc_splat_u8_ns (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t var24 = ex->params[24];
+
+ var0 = ex->arrays[0];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyb */
+ var0[i] = var24;
+ }
+
+}
+
+void
+orc_splat_u8_ns (uint8_t * d1, int p1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_splat_u8_ns");
+ orc_program_set_backup_function (p, _backup_orc_splat_u8_ns);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_parameter (p, 1, "p1");
+
+ orc_program_append (p, "copyb", ORC_VAR_D1, ORC_VAR_P1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->params[ORC_VAR_P1] = p1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_splat_s16_ns */
+#ifdef DISABLE_ORC
+void
+orc_splat_s16_ns (int16_t * d1, int p1, int n)
+{
+ int i;
+ int16_t *var0;
+ const int16_t var24 = p1;
+
+ var0 = (void *) d1;
+
+ for (i = 0; i < n; i++) {
+ /* 0: copyw */
+ var0[i] = var24;
+ }
+
+}
+
+#else
+static void
+_backup_orc_splat_s16_ns (OrcExecutor * ex)
+{
+ int i;
+ int16_t *var0;
+ const int16_t var24 = ex->params[24];
+
+ var0 = ex->arrays[0];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: copyw */
+ var0[i] = var24;
+ }
+
+}
+
+void
+orc_splat_s16_ns (int16_t * d1, int p1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_splat_s16_ns");
+ orc_program_set_backup_function (p, _backup_orc_splat_s16_ns);
+ orc_program_add_destination (p, 2, "d1");
+ orc_program_add_parameter (p, 2, "p1");
+
+ orc_program_append (p, "copyw", ORC_VAR_D1, ORC_VAR_P1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->params[ORC_VAR_P1] = p1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_matrix2_u8 */
+#ifdef DISABLE_ORC
+void
+orc_matrix2_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, int p1, int p2,
+ int p3, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int16_t var16 = 6;
+ const int16_t var24 = p1;
+ const int16_t var25 = p2;
+ const int16_t var26 = p3;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: addw */
+ var37 = var36 + var26;
+ /* 6: shrsw */
+ var38 = var37 >> var16;
+ /* 7: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var38);
+ }
+
+}
+
+#else
+static void
+_backup_orc_matrix2_u8 (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int16_t var16 = 6;
+ const int16_t var24 = ex->params[24];
+ const int16_t var25 = ex->params[25];
+ const int16_t var26 = ex->params[26];
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: addw */
+ var37 = var36 + var26;
+ /* 6: shrsw */
+ var38 = var37 >> var16;
+ /* 7: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var38);
+ }
+
+}
+
+void
+orc_matrix2_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, int p1, int p2,
+ int p3, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_matrix2_u8");
+ orc_program_set_backup_function (p, _backup_orc_matrix2_u8);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_constant (p, 2, 6, "c1");
+ orc_program_add_parameter (p, 2, "p1");
+ orc_program_add_parameter (p, 2, "p2");
+ orc_program_add_parameter (p, 2, "p3");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P3);
+ orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->params[ORC_VAR_P1] = p1;
+ ex->params[ORC_VAR_P2] = p2;
+ ex->params[ORC_VAR_P3] = p3;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_matrix3_u8 */
+#ifdef DISABLE_ORC
+void
+orc_matrix3_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int p2, int p3, int p4, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int16_t var16 = 6;
+ const int16_t var24 = p1;
+ const int16_t var25 = p2;
+ const int16_t var26 = p3;
+ const int16_t var27 = p4;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: convubw */
+ var37 = (uint8_t) var6[i];
+ /* 6: mullw */
+ var38 = (var37 * var26) & 0xffff;
+ /* 7: addw */
+ var39 = var36 + var38;
+ /* 8: addw */
+ var40 = var39 + var27;
+ /* 9: shrsw */
+ var41 = var40 >> var16;
+ /* 10: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var41);
+ }
+
+}
+
+#else
+static void
+_backup_orc_matrix3_u8 (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int16_t var16 = 6;
+ const int16_t var24 = ex->params[24];
+ const int16_t var25 = ex->params[25];
+ const int16_t var26 = ex->params[26];
+ const int16_t var27 = ex->params[27];
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: convubw */
+ var37 = (uint8_t) var6[i];
+ /* 6: mullw */
+ var38 = (var37 * var26) & 0xffff;
+ /* 7: addw */
+ var39 = var36 + var38;
+ /* 8: addw */
+ var40 = var39 + var27;
+ /* 9: shrsw */
+ var41 = var40 >> var16;
+ /* 10: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var41);
+ }
+
+}
+
+void
+orc_matrix3_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int p2, int p3, int p4, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_matrix3_u8");
+ orc_program_set_backup_function (p, _backup_orc_matrix3_u8);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_constant (p, 2, 6, "c1");
+ orc_program_add_parameter (p, 2, "p1");
+ orc_program_add_parameter (p, 2, "p2");
+ orc_program_add_parameter (p, 2, "p3");
+ orc_program_add_parameter (p, 2, "p4");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S3, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P3);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P4);
+ orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+ ex->params[ORC_VAR_P1] = p1;
+ ex->params[ORC_VAR_P2] = p2;
+ ex->params[ORC_VAR_P3] = p3;
+ ex->params[ORC_VAR_P4] = p4;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_pack_123x */
+#ifdef DISABLE_ORC
+void
+orc_pack_123x (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int n)
+{
+ int i;
+ int32_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t var24 = p1;
+ int16_t var32;
+ int16_t var33;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: mergebw */
+ var32 = ((uint8_t) var4[i]) | ((uint8_t) var5[i] << 8);
+ /* 1: mergebw */
+ var33 = ((uint8_t) var6[i]) | ((uint8_t) var24 << 8);
+ /* 2: mergewl */
+ var0[i] = ((uint16_t) var32) | ((uint16_t) var33 << 16);
+ }
+
+}
+
+#else
+static void
+_backup_orc_pack_123x (OrcExecutor * ex)
+{
+ int i;
+ int32_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t var24 = ex->params[24];
+ int16_t var32;
+ int16_t var33;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: mergebw */
+ var32 = ((uint8_t) var4[i]) | ((uint8_t) var5[i] << 8);
+ /* 1: mergebw */
+ var33 = ((uint8_t) var6[i]) | ((uint8_t) var24 << 8);
+ /* 2: mergewl */
+ var0[i] = ((uint16_t) var32) | ((uint16_t) var33 << 16);
+ }
+
+}
+
+void
+orc_pack_123x (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_pack_123x");
+ orc_program_set_backup_function (p, _backup_orc_pack_123x);
+ orc_program_add_destination (p, 4, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_parameter (p, 1, "p1");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+
+ orc_program_append (p, "mergebw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_S2);
+ orc_program_append (p, "mergebw", ORC_VAR_T2, ORC_VAR_S3, ORC_VAR_P1);
+ orc_program_append (p, "mergewl", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_T2);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+ ex->params[ORC_VAR_P1] = p1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* orc_pack_x123 */
+#ifdef DISABLE_ORC
+void
+orc_pack_x123 (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int n)
+{
+ int i;
+ int32_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t var24 = p1;
+ int16_t var32;
+ int16_t var33;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+
+ for (i = 0; i < n; i++) {
+ /* 0: mergebw */
+ var32 = ((uint8_t) var24) | ((uint8_t) var4[i] << 8);
+ /* 1: mergebw */
+ var33 = ((uint8_t) var5[i]) | ((uint8_t) var6[i] << 8);
+ /* 2: mergewl */
+ var0[i] = ((uint16_t) var32) | ((uint16_t) var33 << 16);
+ }
+
+}
+
+#else
+static void
+_backup_orc_pack_x123 (OrcExecutor * ex)
+{
+ int i;
+ int32_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t var24 = ex->params[24];
+ int16_t var32;
+ int16_t var33;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: mergebw */
+ var32 = ((uint8_t) var24) | ((uint8_t) var4[i] << 8);
+ /* 1: mergebw */
+ var33 = ((uint8_t) var5[i]) | ((uint8_t) var6[i] << 8);
+ /* 2: mergewl */
+ var0[i] = ((uint16_t) var32) | ((uint16_t) var33 << 16);
+ }
+
+}
+
+void
+orc_pack_x123 (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1,
+ int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "orc_pack_x123");
+ orc_program_set_backup_function (p, _backup_orc_pack_x123);
+ orc_program_add_destination (p, 4, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_parameter (p, 1, "p1");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+
+ orc_program_append (p, "mergebw", ORC_VAR_T1, ORC_VAR_P1, ORC_VAR_S1);
+ orc_program_append (p, "mergebw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_S3);
+ orc_program_append (p, "mergewl", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_T2);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+ ex->params[ORC_VAR_P1] = p1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_combine4_u8 */
+#ifdef DISABLE_ORC
+void
+cogorc_combine4_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3,
+ uint8_t * s4, int p1, int p2, int p3, int p4, int n)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t *var7;
+ const int16_t var16 = 32;
+ const int16_t var17 = 6;
+ const int16_t var24 = p1;
+ const int16_t var25 = p2;
+ const int16_t var26 = p3;
+ const int16_t var27 = p4;
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+ int16_t var43;
+ int16_t var44;
+
+ var0 = (void *) d1;
+ var4 = (void *) s1;
+ var5 = (void *) s2;
+ var6 = (void *) s3;
+ var7 = (void *) s4;
+
+ for (i = 0; i < n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: convubw */
+ var37 = (uint8_t) var6[i];
+ /* 6: mullw */
+ var38 = (var37 * var26) & 0xffff;
+ /* 7: addw */
+ var39 = var36 + var38;
+ /* 8: convubw */
+ var40 = (uint8_t) var7[i];
+ /* 9: mullw */
+ var41 = (var40 * var27) & 0xffff;
+ /* 10: addw */
+ var42 = var39 + var41;
+ /* 11: addw */
+ var43 = var42 + var16;
+ /* 12: shrsw */
+ var44 = var43 >> var17;
+ /* 13: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var44);
+ }
+
+}
+
+#else
+static void
+_backup_cogorc_combine4_u8 (OrcExecutor * ex)
+{
+ int i;
+ int8_t *var0;
+ const int8_t *var4;
+ const int8_t *var5;
+ const int8_t *var6;
+ const int8_t *var7;
+ const int16_t var16 = 32;
+ const int16_t var17 = 6;
+ const int16_t var24 = ex->params[24];
+ const int16_t var25 = ex->params[25];
+ const int16_t var26 = ex->params[26];
+ const int16_t var27 = ex->params[27];
+ int16_t var32;
+ int16_t var33;
+ int16_t var34;
+ int16_t var35;
+ int16_t var36;
+ int16_t var37;
+ int16_t var38;
+ int16_t var39;
+ int16_t var40;
+ int16_t var41;
+ int16_t var42;
+ int16_t var43;
+ int16_t var44;
+
+ var0 = ex->arrays[0];
+ var4 = ex->arrays[4];
+ var5 = ex->arrays[5];
+ var6 = ex->arrays[6];
+ var7 = ex->arrays[7];
+
+ for (i = 0; i < ex->n; i++) {
+ /* 0: convubw */
+ var32 = (uint8_t) var4[i];
+ /* 1: mullw */
+ var34 = (var32 * var24) & 0xffff;
+ /* 2: convubw */
+ var33 = (uint8_t) var5[i];
+ /* 3: mullw */
+ var35 = (var33 * var25) & 0xffff;
+ /* 4: addw */
+ var36 = var34 + var35;
+ /* 5: convubw */
+ var37 = (uint8_t) var6[i];
+ /* 6: mullw */
+ var38 = (var37 * var26) & 0xffff;
+ /* 7: addw */
+ var39 = var36 + var38;
+ /* 8: convubw */
+ var40 = (uint8_t) var7[i];
+ /* 9: mullw */
+ var41 = (var40 * var27) & 0xffff;
+ /* 10: addw */
+ var42 = var39 + var41;
+ /* 11: addw */
+ var43 = var42 + var16;
+ /* 12: shrsw */
+ var44 = var43 >> var17;
+ /* 13: convsuswb */
+ var0[i] = ORC_CLAMP_UB (var44);
+ }
+
+}
+
+void
+cogorc_combine4_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3,
+ uint8_t * s4, int p1, int p2, int p3, int p4, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_combine4_u8");
+ orc_program_set_backup_function (p, _backup_cogorc_combine4_u8);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 1, "s1");
+ orc_program_add_source (p, 1, "s2");
+ orc_program_add_source (p, 1, "s3");
+ orc_program_add_source (p, 1, "s4");
+ orc_program_add_constant (p, 2, 32, "c1");
+ orc_program_add_constant (p, 2, 6, "c2");
+ orc_program_add_parameter (p, 2, "p1");
+ orc_program_add_parameter (p, 2, "p2");
+ orc_program_add_parameter (p, 2, "p3");
+ orc_program_add_parameter (p, 2, "p4");
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+
+ orc_program_append (p, "convubw", ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S3, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P3);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "convubw", ORC_VAR_T2, ORC_VAR_S4, ORC_VAR_D1);
+ orc_program_append (p, "mullw", ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P4);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_T2);
+ orc_program_append (p, "addw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1);
+ orc_program_append (p, "shrsw", ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C2);
+ orc_program_append (p, "convsuswb", ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+ ex->arrays[ORC_VAR_S2] = s2;
+ ex->arrays[ORC_VAR_S3] = s3;
+ ex->arrays[ORC_VAR_S4] = s4;
+ ex->params[ORC_VAR_P1] = p1;
+ ex->params[ORC_VAR_P2] = p2;
+ ex->params[ORC_VAR_P3] = p3;
+ ex->params[ORC_VAR_P4] = p4;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_unpack_ayuv_y */
+#ifdef DISABLE_ORC
+void
+cogorc_unpack_ayuv_y (uint8_t * d1, uint32_t * s1, int n)
+{
+}
+
+#else
+static void
+_backup_cogorc_unpack_ayuv_y (OrcExecutor * ex)
+{
+}
+
+void
+cogorc_unpack_ayuv_y (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_unpack_ayuv_y");
+ orc_program_set_backup_function (p, _backup_cogorc_unpack_ayuv_y);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select0lw", ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_unpack_ayuv_u */
+#ifdef DISABLE_ORC
+void
+cogorc_unpack_ayuv_u (uint8_t * d1, uint32_t * s1, int n)
+{
+}
+
+#else
+static void
+_backup_cogorc_unpack_ayuv_u (OrcExecutor * ex)
+{
+}
+
+void
+cogorc_unpack_ayuv_u (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_unpack_ayuv_u");
+ orc_program_set_backup_function (p, _backup_cogorc_unpack_ayuv_u);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select1lw", ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1);
+ orc_program_append (p, "select0wb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
+
+
+/* cogorc_unpack_ayuv_v */
+#ifdef DISABLE_ORC
+void
+cogorc_unpack_ayuv_v (uint8_t * d1, uint32_t * s1, int n)
+{
+}
+
+#else
+static void
+_backup_cogorc_unpack_ayuv_v (OrcExecutor * ex)
+{
+}
+
+void
+cogorc_unpack_ayuv_v (uint8_t * d1, uint32_t * s1, int n)
+{
+ OrcExecutor _ex, *ex = &_ex;
+ static int p_inited = 0;
+ static OrcProgram *p = 0;
+
+ if (!p_inited) {
+ orc_once_mutex_lock ();
+ if (!p_inited) {
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+ orc_program_set_name (p, "cogorc_unpack_ayuv_v");
+ orc_program_set_backup_function (p, _backup_cogorc_unpack_ayuv_v);
+ orc_program_add_destination (p, 1, "d1");
+ orc_program_add_source (p, 4, "s1");
+ orc_program_add_temporary (p, 2, "t1");
+
+ orc_program_append (p, "select1lw", ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1);
+ orc_program_append (p, "select1wb", ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1);
+
+ result = orc_program_compile (p);
+ }
+ p_inited = TRUE;
+ orc_once_mutex_unlock ();
+ }
+ ex->program = p;
+
+ ex->n = n;
+ ex->arrays[ORC_VAR_D1] = d1;
+ ex->arrays[ORC_VAR_S1] = s1;
+
+ orc_executor_run (ex);
+}
+#endif
diff --git a/ext/cog/cogorc.h b/ext/cog/cogorc.h
new file mode 100644
index 000000000..e39dcee9a
--- /dev/null
+++ b/ext/cog/cogorc.h
@@ -0,0 +1,36 @@
+
+/* autogenerated from cog.orc */
+
+#ifndef _ORC_OUT_H_
+#define _ORC_OUT_H_
+
+void cogorc_downsample_horiz_cosite_3tap (uint8_t * d1, uint16_t * s1, uint16_t * s2, int n);
+void cogorc_downsample_vert_halfsite_2tap (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n);
+void cogorc_downsample_vert_halfsite_3tap (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n);
+void cogorc_downsample_vert_halfsite_4tap (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, uint8_t * s4, int n);
+void cogorc_upsample_horiz_cosite (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n);
+void cogorc_upsample_vert_avgub (uint8_t * d1, uint8_t * s1, uint8_t * s2, int n);
+void orc_unpack_yuyv_y (uint8_t * d1, uint16_t * s1, int n);
+void orc_unpack_yuyv_u (uint8_t * d1, uint32_t * s1, int n);
+void orc_unpack_yuyv_v (uint8_t * d1, uint32_t * s1, int n);
+void orc_pack_yuyv (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n);
+void orc_unpack_uyvy_y (uint8_t * d1, uint16_t * s1, int n);
+void orc_unpack_uyvy_u (uint8_t * d1, uint32_t * s1, int n);
+void orc_unpack_uyvy_v (uint8_t * d1, uint32_t * s1, int n);
+void orc_pack_uyvy (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n);
+void orc_memcpy (void * d1, void * s1, int n);
+void orc_addc_convert_u8_s16 (uint8_t * d1, int16_t * s1, int n);
+void orc_subc_convert_s16_u8 (int16_t * d1, uint8_t * s1, int n);
+void orc_splat_u8_ns (uint8_t * d1, int p1, int n);
+void orc_splat_s16_ns (int16_t * d1, int p1, int n);
+void orc_matrix2_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, int p1, int p2, int p3, int n);
+void orc_matrix3_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1, int p2, int p3, int p4, int n);
+void orc_pack_123x (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1, int n);
+void orc_pack_x123 (uint32_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, int p1, int n);
+void cogorc_combine4_u8 (uint8_t * d1, uint8_t * s1, uint8_t * s2, uint8_t * s3, uint8_t * s4, int p1, int p2, int p3, int p4, int n);
+void cogorc_unpack_ayuv_y (uint8_t * d1, uint32_t * s1, int n);
+void cogorc_unpack_ayuv_u (uint8_t * d1, uint32_t * s1, int n);
+void cogorc_unpack_ayuv_v (uint8_t * d1, uint32_t * s1, int n);
+
+#endif
+
diff --git a/ext/cog/cogvirtframe.c b/ext/cog/cogvirtframe.c
new file mode 100644
index 000000000..50dcedfb6
--- /dev/null
+++ b/ext/cog/cogvirtframe.c
@@ -0,0 +1,1734 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define COG_ENABLE_UNSTABLE_API 1
+
+#include <cog-video/cogvirtframe.h>
+#include <cog-video/cogorc.h>
+#include <cog/cog.h>
+#include <string.h>
+#include <math.h>
+#include <orc/orc.h>
+
+
+CogFrame *
+cog_frame_new_virtual (CogMemoryDomain * domain, CogFrameFormat format,
+ int width, int height)
+{
+ CogFrame *frame = cog_frame_new ();
+ int bytes_pp;
+ int h_shift, v_shift;
+ int chroma_width;
+ int chroma_height;
+ int i;
+
+ frame->format = format;
+ frame->width = width;
+ frame->height = height;
+ frame->domain = domain;
+
+ if (COG_FRAME_IS_PACKED (format)) {
+ frame->components[0].format = format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ if (format == COG_FRAME_FORMAT_AYUV) {
+ frame->components[0].stride = width * 4;
+ } else if (format == COG_FRAME_FORMAT_v216) {
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 4;
+ } else if (format == COG_FRAME_FORMAT_v210) {
+ frame->components[0].stride = ((width + 47) / 48) * 128;
+ } else {
+ frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
+ }
+ frame->components[0].length = frame->components[0].stride * height;
+
+ frame->components[0].data = frame->regions[0];
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->regions[0] =
+ malloc (frame->components[0].stride * COG_FRAME_CACHE_SIZE);
+ for (i = 0; i < COG_FRAME_CACHE_SIZE; i++) {
+ frame->cached_lines[0][i] = -1;
+ }
+ frame->is_virtual = TRUE;
+
+ return frame;
+ }
+
+ switch (COG_FRAME_FORMAT_DEPTH (format)) {
+ case COG_FRAME_FORMAT_DEPTH_U8:
+ bytes_pp = 1;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S16:
+ bytes_pp = 2;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S32:
+ bytes_pp = 4;
+ break;
+ default:
+ COG_ASSERT (0);
+ bytes_pp = 0;
+ break;
+ }
+
+ h_shift = COG_FRAME_FORMAT_H_SHIFT (format);
+ v_shift = COG_FRAME_FORMAT_V_SHIFT (format);
+ chroma_width = ROUND_UP_SHIFT (width, h_shift);
+ chroma_height = ROUND_UP_SHIFT (height, v_shift);
+
+ frame->components[0].format = format;
+ frame->components[0].width = width;
+ frame->components[0].height = height;
+ frame->components[0].stride = ROUND_UP_4 (width * bytes_pp);
+ frame->components[0].length =
+ frame->components[0].stride * frame->components[0].height;
+ frame->components[0].v_shift = 0;
+ frame->components[0].h_shift = 0;
+
+ frame->components[1].format = format;
+ frame->components[1].width = chroma_width;
+ frame->components[1].height = chroma_height;
+ frame->components[1].stride = ROUND_UP_4 (chroma_width * bytes_pp);
+ frame->components[1].length =
+ frame->components[1].stride * frame->components[1].height;
+ frame->components[1].v_shift = v_shift;
+ frame->components[1].h_shift = h_shift;
+
+ frame->components[2].format = format;
+ frame->components[2].width = chroma_width;
+ frame->components[2].height = chroma_height;
+ frame->components[2].stride = ROUND_UP_4 (chroma_width * bytes_pp);
+ frame->components[2].length =
+ frame->components[2].stride * frame->components[2].height;
+ frame->components[2].v_shift = v_shift;
+ frame->components[2].h_shift = h_shift;
+
+ for (i = 0; i < 3; i++) {
+ CogFrameData *comp = &frame->components[i];
+ int j;
+
+ frame->regions[i] = malloc (comp->stride * COG_FRAME_CACHE_SIZE);
+ for (j = 0; j < COG_FRAME_CACHE_SIZE; j++) {
+ frame->cached_lines[i][j] = -1;
+ }
+ }
+ frame->is_virtual = TRUE;
+
+ return frame;
+}
+
+void *
+cog_virt_frame_get_line (CogFrame * frame, int component, int i)
+{
+ CogFrameData *comp = &frame->components[component];
+ int j;
+ int min;
+ int min_j;
+
+ //COG_ASSERT(i >= 0);
+ //COG_ASSERT(i < comp->height);
+
+ if (!frame->is_virtual) {
+ return COG_FRAME_DATA_GET_LINE (&frame->components[component], i);
+ }
+
+ for (j = 0; j < COG_FRAME_CACHE_SIZE; j++) {
+ if (frame->cached_lines[component][j] == i) {
+ return COG_OFFSET (frame->regions[component], comp->stride * j);
+ }
+ }
+
+ min_j = 0;
+ min = frame->cached_lines[component][0];
+ for (j = 1; j < COG_FRAME_CACHE_SIZE; j++) {
+ if (frame->cached_lines[component][j] < min) {
+ min = frame->cached_lines[component][j];
+ min_j = j;
+ }
+ }
+ frame->cached_lines[component][min_j] = i;
+
+ cog_virt_frame_render_line (frame,
+ COG_OFFSET (frame->regions[component], comp->stride * min_j),
+ component, i);
+
+ return COG_OFFSET (frame->regions[component], comp->stride * min_j);
+}
+
+void
+cog_virt_frame_render_line (CogFrame * frame, void *dest, int component, int i)
+{
+ frame->render_line (frame, dest, component, i);
+}
+
+static void
+copy (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame, component, i);
+ switch (COG_FRAME_FORMAT_DEPTH (frame->format)) {
+ case COG_FRAME_FORMAT_DEPTH_U8:
+ orc_memcpy (dest, src, frame->components[component].width);
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S16:
+ orc_memcpy (dest, src, frame->components[component].width * 2);
+ break;
+ default:
+ COG_ASSERT (0);
+ break;
+ }
+}
+
+void
+cog_virt_frame_render (CogFrame * frame, CogFrame * dest)
+{
+ int i, k;
+
+ COG_ASSERT (frame->width == dest->width);
+ COG_ASSERT (frame->height >= dest->height);
+
+ if (frame->is_virtual) {
+ for (k = 0; k < 3; k++) {
+ CogFrameData *comp = dest->components + k;
+
+ for (i = 0; i < dest->components[k].height; i++) {
+ cog_virt_frame_render_line (frame,
+ COG_FRAME_DATA_GET_LINE (comp, i), k, i);
+ }
+ }
+ } else {
+ for (k = 0; k < 3; k++) {
+ CogFrameData *comp = dest->components + k;
+
+ for (i = 0; i < dest->components[k].height; i++) {
+ copy (frame, COG_FRAME_DATA_GET_LINE (comp, i), k, i);
+ }
+ }
+ }
+}
+
+static void
+cog_virt_frame_render_downsample_horiz_cosite_3tap (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int n_src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ n_src = frame->virt_frame1->components[component].width;
+
+ cogorc_downsample_horiz_cosite_3tap (dest + 1,
+ (uint16_t *) (src + 1), (uint16_t *) (src + 3),
+ frame->components[component].width - 1);
+
+ {
+ int j;
+ int x;
+
+ j = 0;
+ x = 1 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
+ x += 2 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
+ x += 1 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
+ dest[j] = CLAMP ((x + 2) >> 2, 0, 255);
+
+#if 0
+ j = frame->components[component].width - 1;
+ x = 1 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
+ x += 2 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
+ x += 1 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
+ dest[j] = CLAMP ((x + 2) >> 2, 0, 255);
+#endif
+ }
+}
+
+void
+cog_virt_frame_render_downsample_horiz_halfsite (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int j;
+ int n_src;
+ int taps = 4;
+ int k;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ n_src = frame->virt_frame1->components[component].width;
+
+ switch (taps) {
+ case 4:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ x += 6 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
+ x += 26 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
+ x += 26 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
+ x += 6 * src[CLAMP (j * 2 + 2, 0, n_src - 1)];
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ case 6:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ x += -3 * src[CLAMP (j * 2 - 2, 0, n_src - 1)];
+ x += 8 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
+ x += 27 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
+ x += 27 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
+ x += 8 * src[CLAMP (j * 2 + 2, 0, n_src - 1)];
+ x += -3 * src[CLAMP (j * 2 + 3, 0, n_src - 1)];
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ case 8:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ const int taps8[8] = { -2, -4, 9, 29, 29, 9, -4, -2 };
+ for (k = 0; k < 8; k++) {
+ x += taps8[k] * src[CLAMP (j * 2 - 3 + k, 0, n_src - 1)];
+ }
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ case 10:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ const int taps10[10] = { 1, -2, -5, 9, 29, 29, 9, -5, -2, 1 };
+ for (k = 0; k < 10; k++) {
+ x += taps10[k] * src[CLAMP (j * 2 - 4 + k, 0, n_src - 1)];
+ }
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_horiz_downsample (CogFrame * vf, int n_taps)
+{
+ CogFrame *virt_frame;
+
+ virt_frame =
+ cog_frame_new_virtual (NULL, vf->format, vf->width / 2, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->param1 = n_taps;
+ switch (n_taps) {
+ case 3:
+ virt_frame->render_line =
+ cog_virt_frame_render_downsample_horiz_cosite_3tap;
+ break;
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ virt_frame->render_line = cog_virt_frame_render_downsample_horiz_halfsite;
+ break;
+ default:
+ COG_ASSERT (0);
+ return NULL;
+ }
+
+ return virt_frame;
+}
+
+void
+cog_virt_frame_render_downsample_vert_cosite (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ uint8_t *src3;
+ int n_src;
+
+ n_src = frame->virt_frame1->components[component].height;
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 - 1, 0, n_src - 1));
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 0, 0, n_src - 1));
+ src3 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 1, 0, n_src - 1));
+
+ cogorc_downsample_vert_halfsite_3tap (dest, src1, src2, src3,
+ frame->components[component].width);
+}
+
+static void
+cog_virt_frame_render_downsample_vert_halfsite_2tap (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ //static OrcProgram *p = NULL;
+ //OrcExecutor _ex, *ex = &_ex;
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ int n_src;
+
+ n_src = frame->virt_frame1->components[component].height;
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2, 0, n_src - 1));
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 1, 0, n_src - 1));
+
+ cogorc_downsample_vert_halfsite_2tap (dest, src1, src2,
+ frame->components[component].width);
+}
+
+static void
+cog_virt_frame_render_downsample_vert_halfsite_4tap (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ //static OrcProgram *p = NULL;
+ //OrcExecutor _ex, *ex = &_ex;
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ uint8_t *src3;
+ uint8_t *src4;
+ int n_src;
+
+ n_src = frame->virt_frame1->components[component].height;
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 - 1, 0, n_src - 1));
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2, 0, n_src - 1));
+ src3 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 1, 0, n_src - 1));
+ src4 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 2, 0, n_src - 1));
+
+ cogorc_downsample_vert_halfsite_4tap (dest, src1, src2, src3, src4,
+ frame->components[component].width);
+}
+
+
+void
+cog_virt_frame_render_downsample_vert_halfsite (CogFrame * frame,
+ void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src[10];
+ int j;
+ int n_src;
+ int taps = frame->param1;
+ int k;
+
+ n_src = frame->virt_frame1->components[component].height;
+ for (j = 0; j < taps; j++) {
+ src[j] = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 - (taps - 2) / 2 + j, 0, n_src - 1));
+ }
+
+ switch (taps) {
+ case 4:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ x += 6 * src[0][j];
+ x += 26 * src[1][j];
+ x += 26 * src[2][j];
+ x += 6 * src[3][j];
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ case 6:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ x += -3 * src[0][j];
+ x += 8 * src[1][j];
+ x += 27 * src[2][j];
+ x += 27 * src[3][j];
+ x += 8 * src[4][j];
+ x += -3 * src[5][j];
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ case 8:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ const int taps8[8] = { -2, -4, 9, 29, 29, 9, -4, -2 };
+ for (k = 0; k < 8; k++) {
+ x += taps8[k] * src[k][j];
+ }
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ case 10:
+ for (j = 0; j < frame->components[component].width; j++) {
+ int x = 0;
+ const int taps10[10] = { 1, -2, -5, 9, 29, 29, 9, -5, -2, 1 };
+ //const int taps10[10] = { -1, 1, 6, 11, 15, 15, 11, 6, 1, -1 };
+ for (k = 0; k < 10; k++) {
+ x += taps10[k] * src[k][j];
+ }
+ dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
+ }
+ break;
+ default:
+ COG_ASSERT (0);
+ break;
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_vert_downsample (CogFrame * vf, int n_taps)
+{
+ CogFrame *virt_frame;
+
+ virt_frame =
+ cog_frame_new_virtual (NULL, vf->format, vf->width, vf->height / 2);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->param1 = n_taps;
+ switch (n_taps) {
+ case 2:
+ virt_frame->render_line =
+ cog_virt_frame_render_downsample_vert_halfsite_2tap;
+ break;
+ case 3:
+ virt_frame->render_line = cog_virt_frame_render_downsample_vert_cosite;
+ break;
+ case 4:
+ virt_frame->render_line =
+ cog_virt_frame_render_downsample_vert_halfsite_4tap;
+ break;
+ default:
+ virt_frame->render_line = cog_virt_frame_render_downsample_vert_halfsite;
+ break;
+ }
+
+ return virt_frame;
+}
+
+void
+get_taps (double *taps, double x)
+{
+ taps[3] = x * x * (x - 1);
+ taps[2] = x * (-x * x + x + 1);
+ x = 1 - x;
+ taps[1] = x * (-x * x + x + 1);
+ taps[0] = x * x * (x - 1);
+}
+
+void
+cog_virt_frame_render_resample_vert (CogFrame * frame, void *_dest,
+ int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ uint8_t *src3;
+ uint8_t *src4;
+ int n_src;
+ double taps[4];
+ double *scale = (double *) frame->virt_priv;
+ double x;
+ int src_i;
+
+ x = (*scale) * i;
+ src_i = floor (x);
+ get_taps (taps, x - floor (x));
+
+ n_src = frame->virt_frame1->components[component].height;
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (src_i - 1, 0, n_src - 1));
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (src_i + 0, 0, n_src - 1));
+ src3 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (src_i + 1, 0, n_src - 1));
+ src4 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (src_i + 2, 0, n_src - 1));
+
+ cogorc_combine4_u8 (dest, src1, src2, src3, src4,
+ rint (taps[0] * 64.0), rint (taps[1] * 64.0),
+ rint (taps[2] * 64.0), rint (taps[3] * 64.0),
+ frame->components[component].width);
+}
+
+CogFrame *
+cog_virt_frame_new_vert_resample (CogFrame * vf, int height)
+{
+ CogFrame *virt_frame;
+ double *scale;
+
+ virt_frame = cog_frame_new_virtual (NULL, vf->format, vf->width, height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = cog_virt_frame_render_resample_vert;
+
+ scale = malloc (sizeof (double));
+ virt_frame->virt_priv = scale;
+
+ *scale = (double) vf->height / height;
+
+ return virt_frame;
+}
+
+void
+cog_virt_frame_render_resample_horiz (CogFrame * frame, void *_dest,
+ int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int j;
+ int n_src;
+ double taps[4];
+ double *scale = (double *) frame->virt_priv;
+ int src_i;
+
+ n_src = frame->virt_frame1->components[component].width;
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+
+ for (j = 0; j < frame->components[component].width; j++) {
+ double x;
+ double y = 0;
+
+ x = (*scale) * j;
+ src_i = floor (x);
+ get_taps (taps, x - floor (x));
+
+ y = 0;
+ y += taps[0] * src[CLAMP (src_i - 1, 0, n_src - 1)];
+ y += taps[1] * src[CLAMP (src_i + 0, 0, n_src - 1)];
+ y += taps[2] * src[CLAMP (src_i + 1, 0, n_src - 1)];
+ y += taps[3] * src[CLAMP (src_i + 2, 0, n_src - 1)];
+ dest[j] = CLAMP (rint (y), 0, 255);
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_horiz_resample (CogFrame * vf, int width)
+{
+ CogFrame *virt_frame;
+ double *scale;
+
+ virt_frame = cog_frame_new_virtual (NULL, vf->format, width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = cog_virt_frame_render_resample_horiz;
+
+ scale = malloc (sizeof (double));
+ virt_frame->virt_priv = scale;
+
+ *scale = (double) vf->width / width;
+
+ return virt_frame;
+}
+
+static void
+unpack_yuyv (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+
+ switch (component) {
+ case 0:
+ orc_unpack_yuyv_y (dest, (void *) src, frame->width);
+ break;
+ case 1:
+ orc_unpack_yuyv_u (dest, (void *) src, frame->width / 2);
+ break;
+ case 2:
+ orc_unpack_yuyv_v (dest, (void *) src, frame->width / 2);
+ break;
+ }
+}
+
+static void
+unpack_uyvy (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+
+ switch (component) {
+ case 0:
+ orc_unpack_uyvy_y (dest, (void *) src, frame->width);
+ break;
+ case 1:
+ orc_unpack_uyvy_u (dest, (void *) src, frame->width / 2);
+ break;
+ case 2:
+ orc_unpack_uyvy_v (dest, (void *) src, frame->width / 2);
+ break;
+ }
+}
+
+static void
+unpack_ayuv (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint32_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+
+ switch (component) {
+ case 0:
+ cogorc_unpack_ayuv_y (dest, src, frame->width);
+ break;
+ case 1:
+ cogorc_unpack_ayuv_y (dest, src, frame->width);
+ break;
+ case 2:
+ cogorc_unpack_ayuv_v (dest, src, frame->width);
+ break;
+ }
+}
+
+static void
+unpack_v210 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int j;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+
+#define READ_UINT32_LE(a) (((uint8_t *)(a))[0] | (((uint8_t *)(a))[1]<<8) | \
+ (((uint8_t *)(a))[2]<<16) | (((uint8_t *)(a))[3]<<24))
+ switch (component) {
+ case 0:
+ for (j = 0; j < frame->width / 6; j++) {
+ dest[j * 6 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 10) & 0x3ff) >> 2;
+ dest[j * 6 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 0) & 0x3ff) >> 2;
+ dest[j * 6 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 20) & 0x3ff) >> 2;
+ dest[j * 6 + 3] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 10) & 0x3ff) >> 2;
+ dest[j * 6 + 4] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 0) & 0x3ff) >> 2;
+ dest[j * 6 + 5] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 20) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 0 < frame->width) {
+ dest[j * 6 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 10) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 1 < frame->width) {
+ dest[j * 6 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 0) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 2 < frame->width) {
+ dest[j * 6 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 20) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 3 < frame->width) {
+ dest[j * 6 + 3] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 10) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 4 < frame->width) {
+ dest[j * 6 + 4] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 0) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 5 < frame->width) {
+ dest[j * 6 + 5] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 20) & 0x3ff) >> 2;
+ }
+ break;
+ case 1:
+ for (j = 0; j < frame->width / 6; j++) {
+ dest[j * 3 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 0) & 0x3ff) >> 2;
+ dest[j * 3 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 10) & 0x3ff) >> 2;
+ dest[j * 3 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 20) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 0 < frame->width) {
+ dest[j * 3 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 0) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 2 < frame->width) {
+ dest[j * 3 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 4) >> 10) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 4 < frame->width) {
+ dest[j * 3 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 20) & 0x3ff) >> 2;
+ }
+ break;
+ case 2:
+ for (j = 0; j < frame->width / 6; j++) {
+ dest[j * 3 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 20) & 0x3ff) >> 2;
+ dest[j * 3 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 0) & 0x3ff) >> 2;
+ dest[j * 3 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 10) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 0 < frame->width) {
+ dest[j * 3 + 0] =
+ ((READ_UINT32_LE (src + j * 16 + 0) >> 20) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 2 < frame->width) {
+ dest[j * 3 + 1] =
+ ((READ_UINT32_LE (src + j * 16 + 8) >> 0) & 0x3ff) >> 2;
+ }
+ if (j * 6 + 4 < frame->width) {
+ dest[j * 3 + 2] =
+ ((READ_UINT32_LE (src + j * 16 + 12) >> 10) & 0x3ff) >> 2;
+ }
+ break;
+ }
+}
+
+static void
+unpack_v216 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int j;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+
+ switch (component) {
+ case 0:
+ for (j = 0; j < frame->width; j++) {
+ dest[j] = src[j * 4 + 2 + 1];
+ }
+ break;
+ case 1:
+ for (j = 0; j < frame->width / 2; j++) {
+ dest[j] = src[j * 8 + 0 + 1];
+ }
+ break;
+ case 2:
+ for (j = 0; j < frame->width / 2; j++) {
+ dest[j] = src[j * 8 + 4 + 1];
+ }
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_unpack (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+ CogFrameFormat format;
+ CogFrameRenderFunc render_line;
+
+ switch (vf->format) {
+ case COG_FRAME_FORMAT_YUYV:
+ format = COG_FRAME_FORMAT_U8_422;
+ render_line = unpack_yuyv;
+ break;
+ case COG_FRAME_FORMAT_UYVY:
+ format = COG_FRAME_FORMAT_U8_422;
+ render_line = unpack_uyvy;
+ break;
+ case COG_FRAME_FORMAT_AYUV:
+ format = COG_FRAME_FORMAT_U8_444;
+ render_line = unpack_ayuv;
+ break;
+ case COG_FRAME_FORMAT_v210:
+ format = COG_FRAME_FORMAT_U8_422;
+ render_line = unpack_v210;
+ break;
+ case COG_FRAME_FORMAT_v216:
+ format = COG_FRAME_FORMAT_U8_422;
+ render_line = unpack_v216;
+ break;
+ default:
+ return vf;
+ }
+
+ virt_frame = cog_frame_new_virtual (NULL, format, vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = render_line;
+
+ return virt_frame;
+}
+
+
+static void
+pack_yuyv (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_yuyv (dest, src_y, src_u, src_v, frame->width / 2);
+}
+
+
+CogFrame *
+cog_virt_frame_new_pack_YUY2 (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_YUYV,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_yuyv;
+
+ return virt_frame;
+}
+
+static void
+pack_uyvy (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_uyvy (dest, src_y, src_u, src_v, frame->width / 2);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_UYVY (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_YUYV,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_uyvy;
+
+ return virt_frame;
+}
+
+static void
+pack_v216 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+ int j;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ for (j = 0; j < frame->width / 2; j++) {
+ dest[j * 8 + 0] = src_u[j];
+ dest[j * 8 + 1] = src_u[j];
+ dest[j * 8 + 2] = src_y[j * 2 + 0];
+ dest[j * 8 + 3] = src_y[j * 2 + 0];
+ dest[j * 8 + 4] = src_v[j];
+ dest[j * 8 + 5] = src_v[j];
+ dest[j * 8 + 6] = src_y[j * 2 + 1];
+ dest[j * 8 + 7] = src_y[j * 2 + 1];
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_pack_v216 (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_v216,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_v216;
+
+ return virt_frame;
+}
+
+static void
+pack_v210 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+ int j;
+ uint32_t val;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+#define TO_10(x) (((x)<<2) | ((x)>>6))
+#define WRITE_UINT32_LE(a,b) do { \
+ ((uint8_t *)(a))[0] = (b)&0xff; \
+ ((uint8_t *)(a))[1] = ((b)>>8)&0xff; \
+ ((uint8_t *)(a))[2] = ((b)>>16)&0xff; \
+ ((uint8_t *)(a))[3] = ((b)>>24)&0xff; \
+} while(0)
+ for (j = 0; j < frame->width / 6; j++) {
+ int y0, y1, y2, y3, y4, y5;
+ int cr0, cr1, cr2;
+ int cb0, cb1, cb2;
+
+ y0 = TO_10 (src_y[j * 6 + 0]);
+ y1 = TO_10 (src_y[j * 6 + 1]);
+ y2 = TO_10 (src_y[j * 6 + 2]);
+ y3 = TO_10 (src_y[j * 6 + 3]);
+ y4 = TO_10 (src_y[j * 6 + 4]);
+ y5 = TO_10 (src_y[j * 6 + 5]);
+ cb0 = TO_10 (src_u[j * 3 + 0]);
+ cb1 = TO_10 (src_u[j * 3 + 1]);
+ cb2 = TO_10 (src_u[j * 3 + 2]);
+ cr0 = TO_10 (src_v[j * 3 + 0]);
+ cr1 = TO_10 (src_v[j * 3 + 1]);
+ cr2 = TO_10 (src_v[j * 3 + 2]);
+
+ val = (cr0 << 20) | (y0 << 10) | (cb0);
+ WRITE_UINT32_LE (dest + j * 16 + 0, val);
+
+ val = (y2 << 20) | (cb1 << 10) | (y1);
+ WRITE_UINT32_LE (dest + j * 16 + 4, val);
+
+ val = (cb2 << 20) | (y3 << 10) | (cr1);
+ WRITE_UINT32_LE (dest + j * 16 + 8, val);
+
+ val = (y5 << 20) | (cr2 << 10) | (y4);
+ WRITE_UINT32_LE (dest + j * 16 + 12, val);
+ }
+ if (j * 6 < frame->width) {
+ int y0, y1, y2, y3, y4, y5;
+ int cr0, cr1, cr2;
+ int cb0, cb1, cb2;
+
+ y0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_y[j * 6 + 0]) : 0;
+ y1 = ((j * 6 + 1) < frame->width) ? TO_10 (src_y[j * 6 + 1]) : 0;
+ y2 = ((j * 6 + 2) < frame->width) ? TO_10 (src_y[j * 6 + 2]) : 0;
+ y3 = ((j * 6 + 3) < frame->width) ? TO_10 (src_y[j * 6 + 3]) : 0;
+ y4 = ((j * 6 + 4) < frame->width) ? TO_10 (src_y[j * 6 + 4]) : 0;
+ y5 = ((j * 6 + 5) < frame->width) ? TO_10 (src_y[j * 6 + 5]) : 0;
+ cb0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_u[j * 3 + 0]) : 0;
+ cb1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_u[j * 3 + 1]) : 0;
+ cb2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_u[j * 3 + 2]) : 0;
+ cr0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_v[j * 3 + 0]) : 0;
+ cr1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_v[j * 3 + 1]) : 0;
+ cr2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_v[j * 3 + 2]) : 0;
+
+ val = (cr0 << 20) | (y0 << 10) | (cb0);
+ WRITE_UINT32_LE (dest + j * 16 + 0, val);
+
+ val = (y2 << 20) | (cb1 << 10) | (y1);
+ WRITE_UINT32_LE (dest + j * 16 + 4, val);
+
+ val = (cb2 << 20) | (y3 << 10) | (cr1);
+ WRITE_UINT32_LE (dest + j * 16 + 8, val);
+
+ val = (y5 << 20) | (cr2 << 10) | (y4);
+ WRITE_UINT32_LE (dest + j * 16 + 12, val);
+ }
+
+}
+
+CogFrame *
+cog_virt_frame_new_pack_v210 (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_v210,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_v210;
+
+ return virt_frame;
+}
+
+static void
+pack_ayuv (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_x123 (dest, src_y, src_u, src_v, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_AYUV (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_AYUV,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_ayuv;
+
+ return virt_frame;
+}
+
+static void
+pack_rgb (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+ int j;
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ for (j = 0; j < frame->width; j++) {
+ dest[j * 3 + 0] = src_y[j];
+ dest[j * 3 + 1] = src_u[j];
+ dest[j * 3 + 2] = src_v[j];
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_pack_RGB (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_RGB,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_rgb;
+
+ return virt_frame;
+}
+
+static void
+color_matrix (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ uint8_t *src3;
+ double m1, m2, m3;
+ double offset;
+
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src3 = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+#if 0
+ /* for RGB -> YUV */
+ switch (component) {
+ case 0:
+ m1 = 0.25679;
+ m2 = 0.50413;
+ m3 = 0.097906;
+ offset = 16;
+ break;
+ case 1:
+ m1 = -0.14822;
+ m2 = -0.29099;
+ m3 = 0.43922;
+ offset = 128;
+ break;
+ case 2:
+ m1 = 0.43922;
+ m2 = -0.36779;
+ m3 = -0.071427;
+ offset = 128;
+ break;
+ default:
+ m1 = 0.0;
+ m2 = 0.0;
+ m3 = 0.0;
+ offset = 0;
+ break;
+ }
+#endif
+
+ switch (component) {
+ case 0:
+ m1 = 1.1644;
+ m2 = 0;
+ m3 = 1.596;
+ offset = -222.92;
+ orc_matrix2_u8 (dest, src1, src3, 75, 102, -14269 + 32, frame->width);
+ break;
+ case 1:
+ m1 = 1.1644;
+ m2 = -0.39176;
+ m3 = -0.81297;
+ offset = 135.58;
+ orc_matrix3_u8 (dest, src1, src2, src3, 75, -25, -52, 8677 + 32,
+ frame->width);
+ break;
+ case 2:
+ m1 = 1.1644;
+ m2 = 2.0172;
+ m3 = 0;
+ offset = -276.84;
+ orc_matrix2_u8 (dest, src1, src2, 75, 129, -17718 + 32, frame->width);
+ break;
+ default:
+ m1 = 0.0;
+ m2 = 0.0;
+ m3 = 0.0;
+ offset = 0;
+ break;
+ }
+
+}
+
+CogFrame *
+cog_virt_frame_new_color_matrix (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = color_matrix;
+
+ return virt_frame;
+}
+
+static void
+convert_444_422 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int n_src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ n_src = frame->virt_frame1->components[component].width;
+
+ if (component == 0) {
+ orc_memcpy (dest, src, frame->width);
+ } else {
+ cogorc_downsample_horiz_cosite_3tap (dest + 1,
+ (uint16_t *) (src + 1), (uint16_t *) (src + 3),
+ frame->components[component].width - 1);
+
+ {
+ int j;
+ int x;
+
+ j = 0;
+ x = 1 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
+ x += 2 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
+ x += 1 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
+ dest[j] = CLAMP ((x + 2) >> 2, 0, 255);
+ }
+ }
+}
+
+static void
+convert_422_420 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ if (component == 0) {
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ orc_memcpy (dest, src, frame->components[component].width);
+ } else {
+ uint8_t *dest = _dest;
+ uint8_t *src1;
+ uint8_t *src2;
+ uint8_t *src3;
+ int n_src;
+
+ n_src = frame->virt_frame1->components[component].height;
+ src1 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 - 1, 0, n_src - 1));
+ src2 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 0, 0, n_src - 1));
+ src3 = cog_virt_frame_get_line (frame->virt_frame1, component,
+ CLAMP (i * 2 + 1, 0, n_src - 1));
+
+ cogorc_downsample_vert_halfsite_3tap (dest, src1, src2, src3,
+ frame->components[component].width);
+ }
+}
+
+/* up */
+
+static void
+convert_422_444 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+
+ if (component == 0) {
+ orc_memcpy (dest, src, frame->width);
+ } else {
+ cogorc_upsample_horiz_cosite (dest, src, src + 1,
+ frame->components[component].width / 2 - 1);
+ dest[frame->components[component].width - 2] =
+ src[frame->components[component].width / 2 - 1];
+ dest[frame->components[component].width - 1] =
+ src[frame->components[component].width / 2 - 1];
+ }
+}
+
+static void
+convert_420_422 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ if (component == 0) {
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ orc_memcpy (dest, src, frame->components[component].width);
+ } else {
+ if ((i & 1) && i < frame->components[component].height - 1) {
+ uint8_t *src2;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i >> 1);
+ src2 = cog_virt_frame_get_line (frame->virt_frame1,
+ component, (i >> 1) + 1);
+ cogorc_upsample_vert_avgub (dest, src, src2,
+ frame->components[component].width);
+ } else {
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i >> 1);
+ orc_memcpy (dest, src, frame->components[component].width);
+ }
+ }
+}
+
+CogFrame *
+cog_virt_frame_new_subsample (CogFrame * vf, CogFrameFormat format)
+{
+ CogFrame *virt_frame;
+ CogFrameRenderFunc render_line;
+
+ if (vf->format == format) {
+ return vf;
+ }
+ if (vf->format == COG_FRAME_FORMAT_U8_422 &&
+ format == COG_FRAME_FORMAT_U8_420) {
+ render_line = convert_422_420;
+ } else if (vf->format == COG_FRAME_FORMAT_U8_444 &&
+ format == COG_FRAME_FORMAT_U8_420) {
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_422,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = convert_444_422;
+ vf = virt_frame;
+
+ render_line = convert_422_420;
+ } else if (vf->format == COG_FRAME_FORMAT_U8_444 &&
+ format == COG_FRAME_FORMAT_U8_422) {
+ render_line = convert_444_422;
+ } else if (vf->format == COG_FRAME_FORMAT_U8_420 &&
+ format == COG_FRAME_FORMAT_U8_422) {
+ render_line = convert_420_422;
+ } else if (vf->format == COG_FRAME_FORMAT_U8_420 &&
+ format == COG_FRAME_FORMAT_U8_444) {
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_422,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = convert_420_422;
+ vf = virt_frame;
+
+ render_line = convert_422_444;
+ } else if (vf->format == COG_FRAME_FORMAT_U8_422 &&
+ format == COG_FRAME_FORMAT_U8_444) {
+ render_line = convert_422_444;
+ } else {
+ COG_ASSERT (0);
+ return NULL;
+ }
+ virt_frame = cog_frame_new_virtual (NULL, format, vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = render_line;
+
+ return virt_frame;
+}
+
+
+static void
+convert_u8_s16 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ int16_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ orc_addc_convert_u8_s16 (dest, frame->virt_priv,
+ frame->components[component].width);
+}
+
+CogFrame *
+cog_virt_frame_new_convert_u8 (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+ CogFrameFormat format;
+
+ format = (vf->format & 3) | COG_FRAME_FORMAT_U8_444;
+
+ virt_frame = cog_frame_new_virtual (NULL, format, vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = convert_u8_s16;
+ virt_frame->virt_priv = cog_malloc (sizeof (int16_t) * vf->width);
+
+ return virt_frame;
+}
+
+static void
+convert_s16_u8 (CogFrame * frame, void *_dest, int component, int i)
+{
+ int16_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+
+ orc_subc_convert_s16_u8 (dest, src, frame->components[component].width);
+}
+
+CogFrame *
+cog_virt_frame_new_convert_s16 (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+ CogFrameFormat format;
+
+ format = (vf->format & 3) | COG_FRAME_FORMAT_S16_444;
+
+ virt_frame = cog_frame_new_virtual (NULL, format, vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = convert_s16_u8;
+
+ return virt_frame;
+}
+
+static void
+crop_u8 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ orc_memcpy (dest, src, frame->components[component].width);
+}
+
+static void
+crop_s16 (CogFrame * frame, void *_dest, int component, int i)
+{
+ int16_t *dest = _dest;
+ int16_t *src;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component, i);
+ orc_memcpy (dest, src, frame->components[component].width * sizeof (int16_t));
+}
+
+CogFrame *
+cog_virt_frame_new_crop (CogFrame * vf, int width, int height)
+{
+ CogFrame *virt_frame;
+
+ if (width == vf->width && height == vf->height)
+ return vf;
+
+ COG_ASSERT (width <= vf->width);
+ COG_ASSERT (height <= vf->height);
+
+ virt_frame = cog_frame_new_virtual (NULL, vf->format, width, height);
+ virt_frame->virt_frame1 = vf;
+ switch (COG_FRAME_FORMAT_DEPTH (vf->format)) {
+ case COG_FRAME_FORMAT_DEPTH_U8:
+ virt_frame->render_line = crop_u8;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S16:
+ virt_frame->render_line = crop_s16;
+ break;
+ default:
+ COG_ASSERT (0);
+ break;
+ }
+
+ return virt_frame;
+}
+
+static void
+edge_extend_u8 (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ CogFrame *srcframe = frame->virt_frame1;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component,
+ MIN (i, srcframe->components[component].height - 1));
+ orc_memcpy (dest, src, srcframe->components[component].width);
+ orc_splat_u8_ns (dest + srcframe->components[component].width,
+ dest[srcframe->components[component].width - 1],
+ frame->components[component].width -
+ srcframe->components[component].width);
+}
+
+static void
+edge_extend_s16 (CogFrame * frame, void *_dest, int component, int i)
+{
+ int16_t *dest = _dest;
+ int16_t *src;
+ CogFrame *srcframe = frame->virt_frame1;
+
+ src = cog_virt_frame_get_line (frame->virt_frame1, component,
+ MIN (i, srcframe->components[component].height - 1));
+ orc_memcpy (dest, src,
+ srcframe->components[component].width * sizeof (int16_t));
+ orc_splat_s16_ns (dest + srcframe->components[component].width,
+ dest[srcframe->components[component].width - 1],
+ frame->components[component].width -
+ srcframe->components[component].width);
+}
+
+CogFrame *
+cog_virt_frame_new_edgeextend (CogFrame * vf, int width, int height)
+{
+ CogFrame *virt_frame;
+
+ if (width == vf->width && height == vf->height)
+ return vf;
+
+ COG_ASSERT (width >= vf->width);
+ COG_ASSERT (height >= vf->height);
+
+ virt_frame = cog_frame_new_virtual (NULL, vf->format, width, height);
+ virt_frame->virt_frame1 = vf;
+ switch (COG_FRAME_FORMAT_DEPTH (vf->format)) {
+ case COG_FRAME_FORMAT_DEPTH_U8:
+ virt_frame->render_line = edge_extend_u8;
+ break;
+ case COG_FRAME_FORMAT_DEPTH_S16:
+ virt_frame->render_line = edge_extend_s16;
+ break;
+ default:
+ COG_ASSERT (0);
+ break;
+ }
+
+ return virt_frame;
+}
+
+
+
+static void
+pack_RGBx (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_123x (dest, src_r, src_g, src_b, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_RGBx (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_RGBx,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_RGBx;
+
+ return virt_frame;
+}
+
+static void
+pack_xRGB (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_x123 (dest, src_r, src_g, src_b, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_xRGB (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_xRGB,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_xRGB;
+
+ return virt_frame;
+}
+
+static void
+pack_BGRx (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_123x (dest, src_b, src_g, src_r, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_BGRx (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_BGRx,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_BGRx;
+
+ return virt_frame;
+}
+
+static void
+pack_xBGR (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_x123 (dest, src_b, src_g, src_r, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_xBGR (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_xBGR,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_xBGR;
+
+ return virt_frame;
+}
+
+static void
+pack_RGBA (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_123x (dest, src_r, src_g, src_b, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_RGBA (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_RGBA,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_RGBA;
+
+ return virt_frame;
+}
+
+static void
+pack_ARGB (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_x123 (dest, src_r, src_g, src_b, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_ARGB (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_ARGB,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_ARGB;
+
+ return virt_frame;
+}
+
+static void
+pack_BGRA (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_123x (dest, src_b, src_g, src_r, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_BGRA (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_BGRA,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_BGRA;
+
+ return virt_frame;
+}
+
+static void
+pack_ABGR (CogFrame * frame, void *_dest, int component, int i)
+{
+ uint32_t *dest = _dest;
+ uint8_t *src_r;
+ uint8_t *src_g;
+ uint8_t *src_b;
+
+ src_r = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
+ src_g = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
+ src_b = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
+
+ orc_pack_x123 (dest, src_b, src_g, src_r, 0xff, frame->width);
+}
+
+CogFrame *
+cog_virt_frame_new_pack_ABGR (CogFrame * vf)
+{
+ CogFrame *virt_frame;
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_ABGR,
+ vf->width, vf->height);
+ virt_frame->virt_frame1 = vf;
+ virt_frame->render_line = pack_ABGR;
+
+ return virt_frame;
+}
diff --git a/ext/cog/cogvirtframe.h b/ext/cog/cogvirtframe.h
new file mode 100644
index 000000000..83b476a8b
--- /dev/null
+++ b/ext/cog/cogvirtframe.h
@@ -0,0 +1,50 @@
+
+#ifndef __COG_VIRT_FRAME_H__
+#define __COG_VIRT_FRAME_H__
+
+#include <cog/cogutils.h>
+#include <cog-video/cogframe.h>
+
+COG_BEGIN_DECLS
+
+CogFrame *cog_frame_new_virtual (CogMemoryDomain *domain,
+ CogFrameFormat format, int width, int height);
+
+void *cog_virt_frame_get_line (CogFrame *frame, int component, int i);
+void cog_virt_frame_render_line (CogFrame *frame, void *dest,
+ int component, int i);
+
+void cog_virt_frame_render (CogFrame *frame, CogFrame *dest);
+
+CogFrame *cog_virt_frame_new_horiz_downsample (CogFrame *vf, int n_taps);
+CogFrame *cog_virt_frame_new_vert_downsample (CogFrame *vf, int n_taps);
+CogFrame *cog_virt_frame_new_vert_resample (CogFrame *vf, int height);
+CogFrame *cog_virt_frame_new_horiz_resample (CogFrame *vf, int width);
+CogFrame *cog_virt_frame_new_unpack (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_YUY2 (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_UYVY (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_AYUV (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_v216 (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_v210 (CogFrame *vf);
+CogFrame *cog_virt_frame_new_pack_RGB (CogFrame *vf);
+CogFrame *cog_virt_frame_new_color_matrix (CogFrame *vf);
+CogFrame *cog_virt_frame_new_subsample (CogFrame *vf, CogFrameFormat format);
+
+CogFrame * cog_virt_frame_new_convert_u8 (CogFrame *vf);
+CogFrame * cog_virt_frame_new_convert_s16 (CogFrame *vf);
+CogFrame * cog_virt_frame_new_crop (CogFrame *vf, int width, int height);
+CogFrame * cog_virt_frame_new_edgeextend (CogFrame *vf, int width, int height);
+
+CogFrame * cog_virt_frame_new_pack_RGBx (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_xRGB (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_BGRx (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_xBGR (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_RGBA (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_ARGB (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_BGRA (CogFrame *vf);
+CogFrame * cog_virt_frame_new_pack_ABGR (CogFrame *vf);
+
+COG_END_DECLS
+
+#endif
+
diff --git a/ext/cog/gstcog.c b/ext/cog/gstcog.c
new file mode 100644
index 000000000..45b441c95
--- /dev/null
+++ b/ext/cog/gstcog.c
@@ -0,0 +1,75 @@
+/* GStreamer
+ * Copyright (C) 2007 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <gst/gst.h>
+#include <cog/cog.h>
+
+#include "gstjpegdec.h"
+
+//GType gst_dither_get_type (void);
+GType gst_deblock_get_type (void);
+GType gst_cogdownsample_get_type (void);
+GType gst_motion_detect_get_type (void);
+GType gst_cogcolorspace_get_type (void);
+GType gst_cog_scale_get_type (void);
+GType gst_colorconvert_get_type (void);
+GType gst_logoinsert_get_type (void);
+GType gst_mse_get_type (void);
+GType gst_decimate_get_type (void);
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ cog_init ();
+
+ gst_element_register (plugin, "cogjpegdec", GST_RANK_PRIMARY,
+ GST_TYPE_JPEG_DEC);
+ //gst_element_register (plugin, "dither", GST_RANK_NONE,
+ // gst_dither_get_type());
+ gst_element_register (plugin, "deblock", GST_RANK_NONE,
+ gst_deblock_get_type ());
+ gst_element_register (plugin, "cogdownsample", GST_RANK_NONE,
+ gst_cogdownsample_get_type ());
+ gst_element_register (plugin, "motiondetect", GST_RANK_NONE,
+ gst_motion_detect_get_type ());
+ gst_element_register (plugin, "cogcolorspace", GST_RANK_NONE,
+ gst_cogcolorspace_get_type ());
+ gst_element_register (plugin, "cogscale", GST_RANK_NONE,
+ gst_cog_scale_get_type ());
+ gst_element_register (plugin, "colorconvert", GST_RANK_NONE,
+ gst_colorconvert_get_type ());
+ gst_element_register (plugin, "coglogoinsert", GST_RANK_NONE,
+ gst_logoinsert_get_type ());
+ gst_element_register (plugin, "cogmse", GST_RANK_NONE, gst_mse_get_type ());
+ gst_element_register (plugin, "cogdecimate", GST_RANK_NONE,
+ gst_decimate_get_type ());
+
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "cog",
+ "Cog plugin",
+ plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/cog/gstcogcolorspace.c b/ext/cog/gstcogcolorspace.c
new file mode 100644
index 000000000..e2d968394
--- /dev/null
+++ b/ext/cog/gstcogcolorspace.c
@@ -0,0 +1,485 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file was (probably) generated from
+ * gstvideotemplate.c,v 1.18 2005/11/14 02:13:34 thomasvs Exp
+ * and
+ * $Id: make_filter,v 1.8 2004/04/19 22:51:57 ds Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <cog/cog.h>
+#include <math.h>
+#include <cog-video/cogvirtframe.h>
+#include "gstcogutils.h"
+
+#define GST_TYPE_COGCOLORSPACE \
+ (gst_cogcolorspace_get_type())
+#define GST_COGCOLORSPACE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COGCOLORSPACE,GstCogcolorspace))
+#define GST_COGCOLORSPACE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COGCOLORSPACE,GstCogcolorspaceClass))
+#define GST_IS_COGCOLORSPACE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COGCOLORSPACE))
+#define GST_IS_COGCOLORSPACE_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COGCOLORSPACE))
+
+typedef struct _GstCogcolorspace GstCogcolorspace;
+typedef struct _GstCogcolorspaceClass GstCogcolorspaceClass;
+
+struct _GstCogcolorspace
+{
+ GstBaseTransform base_transform;
+
+};
+
+struct _GstCogcolorspaceClass
+{
+ GstBaseTransformClass parent_class;
+
+};
+
+GType gst_cogcolorspace_get_type (void);
+
+/* GstCogcolorspace signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+ ARG_WAVELET_TYPE,
+ ARG_LEVEL
+ /* FILL ME */
+};
+
+static void gst_cogcolorspace_base_init (gpointer g_class);
+static void gst_cogcolorspace_class_init (gpointer g_class,
+ gpointer class_data);
+static void gst_cogcolorspace_init (GTypeInstance * instance, gpointer g_class);
+
+static void gst_cogcolorspace_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_cogcolorspace_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_cogcolorspace_transform_caps (GstBaseTransform *
+ base_transform, GstPadDirection direction, GstCaps * caps);
+static GstFlowReturn gst_cogcolorspace_transform (GstBaseTransform *
+ base_transform, GstBuffer * inbuf, GstBuffer * outbuf);
+static gboolean gst_cogcolorspace_get_unit_size (GstBaseTransform *
+ base_transform, GstCaps * caps, guint * size);
+
+static GstStaticPadTemplate gst_cogcolorspace_sink_template =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV
+ ("{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444, v216, v210 }")
+ ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB
+ ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA
+ ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR)
+ );
+
+static GstStaticPadTemplate gst_cogcolorspace_src_template =
+ GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV
+ ("{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444, v216, v210 }")
+ ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB
+ ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA
+ ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR)
+ );
+
+GType
+gst_cogcolorspace_get_type (void)
+{
+ static GType compress_type = 0;
+
+ if (!compress_type) {
+ static const GTypeInfo compress_info = {
+ sizeof (GstCogcolorspaceClass),
+ gst_cogcolorspace_base_init,
+ NULL,
+ gst_cogcolorspace_class_init,
+ NULL,
+ NULL,
+ sizeof (GstCogcolorspace),
+ 0,
+ gst_cogcolorspace_init,
+ };
+
+ compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
+ "GstCogcolorspace", &compress_info, 0);
+ }
+ return compress_type;
+}
+
+
+static void
+gst_cogcolorspace_base_init (gpointer g_class)
+{
+ static GstElementDetails compress_details =
+ GST_ELEMENT_DETAILS ("YCbCr format conversion",
+ "Filter/Effect/Video",
+ "YCbCr format conversion",
+ "David Schleef <ds@schleef.org>");
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ //GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cogcolorspace_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cogcolorspace_sink_template));
+
+ gst_element_class_set_details (element_class, &compress_details);
+}
+
+static void
+gst_cogcolorspace_class_init (gpointer g_class, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *base_transform_class;
+ GstCogcolorspaceClass *colorspace_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+ colorspace_class = GST_COGCOLORSPACE_CLASS (g_class);
+
+ gobject_class->set_property = gst_cogcolorspace_set_property;
+ gobject_class->get_property = gst_cogcolorspace_get_property;
+
+#if 0
+ g_object_class_install_property (gobject_class, ARG_WAVELET_TYPE,
+ g_param_spec_int ("wavelet-type", "wavelet type", "wavelet type",
+ 0, 4, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_LEVEL,
+ g_param_spec_int ("level", "level", "level",
+ 0, 100, 0, G_PARAM_READWRITE));
+#endif
+
+ base_transform_class->transform = gst_cogcolorspace_transform;
+ base_transform_class->transform_caps = gst_cogcolorspace_transform_caps;
+ base_transform_class->get_unit_size = gst_cogcolorspace_get_unit_size;
+}
+
+static void
+gst_cogcolorspace_init (GTypeInstance * instance, gpointer g_class)
+{
+ //GstCogcolorspace *compress = GST_COGCOLORSPACE (instance);
+ //GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
+
+ GST_DEBUG ("gst_cogcolorspace_init");
+}
+
+static void
+gst_cogcolorspace_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstCogcolorspace *src;
+
+ g_return_if_fail (GST_IS_COGCOLORSPACE (object));
+ src = GST_COGCOLORSPACE (object);
+
+ GST_DEBUG ("gst_cogcolorspace_set_property");
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_cogcolorspace_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstCogcolorspace *src;
+
+ g_return_if_fail (GST_IS_COGCOLORSPACE (object));
+ src = GST_COGCOLORSPACE (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+#if 0
+static void
+transform_value (GValue * dest)
+{
+ GValue fourcc = { 0 };
+
+ g_value_init (dest, GST_TYPE_LIST);
+ g_value_init (&fourcc, GST_TYPE_FOURCC);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('I', '4', '2', '0'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', 'V', '1', '2'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', '4', '2', 'B'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', '4', '4', '4'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('v', '2', '1', '0'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('v', '2', '1', '6'));
+ gst_value_list_append_value (dest, &fourcc);
+
+ g_value_unset (&fourcc);
+}
+#endif
+
+static GstCaps *
+gst_cogcolorspace_caps_remove_format_info (GstCaps * caps)
+{
+ int i;
+ GstStructure *structure;
+ GstCaps *rgbcaps;
+
+ caps = gst_caps_copy (caps);
+
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+
+ gst_structure_set_name (structure, "video/x-raw-yuv");
+ gst_structure_remove_field (structure, "format");
+ gst_structure_remove_field (structure, "endianness");
+ gst_structure_remove_field (structure, "depth");
+ gst_structure_remove_field (structure, "bpp");
+ gst_structure_remove_field (structure, "red_mask");
+ gst_structure_remove_field (structure, "green_mask");
+ gst_structure_remove_field (structure, "blue_mask");
+ gst_structure_remove_field (structure, "alpha_mask");
+ gst_structure_remove_field (structure, "palette_data");
+ }
+
+ gst_caps_do_simplify (caps);
+ rgbcaps = gst_caps_copy (caps);
+
+ for (i = 0; i < gst_caps_get_size (rgbcaps); i++) {
+ structure = gst_caps_get_structure (rgbcaps, i);
+
+ gst_structure_set_name (structure, "video/x-raw-rgb");
+ }
+
+ gst_caps_append (caps, rgbcaps);
+
+ return caps;
+}
+
+static GstCaps *
+gst_cogcolorspace_transform_caps (GstBaseTransform * base_transform,
+ GstPadDirection direction, GstCaps * caps)
+{
+#if 0
+ int i;
+ GstStructure *structure;
+ GValue new_value = { 0 };
+ const GValue *value;
+
+ caps = gst_caps_copy (caps);
+
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+
+ value = gst_structure_get_value (structure, "format");
+ transform_value (&new_value);
+ gst_structure_set_value (structure, "format", &new_value);
+ g_value_unset (&new_value);
+ }
+
+ return caps;
+#endif
+#if 0
+ GstCaps *template;
+ GstCaps *result;
+
+ template = gst_ffmpegcsp_codectype_to_caps (CODEC_TYPE_VIDEO, NULL);
+ result = gst_caps_intersect (caps, template);
+ gst_caps_unref (template);
+
+ gst_caps_append (result, gst_ffmpegcsp_caps_remove_format_info (caps));
+
+ return result;
+#endif
+ return gst_cogcolorspace_caps_remove_format_info (caps);
+}
+
+static gboolean
+gst_cogcolorspace_get_unit_size (GstBaseTransform * base_transform,
+ GstCaps * caps, guint * size)
+{
+ int width, height;
+ GstVideoFormat format;
+ gboolean ret;
+
+ ret = gst_video_format_parse_caps (caps, &format, &width, &height);
+ if (!ret)
+ return FALSE;
+
+ *size = gst_video_format_get_size (format, width, height);
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_cogcolorspace_transform (GstBaseTransform * base_transform,
+ GstBuffer * inbuf, GstBuffer * outbuf)
+{
+ GstCogcolorspace *compress;
+ CogFrame *out_frame;
+ CogFrame *frame;
+ int width, height;
+ uint32_t in_format;
+ uint32_t out_format;
+ CogFrameFormat new_subsample;
+ gboolean ret;
+
+ g_return_val_if_fail (GST_IS_COGCOLORSPACE (base_transform), GST_FLOW_ERROR);
+ compress = GST_COGCOLORSPACE (base_transform);
+
+ ret = gst_video_format_parse_caps (inbuf->caps, &in_format, &width, &height);
+ ret |=
+ gst_video_format_parse_caps (outbuf->caps, &out_format, &width, &height);
+ if (!ret) {
+ return GST_FLOW_ERROR;
+ }
+
+ frame = gst_cog_buffer_wrap (gst_buffer_ref (inbuf),
+ in_format, width, height);
+ out_frame = gst_cog_buffer_wrap (gst_buffer_ref (outbuf),
+ out_format, width, height);
+
+ switch (out_format) {
+ case GST_VIDEO_FORMAT_YUY2:
+ case GST_VIDEO_FORMAT_UYVY:
+ case GST_VIDEO_FORMAT_YVYU:
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_v210:
+ case GST_VIDEO_FORMAT_v216:
+ new_subsample = COG_FRAME_FORMAT_U8_422;
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ new_subsample = COG_FRAME_FORMAT_U8_420;
+ break;
+ case GST_VIDEO_FORMAT_Y444:
+ case GST_VIDEO_FORMAT_RGBx:
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_BGRx:
+ case GST_VIDEO_FORMAT_xBGR:
+ case GST_VIDEO_FORMAT_RGBA:
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_ABGR:
+ default:
+ new_subsample = COG_FRAME_FORMAT_U8_444;
+ break;
+ }
+
+ frame = cog_virt_frame_new_unpack (frame);
+ frame = cog_virt_frame_new_subsample (frame, new_subsample);
+
+ if (gst_video_format_is_rgb (out_format) &&
+ gst_video_format_is_yuv (in_format)) {
+ frame = cog_virt_frame_new_color_matrix (frame);
+ }
+ if (gst_video_format_is_yuv (out_format) &&
+ gst_video_format_is_rgb (in_format)) {
+ GST_ERROR ("not supported!");
+ }
+
+ switch (out_format) {
+ case GST_VIDEO_FORMAT_YUY2:
+ frame = cog_virt_frame_new_pack_YUY2 (frame);
+ break;
+ case GST_VIDEO_FORMAT_UYVY:
+ frame = cog_virt_frame_new_pack_UYVY (frame);
+ break;
+ case GST_VIDEO_FORMAT_AYUV:
+ frame = cog_virt_frame_new_pack_AYUV (frame);
+ break;
+ case GST_VIDEO_FORMAT_v216:
+ frame = cog_virt_frame_new_pack_v216 (frame);
+ break;
+ case GST_VIDEO_FORMAT_v210:
+ frame = cog_virt_frame_new_pack_v210 (frame);
+ break;
+ case GST_VIDEO_FORMAT_RGBx:
+ frame = cog_virt_frame_new_pack_RGBx (frame);
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ frame = cog_virt_frame_new_pack_xRGB (frame);
+ break;
+ case GST_VIDEO_FORMAT_BGRx:
+ frame = cog_virt_frame_new_pack_BGRx (frame);
+ break;
+ case GST_VIDEO_FORMAT_xBGR:
+ frame = cog_virt_frame_new_pack_xBGR (frame);
+ break;
+ case GST_VIDEO_FORMAT_RGBA:
+ frame = cog_virt_frame_new_pack_RGBA (frame);
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ frame = cog_virt_frame_new_pack_ARGB (frame);
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ frame = cog_virt_frame_new_pack_BGRA (frame);
+ break;
+ case GST_VIDEO_FORMAT_ABGR:
+ frame = cog_virt_frame_new_pack_ABGR (frame);
+ break;
+ default:
+ break;
+ }
+
+ cog_virt_frame_render (frame, out_frame);
+ cog_frame_unref (frame);
+ cog_frame_unref (out_frame);
+
+ return GST_FLOW_OK;
+}
diff --git a/ext/cog/gstcogdownsample.c b/ext/cog/gstcogdownsample.c
new file mode 100644
index 000000000..682e94f52
--- /dev/null
+++ b/ext/cog/gstcogdownsample.c
@@ -0,0 +1,412 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file was (probably) generated from
+ * gstvideotemplate.c,v 1.18 2005/11/14 02:13:34 thomasvs Exp
+ * and
+ * $Id: make_filter,v 1.8 2004/04/19 22:51:57 ds Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <cog/cog.h>
+#include <math.h>
+#include <cog-video/cogvirtframe.h>
+
+#define GST_TYPE_COGDOWNSAMPLE \
+ (gst_cogdownsample_get_type())
+#define GST_COGDOWNSAMPLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COGDOWNSAMPLE,GstCogdownsample))
+#define GST_COGDOWNSAMPLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COGDOWNSAMPLE,GstCogdownsampleClass))
+#define GST_IS_COGDOWNSAMPLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COGDOWNSAMPLE))
+#define GST_IS_COGDOWNSAMPLE_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COGDOWNSAMPLE))
+
+typedef struct _GstCogdownsample GstCogdownsample;
+typedef struct _GstCogdownsampleClass GstCogdownsampleClass;
+
+struct _GstCogdownsample
+{
+ GstBaseTransform base_transform;
+
+ //CogVideoFormat format;
+};
+
+struct _GstCogdownsampleClass
+{
+ GstBaseTransformClass parent_class;
+
+};
+
+GType gst_cogdownsample_get_type (void);
+
+/* GstCogdownsample signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+ ARG_WAVELET_TYPE,
+ ARG_LEVEL
+ /* FILL ME */
+};
+
+static void gst_cogdownsample_base_init (gpointer g_class);
+static void gst_cogdownsample_class_init (gpointer g_class,
+ gpointer class_data);
+static void gst_cogdownsample_init (GTypeInstance * instance, gpointer g_class);
+
+static void gst_cogdownsample_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_cogdownsample_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_cogdownsample_transform_caps (GstBaseTransform *
+ base_transform, GstPadDirection direction, GstCaps * caps);
+static GstFlowReturn gst_cogdownsample_transform (GstBaseTransform *
+ base_transform, GstBuffer * inbuf, GstBuffer * outbuf);
+static gboolean gst_cogdownsample_get_unit_size (GstBaseTransform *
+ base_transform, GstCaps * caps, guint * size);
+
+static GstStaticPadTemplate gst_cogdownsample_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
+ );
+
+static GstStaticPadTemplate gst_cogdownsample_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
+ );
+
+GType
+gst_cogdownsample_get_type (void)
+{
+ static GType compress_type = 0;
+
+ if (!compress_type) {
+ static const GTypeInfo compress_info = {
+ sizeof (GstCogdownsampleClass),
+ gst_cogdownsample_base_init,
+ NULL,
+ gst_cogdownsample_class_init,
+ NULL,
+ NULL,
+ sizeof (GstCogdownsample),
+ 0,
+ gst_cogdownsample_init,
+ };
+
+ compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
+ "GstCogdownsample", &compress_info, 0);
+ }
+ return compress_type;
+}
+
+
+static void
+gst_cogdownsample_base_init (gpointer g_class)
+{
+ static GstElementDetails compress_details =
+ GST_ELEMENT_DETAILS ("Downsample video",
+ "Filter/Effect/Video",
+ "Decreases size of video by a factor of 2",
+ "David Schleef <ds@schleef.org>");
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ //GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cogdownsample_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cogdownsample_sink_template));
+
+ gst_element_class_set_details (element_class, &compress_details);
+}
+
+static void
+gst_cogdownsample_class_init (gpointer g_class, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *base_transform_class;
+ GstCogdownsampleClass *downsample_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+ downsample_class = GST_COGDOWNSAMPLE_CLASS (g_class);
+
+ gobject_class->set_property = gst_cogdownsample_set_property;
+ gobject_class->get_property = gst_cogdownsample_get_property;
+
+#if 0
+ g_object_class_install_property (gobject_class, ARG_WAVELET_TYPE,
+ g_param_spec_int ("wavelet-type", "wavelet type", "wavelet type",
+ 0, 4, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_LEVEL,
+ g_param_spec_int ("level", "level", "level",
+ 0, 100, 0, G_PARAM_READWRITE));
+#endif
+
+ base_transform_class->transform = gst_cogdownsample_transform;
+ base_transform_class->transform_caps = gst_cogdownsample_transform_caps;
+ base_transform_class->get_unit_size = gst_cogdownsample_get_unit_size;
+}
+
+static void
+gst_cogdownsample_init (GTypeInstance * instance, gpointer g_class)
+{
+ //GstCogdownsample *compress = GST_COGDOWNSAMPLE (instance);
+ //GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
+
+ GST_DEBUG ("gst_cogdownsample_init");
+}
+
+static void
+gst_cogdownsample_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstCogdownsample *src;
+
+ g_return_if_fail (GST_IS_COGDOWNSAMPLE (object));
+ src = GST_COGDOWNSAMPLE (object);
+
+ GST_DEBUG ("gst_cogdownsample_set_property");
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_cogdownsample_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstCogdownsample *src;
+
+ g_return_if_fail (GST_IS_COGDOWNSAMPLE (object));
+ src = GST_COGDOWNSAMPLE (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+transform_value (GValue * dest, const GValue * src, GstPadDirection dir)
+{
+ g_value_init (dest, G_VALUE_TYPE (src));
+
+ if (G_VALUE_HOLDS_INT (src)) {
+ int x;
+
+ x = g_value_get_int (src);
+ if (dir == GST_PAD_SINK) {
+ g_value_set_int (dest, x / 2);
+ } else {
+ g_value_set_int (dest, x * 2);
+ }
+ } else if (GST_VALUE_HOLDS_INT_RANGE (src)) {
+ int min, max;
+
+ min = gst_value_get_int_range_min (src);
+ max = gst_value_get_int_range_max (src);
+
+ if (dir == GST_PAD_SINK) {
+ min = (min + 1) / 2;
+ if (max == G_MAXINT) {
+ max = G_MAXINT / 2;
+ } else {
+ max = (max + 1) / 2;
+ }
+ } else {
+ if (max > G_MAXINT / 2) {
+ max = G_MAXINT;
+ } else {
+ max = max * 2;
+ }
+ if (min > G_MAXINT / 2) {
+ min = G_MAXINT;
+ } else {
+ min = min * 2;
+ }
+ }
+ gst_value_set_int_range (dest, min, max);
+ } else {
+ /* FIXME */
+ g_warning ("case not handled");
+ g_value_set_int (dest, 100);
+ }
+}
+
+static GstCaps *
+gst_cogdownsample_transform_caps (GstBaseTransform * base_transform,
+ GstPadDirection direction, GstCaps * caps)
+{
+ int i;
+ GstStructure *structure;
+ GValue new_value = { 0 };
+ const GValue *value;
+
+ caps = gst_caps_copy (caps);
+
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+
+ value = gst_structure_get_value (structure, "width");
+ transform_value (&new_value, value, direction);
+ gst_structure_set_value (structure, "width", &new_value);
+ g_value_unset (&new_value);
+
+ value = gst_structure_get_value (structure, "height");
+ transform_value (&new_value, value, direction);
+ gst_structure_set_value (structure, "height", &new_value);
+ g_value_unset (&new_value);
+ }
+
+ return caps;
+}
+
+static gboolean
+gst_cogdownsample_get_unit_size (GstBaseTransform * base_transform,
+ GstCaps * caps, guint * size)
+{
+ int width, height;
+ uint32_t format;
+
+ gst_structure_get_fourcc (gst_caps_get_structure (caps, 0),
+ "format", &format);
+ gst_structure_get_int (gst_caps_get_structure (caps, 0), "width", &width);
+ gst_structure_get_int (gst_caps_get_structure (caps, 0), "height", &height);
+
+ switch (format) {
+ case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+ case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+ *size = width * height * 3 / 2;
+ break;
+ case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+ case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+ *size = width * height * 2;
+ break;
+ case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
+ *size = width * height * 4;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_cogdownsample_transform (GstBaseTransform * base_transform,
+ GstBuffer * inbuf, GstBuffer * outbuf)
+{
+ GstCogdownsample *compress;
+ CogFrame *outframe;
+ int width, height;
+ uint32_t format;
+ CogFrame *frame;
+
+ g_return_val_if_fail (GST_IS_COGDOWNSAMPLE (base_transform), GST_FLOW_ERROR);
+ compress = GST_COGDOWNSAMPLE (base_transform);
+
+ gst_structure_get_fourcc (gst_caps_get_structure (inbuf->caps, 0),
+ "format", &format);
+ gst_structure_get_int (gst_caps_get_structure (inbuf->caps, 0),
+ "width", &width);
+ gst_structure_get_int (gst_caps_get_structure (inbuf->caps, 0),
+ "height", &height);
+
+ switch (format) {
+ case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+ frame = cog_frame_new_from_data_I420 (GST_BUFFER_DATA (inbuf),
+ width, height);
+ outframe = cog_frame_new_from_data_I420 (GST_BUFFER_DATA (outbuf),
+ width / 2, height / 2);
+ break;
+ case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+ frame = cog_frame_new_from_data_YV12 (GST_BUFFER_DATA (inbuf),
+ width, height);
+ outframe = cog_frame_new_from_data_YV12 (GST_BUFFER_DATA (outbuf),
+ width / 2, height / 2);
+ break;
+ case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+ frame = cog_frame_new_from_data_YUY2 (GST_BUFFER_DATA (inbuf),
+ width, height);
+ outframe = cog_frame_new_from_data_YUY2 (GST_BUFFER_DATA (outbuf),
+ width / 2, height / 2);
+ break;
+ case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+ frame = cog_frame_new_from_data_UYVY (GST_BUFFER_DATA (inbuf),
+ width, height);
+ outframe = cog_frame_new_from_data_UYVY (GST_BUFFER_DATA (outbuf),
+ width / 2, height / 2);
+ break;
+ case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
+ frame = cog_frame_new_from_data_AYUV (GST_BUFFER_DATA (inbuf),
+ width, height);
+ outframe = cog_frame_new_from_data_AYUV (GST_BUFFER_DATA (outbuf),
+ width / 2, height / 2);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ frame = cog_virt_frame_new_unpack (frame);
+ frame = cog_virt_frame_new_horiz_downsample (frame, 3);
+ frame = cog_virt_frame_new_vert_downsample (frame, 2);
+
+ switch (format) {
+ case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+ frame = cog_virt_frame_new_pack_YUY2 (frame);
+ break;
+ case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+ frame = cog_virt_frame_new_pack_UYVY (frame);
+ break;
+ case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
+ frame = cog_virt_frame_new_pack_AYUV (frame);
+ break;
+ default:
+ break;
+ }
+
+ cog_virt_frame_render (frame, outframe);
+ cog_frame_unref (frame);
+ cog_frame_unref (outframe);
+
+ return GST_FLOW_OK;
+}
diff --git a/ext/cog/gstcogfilter.c b/ext/cog/gstcogfilter.c
new file mode 100644
index 000000000..0281db757
--- /dev/null
+++ b/ext/cog/gstcogfilter.c
@@ -0,0 +1,265 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file was (probably) generated from
+ * gstvideotemplate.c,v 1.18 2005/11/14 02:13:34 thomasvs Exp
+ * and
+ * $Id: make_filter,v 1.8 2004/04/19 22:51:57 ds Exp $
+ */
+
+#define SCHRO_ENABLE_UNSTABLE_API
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <schroedinger/schro.h>
+#include <schroedinger/schrotables.h>
+#include <liboil/liboil.h>
+#include <math.h>
+
+#define GST_TYPE_SCHROFILTER \
+ (gst_schrofilter_get_type())
+#define GST_SCHROFILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SCHROFILTER,GstSchrofilter))
+#define GST_SCHROFILTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SCHROFILTER,GstSchrofilterClass))
+#define GST_IS_SCHROFILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SCHROFILTER))
+#define GST_IS_SCHROFILTER_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHROFILTER))
+
+typedef struct _GstSchrofilter GstSchrofilter;
+typedef struct _GstSchrofilterClass GstSchrofilterClass;
+
+struct _GstSchrofilter
+{
+ GstBaseTransform base_transform;
+
+ int wavelet_type;
+ int level;
+
+ SchroVideoFormat format;
+
+ SchroFrame *tmp_frame;
+ int16_t *tmpbuf;
+
+ int frame_number;
+
+};
+
+struct _GstSchrofilterClass
+{
+ GstBaseTransformClass parent_class;
+
+};
+
+
+/* GstSchrofilter signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+ ARG_WAVELET_TYPE,
+ ARG_LEVEL
+ /* FILL ME */
+};
+
+GType gst_schrofilter_get_type (void);
+
+static void gst_schrofilter_base_init (gpointer g_class);
+static void gst_schrofilter_class_init (gpointer g_class, gpointer class_data);
+static void gst_schrofilter_init (GTypeInstance * instance, gpointer g_class);
+
+static void gst_schrofilter_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_schrofilter_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstFlowReturn gst_schrofilter_transform_ip (GstBaseTransform *
+ base_transform, GstBuffer * buf);
+
+static GstStaticPadTemplate gst_schrofilter_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
+ );
+
+static GstStaticPadTemplate gst_schrofilter_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
+ );
+
+GType
+gst_schrofilter_get_type (void)
+{
+ static GType compress_type = 0;
+
+ if (!compress_type) {
+ static const GTypeInfo compress_info = {
+ sizeof (GstSchrofilterClass),
+ gst_schrofilter_base_init,
+ NULL,
+ gst_schrofilter_class_init,
+ NULL,
+ NULL,
+ sizeof (GstSchrofilter),
+ 0,
+ gst_schrofilter_init,
+ };
+
+ compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
+ "GstSchrofilter", &compress_info, 0);
+ }
+ return compress_type;
+}
+
+
+static void
+gst_schrofilter_base_init (gpointer g_class)
+{
+ static GstElementDetails compress_details =
+ GST_ELEMENT_DETAILS ("Schroedinger Video Filters",
+ "Filter/Effect/Video",
+ "Applies a Schroedinger compression pre-filter to video",
+ "David Schleef <ds@schleef.org>");
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ //GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_schrofilter_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_schrofilter_sink_template));
+
+ gst_element_class_set_details (element_class, &compress_details);
+}
+
+static void
+gst_schrofilter_class_init (gpointer g_class, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *base_transform_class;
+ GstSchrofilterClass *filter_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+ filter_class = GST_SCHROFILTER_CLASS (g_class);
+
+ gobject_class->set_property = gst_schrofilter_set_property;
+ gobject_class->get_property = gst_schrofilter_get_property;
+
+ g_object_class_install_property (gobject_class, ARG_WAVELET_TYPE,
+ g_param_spec_int ("wavelet-type", "wavelet type", "wavelet type",
+ 0, 4, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_LEVEL,
+ g_param_spec_int ("level", "level", "level",
+ 0, 100, 0, G_PARAM_READWRITE));
+
+ base_transform_class->transform_ip = gst_schrofilter_transform_ip;
+}
+
+static void
+gst_schrofilter_init (GTypeInstance * instance, gpointer g_class)
+{
+ //GstSchrofilter *compress = GST_SCHROFILTER (instance);
+ //GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
+
+ GST_DEBUG ("gst_schrofilter_init");
+}
+
+static void
+gst_schrofilter_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstSchrofilter *src;
+
+ g_return_if_fail (GST_IS_SCHROFILTER (object));
+ src = GST_SCHROFILTER (object);
+
+ GST_DEBUG ("gst_schrofilter_set_property");
+ switch (prop_id) {
+ case ARG_WAVELET_TYPE:
+ src->wavelet_type = g_value_get_int (value);
+ break;
+ case ARG_LEVEL:
+ src->level = g_value_get_int (value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_schrofilter_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstSchrofilter *src;
+
+ g_return_if_fail (GST_IS_SCHROFILTER (object));
+ src = GST_SCHROFILTER (object);
+
+ switch (prop_id) {
+ case ARG_WAVELET_TYPE:
+ g_value_set_int (value, src->wavelet_type);
+ break;
+ case ARG_LEVEL:
+ g_value_set_int (value, src->level);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GstFlowReturn
+gst_schrofilter_transform_ip (GstBaseTransform * base_transform,
+ GstBuffer * buf)
+{
+ GstSchrofilter *compress;
+ SchroFrame *frame;
+ int width, height;
+
+ g_return_val_if_fail (GST_IS_SCHROFILTER (base_transform), GST_FLOW_ERROR);
+ compress = GST_SCHROFILTER (base_transform);
+
+ gst_structure_get_int (gst_caps_get_structure (buf->caps, 0),
+ "width", &width);
+ gst_structure_get_int (gst_caps_get_structure (buf->caps, 0),
+ "height", &height);
+
+ frame = schro_frame_new_from_data_I420 (GST_BUFFER_DATA (buf), width, height);
+ schro_frame_filter_lowpass2 (frame, 5.0);
+ //schro_frame_filter_wavelet (frame);
+
+ return GST_FLOW_OK;
+}
diff --git a/ext/cog/gstcogmse.c b/ext/cog/gstcogmse.c
new file mode 100644
index 000000000..f4e499c87
--- /dev/null
+++ b/ext/cog/gstcogmse.c
@@ -0,0 +1,542 @@
+/*
+ * GStreamer
+ * Copyright (C) 2007,2009 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <cog-video/cogframe.h>
+#include <orc/orc.h>
+#include <math.h>
+
+#include "gstcogutils.h"
+
+#define GST_CAT_DEFAULT gst_mse_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define GST_TYPE_MSE (gst_mse_get_type())
+#define GST_MSE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MSE,GstMSE))
+#define GST_IS_MSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MSE))
+#define GST_MSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_MSE,GstMSEClass))
+#define GST_IS_MSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_MSE))
+#define GST_MSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_MSE,GstMSEClass))
+typedef struct _GstMSE GstMSE;
+typedef struct _GstMSEClass GstMSEClass;
+
+typedef void (*GstMSEProcessFunc) (GstMSE *, guint8 *, guint);
+
+struct _GstMSE
+{
+ GstElement element;
+
+ /* < private > */
+ GstPad *srcpad;
+ GstPad *sinkpad_ref;
+ GstPad *sinkpad_test;
+
+ GstBuffer *buffer_ref;
+
+ GMutex *lock;
+ GCond *cond;
+ gboolean cancel;
+
+ GstVideoFormat format;
+ int width;
+ int height;
+
+ double luma_mse_sum;
+ double chroma_mse_sum;
+ int n_frames;
+};
+
+struct _GstMSEClass
+{
+ GstElementClass parent;
+};
+
+static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
+ "Filter/Effect",
+ "FIXME example filter",
+ "FIXME <fixme@fixme.com>");
+
+enum
+{
+ PROP_0,
+ LUMA_PSNR,
+ CHROMA_PSNR
+};
+
+#define DEBUG_INIT(bla) \
+ GST_DEBUG_CATEGORY_INIT (gst_mse_debug, "mse", 0, "cogmse element");
+
+GST_BOILERPLATE_FULL (GstMSE, gst_mse, GstElement,
+ GST_TYPE_ELEMENT, DEBUG_INIT);
+
+static void gst_mse_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_mse_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstFlowReturn gst_mse_chain_test (GstPad * pad, GstBuffer * buffer);
+static GstFlowReturn gst_mse_chain_ref (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_mse_sink_event (GstPad * pad, GstEvent * event);
+static void gst_mse_reset (GstMSE * filter);
+//static GstPadLinkReturn gst_mse_link_src (GstPad *pad, GstPad *peer);
+static GstCaps *gst_mse_getcaps (GstPad * pad);
+static gboolean gst_mse_set_caps (GstPad * pad, GstCaps * outcaps);
+static void gst_mse_finalize (GObject * object);
+
+static void cog_frame_mse (CogFrame * a, CogFrame * b, double *mse);
+static double mse_to_db (double mse, gboolean is_chroma);
+
+
+static GstStaticPadTemplate gst_framestore_sink_ref_template =
+GST_STATIC_PAD_TEMPLATE ("sink_ref",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,AYUV}"))
+ );
+
+static GstStaticPadTemplate gst_framestore_sink_test_template =
+GST_STATIC_PAD_TEMPLATE ("sink_test",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,AYUV}"))
+ );
+
+static GstStaticPadTemplate gst_framestore_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,AYUV}"))
+ );
+
+static void
+gst_mse_base_init (gpointer klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_framestore_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_framestore_sink_ref_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_framestore_sink_test_template));
+
+ gst_element_class_set_details (element_class, &element_details);
+}
+
+static void
+gst_mse_class_init (GstMSEClass * klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gobject_class->set_property = gst_mse_set_property;
+ gobject_class->get_property = gst_mse_get_property;
+
+ gobject_class->finalize = gst_mse_finalize;
+
+ g_object_class_install_property (gobject_class, LUMA_PSNR,
+ g_param_spec_double ("luma-psnr", "luma-psnr", "luma-psnr",
+ 0, 70, 40, G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class, CHROMA_PSNR,
+ g_param_spec_double ("chroma-psnr", "chroma-psnr", "chroma-psnr",
+ 0, 70, 40, G_PARAM_READABLE));
+
+}
+
+static void
+gst_mse_init (GstMSE * filter, GstMSEClass * klass)
+{
+ gst_element_create_all_pads (GST_ELEMENT (filter));
+
+ filter->srcpad = gst_element_get_pad (GST_ELEMENT (filter), "src");
+
+ //gst_pad_set_link_function (filter->srcpad, gst_mse_link_src);
+ gst_pad_set_getcaps_function (filter->srcpad, gst_mse_getcaps);
+
+ filter->sinkpad_ref = gst_element_get_pad (GST_ELEMENT (filter), "sink_ref");
+
+ gst_pad_set_chain_function (filter->sinkpad_ref, gst_mse_chain_ref);
+ gst_pad_set_event_function (filter->sinkpad_ref, gst_mse_sink_event);
+ gst_pad_set_getcaps_function (filter->sinkpad_ref, gst_mse_getcaps);
+
+ filter->sinkpad_test =
+ gst_element_get_pad (GST_ELEMENT (filter), "sink_test");
+
+ gst_pad_set_chain_function (filter->sinkpad_test, gst_mse_chain_test);
+ gst_pad_set_event_function (filter->sinkpad_test, gst_mse_sink_event);
+ gst_pad_set_getcaps_function (filter->sinkpad_test, gst_mse_getcaps);
+ gst_pad_set_setcaps_function (filter->sinkpad_test, gst_mse_set_caps);
+
+ gst_mse_reset (filter);
+
+ filter->cond = g_cond_new ();
+ filter->lock = g_mutex_new ();
+}
+
+static void
+gst_mse_finalize (GObject * object)
+{
+ GstMSE *fs = GST_MSE (object);
+
+ g_mutex_free (fs->lock);
+ g_cond_free (fs->cond);
+}
+
+static GstCaps *
+gst_mse_getcaps (GstPad * pad)
+{
+ GstMSE *fs;
+ GstCaps *caps;
+ GstCaps *icaps;
+ GstCaps *peercaps;
+
+ fs = GST_MSE (gst_pad_get_parent (pad));
+
+ caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+
+ if (pad != fs->srcpad) {
+ peercaps = gst_pad_peer_get_caps (fs->srcpad);
+ if (peercaps) {
+ icaps = gst_caps_intersect (caps, peercaps);
+ gst_caps_unref (caps);
+ gst_caps_unref (peercaps);
+ caps = icaps;
+ }
+ }
+
+ if (pad != fs->sinkpad_ref) {
+ peercaps = gst_pad_peer_get_caps (fs->sinkpad_ref);
+ if (peercaps) {
+ icaps = gst_caps_intersect (caps, peercaps);
+ gst_caps_unref (caps);
+ gst_caps_unref (peercaps);
+ caps = icaps;
+ }
+ }
+
+ if (pad != fs->sinkpad_test) {
+ peercaps = gst_pad_peer_get_caps (fs->sinkpad_ref);
+ if (peercaps) {
+ icaps = gst_caps_intersect (caps, peercaps);
+ gst_caps_unref (caps);
+ gst_caps_unref (peercaps);
+ caps = icaps;
+ }
+ }
+
+ gst_object_unref (fs);
+
+ return caps;
+}
+
+static gboolean
+gst_mse_set_caps (GstPad * pad, GstCaps * caps)
+{
+ GstMSE *fs;
+
+ fs = GST_MSE (gst_pad_get_parent (pad));
+
+ gst_video_format_parse_caps (caps, &fs->format, &fs->width, &fs->height);
+
+ gst_object_unref (fs);
+
+ return TRUE;
+}
+
+static void
+gst_mse_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ //GstMSE *fs = GST_MSE (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_mse_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstMSE *fs = GST_MSE (object);
+
+ switch (prop_id) {
+ case LUMA_PSNR:
+ g_value_set_double (value,
+ mse_to_db (fs->luma_mse_sum / fs->n_frames, FALSE));
+ break;
+ case CHROMA_PSNR:
+ g_value_set_double (value,
+ mse_to_db (fs->chroma_mse_sum / fs->n_frames, TRUE));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_mse_reset (GstMSE * fs)
+{
+ fs->luma_mse_sum = 0;
+ fs->chroma_mse_sum = 0;
+ fs->n_frames = 0;
+
+ if (fs->buffer_ref) {
+ gst_buffer_unref (fs->buffer_ref);
+ fs->buffer_ref = NULL;
+ }
+}
+
+
+static GstFlowReturn
+gst_mse_chain_ref (GstPad * pad, GstBuffer * buffer)
+{
+ GstMSE *fs;
+
+ fs = GST_MSE (gst_pad_get_parent (pad));
+
+ GST_DEBUG ("chain ref");
+
+ g_mutex_lock (fs->lock);
+ while (fs->buffer_ref) {
+ GST_DEBUG ("waiting for ref buffer clear");
+ g_cond_wait (fs->cond, fs->lock);
+ if (fs->cancel) {
+ g_mutex_unlock (fs->lock);
+ return GST_FLOW_WRONG_STATE;
+ }
+ }
+
+ fs->buffer_ref = buffer;
+ g_cond_signal (fs->cond);
+
+ g_mutex_unlock (fs->lock);
+
+ gst_object_unref (fs);
+
+ return GST_FLOW_OK;
+}
+
+static GstFlowReturn
+gst_mse_chain_test (GstPad * pad, GstBuffer * buffer)
+{
+ GstMSE *fs;
+ GstFlowReturn ret;
+ GstBuffer *buffer_ref;
+
+ fs = GST_MSE (gst_pad_get_parent (pad));
+
+ GST_DEBUG_OBJECT (fs, "chain test");
+
+ g_mutex_lock (fs->lock);
+ while (fs->buffer_ref == NULL) {
+ GST_DEBUG_OBJECT (fs, "waiting for ref buffer");
+ g_cond_wait (fs->cond, fs->lock);
+ if (fs->cancel) {
+ g_mutex_unlock (fs->lock);
+ return GST_FLOW_WRONG_STATE;
+ }
+ }
+
+ buffer_ref = fs->buffer_ref;
+ fs->buffer_ref = NULL;
+ g_cond_signal (fs->cond);
+
+ g_mutex_unlock (fs->lock);
+
+ if (1) {
+ CogFrame *frame_ref;
+ CogFrame *frame_test;
+ double mse[3];
+
+ frame_ref = gst_cog_buffer_wrap (gst_buffer_ref (buffer_ref), fs->format,
+ fs->width, fs->height);
+ frame_test = gst_cog_buffer_wrap (gst_buffer_ref (buffer), fs->format,
+ fs->width, fs->height);
+
+ cog_frame_mse (frame_ref, frame_test, mse);
+
+ GST_INFO ("mse %g %g %g", mse_to_db (mse[0], FALSE),
+ mse_to_db (mse[1], TRUE), mse_to_db (mse[2], TRUE));
+
+ fs->luma_mse_sum += mse[0];
+ fs->chroma_mse_sum += 0.5 * (mse[1] + mse[2]);
+ fs->n_frames++;
+
+ cog_frame_unref (frame_ref);
+ cog_frame_unref (frame_test);
+ }
+
+
+ ret = gst_pad_push (fs->srcpad, buffer);
+ gst_buffer_unref (buffer_ref);
+
+ gst_object_unref (fs);
+
+ return ret;
+}
+
+static gboolean
+gst_mse_sink_event (GstPad * pad, GstEvent * event)
+{
+ GstMSE *fs;
+
+ fs = GST_MSE (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:
+ {
+ gboolean update;
+ double rate;
+ double applied_rate;
+ GstFormat format;
+ gint64 start, stop, position;
+
+ gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
+ &format, &start, &stop, &position);
+
+ GST_DEBUG ("new_segment %d %g %g %d %lld %lld %lld",
+ update, rate, applied_rate, format, start, stop, position);
+
+ }
+ break;
+ case GST_EVENT_FLUSH_START:
+ GST_DEBUG ("flush start");
+ break;
+ case GST_EVENT_FLUSH_STOP:
+ GST_DEBUG ("flush stop");
+ break;
+ default:
+ break;
+ }
+
+ gst_pad_push_event (fs->srcpad, event);
+
+ return TRUE;
+}
+
+static int
+sum_square_diff_u8 (uint8_t * s1, uint8_t * s2, int n)
+{
+#if 0
+ int sum = 0;
+ int i;
+ int x;
+
+ for (i = 0; i < n; i++) {
+ x = s1[i] - s2[i];
+ sum += x * x;
+ }
+ d_1[0] = sum;
+#endif
+ static OrcProgram *p = NULL;
+ OrcExecutor *ex;
+ int val;
+
+ if (p == NULL) {
+ OrcCompileResult ret;
+
+ p = orc_program_new_ass (4, 1, 1);
+ orc_program_add_temporary (p, 2, "t1");
+ orc_program_add_temporary (p, 2, "t2");
+ orc_program_add_temporary (p, 4, "t3");
+
+ orc_program_append_ds_str (p, "convubw", "t1", "s1");
+ orc_program_append_ds_str (p, "convubw", "t2", "s2");
+ orc_program_append_str (p, "subw", "t1", "t1", "t2");
+ orc_program_append_str (p, "mullw", "t1", "t1", "t1");
+ orc_program_append_ds_str (p, "convuwl", "t3", "t1");
+ orc_program_append_ds_str (p, "accl", "a1", "t3");
+
+ ret = orc_program_compile (p);
+ if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (ret)) {
+ GST_ERROR ("Orc compiler failure");
+ return 0;
+ }
+ }
+
+ ex = orc_executor_new (p);
+ orc_executor_set_n (ex, n);
+ orc_executor_set_array_str (ex, "s1", s1);
+ orc_executor_set_array_str (ex, "s2", s2);
+
+ orc_executor_run (ex);
+ val = orc_executor_get_accumulator (ex, 0);
+ orc_executor_free (ex);
+
+ return val;
+}
+
+static double
+cog_frame_component_squared_error (CogFrameData * a, CogFrameData * b)
+{
+ int j;
+ double sum;
+
+ COG_ASSERT (a->width == b->width);
+ COG_ASSERT (a->height == b->height);
+
+ sum = 0;
+ for (j = 0; j < a->height; j++) {
+ sum += sum_square_diff_u8 (COG_FRAME_DATA_GET_LINE (a, j),
+ COG_FRAME_DATA_GET_LINE (b, j), a->width);
+ }
+ return sum;
+}
+
+static void
+cog_frame_mse (CogFrame * a, CogFrame * b, double *mse)
+{
+ double sum, n;
+
+ sum = cog_frame_component_squared_error (&a->components[0],
+ &b->components[0]);
+ n = a->components[0].width * a->components[0].height;
+ mse[0] = sum / n;
+
+ sum = cog_frame_component_squared_error (&a->components[1],
+ &b->components[1]);
+ n = a->components[1].width * a->components[1].height;
+ mse[1] = sum / n;
+
+ sum = cog_frame_component_squared_error (&a->components[2],
+ &b->components[2]);
+ n = a->components[2].width * a->components[2].height;
+ mse[2] = sum / n;
+}
+
+static double
+mse_to_db (double mse, gboolean is_chroma)
+{
+ if (is_chroma) {
+ return 10.0 * log (mse / (224.0 * 224.0)) / log (10.0);
+ } else {
+ return 10.0 * log (mse / (219.0 * 219.0)) / log (10.0);
+ }
+}
diff --git a/ext/cog/gstcogscale.c b/ext/cog/gstcogscale.c
new file mode 100644
index 000000000..6187d18c3
--- /dev/null
+++ b/ext/cog/gstcogscale.c
@@ -0,0 +1,732 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) 2005 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-videoscale
+ * @see_also: videorate, ffmpegcolorspace
+ *
+ * <refsect2>
+ * <para>
+ * This element resizes video frames. By default the element will try to
+ * negotiate to the same size on the source and sinkpad so that no scaling
+ * is needed. It is therefore safe to insert this element in a pipeline to
+ * get more robust behaviour without any cost if no scaling is needed.
+ * </para>
+ * <para>
+ * This element supports a wide range of color spaces including various YUV and
+ * RGB formats and is therefore generally able to operate anywhere in a
+ * pipeline.
+ * </para>
+ * <title>Example pipelines</title>
+ * <para>
+ * <programlisting>
+ * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! ffmpegcolorspace ! videoscale ! ximagesink
+ * </programlisting>
+ * Decode an Ogg/Theora and display the video using ximagesink. Since
+ * ximagesink cannot perform scaling, the video scaling will be performed by
+ * videoscale when you resize the video window.
+ * To create the test Ogg/Theora file refer to the documentation of theoraenc.
+ * </para>
+ * <para>
+ * <programlisting>
+ * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! videoscale ! video/x-raw-yuv, width=50 ! xvimagesink
+ * </programlisting>
+ * Decode an Ogg/Theora and display the video using xvimagesink with a width of
+ * 50.
+ * </para>
+ * </refsect2>
+ *
+ * Last reviewed on 2006-03-02 (0.10.4)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/base/gstbasetransform.h>
+#include <cog/cog.h>
+#include <cog-video/cogvirtframe.h>
+#include "gstcogutils.h"
+
+GST_DEBUG_CATEGORY_STATIC (cog_scale_debug);
+#define GST_CAT_DEFAULT cog_scale_debug
+
+#define GST_TYPE_COG_SCALE \
+ (gst_cog_scale_get_type())
+#define GST_COG_SCALE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COG_SCALE,GstCogScale))
+#define GST_COG_SCALE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COG_SCALE,GstCogScaleClass))
+#define GST_IS_COG_SCALE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COG_SCALE))
+#define GST_IS_COG_SCALE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COG_SCALE))
+
+/**
+ * GstCogScaleMethod:
+ * @GST_COG_SCALE_NEAREST: use nearest neighbour scaling (fast and ugly)
+ * @GST_COG_SCALE_BILINEAR: use bilinear scaling (slower but prettier).
+ * @GST_COG_SCALE_4TAP: use a 4-tap filter for scaling (slow).
+ *
+ * The videoscale method to use.
+ */
+typedef enum
+{
+ GST_COG_SCALE_NEAREST,
+ GST_COG_SCALE_BILINEAR,
+ GST_COG_SCALE_4TAP
+} GstCogScaleMethod;
+
+typedef struct _GstCogScale GstCogScale;
+typedef struct _GstCogScaleClass GstCogScaleClass;
+
+/**
+ * GstCogScale:
+ *
+ * Opaque data structure
+ */
+struct _GstCogScale
+{
+ GstBaseTransform element;
+
+ GstCogScaleMethod method;
+
+ /* negotiated stuff */
+ GstVideoFormat format;
+ guint src_size;
+ guint dest_size;
+ gint to_width;
+ gint to_height;
+ gint from_width;
+ gint from_height;
+
+ /*< private > */
+};
+
+struct _GstCogScaleClass
+{
+ GstBaseTransformClass parent_class;
+};
+
+GType gst_cog_scale_get_type (void);
+
+
+/* elementfactory information */
+static const GstElementDetails cog_scale_details =
+GST_ELEMENT_DETAILS ("Video scaler",
+ "Filter/Effect/Video",
+ "Resizes video",
+ "Wim Taymans <wim.taymans@chello.be>");
+
+#define DEFAULT_PROP_METHOD GST_COG_SCALE_NEAREST
+
+enum
+{
+ PROP_0,
+ PROP_METHOD
+ /* FILL ME */
+};
+
+/* can't handle width/height of 1 yet, since we divide a lot by (n-1) */
+#undef GST_VIDEO_SIZE_RANGE
+#define GST_VIDEO_SIZE_RANGE "(int) [ 2, MAX ]"
+
+#define TEMPLATE_CAPS \
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV, Y42B }") ";" \
+ GST_VIDEO_CAPS_ARGB)
+
+#if 0
+/* not supported */
+GST_VIDEO_CAPS_RGBx
+ GST_VIDEO_CAPS_BGRx
+ GST_VIDEO_CAPS_xRGB
+ GST_VIDEO_CAPS_xBGR
+ GST_VIDEO_CAPS_RGBA
+ GST_VIDEO_CAPS_BGRA
+ GST_VIDEO_CAPS_ABGR GST_VIDEO_CAPS_RGB GST_VIDEO_CAPS_BGR
+GST_VIDEO_CAPS_YUV ("{ Y41B, YVYU }")
+#endif
+#define GST_TYPE_COG_SCALE_METHOD (gst_cog_scale_method_get_type())
+ static GType gst_cog_scale_method_get_type (void)
+{
+ static GType cog_scale_method_type = 0;
+ static const GEnumValue cog_scale_methods[] = {
+ {GST_COG_SCALE_NEAREST, "Nearest Neighbour", "nearest-neighbour"},
+ {GST_COG_SCALE_BILINEAR, "Bilinear", "bilinear"},
+ {GST_COG_SCALE_4TAP, "4-tap", "4-tap"},
+ {0, NULL, NULL},
+ };
+
+ if (!cog_scale_method_type) {
+ cog_scale_method_type =
+ g_enum_register_static ("GstCogScaleMethod", cog_scale_methods);
+ }
+ return cog_scale_method_type;
+}
+
+static GstStaticPadTemplate gst_cog_scale_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ TEMPLATE_CAPS);
+
+static GstStaticPadTemplate gst_cog_scale_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ TEMPLATE_CAPS);
+
+static void gst_cog_scale_base_init (gpointer g_class);
+static void gst_cog_scale_class_init (GstCogScaleClass * klass);
+static void gst_cog_scale_init (GstCogScale * videoscale);
+static void gst_cog_scale_finalize (GstCogScale * videoscale);
+static gboolean gst_cog_scale_src_event (GstBaseTransform * trans,
+ GstEvent * event);
+
+/* base transform vmethods */
+static GstCaps *gst_cog_scale_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps);
+static gboolean gst_cog_scale_set_caps (GstBaseTransform * trans,
+ GstCaps * in, GstCaps * out);
+static gboolean gst_cog_scale_get_unit_size (GstBaseTransform * trans,
+ GstCaps * caps, guint * size);
+static GstFlowReturn gst_cog_scale_transform (GstBaseTransform * trans,
+ GstBuffer * in, GstBuffer * out);
+static void gst_cog_scale_fixate_caps (GstBaseTransform * base,
+ GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
+
+static void gst_cog_scale_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_cog_scale_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstElementClass *parent_class = NULL;
+
+
+GType
+gst_cog_scale_get_type (void)
+{
+ static GType cog_scale_type = 0;
+
+ if (!cog_scale_type) {
+ static const GTypeInfo cog_scale_info = {
+ sizeof (GstCogScaleClass),
+ gst_cog_scale_base_init,
+ NULL,
+ (GClassInitFunc) gst_cog_scale_class_init,
+ NULL,
+ NULL,
+ sizeof (GstCogScale),
+ 0,
+ (GInstanceInitFunc) gst_cog_scale_init,
+ };
+
+ cog_scale_type =
+ g_type_register_static (GST_TYPE_BASE_TRANSFORM, "GstCogScale",
+ &cog_scale_info, 0);
+
+ GST_DEBUG_CATEGORY_INIT (cog_scale_debug, "cogscale", 0, "Cog scale");
+ }
+ return cog_scale_type;
+}
+
+static void
+gst_cog_scale_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_set_details (element_class, &cog_scale_details);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cog_scale_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_cog_scale_sink_template));
+}
+
+static void
+gst_cog_scale_class_init (GstCogScaleClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *trans_class;
+
+ gobject_class = (GObjectClass *) klass;
+ trans_class = (GstBaseTransformClass *) klass;
+
+ gobject_class->finalize = (GObjectFinalizeFunc) gst_cog_scale_finalize;
+ gobject_class->set_property = gst_cog_scale_set_property;
+ gobject_class->get_property = gst_cog_scale_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_METHOD,
+ g_param_spec_enum ("method", "method", "method",
+ GST_TYPE_COG_SCALE_METHOD, DEFAULT_PROP_METHOD,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ trans_class->transform_caps =
+ GST_DEBUG_FUNCPTR (gst_cog_scale_transform_caps);
+ trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_cog_scale_set_caps);
+ trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_cog_scale_get_unit_size);
+ trans_class->transform = GST_DEBUG_FUNCPTR (gst_cog_scale_transform);
+ trans_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_cog_scale_fixate_caps);
+ trans_class->src_event = GST_DEBUG_FUNCPTR (gst_cog_scale_src_event);
+
+ trans_class->passthrough_on_same_caps = TRUE;
+
+ parent_class = g_type_class_peek_parent (klass);
+}
+
+static void
+gst_cog_scale_init (GstCogScale * videoscale)
+{
+ gst_base_transform_set_qos_enabled (GST_BASE_TRANSFORM (videoscale), TRUE);
+ videoscale->method = DEFAULT_PROP_METHOD;
+}
+
+static void
+gst_cog_scale_finalize (GstCogScale * videoscale)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (videoscale));
+}
+
+static void
+gst_cog_scale_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstCogScale *vscale = GST_COG_SCALE (object);
+
+ switch (prop_id) {
+ case PROP_METHOD:
+ GST_OBJECT_LOCK (vscale);
+ vscale->method = g_value_get_enum (value);
+ GST_OBJECT_UNLOCK (vscale);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_cog_scale_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstCogScale *vscale = GST_COG_SCALE (object);
+
+ switch (prop_id) {
+ case PROP_METHOD:
+ GST_OBJECT_LOCK (vscale);
+ g_value_set_enum (value, vscale->method);
+ GST_OBJECT_UNLOCK (vscale);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GstCaps *
+gst_cog_scale_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps)
+{
+ GstCogScale *videoscale;
+ GstCaps *ret;
+ GstStructure *structure;
+ const GValue *par;
+ gint method;
+
+ /* this function is always called with a simple caps */
+ g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
+
+ videoscale = GST_COG_SCALE (trans);
+
+ GST_OBJECT_LOCK (videoscale);
+ method = videoscale->method;
+ GST_OBJECT_UNLOCK (videoscale);
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ /* check compatibility of format and method before we copy the input caps */
+ if (method == GST_COG_SCALE_4TAP) {
+ guint32 fourcc;
+
+ if (!gst_structure_has_name (structure, "video/x-raw-yuv"))
+ goto method_not_implemented_for_format;
+ if (!gst_structure_get_fourcc (structure, "format", &fourcc))
+ goto method_not_implemented_for_format;
+ if (fourcc != GST_MAKE_FOURCC ('I', '4', '2', '0') &&
+ fourcc != GST_MAKE_FOURCC ('Y', 'V', '1', '2'))
+ goto method_not_implemented_for_format;
+ }
+
+ ret = gst_caps_copy (caps);
+ structure = gst_caps_get_structure (ret, 0);
+
+ gst_structure_set (structure,
+ "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+ "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+
+ /* if pixel aspect ratio, make a range of it */
+ if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
+ GstCaps *copy;
+ GstStructure *cstruct;
+
+ /* copy input PAR first, this is the prefered PAR */
+ gst_structure_set_value (structure, "pixel-aspect-ratio", par);
+
+ /* then make a copy with a fraction range as a second choice */
+ copy = gst_caps_copy (ret);
+ cstruct = gst_caps_get_structure (copy, 0);
+ gst_structure_set (cstruct,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+
+ /* and append */
+ gst_caps_append (ret, copy);
+ }
+
+ GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
+
+ return ret;
+
+method_not_implemented_for_format:
+ {
+ GST_DEBUG_OBJECT (trans, "method %d not implemented for format %"
+ GST_PTR_FORMAT ", returning empty caps", method, caps);
+ return gst_caps_new_empty ();
+ }
+}
+
+static gboolean
+gst_cog_scale_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out)
+{
+ GstCogScale *videoscale;
+ gboolean ret;
+
+ videoscale = GST_COG_SCALE (trans);
+
+ ret = gst_video_format_parse_caps (in, &videoscale->format,
+ &videoscale->from_width, &videoscale->from_height);
+ ret &= gst_video_format_parse_caps (out, NULL,
+ &videoscale->to_width, &videoscale->to_height);
+ if (!ret)
+ goto done;
+
+ videoscale->src_size = gst_video_format_get_size (videoscale->format,
+ videoscale->from_width, videoscale->from_height);
+ videoscale->dest_size = gst_video_format_get_size (videoscale->format,
+ videoscale->to_width, videoscale->to_height);
+
+ /* FIXME: par */
+ GST_DEBUG_OBJECT (videoscale, "from=%dx%d, size %d -> to=%dx%d, size %d",
+ videoscale->from_width, videoscale->from_height, videoscale->src_size,
+ videoscale->to_width, videoscale->to_height, videoscale->dest_size);
+
+done:
+ return ret;
+}
+
+static gboolean
+gst_cog_scale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
+ guint * size)
+{
+ GstCogScale *videoscale;
+ GstVideoFormat format;
+ gint width, height;
+
+ g_assert (size);
+
+ videoscale = GST_COG_SCALE (trans);
+
+ if (!gst_video_format_parse_caps (caps, &format, &width, &height))
+ return FALSE;
+
+ *size = gst_video_format_get_size (format, width, height);
+
+ return TRUE;
+}
+
+static void
+gst_cog_scale_fixate_caps (GstBaseTransform * base, GstPadDirection direction,
+ GstCaps * caps, GstCaps * othercaps)
+{
+ GstStructure *ins, *outs;
+ const GValue *from_par, *to_par;
+
+ g_return_if_fail (gst_caps_is_fixed (caps));
+
+ GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT
+ " based on caps %" GST_PTR_FORMAT, othercaps, caps);
+
+ ins = gst_caps_get_structure (caps, 0);
+ outs = gst_caps_get_structure (othercaps, 0);
+
+ from_par = gst_structure_get_value (ins, "pixel-aspect-ratio");
+ to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");
+
+ /* we have both PAR but they might not be fixated */
+ if (from_par && to_par) {
+ gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
+ gint count = 0, w = 0, h = 0;
+ guint num, den;
+
+ /* from_par should be fixed */
+ g_return_if_fail (gst_value_is_fixed (from_par));
+
+ from_par_n = gst_value_get_fraction_numerator (from_par);
+ from_par_d = gst_value_get_fraction_denominator (from_par);
+
+ /* fixate the out PAR */
+ if (!gst_value_is_fixed (to_par)) {
+ GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n,
+ from_par_d);
+ gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio",
+ from_par_n, from_par_d);
+ }
+
+ to_par_n = gst_value_get_fraction_numerator (to_par);
+ to_par_d = gst_value_get_fraction_denominator (to_par);
+
+ /* if both width and height are already fixed, we can't do anything
+ * about it anymore */
+ if (gst_structure_get_int (outs, "width", &w))
+ ++count;
+ if (gst_structure_get_int (outs, "height", &h))
+ ++count;
+ if (count == 2) {
+ GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating",
+ w, h);
+ return;
+ }
+
+ gst_structure_get_int (ins, "width", &from_w);
+ gst_structure_get_int (ins, "height", &from_h);
+
+ if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h,
+ from_par_n, from_par_d, to_par_n, to_par_d)) {
+ GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
+ ("Error calculating the output scaled size - integer overflow"));
+ return;
+ }
+
+ GST_DEBUG_OBJECT (base,
+ "scaling input with %dx%d and PAR %d/%d to output PAR %d/%d",
+ from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d);
+ GST_DEBUG_OBJECT (base, "resulting output should respect ratio of %d/%d",
+ num, den);
+
+ /* now find a width x height that respects this display ratio.
+ * prefer those that have one of w/h the same as the incoming video
+ * using wd / hd = num / den */
+
+ /* if one of the output width or height is fixed, we work from there */
+ if (h) {
+ GST_DEBUG_OBJECT (base, "height is fixed,scaling width");
+ w = (guint) gst_util_uint64_scale_int (h, num, den);
+ } else if (w) {
+ GST_DEBUG_OBJECT (base, "width is fixed, scaling height");
+ h = (guint) gst_util_uint64_scale_int (w, den, num);
+ } else {
+ /* none of width or height is fixed, figure out both of them based only on
+ * the input width and height */
+ /* check hd / den is an integer scale factor, and scale wd with the PAR */
+ if (from_h % den == 0) {
+ GST_DEBUG_OBJECT (base, "keeping video height");
+ h = from_h;
+ w = (guint) gst_util_uint64_scale_int (h, num, den);
+ } else if (from_w % num == 0) {
+ GST_DEBUG_OBJECT (base, "keeping video width");
+ w = from_w;
+ h = (guint) gst_util_uint64_scale_int (w, den, num);
+ } else {
+ GST_DEBUG_OBJECT (base, "approximating but keeping video height");
+ h = from_h;
+ w = (guint) gst_util_uint64_scale_int (h, num, den);
+ }
+ }
+ GST_DEBUG_OBJECT (base, "scaling to %dx%d", w, h);
+
+ /* now fixate */
+ gst_structure_fixate_field_nearest_int (outs, "width", w);
+ gst_structure_fixate_field_nearest_int (outs, "height", h);
+ } else {
+ gint width, height;
+
+ if (gst_structure_get_int (ins, "width", &width)) {
+ if (gst_structure_has_field (outs, "width")) {
+ gst_structure_fixate_field_nearest_int (outs, "width", width);
+ }
+ }
+ if (gst_structure_get_int (ins, "height", &height)) {
+ if (gst_structure_has_field (outs, "height")) {
+ gst_structure_fixate_field_nearest_int (outs, "height", height);
+ }
+ }
+ }
+
+ GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, othercaps);
+}
+
+#if 0
+static gboolean
+gst_cog_scale_prepare_image (gint format, GstBuffer * buf,
+ VSImage * img, VSImage * img_u, VSImage * img_v)
+{
+ gboolean res = TRUE;
+
+ img->pixels = GST_BUFFER_DATA (buf);
+
+ switch (format) {
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ img_u->pixels = img->pixels + GST_ROUND_UP_2 (img->height) * img->stride;
+ img_u->height = GST_ROUND_UP_2 (img->height) / 2;
+ img_u->width = GST_ROUND_UP_2 (img->width) / 2;
+ img_u->stride = GST_ROUND_UP_4 (img_u->width);
+ memcpy (img_v, img_u, sizeof (*img_v));
+ img_v->pixels = img_u->pixels + img_u->height * img_u->stride;
+ break;
+ default:
+ break;
+ }
+ return res;
+}
+#endif
+
+static GstFlowReturn
+gst_cog_scale_transform (GstBaseTransform * trans, GstBuffer * in,
+ GstBuffer * out)
+{
+ GstCogScale *videoscale;
+ GstFlowReturn ret = GST_FLOW_OK;
+ CogFrame *outframe;
+ CogFrame *frame;
+ gint method;
+ int w, h;
+
+ videoscale = GST_COG_SCALE (trans);
+
+ GST_OBJECT_LOCK (videoscale);
+ method = videoscale->method;
+ GST_OBJECT_UNLOCK (videoscale);
+
+ frame = gst_cog_buffer_wrap (gst_buffer_ref (in), videoscale->format,
+ videoscale->from_width, videoscale->from_height);
+ outframe = gst_cog_buffer_wrap (gst_buffer_ref (out), videoscale->format,
+ videoscale->to_width, videoscale->to_height);
+
+ frame = cog_virt_frame_new_unpack (frame);
+
+ w = videoscale->from_width;
+ h = videoscale->from_height;
+ while (w >= 2 * videoscale->to_width || h >= 2 * videoscale->to_height) {
+ if (w >= 2 * videoscale->to_width) {
+ frame = cog_virt_frame_new_horiz_downsample (frame, 3);
+ w /= 2;
+ }
+ if (h >= 2 * videoscale->to_height) {
+ frame = cog_virt_frame_new_vert_downsample (frame, 2);
+ h /= 2;
+ }
+ }
+ if (w != videoscale->to_width) {
+ frame = cog_virt_frame_new_horiz_resample (frame, videoscale->to_width);
+ }
+ if (h != videoscale->to_height) {
+ frame = cog_virt_frame_new_vert_resample (frame, videoscale->to_height);
+ }
+
+ switch (videoscale->format) {
+ case GST_VIDEO_FORMAT_YUY2:
+ frame = cog_virt_frame_new_pack_YUY2 (frame);
+ break;
+ case GST_VIDEO_FORMAT_UYVY:
+ frame = cog_virt_frame_new_pack_UYVY (frame);
+ break;
+ default:
+ break;
+ }
+
+ cog_virt_frame_render (frame, outframe);
+ cog_frame_unref (frame);
+ cog_frame_unref (outframe);
+
+ GST_LOG_OBJECT (videoscale, "pushing buffer of %d bytes",
+ GST_BUFFER_SIZE (out));
+
+ return ret;
+
+ /* ERRORS */
+#if 0
+unsupported:
+ {
+ GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL),
+ ("Unsupported format %d for scaling method %d",
+ videoscale->format, method));
+ return GST_FLOW_ERROR;
+ }
+unknown_mode:
+ {
+ GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL),
+ ("Unknown scaling method %d", videoscale->method));
+ return GST_FLOW_ERROR;
+ }
+#endif
+}
+
+static gboolean
+gst_cog_scale_src_event (GstBaseTransform * trans, GstEvent * event)
+{
+ GstCogScale *videoscale;
+ gboolean ret;
+ double a;
+ GstStructure *structure;
+
+ videoscale = GST_COG_SCALE (trans);
+
+ GST_DEBUG_OBJECT (videoscale, "handling %s event",
+ GST_EVENT_TYPE_NAME (event));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NAVIGATION:
+ event =
+ GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
+
+ structure = (GstStructure *) gst_event_get_structure (event);
+ if (gst_structure_get_double (structure, "pointer_x", &a)) {
+ gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
+ a * videoscale->from_width / videoscale->to_width, NULL);
+ }
+ if (gst_structure_get_double (structure, "pointer_y", &a)) {
+ gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
+ a * videoscale->from_height / videoscale->to_height, NULL);
+ }
+ break;
+ case GST_EVENT_QOS:
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event);
+
+ return ret;
+}
diff --git a/ext/cog/gstcogutils.c b/ext/cog/gstcogutils.c
new file mode 100644
index 000000000..552509045
--- /dev/null
+++ b/ext/cog/gstcogutils.c
@@ -0,0 +1,182 @@
+/* Cog
+ * Copyright (C) 2008 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <cog/cog.h>
+#include <cog-video/cogvirtframe.h>
+#include <math.h>
+#include <string.h>
+
+//GST_DEBUG_CATEGORY_EXTERN (cog_debug);
+//#define GST_CAT_DEFAULT cog_debug
+
+
+
+
+static void
+gst_cog_frame_free (CogFrame * frame, void *priv)
+{
+ gst_buffer_unref (GST_BUFFER (priv));
+}
+
+CogFrame *
+gst_cog_buffer_wrap (GstBuffer * buf, GstVideoFormat format, int width,
+ int height)
+{
+ CogFrame *frame;
+ int size;
+
+ size = gst_video_format_get_size (format, width, height);
+ if (GST_BUFFER_SIZE (buf) != size) {
+ GST_ERROR ("size incorrect, expected %d, got %d", size,
+ GST_BUFFER_SIZE (buf));
+ }
+
+ switch (format) {
+ case GST_VIDEO_FORMAT_I420:
+ frame =
+ cog_frame_new_from_data_I420 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ frame =
+ cog_frame_new_from_data_YV12 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ frame =
+ cog_frame_new_from_data_YUY2 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_UYVY:
+ frame =
+ cog_frame_new_from_data_UYVY (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_AYUV:
+ frame =
+ cog_frame_new_from_data_AYUV (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_Y42B:
+ frame =
+ cog_frame_new_from_data_Y42B (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_Y444:
+ frame =
+ cog_frame_new_from_data_Y444 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_v210:
+ frame =
+ cog_frame_new_from_data_v210 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_v216:
+ frame =
+ cog_frame_new_from_data_v216 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_RGBx:
+ frame =
+ cog_frame_new_from_data_RGBx (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_BGRx:
+ frame =
+ cog_frame_new_from_data_BGRx (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ frame =
+ cog_frame_new_from_data_xRGB (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_xBGR:
+ frame =
+ cog_frame_new_from_data_xBGR (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_RGBA:
+ frame =
+ cog_frame_new_from_data_RGBA (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ frame =
+ cog_frame_new_from_data_BGRA (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ frame =
+ cog_frame_new_from_data_ARGB (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_ABGR:
+ frame =
+ cog_frame_new_from_data_ABGR (GST_BUFFER_DATA (buf), width, height);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ cog_frame_set_free_callback (frame, gst_cog_frame_free, buf);
+
+ return frame;
+}
+
+#if 0
+#ifdef GST_BUFFER_FREE_FUNC
+static void
+cog_buf_free_func (gpointer priv)
+{
+ CogBuffer *buffer = (CogBuffer *) priv;
+
+ cog_buffer_unref (buffer);
+}
+#endif
+
+/* takes the reference */
+GstBuffer *
+gst_cog_wrap_cog_buffer (CogBuffer * buffer)
+{
+ GstBuffer *gstbuf;
+
+#ifdef GST_BUFFER_FREE_FUNC
+ gstbuf = gst_buffer_new ();
+ GST_BUFFER_DATA (gstbuf) = buffer->data;
+ GST_BUFFER_SIZE (gstbuf) = buffer->length;
+ GST_BUFFER_MALLOCDATA (gstbuf) = (void *) buffer;
+ GST_BUFFER_FREE_FUNC (gstbuf) = cog_buf_free_func;
+#else
+ gstbuf = gst_buffer_new_and_alloc (buffer->length);
+ memcpy (GST_BUFFER_DATA (gstbuf), buffer->data, buffer->length);
+#endif
+
+ return gstbuf;
+}
+
+static void
+gst_cog_buffer_free (CogBuffer * buffer, void *priv)
+{
+ gst_buffer_unref (GST_BUFFER (priv));
+}
+
+CogBuffer *
+gst_cog_wrap_gst_buffer (GstBuffer * buffer)
+{
+ CogBuffer *cogbuf;
+
+ cogbuf = cog_buffer_new_with_data (GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+ cogbuf->free = gst_cog_buffer_free;
+ cogbuf->priv = buffer;
+
+ return cogbuf;
+}
+#endif
diff --git a/ext/cog/gstcogutils.h b/ext/cog/gstcogutils.h
new file mode 100644
index 000000000..c6baf8523
--- /dev/null
+++ b/ext/cog/gstcogutils.h
@@ -0,0 +1,37 @@
+/* Schrodinger
+ * Copyright (C) 2008 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_COG_UTILS_H_
+#define _GST_COG_UTILS_H_
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <cog/cog.h>
+#include <cog-video/cogframe.h>
+
+CogFrame *
+gst_cog_buffer_wrap (GstBuffer *buf, GstVideoFormat format, int width,
+ int height);
+#if 0
+GstBuffer * gst_cog_wrap_cog_buffer (CogBuffer *buffer);
+CogBuffer * gst_cog_wrap_gst_buffer (GstBuffer *buffer);
+#endif
+
+#endif
+
diff --git a/ext/cog/gstcolorconvert.c b/ext/cog/gstcolorconvert.c
new file mode 100644
index 000000000..1c9e9cd77
--- /dev/null
+++ b/ext/cog/gstcolorconvert.c
@@ -0,0 +1,864 @@
+/* GStreamer
+ * Copyright (C) 2008 David Schleef <ds@entropywave.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <cog/cog.h>
+#include <cog-video/cogvirtframe.h>
+#include <math.h>
+
+#include "gstcogutils.h"
+
+#define GST_TYPE_COLORCONVERT \
+ (gst_colorconvert_get_type())
+#define GST_COLORCONVERT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLORCONVERT,GstColorconvert))
+#define GST_COLORCONVERT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COLORCONVERT,GstColorconvertClass))
+#define GST_IS_COLORCONVERT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLORCONVERT))
+#define GST_IS_COLORCONVERT_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLORCONVERT))
+
+typedef struct _GstColorconvert GstColorconvert;
+typedef struct _GstColorconvertClass GstColorconvertClass;
+
+struct _GstColorconvert
+{
+ GstBaseTransform base_transform;
+
+ gchar *location;
+
+ GstVideoFormat format;
+ int width;
+ int height;
+
+};
+
+struct _GstColorconvertClass
+{
+ GstBaseTransformClass parent_class;
+
+};
+
+
+/* GstColorconvert signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+};
+
+GType gst_colorconvert_get_type (void);
+
+static void gst_colorconvert_base_init (gpointer g_class);
+static void gst_colorconvert_class_init (gpointer g_class, gpointer class_data);
+static void gst_colorconvert_init (GTypeInstance * instance, gpointer g_class);
+
+static void gst_colorconvert_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_colorconvert_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static gboolean gst_colorconvert_set_caps (GstBaseTransform * base_transform,
+ GstCaps * incaps, GstCaps * outcaps);
+static GstFlowReturn gst_colorconvert_transform_ip (GstBaseTransform *
+ base_transform, GstBuffer * buf);
+static CogFrame *cog_virt_frame_new_color_transform (CogFrame * frame);
+
+static GstStaticPadTemplate gst_colorconvert_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,UYVY,AYUV}"))
+ );
+
+static GstStaticPadTemplate gst_colorconvert_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,UYVY,AYUV}"))
+ );
+
+GType
+gst_colorconvert_get_type (void)
+{
+ static GType compress_type = 0;
+
+ if (!compress_type) {
+ static const GTypeInfo compress_info = {
+ sizeof (GstColorconvertClass),
+ gst_colorconvert_base_init,
+ NULL,
+ gst_colorconvert_class_init,
+ NULL,
+ NULL,
+ sizeof (GstColorconvert),
+ 0,
+ gst_colorconvert_init,
+ };
+
+ compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
+ "GstColorconvert", &compress_info, 0);
+ }
+ return compress_type;
+}
+
+
+static void
+gst_colorconvert_base_init (gpointer g_class)
+{
+ static GstElementDetails compress_details =
+ GST_ELEMENT_DETAILS ("Video Filter Template",
+ "Filter/Effect/Video",
+ "Template for a video filter",
+ "David Schleef <ds@schleef.org>");
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ //GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_colorconvert_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_colorconvert_sink_template));
+
+ gst_element_class_set_details (element_class, &compress_details);
+}
+
+static void
+gst_colorconvert_class_init (gpointer g_class, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *base_transform_class;
+ GstColorconvertClass *filter_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+ filter_class = GST_COLORCONVERT_CLASS (g_class);
+
+ gobject_class->set_property = gst_colorconvert_set_property;
+ gobject_class->get_property = gst_colorconvert_get_property;
+
+ base_transform_class->set_caps = gst_colorconvert_set_caps;
+ base_transform_class->transform_ip = gst_colorconvert_transform_ip;
+}
+
+static void
+gst_colorconvert_init (GTypeInstance * instance, gpointer g_class)
+{
+ //GstColorconvert *compress = GST_COLORCONVERT (instance);
+ //GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
+
+ GST_DEBUG ("gst_colorconvert_init");
+}
+
+static void
+gst_colorconvert_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstColorconvert *src;
+
+ g_return_if_fail (GST_IS_COLORCONVERT (object));
+ src = GST_COLORCONVERT (object);
+
+ GST_DEBUG ("gst_colorconvert_set_property");
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_colorconvert_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstColorconvert *src;
+
+ g_return_if_fail (GST_IS_COLORCONVERT (object));
+ src = GST_COLORCONVERT (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+gst_colorconvert_set_caps (GstBaseTransform * base_transform,
+ GstCaps * incaps, GstCaps * outcaps)
+{
+ GstColorconvert *li;
+
+ g_return_val_if_fail (GST_IS_COLORCONVERT (base_transform), GST_FLOW_ERROR);
+ li = GST_COLORCONVERT (base_transform);
+
+ gst_video_format_parse_caps (incaps, &li->format, &li->width, &li->height);
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_colorconvert_transform_ip (GstBaseTransform * base_transform,
+ GstBuffer * buf)
+{
+ GstColorconvert *li;
+ CogFrame *frame;
+ CogFrame *vf;
+
+ g_return_val_if_fail (GST_IS_COLORCONVERT (base_transform), GST_FLOW_ERROR);
+ li = GST_COLORCONVERT (base_transform);
+
+ frame = gst_cog_buffer_wrap (gst_buffer_ref (buf),
+ li->format, li->width, li->height);
+
+ vf = cog_virt_frame_new_unpack (cog_frame_ref (frame));
+ vf = cog_virt_frame_new_subsample (vf, COG_FRAME_FORMAT_U8_444);
+ vf = cog_virt_frame_new_color_transform (vf);
+ if (frame->format == COG_FRAME_FORMAT_YUYV) {
+ vf = cog_virt_frame_new_subsample (vf, COG_FRAME_FORMAT_U8_422);
+ vf = cog_virt_frame_new_pack_YUY2 (vf);
+ } else if (frame->format == COG_FRAME_FORMAT_UYVY) {
+ vf = cog_virt_frame_new_subsample (vf, COG_FRAME_FORMAT_U8_422);
+ vf = cog_virt_frame_new_pack_UYVY (vf);
+ } else if (frame->format == COG_FRAME_FORMAT_AYUV) {
+ vf = cog_virt_frame_new_pack_AYUV (vf);
+ } else if (frame->format == COG_FRAME_FORMAT_U8_420) {
+ vf = cog_virt_frame_new_subsample (vf, COG_FRAME_FORMAT_U8_420);
+ } else {
+ g_assert_not_reached ();
+ }
+
+ cog_virt_frame_render (vf, frame);
+
+ cog_frame_unref (frame);
+ cog_frame_unref (vf);
+
+ return GST_FLOW_OK;
+}
+
+
+
+static void
+color_transform (CogFrame * frame, void *_dest, int component, int j)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src_y;
+ uint8_t *src_u;
+ uint8_t *src_v;
+ uint8_t *table;
+ int i;
+
+ table = COG_OFFSET (frame->virt_priv2, component * 0x1000000);
+
+ src_y = cog_virt_frame_get_line (frame->virt_frame1, 0, j);
+ src_u = cog_virt_frame_get_line (frame->virt_frame1, 1, j);
+ src_v = cog_virt_frame_get_line (frame->virt_frame1, 2, j);
+
+ for (i = 0; i < frame->width; i++) {
+ dest[i] = table[(src_y[i] << 16) | (src_u[i] << 8) | (src_v[i])];
+ }
+}
+
+static uint8_t *get_color_transform_table (void);
+
+static CogFrame *
+cog_virt_frame_new_color_transform (CogFrame * frame)
+{
+ CogFrame *virt_frame;
+
+ COG_ASSERT (frame->format == COG_FRAME_FORMAT_U8_444);
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
+ frame->width, frame->height);
+ virt_frame->virt_frame1 = frame;
+ virt_frame->render_line = color_transform;
+
+ virt_frame->virt_priv2 = get_color_transform_table ();
+
+ return virt_frame;
+}
+
+
+/* our simple CMS */
+
+typedef struct _Color Color;
+typedef struct _ColorMatrix ColorMatrix;
+
+struct _Color
+{
+ double v[3];
+};
+
+struct _ColorMatrix
+{
+ double m[4][4];
+};
+
+void
+color_xyY_to_XYZ (Color * c)
+{
+ if (c->v[1] == 0) {
+ c->v[0] = 0;
+ c->v[1] = 0;
+ c->v[2] = 0;
+ } else {
+ double X, Y, Z;
+ X = c->v[0] * c->v[2] / c->v[1];
+ Y = c->v[2];
+ Z = (1.0 - c->v[0] - c->v[1]) * c->v[2] / c->v[1];
+ c->v[0] = X;
+ c->v[1] = Y;
+ c->v[2] = Z;
+ }
+}
+
+void
+color_XYZ_to_xyY (Color * c)
+{
+ double d;
+ d = c->v[0] + c->v[1] + c->v[2];
+ if (d == 0) {
+ c->v[0] = 0.3128;
+ c->v[1] = 0.3290;
+ c->v[2] = 0;
+ } else {
+ double x, y, Y;
+ x = c->v[0] / d;
+ y = c->v[1] / d;
+ Y = c->v[1];
+ c->v[0] = x;
+ c->v[1] = y;
+ c->v[2] = Y;
+ }
+}
+
+void
+color_set (Color * c, double x, double y, double z)
+{
+ c->v[0] = x;
+ c->v[1] = y;
+ c->v[2] = z;
+}
+
+void
+color_matrix_set_identity (ColorMatrix * m)
+{
+ int i, j;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m->m[i][j] = (i == j);
+ }
+ }
+}
+
+/* Prettyprint a 4x4 matrix @m@ */
+void
+color_matrix_dump (ColorMatrix * m)
+{
+ int i, j;
+
+ printf ("[\n");
+ for (i = 0; i < 4; i++) {
+ printf (" ");
+ for (j = 0; j < 4; j++) {
+ printf (" %8.5g", m->m[i][j]);
+ }
+ printf ("\n");
+ }
+ printf ("]\n");
+}
+
+/* Perform 4x4 matrix multiplication:
+ * - @dst@ = @a@ * @b@
+ * - @dst@ may be a pointer to @a@ andor @b@
+ */
+void
+color_matrix_multiply (ColorMatrix * dst, ColorMatrix * a, ColorMatrix * b)
+{
+ ColorMatrix tmp;
+ int i, j, k;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ double x = 0;
+ for (k = 0; k < 4; k++) {
+ x += a->m[i][k] * b->m[k][j];
+ }
+ tmp.m[i][j] = x;
+ }
+ }
+
+ memcpy (dst, &tmp, sizeof (ColorMatrix));
+}
+
+void
+color_matrix_apply (ColorMatrix * m, Color * dest, Color * src)
+{
+ int i;
+ Color tmp;
+
+ for (i = 0; i < 3; i++) {
+ double x = 0;
+ x += m->m[i][0] * src->v[0];
+ x += m->m[i][1] * src->v[1];
+ x += m->m[i][2] * src->v[2];
+ x += m->m[i][3];
+ tmp.v[i] = x;
+ }
+ memcpy (dest, &tmp, sizeof (tmp));
+}
+
+void
+color_matrix_offset_components (ColorMatrix * m, double a1, double a2,
+ double a3)
+{
+ ColorMatrix a;
+
+ color_matrix_set_identity (&a);
+ a.m[0][3] = a1;
+ a.m[1][3] = a2;
+ a.m[2][3] = a3;
+ color_matrix_multiply (m, &a, m);
+}
+
+void
+color_matrix_scale_components (ColorMatrix * m, double a1, double a2, double a3)
+{
+ ColorMatrix a;
+
+ color_matrix_set_identity (&a);
+ a.m[0][0] = a1;
+ a.m[1][1] = a2;
+ a.m[2][2] = a3;
+ color_matrix_multiply (m, &a, m);
+}
+
+void
+color_matrix_YCbCr_to_RGB (ColorMatrix * m, double Kr, double Kb)
+{
+ double Kg = 1.0 - Kr - Kb;
+ ColorMatrix k = {
+ {
+ {1., 0., 2 * (1 - Kr), 0.},
+ {1., -2 * Kb * (1 - Kb) / Kg, -2 * Kr * (1 - Kr) / Kg, 0.},
+ {1., 2 * (1 - Kb), 0., 0.},
+ {0., 0., 0., 1.},
+ }
+ };
+
+ color_matrix_multiply (m, &k, m);
+}
+
+void
+color_matrix_RGB_to_YCbCr (ColorMatrix * m, double Kr, double Kb)
+{
+ double Kg = 1.0 - Kr - Kb;
+ ColorMatrix k;
+ double x;
+
+ k.m[0][0] = Kr;
+ k.m[0][1] = Kg;
+ k.m[0][2] = Kb;
+ k.m[0][3] = 0;
+
+ x = 1 / (2 * (1 - Kb));
+ k.m[1][0] = -x * Kr;
+ k.m[1][1] = -x * Kg;
+ k.m[1][2] = x * (1 - Kb);
+ k.m[1][3] = 0;
+
+ x = 1 / (2 * (1 - Kr));
+ k.m[2][0] = x * (1 - Kr);
+ k.m[2][1] = -x * Kg;
+ k.m[2][2] = -x * Kb;
+ k.m[2][3] = 0;
+
+ k.m[3][0] = 0;
+ k.m[3][1] = 0;
+ k.m[3][2] = 0;
+ k.m[3][3] = 1;
+
+ color_matrix_multiply (m, &k, m);
+}
+
+void
+color_matrix_build_yuv_to_rgb_601 (ColorMatrix * dst)
+{
+ /*
+ * At this point, everything is in YCbCr
+ * All components are in the range [0,255]
+ */
+ color_matrix_set_identity (dst);
+
+ /* offset required to get input video black to (0.,0.,0.) */
+ color_matrix_offset_components (dst, -16, -128, -128);
+
+ /* scale required to get input video black to (0.,0.,0.) */
+ color_matrix_scale_components (dst, (1 / 219.0), (1 / 224.0), (1 / 224.0));
+
+ /* colour matrix, YCbCr -> RGB */
+ /* Requires Y in [0,1.0], Cb&Cr in [-0.5,0.5] */
+ color_matrix_YCbCr_to_RGB (dst, 0.2990, 0.1140); // SD
+ //color_matrix_YCbCr_to_RGB (dst, 0.2126, 0.0722); // HD
+
+ /*
+ * We are now in RGB space
+ */
+
+ /* scale to output range. */
+ //color_matrix_scale_components (dst, 255.0, 255.0, 255.0);
+}
+
+void
+color_matrix_build_bt709_to_bt601 (ColorMatrix * dst)
+{
+ color_matrix_set_identity (dst);
+
+ /* offset required to get input video black to (0.,0.,0.) */
+ color_matrix_offset_components (dst, -16, -128, -128);
+
+ /* scale required to get input video black to (0.,0.,0.) */
+ color_matrix_scale_components (dst, (1 / 219.0), (1 / 224.0), (1 / 224.0));
+
+ /* colour matrix, YCbCr -> RGB */
+ /* Requires Y in [0,1.0], Cb&Cr in [-0.5,0.5] */
+ //color_matrix_YCbCr_to_RGB (dst, 0.2990, 0.1140); // SD
+ color_matrix_YCbCr_to_RGB (dst, 0.2126, 0.0722); // HD
+
+ color_matrix_RGB_to_YCbCr (dst, 0.2990, 0.1140); // SD
+
+ color_matrix_scale_components (dst, 219.0, 224.0, 224.0);
+
+ color_matrix_offset_components (dst, 16, 128, 128);
+}
+
+void
+color_matrix_build_rgb_to_yuv_601 (ColorMatrix * dst)
+{
+ color_matrix_set_identity (dst);
+
+ //color_matrix_scale_components (dst, (1/255.0), (1/255.0), (1/255.0));
+
+ color_matrix_RGB_to_YCbCr (dst, 0.2990, 0.1140); // SD
+ //color_matrix_RGB_to_YCbCr (dst, 0.2126, 0.0722); // HD
+ //color_matrix_RGB_to_YCbCr (dst, 0.212, 0.087); // SMPTE 240M
+
+ color_matrix_scale_components (dst, 219.0, 224.0, 224.0);
+
+ color_matrix_offset_components (dst, 16, 128, 128);
+
+ {
+ Color c;
+ int i;
+ for (i = 7; i >= 0; i--) {
+ color_set (&c, (i & 2) ? 0.75 : 0.0, (i & 4) ? 0.75 : 0.0,
+ (i & 1) ? 0.75 : 0.0);
+ color_matrix_apply (dst, &c, &c);
+ g_print (" { %g, %g, %g },\n", rint (c.v[0]), rint (c.v[1]),
+ rint (c.v[2]));
+ }
+ color_set (&c, -0.075, -0.075, -0.075);
+ color_matrix_apply (dst, &c, &c);
+ g_print (" { %g, %g, %g },\n", rint (c.v[0]), rint (c.v[1]),
+ rint (c.v[2]));
+ color_set (&c, 0.075, 0.075, 0.075);
+ color_matrix_apply (dst, &c, &c);
+ g_print (" { %g, %g, %g },\n", rint (c.v[0]), rint (c.v[1]),
+ rint (c.v[2]));
+ }
+}
+
+void
+color_matrix_invert (ColorMatrix * m)
+{
+ ColorMatrix tmp;
+ int i, j;
+ double det;
+
+ color_matrix_set_identity (&tmp);
+ for (j = 0; j < 3; j++) {
+ for (i = 0; i < 3; i++) {
+ tmp.m[j][i] =
+ m->m[(i + 1) % 3][(j + 1) % 3] * m->m[(i + 2) % 3][(j + 2) % 3] -
+ m->m[(i + 1) % 3][(j + 2) % 3] * m->m[(i + 2) % 3][(j + 1) % 3];
+ }
+ }
+ det =
+ tmp.m[0][0] * m->m[0][0] + tmp.m[0][1] * m->m[1][0] +
+ tmp.m[0][2] * m->m[2][0];
+ for (j = 0; j < 3; j++) {
+ for (i = 0; i < 3; i++) {
+ tmp.m[i][j] /= det;
+ }
+ }
+ memcpy (m, &tmp, sizeof (tmp));
+}
+
+void
+color_matrix_copy (ColorMatrix * dest, ColorMatrix * src)
+{
+ memcpy (dest, src, sizeof (ColorMatrix));
+}
+
+void
+color_matrix_transpose (ColorMatrix * m)
+{
+ int i, j;
+ ColorMatrix tmp;
+
+ color_matrix_set_identity (&tmp);
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ tmp.m[i][j] = m->m[j][i];
+ }
+ }
+ memcpy (m, &tmp, sizeof (ColorMatrix));
+}
+
+void
+color_matrix_build_XYZ (ColorMatrix * dst,
+ double rx, double ry,
+ double gx, double gy, double bx, double by, double wx, double wy)
+{
+ Color r, g, b, w, scale;
+ ColorMatrix m;
+
+ color_set (&r, rx, ry, 1.0);
+ color_xyY_to_XYZ (&r);
+ color_set (&g, gx, gy, 1.0);
+ color_xyY_to_XYZ (&g);
+ color_set (&b, bx, by, 1.0);
+ color_xyY_to_XYZ (&b);
+ color_set (&w, wx, wy, 1.0);
+ color_xyY_to_XYZ (&w);
+
+ color_matrix_set_identity (dst);
+
+ dst->m[0][0] = r.v[0];
+ dst->m[0][1] = r.v[1];
+ dst->m[0][2] = r.v[2];
+ dst->m[1][0] = g.v[0];
+ dst->m[1][1] = g.v[1];
+ dst->m[1][2] = g.v[2];
+ dst->m[2][0] = b.v[0];
+ dst->m[2][1] = b.v[1];
+ dst->m[2][2] = b.v[2];
+
+ color_matrix_dump (dst);
+ color_matrix_copy (&m, dst);
+ color_matrix_invert (&m);
+ color_matrix_dump (&m);
+
+ color_matrix_transpose (&m);
+ color_matrix_apply (&m, &scale, &w);
+ g_print ("%g %g %g\n", scale.v[0], scale.v[1], scale.v[2]);
+
+ dst->m[0][0] = r.v[0] * scale.v[0];
+ dst->m[0][1] = r.v[1] * scale.v[0];
+ dst->m[0][2] = r.v[2] * scale.v[0];
+ dst->m[1][0] = g.v[0] * scale.v[1];
+ dst->m[1][1] = g.v[1] * scale.v[1];
+ dst->m[1][2] = g.v[2] * scale.v[1];
+ dst->m[2][0] = b.v[0] * scale.v[2];
+ dst->m[2][1] = b.v[1] * scale.v[2];
+ dst->m[2][2] = b.v[2] * scale.v[2];
+
+ color_matrix_transpose (dst);
+ color_matrix_dump (dst);
+
+ color_set (&scale, 1, 1, 1);
+ color_matrix_apply (dst, &scale, &scale);
+ color_XYZ_to_xyY (&scale);
+ g_print ("white %g %g %g\n", scale.v[0], scale.v[1], scale.v[2]);
+
+}
+
+void
+color_matrix_build_rgb_to_XYZ_601 (ColorMatrix * dst)
+{
+ /* SMPTE C primaries, SMPTE 170M-2004 */
+ color_matrix_build_XYZ (dst,
+ 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, 0.3127, 0.3290);
+#if 0
+ /* NTSC 1953 primaries, SMPTE 170M-2004 */
+ color_matrix_build_XYZ (dst,
+ 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, 0.3127, 0.3290);
+#endif
+}
+
+void
+color_matrix_build_XYZ_to_rgb_709 (ColorMatrix * dst)
+{
+ /* Rec. ITU-R BT.709-5 */
+ color_matrix_build_XYZ (dst,
+ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060, 0.3127, 0.3290);
+}
+
+void
+color_matrix_build_XYZ_to_rgb_dell (ColorMatrix * dst)
+{
+ /* Dell monitor */
+#if 1
+ color_matrix_build_XYZ (dst,
+ 0.662, 0.329, 0.205, 0.683, 0.146, 0.077, 0.3135, 0.3290);
+#endif
+#if 0
+ color_matrix_build_XYZ (dst,
+ 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, 0.3127, 0.3290);
+#endif
+ color_matrix_invert (dst);
+}
+
+void
+color_transfer_function_apply (Color * dest, Color * src)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (src->v[i] < 0.0812) {
+ dest->v[i] = src->v[i] / 4.500;
+ } else {
+ dest->v[i] = pow (src->v[i] + 0.099, 1 / 0.4500);
+ }
+ }
+}
+
+void
+color_transfer_function_unapply (Color * dest, Color * src)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (src->v[i] < 0.0812 / 4.500) {
+ dest->v[i] = src->v[i] * 4.500;
+ } else {
+ dest->v[i] = pow (src->v[i], 0.4500) - 0.099;
+ }
+ }
+}
+
+void
+color_gamut_clamp (Color * dest, Color * src)
+{
+ dest->v[0] = CLAMP (src->v[0], 0.0, 1.0);
+ dest->v[1] = CLAMP (src->v[1], 0.0, 1.0);
+ dest->v[2] = CLAMP (src->v[2], 0.0, 1.0);
+}
+
+static uint8_t *
+get_color_transform_table (void)
+{
+ static uint8_t *color_transform_table = NULL;
+
+#if 1
+ if (!color_transform_table) {
+ ColorMatrix bt601_to_rgb;
+ ColorMatrix bt601_to_yuv;
+ ColorMatrix bt601_rgb_to_XYZ;
+ ColorMatrix dell_XYZ_to_rgb;
+ uint8_t *table_y;
+ uint8_t *table_u;
+ uint8_t *table_v;
+ int y, u, v;
+
+ color_matrix_build_yuv_to_rgb_601 (&bt601_to_rgb);
+ color_matrix_build_rgb_to_yuv_601 (&bt601_to_yuv);
+ color_matrix_build_rgb_to_XYZ_601 (&bt601_rgb_to_XYZ);
+ color_matrix_build_XYZ_to_rgb_dell (&dell_XYZ_to_rgb);
+
+ color_transform_table = g_malloc (0x1000000 * 3);
+
+ table_y = COG_OFFSET (color_transform_table, 0 * 0x1000000);
+ table_u = COG_OFFSET (color_transform_table, 1 * 0x1000000);
+ table_v = COG_OFFSET (color_transform_table, 2 * 0x1000000);
+
+ for (y = 0; y < 256; y++) {
+ for (u = 0; u < 256; u++) {
+ for (v = 0; v < 256; v++) {
+ Color c;
+
+ c.v[0] = y;
+ c.v[1] = u;
+ c.v[2] = v;
+ color_matrix_apply (&bt601_to_rgb, &c, &c);
+ color_gamut_clamp (&c, &c);
+ color_transfer_function_apply (&c, &c);
+ color_matrix_apply (&bt601_rgb_to_XYZ, &c, &c);
+ color_matrix_apply (&dell_XYZ_to_rgb, &c, &c);
+ color_transfer_function_unapply (&c, &c);
+ color_gamut_clamp (&c, &c);
+ color_matrix_apply (&bt601_to_yuv, &c, &c);
+
+ table_y[(y << 16) | (u << 8) | (v)] = rint (c.v[0]);
+ table_u[(y << 16) | (u << 8) | (v)] = rint (c.v[1]);
+ table_v[(y << 16) | (u << 8) | (v)] = rint (c.v[2]);
+ }
+ }
+ }
+ }
+#endif
+#if 0
+ if (!color_transform_table) {
+ ColorMatrix bt709_to_bt601;
+ uint8_t *table_y;
+ uint8_t *table_u;
+ uint8_t *table_v;
+ int y, u, v;
+
+ color_matrix_build_bt709_to_bt601 (&bt709_to_bt601);
+
+ color_transform_table = g_malloc (0x1000000 * 3);
+
+ table_y = COG_OFFSET (color_transform_table, 0 * 0x1000000);
+ table_u = COG_OFFSET (color_transform_table, 1 * 0x1000000);
+ table_v = COG_OFFSET (color_transform_table, 2 * 0x1000000);
+
+ for (y = 0; y < 256; y++) {
+ for (u = 0; u < 256; u++) {
+ for (v = 0; v < 256; v++) {
+ Color c;
+
+ c.v[0] = y;
+ c.v[1] = u;
+ c.v[2] = v;
+ color_matrix_apply (&bt709_to_bt601, &c, &c);
+
+ table_y[(y << 16) | (u << 8) | (v)] = rint (c.v[0]);
+ table_u[(y << 16) | (u << 8) | (v)] = rint (c.v[1]);
+ table_v[(y << 16) | (u << 8) | (v)] = rint (c.v[2]);
+ }
+ }
+ }
+ }
+#endif
+
+ return color_transform_table;
+}
diff --git a/ext/cog/gstlogoinsert.c b/ext/cog/gstlogoinsert.c
new file mode 100644
index 000000000..1384aa349
--- /dev/null
+++ b/ext/cog/gstlogoinsert.c
@@ -0,0 +1,458 @@
+/* GStreamer
+ * Copyright (C) 2008 David Schleef <ds@entropywave.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/video/video.h>
+#include <string.h>
+#include <cog/cog.h>
+#include <cog-video/cogvirtframe.h>
+#include <math.h>
+#include <png.h>
+#include "gstcogutils.h"
+
+#define GST_TYPE_LOGOINSERT \
+ (gst_logoinsert_get_type())
+#define GST_LOGOINSERT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LOGOINSERT,GstLogoinsert))
+#define GST_LOGOINSERT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LOGOINSERT,GstLogoinsertClass))
+#define GST_IS_LOGOINSERT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LOGOINSERT))
+#define GST_IS_LOGOINSERT_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LOGOINSERT))
+
+typedef struct _GstLogoinsert GstLogoinsert;
+typedef struct _GstLogoinsertClass GstLogoinsertClass;
+
+struct _GstLogoinsert
+{
+ GstBaseTransform base_transform;
+
+ gchar *location;
+
+ GstVideoFormat format;
+ int width;
+ int height;
+
+ gchar *data;
+ gsize size;
+ CogFrame *overlay_frame;
+ CogFrame *ayuv_frame;
+ CogFrame *alpha_frame;
+
+};
+
+struct _GstLogoinsertClass
+{
+ GstBaseTransformClass parent_class;
+
+};
+
+
+/* GstLogoinsert signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+ ARG_LOCATION,
+};
+
+GType gst_logoinsert_get_type (void);
+
+static void gst_logoinsert_base_init (gpointer g_class);
+static void gst_logoinsert_class_init (gpointer g_class, gpointer class_data);
+static void gst_logoinsert_init (GTypeInstance * instance, gpointer g_class);
+
+static void gst_logoinsert_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_logoinsert_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static void gst_logoinsert_set_location (GstLogoinsert * li,
+ const gchar * location);
+
+static gboolean gst_logoinsert_set_caps (GstBaseTransform * base_transform,
+ GstCaps * incaps, GstCaps * outcaps);
+static GstFlowReturn gst_logoinsert_transform_ip (GstBaseTransform *
+ base_transform, GstBuffer * buf);
+static CogFrame *cog_frame_new_from_png (void *data, int size);
+static CogFrame *cog_virt_frame_extract_alpha (CogFrame * frame);
+static CogFrame *cog_frame_realize (CogFrame * frame);
+
+static GstStaticPadTemplate gst_logoinsert_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
+ );
+
+static GstStaticPadTemplate gst_logoinsert_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,YUY2,UYVY,AYUV}"))
+ );
+
+GType
+gst_logoinsert_get_type (void)
+{
+ static GType compress_type = 0;
+
+ if (!compress_type) {
+ static const GTypeInfo compress_info = {
+ sizeof (GstLogoinsertClass),
+ gst_logoinsert_base_init,
+ NULL,
+ gst_logoinsert_class_init,
+ NULL,
+ NULL,
+ sizeof (GstLogoinsert),
+ 0,
+ gst_logoinsert_init,
+ };
+
+ compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
+ "GstLogoinsert", &compress_info, 0);
+ }
+ return compress_type;
+}
+
+
+static void
+gst_logoinsert_base_init (gpointer g_class)
+{
+ static GstElementDetails compress_details =
+ GST_ELEMENT_DETAILS ("Video Filter Template",
+ "Filter/Effect/Video",
+ "Template for a video filter",
+ "David Schleef <ds@schleef.org>");
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ //GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_logoinsert_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_logoinsert_sink_template));
+
+ gst_element_class_set_details (element_class, &compress_details);
+}
+
+static void
+gst_logoinsert_class_init (gpointer g_class, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *base_transform_class;
+ GstLogoinsertClass *filter_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ base_transform_class = GST_BASE_TRANSFORM_CLASS (g_class);
+ filter_class = GST_LOGOINSERT_CLASS (g_class);
+
+ gobject_class->set_property = gst_logoinsert_set_property;
+ gobject_class->get_property = gst_logoinsert_get_property;
+
+ g_object_class_install_property (gobject_class, ARG_LOCATION,
+ g_param_spec_string ("location", "location",
+ "location of PNG file to overlay", "", G_PARAM_READWRITE));
+
+ base_transform_class->set_caps = gst_logoinsert_set_caps;
+ base_transform_class->transform_ip = gst_logoinsert_transform_ip;
+}
+
+static void
+gst_logoinsert_init (GTypeInstance * instance, gpointer g_class)
+{
+ //GstLogoinsert *compress = GST_LOGOINSERT (instance);
+ //GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
+
+ GST_DEBUG ("gst_logoinsert_init");
+}
+
+static void
+gst_logoinsert_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstLogoinsert *src;
+
+ g_return_if_fail (GST_IS_LOGOINSERT (object));
+ src = GST_LOGOINSERT (object);
+
+ GST_DEBUG ("gst_logoinsert_set_property");
+ switch (prop_id) {
+ case ARG_LOCATION:
+ gst_logoinsert_set_location (src, g_value_get_string (value));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_logoinsert_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstLogoinsert *src;
+
+ g_return_if_fail (GST_IS_LOGOINSERT (object));
+ src = GST_LOGOINSERT (object);
+
+ switch (prop_id) {
+ case ARG_LOCATION:
+ g_value_set_string (value, src->location);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+gst_logoinsert_set_caps (GstBaseTransform * base_transform,
+ GstCaps * incaps, GstCaps * outcaps)
+{
+ GstLogoinsert *li;
+
+ g_return_val_if_fail (GST_IS_LOGOINSERT (base_transform), GST_FLOW_ERROR);
+ li = GST_LOGOINSERT (base_transform);
+
+ gst_video_format_parse_caps (incaps, &li->format, &li->width, &li->height);
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_logoinsert_transform_ip (GstBaseTransform * base_transform, GstBuffer * buf)
+{
+ GstLogoinsert *li;
+ CogFrame *frame;
+
+ g_return_val_if_fail (GST_IS_LOGOINSERT (base_transform), GST_FLOW_ERROR);
+ li = GST_LOGOINSERT (base_transform);
+
+ frame = gst_cog_buffer_wrap (buf, li->format, li->width, li->height);
+
+ if (li->ayuv_frame == NULL)
+ return GST_FLOW_OK;
+
+ if (li->overlay_frame == NULL) {
+ CogFrame *f;
+
+ f = cog_virt_frame_extract_alpha (cog_frame_ref (li->ayuv_frame));
+ f = cog_virt_frame_new_subsample (f, frame->format);
+ li->alpha_frame = cog_frame_realize (f);
+
+ f = cog_virt_frame_new_unpack (cog_frame_ref (li->ayuv_frame));
+ f = cog_virt_frame_new_color_matrix (f);
+ f = cog_virt_frame_new_subsample (f, frame->format);
+ li->overlay_frame = cog_frame_realize (f);
+ }
+
+ if (1) {
+ int i, j;
+ int k;
+ guint8 *dest;
+ guint8 *src;
+ guint8 *alpha;
+ int offset_x, offset_y;
+
+ for (k = 0; k < 3; k++) {
+ offset_x = frame->components[k].width -
+ li->alpha_frame->components[k].width;
+ offset_y = frame->components[k].height -
+ li->alpha_frame->components[k].height;
+
+ for (j = 0; j < li->overlay_frame->components[k].height; j++) {
+ dest = COG_FRAME_DATA_GET_LINE (frame->components + k, j + offset_y);
+ src = COG_FRAME_DATA_GET_LINE (li->overlay_frame->components + k, j);
+ alpha = COG_FRAME_DATA_GET_LINE (li->alpha_frame->components + k, j);
+
+#define oil_divide_255(x) ((((x)+128) + (((x)+128)>>8))>>8)
+
+ for (i = 0; i < li->overlay_frame->components[k].width; i++) {
+ dest[i + offset_x] =
+ oil_divide_255 (src[i] * alpha[i] + dest[i + offset_x] * (255 -
+ alpha[i]));
+ }
+ }
+ }
+ }
+
+
+ return GST_FLOW_OK;
+}
+
+static void
+gst_logoinsert_set_location (GstLogoinsert * li, const gchar * location)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ g_free (li->location);
+ g_free (li->data);
+ if (li->overlay_frame) {
+ cog_frame_unref (li->overlay_frame);
+ li->overlay_frame = NULL;
+ }
+
+ li->location = g_strdup (location);
+
+ ret = g_file_get_contents (li->location, &li->data, &li->size, &error);
+ if (!ret) {
+ li->data = NULL;
+ li->size = 0;
+ return;
+ }
+
+ li->ayuv_frame = cog_frame_new_from_png (li->data, li->size);
+
+ if (li->alpha_frame) {
+ cog_frame_unref (li->alpha_frame);
+ li->alpha_frame = NULL;
+ }
+ if (li->overlay_frame) {
+ cog_frame_unref (li->overlay_frame);
+ li->overlay_frame = NULL;
+ }
+}
+
+
+/* load PNG into CogFrame */
+
+struct png_data_struct
+{
+ unsigned char *data;
+ int size;
+ int offset;
+};
+
+static void
+read_data (png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ struct png_data_struct *s = png_ptr->io_ptr;
+
+ memcpy (data, s->data + s->offset, length);
+ s->offset += length;
+}
+
+static CogFrame *
+cog_frame_new_from_png (void *data, int size)
+{
+ struct png_data_struct s = { 0 };
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_bytep *rows;
+ CogFrame *frame;
+ guchar *frame_data;
+ int rowbytes;
+ int j;
+ int width, height;
+ int color_type;
+
+ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info_ptr = png_create_info_struct (png_ptr);
+
+ s.data = data;
+ s.size = size;
+ png_set_read_fn (png_ptr, (void *) &s, read_data);
+
+ png_read_info (png_ptr, info_ptr);
+
+ width = png_get_image_width (png_ptr, info_ptr);
+ height = png_get_image_height (png_ptr, info_ptr);
+ color_type = png_get_color_type (png_ptr, info_ptr);
+ GST_DEBUG ("PNG size %dx%d color_type %d", width, height, color_type);
+
+ png_set_strip_16 (png_ptr);
+ png_set_packing (png_ptr);
+ if (color_type == PNG_COLOR_TYPE_RGB) {
+ png_set_filler (png_ptr, 0xff, PNG_FILLER_BEFORE);
+ }
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ png_set_swap_alpha (png_ptr);
+ }
+
+ frame_data = g_malloc (width * height * 4);
+ frame = cog_frame_new_from_data_AYUV (frame_data, width, height);
+
+ rowbytes = png_get_rowbytes (png_ptr, info_ptr);
+ rows = (png_bytep *) g_malloc (sizeof (png_bytep) * height);
+
+ for (j = 0; j < height; j++) {
+ rows[j] = COG_FRAME_DATA_GET_LINE (frame->components + 0, j);
+ }
+ png_read_image (png_ptr, rows);
+ g_free (rows);
+
+ // PNG_TRANSFORM_STRP_16 | PNG_TRANSFORM_PACKING,
+
+ png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
+
+
+ return frame;
+}
+
+static void
+extract_alpha (CogFrame * frame, void *_dest, int component, int j)
+{
+ uint8_t *dest = _dest;
+ uint8_t *src;
+ int i;
+
+ src = COG_FRAME_DATA_GET_LINE (frame->virt_frame1->components + 0, j);
+ for (i = 0; i < frame->width; i++) {
+ dest[i] = src[i * 4 + 0];
+ }
+}
+
+static CogFrame *
+cog_virt_frame_extract_alpha (CogFrame * frame)
+{
+ CogFrame *virt_frame;
+
+ /* FIXME check that frame is a real AYUV frame */
+
+ virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
+ frame->width, frame->height);
+ virt_frame->virt_frame1 = frame;
+ virt_frame->render_line = extract_alpha;
+
+ return virt_frame;
+}
+
+static CogFrame *
+cog_frame_realize (CogFrame * frame)
+{
+ CogFrame *dest;
+
+ dest = cog_frame_clone (NULL, frame);
+ cog_virt_frame_render (frame, dest);
+ cog_frame_unref (frame);
+
+ return dest;
+}