From 3fb41e2cc31d0b3f507a40bfa35402a348e2a0f6 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 2 Dec 2011 23:34:47 +0100 Subject: [PATCH 01/31] tests: add a test for fft result value-ranges Add a small example that uses ffts of various types and parameters and check the result value ranges. --- configure.ac | 1 + tests/examples/Makefile.am | 2 +- tests/examples/fft/.gitignore | 2 + tests/examples/fft/fftrange.c | 184 ++++++++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 tests/examples/fft/.gitignore create mode 100644 tests/examples/fft/fftrange.c diff --git a/configure.ac b/configure.ac index b0814fce59..49b96531cc 100644 --- a/configure.ac +++ b/configure.ac @@ -1015,6 +1015,7 @@ tests/examples/app/Makefile tests/examples/audio/Makefile tests/examples/dynamic/Makefile tests/examples/encoding/Makefile +tests/examples/fft/Makefile tests/examples/gio/Makefile tests/examples/overlay/Makefile tests/examples/seek/Makefile diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index f44e6e81cf..475ca45695 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -8,7 +8,7 @@ if USE_GIO GIO_SUBDIRS = gio endif -SUBDIRS = app audio dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec v4l encoding +SUBDIRS = app audio dynamic fft $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec v4l encoding DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec v4l encoding diff --git a/tests/examples/fft/.gitignore b/tests/examples/fft/.gitignore new file mode 100644 index 0000000000..74f063698b --- /dev/null +++ b/tests/examples/fft/.gitignore @@ -0,0 +1,2 @@ +fftrange + diff --git a/tests/examples/fft/fftrange.c b/tests/examples/fft/fftrange.c new file mode 100644 index 0000000000..956f4a3525 --- /dev/null +++ b/tests/examples/fft/fftrange.c @@ -0,0 +1,184 @@ +/* GStreamer + * (c) 2011 Stefan Kost + * + * 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. + */ + +#include +#include +#include +#include +#include + +/* effectively max range seems to be 1/4 of what it should be */ + +#define MAKE_I_TEST(_g_,_G_,_t_,_T_,_f_) \ +static void \ +test_##_t_ (const gchar *test_name, gint num_freq, gint window) \ +{ \ + GstFFT ##_T_ *ctx; \ + GstFFT ##_T_ ##Complex *fdata; \ + _g_ *adata; \ + _g_ maxfr = 0, maxfi = 0; \ + gint num_samples = num_freq * 2 - 2; \ + gint s, f; \ + \ + ctx = gst_fft_ ##_t_ ##_new (num_samples, FALSE); \ + fdata = g_new (GstFFT ##_T_ ##Complex, num_freq); \ + adata = g_new (_g_, num_samples); \ + \ + for (s = 0; s < num_samples;) { \ + adata[s++]=G_MIN##_G_; \ + adata[s++]=G_MAX##_G_; \ + } \ + \ + gst_fft_ ##_t_ ##_window (ctx, adata, window); \ + gst_fft_ ##_t_ ##_fft (ctx, adata, fdata); \ + \ + for (f = 0; f < num_freq; f++) { \ + if (fdata[1+f].r > maxfr) \ + maxfr = fdata[1+f].r; \ + if (fdata[1+f].i > maxfi) \ + maxfi = fdata[1+f].i; \ + } \ + \ + printf (#_t_" %-15s: maxfr: %"_f_" %10.5f maxfi: %"_f_" %10.5f\n",\ + test_name, \ + maxfr, (gfloat)G_MAX##_G_/maxfr, \ + maxfi, (gfloat)G_MAX##_G_/maxfi); \ + \ + gst_fft_ ##_t_ ##_free (ctx); \ + g_free (fdata); \ + g_free (adata); \ +} + +MAKE_I_TEST (gint16, INT16, s16, S16, "6d"); +MAKE_I_TEST (gint32, INT32, s32, S32, "9d"); + +#define MAKE_F_TEST(_g_,_G_,_t_,_T_,_f_) \ +static void \ +test_##_t_ (const gchar *test_name, gint num_freq, gint window) \ +{ \ + GstFFT ##_T_ *ctx; \ + GstFFT ##_T_ ##Complex *fdata; \ + _g_ *adata; \ + _g_ maxfr = 0, maxfi = 0; \ + gint num_samples = num_freq * 2 - 2; \ + gint s, f; \ + \ + ctx = gst_fft_ ##_t_ ##_new (num_samples, FALSE); \ + fdata = g_new (GstFFT ##_T_ ##Complex, num_freq); \ + adata = g_new (_g_, num_samples); \ + \ + for (s = 0; s < num_samples;) { \ + adata[s++]=-1.0; \ + adata[s++]=+1.0; \ + } \ + \ + gst_fft_ ##_t_ ##_window (ctx, adata, window); \ + gst_fft_ ##_t_ ##_fft (ctx, adata, fdata); \ + \ + for (f = 0; f < num_freq; f++) { \ + if (fdata[1+f].r > maxfr) \ + maxfr = fdata[1+f].r; \ + if (fdata[1+f].i > maxfi) \ + maxfi = fdata[1+f].i; \ + } \ + \ + printf (#_t_" %-15s: maxfr: %"_f_" %10.5f maxfi: %"_f_" %10.5f\n",\ + test_name, \ + maxfr, (gfloat)1.0/maxfr, \ + maxfi, (gfloat)1.0/maxfi); \ + \ + gst_fft_ ##_t_ ##_free (ctx); \ + g_free (fdata); \ + g_free (adata); \ +} + +MAKE_F_TEST (gfloat, FLOAT, f32, F32, "10.5f"); +MAKE_F_TEST (gdouble, DOUBLE, f64, F64, "10.5f"); + +gint +main (gint argc, gchar * argv[]) +{ + gint num_bands; + + gst_init (&argc, &argv); + + num_bands = 200; + test_s16 ("200, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_s16 ("200, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_s16 ("200, hann", num_bands, GST_FFT_WINDOW_HANN); + test_s16 ("200, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_s16 ("200, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts (""); + + num_bands = 300; + test_s16 ("300, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_s16 ("300, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_s16 ("300, hann", num_bands, GST_FFT_WINDOW_HANN); + test_s16 ("300, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_s16 ("300, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts ("\n"); + + num_bands = 200; + test_s32 ("200, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_s32 ("200, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_s32 ("200, hann", num_bands, GST_FFT_WINDOW_HANN); + test_s32 ("200, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_s32 ("200, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts (""); + + num_bands = 300; + test_s32 ("300, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_s32 ("300, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_s32 ("300, hann", num_bands, GST_FFT_WINDOW_HANN); + test_s32 ("300, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_s32 ("300, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts ("\n"); + + num_bands = 200; + test_f32 ("200, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_f32 ("200, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_f32 ("200, hann", num_bands, GST_FFT_WINDOW_HANN); + test_f32 ("200, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_f32 ("200, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts (""); + + num_bands = 300; + test_f32 ("300, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_f32 ("300, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_f32 ("300, hann", num_bands, GST_FFT_WINDOW_HANN); + test_f32 ("300, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_f32 ("300, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts ("\n"); + + num_bands = 200; + test_f64 ("200, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_f64 ("200, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_f64 ("200, hann", num_bands, GST_FFT_WINDOW_HANN); + test_f64 ("200, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_f64 ("200, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts (""); + + num_bands = 300; + test_f64 ("300, none", num_bands, GST_FFT_WINDOW_RECTANGULAR); + test_f64 ("300, hamming", num_bands, GST_FFT_WINDOW_HAMMING); + test_f64 ("300, hann", num_bands, GST_FFT_WINDOW_HANN); + test_f64 ("300, bartlett", num_bands, GST_FFT_WINDOW_BARTLETT); + test_f64 ("300, blackman", num_bands, GST_FFT_WINDOW_BLACKMAN); + puts ("\n"); +} From f4213c5e85d902e5032677f1ff76e8c271e4cb7f Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 2 Dec 2011 23:35:50 +0100 Subject: [PATCH 02/31] configure: trim trailing whitespace --- configure.ac | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 49b96531cc..698451ca9b 100644 --- a/configure.ac +++ b/configure.ac @@ -189,7 +189,7 @@ CPPFLAGS="$ac_cppflags_save" AM_CONDITIONAL(HAVE_LIBXML_HTML, test "x$HAVE_LIBXML_HTML" = "xyes") dnl used in gst/tcp -AC_CHECK_HEADERS([sys/socket.h], +AC_CHECK_HEADERS([sys/socket.h], HAVE_SYS_SOCKET_H="yes", HAVE_SYS_SOCKET_H="no") AM_CONDITIONAL(HAVE_SYS_SOCKET_H, test "x$HAVE_SYS_SOCKET_H" = "xyes") @@ -546,7 +546,7 @@ AG_GST_CHECK_FEATURE(X, [X libraries and plugins], CFLAGS="$ac_cflags_save" CPPFLAGS="$ac_cppflags_save" ]) - + dnl Check for Xv extension translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true) AG_GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions], @@ -558,24 +558,24 @@ dnl check for X Shm translit(dnm, m, l) AM_CONDITIONAL(USE_XSHM, true) AG_GST_CHECK_FEATURE(XSHM, [X Shared Memory extension], , [ if test x$HAVE_X = xyes; then - AC_CHECK_LIB(Xext, XShmAttach, + AC_CHECK_LIB(Xext, XShmAttach, HAVE_XSHM="yes", HAVE_XSHM="no", - $X_LIBS) + $X_LIBS) if test "x$HAVE_XSHM" = "xyes"; then XSHM_LIBS="-lXext" else dnl On AIX, it is in XextSam instead, but we still need -lXext - AC_CHECK_LIB(XextSam, XShmAttach, + AC_CHECK_LIB(XextSam, XShmAttach, HAVE_XSHM="yes", HAVE_XSHM="no", - $X_LIBS) + $X_LIBS) if test "x$HAVE_XSHM" = "xyes"; then XSHM_LIBS="-lXext -lXextSam" fi fi fi -], , [ - AC_SUBST(HAVE_XSHM) - AC_SUBST(XSHM_LIBS) +], , [ + AC_SUBST(HAVE_XSHM) + AC_SUBST(XSHM_LIBS) ]) dnl v4l/v4l2 checks have been moved down because they require X @@ -651,17 +651,17 @@ AG_GST_CHECK_FEATURE(CDPARANOIA, [CDParanoia], cdparanoia, [ PKG_CHECK_MODULES(CDPARANOIA, cdparanoia-3 >= 10.2, [ HAVE_CDPARANOIA="yes" ], [ - AG_GST_CHECK_LIBHEADER(CDPARANOIA, cdda_interface, - cdda_open, -lm, - cdda_interface.h, + AG_GST_CHECK_LIBHEADER(CDPARANOIA, cdda_interface, + cdda_open, -lm, + cdda_interface.h, CDPARANOIA_LIBS="-lcdda_interface -lcdda_paranoia" HEADER_DIR="no" FOUND_CDPARANOIA="yes") if test "x$FOUND_CDPARANOIA" != "xyes"; then - AG_GST_CHECK_LIBHEADER(CDPARANOIA, cdda_interface, - cdda_open, -lm, - cdda/cdda_interface.h, + AG_GST_CHECK_LIBHEADER(CDPARANOIA, cdda_interface, + cdda_open, -lm, + cdda/cdda_interface.h, CDPARANOIA_LIBS="-lcdda_interface -lcdda_paranoia" HEADER_DIR="yes" FOUND_CDPARANOIA="yes") From 5398950012f4c50f1c8726c1a10978ce74be8c95 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Sun, 4 Dec 2011 13:43:06 +0100 Subject: [PATCH 03/31] fft-example: re-add Makefile.am --- tests/examples/fft/Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/examples/fft/Makefile.am diff --git a/tests/examples/fft/Makefile.am b/tests/examples/fft/Makefile.am new file mode 100644 index 0000000000..c71f18d4eb --- /dev/null +++ b/tests/examples/fft/Makefile.am @@ -0,0 +1,6 @@ + +noinst_PROGRAMS = fftrange +fftrange_SOURCES = fftrange.c +fftrange_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +fftrange_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstfft-$(GST_MAJORMINOR) $(GST_LIBS) + From 6098442bd0b2eb1e19c595aace0911af44b6a439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 15:23:21 +0000 Subject: [PATCH 04/31] xmpwriter: update for thread API deprecations in glib master --- gst-libs/gst/tag/xmpwriter.c | 60 +++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/tag/xmpwriter.c b/gst-libs/gst/tag/xmpwriter.c index 842f897582..10bf1f9534 100644 --- a/gst-libs/gst/tag/xmpwriter.c +++ b/gst-libs/gst/tag/xmpwriter.c @@ -47,9 +47,21 @@ static GQuark tag_xmp_writer_key; typedef struct { GSList *schemas; +#if !GLIB_CHECK_VERSION (2, 31, 0) GStaticMutex lock; +#else + GMutex lock; +#endif } GstTagXmpWriterData; +#if !GLIB_CHECK_VERSION (2, 31, 0) +#define GST_TAG_XMP_WRITER_DATA_LOCK(data) g_static_mutex_lock(&data->lock) +#define GST_TAG_XMP_WRITER_DATA_UNLOCK(data) g_static_mutex_unlock(&data->lock) +#else +#define GST_TAG_XMP_WRITER_DATA_LOCK(data) g_mutex_lock(&data->lock) +#define GST_TAG_XMP_WRITER_DATA_UNLOCK(data) g_mutex_unlock(&data->lock) +#endif + GType gst_tag_xmp_writer_get_type (void) { @@ -116,8 +128,11 @@ gst_tag_xmp_writer_data_free (gpointer p) } g_slist_free (data->schemas); } - +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_mutex_free (&data->lock); +#else + g_mutex_clear (&data->lock); +#endif g_slice_free (GstTagXmpWriterData, data); } @@ -129,22 +144,37 @@ gst_tag_xmp_writer_get_data (GstTagXmpWriter * xmpconfig) data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key); if (!data) { + /* make sure no other thread is creating a GstTagData at the same time */ +#if !GLIB_CHECK_VERSION (2, 31, 0) static GStaticMutex create_mutex = G_STATIC_MUTEX_INIT; - /* make sure no other thread is creating a GstTagXmpWriterData at the same time */ g_static_mutex_lock (&create_mutex); +#else + static GMutex create_mutex; /* no initialisation required */ + + g_mutex_lock (&create_mutex); +#endif + data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key); if (!data) { data = g_slice_new (GstTagXmpWriterData); - g_static_mutex_init (&data->lock); +#if !GLIB_CHECK_VERSION (2, 31, 0) + g_static_mutex_init (&data->lock); +#else + g_mutex_init (&data->lock); +#endif data->schemas = NULL; gst_tag_xmp_writer_data_add_all_schemas_unlocked (data); g_object_set_qdata_full (G_OBJECT (xmpconfig), tag_xmp_writer_key, data, gst_tag_xmp_writer_data_free); } +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_mutex_unlock (&create_mutex); +#else + g_mutex_unlock (&create_mutex); +#endif } return data; @@ -168,9 +198,9 @@ gst_tag_xmp_writer_add_all_schemas (GstTagXmpWriter * config) data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); gst_tag_xmp_writer_data_add_all_schemas_unlocked (data); - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); } /** @@ -191,9 +221,9 @@ gst_tag_xmp_writer_add_schema (GstTagXmpWriter * config, const gchar * schema) data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); gst_tag_xmp_writer_data_add_schema_unlocked (data, schema); - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); } /** @@ -217,14 +247,14 @@ gst_tag_xmp_writer_has_schema (GstTagXmpWriter * config, const gchar * schema) data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); for (iter = data->schemas; iter; iter = g_slist_next (iter)) { if (strcmp ((const gchar *) iter->data, schema) == 0) { ret = TRUE; break; } } - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); return ret; } @@ -250,7 +280,7 @@ gst_tag_xmp_writer_remove_schema (GstTagXmpWriter * config, data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); for (iter = data->schemas; iter; iter = g_slist_next (iter)) { if (strcmp ((const gchar *) iter->data, schema) == 0) { g_free (iter->data); @@ -258,7 +288,7 @@ gst_tag_xmp_writer_remove_schema (GstTagXmpWriter * config, break; } } - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); } /** @@ -280,7 +310,7 @@ gst_tag_xmp_writer_remove_all_schemas (GstTagXmpWriter * config) data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); if (data->schemas) { for (iter = data->schemas; iter; iter = g_slist_next (iter)) { g_free (iter->data); @@ -288,7 +318,7 @@ gst_tag_xmp_writer_remove_all_schemas (GstTagXmpWriter * config) g_slist_free (data->schemas); } data->schemas = NULL; - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); } GstBuffer * @@ -304,7 +334,7 @@ gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config, data = gst_tag_xmp_writer_get_data (config); - g_static_mutex_lock (&data->lock); + GST_TAG_XMP_WRITER_DATA_LOCK (data); if (data->schemas) { gchar **array = g_new0 (gchar *, g_slist_length (data->schemas) + 1); if (array) { @@ -316,7 +346,7 @@ gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config, g_free (array); } } - g_static_mutex_unlock (&data->lock); + GST_TAG_XMP_WRITER_DATA_UNLOCK (data); return buf; } From 0d98aa25b8a163625281b0b1d7f05dd0ed345218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 16:43:38 +0000 Subject: [PATCH 05/31] Work around deprecated thread API in glib master Add private replacements for deprecated functions such as g_mutex_new(), g_mutex_free(), g_cond_new() etc., mostly to avoid the deprecation warnings. We'll change these over to the new API once we depend on glib >= 2.32. Replace g_thread_create() with g_thread_try_new(). --- ext/alsa/gstalsadeviceprobe.c | 6 +- ext/alsa/gstalsamixer.c | 1 + ext/alsa/gstalsasink.c | 1 + ext/alsa/gstalsasrc.c | 1 + ext/ogg/gstoggdemux.c | 2 + ext/pango/gsttextoverlay.c | 2 + gst-libs/gst/Makefile.am | 2 +- gst-libs/gst/app/gstappsink.c | 2 + gst-libs/gst/app/gstappsrc.c | 2 + gst-libs/gst/audio/gstaudiosink.c | 9 ++ gst-libs/gst/audio/gstaudiosrc.c | 9 ++ gst-libs/gst/audio/gstringbuffer.c | 2 + gst-libs/gst/glib-compat-private.h | 120 ++++++++++++++++++++++++++ gst-libs/gst/pbutils/gstdiscoverer.c | 2 + gst-libs/gst/rtsp/gstrtspconnection.c | 2 + gst-libs/gst/video/convertframe.c | 2 + gst/encoding/gststreamcombiner.c | 7 +- gst/encoding/gststreamsplitter.c | 7 +- gst/playback/gstdecodebin.c | 1 + gst/playback/gstdecodebin2.c | 2 + gst/playback/gstplaybasebin.c | 2 + gst/playback/gstplaybin2.c | 2 + gst/playback/gstplaysinkconvertbin.c | 1 + gst/playback/gststreamsynchronizer.c | 7 +- gst/playback/gstsubtitleoverlay.c | 5 +- gst/playback/gsturidecodebin.c | 5 +- gst/tcp/gstmultifdsink.c | 6 ++ sys/ximage/ximagesink.c | 7 ++ sys/xvimage/xvimagesink.c | 8 ++ 29 files changed, 206 insertions(+), 19 deletions(-) create mode 100644 gst-libs/gst/glib-compat-private.h diff --git a/ext/alsa/gstalsadeviceprobe.c b/ext/alsa/gstalsadeviceprobe.c index 83596a3f5d..4b22d34104 100644 --- a/ext/alsa/gstalsadeviceprobe.c +++ b/ext/alsa/gstalsadeviceprobe.c @@ -26,6 +26,8 @@ #include "gstalsadeviceprobe.h" #include "gst/interfaces/propertyprobe.h" +G_LOCK_DEFINE_STATIC (probe_lock); + static const GList * gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe) { @@ -34,7 +36,7 @@ gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe) /* well, not perfect, but better than no locking at all. * In the worst case we leak a list node, so who cares? */ - GST_CLASS_LOCK (GST_OBJECT_CLASS (klass)); + G_LOCK (probe_lock); if (!list) { GParamSpec *pspec; @@ -43,7 +45,7 @@ gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe) list = g_list_append (NULL, pspec); } - GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass)); + G_UNLOCK (probe_lock); return list; } diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index 46c10c44c4..84e0654843 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -35,6 +35,7 @@ #endif #include "gstalsamixer.h" +#include "gst/glib-compat-private.h" #include static void gst_alsa_mixer_update_option (GstAlsaMixer * mixer, diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index a878b5ef08..24b1d8aac2 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -52,6 +52,7 @@ #include "gstalsadeviceprobe.h" #include +#include "gst/glib-compat-private.h" #define DEFAULT_DEVICE "default" #define DEFAULT_DEVICE_NAME "" diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c index 1a99a68f90..917f0dc323 100644 --- a/ext/alsa/gstalsasrc.c +++ b/ext/alsa/gstalsasrc.c @@ -48,6 +48,7 @@ #include "gstalsasrc.h" #include "gstalsadeviceprobe.h" +#include "gst/glib-compat-private.h" #include diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 6e924f9dd6..ba5fc2095e 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -45,6 +45,8 @@ #include "gstoggdemux.h" +#include "gst/glib-compat-private.h" + #define CHUNKSIZE (8500) /* this is out of vorbisfile */ /* we hope we get a granpos within this many bytes off the end */ diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 6abff7dbc5..76b8f7448b 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -92,6 +92,8 @@ #include "gsttextrender.h" #include +#include "gst/glib-compat-private.h" + /* FIXME: * - use proper strides and offset for I420 * - if text is wider than the video picture, it does not get diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 6f261b3d6e..0984251621 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -18,7 +18,7 @@ SUBDIRS = \ riff \ app -noinst_HEADERS = gettext.h gst-i18n-plugin.h +noinst_HEADERS = gettext.h gst-i18n-plugin.h glib-compat-private.h # dependencies: audio: interfaces pbutils diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c index a1a20a5b06..9a891b6c9e 100644 --- a/gst-libs/gst/app/gstappsink.c +++ b/gst-libs/gst/app/gstappsink.c @@ -76,6 +76,8 @@ #include "gstappsink.h" +#include "gst/glib-compat-private.h" + struct _GstAppSinkPrivate { GstCaps *caps; diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c index 6ae59e5931..543a2ad043 100644 --- a/gst-libs/gst/app/gstappsrc.c +++ b/gst-libs/gst/app/gstappsrc.c @@ -102,6 +102,8 @@ #include "gstapp-marshal.h" #include "gstappsrc.h" +#include "gst/glib-compat-private.h" + struct _GstAppSrcPrivate { GCond *cond; diff --git a/gst-libs/gst/audio/gstaudiosink.c b/gst-libs/gst/audio/gstaudiosink.c index ac39cb1bfa..c5fec7367c 100644 --- a/gst-libs/gst/audio/gstaudiosink.c +++ b/gst-libs/gst/audio/gstaudiosink.c @@ -71,6 +71,8 @@ #include "gstaudiosink.h" +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_audio_sink_debug); #define GST_CAT_DEFAULT gst_audio_sink_debug @@ -426,9 +428,16 @@ gst_audioringbuffer_activate (GstRingBuffer * buf, gboolean active) abuf->running = TRUE; GST_DEBUG_OBJECT (sink, "starting thread"); + +#if !GLIB_CHECK_VERSION (2, 31, 0) sink->thread = g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE, &error); +#else + sink->thread = g_thread_try_new ("audiosink-ringbuffer", + (GThreadFunc) audioringbuffer_thread_func, buf, &error); +#endif + if (!sink->thread || error != NULL) goto thread_failed; diff --git a/gst-libs/gst/audio/gstaudiosrc.c b/gst-libs/gst/audio/gstaudiosrc.c index d7a6b547db..004153e6ce 100644 --- a/gst-libs/gst/audio/gstaudiosrc.c +++ b/gst-libs/gst/audio/gstaudiosrc.c @@ -71,6 +71,8 @@ #include "gstaudiosrc.h" +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_audio_src_debug); #define GST_CAT_DEFAULT gst_audio_src_debug @@ -382,9 +384,16 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec) abuf = GST_AUDIORING_BUFFER (buf); abuf->running = TRUE; + /* FIXME: handle thread creation failure */ +#if !GLIB_CHECK_VERSION (2, 31, 0) src->thread = g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE, NULL); +#else + src->thread = g_thread_try_new ("audiosrc-ringbuffer", + (GThreadFunc) audioringbuffer_thread_func, buf, NULL); +#endif + GST_AUDIORING_BUFFER_WAIT (buf); return result; diff --git a/gst-libs/gst/audio/gstringbuffer.c b/gst-libs/gst/audio/gstringbuffer.c index ab1880c687..50693045cf 100644 --- a/gst-libs/gst/audio/gstringbuffer.c +++ b/gst-libs/gst/audio/gstringbuffer.c @@ -43,6 +43,8 @@ #include "gstringbuffer.h" +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_ring_buffer_debug); #define GST_CAT_DEFAULT gst_ring_buffer_debug diff --git a/gst-libs/gst/glib-compat-private.h b/gst-libs/gst/glib-compat-private.h new file mode 100644 index 0000000000..d143d3257d --- /dev/null +++ b/gst-libs/gst/glib-compat-private.h @@ -0,0 +1,120 @@ +/* + * glib-compat.c + * Functions copied from glib 2.10 + * + * Copyright 2005 David Schleef + */ + +#ifndef __GLIB_COMPAT_PRIVATE_H__ +#define __GLIB_COMPAT_PRIVATE_H__ + +#include + +G_BEGIN_DECLS + +#if !GLIB_CHECK_VERSION(2,25,0) + +#if defined (_MSC_VER) && !defined(_WIN64) +typedef struct _stat32 GStatBuf; +#else +typedef struct stat GStatBuf; +#endif + +#endif + +#if GLIB_CHECK_VERSION(2,26,0) +#define GLIB_HAS_GDATETIME +#endif + +/* See bug #651514 */ +#if GLIB_CHECK_VERSION(2,29,5) +#define G_ATOMIC_POINTER_COMPARE_AND_EXCHANGE(a,b,c) \ + g_atomic_pointer_compare_and_exchange ((a),(b),(c)) +#define G_ATOMIC_INT_COMPARE_AND_EXCHANGE(a,b,c) \ + g_atomic_int_compare_and_exchange ((a),(b),(c)) +#else +#define G_ATOMIC_POINTER_COMPARE_AND_EXCHANGE(a,b,c) \ + g_atomic_pointer_compare_and_exchange ((volatile gpointer *)(a),(b),(c)) +#define G_ATOMIC_INT_COMPARE_AND_EXCHANGE(a,b,c) \ + g_atomic_int_compare_and_exchange ((volatile int *)(a),(b),(c)) +#endif + +/* See bug #651514 */ +#if GLIB_CHECK_VERSION(2,29,5) +#define G_ATOMIC_INT_ADD(a,b) g_atomic_int_add ((a),(b)) +#else +#define G_ATOMIC_INT_ADD(a,b) g_atomic_int_exchange_and_add ((a),(b)) +#endif + +/* copies */ + +#if GLIB_CHECK_VERSION (2, 31, 0) +#define g_mutex_new gst_g_mutex_new +static inline GMutex * +gst_g_mutex_new (void) +{ + GMutex *mutex = g_slice_new (GMutex); + g_mutex_init (mutex); + return mutex; +} +#define g_mutex_free gst_g_mutex_free +static inline void +gst_g_mutex_free (GMutex *mutex) +{ + g_mutex_clear (mutex); + g_slice_free (GMutex, mutex); +} +#define g_static_rec_mutex_init gst_g_static_rec_mutex_init +static inline void +gst_g_static_rec_mutex_init (GStaticRecMutex *mutex) +{ + static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT; + + *mutex = init_mutex; +} +#define g_cond_new gst_g_cond_new +static inline GCond * +gst_g_cond_new (void) +{ + GCond *cond = g_slice_new (GCond); + g_cond_init (cond); + return cond; +} +#define g_cond_free gst_g_cond_free +static inline void +gst_g_cond_free (GCond *cond) +{ + g_cond_clear (cond); + g_slice_free (GCond, cond); +} +#define g_cond_timed_wait gst_g_cond_timed_wait +static inline gboolean +gst_g_cond_timed_wait (GCond *cond, GMutex *mutex, GTimeVal *abs_time) +{ + gint64 end_time; + + if (abs_time == NULL) { + g_cond_wait (cond, mutex); + return TRUE; + } + + end_time = abs_time->tv_sec; + end_time *= 1000000; + end_time += abs_time->tv_usec; + + /* would be nice if we had clock_rtoffset, but that didn't seem to + * make it into the kernel yet... + */ + /* if CLOCK_MONOTONIC is not defined then g_get_montonic_time() and + * g_get_real_time() are returning the same clock and we'd add ~0 + */ + end_time += g_get_monotonic_time () - g_get_real_time (); + return g_cond_wait_until (cond, mutex, end_time); +} +#endif /* GLIB_CHECK_VERSION (2, 31, 0) */ + +/* adaptations */ + +G_END_DECLS + +#endif diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index bce956edbe..6af71dca4a 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -48,6 +48,8 @@ #include "pbutils-marshal.h" #include "pbutils-private.h" +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (discoverer_debug); #define GST_CAT_DEFAULT discoverer_debug diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c index da39c21cd2..5fcfa252d3 100644 --- a/gst-libs/gst/rtsp/gstrtspconnection.c +++ b/gst-libs/gst/rtsp/gstrtspconnection.c @@ -93,6 +93,8 @@ #include "gstrtspconnection.h" #include "gstrtspbase64.h" +#include "gst/glib-compat-private.h" + union gst_sockaddr { struct sockaddr sa; diff --git a/gst-libs/gst/video/convertframe.c b/gst-libs/gst/video/convertframe.c index 58dc426258..756ce71979 100644 --- a/gst-libs/gst/video/convertframe.c +++ b/gst-libs/gst/video/convertframe.c @@ -22,6 +22,8 @@ #include #include "video.h" +#include "gst/glib-compat-private.h" + static gboolean caps_are_raw (const GstCaps * caps) { diff --git a/gst/encoding/gststreamcombiner.c b/gst/encoding/gststreamcombiner.c index 7328695917..c601cf8811 100644 --- a/gst/encoding/gststreamcombiner.c +++ b/gst/encoding/gststreamcombiner.c @@ -23,6 +23,7 @@ #endif #include "gststreamcombiner.h" +#include "gst/glib-compat-private.h" static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, @@ -62,10 +63,8 @@ gst_stream_combiner_class_init (GstStreamCombinerClass * klass) GST_DEBUG_CATEGORY_INIT (gst_stream_combiner_debug, "streamcombiner", 0, "Stream Combiner"); - gst_element_class_add_static_pad_template (gstelement_klass, - &src_template); - gst_element_class_add_static_pad_template (gstelement_klass, - &sink_template); + gst_element_class_add_static_pad_template (gstelement_klass, &src_template); + gst_element_class_add_static_pad_template (gstelement_klass, &sink_template); gstelement_klass->request_new_pad = GST_DEBUG_FUNCPTR (gst_stream_combiner_request_new_pad); diff --git a/gst/encoding/gststreamsplitter.c b/gst/encoding/gststreamsplitter.c index 9221b353a2..8c568a9630 100644 --- a/gst/encoding/gststreamsplitter.c +++ b/gst/encoding/gststreamsplitter.c @@ -23,6 +23,7 @@ #endif #include "gststreamsplitter.h" +#include "gst/glib-compat-private.h" static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src_%d", GST_PAD_SRC, GST_PAD_REQUEST, @@ -62,10 +63,8 @@ gst_stream_splitter_class_init (GstStreamSplitterClass * klass) GST_DEBUG_CATEGORY_INIT (gst_stream_splitter_debug, "streamsplitter", 0, "Stream Splitter"); - gst_element_class_add_static_pad_template (gstelement_klass, - &src_template); - gst_element_class_add_static_pad_template (gstelement_klass, - &sink_template); + gst_element_class_add_static_pad_template (gstelement_klass, &src_template); + gst_element_class_add_static_pad_template (gstelement_klass, &sink_template); gstelement_klass->request_new_pad = GST_DEBUG_FUNCPTR (gst_stream_splitter_request_new_pad); diff --git a/gst/playback/gstdecodebin.c b/gst/playback/gstdecodebin.c index 7ce222fb48..771a1db618 100644 --- a/gst/playback/gstdecodebin.c +++ b/gst/playback/gstdecodebin.c @@ -45,6 +45,7 @@ #include #include #include +#include "gst/glib-compat-private.h" #include "gstplay-marshal.h" diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 45ff2b14bb..187221eb51 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -96,6 +96,8 @@ #include "gstplayback.h" #include "gstrawcaps.h" +#include "gst/glib-compat-private.h" + /* generic templates */ static GstStaticPadTemplate decoder_bin_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", diff --git a/gst/playback/gstplaybasebin.c b/gst/playback/gstplaybasebin.c index 2d26aad88d..7ab2c29ac1 100644 --- a/gst/playback/gstplaybasebin.c +++ b/gst/playback/gstplaybasebin.c @@ -29,6 +29,8 @@ #include +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_play_base_bin_debug); #define GST_CAT_DEFAULT gst_play_base_bin_debug diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 9f86e3e3ec..f9478e266e 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -233,6 +233,8 @@ #include "gstplaysink.h" #include "gstsubtitleoverlay.h" +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_play_bin_debug); #define GST_CAT_DEFAULT gst_play_bin_debug diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index d05f2ac517..51ede9bb46 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -26,6 +26,7 @@ #include #include +#include "gst/glib-compat-private.h" GST_DEBUG_CATEGORY_STATIC (gst_play_sink_convert_bin_debug); #define GST_CAT_DEFAULT gst_play_sink_convert_bin_debug diff --git a/gst/playback/gststreamsynchronizer.c b/gst/playback/gststreamsynchronizer.c index 594b4b2be1..c6c53dbc81 100644 --- a/gst/playback/gststreamsynchronizer.c +++ b/gst/playback/gststreamsynchronizer.c @@ -22,6 +22,7 @@ #endif #include "gststreamsynchronizer.h" +#include "gst/glib-compat-private.h" GST_DEBUG_CATEGORY_STATIC (stream_synchronizer_debug); #define GST_CAT_DEFAULT stream_synchronizer_debug @@ -955,10 +956,8 @@ gst_stream_synchronizer_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_static_pad_template (gstelement_class, - &srctemplate); - gst_element_class_add_static_pad_template (gstelement_class, - &sinktemplate); + gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); + gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate); gst_element_class_set_details_simple (gstelement_class, "Stream Synchronizer", "Generic", diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index 2828a8c610..8ca5184bf0 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -45,6 +45,8 @@ #include #include +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (subtitle_overlay_debug); #define GST_CAT_DEFAULT subtitle_overlay_debug @@ -1617,8 +1619,7 @@ gst_subtitle_overlay_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_static_pad_template (gstelement_class, - &srctemplate); + gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); gst_element_class_add_static_pad_template (gstelement_class, &video_sinktemplate); diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index e0660b5e2e..2a5026f972 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -38,6 +38,8 @@ #include "gstplay-enum.h" #include "gstrawcaps.h" +#include "gst/glib-compat-private.h" + #define GST_TYPE_URI_DECODE_BIN \ (gst_uri_decode_bin_get_type()) #define GST_URI_DECODE_BIN(obj) \ @@ -213,8 +215,7 @@ gst_uri_decode_bin_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_static_pad_template (gstelement_class, - &srctemplate); + gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); gst_element_class_set_details_simple (gstelement_class, "URI Decoder", "Generic/Bin/Decoder", "Autoplug and decode an URI to raw media", diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index 912c2738e2..a52dabdecb 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -2883,8 +2883,14 @@ gst_multi_fd_sink_start (GstBaseSink * bsink) } this->running = TRUE; + +#if !GLIB_CHECK_VERSION (2, 31, 0) this->thread = g_thread_create ((GThreadFunc) gst_multi_fd_sink_thread, this, TRUE, NULL); +#else + this->thread = g_thread_new ("multifdsink", + (GThreadFunc) gst_multi_fd_sink_thread, this); +#endif GST_OBJECT_FLAG_SET (this, GST_MULTI_FD_SINK_OPEN); diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 7e5cb1a7c3..2adcc735c0 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -113,6 +113,8 @@ /* Debugging category */ #include +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_EXTERN (gst_debug_ximagesink); #define GST_CAT_DEFAULT gst_debug_ximagesink @@ -1171,8 +1173,13 @@ gst_ximagesink_manage_event_thread (GstXImageSink * ximagesink) GST_DEBUG_OBJECT (ximagesink, "run xevent thread, expose %d, events %d", ximagesink->handle_expose, ximagesink->handle_events); ximagesink->running = TRUE; +#if !GLIB_CHECK_VERSION (2, 31, 0) ximagesink->event_thread = g_thread_create ( (GThreadFunc) gst_ximagesink_event_thread, ximagesink, TRUE, NULL); +#else + ximagesink->event_thread = g_thread_try_new ("ximagesink-events", + (GThreadFunc) gst_ximagesink_event_thread, ximagesink, NULL); +#endif } } else { if (ximagesink->event_thread) { diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index d0cc4a832c..8a7913b6ac 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -126,6 +126,9 @@ /* Debugging category */ #include + +#include "gst/glib-compat-private.h" + GST_DEBUG_CATEGORY_STATIC (gst_debug_xvimagesink); #define GST_CAT_DEFAULT gst_debug_xvimagesink GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE); @@ -1685,8 +1688,13 @@ gst_xvimagesink_manage_event_thread (GstXvImageSink * xvimagesink) GST_DEBUG_OBJECT (xvimagesink, "run xevent thread, expose %d, events %d", xvimagesink->handle_expose, xvimagesink->handle_events); xvimagesink->running = TRUE; +#if !GLIB_CHECK_VERSION (2, 31, 0) xvimagesink->event_thread = g_thread_create ( (GThreadFunc) gst_xvimagesink_event_thread, xvimagesink, TRUE, NULL); +#else + xvimagesink->event_thread = g_thread_try_new ("xvimagesink-events", + (GThreadFunc) gst_xvimagesink_event_thread, xvimagesink, NULL); +#endif } } else { if (xvimagesink->event_thread) { From ff6cc8af82136371a7e6236d438eed8b020ff951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 17:02:39 +0000 Subject: [PATCH 06/31] tools, tests: g_thread_init() is deprecated in glib master It's not needed any longer. --- tests/examples/encoding/encoding.c | 2 ++ tests/examples/overlay/gtk-xoverlay.c | 2 ++ tests/examples/overlay/qt-xoverlay.cpp | 2 ++ tests/examples/seek/jsseek.c | 2 ++ tests/examples/seek/scrubby.c | 2 ++ tests/examples/seek/seek.c | 2 ++ tests/icles/stress-playbin.c | 2 ++ tests/icles/test-colorkey.c | 2 ++ tests/icles/test-xoverlay.c | 2 ++ tools/gst-discoverer.c | 2 ++ 10 files changed, 20 insertions(+) diff --git a/tests/examples/encoding/encoding.c b/tests/examples/encoding/encoding.c index 86d7f8f126..4c4865c43c 100644 --- a/tests/examples/encoding/encoding.c +++ b/tests/examples/encoding/encoding.c @@ -395,8 +395,10 @@ main (int argc, char **argv) GstEncodingProfile *prof; gchar *inputuri; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new ("- encode URIs with GstProfile and encodebin"); g_option_context_add_main_entries (ctx, options, NULL); diff --git a/tests/examples/overlay/gtk-xoverlay.c b/tests/examples/overlay/gtk-xoverlay.c index c05685c7e2..3050bd703c 100644 --- a/tests/examples/overlay/gtk-xoverlay.c +++ b/tests/examples/overlay/gtk-xoverlay.c @@ -98,8 +98,10 @@ main (int argc, char **argv) gulong embed_xid; GstStateChangeReturn sret; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif gst_init (&argc, &argv); gtk_init (&argc, &argv); diff --git a/tests/examples/overlay/qt-xoverlay.cpp b/tests/examples/overlay/qt-xoverlay.cpp index aa483a71cd..cf8840fa95 100644 --- a/tests/examples/overlay/qt-xoverlay.cpp +++ b/tests/examples/overlay/qt-xoverlay.cpp @@ -80,8 +80,10 @@ find_video_sink (void) int main(int argc, char *argv[]) { +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif gst_init (&argc, &argv); QApplication app(argc, argv); diff --git a/tests/examples/seek/jsseek.c b/tests/examples/seek/jsseek.c index ab2bfc3950..fd16c548ed 100644 --- a/tests/examples/seek/jsseek.c +++ b/tests/examples/seek/jsseek.c @@ -2672,8 +2672,10 @@ main (int argc, char **argv) GOptionContext *ctx; GError *err = NULL; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new ("- test seeking in gsteamer"); g_option_context_add_main_entries (ctx, options, NULL); diff --git a/tests/examples/seek/scrubby.c b/tests/examples/seek/scrubby.c index c9a02f42bb..501d5599fd 100644 --- a/tests/examples/seek/scrubby.c +++ b/tests/examples/seek/scrubby.c @@ -463,8 +463,10 @@ main (int argc, char **argv) GOptionContext *ctx; GError *err = NULL; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new ("seek"); g_option_context_add_main_entries (ctx, options, NULL); diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index b04967b44b..60c09973e2 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -2675,8 +2675,10 @@ main (int argc, char **argv) GOptionContext *ctx; GError *err = NULL; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new ("- test seeking in gsteamer"); g_option_context_add_main_entries (ctx, options, NULL); diff --git a/tests/icles/stress-playbin.c b/tests/icles/stress-playbin.c index 3b90710336..30970ce0d7 100644 --- a/tests/icles/stress-playbin.c +++ b/tests/icles/stress-playbin.c @@ -100,8 +100,10 @@ main (int argc, char **argv) }; GTimer *timer; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new ("FILES OR DIRECTORIES WITH AUDIO FILES"); g_option_context_add_main_entries (ctx, options, NULL); diff --git a/tests/icles/test-colorkey.c b/tests/icles/test-colorkey.c index ac04ba5c7d..9d88aec340 100644 --- a/tests/icles/test-colorkey.c +++ b/tests/icles/test-colorkey.c @@ -172,8 +172,10 @@ main (int argc, char **argv) GstPropertyProbe *probe; GValueArray *arr; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif gst_init (&argc, &argv); gtk_init (&argc, &argv); diff --git a/tests/icles/test-xoverlay.c b/tests/icles/test-xoverlay.c index 9ef552eeea..c1610b6601 100644 --- a/tests/icles/test-xoverlay.c +++ b/tests/icles/test-xoverlay.c @@ -144,8 +144,10 @@ main (gint argc, gchar ** argv) gulong embed_xid = 0; gboolean force_aspect = FALSE, draw_borders = FALSE; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif gst_init (&argc, &argv); gtk_init (&argc, &argv); diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index 210c1ed752..a3cd4f9df4 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -497,8 +497,10 @@ main (int argc, char **argv) }; GOptionContext *ctx; +#if !GLIB_CHECK_VERSION (2, 31, 0) if (!g_thread_supported ()) g_thread_init (NULL); +#endif ctx = g_option_context_new From 9c307bccc5006ba61b38bd35de25859ddbfe4e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 20:21:26 +0000 Subject: [PATCH 07/31] alsamixer: embed static mutexes into the mixer structure instead of allocating them dynamically --- ext/alsa/gstalsamixer.c | 87 +++++++++++++++++++---------------------- ext/alsa/gstalsamixer.h | 6 ++- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index 84e0654843..79be56d7ec 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -131,14 +131,14 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) count = snd_mixer_get_count (handle); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); /* Check if we have a playback mixer labelled as 'Master' */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "Master") == 0) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -149,7 +149,7 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "Front") == 0) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -160,7 +160,7 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "PCM") == 0) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -171,7 +171,7 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "Speaker") == 0) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -184,7 +184,7 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) if (snd_mixer_selem_has_playback_volume (element) && snd_mixer_selem_has_playback_switch (element) && !snd_mixer_selem_is_playback_mono (element)) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -195,7 +195,7 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && snd_mixer_selem_has_playback_switch (element)) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); @@ -205,13 +205,13 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element)) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return element; } element = snd_mixer_elem_next (element); } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); /* Looks like we're out of luck ... */ return NULL; } @@ -223,7 +223,7 @@ gst_alsa_mixer_update (GstAlsaMixer * mixer, snd_mixer_elem_t * elem) g_return_if_fail (mixer != NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); for (item = mixer->tracklist; item != NULL; item = item->next) { if (GST_IS_ALSA_MIXER_TRACK (item->data)) { @@ -239,7 +239,7 @@ gst_alsa_mixer_update (GstAlsaMixer * mixer, snd_mixer_elem_t * elem) } } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } static int @@ -288,7 +288,7 @@ gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer) if (mixer->tracklist) return; - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); master = gst_alsa_mixer_find_master_mixer (mixer, mixer->handle); @@ -410,7 +410,7 @@ gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer) snd_mixer_elem_set_callback_private (temp, mixer); } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } static void @@ -422,13 +422,13 @@ task_monitor_alsa (gpointer data) GstAlsaMixer *mixer = (GstAlsaMixer *) data; gint ret; - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); nfds = snd_mixer_poll_descriptors_count (mixer->handle); if (nfds <= 0) { GST_ERROR ("snd_mixer_poll_descriptors_count <= 0: %d", nfds); /* FIXME: sleep ? stop monitoring ? */ - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return; } @@ -440,7 +440,7 @@ task_monitor_alsa (gpointer data) GST_ELEMENT_ERROR (mixer, RESOURCE, READ, (NULL), ("alsa error: %s", snd_strerror (rnfds))); gst_task_pause (mixer->task); - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return; } @@ -448,7 +448,7 @@ task_monitor_alsa (gpointer data) pfds[rnfds].events = POLLIN | POLLPRI | POLLHUP | POLLERR; pfds[rnfds].revents = 0; - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); GST_LOG ("task loop"); ret = poll (pfds, rnfds + 1, -1); @@ -459,7 +459,7 @@ task_monitor_alsa (gpointer data) return; } - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); ret = snd_mixer_poll_descriptors_revents (mixer->handle, pfds, nfds, &revents); @@ -475,7 +475,7 @@ task_monitor_alsa (gpointer data) gst_task_pause (mixer->task); } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } /* API */ @@ -492,14 +492,11 @@ gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir) if (pipe (ret->pfd) == -1) goto error; - ret->rec_mutex = g_new (GStaticRecMutex, 1); - g_static_rec_mutex_init (ret->rec_mutex); - - ret->task_mutex = g_new (GStaticRecMutex, 1); - g_static_rec_mutex_init (ret->task_mutex); + g_static_rec_mutex_init (&ret->rec_mutex); + g_static_rec_mutex_init (&ret->task_mutex); ret->task = gst_task_create (task_monitor_alsa, ret); - gst_task_set_lock (ret->task, ret->task_mutex); + gst_task_set_lock (ret->task, &ret->task_mutex); ret->device = g_strdup (device); ret->dir = dir; @@ -541,9 +538,7 @@ gst_alsa_mixer_free (GstAlsaMixer * mixer) mixer->task = NULL; } - g_static_rec_mutex_free (mixer->task_mutex); - g_free (mixer->task_mutex); - mixer->task_mutex = NULL; + g_static_rec_mutex_free (&mixer->task_mutex); if (mixer->pfd[0] > 0) { close (mixer->pfd[0]); @@ -581,9 +576,7 @@ gst_alsa_mixer_free (GstAlsaMixer * mixer) mixer->handle = NULL; } - g_static_rec_mutex_free (mixer->rec_mutex); - g_free (mixer->rec_mutex); - mixer->rec_mutex = NULL; + g_static_rec_mutex_free (&mixer->rec_mutex); g_free (mixer); } @@ -607,7 +600,7 @@ gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track, g_return_if_fail (mixer->handle != NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); gst_alsa_mixer_track_update (alsa_track); @@ -643,7 +636,7 @@ gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track, volumes[i] = alsa_track->volumes[i]; } } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } static gboolean @@ -671,7 +664,7 @@ gst_alsa_mixer_set_volume (GstAlsaMixer * mixer, GstMixerTrack * track, g_return_if_fail (mixer->handle != NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); gst_alsa_mixer_track_update (alsa_track); @@ -719,7 +712,7 @@ gst_alsa_mixer_set_volume (GstAlsaMixer * mixer, GstMixerTrack * track, alsa_track->volumes[i] = volumes[i]; } } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } void @@ -730,12 +723,12 @@ gst_alsa_mixer_set_mute (GstAlsaMixer * mixer, GstMixerTrack * track, g_return_if_fail (mixer->handle != NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); gst_alsa_mixer_track_update (alsa_track); if (! !(mute) == ! !(track->flags & GST_MIXER_TRACK_MUTE)) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return; } if (mute) { @@ -771,7 +764,7 @@ gst_alsa_mixer_set_mute (GstAlsaMixer * mixer, GstMixerTrack * track, snd_mixer_selem_set_playback_volume (ctrl_track->element, i, vol); } } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } void @@ -782,12 +775,12 @@ gst_alsa_mixer_set_record (GstAlsaMixer * mixer, g_return_if_fail (mixer->handle != NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); gst_alsa_mixer_track_update (alsa_track); if (! !(record) == ! !(track->flags & GST_MIXER_TRACK_RECORD)) { - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); return; } @@ -827,7 +820,7 @@ gst_alsa_mixer_set_record (GstAlsaMixer * mixer, snd_mixer_selem_set_capture_volume (alsa_track->element, i, vol); } } - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } void @@ -849,9 +842,9 @@ gst_alsa_mixer_set_option (GstAlsaMixer * mixer, if (idx == -1) return; - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); snd_mixer_selem_set_enum_item (alsa_opts->element, 0, idx); - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); } const gchar * @@ -862,9 +855,9 @@ gst_alsa_mixer_get_option (GstAlsaMixer * mixer, GstMixerOptions * opts) GstAlsaMixerOptions *alsa_opts = GST_ALSA_MIXER_OPTIONS (opts); g_return_val_if_fail (mixer->handle != NULL, NULL); - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx); - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); if (ret == 0) return g_list_nth_data (opts->values, idx); else @@ -891,9 +884,9 @@ gst_alsa_mixer_update_option (GstAlsaMixer * mixer, GST_WARNING ("Cannot send update notifications, no GstMixer * given"); return; } - g_static_rec_mutex_lock (mixer->rec_mutex); + GST_ALSA_MIXER_LOCK (mixer); ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx); - g_static_rec_mutex_unlock (mixer->rec_mutex); + GST_ALSA_MIXER_UNLOCK (mixer); if (ret == 0) { option = g_list_nth_data (GST_MIXER_OPTIONS (alsa_opts)->values, idx); gst_mixer_option_changed (mixer->interface, GST_MIXER_OPTIONS (alsa_opts), diff --git a/ext/alsa/gstalsamixer.h b/ext/alsa/gstalsamixer.h index ccc3784574..18a9688d3b 100644 --- a/ext/alsa/gstalsamixer.h +++ b/ext/alsa/gstalsamixer.h @@ -53,8 +53,8 @@ struct _GstAlsaMixer snd_mixer_t * handle; GstTask * task; - GStaticRecMutex * task_mutex; - GStaticRecMutex * rec_mutex; + GStaticRecMutex task_mutex; + GStaticRecMutex rec_mutex; int pfd[2]; @@ -65,6 +65,8 @@ struct _GstAlsaMixer GstAlsaMixerDirection dir; }; +#define GST_ALSA_MIXER_LOCK(mixer) g_static_rec_mutex_lock (&mixer->rec_mutex) +#define GST_ALSA_MIXER_UNLOCK(mixer) g_static_rec_mutex_unlock (&mixer->rec_mutex) GstAlsaMixer* gst_alsa_mixer_new (const gchar *device, GstAlsaMixerDirection dir); From 482823463937e4c88c41c5fc78486bf31e6b8397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 20:38:19 +0000 Subject: [PATCH 08/31] alsamixer: use GRectMutext instead of GStaticRecMutex with newer glib versions --- ext/alsa/gstalsamixer.c | 13 ++++++++++--- ext/alsa/gstalsamixer.h | 10 ++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index 79be56d7ec..87b2db34f0 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -492,7 +492,11 @@ gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir) if (pipe (ret->pfd) == -1) goto error; +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_rec_mutex_init (&ret->rec_mutex); +#else + g_rec_mutex_init (&ret->rec_mutex); +#endif g_static_rec_mutex_init (&ret->task_mutex); ret->task = gst_task_create (task_monitor_alsa, ret); @@ -575,8 +579,11 @@ gst_alsa_mixer_free (GstAlsaMixer * mixer) snd_mixer_close (mixer->handle); mixer->handle = NULL; } - +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_rec_mutex_free (&mixer->rec_mutex); +#else + g_rec_mutex_clear (&mixer->rec_mutex); +#endif g_free (mixer); } @@ -759,8 +766,8 @@ gst_alsa_mixer_set_mute (GstAlsaMixer * mixer, GstMixerTrack * track, for (i = 0; i < ((GstMixerTrack *) ctrl_track)->num_channels; i++) { long vol = - mute ? ((GstMixerTrack *) ctrl_track)-> - min_volume : ctrl_track->volumes[i]; + mute ? ((GstMixerTrack *) ctrl_track)->min_volume : ctrl_track-> + volumes[i]; snd_mixer_selem_set_playback_volume (ctrl_track->element, i, vol); } } diff --git a/ext/alsa/gstalsamixer.h b/ext/alsa/gstalsamixer.h index 18a9688d3b..dc20cf22cd 100644 --- a/ext/alsa/gstalsamixer.h +++ b/ext/alsa/gstalsamixer.h @@ -54,7 +54,12 @@ struct _GstAlsaMixer GstTask * task; GStaticRecMutex task_mutex; + +#if !GLIB_CHECK_VERSION (2, 31, 0) GStaticRecMutex rec_mutex; +#else + GRecMutex rec_mutex; +#endif int pfd[2]; @@ -65,8 +70,13 @@ struct _GstAlsaMixer GstAlsaMixerDirection dir; }; +#if !GLIB_CHECK_VERSION (2, 31, 0) #define GST_ALSA_MIXER_LOCK(mixer) g_static_rec_mutex_lock (&mixer->rec_mutex) #define GST_ALSA_MIXER_UNLOCK(mixer) g_static_rec_mutex_unlock (&mixer->rec_mutex) +#else +#define GST_ALSA_MIXER_LOCK(mixer) g_rec_mutex_lock (&mixer->rec_mutex) +#define GST_ALSA_MIXER_UNLOCK(mixer) g_rec_mutex_unlock (&mixer->rec_mutex) +#endif GstAlsaMixer* gst_alsa_mixer_new (const gchar *device, GstAlsaMixerDirection dir); From 5440ae3c184643179a63ef1ad9a80e8d92a36254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 4 Dec 2011 20:50:25 +0000 Subject: [PATCH 09/31] Suppress deprecation warnings in selected files, for g_static_rec_mutex_* mostly GStaticRecMutex is part of our API/ABI, not much we can do here in 0.10 for most of these. --- ext/alsa/gstalsamixer.c | 4 ++++ ext/ogg/gstoggdemux.c | 5 +++++ gst-libs/gst/audio/gstaudiodecoder.c | 4 ++++ gst-libs/gst/audio/gstaudioencoder.c | 4 ++++ gst-libs/gst/audio/gstbaseaudiosink.c | 4 ++++ gst/playback/gstdecodebin.c | 4 ++++ gst/playback/gstdecodebin2.c | 4 ++++ gst/playback/gstplaybin2.c | 4 ++++ gst/playback/gstplaysink.c | 4 ++++ gst/playback/gststreamsynchronizer.c | 4 ++++ gst/tcp/gstmultifdsink.c | 5 +++++ 11 files changed, 46 insertions(+) diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index 87b2db34f0..6b775454a1 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -34,6 +34,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gstalsamixer.h" #include "gst/glib-compat-private.h" #include diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index ba5fc2095e..b9cb31bef9 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -39,6 +39,11 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include #include diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index c20239877e..ced5419981 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -149,6 +149,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gstaudiodecoder.h" #include diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index 55f8d83810..1be86ad5c0 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -151,6 +151,10 @@ # include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gstaudioencoder.h" #include #include diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index a653ebf31c..f0f28b5bb4 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -34,6 +34,10 @@ #include +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gstbaseaudiosink.h" GST_DEBUG_CATEGORY_STATIC (gst_base_audio_sink_debug); diff --git a/gst/playback/gstdecodebin.c b/gst/playback/gstdecodebin.c index 771a1db618..7ae0cb9d3d 100644 --- a/gst/playback/gstdecodebin.c +++ b/gst/playback/gstdecodebin.c @@ -40,6 +40,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 187221eb51..c7e8921d05 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -85,6 +85,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index f9478e266e..f8ccb51501 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -220,6 +220,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 06d1081d0e..81729e6dc2 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -22,6 +22,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include diff --git a/gst/playback/gststreamsynchronizer.c b/gst/playback/gststreamsynchronizer.c index c6c53dbc81..45f8db47af 100644 --- a/gst/playback/gststreamsynchronizer.c +++ b/gst/playback/gststreamsynchronizer.c @@ -21,6 +21,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gststreamsynchronizer.h" #include "gst/glib-compat-private.h" diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index a52dabdecb..9ebfc49622 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -101,6 +101,11 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include #include From b0f4085f229d02f656ebbf1349c5c7681ce96557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 5 Dec 2011 09:38:33 +0100 Subject: [PATCH 10/31] xoverlay: Fix mistakes in the sample code Fixes bug #665430. --- gst-libs/gst/interfaces/xoverlay.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/interfaces/xoverlay.c b/gst-libs/gst/interfaces/xoverlay.c index cf6a6bbd25..77c9e75c41 100644 --- a/gst-libs/gst/interfaces/xoverlay.c +++ b/gst-libs/gst/interfaces/xoverlay.c @@ -143,6 +143,7 @@ * GstXOverlay and Gtk+ * * |[ + * #include <gst/interfaces/xoverlay.h> * #include <gtk/gtk.h> * #ifdef GDK_WINDOWING_X11 * #include <gdk/gdkx.h> // for GDK_WINDOW_XID @@ -184,7 +185,7 @@ * #endif * * #ifdef GDK_WINDOWING_X11 - * video_window_xid = GDK_WINDOW_XID (video_window->window); + * video_window_xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window)); * #endif * } * ... @@ -212,7 +213,7 @@ * // realize window now so that the video window gets created and we can * // obtain its XID before the pipeline is started up and the videosink * // asks for the XID of the window to render onto - * gtk_widget_realize (window); + * gtk_widget_realize (video_window); * * // we should have the XID now * g_assert (video_window_xid != 0); From 80054a3b1e47a4257044b0a415743c717c73fbe8 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 17 Oct 2011 17:25:11 +0200 Subject: [PATCH 11/31] video: add some internal helper functions for image blending This could be improved if we decide we don't need it to be this generic/flexible. --- gst-libs/gst/video/.gitignore | 1 + gst-libs/gst/video/Makefile.am | 39 +- gst-libs/gst/video/video-blend.c | 1423 ++++++++++++++++++++++++++ gst-libs/gst/video/video-blend.h | 77 ++ gst-libs/gst/video/videoblendorc.orc | 498 +++++++++ 5 files changed, 2028 insertions(+), 10 deletions(-) create mode 100644 gst-libs/gst/video/video-blend.c create mode 100644 gst-libs/gst/video/video-blend.h create mode 100644 gst-libs/gst/video/videoblendorc.orc diff --git a/gst-libs/gst/video/.gitignore b/gst-libs/gst/video/.gitignore index 42df1ec5ae..750405b619 100644 --- a/gst-libs/gst/video/.gitignore +++ b/gst-libs/gst/video/.gitignore @@ -1,2 +1,3 @@ video-enumtypes.c video-enumtypes.h +videoblendorc.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 21ce6e48bc..5ab524f082 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -4,26 +4,45 @@ glib_enum_define = GST_VIDEO glib_gen_prefix = gst_video glib_gen_basename = video +lib_LTLIBRARIES = libgstvideo-@GST_MAJORMINOR@.la + +ORC_SOURCE=videoblendorc +include $(top_srcdir)/common/orc.mak + built_sources = video-enumtypes.c built_headers = video-enumtypes.h -BUILT_SOURCES = $(built_sources) $(built_headers) -lib_LTLIBRARIES = libgstvideo-@GST_MAJORMINOR@.la +# orc.mak sets BUILT_SOURCES as well +BUILT_SOURCES += $(built_sources) $(built_headers) CLEANFILES = $(BUILT_SOURCES) +# video-blend.h should be disted but not installed into the includedir libgstvideo_@GST_MAJORMINOR@_la_SOURCES = \ - video.c gstvideosink.c gstvideofilter.c convertframe.c -nodist_libgstvideo_@GST_MAJORMINOR@_la_SOURCES = $(BUILT_SOURCES) - + video.c gstvideosink.c gstvideofilter.c convertframe.c \ + video-blend.c video-blend.h +nodist_libgstvideo_@GST_MAJORMINOR@_la_SOURCES = \ + $(built_sources) $(built_headers) \ + $(ORC_NODIST_SOURCES) libgstvideo_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video libgstvideo_@GST_MAJORMINOR@include_HEADERS = \ video.h gstvideosink.h gstvideofilter.h nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS = $(built_headers) -libgstvideo_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) -libgstvideo_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) -libgstvideo_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS) +libgstvideo_@GST_MAJORMINOR@_la_CFLAGS = \ + $(GST_PLUGINS_BASE_CFLAGS)\ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(ORC_CFLAGS) + +libgstvideo_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) \ + $(GST_LIBS) \ + $(ORC_LIBS) + +libgstvideo_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_LIB_LDFLAGS) \ + $(GST_ALL_LDFLAGS) \ + $(GST_LT_LDFLAGS) include $(top_srcdir)/common/gst-glib-gen.mak @@ -31,9 +50,9 @@ if HAVE_INTROSPECTION BUILT_GIRSOURCES = GstVideo-@GST_MAJORMINOR@.gir gir_headers=$(patsubst %,$(srcdir)/%, $(libgstvideo_@GST_MAJORMINOR@include_HEADERS)) -gir_headers+=$(patsubst %,$(builddir)/%, $(nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS)) +gir_headers+=$(patsubst %,$(builddir)/%, $(built_headers)) gir_sources=$(patsubst %,$(srcdir)/%, $(libgstvideo_@GST_MAJORMINOR@_la_SOURCES)) -gir_sources+=$(patsubst %,$(builddir)/%, $(nodist_libgstvideo_@GST_MAJORMINOR@_la_SOURCES)) +gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources)) gir_cincludes=$(patsubst %,--c-include='gst/video/%',$(libgstvideo_@GST_MAJORMINOR@include_HEADERS)) gir_cincludes+=$(patsubst %,--c-include='gst/video/%',$(nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS)) diff --git a/gst-libs/gst/video/video-blend.c b/gst-libs/gst/video/video-blend.c new file mode 100644 index 0000000000..745d540ee8 --- /dev/null +++ b/gst-libs/gst/video/video-blend.c @@ -0,0 +1,1423 @@ +/* Gstreamer video blending utility functions + * + * Copied/pasted from gst/videoconvert/videoconvert.c + * Copyright (C) 2010 David Schleef + * Copyright (C) 2010 Sebastian Dröge + * + * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011> Collabora Ltd. + * Copyright (C) <2011> Thibault Saunier + * + * 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 "video-blend.h" +#include "videoblendorc.h" + +#include + +#ifndef GST_DISABLE_GST_DEBUG + +#define GST_CAT_DEFAULT ensure_debug_category() + +static GstDebugCategory * +ensure_debug_category (void) +{ + static gsize cat_gonce = 0; + + if (g_once_init_enter (&cat_gonce)) { + gsize cat_done; + + cat_done = (gsize) _gst_debug_category_new ("video-blending", 0, + "video blending"); + + g_once_init_leave (&cat_gonce, cat_done); + } + + return (GstDebugCategory *) cat_gonce; +} + +#else + +#define ensure_debug_category() /* NOOP */ + +#endif /* GST_DISABLE_GST_DEBUG */ + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define ARGB_A 3 +# define ARGB_R 2 +# define ARGB_G 1 +# define ARGB_B 0 +#else +# define ARGB_A 0 +# define ARGB_R 1 +# define ARGB_G 2 +# define ARGB_B 3 +#endif + +/* Copy/pasted from 0.11 video.c */ +static int +fill_planes (GstBlendVideoFormatInfo * info) +{ + gint width, height; + + width = info->width; + height = info->height; + + switch (info->fmt) { + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + info->stride[0] = GST_ROUND_UP_4 (width * 2); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_AYUV: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_r210: + info->stride[0] = width * 4; + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_RGB16: + case GST_VIDEO_FORMAT_BGR16: + case GST_VIDEO_FORMAT_RGB15: + case GST_VIDEO_FORMAT_BGR15: + info->stride[0] = GST_ROUND_UP_4 (width * 2); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + case GST_VIDEO_FORMAT_v308: + info->stride[0] = GST_ROUND_UP_4 (width * 3); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_v210: + info->stride[0] = ((width + 47) / 48) * 128; + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_v216: + info->stride[0] = GST_ROUND_UP_8 (width * 4); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_GRAY8: + case GST_VIDEO_FORMAT_Y800: + info->stride[0] = GST_ROUND_UP_4 (width); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_GRAY16_BE: + case GST_VIDEO_FORMAT_GRAY16_LE: + case GST_VIDEO_FORMAT_Y16: + info->stride[0] = GST_ROUND_UP_4 (width * 2); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_UYVP: + info->stride[0] = GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_RGB8_PALETTED: + info->stride[0] = GST_ROUND_UP_4 (width); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_IYU1: + info->stride[0] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) + + GST_ROUND_UP_4 (width) / 2); + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + info->stride[0] = width * 8; + info->offset[0] = 0; + break; + case GST_VIDEO_FORMAT_I420: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2); + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); + info->offset[2] = info->offset[1] + + info->stride[1] * (GST_ROUND_UP_2 (height) / 2); + break; + case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */ + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2); + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[2] = info->stride[0] * GST_ROUND_UP_2 (height); + info->offset[1] = info->offset[2] + + info->stride[1] * (GST_ROUND_UP_2 (height) / 2); + break; + case GST_VIDEO_FORMAT_Y41B: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_16 (width) / 4; + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * height; + info->offset[2] = info->offset[1] + info->stride[1] * height; + /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */ + break; + case GST_VIDEO_FORMAT_Y42B: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_8 (width) / 2; + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * height; + info->offset[2] = info->offset[1] + info->stride[1] * height; + /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */ + break; + case GST_VIDEO_FORMAT_Y444: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = info->stride[0]; + info->stride[2] = info->stride[0]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * height; + info->offset[2] = info->offset[1] * 2; + break; + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = info->stride[0]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); + break; + case GST_VIDEO_FORMAT_A420: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2); + info->stride[2] = info->stride[1]; + info->stride[3] = info->stride[0]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); + info->offset[2] = info->offset[1] + + info->stride[1] * (GST_ROUND_UP_2 (height) / 2); + info->offset[3] = info->offset[2] + + info->stride[2] * (GST_ROUND_UP_2 (height) / 2); + break; + case GST_VIDEO_FORMAT_YUV9: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4); + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * height; + info->offset[2] = info->offset[1] + + info->stride[1] * (GST_ROUND_UP_4 (height) / 4); + break; + case GST_VIDEO_FORMAT_YVU9: + info->stride[0] = GST_ROUND_UP_4 (width); + info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4); + info->stride[2] = info->stride[1]; + info->offset[0] = 0; + info->offset[2] = info->stride[0] * height; + info->offset[1] = info->offset[2] + + info->stride[1] * (GST_ROUND_UP_4 (height) / 4); + break; + case GST_VIDEO_FORMAT_UNKNOWN: + GST_ERROR ("invalid format"); + g_warning ("invalid format"); + break; + } + return 0; +} + +typedef struct +{ + GstVideoFormat format; + void (*getline) (guint8 * dest, const GstBlendVideoFormatInfo * src, + guint xoff, int j); + void (*putline) (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, + int j); + void (*matrix) (guint8 * tmpline, guint width); +} GetPutLine; + + +#define GET_LINE(info, comp, line) \ + (info)->pixels + info->offset[(comp)] + ((info)->stride[(comp)] * (line)) + +/* Line conversion to AYUV */ + +/* Supports YV12 as well */ +static void +getline_I420 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_I420 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (src, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2), src->width); +} + +/* Supports YV12 as well */ +static void +putline_I420 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_I420 (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (dest, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + line, srcinfo->width / 2); +} + +static void +getline_YUY2 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_YUY2 (dest, GET_LINE (src, 0, j) + + (GST_ROUND_UP_2 (xoff * 4) / 2), src->width / 2); +} + +static void +putline_YUY2 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + cogorc_putline_YUY2 (GET_LINE (dest, 0, + j) + (GST_ROUND_UP_2 (xoff * 4) / 2), line, srcinfo->width / 2); +} + + +static void +getline_AYUV (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + memcpy (dest, GET_LINE (src, 0, j) + (xoff * 4), (src->width - xoff) * 4); +} + +static void +putline_AYUV (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + memcpy (GET_LINE (dest, 0, j) + (xoff * 4), line, srcinfo->width * 4); +} + +static void +getline_UYVY (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_UYVY (dest, GET_LINE (src, 0, j) + xoff * 2, src->width / 2); +} + +static void +putline_UYVY (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + cogorc_putline_UYVY (GET_LINE (dest, 0, j) + + (GST_ROUND_UP_2 (xoff * 4) / 2), line, srcinfo->width / 2); +} + +static void +getline_v308 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff * 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 0]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 2]; + } +} + +static void +putline_v308 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff * 3); + + for (i = 0; i < srcinfo->width; i++) { + destline[i * 3 + 0] = line[i * 4 + 1]; + destline[i * 3 + 1] = line[i * 4 + 2]; + destline[i * 3 + 2] = line[i * 4 + 3]; + } +} + +static void +getline_v210 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff * 4) / 5; + + for (i = 0; i < src->width; i += 6) { + guint32 a0, a1, a2, a3; + guint16 y0, y1, y2, y3, y4, y5; + guint16 u0, u2, u4; + guint16 v0, v2, v4; + + a0 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 0); + a1 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 4); + a2 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 8); + a3 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 12); + + u0 = ((a0 >> 0) & 0x3ff) >> 2; + y0 = ((a0 >> 10) & 0x3ff) >> 2; + v0 = ((a0 >> 20) & 0x3ff) >> 2; + y1 = ((a1 >> 0) & 0x3ff) >> 2; + + u2 = ((a1 >> 10) & 0x3ff) >> 2; + y2 = ((a1 >> 20) & 0x3ff) >> 2; + v2 = ((a2 >> 0) & 0x3ff) >> 2; + y3 = ((a2 >> 10) & 0x3ff) >> 2; + + u4 = ((a2 >> 20) & 0x3ff) >> 2; + y4 = ((a3 >> 0) & 0x3ff) >> 2; + v4 = ((a3 >> 10) & 0x3ff) >> 2; + y5 = ((a3 >> 20) & 0x3ff) >> 2; + + dest[4 * (i + 0) + 0] = 0xff; + dest[4 * (i + 0) + 1] = y0; + dest[4 * (i + 0) + 2] = u0; + dest[4 * (i + 0) + 3] = v0; + + dest[4 * (i + 1) + 0] = 0xff; + dest[4 * (i + 1) + 1] = y1; + dest[4 * (i + 1) + 2] = u0; + dest[4 * (i + 1) + 3] = v0; + + dest[4 * (i + 2) + 0] = 0xff; + dest[4 * (i + 2) + 1] = y2; + dest[4 * (i + 2) + 2] = u2; + dest[4 * (i + 2) + 3] = v2; + + dest[4 * (i + 3) + 0] = 0xff; + dest[4 * (i + 3) + 1] = y3; + dest[4 * (i + 3) + 2] = u2; + dest[4 * (i + 3) + 3] = v2; + + dest[4 * (i + 4) + 0] = 0xff; + dest[4 * (i + 4) + 1] = y4; + dest[4 * (i + 4) + 2] = u4; + dest[4 * (i + 4) + 3] = v4; + + dest[4 * (i + 5) + 0] = 0xff; + dest[4 * (i + 5) + 1] = y5; + dest[4 * (i + 5) + 2] = u4; + dest[4 * (i + 5) + 3] = v4; + + } + +} + +static void +putline_v210 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff * 4) / 5; + + + for (i = 0; i < srcinfo->width + 5; i += 6) { + guint32 a0, a1, a2, a3; + guint16 y0, y1, y2, y3, y4, y5; + guint16 u0, u1, u2; + guint16 v0, v1, v2; + + y0 = line[4 * (i + 0) + 1] << 2; + y1 = line[4 * (i + 1) + 1] << 2; + y2 = line[4 * (i + 2) + 1] << 2; + y3 = line[4 * (i + 3) + 1] << 2; + y4 = line[4 * (i + 4) + 1] << 2; + y5 = line[4 * (i + 5) + 1] << 2; + + u0 = (line[4 * (i + 0) + 2] + line[4 * (i + 1) + 2]) << 1; + u1 = (line[4 * (i + 2) + 2] + line[4 * (i + 3) + 2]) << 1; + u2 = (line[4 * (i + 4) + 2] + line[4 * (i + 5) + 2]) << 1; + + v0 = (line[4 * (i + 0) + 3] + line[4 * (i + 1) + 3]) << 1; + v1 = (line[4 * (i + 2) + 3] + line[4 * (i + 3) + 3]) << 1; + v2 = (line[4 * (i + 4) + 3] + line[4 * (i + 5) + 3]) << 1; + + a0 = u0 | (y0 << 10) | (v0 << 20); + a1 = y1 | (u1 << 10) | (y2 << 20); + a2 = v1 | (y3 << 10) | (u2 << 20); + a3 = y4 | (v2 << 10) | (y5 << 20); + + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 0, a0); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 4, a1); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 8, a2); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 12, a3); + } +} + +static void +getline_v216 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + GST_ROUND_UP_2 (xoff + 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = GST_READ_UINT16_LE (srcline + i * 4 + 2) >> 8; + dest[i * 4 + 2] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 0) >> 8; + dest[i * 4 + 3] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 4) >> 8; + } +} + +static void +putline_v216 (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 (xoff + 3); + + for (i = 0; i < srcinfo->width / 2; i++) { + GST_WRITE_UINT16_LE (destline + i * 8 + 0, line[(i * 2 + 0) * 4 + 2] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 2, line[(i * 2 + 0) * 4 + 1] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 4, line[(i * 2 + 1) * 4 + 3] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 8, line[(i * 2 + 0) * 4 + 1] << 8); + } +} + +static void +getline_Y41B (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_YUV9 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j) + (xoff / 4), GET_LINE (src, 2, j) + (xoff / 4), + src->width / 2); +} + +static void +putline_Y41B (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destlineY = GET_LINE (dest, 0, j) + xoff; + guint8 *destlineU = GET_LINE (dest, 1, j) + (xoff / 4); + guint8 *destlineV = GET_LINE (dest, 2, j) + (xoff / 4); + + for (i = 0; i < srcinfo->width - 3; i += 4) { + destlineY[i] = line[i * 4 + 1]; + destlineY[i + 1] = line[i * 4 + 5]; + destlineY[i + 2] = line[i * 4 + 9]; + destlineY[i + 3] = line[i * 4 + 13]; + + destlineU[i >> 2] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 + + 14] + 2) >> 2; + destlineV[i >> 2] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 + + 15] + 2) >> 2; + } + + if (i == srcinfo->width - 3) { + destlineY[i] = line[i * 4 + 1]; + destlineY[i + 1] = line[i * 4 + 5]; + destlineY[i + 2] = line[i * 4 + 9]; + + destlineU[i >> 2] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + 1) / 3; + destlineV[i >> 2] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + 1) / 3; + } else if (i == srcinfo->width - 2) { + destlineY[i] = line[i * 4 + 1]; + destlineY[i + 1] = line[i * 4 + 5]; + + destlineU[i >> 2] = (line[i * 4 + 2] + line[i * 4 + 6] + 1) >> 1; + destlineV[i >> 2] = (line[i * 4 + 3] + line[i * 4 + 7] + 1) >> 1; + } else if (i == srcinfo->width - 1) { + destlineY[i + 1] = line[i * 4 + 5]; + + destlineU[i >> 2] = line[i * 4 + 2]; + destlineV[i >> 2] = line[i * 4 + 3]; + } +} + +static void +getline_Y42B (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_Y42B (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (src, 2, j) + GST_ROUND_UP_2 (xoff / 2), src->width / 2); +} + +static void +putline_Y42B (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_Y42B (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (dest, 2, j) + GST_ROUND_UP_2 (xoff / 2), line, + srcinfo->width / 2); +} + +static void +getline_Y444 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_Y444 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j) + xoff, GET_LINE (src, 2, j) + xoff, src->width); +} + +static void +putline_Y444 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_Y444 (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j) + xoff, + GET_LINE (dest, 2, j) + xoff, line, srcinfo->width); +} + +static void +getline_Y800 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_Y800 (dest, GET_LINE (src, 0, j) + xoff, src->width); +} + +static void +putline_Y800 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_Y800 (GET_LINE (dest, 0, j) + xoff, line, srcinfo->width); +} + +static void +getline_Y16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_Y16 (dest, GET_LINE (src, 0, j) + xoff * 2, src->width); +} + +static void +putline_Y16 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_Y16 (GET_LINE (dest, 0, j) + xoff * 2, line, srcinfo->width); +} + +static void +getline_NV12 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_NV12 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j >> 1) + xoff, src->width / 2); +} + +static void +putline_NV12 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_NV12 (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j >> 1) + xoff, line, srcinfo->width / 2); +} + +static void +getline_NV21 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_NV21 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j >> 1) + xoff, src->width / 2); +} + +static void +putline_NV21 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_NV21 (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j >> 1) + xoff, line, srcinfo->width / 2); +} + +static void +getline_UYVP (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + + xoff * 3; + + for (i = 0; i < src->width; i += 2) { + guint16 y0, y1; + guint16 u0; + guint16 v0; + + u0 = (srcline[(i / 2) * 5 + 0] << 2) | (srcline[(i / 2) * 5 + 1] >> 6); + + y0 = ((srcline[(i / 2) * 5 + 1] & 0x3f) << 4) | + (srcline[(i / 2) * 5 + 2] >> 4); + + v0 = ((srcline[(i / 2) * 5 + 2] & 0x0f) << 6) | + (srcline[(i / 2) * 5 + 3] >> 2); + + y1 = ((srcline[(i / 2) * 5 + 3] & 0x03) << 8) | srcline[(i / 2) * 5 + 4]; + + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = y0 >> 2; + dest[i * 4 + 2] = u0 >> 2; + dest[i * 4 + 3] = v0 >> 2; + dest[i * 4 + 4] = 0xff; + dest[i * 4 + 5] = y1 >> 2; + dest[i * 4 + 6] = u0 >> 2; + dest[i * 4 + 7] = v0 >> 2; + } +} + +static void +putline_UYVP (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3; + + for (i = 0; i < srcinfo->width; i += 2) { + guint16 y0, y1; + guint16 u0; + guint16 v0; + + y0 = line[4 * (i + 0) + 1]; + y1 = line[4 * (i + 1) + 1]; + u0 = (line[4 * (i + 0) + 2] + line[4 * (i + 1) + 2] + 1) >> 1; + v0 = (line[4 * (i + 0) + 3] + line[4 * (i + 1) + 3] + 1) >> 1; + + destline[(i / 2) * 5 + 0] = u0; + destline[(i / 2) * 5 + 1] = y0 >> 2; + destline[(i / 2) * 5 + 2] = (y0 << 6) | (v0 >> 4); + destline[(i / 2) * 5 + 3] = (v0 << 4) | (y1 >> 2); + destline[(i / 2) * 5 + 4] = (y1 << 2); + } +} + +static void +getline_A420 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_A420 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (src, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (src, 3, j) + GST_ROUND_UP_2 (xoff / 2), src->width); +} + +static void +putline_A420 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_A420 (GET_LINE (dest, 0, j) + xoff, + GET_LINE (dest, 1, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (dest, 2, j >> 1) + GST_ROUND_UP_2 (xoff / 2), + GET_LINE (dest, 3, j) + GST_ROUND_UP_2 (xoff / 2), line, + srcinfo->width / 2); +} + +static void +getline_YUV9 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_YUV9 (dest, + GET_LINE (src, 0, j) + xoff, + GET_LINE (src, 1, j >> 2) + GST_ROUND_UP_4 (xoff / 4), + GET_LINE (src, 2, j >> 2) + GST_ROUND_UP_4 (xoff / 4), src->width / 2); +} + +static void +putline_YUV9 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destY = GET_LINE (dest, 0, j) + xoff; + guint8 *destU = GET_LINE (dest, 1, j >> 2) + GST_ROUND_UP_4 (xoff / 4); + guint8 *destV = GET_LINE (dest, 2, j >> 2) + GST_ROUND_UP_4 (xoff / 4); + guint width = srcinfo->width; + + for (i = 0; i < width - 3; i += 4) { + destY[i] = line[i * 4 + 1]; + destY[i + 1] = line[i * 4 + 5]; + destY[i + 2] = line[i * 4 + 9]; + destY[i + 3] = line[i * 4 + 13]; + if (j % 4 == 0) { + destU[i >> 2] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 + + 14]) >> 2; + destV[i >> 2] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 + + 15]) >> 2; + } + } + + if (i == width - 3) { + destY[i] = line[i * 4 + 1]; + destY[i + 1] = line[i * 4 + 5]; + destY[i + 2] = line[i * 4 + 9]; + if (j % 4 == 0) { + destU[i >> 2] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10]) / 3; + destV[i >> 2] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11]) / 3; + } + } else if (i == width - 2) { + destY[i] = line[i * 4 + 1]; + destY[i + 1] = line[i * 4 + 5]; + if (j % 4 == 0) { + destU[i >> 2] = (line[i * 4 + 2] + line[i * 4 + 6]) >> 1; + destV[i >> 2] = (line[i * 4 + 3] + line[i * 4 + 7]) >> 1; + } + } else if (i == width - 1) { + destY[i] = line[i * 4 + 1]; + destU[i >> 2] = line[i * 4 + 2]; + destV[i >> 2] = line[i * 4 + 3]; + } +} + +static void +getline_IYU1 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = + GET_LINE (src, 0, j) + GST_ROUND_UP_2 ((xoff * 3) / 2); + guint width = src->width; + + for (i = 0; i < width - 3; i += 4) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 4] = 0xff; + dest[i * 4 + 8] = 0xff; + dest[i * 4 + 12] = 0xff; + dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1]; + dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2]; + dest[i * 4 + 9] = srcline[(i >> 2) * 6 + 4]; + dest[i * 4 + 13] = srcline[(i >> 2) * 6 + 5]; + dest[i * 4 + 2] = dest[i * 4 + 6] = dest[i * 4 + 10] = dest[i * 4 + 14] = + srcline[(i >> 2) * 6 + 0]; + dest[i * 4 + 3] = dest[i * 4 + 7] = dest[i * 4 + 11] = dest[i * 4 + 15] = + srcline[(i >> 2) * 6 + 3]; + } + + if (i == width - 3) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 4] = 0xff; + dest[i * 4 + 8] = 0xff; + dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1]; + dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2]; + dest[i * 4 + 9] = srcline[(i >> 2) * 6 + 4]; + dest[i * 4 + 2] = dest[i * 4 + 6] = dest[i * 4 + 10] = + srcline[(i >> 2) * 6 + 0]; + dest[i * 4 + 3] = dest[i * 4 + 7] = dest[i * 4 + 11] = + srcline[(i >> 2) * 6 + 3]; + } else if (i == width - 2) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 4] = 0xff; + dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1]; + dest[i * 4 + 5] = srcline[(i >> 2) * 6 + 2]; + dest[i * 4 + 2] = dest[i * 4 + 6] = srcline[(i >> 2) * 6 + 0]; + dest[i * 4 + 3] = dest[i * 4 + 7] = srcline[(i >> 2) * 6 + 3]; + } else if (i == width - 1) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[(i >> 2) * 6 + 1]; + dest[i * 4 + 2] = srcline[(i >> 2) * 6 + 0]; + dest[i * 4 + 3] = srcline[(i >> 2) * 6 + 3]; + } +} + +static void +putline_IYU1 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + GST_ROUND_UP_2 ((xoff * 3) / 2); + guint width = srcinfo->width; + + for (i = 0; i < width - 3; i += 4) { + destline[(i >> 2) * 6 + 1] = line[i * 4 + 1]; + destline[(i >> 2) * 6 + 2] = line[i * 4 + 5]; + destline[(i >> 2) * 6 + 4] = line[i * 4 + 9]; + destline[(i >> 2) * 6 + 5] = line[i * 4 + 13]; + destline[(i >> 2) * 6 + 0] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10] + line[i * 4 + + 14]) >> 2; + destline[(i >> 2) * 6 + 3] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11] + line[i * 4 + + 15]) >> 2; + } + + if (i == width - 3) { + destline[(i >> 2) * 6 + 1] = line[i * 4 + 1]; + destline[(i >> 2) * 6 + 2] = line[i * 4 + 5]; + destline[(i >> 2) * 6 + 4] = line[i * 4 + 9]; + destline[(i >> 2) * 6 + 0] = + (line[i * 4 + 2] + line[i * 4 + 6] + line[i * 4 + 10]) / 3; + destline[(i >> 2) * 6 + 3] = + (line[i * 4 + 3] + line[i * 4 + 7] + line[i * 4 + 11]) / 3; + } else if (i == width - 2) { + destline[(i >> 2) * 6 + 1] = line[i * 4 + 1]; + destline[(i >> 2) * 6 + 2] = line[i * 4 + 5]; + destline[(i >> 2) * 6 + 0] = (line[i * 4 + 2] + line[i * 4 + 6]) >> 1; + destline[(i >> 2) * 6 + 3] = (line[i * 4 + 3] + line[i * 4 + 7]) >> 1; + } else if (i == width - 1) { + destline[(i >> 2) * 6 + 1] = line[i * 4 + 1]; + destline[(i >> 2) * 6 + 0] = line[i * 4 + 2]; + destline[(i >> 2) * 6 + 3] = line[i * 4 + 3]; + } +} + + +/* Line conversion to ARGB */ +static void +getline_RGB (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + xoff * 3; + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 0]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 2]; + } +} + +static void +putline_RGB (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3; + + for (i = 0; i < srcinfo->width; i++) { + destline[i * 3 + 0] = line[i * 4 + 1]; + destline[i * 3 + 1] = line[i * 4 + 2]; + destline[i * 3 + 2] = line[i * 4 + 3]; + } +} + +static void +getline_BGR (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint8 *srcline = GET_LINE (src, 0, j) + xoff * 3; + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 2]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 0]; + } +} + +static void +putline_BGR (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + int i; + guint8 *destline = GET_LINE (dest, 0, j) + xoff * 3; + + for (i = 0; i < srcinfo->width; i++) { + destline[i * 3 + 0] = line[i * 4 + 3]; + destline[i * 3 + 1] = line[i * 4 + 2]; + destline[i * 3 + 2] = line[i * 4 + 1]; + } +} + +static void +getline_RGBA (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_RGBA (dest, GET_LINE (src, 0, j) + (4 * xoff), src->width); +} + +static void +putline_RGBA (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + cogorc_putline_RGBA (GET_LINE (dest, 0, j) + (4 * xoff), + line, srcinfo->width); +} + +static void +getline_ARGB (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + + memcpy (dest, GET_LINE (src, 0, j), (src->width - xoff) * 4); +} + +static void +putline_ARGB (GstBlendVideoFormatInfo * dest, GstBlendVideoFormatInfo * srcinfo, + const guint8 * line, guint xoff, int j) +{ + memcpy (GET_LINE (dest, 0, j) + (xoff * 4), line, srcinfo->width * 4); +} + +static void +getline_RGB16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j) + + (xoff * 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = ((srcline[i] >> 11) & 0x1f) << 3; + dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x3f) << 2; + dest[i * 4 + 3] = ((srcline[i]) & 0x1f) << 3; + } +} + +static void +putline_RGB16 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3); + + for (i = 0; i < srcinfo->width; i++) { + destline[i] = ((line[i * 4 + 1] >> 3) << 11) | ((line[i * 4 + + 2] >> 2) << 5) | (line[i * 4 + 3] >> 3); + } +} + +static void +getline_RGB15 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j) + + (xoff * 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = ((srcline[i] >> 10) & 0x1f) << 3; + dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x1f) << 3; + dest[i * 4 + 3] = ((srcline[i]) & 0x1f) << 3; + } +} + +static void +putline_RGB15 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3); + + for (i = 0; i < srcinfo->width; i++) { + destline[i] = ((line[i * 4 + 1] >> 3) << 10) | ((line[i * 4 + + 2] >> 3) << 5) | (line[i * 4 + 3] >> 3); + } +} + +static void +getline_BGR15 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j) + + (xoff * 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 3] = ((srcline[i] >> 10) & 0x1f) << 3; + dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x1f) << 3; + dest[i * 4 + 1] = ((srcline[i]) & 0x1f) << 3; + } +} + +static void +putline_BGR15 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3); + + for (i = 0; i < srcinfo->width; i++) { + destline[i] = ((line[i * 4 + 3] >> 3) << 10) | ((line[i * 4 + + 2] >> 3) << 5) | (line[i * 4 + 1] >> 3); + } +} + +static void +getline_BGR16 (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + int i; + const guint16 *srcline = (const guint16 *) GET_LINE (src, 0, j) + + (xoff * 3); + + for (i = 0; i < src->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 3] = ((srcline[i] >> 11) & 0x1f) << 3; + dest[i * 4 + 2] = ((srcline[i] >> 5) & 0x3f) << 2; + dest[i * 4 + 1] = ((srcline[i]) & 0x1f) << 3; + } +} + +static void +putline_BGR16 (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + int i; + guint16 *destline = (guint16 *) GET_LINE (dest, 0, j) + (xoff * 3); + + for (i = 0; i < srcinfo->width; i++) { + destline[i] = ((line[i * 4 + 3] >> 3) << 11) | ((line[i * 4 + + 2] >> 2) << 5) | (line[i * 4 + 1] >> 3); + } +} + +static void +getline_BGRA (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_BGRA (dest, GET_LINE (src, 0, j) + xoff * 4, src->width); +} + +static void +putline_BGRA (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_BGRA (GET_LINE (dest, 0, j) + xoff * 4, line, srcinfo->width); +} + +static void +getline_ABGR (guint8 * dest, const GstBlendVideoFormatInfo * src, guint xoff, + int j) +{ + cogorc_getline_ABGR (dest, GET_LINE (src, 0, j) + (xoff * 4), src->width); +} + +static void +putline_ABGR (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * srcinfo, const guint8 * line, guint xoff, int j) +{ + cogorc_putline_ABGR (GET_LINE (dest, 0, j) + (xoff * 4), + line, srcinfo->width); +} + +static const GetPutLine lines[] = { + /* YUV lines conversion */ + {GST_VIDEO_FORMAT_I420, getline_I420, putline_I420}, + {GST_VIDEO_FORMAT_YV12, getline_I420, putline_I420}, + {GST_VIDEO_FORMAT_AYUV, getline_AYUV, putline_AYUV}, + {GST_VIDEO_FORMAT_YUY2, getline_YUY2, putline_YUY2}, + {GST_VIDEO_FORMAT_UYVY, getline_UYVY, putline_UYVY}, + {GST_VIDEO_FORMAT_v308, getline_v308, putline_v308}, + {GST_VIDEO_FORMAT_v210, getline_v210, putline_v210}, + {GST_VIDEO_FORMAT_v216, getline_v216, putline_v216}, + {GST_VIDEO_FORMAT_Y41B, getline_Y41B, putline_Y41B}, + {GST_VIDEO_FORMAT_Y42B, getline_Y42B, putline_Y42B}, + {GST_VIDEO_FORMAT_Y444, getline_Y444, putline_Y444}, + {GST_VIDEO_FORMAT_Y800, getline_Y800, putline_Y800}, + {GST_VIDEO_FORMAT_Y16, getline_Y16, putline_Y16}, + {GST_VIDEO_FORMAT_NV12, getline_NV12, putline_NV12}, + {GST_VIDEO_FORMAT_NV21, getline_NV21, putline_NV21}, + {GST_VIDEO_FORMAT_UYVP, getline_UYVP, putline_UYVP}, + {GST_VIDEO_FORMAT_A420, getline_A420, putline_A420}, + {GST_VIDEO_FORMAT_YUV9, getline_YUV9, putline_YUV9}, + {GST_VIDEO_FORMAT_IYU1, getline_IYU1, putline_IYU1}, + + /* ARGB lines conversion */ + {GST_VIDEO_FORMAT_RGB, getline_RGB, putline_RGB}, + {GST_VIDEO_FORMAT_BGR, getline_BGR, putline_BGR}, + {GST_VIDEO_FORMAT_RGBx, getline_RGBA, putline_RGBA}, + {GST_VIDEO_FORMAT_RGBA, getline_RGBA, putline_RGBA}, + {GST_VIDEO_FORMAT_ARGB, getline_ARGB, putline_ARGB}, + {GST_VIDEO_FORMAT_RGB16, getline_RGB16, putline_RGB16}, + {GST_VIDEO_FORMAT_BGR16, getline_BGR16, putline_BGR16}, + {GST_VIDEO_FORMAT_BGR15, getline_BGR15, putline_BGR15}, + {GST_VIDEO_FORMAT_RGB15, getline_RGB15, putline_RGB15}, + {GST_VIDEO_FORMAT_BGRA, getline_BGRA, putline_BGRA}, + {GST_VIDEO_FORMAT_ABGR, getline_ABGR, putline_ABGR}, + {GST_VIDEO_FORMAT_BGRx, getline_BGRA, putline_BGRA} +}; + +static void +matrix_identity (guint8 * tmpline, guint width) +{ +} + +static void +matrix_rgb_to_yuv (guint8 * tmpline, guint width) +{ + int i; + int r, g, b; + int y, u, v; + + for (i = 0; i < width; i++) { + r = tmpline[i * 4 + 1]; + g = tmpline[i * 4 + 2]; + b = tmpline[i * 4 + 3]; + + y = (47 * r + 157 * g + 16 * b + 4096) >> 8; + u = (-26 * r - 87 * g + 112 * b + 32768) >> 8; + v = (112 * r - 102 * g - 10 * b + 32768) >> 8; + + tmpline[i * 4 + 1] = CLAMP (y, 0, 255); + tmpline[i * 4 + 2] = CLAMP (u, 0, 255); + tmpline[i * 4 + 3] = CLAMP (v, 0, 255); + } +} + +static void +matrix_yuv_to_rgb (guint8 * tmpline, guint width) +{ + int i; + int r, g, b; + int y, u, v; + + for (i = 0; i < width; i++) { + y = tmpline[i * 4 + 1]; + u = tmpline[i * 4 + 2]; + v = tmpline[i * 4 + 3]; + + r = (298 * y + 459 * v - 63514) >> 8; + g = (298 * y - 55 * u - 136 * v + 19681) >> 8; + b = (298 * y + 541 * u - 73988) >> 8; + + tmpline[i * 4 + ARGB_R] = CLAMP (r, 0, 255); + tmpline[i * 4 + ARGB_G] = CLAMP (g, 0, 255); + tmpline[i * 4 + ARGB_B] = CLAMP (b, 0, 255); + } +} + +static gboolean +lookup_getput (GetPutLine * getput, GstVideoFormat fmt) +{ + int i; + + getput->getline = NULL; + getput->putline = NULL; + getput->matrix = matrix_identity; + + for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) { + if (lines[i].format == fmt) { + getput->getline = lines[i].getline; + getput->putline = lines[i].putline; + + return TRUE; + } + } + GST_WARNING ("Conversion from %i not supported", fmt); + + return FALSE; +} + +#define BLEND(ret, alpha, v0, v1) \ +{ \ + ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \ +} + +void +video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src, + gint dest_height, gint dest_width) +{ + int acc; + int y_increment; + int x_increment; + int y1; + int i; + int j; + int x; + int dest_size; + guint dest_stride = dest_width * 4; + guint src_stride = src->width * 4; + + guint8 *tmpbuf = g_malloc (dest_width * 8 * 4); + guint8 *dest_pixels = + g_malloc (gst_video_format_get_size (src->fmt, dest_height, + dest_width)); + + if (dest_height == 1) + y_increment = 0; + else + y_increment = ((src->height - 1) << 16) / (dest_height - 1) - 1; + + if (dest_width == 1) + x_increment = 0; + else + x_increment = ((src->width - 1) << 16) / (dest_width - 1) - 1; + + dest_size = dest_width * 4; + +#define LINE(x) ((tmpbuf) + (dest_size)*((x)&1)) + + acc = 0; + orc_resample_bilinear_u32 (LINE (0), src->pixels, 0, x_increment, dest_width); + y1 = 0; + for (i = 0; i < dest_height; i++) { + j = acc >> 16; + x = acc & 0xffff; + + if (x == 0) { + memcpy (dest_pixels + i * dest_stride, LINE (j), dest_size); + } else { + if (j > y1) { + orc_resample_bilinear_u32 (LINE (j), + src->pixels + j * src_stride, 0, x_increment, dest_width); + y1++; + } + if (j >= y1) { + orc_resample_bilinear_u32 (LINE (j + 1), + src->pixels + (j + 1) * src_stride, 0, x_increment, dest_width); + y1++; + } + orc_merge_linear_u8 (dest_pixels + i * dest_stride, + LINE (j), LINE (j + 1), (x >> 8), dest_width * 4); + } + + acc += y_increment; + } + + /* Update src, our reference to the old src->pixels is lost */ + video_blend_format_info_init (src, dest_pixels, dest_height, dest_width, + src->fmt); + + g_free (tmpbuf); +} + +/* video_blend: + * @dest: The #GstBlendVideoFormatInfo where to blend @src in + * @src: the #GstBlendVideoFormatInfo that we want to blend into + * @dest + * @x: The x offset in pixel where the @src image should be blended + * @y: the y offset in pixel where the @src image should be blended + * + * Lets you blend the @src image into the @dest image + */ +gboolean +video_blend (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * src, guint x, guint y) +{ + guint i, j; + guint8 alpha; + GetPutLine getputdest, getputsrc; + + gint src_stride = src->width * 4; + guint8 *tmpdestline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); + guint8 *tmpsrcline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); + + ensure_debug_category (); + + + if (!lookup_getput (&getputdest, dest->fmt)) + goto failed; + + if (!lookup_getput (&getputsrc, src->fmt)) + goto failed; + + if (gst_video_format_is_rgb (src->fmt) != gst_video_format_is_rgb (dest->fmt)) + getputsrc.matrix = gst_video_format_is_rgb (src->fmt) ? + matrix_rgb_to_yuv : matrix_yuv_to_rgb; + + /* adjust src pointers for negative sizes */ + if (x < 0) { + src += -x * 4; + src->width -= -x; + x = 0; + } + + if (y < 0) { + src += -y * src_stride; + src->height -= -y; + y = 0; + } + + /* adjust width/height if the src is bigger than dest */ + if (x + src->width > dest->width) + src->width = dest->width - x; + + if (y + src->height > dest->height) + src->height = dest->height - y; + + /* Mainloop doing the needed conversions, and blending */ + for (i = y; i < y + src->height; i++) { + + getputdest.getline (tmpdestline, dest, x, i); + getputsrc.getline (tmpsrcline, src, 0, (i - y)); + + getputsrc.matrix (tmpsrcline, src->width); + + /* Here dest and src are both either in AYUV or ARGB + * TODO: Make the orc version working properly*/ + for (j = 0; j < src->width * 4; j += 4) { + alpha = tmpsrcline[j]; + + BLEND (tmpdestline[j + 1], alpha, tmpsrcline[j + 1], tmpdestline[j + 1]); + BLEND (tmpdestline[j + 2], alpha, tmpsrcline[j + 2], tmpdestline[j + 2]); + BLEND (tmpdestline[j + 3], alpha, tmpsrcline[j + 3], tmpdestline[j + 3]); + } + + /* FIXME + * #if G_BYTE_ORDER == LITTLE_ENDIAN + * orc_blend_little (tmpdestline, tmpsrcline, dest->width); + * #else + * orc_blend_big (tmpdestline, tmpsrcline, src->width); + * #endif + */ + + getputdest.putline (dest, src, tmpdestline, x, i); + + } + + g_free (tmpdestline); + g_free (tmpsrcline); + + return TRUE; + +failed: + GST_WARNING ("Could not do the blending"); + g_free (tmpdestline); + g_free (tmpsrcline); + + return FALSE; +} + +/* video_blend_format_info_init: + * @info: The #GstBlendVideoFormatInfo to initialize + * @pixels: The pixels data in @fmt format + * @height: The height of the image + * @width: the width of the image + * @fmt: The #GstVideoFormat of the image + * + * Initializes a GstBlendVideoFormatInfo. + * This function can be called on already initialized instances. + */ +void +video_blend_format_info_init (GstBlendVideoFormatInfo * info, + guint8 * pixels, guint height, guint width, GstVideoFormat fmt) +{ + guint nb_component = gst_video_format_has_alpha (fmt) ? 4 : 3; + + ensure_debug_category (); + + GST_DEBUG + ("Initializing video bleding info, height %i, width %i, fmt %i nb_component %i", + height, width, fmt, nb_component); + + info->width = width; + info->height = height; + info->pixels = pixels; + info->fmt = fmt; + info->size = gst_video_format_get_size (fmt, height, width); + + fill_planes (info); +} diff --git a/gst-libs/gst/video/video-blend.h b/gst-libs/gst/video/video-blend.h new file mode 100644 index 0000000000..3d9402ebee --- /dev/null +++ b/gst-libs/gst/video/video-blend.h @@ -0,0 +1,77 @@ +/* Gstreamer video blending utility functions + * + * Copyright (C) <2011> Intel Corporation + * Copyright (C) <2011> Collabora Ltd. + * Copyright (C) <2011> Thibault Saunier + * + * 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_VIDEO_BLEND__ +#define __GST_VIDEO_BLEND__ + +#include +#include + +#define MAX_VIDEO_PLANES 4 + +typedef struct _GstBlendVideoFormatInfo GstBlendVideoFormatInfo; + +/** + * GstBlendVideoFormatInfo: + * @fmt: The #GstVideoFormat describing the video format + * @width: The width of the video + * @height: The height of the video + * @pixels: The buffer containing the pixels of the video + * @size: The size in byte of @pixels + * @offset: The offsets of the different component of the video + * @stride: The stride of the different component of the video + * + * Information describing image properties containing necessary + * fields to do video blending. + */ +struct _GstBlendVideoFormatInfo +{ + GstVideoFormat fmt; + + gint width; + gint height; + + gint dest_width; + gint dest_height; + + guint8 * pixels; + gsize size; + + /* YUV components: Y=0, U=1, V=2, A=3 + * RGB components: R=0, G=1, B=2, A=3 */ + gint offset[MAX_VIDEO_PLANES]; + gint stride[MAX_VIDEO_PLANES]; +}; + +void video_blend_format_info_init (GstBlendVideoFormatInfo * info, + guint8 *pixels, guint height, + guint width, GstVideoFormat fmt); + +void video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src, + gint dest_height, gint dest_width); + +gboolean video_blend (GstBlendVideoFormatInfo * dest, + GstBlendVideoFormatInfo * src, + guint x, guint y); + +#endif diff --git a/gst-libs/gst/video/videoblendorc.orc b/gst-libs/gst/video/videoblendorc.orc new file mode 100644 index 0000000000..2bdae90096 --- /dev/null +++ b/gst-libs/gst/video/videoblendorc.orc @@ -0,0 +1,498 @@ +.function orc_blend_little +.flags 1d +.dest 4 d guint8 +.source 4 s guint8 +.temp 4 t +.temp 2 tw +.temp 1 tb +.temp 4 a +.temp 8 d_wide +.temp 8 s_wide +.temp 8 a_wide +.const 4 a_alpha 0x000000ff + +loadl t, s +convlw tw, t +convwb tb, tw +splatbl a, tb +x4 convubw a_wide, a +x4 shruw a_wide, a_wide, 8 +x4 convubw s_wide, t +loadl t, d +x4 convubw d_wide, t +x4 subw s_wide, s_wide, d_wide +x4 mullw s_wide, s_wide, a_wide +x4 div255w s_wide, s_wide +x4 addw d_wide, d_wide, s_wide +x4 convwb t, d_wide +orl t, t, a_alpha +storel d, t + +.function orc_blend_big +.flags 1d +.dest 4 d guint8 +.source 4 s guint8 +.temp 4 t +.temp 4 t2 +.temp 2 tw +.temp 1 tb +.temp 4 a +.temp 8 d_wide +.temp 8 s_wide +.temp 8 a_wide +.const 4 a_alpha 0xff000000 + +loadl t, s +shrul t2, t, 24 +convlw tw, t2 +convwb tb, tw +splatbl a, tb +x4 convubw a_wide, a +x4 shruw a_wide, a_wide, 8 +x4 convubw s_wide, t +loadl t, d +x4 convubw d_wide, t +x4 subw s_wide, s_wide, d_wide +x4 mullw s_wide, s_wide, a_wide +x4 div255w s_wide, s_wide +x4 addw d_wide, d_wide, s_wide +x4 convwb t, d_wide +orl t, t, a_alpha +storel d, t + +.function cogorc_getline_I420 +.dest 4 d guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay +.temp 1 tu +.temp 1 tv + +loadupdb tu, u +loadupdb tv, v +mergebw uv, tu, tv +mergebw ay, c255, y +mergewl d, ay, uv + + +.function cogorc_putline_I420 +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uv +.temp 2 uu +.temp 2 vv +.temp 1 t1 +.temp 1 t2 + +x2 splitlw uv, ay, ayuv +x2 select1wb y, ay +x2 splitwb vv, uu, uv +splitwb t1, t2, uu +avgub u, t1, t2 +splitwb t1, t2, vv +avgub v, t1, t2 + +.function cogorc_getline_YUY2 +.dest 8 ayuv guint8 +.source 4 yuy2 guint8 +.const 2 c255 0xff +.temp 2 yy +.temp 2 uv +.temp 4 ayay +.temp 4 uvuv + +x2 splitwb uv, yy, yuy2 +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_putline_YUY2 +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 +.temp 2 yy +.temp 2 uv1 +.temp 2 uv2 +.temp 4 ayay +.temp 4 uvuv + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +x2 select1wb yy, ayay +x2 mergebw yuy2, yy, uv1 + + +.function cogorc_putline_UYVY +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 +.temp 2 yy +.temp 2 uv1 +.temp 2 uv2 +.temp 4 ayay +.temp 4 uvuv + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +x2 select1wb yy, ayay +x2 mergebw yuy2, uv1, yy + + +.function cogorc_getline_UYVY +.dest 8 ayuv guint8 +.source 4 uyvy guint8 +.const 2 c255 0xff +.temp 2 yy +.temp 2 uv +.temp 4 ayay +.temp 4 uvuv + +x2 splitwb yy, uv, uyvy +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_getline_YUV9 +.dest 8 d guint8 +.source 2 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 tuv +.temp 4 ay +.temp 4 uv +.temp 1 tu +.temp 1 tv + +loadupdb tu, u +loadupdb tv, v +mergebw tuv, tu, tv +mergewl uv, tuv, tuv +x2 mergebw ay, c255, y +x2 mergewl d, ay, uv + + +.function cogorc_getline_Y42B +.dest 8 ayuv guint8 +.source 2 yy guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay +.temp 4 uvuv +.temp 4 ayay + +mergebw uv, u, v +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + +.function cogorc_putline_Y42B +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv guint8 +.temp 4 ayay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +splitwb v, u, uv1 +x2 select1wb y, ayay + + +.function cogorc_getline_Y444 +.dest 4 ayuv guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay + +mergebw uv, u, v +mergebw ay, c255, y +mergewl ayuv, ay, uv + + +.function cogorc_putline_Y444 +.dest 1 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 ayuv guint8 +.temp 2 ay +.temp 2 uv + +splitlw uv, ay, ayuv +splitwb v, u, uv +select1wb y, ay + +.function cogorc_getline_Y800 +.dest 4 ayuv guint8 +.source 1 y guint8 +.const 1 c255 255 +.const 2 c0x8080 0x8080 +.temp 2 ay + +mergebw ay, c255, y +mergewl ayuv, ay, c0x8080 + + +.function cogorc_putline_Y800 +.dest 1 y guint8 +.source 4 ayuv guint8 +.temp 2 ay + +select0lw ay, ayuv +select1wb y, ay + + +.function cogorc_putline_Y16 +.dest 2 y guint8 +.source 4 ayuv guint8 +.temp 2 ay +.temp 1 yb + +select0lw ay, ayuv +select1wb yb, ay +convubw ay, yb +shlw y, ay, 8 + + +.function cogorc_getline_Y16 +.dest 4 ayuv guint8 +.source 2 y guint8 +.const 1 c255 255 +.const 2 c0x8080 0x8080 +.temp 2 ay +.temp 1 yb + +convhwb yb, y +mergebw ay, c255, yb +mergewl ayuv, ay, c0x8080 + +.function cogorc_getline_BGRA +.dest 4 argb guint8 +.source 4 bgra guint8 + +swapl argb, bgra + +.function cogorc_putline_BGRA +.dest 4 bgra guint8 +.source 4 argb guint8 + +swapl bgra, argb + +.function cogorc_putline_RGBA +.dest 4 rgba guint8 +.source 4 argb guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 rg +.temp 2 ba +.temp 2 ar +.temp 2 gb + +splitlw gb, ar, argb +splitwb b, g, gb +splitwb r, a, ar +mergebw ba, b, a +mergebw rg, r, g +mergewl rgba, rg, ba + +.function cogorc_getline_RGBA +.dest 4 argb guint8 +.source 4 rgba guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 rg +.temp 2 ba +.temp 2 ar +.temp 2 gb + +splitlw ba, rg, rgba +splitwb g, r, rg +splitwb a, b, ba +mergebw ar, a, r +mergebw gb, g, b +mergewl argb, ar, gb + + +.function cogorc_getline_ABGR +.dest 4 argb guint8 +.source 4 abgr guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 gr +.temp 2 ab +.temp 2 ar +.temp 2 gb + +splitlw gr, ab, abgr +splitwb r, g, gr +splitwb b, a, ab +mergebw ar, a, r +mergebw gb, g, b +mergewl argb, ar, gb + + +.function cogorc_putline_ABGR +.dest 4 abgr guint8 +.source 4 argb guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 gr +.temp 2 ab +.temp 2 ar +.temp 2 gb + +splitlw gb, ar, argb +splitwb b, g, gb +splitwb r, a, ar +mergebw ab, a, b +mergebw gr, g, r +mergewl abgr, ab, gr + +.function cogorc_getline_NV12 +.dest 8 d guint8 +.source 2 y guint8 +.source 2 uv guint8 +.const 1 c255 255 +.temp 4 ay +.temp 4 uvuv + +mergewl uvuv, uv, uv +x2 mergebw ay, c255, y +x2 mergewl d, ay, uvuv + +.function cogorc_putline_NV12 +.dest 2 y guint8 +.dest 2 uv guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 + +x2 splitlw uvuv, ay, ayuv +x2 select1wb y, ay +splitlw uv1, uv2, uvuv +x2 avgub uv, uv1, uv2 + +.function cogorc_getline_NV21 +.dest 8 d guint8 +.source 2 y guint8 +.source 2 vu guint8 +.const 1 c255 255 +.temp 2 uv +.temp 4 ay +.temp 4 uvuv + +swapw uv, vu +mergewl uvuv, uv, uv +x2 mergebw ay, c255, y +x2 mergewl d, ay, uvuv + + +.function cogorc_putline_NV21 +.dest 2 y guint8 +.dest 2 vu guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 +.temp 2 uv + +x2 splitlw uvuv, ay, ayuv +x2 select1wb y, ay +splitlw uv1, uv2, uvuv +x2 avgub uv, uv1, uv2 +swapw vu, uv + + +.function cogorc_getline_A420 +.dest 4 d guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.source 1 a guint8 +.temp 2 uv +.temp 2 ay +.temp 1 tu +.temp 1 tv + +loadupdb tu, u +loadupdb tv, v +mergebw uv, tu, tv +mergebw ay, a, y +mergewl d, ay, uv + +.function cogorc_putline_A420 +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.dest 2 a guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uv +.temp 2 uu +.temp 2 vv +.temp 1 t1 +.temp 1 t2 + +x2 splitlw uv, ay, ayuv +x2 select1wb y, ay +x2 select0wb a, ay +x2 splitwb vv, uu, uv +splitwb t1, t2, uu +avgub u, t1, t2 +splitwb t1, t2, vv +avgub v, t1, t2 + +.function orc_resample_bilinear_u32 +.dest 4 d1 guint8 +.source 4 s1 guint8 +.param 4 p1 +.param 4 p2 + +ldreslinl d1, s1, p1, p2 + +.function orc_merge_linear_u8 +.dest 1 d1 +.source 1 s1 +.source 1 s2 +.param 1 p1 +.temp 2 t1 +.temp 2 t2 +.temp 1 a +.temp 1 t + +loadb a, s1 +convubw t1, s1 +convubw t2, s2 +subw t2, t2, t1 +mullw t2, t2, p1 +addw t2, t2, 128 +convhwb t, t2 +addb d1, t, a From b0ff1d22e91142ec7335aec9e6dceefb34ae2a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 15 Nov 2011 18:00:00 +0000 Subject: [PATCH 12/31] video: add fallbacks for compilation without orc --- gst-libs/gst/video/videoblendorc-dist.c | 6118 +++++++++++++++++++++++ gst-libs/gst/video/videoblendorc-dist.h | 107 + 2 files changed, 6225 insertions(+) create mode 100644 gst-libs/gst/video/videoblendorc-dist.c create mode 100644 gst-libs/gst/video/videoblendorc-dist.h diff --git a/gst-libs/gst/video/videoblendorc-dist.c b/gst-libs/gst/video/videoblendorc-dist.c new file mode 100644 index 0000000000..01b73f11b5 --- /dev/null +++ b/gst-libs/gst/video/videoblendorc-dist.c @@ -0,0 +1,6118 @@ + +/* autogenerated from videoblendorc.orc */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include + +#ifndef _ORC_INTEGER_TYPEDEFS_ +#define _ORC_INTEGER_TYPEDEFS_ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +typedef int8_t orc_int8; +typedef int16_t orc_int16; +typedef int32_t orc_int32; +typedef int64_t orc_int64; +typedef uint8_t orc_uint8; +typedef uint16_t orc_uint16; +typedef uint32_t orc_uint32; +typedef uint64_t orc_uint64; +#define ORC_UINT64_C(x) UINT64_C(x) +#elif defined(_MSC_VER) +typedef signed __int8 orc_int8; +typedef signed __int16 orc_int16; +typedef signed __int32 orc_int32; +typedef signed __int64 orc_int64; +typedef unsigned __int8 orc_uint8; +typedef unsigned __int16 orc_uint16; +typedef unsigned __int32 orc_uint32; +typedef unsigned __int64 orc_uint64; +#define ORC_UINT64_C(x) (x##Ui64) +#define inline __inline +#else +#include +typedef signed char orc_int8; +typedef short orc_int16; +typedef int orc_int32; +typedef unsigned char orc_uint8; +typedef unsigned short orc_uint16; +typedef unsigned int orc_uint32; +#if INT_MAX == LONG_MAX +typedef long long orc_int64; +typedef unsigned long long orc_uint64; +#define ORC_UINT64_C(x) (x##ULL) +#else +typedef long orc_int64; +typedef unsigned long orc_uint64; +#define ORC_UINT64_C(x) (x##UL) +#endif +#endif +typedef union +{ + orc_int16 i; + orc_int8 x2[2]; +} orc_union16; +typedef union +{ + orc_int32 i; + float f; + orc_int16 x2[2]; + orc_int8 x4[4]; +} orc_union32; +typedef union +{ + orc_int64 i; + double f; + orc_int32 x2[2]; + float x2f[2]; + orc_int16 x4[4]; +} orc_union64; +#endif +#ifndef ORC_RESTRICT +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define ORC_RESTRICT restrict +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ORC_RESTRICT __restrict__ +#else +#define ORC_RESTRICT +#endif +#endif + +#ifndef DISABLE_ORC +#include +#endif +void orc_blend_little (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n); +void orc_blend_big (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n); +void cogorc_getline_I420 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, + const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_I420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_YUY2 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_YUY2 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_UYVY (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_UYVY (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_YUV9 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, + const guint8 * ORC_RESTRICT s3, int n); +void cogorc_getline_Y42B (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, + const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_Y42B (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y444 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, + const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_Y444 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y800 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_Y800 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_Y16 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y16 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_BGRA (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_BGRA (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_RGBA (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_RGBA (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_ABGR (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_ABGR (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_NV12 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void cogorc_putline_NV12 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_NV21 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void cogorc_putline_NV21 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_A420 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, + const guint8 * ORC_RESTRICT s3, const guint8 * ORC_RESTRICT s4, int n); +void cogorc_putline_A420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, guint8 * ORC_RESTRICT d4, + const guint8 * ORC_RESTRICT s1, int n); +void orc_resample_bilinear_u32 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int p1, int p2, int n); +void orc_merge_linear_u8 (orc_uint8 * ORC_RESTRICT d1, + const orc_uint8 * ORC_RESTRICT s1, const orc_uint8 * ORC_RESTRICT s2, + int p1, int n); + + +/* begin Orc C target preamble */ +#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_SWAP_Q(x) ((((x)&ORC_UINT64_C(0xff))<<56) | (((x)&ORC_UINT64_C(0xff00))<<40) | (((x)&ORC_UINT64_C(0xff0000))<<24) | (((x)&ORC_UINT64_C(0xff000000))<<8) | (((x)&ORC_UINT64_C(0xff00000000))>>8) | (((x)&ORC_UINT64_C(0xff0000000000))>>24) | (((x)&ORC_UINT64_C(0xff000000000000))>>40) | (((x)&ORC_UINT64_C(0xff00000000000000))>>56)) +#define ORC_PTR_OFFSET(ptr,offset) ((void *)(((unsigned char *)(ptr)) + (offset))) +#define ORC_DENORMAL(x) ((x) & ((((x)&0x7f800000) == 0) ? 0xff800000 : 0xffffffff)) +#define ORC_ISNAN(x) ((((x)&0x7f800000) == 0x7f800000) && (((x)&0x007fffff) != 0)) +#define ORC_DENORMAL_DOUBLE(x) ((x) & ((((x)&ORC_UINT64_C(0x7ff0000000000000)) == 0) ? ORC_UINT64_C(0xfff0000000000000) : ORC_UINT64_C(0xffffffffffffffff))) +#define ORC_ISNAN_DOUBLE(x) ((((x)&ORC_UINT64_C(0x7ff0000000000000)) == ORC_UINT64_C(0x7ff0000000000000)) && (((x)&ORC_UINT64_C(0x000fffffffffffff)) != 0)) +#ifndef ORC_RESTRICT +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define ORC_RESTRICT restrict +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ORC_RESTRICT __restrict__ +#else +#define ORC_RESTRICT +#endif +#endif +/* end Orc C target preamble */ + + + +/* orc_blend_little */ +#ifdef DISABLE_ORC +void +orc_blend_little (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_int8 var42; + orc_union32 var43; + orc_union64 var44; + orc_union64 var45; + orc_union64 var46; + orc_union32 var47; + orc_union64 var48; + orc_union64 var49; + orc_union64 var50; + orc_union64 var51; + orc_union64 var52; + orc_union32 var53; + orc_union32 var54; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + /* 14: loadpl */ + var39.i = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: convlw */ + var41.i = var40.i; + /* 2: convwb */ + var42 = var41.i; + /* 3: splatbl */ + var43.i = + ((var42 & 0xff) << 24) | ((var42 & 0xff) << 16) | ((var42 & 0xff) << 8) + | (var42 & 0xff); + /* 4: convubw */ + var44.x4[0] = (orc_uint8) var43.x4[0]; + var44.x4[1] = (orc_uint8) var43.x4[1]; + var44.x4[2] = (orc_uint8) var43.x4[2]; + var44.x4[3] = (orc_uint8) var43.x4[3]; + /* 5: shruw */ + var45.x4[0] = ((orc_uint16) var44.x4[0]) >> 8; + var45.x4[1] = ((orc_uint16) var44.x4[1]) >> 8; + var45.x4[2] = ((orc_uint16) var44.x4[2]) >> 8; + var45.x4[3] = ((orc_uint16) var44.x4[3]) >> 8; + /* 6: convubw */ + var46.x4[0] = (orc_uint8) var40.x4[0]; + var46.x4[1] = (orc_uint8) var40.x4[1]; + var46.x4[2] = (orc_uint8) var40.x4[2]; + var46.x4[3] = (orc_uint8) var40.x4[3]; + /* 7: loadl */ + var47 = ptr0[i]; + /* 8: convubw */ + var48.x4[0] = (orc_uint8) var47.x4[0]; + var48.x4[1] = (orc_uint8) var47.x4[1]; + var48.x4[2] = (orc_uint8) var47.x4[2]; + var48.x4[3] = (orc_uint8) var47.x4[3]; + /* 9: subw */ + var49.x4[0] = var46.x4[0] - var48.x4[0]; + var49.x4[1] = var46.x4[1] - var48.x4[1]; + var49.x4[2] = var46.x4[2] - var48.x4[2]; + var49.x4[3] = var46.x4[3] - var48.x4[3]; + /* 10: mullw */ + var50.x4[0] = (var49.x4[0] * var45.x4[0]) & 0xffff; + var50.x4[1] = (var49.x4[1] * var45.x4[1]) & 0xffff; + var50.x4[2] = (var49.x4[2] * var45.x4[2]) & 0xffff; + var50.x4[3] = (var49.x4[3] * var45.x4[3]) & 0xffff; + /* 11: div255w */ + var51.x4[0] = + ((orc_uint16) (((orc_uint16) (var50.x4[0] + 128)) + + (((orc_uint16) (var50.x4[0] + 128)) >> 8))) >> 8; + var51.x4[1] = + ((orc_uint16) (((orc_uint16) (var50.x4[1] + 128)) + + (((orc_uint16) (var50.x4[1] + 128)) >> 8))) >> 8; + var51.x4[2] = + ((orc_uint16) (((orc_uint16) (var50.x4[2] + 128)) + + (((orc_uint16) (var50.x4[2] + 128)) >> 8))) >> 8; + var51.x4[3] = + ((orc_uint16) (((orc_uint16) (var50.x4[3] + 128)) + + (((orc_uint16) (var50.x4[3] + 128)) >> 8))) >> 8; + /* 12: addw */ + var52.x4[0] = var48.x4[0] + var51.x4[0]; + var52.x4[1] = var48.x4[1] + var51.x4[1]; + var52.x4[2] = var48.x4[2] + var51.x4[2]; + var52.x4[3] = var48.x4[3] + var51.x4[3]; + /* 13: convwb */ + var53.x4[0] = var52.x4[0]; + var53.x4[1] = var52.x4[1]; + var53.x4[2] = var52.x4[2]; + var53.x4[3] = var52.x4[3]; + /* 15: orl */ + var54.i = var53.i | var39.i; + /* 16: storel */ + ptr0[i] = var54; + } + +} + +#else +static void +_backup_orc_blend_little (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_int8 var42; + orc_union32 var43; + orc_union64 var44; + orc_union64 var45; + orc_union64 var46; + orc_union32 var47; + orc_union64 var48; + orc_union64 var49; + orc_union64 var50; + orc_union64 var51; + orc_union64 var52; + orc_union32 var53; + orc_union32 var54; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + /* 14: loadpl */ + var39.i = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: convlw */ + var41.i = var40.i; + /* 2: convwb */ + var42 = var41.i; + /* 3: splatbl */ + var43.i = + ((var42 & 0xff) << 24) | ((var42 & 0xff) << 16) | ((var42 & 0xff) << 8) + | (var42 & 0xff); + /* 4: convubw */ + var44.x4[0] = (orc_uint8) var43.x4[0]; + var44.x4[1] = (orc_uint8) var43.x4[1]; + var44.x4[2] = (orc_uint8) var43.x4[2]; + var44.x4[3] = (orc_uint8) var43.x4[3]; + /* 5: shruw */ + var45.x4[0] = ((orc_uint16) var44.x4[0]) >> 8; + var45.x4[1] = ((orc_uint16) var44.x4[1]) >> 8; + var45.x4[2] = ((orc_uint16) var44.x4[2]) >> 8; + var45.x4[3] = ((orc_uint16) var44.x4[3]) >> 8; + /* 6: convubw */ + var46.x4[0] = (orc_uint8) var40.x4[0]; + var46.x4[1] = (orc_uint8) var40.x4[1]; + var46.x4[2] = (orc_uint8) var40.x4[2]; + var46.x4[3] = (orc_uint8) var40.x4[3]; + /* 7: loadl */ + var47 = ptr0[i]; + /* 8: convubw */ + var48.x4[0] = (orc_uint8) var47.x4[0]; + var48.x4[1] = (orc_uint8) var47.x4[1]; + var48.x4[2] = (orc_uint8) var47.x4[2]; + var48.x4[3] = (orc_uint8) var47.x4[3]; + /* 9: subw */ + var49.x4[0] = var46.x4[0] - var48.x4[0]; + var49.x4[1] = var46.x4[1] - var48.x4[1]; + var49.x4[2] = var46.x4[2] - var48.x4[2]; + var49.x4[3] = var46.x4[3] - var48.x4[3]; + /* 10: mullw */ + var50.x4[0] = (var49.x4[0] * var45.x4[0]) & 0xffff; + var50.x4[1] = (var49.x4[1] * var45.x4[1]) & 0xffff; + var50.x4[2] = (var49.x4[2] * var45.x4[2]) & 0xffff; + var50.x4[3] = (var49.x4[3] * var45.x4[3]) & 0xffff; + /* 11: div255w */ + var51.x4[0] = + ((orc_uint16) (((orc_uint16) (var50.x4[0] + 128)) + + (((orc_uint16) (var50.x4[0] + 128)) >> 8))) >> 8; + var51.x4[1] = + ((orc_uint16) (((orc_uint16) (var50.x4[1] + 128)) + + (((orc_uint16) (var50.x4[1] + 128)) >> 8))) >> 8; + var51.x4[2] = + ((orc_uint16) (((orc_uint16) (var50.x4[2] + 128)) + + (((orc_uint16) (var50.x4[2] + 128)) >> 8))) >> 8; + var51.x4[3] = + ((orc_uint16) (((orc_uint16) (var50.x4[3] + 128)) + + (((orc_uint16) (var50.x4[3] + 128)) >> 8))) >> 8; + /* 12: addw */ + var52.x4[0] = var48.x4[0] + var51.x4[0]; + var52.x4[1] = var48.x4[1] + var51.x4[1]; + var52.x4[2] = var48.x4[2] + var51.x4[2]; + var52.x4[3] = var48.x4[3] + var51.x4[3]; + /* 13: convwb */ + var53.x4[0] = var52.x4[0]; + var53.x4[1] = var52.x4[1]; + var53.x4[2] = var52.x4[2]; + var53.x4[3] = var52.x4[3]; + /* 15: orl */ + var54.i = var53.i | var39.i; + /* 16: storel */ + ptr0[i] = var54; + } + +} + +void +orc_blend_little (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "orc_blend_little"); + orc_program_set_backup_function (p, _backup_orc_blend_little); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_constant (p, 4, 0x000000ff, "c1"); + orc_program_add_constant (p, 4, 0x00000008, "c2"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 1, "t3"); + orc_program_add_temporary (p, 4, "t4"); + orc_program_add_temporary (p, 8, "t5"); + orc_program_add_temporary (p, 8, "t6"); + orc_program_add_temporary (p, 8, "t7"); + + orc_program_append_2 (p, "loadl", 0, ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convlw", 0, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convwb", 0, ORC_VAR_T3, ORC_VAR_T2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "splatbl", 0, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T7, ORC_VAR_T4, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "shruw", 2, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_C2, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T6, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "loadl", 0, ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T5, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "subw", 2, ORC_VAR_T6, ORC_VAR_T6, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "mullw", 2, ORC_VAR_T6, ORC_VAR_T6, ORC_VAR_T7, + ORC_VAR_D1); + orc_program_append_2 (p, "div255w", 2, ORC_VAR_T6, ORC_VAR_T6, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "addw", 2, ORC_VAR_T5, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "convwb", 2, ORC_VAR_T1, ORC_VAR_T5, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "orl", 0, ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1, + ORC_VAR_D1); + orc_program_append_2 (p, "storel", 0, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* orc_blend_big */ +#ifdef DISABLE_ORC +void +orc_blend_big (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union32 var42; + orc_union16 var43; + orc_int8 var44; + orc_union32 var45; + orc_union64 var46; + orc_union64 var47; + orc_union64 var48; + orc_union32 var49; + orc_union64 var50; + orc_union64 var51; + orc_union64 var52; + orc_union64 var53; + orc_union64 var54; + orc_union32 var55; + orc_union32 var56; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + /* 15: loadpl */ + var40.i = (int) 0xff000000; /* -16777216 or 2.11371e-314f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var41 = ptr4[i]; + /* 1: shrul */ + var42.i = ((orc_uint32) var41.i) >> 24; + /* 2: convlw */ + var43.i = var42.i; + /* 3: convwb */ + var44 = var43.i; + /* 4: splatbl */ + var45.i = + ((var44 & 0xff) << 24) | ((var44 & 0xff) << 16) | ((var44 & 0xff) << 8) + | (var44 & 0xff); + /* 5: convubw */ + var46.x4[0] = (orc_uint8) var45.x4[0]; + var46.x4[1] = (orc_uint8) var45.x4[1]; + var46.x4[2] = (orc_uint8) var45.x4[2]; + var46.x4[3] = (orc_uint8) var45.x4[3]; + /* 6: shruw */ + var47.x4[0] = ((orc_uint16) var46.x4[0]) >> 8; + var47.x4[1] = ((orc_uint16) var46.x4[1]) >> 8; + var47.x4[2] = ((orc_uint16) var46.x4[2]) >> 8; + var47.x4[3] = ((orc_uint16) var46.x4[3]) >> 8; + /* 7: convubw */ + var48.x4[0] = (orc_uint8) var41.x4[0]; + var48.x4[1] = (orc_uint8) var41.x4[1]; + var48.x4[2] = (orc_uint8) var41.x4[2]; + var48.x4[3] = (orc_uint8) var41.x4[3]; + /* 8: loadl */ + var49 = ptr0[i]; + /* 9: convubw */ + var50.x4[0] = (orc_uint8) var49.x4[0]; + var50.x4[1] = (orc_uint8) var49.x4[1]; + var50.x4[2] = (orc_uint8) var49.x4[2]; + var50.x4[3] = (orc_uint8) var49.x4[3]; + /* 10: subw */ + var51.x4[0] = var48.x4[0] - var50.x4[0]; + var51.x4[1] = var48.x4[1] - var50.x4[1]; + var51.x4[2] = var48.x4[2] - var50.x4[2]; + var51.x4[3] = var48.x4[3] - var50.x4[3]; + /* 11: mullw */ + var52.x4[0] = (var51.x4[0] * var47.x4[0]) & 0xffff; + var52.x4[1] = (var51.x4[1] * var47.x4[1]) & 0xffff; + var52.x4[2] = (var51.x4[2] * var47.x4[2]) & 0xffff; + var52.x4[3] = (var51.x4[3] * var47.x4[3]) & 0xffff; + /* 12: div255w */ + var53.x4[0] = + ((orc_uint16) (((orc_uint16) (var52.x4[0] + 128)) + + (((orc_uint16) (var52.x4[0] + 128)) >> 8))) >> 8; + var53.x4[1] = + ((orc_uint16) (((orc_uint16) (var52.x4[1] + 128)) + + (((orc_uint16) (var52.x4[1] + 128)) >> 8))) >> 8; + var53.x4[2] = + ((orc_uint16) (((orc_uint16) (var52.x4[2] + 128)) + + (((orc_uint16) (var52.x4[2] + 128)) >> 8))) >> 8; + var53.x4[3] = + ((orc_uint16) (((orc_uint16) (var52.x4[3] + 128)) + + (((orc_uint16) (var52.x4[3] + 128)) >> 8))) >> 8; + /* 13: addw */ + var54.x4[0] = var50.x4[0] + var53.x4[0]; + var54.x4[1] = var50.x4[1] + var53.x4[1]; + var54.x4[2] = var50.x4[2] + var53.x4[2]; + var54.x4[3] = var50.x4[3] + var53.x4[3]; + /* 14: convwb */ + var55.x4[0] = var54.x4[0]; + var55.x4[1] = var54.x4[1]; + var55.x4[2] = var54.x4[2]; + var55.x4[3] = var54.x4[3]; + /* 16: orl */ + var56.i = var55.i | var40.i; + /* 17: storel */ + ptr0[i] = var56; + } + +} + +#else +static void +_backup_orc_blend_big (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union32 var42; + orc_union16 var43; + orc_int8 var44; + orc_union32 var45; + orc_union64 var46; + orc_union64 var47; + orc_union64 var48; + orc_union32 var49; + orc_union64 var50; + orc_union64 var51; + orc_union64 var52; + orc_union64 var53; + orc_union64 var54; + orc_union32 var55; + orc_union32 var56; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + /* 15: loadpl */ + var40.i = (int) 0xff000000; /* -16777216 or 2.11371e-314f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var41 = ptr4[i]; + /* 1: shrul */ + var42.i = ((orc_uint32) var41.i) >> 24; + /* 2: convlw */ + var43.i = var42.i; + /* 3: convwb */ + var44 = var43.i; + /* 4: splatbl */ + var45.i = + ((var44 & 0xff) << 24) | ((var44 & 0xff) << 16) | ((var44 & 0xff) << 8) + | (var44 & 0xff); + /* 5: convubw */ + var46.x4[0] = (orc_uint8) var45.x4[0]; + var46.x4[1] = (orc_uint8) var45.x4[1]; + var46.x4[2] = (orc_uint8) var45.x4[2]; + var46.x4[3] = (orc_uint8) var45.x4[3]; + /* 6: shruw */ + var47.x4[0] = ((orc_uint16) var46.x4[0]) >> 8; + var47.x4[1] = ((orc_uint16) var46.x4[1]) >> 8; + var47.x4[2] = ((orc_uint16) var46.x4[2]) >> 8; + var47.x4[3] = ((orc_uint16) var46.x4[3]) >> 8; + /* 7: convubw */ + var48.x4[0] = (orc_uint8) var41.x4[0]; + var48.x4[1] = (orc_uint8) var41.x4[1]; + var48.x4[2] = (orc_uint8) var41.x4[2]; + var48.x4[3] = (orc_uint8) var41.x4[3]; + /* 8: loadl */ + var49 = ptr0[i]; + /* 9: convubw */ + var50.x4[0] = (orc_uint8) var49.x4[0]; + var50.x4[1] = (orc_uint8) var49.x4[1]; + var50.x4[2] = (orc_uint8) var49.x4[2]; + var50.x4[3] = (orc_uint8) var49.x4[3]; + /* 10: subw */ + var51.x4[0] = var48.x4[0] - var50.x4[0]; + var51.x4[1] = var48.x4[1] - var50.x4[1]; + var51.x4[2] = var48.x4[2] - var50.x4[2]; + var51.x4[3] = var48.x4[3] - var50.x4[3]; + /* 11: mullw */ + var52.x4[0] = (var51.x4[0] * var47.x4[0]) & 0xffff; + var52.x4[1] = (var51.x4[1] * var47.x4[1]) & 0xffff; + var52.x4[2] = (var51.x4[2] * var47.x4[2]) & 0xffff; + var52.x4[3] = (var51.x4[3] * var47.x4[3]) & 0xffff; + /* 12: div255w */ + var53.x4[0] = + ((orc_uint16) (((orc_uint16) (var52.x4[0] + 128)) + + (((orc_uint16) (var52.x4[0] + 128)) >> 8))) >> 8; + var53.x4[1] = + ((orc_uint16) (((orc_uint16) (var52.x4[1] + 128)) + + (((orc_uint16) (var52.x4[1] + 128)) >> 8))) >> 8; + var53.x4[2] = + ((orc_uint16) (((orc_uint16) (var52.x4[2] + 128)) + + (((orc_uint16) (var52.x4[2] + 128)) >> 8))) >> 8; + var53.x4[3] = + ((orc_uint16) (((orc_uint16) (var52.x4[3] + 128)) + + (((orc_uint16) (var52.x4[3] + 128)) >> 8))) >> 8; + /* 13: addw */ + var54.x4[0] = var50.x4[0] + var53.x4[0]; + var54.x4[1] = var50.x4[1] + var53.x4[1]; + var54.x4[2] = var50.x4[2] + var53.x4[2]; + var54.x4[3] = var50.x4[3] + var53.x4[3]; + /* 14: convwb */ + var55.x4[0] = var54.x4[0]; + var55.x4[1] = var54.x4[1]; + var55.x4[2] = var54.x4[2]; + var55.x4[3] = var54.x4[3]; + /* 16: orl */ + var56.i = var55.i | var40.i; + /* 17: storel */ + ptr0[i] = var56; + } + +} + +void +orc_blend_big (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "orc_blend_big"); + orc_program_set_backup_function (p, _backup_orc_blend_big); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_constant (p, 4, 0xff000000, "c1"); + orc_program_add_constant (p, 4, 0x00000018, "c2"); + orc_program_add_constant (p, 4, 0x00000008, "c3"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 2, "t3"); + orc_program_add_temporary (p, 1, "t4"); + orc_program_add_temporary (p, 4, "t5"); + orc_program_add_temporary (p, 8, "t6"); + orc_program_add_temporary (p, 8, "t7"); + orc_program_add_temporary (p, 8, "t8"); + + orc_program_append_2 (p, "loadl", 0, ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "shrul", 0, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_C2, + ORC_VAR_D1); + orc_program_append_2 (p, "convlw", 0, ORC_VAR_T3, ORC_VAR_T2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convwb", 0, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "splatbl", 0, ORC_VAR_T5, ORC_VAR_T4, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T8, ORC_VAR_T5, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "shruw", 2, ORC_VAR_T8, ORC_VAR_T8, ORC_VAR_C3, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T7, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "loadl", 0, ORC_VAR_T1, ORC_VAR_D1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 2, ORC_VAR_T6, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "subw", 2, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "mullw", 2, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_T8, + ORC_VAR_D1); + orc_program_append_2 (p, "div255w", 2, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "addw", 2, ORC_VAR_T6, ORC_VAR_T6, ORC_VAR_T7, + ORC_VAR_D1); + orc_program_append_2 (p, "convwb", 2, ORC_VAR_T1, ORC_VAR_T6, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "orl", 0, ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_C1, + ORC_VAR_D1); + orc_program_append_2 (p, "storel", 0, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_I420 */ +#ifdef DISABLE_ORC +void +cogorc_getline_I420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_int8 var39; + orc_int8 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_int8 *) s1; + ptr5 = (orc_int8 *) s2; + ptr6 = (orc_int8 *) s3; + + /* 3: loadpb */ + var36 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var39 = ptr5[i >> 1]; + /* 1: loadupdb */ + var40 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var39; + _dest.x2[1] = var40; + var41.i = _dest.i; + } + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var42.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var41.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_I420 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_int8 var39; + orc_int8 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_int8 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + ptr6 = (orc_int8 *) ex->arrays[6]; + + /* 3: loadpb */ + var36 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var39 = ptr5[i >> 1]; + /* 1: loadupdb */ + var40 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var39; + _dest.x2[1] = var40; + var41.i = _dest.i; + } + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var42.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var41.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_I420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_I420"); + orc_program_set_backup_function (p, _backup_cogorc_getline_I420); + 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_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 1, "t3"); + orc_program_add_temporary (p, 1, "t4"); + + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T3, ORC_VAR_S2, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T4, ORC_VAR_S3, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T2, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_I420 */ +#ifdef DISABLE_ORC +void +cogorc_putline_I420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var38; + orc_union16 var39; + orc_int8 var40; + orc_int8 var41; + orc_union32 var42; + orc_union32 var43; + orc_union16 var44; + orc_union16 var45; + orc_int8 var46; + orc_int8 var47; + orc_int8 var48; + orc_int8 var49; + + ptr0 = (orc_union16 *) d1; + ptr1 = (orc_int8 *) d2; + ptr2 = (orc_int8 *) d3; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var38 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var38.x2[0]; + var42.x2[0] = _src.x2[1]; + var43.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var38.x2[1]; + var42.x2[1] = _src.x2[1]; + var43.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var43.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var43.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var39; + /* 4: splitwb */ + { + orc_union16 _src; + _src.i = var42.x2[0]; + var44.x2[0] = _src.x2[1]; + var45.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var42.x2[1]; + var44.x2[1] = _src.x2[1]; + var45.x2[1] = _src.x2[0]; + } + /* 5: splitwb */ + { + orc_union16 _src; + _src.i = var45.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 6: avgub */ + var40 = ((orc_uint8) var46 + (orc_uint8) var47 + 1) >> 1; + /* 7: storeb */ + ptr1[i] = var40; + /* 8: splitwb */ + { + orc_union16 _src; + _src.i = var44.i; + var48 = _src.x2[1]; + var49 = _src.x2[0]; + } + /* 9: avgub */ + var41 = ((orc_uint8) var48 + (orc_uint8) var49 + 1) >> 1; + /* 10: storeb */ + ptr2[i] = var41; + } + +} + +#else +static void +_backup_cogorc_putline_I420 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var38; + orc_union16 var39; + orc_int8 var40; + orc_int8 var41; + orc_union32 var42; + orc_union32 var43; + orc_union16 var44; + orc_union16 var45; + orc_int8 var46; + orc_int8 var47; + orc_int8 var48; + orc_int8 var49; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr1 = (orc_int8 *) ex->arrays[1]; + ptr2 = (orc_int8 *) ex->arrays[2]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var38 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var38.x2[0]; + var42.x2[0] = _src.x2[1]; + var43.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var38.x2[1]; + var42.x2[1] = _src.x2[1]; + var43.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var43.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var43.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var39; + /* 4: splitwb */ + { + orc_union16 _src; + _src.i = var42.x2[0]; + var44.x2[0] = _src.x2[1]; + var45.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var42.x2[1]; + var44.x2[1] = _src.x2[1]; + var45.x2[1] = _src.x2[0]; + } + /* 5: splitwb */ + { + orc_union16 _src; + _src.i = var45.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 6: avgub */ + var40 = ((orc_uint8) var46 + (orc_uint8) var47 + 1) >> 1; + /* 7: storeb */ + ptr1[i] = var40; + /* 8: splitwb */ + { + orc_union16 _src; + _src.i = var44.i; + var48 = _src.x2[1]; + var49 = _src.x2[0]; + } + /* 9: avgub */ + var41 = ((orc_uint8) var48 + (orc_uint8) var49 + 1) >> 1; + /* 10: storeb */ + ptr2[i] = var41; + } + +} + +void +cogorc_putline_I420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_I420"); + orc_program_set_backup_function (p, _backup_cogorc_putline_I420); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_destination (p, 1, "d2"); + orc_program_add_destination (p, 1, "d3"); + orc_program_add_source (p, 8, "s1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 2, "t3"); + orc_program_add_temporary (p, 2, "t4"); + orc_program_add_temporary (p, 1, "t5"); + orc_program_add_temporary (p, 1, "t6"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 1, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T5, ORC_VAR_T6, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 0, ORC_VAR_D2, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T5, ORC_VAR_T6, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 0, ORC_VAR_D3, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_D3] = d3; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_YUY2 */ +#ifdef DISABLE_ORC +void +cogorc_getline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_union32 var41; + orc_union32 var42; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union32 *) s1; + + /* 2: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var36 = ptr4[i]; + /* 1: splitwb */ + { + orc_union16 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var40.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var40.x2[1]; + var41.x2[1] = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var39.i; + var42.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var42.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var42.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storeq */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_YUY2 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_union32 var41; + orc_union32 var42; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + /* 2: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var36 = ptr4[i]; + /* 1: splitwb */ + { + orc_union16 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var40.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var40.x2[1]; + var41.x2[1] = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var39.i; + var42.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var42.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var42.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storeq */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_YUY2"); + orc_program_set_backup_function (p, _backup_cogorc_getline_YUY2); + orc_program_add_destination (p, 8, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_constant (p, 2, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 4, "t3"); + orc_program_add_temporary (p, 4, "t4"); + + orc_program_append_2 (p, "splitwb", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T3, ORC_VAR_C1, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T4, ORC_VAR_T2, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_YUY2 */ +#ifdef DISABLE_ORC +void +cogorc_putline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union32 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 3: avgub */ + var43.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var43.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 4: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var44.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var44.x2[1] = _src.x2[1]; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44.x2[0]; + _dest.x2[1] = var43.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var44.x2[1]; + _dest.x2[1] = var43.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storel */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_putline_YUY2 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union32 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 3: avgub */ + var43.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var43.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 4: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var44.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var44.x2[1] = _src.x2[1]; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44.x2[0]; + _dest.x2[1] = var43.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var44.x2[1]; + _dest.x2[1] = var43.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storel */ + ptr0[i] = var38; + } + +} + +void +cogorc_putline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_YUY2"); + orc_program_set_backup_function (p, _backup_cogorc_putline_YUY2); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 8, "s1"); + 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, 4, "t4"); + orc_program_add_temporary (p, 4, "t5"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T5, ORC_VAR_T4, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T2, ORC_VAR_T3, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 1, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_T1, ORC_VAR_T4, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_T2, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_UYVY */ +#ifdef DISABLE_ORC +void +cogorc_putline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union32 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 3: avgub */ + var43.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var43.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 4: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var44.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var44.x2[1] = _src.x2[1]; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var43.x2[0]; + _dest.x2[1] = var44.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var43.x2[1]; + _dest.x2[1] = var44.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storel */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_putline_UYVY (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union32 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 3: avgub */ + var43.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var43.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 4: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var44.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var44.x2[1] = _src.x2[1]; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var43.x2[0]; + _dest.x2[1] = var44.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var43.x2[1]; + _dest.x2[1] = var44.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storel */ + ptr0[i] = var38; + } + +} + +void +cogorc_putline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_UYVY"); + orc_program_set_backup_function (p, _backup_cogorc_putline_UYVY); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 8, "s1"); + 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, 4, "t4"); + orc_program_add_temporary (p, 4, "t5"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T5, ORC_VAR_T4, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T2, ORC_VAR_T3, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 1, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_T1, ORC_VAR_T4, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_UYVY */ +#ifdef DISABLE_ORC +void +cogorc_getline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_union32 var41; + orc_union32 var42; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union32 *) s1; + + /* 2: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var36 = ptr4[i]; + /* 1: splitwb */ + { + orc_union16 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var39.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var39.x2[1]; + var41.x2[1] = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.i; + _dest.x2[1] = var40.i; + var42.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var42.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var42.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storeq */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_UYVY (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_union32 var41; + orc_union32 var42; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + /* 2: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var36 = ptr4[i]; + /* 1: splitwb */ + { + orc_union16 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var39.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var39.x2[1]; + var41.x2[1] = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.i; + _dest.x2[1] = var40.i; + var42.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var42.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var42.x2[1]; + var38.x2[1] = _dest.i; + } + /* 6: storeq */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_UYVY"); + orc_program_set_backup_function (p, _backup_cogorc_getline_UYVY); + orc_program_add_destination (p, 8, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_constant (p, 2, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 4, "t3"); + orc_program_add_temporary (p, 4, "t4"); + + orc_program_append_2 (p, "splitwb", 1, ORC_VAR_T1, ORC_VAR_T2, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T3, ORC_VAR_C1, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T4, ORC_VAR_T2, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_YUV9 */ +#ifdef DISABLE_ORC +void +cogorc_getline_YUV9 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_union16 var37; + orc_union16 var38; + orc_union64 var39; + orc_int8 var40; + orc_int8 var41; + orc_union16 var42; + orc_union32 var43; + orc_union32 var44; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_int8 *) s2; + ptr6 = (orc_int8 *) s3; + + /* 4: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var40 = ptr5[i >> 1]; + /* 1: loadupdb */ + var41 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var40; + _dest.x2[1] = var41; + var42.i = _dest.i; + } + /* 3: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var42.i; + var43.i = _dest.i; + } + /* 5: loadw */ + var38 = ptr4[i]; + /* 6: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var38.x2[0]; + var44.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var38.x2[1]; + var44.x2[1] = _dest.i; + } + /* 7: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var44.x2[0]; + _dest.x2[1] = var43.x2[0]; + var39.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var44.x2[1]; + _dest.x2[1] = var43.x2[1]; + var39.x2[1] = _dest.i; + } + /* 8: storeq */ + ptr0[i] = var39; + } + +} + +#else +static void +_backup_cogorc_getline_YUV9 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_union16 var37; + orc_union16 var38; + orc_union64 var39; + orc_int8 var40; + orc_int8 var41; + orc_union16 var42; + orc_union32 var43; + orc_union32 var44; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + ptr6 = (orc_int8 *) ex->arrays[6]; + + /* 4: loadpb */ + var37.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var37.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var40 = ptr5[i >> 1]; + /* 1: loadupdb */ + var41 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var40; + _dest.x2[1] = var41; + var42.i = _dest.i; + } + /* 3: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var42.i; + var43.i = _dest.i; + } + /* 5: loadw */ + var38 = ptr4[i]; + /* 6: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[0]; + _dest.x2[1] = var38.x2[0]; + var44.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var37.x2[1]; + _dest.x2[1] = var38.x2[1]; + var44.x2[1] = _dest.i; + } + /* 7: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var44.x2[0]; + _dest.x2[1] = var43.x2[0]; + var39.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var44.x2[1]; + _dest.x2[1] = var43.x2[1]; + var39.x2[1] = _dest.i; + } + /* 8: storeq */ + ptr0[i] = var39; + } + +} + +void +cogorc_getline_YUV9 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_YUV9"); + orc_program_set_backup_function (p, _backup_cogorc_getline_YUV9); + orc_program_add_destination (p, 8, "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_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 4, "t3"); + orc_program_add_temporary (p, 1, "t4"); + orc_program_add_temporary (p, 1, "t5"); + + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T4, ORC_VAR_S2, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T5, ORC_VAR_S3, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_T4, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T3, ORC_VAR_T1, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T2, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_Y42B */ +#ifdef DISABLE_ORC +void +cogorc_getline_Y42B (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + orc_union64 var40; + orc_union16 var41; + orc_union32 var42; + orc_union32 var43; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_int8 *) s2; + ptr6 = (orc_int8 *) s3; + + /* 3: loadpb */ + var38.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var38.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var36 = ptr5[i]; + /* 1: loadb */ + var37 = ptr6[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var41.i = _dest.i; + } + /* 4: loadw */ + var39 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var38.x2[0]; + _dest.x2[1] = var39.x2[0]; + var42.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var38.x2[1]; + _dest.x2[1] = var39.x2[1]; + var42.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.i; + _dest.x2[1] = var41.i; + var43.i = _dest.i; + } + /* 7: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.x2[0]; + _dest.x2[1] = var43.x2[0]; + var40.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var42.x2[1]; + _dest.x2[1] = var43.x2[1]; + var40.x2[1] = _dest.i; + } + /* 8: storeq */ + ptr0[i] = var40; + } + +} + +#else +static void +_backup_cogorc_getline_Y42B (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + orc_union64 var40; + orc_union16 var41; + orc_union32 var42; + orc_union32 var43; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + ptr6 = (orc_int8 *) ex->arrays[6]; + + /* 3: loadpb */ + var38.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var38.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var36 = ptr5[i]; + /* 1: loadb */ + var37 = ptr6[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var41.i = _dest.i; + } + /* 4: loadw */ + var39 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var38.x2[0]; + _dest.x2[1] = var39.x2[0]; + var42.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var38.x2[1]; + _dest.x2[1] = var39.x2[1]; + var42.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.i; + _dest.x2[1] = var41.i; + var43.i = _dest.i; + } + /* 7: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.x2[0]; + _dest.x2[1] = var43.x2[0]; + var40.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var42.x2[1]; + _dest.x2[1] = var43.x2[1]; + var40.x2[1] = _dest.i; + } + /* 8: storeq */ + ptr0[i] = var40; + } + +} + +void +cogorc_getline_Y42B (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_Y42B"); + orc_program_set_backup_function (p, _backup_cogorc_getline_Y42B); + orc_program_add_destination (p, 8, "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_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 4, "t3"); + orc_program_add_temporary (p, 4, "t4"); + + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_S2, ORC_VAR_S3, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T4, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T3, ORC_VAR_T1, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T4, ORC_VAR_T3, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_Y42B */ +#ifdef DISABLE_ORC +void +cogorc_putline_Y42B (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var36; + orc_int8 var37; + orc_int8 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union16 *) d1; + ptr1 = (orc_int8 *) d2; + ptr2 = (orc_int8 *) d3; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var36 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var36.x2[0]; + var40.x2[0] = _src.x2[1]; + var41.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var36.x2[1]; + var40.x2[1] = _src.x2[1]; + var41.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 3: avgub */ + var44.x2[0] = ((orc_uint8) var42.x2[0] + (orc_uint8) var43.x2[0] + 1) >> 1; + var44.x2[1] = ((orc_uint8) var42.x2[1] + (orc_uint8) var43.x2[1] + 1) >> 1; + /* 4: splitwb */ + { + orc_union16 _src; + _src.i = var44.i; + var37 = _src.x2[1]; + var38 = _src.x2[0]; + } + /* 5: storeb */ + ptr2[i] = var37; + /* 6: storeb */ + ptr1[i] = var38; + /* 7: select1wb */ + { + orc_union16 _src; + _src.i = var41.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var41.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 8: storew */ + ptr0[i] = var39; + } + +} + +#else +static void +_backup_cogorc_putline_Y42B (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var36; + orc_int8 var37; + orc_int8 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr1 = (orc_int8 *) ex->arrays[1]; + ptr2 = (orc_int8 *) ex->arrays[2]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var36 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var36.x2[0]; + var40.x2[0] = _src.x2[1]; + var41.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var36.x2[1]; + var40.x2[1] = _src.x2[1]; + var41.x2[1] = _src.x2[0]; + } + /* 2: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 3: avgub */ + var44.x2[0] = ((orc_uint8) var42.x2[0] + (orc_uint8) var43.x2[0] + 1) >> 1; + var44.x2[1] = ((orc_uint8) var42.x2[1] + (orc_uint8) var43.x2[1] + 1) >> 1; + /* 4: splitwb */ + { + orc_union16 _src; + _src.i = var44.i; + var37 = _src.x2[1]; + var38 = _src.x2[0]; + } + /* 5: storeb */ + ptr2[i] = var37; + /* 6: storeb */ + ptr1[i] = var38; + /* 7: select1wb */ + { + orc_union16 _src; + _src.i = var41.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var41.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 8: storew */ + ptr0[i] = var39; + } + +} + +void +cogorc_putline_Y42B (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_Y42B"); + orc_program_set_backup_function (p, _backup_cogorc_putline_Y42B); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_destination (p, 1, "d2"); + orc_program_add_destination (p, 1, "d3"); + orc_program_add_source (p, 8, "s1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 2, "t3"); + orc_program_add_temporary (p, 2, "t4"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T3, ORC_VAR_T4, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 1, ORC_VAR_T3, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_D3, ORC_VAR_D2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_D3] = d3; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_Y444 */ +#ifdef DISABLE_ORC +void +cogorc_getline_Y444 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var34; + orc_int8 var35; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_union16 var39; + orc_union16 var40; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_int8 *) s1; + ptr5 = (orc_int8 *) s2; + ptr6 = (orc_int8 *) s3; + + /* 3: loadpb */ + var36 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var34 = ptr5[i]; + /* 1: loadb */ + var35 = ptr6[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var34; + _dest.x2[1] = var35; + var39.i = _dest.i; + } + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var40.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.i; + _dest.x2[1] = var39.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_Y444 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + orc_int8 var34; + orc_int8 var35; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_union16 var39; + orc_union16 var40; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_int8 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + ptr6 = (orc_int8 *) ex->arrays[6]; + + /* 3: loadpb */ + var36 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var34 = ptr5[i]; + /* 1: loadb */ + var35 = ptr6[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var34; + _dest.x2[1] = var35; + var39.i = _dest.i; + } + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var40.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.i; + _dest.x2[1] = var39.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_Y444 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_Y444"); + orc_program_set_backup_function (p, _backup_cogorc_getline_Y444); + 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_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_S2, ORC_VAR_S3, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T2, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_Y444 */ +#ifdef DISABLE_ORC +void +cogorc_putline_Y444 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_int8 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var34; + orc_int8 var35; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + + ptr0 = (orc_int8 *) d1; + ptr1 = (orc_int8 *) d2; + ptr2 = (orc_int8 *) d3; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var34 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var34.i; + var38.i = _src.x2[1]; + var39.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var38.i; + var35 = _src.x2[1]; + var36 = _src.x2[0]; + } + /* 3: storeb */ + ptr2[i] = var35; + /* 4: storeb */ + ptr1[i] = var36; + /* 5: select1wb */ + { + orc_union16 _src; + _src.i = var39.i; + var37 = _src.x2[1]; + } + /* 6: storeb */ + ptr0[i] = var37; + } + +} + +#else +static void +_backup_cogorc_putline_Y444 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_int8 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var34; + orc_int8 var35; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + + ptr0 = (orc_int8 *) ex->arrays[0]; + ptr1 = (orc_int8 *) ex->arrays[1]; + ptr2 = (orc_int8 *) ex->arrays[2]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var34 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var34.i; + var38.i = _src.x2[1]; + var39.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var38.i; + var35 = _src.x2[1]; + var36 = _src.x2[0]; + } + /* 3: storeb */ + ptr2[i] = var35; + /* 4: storeb */ + ptr1[i] = var36; + /* 5: select1wb */ + { + orc_union16 _src; + _src.i = var39.i; + var37 = _src.x2[1]; + } + /* 6: storeb */ + ptr0[i] = var37; + } + +} + +void +cogorc_putline_Y444 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_Y444"); + orc_program_set_backup_function (p, _backup_cogorc_putline_Y444); + orc_program_add_destination (p, 1, "d1"); + orc_program_add_destination (p, 1, "d2"); + orc_program_add_destination (p, 1, "d3"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_D3, ORC_VAR_D2, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 0, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_D3] = d3; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_Y800 */ +#ifdef DISABLE_ORC +void +cogorc_getline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + orc_int8 var33; + orc_int8 var34; + orc_union16 var35; + orc_union32 var36; + orc_union16 var37; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_int8 *) s1; + + /* 0: loadpb */ + var33 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + /* 3: loadpw */ + var35.i = (int) 0x00008080; /* 32896 or 1.62528e-319f */ + + for (i = 0; i < n; i++) { + /* 1: loadb */ + var34 = ptr4[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var33; + _dest.x2[1] = var34; + var37.i = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var37.i; + _dest.x2[1] = var35.i; + var36.i = _dest.i; + } + /* 5: storel */ + ptr0[i] = var36; + } + +} + +#else +static void +_backup_cogorc_getline_Y800 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + orc_int8 var33; + orc_int8 var34; + orc_union16 var35; + orc_union32 var36; + orc_union16 var37; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_int8 *) ex->arrays[4]; + + /* 0: loadpb */ + var33 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + /* 3: loadpw */ + var35.i = (int) 0x00008080; /* 32896 or 1.62528e-319f */ + + for (i = 0; i < n; i++) { + /* 1: loadb */ + var34 = ptr4[i]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var33; + _dest.x2[1] = var34; + var37.i = _dest.i; + } + /* 4: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var37.i; + _dest.x2[1] = var35.i; + var36.i = _dest.i; + } + /* 5: storel */ + ptr0[i] = var36; + } + +} + +void +cogorc_getline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_Y800"); + orc_program_set_backup_function (p, _backup_cogorc_getline_Y800); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 1, "s1"); + orc_program_add_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_constant (p, 2, 0x00008080, "c2"); + orc_program_add_temporary (p, 2, "t1"); + + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_C2, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_Y800 */ +#ifdef DISABLE_ORC +void +cogorc_putline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_int8 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var33; + orc_int8 var34; + orc_union16 var35; + + ptr0 = (orc_int8 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var33 = ptr4[i]; + /* 1: select0lw */ + { + orc_union32 _src; + _src.i = var33.i; + var35.i = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var35.i; + var34 = _src.x2[1]; + } + /* 3: storeb */ + ptr0[i] = var34; + } + +} + +#else +static void +_backup_cogorc_putline_Y800 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_int8 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var33; + orc_int8 var34; + orc_union16 var35; + + ptr0 = (orc_int8 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var33 = ptr4[i]; + /* 1: select0lw */ + { + orc_union32 _src; + _src.i = var33.i; + var35.i = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var35.i; + var34 = _src.x2[1]; + } + /* 3: storeb */ + ptr0[i] = var34; + } + +} + +void +cogorc_putline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_Y800"); + orc_program_set_backup_function (p, _backup_cogorc_putline_Y800); + orc_program_add_destination (p, 1, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_temporary (p, 2, "t1"); + + orc_program_append_2 (p, "select0lw", 0, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 0, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_Y16 */ +#ifdef DISABLE_ORC +void +cogorc_putline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var34; + orc_union16 var35; + orc_union16 var36; + orc_int8 var37; + orc_union16 var38; + + ptr0 = (orc_union16 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var34 = ptr4[i]; + /* 1: select0lw */ + { + orc_union32 _src; + _src.i = var34.i; + var36.i = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var36.i; + var37 = _src.x2[1]; + } + /* 3: convubw */ + var38.i = (orc_uint8) var37; + /* 4: shlw */ + var35.i = var38.i << 8; + /* 5: storew */ + ptr0[i] = var35; + } + +} + +#else +static void +_backup_cogorc_putline_Y16 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var34; + orc_union16 var35; + orc_union16 var36; + orc_int8 var37; + orc_union16 var38; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var34 = ptr4[i]; + /* 1: select0lw */ + { + orc_union32 _src; + _src.i = var34.i; + var36.i = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var36.i; + var37 = _src.x2[1]; + } + /* 3: convubw */ + var38.i = (orc_uint8) var37; + /* 4: shlw */ + var35.i = var38.i << 8; + /* 5: storew */ + ptr0[i] = var35; + } + +} + +void +cogorc_putline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_Y16"); + orc_program_set_backup_function (p, _backup_cogorc_putline_Y16); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_constant (p, 4, 0x00000008, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 1, "t2"); + + orc_program_append_2 (p, "select0lw", 0, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 0, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 0, ORC_VAR_T1, ORC_VAR_T2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "shlw", 0, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_C1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_Y16 */ +#ifdef DISABLE_ORC +void +cogorc_getline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + orc_union16 var34; + orc_int8 var35; + orc_union16 var36; + orc_union32 var37; + orc_int8 var38; + orc_union16 var39; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union16 *) s1; + + /* 2: loadpb */ + var35 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + /* 4: loadpw */ + var36.i = (int) 0x00008080; /* 32896 or 1.62528e-319f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var34 = ptr4[i]; + /* 1: convhwb */ + var38 = ((orc_uint16) var34.i) >> 8; + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var35; + _dest.x2[1] = var38; + var39.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var36.i; + var37.i = _dest.i; + } + /* 6: storel */ + ptr0[i] = var37; + } + +} + +#else +static void +_backup_cogorc_getline_Y16 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + orc_union16 var34; + orc_int8 var35; + orc_union16 var36; + orc_union32 var37; + orc_int8 var38; + orc_union16 var39; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + + /* 2: loadpb */ + var35 = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + /* 4: loadpw */ + var36.i = (int) 0x00008080; /* 32896 or 1.62528e-319f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var34 = ptr4[i]; + /* 1: convhwb */ + var38 = ((orc_uint16) var34.i) >> 8; + /* 3: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var35; + _dest.x2[1] = var38; + var39.i = _dest.i; + } + /* 5: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var36.i; + var37.i = _dest.i; + } + /* 6: storel */ + ptr0[i] = var37; + } + +} + +void +cogorc_getline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_Y16"); + orc_program_set_backup_function (p, _backup_cogorc_getline_Y16); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_add_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_constant (p, 2, 0x00008080, "c2"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 1, "t2"); + + orc_program_append_2 (p, "convhwb", 0, ORC_VAR_T2, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_C1, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_C2, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_BGRA */ +#ifdef DISABLE_ORC +void +cogorc_getline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + orc_union32 var33; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var32 = ptr4[i]; + /* 1: swapl */ + var33.i = ORC_SWAP_L (var32.i); + /* 2: storel */ + ptr0[i] = var33; + } + +} + +#else +static void +_backup_cogorc_getline_BGRA (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + orc_union32 var33; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var32 = ptr4[i]; + /* 1: swapl */ + var33.i = ORC_SWAP_L (var32.i); + /* 2: storel */ + ptr0[i] = var33; + } + +} + +void +cogorc_getline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_BGRA"); + orc_program_set_backup_function (p, _backup_cogorc_getline_BGRA); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + + orc_program_append_2 (p, "swapl", 0, ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_BGRA */ +#ifdef DISABLE_ORC +void +cogorc_putline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + orc_union32 var33; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var32 = ptr4[i]; + /* 1: swapl */ + var33.i = ORC_SWAP_L (var32.i); + /* 2: storel */ + ptr0[i] = var33; + } + +} + +#else +static void +_backup_cogorc_putline_BGRA (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + orc_union32 var33; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var32 = ptr4[i]; + /* 1: swapl */ + var33.i = ORC_SWAP_L (var32.i); + /* 2: storel */ + ptr0[i] = var33; + } + +} + +void +cogorc_putline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_BGRA"); + orc_program_set_backup_function (p, _backup_cogorc_putline_BGRA); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + + orc_program_append_2 (p, "swapl", 0, ORC_VAR_D1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_RGBA */ +#ifdef DISABLE_ORC +void +cogorc_putline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44; + _dest.x2[1] = var47; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var46; + _dest.x2[1] = var45; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var49.i; + _dest.x2[1] = var48.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +#else +static void +_backup_cogorc_putline_RGBA (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44; + _dest.x2[1] = var47; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var46; + _dest.x2[1] = var45; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var49.i; + _dest.x2[1] = var48.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +void +cogorc_putline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_RGBA"); + orc_program_set_backup_function (p, _backup_cogorc_putline_RGBA); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + 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, 1, "t4"); + orc_program_add_temporary (p, 2, "t5"); + orc_program_add_temporary (p, 2, "t6"); + orc_program_add_temporary (p, 2, "t7"); + orc_program_add_temporary (p, 2, "t8"); + + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T8, ORC_VAR_T7, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_T8, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_T7, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T6, ORC_VAR_T4, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T5, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_RGBA */ +#ifdef DISABLE_ORC +void +cogorc_getline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var46; + _dest.x2[1] = var45; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44; + _dest.x2[1] = var47; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +#else +static void +_backup_cogorc_getline_RGBA (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var46; + _dest.x2[1] = var45; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var44; + _dest.x2[1] = var47; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +void +cogorc_getline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_RGBA"); + orc_program_set_backup_function (p, _backup_cogorc_getline_RGBA); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + 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, 1, "t4"); + orc_program_add_temporary (p, 2, "t5"); + orc_program_add_temporary (p, 2, "t6"); + orc_program_add_temporary (p, 2, "t7"); + orc_program_add_temporary (p, 2, "t8"); + + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T6, ORC_VAR_T5, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T3, ORC_VAR_T2, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T1, ORC_VAR_T4, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T7, ORC_VAR_T1, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T8, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T7, ORC_VAR_T8, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_ABGR */ +#ifdef DISABLE_ORC +void +cogorc_getline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var47; + _dest.x2[1] = var44; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var45; + _dest.x2[1] = var46; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +#else +static void +_backup_cogorc_getline_ABGR (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var47; + _dest.x2[1] = var44; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var45; + _dest.x2[1] = var46; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +void +cogorc_getline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_ABGR"); + orc_program_set_backup_function (p, _backup_cogorc_getline_ABGR); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + 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, 1, "t4"); + orc_program_add_temporary (p, 2, "t5"); + orc_program_add_temporary (p, 2, "t6"); + orc_program_add_temporary (p, 2, "t7"); + orc_program_add_temporary (p, 2, "t8"); + + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T5, ORC_VAR_T6, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T2, ORC_VAR_T3, ORC_VAR_T5, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T4, ORC_VAR_T1, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T7, ORC_VAR_T1, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T8, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T7, ORC_VAR_T8, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_ABGR */ +#ifdef DISABLE_ORC +void +cogorc_putline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var47; + _dest.x2[1] = var44; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var45; + _dest.x2[1] = var46; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +#else +static void +_backup_cogorc_putline_ABGR (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_int8 var44; + orc_int8 var45; + orc_int8 var46; + orc_int8 var47; + orc_union16 var48; + orc_union16 var49; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadl */ + var40 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 2: splitwb */ + { + orc_union16 _src; + _src.i = var42.i; + var44 = _src.x2[1]; + var45 = _src.x2[0]; + } + /* 3: splitwb */ + { + orc_union16 _src; + _src.i = var43.i; + var46 = _src.x2[1]; + var47 = _src.x2[0]; + } + /* 4: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var47; + _dest.x2[1] = var44; + var48.i = _dest.i; + } + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var45; + _dest.x2[1] = var46; + var49.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var48.i; + _dest.x2[1] = var49.i; + var41.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var41; + } + +} + +void +cogorc_putline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_ABGR"); + orc_program_set_backup_function (p, _backup_cogorc_putline_ABGR); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + 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, 1, "t4"); + orc_program_add_temporary (p, 2, "t5"); + orc_program_add_temporary (p, 2, "t6"); + orc_program_add_temporary (p, 2, "t7"); + orc_program_add_temporary (p, 2, "t8"); + + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T8, ORC_VAR_T7, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_T8, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_T7, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T6, ORC_VAR_T1, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T5, ORC_VAR_T3, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T6, ORC_VAR_T5, + ORC_VAR_D1); + + 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] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_NV12 */ +#ifdef DISABLE_ORC +void +cogorc_getline_NV12 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var34; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union64 var38; + orc_union32 var39; + orc_union32 var40; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_union16 *) s2; + + /* 3: loadpb */ + var36.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var36.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var34 = ptr5[i]; + /* 1: loadw */ + var35 = ptr5[i]; + /* 2: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var34.i; + _dest.x2[1] = var35.i; + var39.i = _dest.i; + } + /* 4: loadw */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[0]; + _dest.x2[1] = var37.x2[0]; + var40.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[1]; + _dest.x2[1] = var37.x2[1]; + var40.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.x2[0]; + _dest.x2[1] = var39.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var40.x2[1]; + _dest.x2[1] = var39.x2[1]; + var38.x2[1] = _dest.i; + } + /* 7: storeq */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_NV12 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var34; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union64 var38; + orc_union32 var39; + orc_union32 var40; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_union16 *) ex->arrays[5]; + + /* 3: loadpb */ + var36.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var36.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var34 = ptr5[i]; + /* 1: loadw */ + var35 = ptr5[i]; + /* 2: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var34.i; + _dest.x2[1] = var35.i; + var39.i = _dest.i; + } + /* 4: loadw */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[0]; + _dest.x2[1] = var37.x2[0]; + var40.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[1]; + _dest.x2[1] = var37.x2[1]; + var40.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var40.x2[0]; + _dest.x2[1] = var39.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var40.x2[1]; + _dest.x2[1] = var39.x2[1]; + var38.x2[1] = _dest.i; + } + /* 7: storeq */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_NV12 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_NV12"); + orc_program_set_backup_function (p, _backup_cogorc_getline_NV12); + orc_program_add_destination (p, 8, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_add_source (p, 2, "s2"); + orc_program_add_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_S2, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T1, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_T2, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_NV12 */ +#ifdef DISABLE_ORC +void +cogorc_putline_NV12 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + orc_union16 *ORC_RESTRICT ptr1; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var36; + orc_union16 var37; + orc_union16 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union16 *) d1; + ptr1 = (orc_union16 *) d2; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var36 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var37.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var37.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var37; + /* 4: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 5: avgub */ + var38.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var38.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 6: storew */ + ptr1[i] = var38; + } + +} + +#else +static void +_backup_cogorc_putline_NV12 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + orc_union16 *ORC_RESTRICT ptr1; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var36; + orc_union16 var37; + orc_union16 var38; + orc_union32 var39; + orc_union32 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr1 = (orc_union16 *) ex->arrays[1]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var36 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var36.x2[0]; + var39.x2[0] = _src.x2[1]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var36.x2[1]; + var39.x2[1] = _src.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var40.x2[0]; + var37.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var40.x2[1]; + var37.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var37; + /* 4: splitlw */ + { + orc_union32 _src; + _src.i = var39.i; + var41.i = _src.x2[1]; + var42.i = _src.x2[0]; + } + /* 5: avgub */ + var38.x2[0] = ((orc_uint8) var41.x2[0] + (orc_uint8) var42.x2[0] + 1) >> 1; + var38.x2[1] = ((orc_uint8) var41.x2[1] + (orc_uint8) var42.x2[1] + 1) >> 1; + /* 6: storew */ + ptr1[i] = var38; + } + +} + +void +cogorc_putline_NV12 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_NV12"); + orc_program_set_backup_function (p, _backup_cogorc_putline_NV12); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_destination (p, 2, "d2"); + orc_program_add_source (p, 8, "s1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 2, "t3"); + orc_program_add_temporary (p, 2, "t4"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T3, ORC_VAR_T4, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 1, ORC_VAR_D2, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_NV21 */ +#ifdef DISABLE_ORC +void +cogorc_getline_NV21 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union16 *) s1; + ptr5 = (orc_union16 *) s2; + + /* 3: loadpb */ + var36.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var36.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var35 = ptr5[i]; + /* 1: swapw */ + var39.i = ORC_SWAP_W (var35.i); + /* 2: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var39.i; + var40.i = _dest.i; + } + /* 4: loadw */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[0]; + _dest.x2[1] = var37.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[1]; + _dest.x2[1] = var37.x2[1]; + var41.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var40.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var40.x2[1]; + var38.x2[1] = _dest.i; + } + /* 7: storeq */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_NV21 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + const orc_union16 *ORC_RESTRICT ptr4; + const orc_union16 *ORC_RESTRICT ptr5; + orc_union16 var35; + orc_union16 var36; + orc_union16 var37; + orc_union64 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + + ptr0 = (orc_union64 *) ex->arrays[0]; + ptr4 = (orc_union16 *) ex->arrays[4]; + ptr5 = (orc_union16 *) ex->arrays[5]; + + /* 3: loadpb */ + var36.x2[0] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + var36.x2[1] = (int) 0x000000ff; /* 255 or 1.25987e-321f */ + + for (i = 0; i < n; i++) { + /* 0: loadw */ + var35 = ptr5[i]; + /* 1: swapw */ + var39.i = ORC_SWAP_W (var35.i); + /* 2: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var39.i; + _dest.x2[1] = var39.i; + var40.i = _dest.i; + } + /* 4: loadw */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[0]; + _dest.x2[1] = var37.x2[0]; + var41.x2[0] = _dest.i; + } + { + orc_union16 _dest; + _dest.x2[0] = var36.x2[1]; + _dest.x2[1] = var37.x2[1]; + var41.x2[1] = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[0]; + _dest.x2[1] = var40.x2[0]; + var38.x2[0] = _dest.i; + } + { + orc_union32 _dest; + _dest.x2[0] = var41.x2[1]; + _dest.x2[1] = var40.x2[1]; + var38.x2[1] = _dest.i; + } + /* 7: storeq */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_NV21 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_NV21"); + orc_program_set_backup_function (p, _backup_cogorc_getline_NV21); + orc_program_add_destination (p, 8, "d1"); + orc_program_add_source (p, 2, "s1"); + orc_program_add_source (p, 2, "s2"); + orc_program_add_constant (p, 1, 0x000000ff, "c1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 4, "t3"); + + orc_program_append_2 (p, "swapw", 0, ORC_VAR_T1, ORC_VAR_S2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T3, ORC_VAR_T1, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 1, ORC_VAR_T2, ORC_VAR_C1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 1, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T3, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_NV21 */ +#ifdef DISABLE_ORC +void +cogorc_putline_NV21 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + orc_union16 *ORC_RESTRICT ptr1; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union16 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union16 *) d1; + ptr1 = (orc_union16 *) d2; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var40.x2[0] = _src.x2[1]; + var41.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var40.x2[1] = _src.x2[1]; + var41.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var41.x2[0]; + var38.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var41.x2[1]; + var38.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var38; + /* 4: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 5: avgub */ + var44.x2[0] = ((orc_uint8) var42.x2[0] + (orc_uint8) var43.x2[0] + 1) >> 1; + var44.x2[1] = ((orc_uint8) var42.x2[1] + (orc_uint8) var43.x2[1] + 1) >> 1; + /* 6: swapw */ + var39.i = ORC_SWAP_W (var44.i); + /* 7: storew */ + ptr1[i] = var39; + } + +} + +#else +static void +_backup_cogorc_putline_NV21 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + orc_union16 *ORC_RESTRICT ptr1; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var37; + orc_union16 var38; + orc_union16 var39; + orc_union32 var40; + orc_union32 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr1 = (orc_union16 *) ex->arrays[1]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var37 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var37.x2[0]; + var40.x2[0] = _src.x2[1]; + var41.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var37.x2[1]; + var40.x2[1] = _src.x2[1]; + var41.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var41.x2[0]; + var38.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var41.x2[1]; + var38.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var38; + /* 4: splitlw */ + { + orc_union32 _src; + _src.i = var40.i; + var42.i = _src.x2[1]; + var43.i = _src.x2[0]; + } + /* 5: avgub */ + var44.x2[0] = ((orc_uint8) var42.x2[0] + (orc_uint8) var43.x2[0] + 1) >> 1; + var44.x2[1] = ((orc_uint8) var42.x2[1] + (orc_uint8) var43.x2[1] + 1) >> 1; + /* 6: swapw */ + var39.i = ORC_SWAP_W (var44.i); + /* 7: storew */ + ptr1[i] = var39; + } + +} + +void +cogorc_putline_NV21 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_NV21"); + orc_program_set_backup_function (p, _backup_cogorc_putline_NV21); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_destination (p, 2, "d2"); + orc_program_add_source (p, 8, "s1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "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_2 (p, "splitlw", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "splitlw", 0, ORC_VAR_T3, ORC_VAR_T4, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 1, ORC_VAR_T5, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "swapw", 0, ORC_VAR_D2, ORC_VAR_T5, ORC_VAR_D1, + ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_getline_A420 */ +#ifdef DISABLE_ORC +void +cogorc_getline_A420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, + const guint8 * ORC_RESTRICT s4, int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + const orc_int8 *ORC_RESTRICT ptr7; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_int8 var39; + orc_int8 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_int8 *) s1; + ptr5 = (orc_int8 *) s2; + ptr6 = (orc_int8 *) s3; + ptr7 = (orc_int8 *) s4; + + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var39 = ptr5[i >> 1]; + /* 1: loadupdb */ + var40 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var39; + _dest.x2[1] = var40; + var41.i = _dest.i; + } + /* 3: loadb */ + var36 = ptr7[i]; + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var42.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var41.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +#else +static void +_backup_cogorc_getline_A420 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + const orc_int8 *ORC_RESTRICT ptr6; + const orc_int8 *ORC_RESTRICT ptr7; + orc_int8 var36; + orc_int8 var37; + orc_union32 var38; + orc_int8 var39; + orc_int8 var40; + orc_union16 var41; + orc_union16 var42; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_int8 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + ptr6 = (orc_int8 *) ex->arrays[6]; + ptr7 = (orc_int8 *) ex->arrays[7]; + + + for (i = 0; i < n; i++) { + /* 0: loadupdb */ + var39 = ptr5[i >> 1]; + /* 1: loadupdb */ + var40 = ptr6[i >> 1]; + /* 2: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var39; + _dest.x2[1] = var40; + var41.i = _dest.i; + } + /* 3: loadb */ + var36 = ptr7[i]; + /* 4: loadb */ + var37 = ptr4[i]; + /* 5: mergebw */ + { + orc_union16 _dest; + _dest.x2[0] = var36; + _dest.x2[1] = var37; + var42.i = _dest.i; + } + /* 6: mergewl */ + { + orc_union32 _dest; + _dest.x2[0] = var42.i; + _dest.x2[1] = var41.i; + var38.i = _dest.i; + } + /* 7: storel */ + ptr0[i] = var38; + } + +} + +void +cogorc_getline_A420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, + const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, + const guint8 * ORC_RESTRICT s4, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_getline_A420"); + orc_program_set_backup_function (p, _backup_cogorc_getline_A420); + 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_source (p, 1, "s4"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 1, "t3"); + orc_program_add_temporary (p, 1, "t4"); + + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T3, ORC_VAR_S2, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T4, ORC_VAR_S3, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T1, ORC_VAR_T3, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T2, ORC_VAR_S4, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "mergewl", 0, ORC_VAR_D1, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->arrays[ORC_VAR_S3] = (void *) s3; + ex->arrays[ORC_VAR_S4] = (void *) s4; + + func = p->code_exec; + func (ex); +} +#endif + + +/* cogorc_putline_A420 */ +#ifdef DISABLE_ORC +void +cogorc_putline_A420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, guint8 * ORC_RESTRICT d4, + const guint8 * ORC_RESTRICT s1, int n) +{ + int i; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + orc_union16 *ORC_RESTRICT ptr3; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_int8 var41; + orc_int8 var42; + orc_union32 var43; + orc_union32 var44; + orc_union16 var45; + orc_union16 var46; + orc_int8 var47; + orc_int8 var48; + orc_int8 var49; + orc_int8 var50; + + ptr0 = (orc_union16 *) d1; + ptr1 = (orc_int8 *) d2; + ptr2 = (orc_int8 *) d3; + ptr3 = (orc_union16 *) d4; + ptr4 = (orc_union64 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var38 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var38.x2[0]; + var43.x2[0] = _src.x2[1]; + var44.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var38.x2[1]; + var43.x2[1] = _src.x2[1]; + var44.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var44.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var44.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var39; + /* 4: select0wb */ + { + orc_union16 _src; + _src.i = var44.x2[0]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var44.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 5: storew */ + ptr3[i] = var40; + /* 6: splitwb */ + { + orc_union16 _src; + _src.i = var43.x2[0]; + var45.x2[0] = _src.x2[1]; + var46.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var43.x2[1]; + var45.x2[1] = _src.x2[1]; + var46.x2[1] = _src.x2[0]; + } + /* 7: splitwb */ + { + orc_union16 _src; + _src.i = var46.i; + var47 = _src.x2[1]; + var48 = _src.x2[0]; + } + /* 8: avgub */ + var41 = ((orc_uint8) var47 + (orc_uint8) var48 + 1) >> 1; + /* 9: storeb */ + ptr1[i] = var41; + /* 10: splitwb */ + { + orc_union16 _src; + _src.i = var45.i; + var49 = _src.x2[1]; + var50 = _src.x2[0]; + } + /* 11: avgub */ + var42 = ((orc_uint8) var49 + (orc_uint8) var50 + 1) >> 1; + /* 12: storeb */ + ptr2[i] = var42; + } + +} + +#else +static void +_backup_cogorc_putline_A420 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union16 *ORC_RESTRICT ptr0; + orc_int8 *ORC_RESTRICT ptr1; + orc_int8 *ORC_RESTRICT ptr2; + orc_union16 *ORC_RESTRICT ptr3; + const orc_union64 *ORC_RESTRICT ptr4; + orc_union64 var38; + orc_union16 var39; + orc_union16 var40; + orc_int8 var41; + orc_int8 var42; + orc_union32 var43; + orc_union32 var44; + orc_union16 var45; + orc_union16 var46; + orc_int8 var47; + orc_int8 var48; + orc_int8 var49; + orc_int8 var50; + + ptr0 = (orc_union16 *) ex->arrays[0]; + ptr1 = (orc_int8 *) ex->arrays[1]; + ptr2 = (orc_int8 *) ex->arrays[2]; + ptr3 = (orc_union16 *) ex->arrays[3]; + ptr4 = (orc_union64 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: loadq */ + var38 = ptr4[i]; + /* 1: splitlw */ + { + orc_union32 _src; + _src.i = var38.x2[0]; + var43.x2[0] = _src.x2[1]; + var44.x2[0] = _src.x2[0]; + } + { + orc_union32 _src; + _src.i = var38.x2[1]; + var43.x2[1] = _src.x2[1]; + var44.x2[1] = _src.x2[0]; + } + /* 2: select1wb */ + { + orc_union16 _src; + _src.i = var44.x2[0]; + var39.x2[0] = _src.x2[1]; + } + { + orc_union16 _src; + _src.i = var44.x2[1]; + var39.x2[1] = _src.x2[1]; + } + /* 3: storew */ + ptr0[i] = var39; + /* 4: select0wb */ + { + orc_union16 _src; + _src.i = var44.x2[0]; + var40.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var44.x2[1]; + var40.x2[1] = _src.x2[0]; + } + /* 5: storew */ + ptr3[i] = var40; + /* 6: splitwb */ + { + orc_union16 _src; + _src.i = var43.x2[0]; + var45.x2[0] = _src.x2[1]; + var46.x2[0] = _src.x2[0]; + } + { + orc_union16 _src; + _src.i = var43.x2[1]; + var45.x2[1] = _src.x2[1]; + var46.x2[1] = _src.x2[0]; + } + /* 7: splitwb */ + { + orc_union16 _src; + _src.i = var46.i; + var47 = _src.x2[1]; + var48 = _src.x2[0]; + } + /* 8: avgub */ + var41 = ((orc_uint8) var47 + (orc_uint8) var48 + 1) >> 1; + /* 9: storeb */ + ptr1[i] = var41; + /* 10: splitwb */ + { + orc_union16 _src; + _src.i = var45.i; + var49 = _src.x2[1]; + var50 = _src.x2[0]; + } + /* 11: avgub */ + var42 = ((orc_uint8) var49 + (orc_uint8) var50 + 1) >> 1; + /* 12: storeb */ + ptr2[i] = var42; + } + +} + +void +cogorc_putline_A420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, + guint8 * ORC_RESTRICT d3, guint8 * ORC_RESTRICT d4, + const guint8 * ORC_RESTRICT s1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "cogorc_putline_A420"); + orc_program_set_backup_function (p, _backup_cogorc_putline_A420); + orc_program_add_destination (p, 2, "d1"); + orc_program_add_destination (p, 1, "d2"); + orc_program_add_destination (p, 1, "d3"); + orc_program_add_destination (p, 2, "d4"); + orc_program_add_source (p, 8, "s1"); + orc_program_add_temporary (p, 4, "t1"); + orc_program_add_temporary (p, 4, "t2"); + orc_program_add_temporary (p, 2, "t3"); + orc_program_add_temporary (p, 2, "t4"); + orc_program_add_temporary (p, 1, "t5"); + orc_program_add_temporary (p, 1, "t6"); + + orc_program_append_2 (p, "splitlw", 1, ORC_VAR_T2, ORC_VAR_T1, ORC_VAR_S1, + ORC_VAR_D1); + orc_program_append_2 (p, "select1wb", 1, ORC_VAR_D1, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "select0wb", 1, ORC_VAR_D4, ORC_VAR_T1, + ORC_VAR_D1, ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 1, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_T2, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T5, ORC_VAR_T6, ORC_VAR_T3, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 0, ORC_VAR_D2, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + orc_program_append_2 (p, "splitwb", 0, ORC_VAR_T5, ORC_VAR_T6, ORC_VAR_T4, + ORC_VAR_D1); + orc_program_append_2 (p, "avgub", 0, ORC_VAR_D3, ORC_VAR_T5, ORC_VAR_T6, + ORC_VAR_D1); + + 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_D2] = d2; + ex->arrays[ORC_VAR_D3] = d3; + ex->arrays[ORC_VAR_D4] = d4; + ex->arrays[ORC_VAR_S1] = (void *) s1; + + func = p->code_exec; + func (ex); +} +#endif + + +/* orc_resample_bilinear_u32 */ +#ifdef DISABLE_ORC +void +orc_resample_bilinear_u32 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int p1, int p2, int n) +{ + int i; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + + ptr0 = (orc_union32 *) d1; + ptr4 = (orc_union32 *) s1; + + + for (i = 0; i < n; i++) { + /* 0: ldreslinl */ + { + int tmp = p1 + i * p2; + orc_union32 a = ptr4[tmp >> 16]; + orc_union32 b = ptr4[(tmp >> 16) + 1]; + var32.x4[0] = + ((orc_uint8) a.x4[0] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[0] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[1] = + ((orc_uint8) a.x4[1] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[1] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[2] = + ((orc_uint8) a.x4[2] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[2] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[3] = + ((orc_uint8) a.x4[3] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[3] * ((tmp >> 8) & 0xff)) >> 8; + } + /* 1: storel */ + ptr0[i] = var32; + } + +} + +#else +static void +_backup_orc_resample_bilinear_u32 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union32 *ORC_RESTRICT ptr0; + const orc_union32 *ORC_RESTRICT ptr4; + orc_union32 var32; + + ptr0 = (orc_union32 *) ex->arrays[0]; + ptr4 = (orc_union32 *) ex->arrays[4]; + + + for (i = 0; i < n; i++) { + /* 0: ldreslinl */ + { + int tmp = ex->params[24] + i * ex->params[25]; + orc_union32 a = ptr4[tmp >> 16]; + orc_union32 b = ptr4[(tmp >> 16) + 1]; + var32.x4[0] = + ((orc_uint8) a.x4[0] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[0] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[1] = + ((orc_uint8) a.x4[1] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[1] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[2] = + ((orc_uint8) a.x4[2] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[2] * ((tmp >> 8) & 0xff)) >> 8; + var32.x4[3] = + ((orc_uint8) a.x4[3] * (256 - ((tmp >> 8) & 0xff)) + + (orc_uint8) b.x4[3] * ((tmp >> 8) & 0xff)) >> 8; + } + /* 1: storel */ + ptr0[i] = var32; + } + +} + +void +orc_resample_bilinear_u32 (guint8 * ORC_RESTRICT d1, + const guint8 * ORC_RESTRICT s1, int p1, int p2, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "orc_resample_bilinear_u32"); + orc_program_set_backup_function (p, _backup_orc_resample_bilinear_u32); + orc_program_add_destination (p, 4, "d1"); + orc_program_add_source (p, 4, "s1"); + orc_program_add_parameter (p, 4, "p1"); + orc_program_add_parameter (p, 4, "p2"); + + orc_program_append_2 (p, "ldreslinl", 0, ORC_VAR_D1, ORC_VAR_S1, + ORC_VAR_P1, ORC_VAR_P2); + + 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] = (void *) s1; + ex->params[ORC_VAR_P1] = p1; + ex->params[ORC_VAR_P2] = p2; + + func = p->code_exec; + func (ex); +} +#endif + + +/* orc_merge_linear_u8 */ +#ifdef DISABLE_ORC +void +orc_merge_linear_u8 (orc_uint8 * ORC_RESTRICT d1, + const orc_uint8 * ORC_RESTRICT s1, const orc_uint8 * ORC_RESTRICT s2, + int p1, int n) +{ + int i; + orc_int8 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + orc_int8 var40; + orc_int8 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + orc_union16 var45; + orc_union16 var46; + orc_int8 var47; + + ptr0 = (orc_int8 *) d1; + ptr4 = (orc_int8 *) s1; + ptr5 = (orc_int8 *) s2; + + /* 6: loadpw */ + var38.i = p1; + /* 8: loadpw */ + var39.i = (int) 0x00000080; /* 128 or 6.32404e-322f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var41 = ptr4[i]; + /* 1: loadb */ + var36 = ptr4[i]; + /* 2: convubw */ + var42.i = (orc_uint8) var36; + /* 3: loadb */ + var37 = ptr5[i]; + /* 4: convubw */ + var43.i = (orc_uint8) var37; + /* 5: subw */ + var44.i = var43.i - var42.i; + /* 7: mullw */ + var45.i = (var44.i * var38.i) & 0xffff; + /* 9: addw */ + var46.i = var45.i + var39.i; + /* 10: convhwb */ + var47 = ((orc_uint16) var46.i) >> 8; + /* 11: addb */ + var40 = var47 + var41; + /* 12: storeb */ + ptr0[i] = var40; + } + +} + +#else +static void +_backup_orc_merge_linear_u8 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_int8 *ORC_RESTRICT ptr0; + const orc_int8 *ORC_RESTRICT ptr4; + const orc_int8 *ORC_RESTRICT ptr5; + orc_int8 var36; + orc_int8 var37; + orc_union16 var38; + orc_union16 var39; + orc_int8 var40; + orc_int8 var41; + orc_union16 var42; + orc_union16 var43; + orc_union16 var44; + orc_union16 var45; + orc_union16 var46; + orc_int8 var47; + + ptr0 = (orc_int8 *) ex->arrays[0]; + ptr4 = (orc_int8 *) ex->arrays[4]; + ptr5 = (orc_int8 *) ex->arrays[5]; + + /* 6: loadpw */ + var38.i = ex->params[24]; + /* 8: loadpw */ + var39.i = (int) 0x00000080; /* 128 or 6.32404e-322f */ + + for (i = 0; i < n; i++) { + /* 0: loadb */ + var41 = ptr4[i]; + /* 1: loadb */ + var36 = ptr4[i]; + /* 2: convubw */ + var42.i = (orc_uint8) var36; + /* 3: loadb */ + var37 = ptr5[i]; + /* 4: convubw */ + var43.i = (orc_uint8) var37; + /* 5: subw */ + var44.i = var43.i - var42.i; + /* 7: mullw */ + var45.i = (var44.i * var38.i) & 0xffff; + /* 9: addw */ + var46.i = var45.i + var39.i; + /* 10: convhwb */ + var47 = ((orc_uint16) var46.i) >> 8; + /* 11: addb */ + var40 = var47 + var41; + /* 12: storeb */ + ptr0[i] = var40; + } + +} + +void +orc_merge_linear_u8 (orc_uint8 * ORC_RESTRICT d1, + const orc_uint8 * ORC_RESTRICT s1, const orc_uint8 * ORC_RESTRICT s2, + int p1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + static volatile int p_inited = 0; + static OrcProgram *p = 0; + void (*func) (OrcExecutor *); + + if (!p_inited) { + orc_once_mutex_lock (); + if (!p_inited) { + + p = orc_program_new (); + orc_program_set_name (p, "orc_merge_linear_u8"); + orc_program_set_backup_function (p, _backup_orc_merge_linear_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, 4, 0x00000080, "c1"); + orc_program_add_parameter (p, 1, "p1"); + orc_program_add_temporary (p, 2, "t1"); + orc_program_add_temporary (p, 2, "t2"); + orc_program_add_temporary (p, 1, "t3"); + orc_program_add_temporary (p, 1, "t4"); + + orc_program_append_2 (p, "loadb", 0, ORC_VAR_T3, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 0, ORC_VAR_T1, ORC_VAR_S1, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "convubw", 0, ORC_VAR_T2, ORC_VAR_S2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "subw", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_T1, + ORC_VAR_D1); + orc_program_append_2 (p, "mullw", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_P1, + ORC_VAR_D1); + orc_program_append_2 (p, "addw", 0, ORC_VAR_T2, ORC_VAR_T2, ORC_VAR_C1, + ORC_VAR_D1); + orc_program_append_2 (p, "convhwb", 0, ORC_VAR_T4, ORC_VAR_T2, ORC_VAR_D1, + ORC_VAR_D1); + orc_program_append_2 (p, "addb", 0, ORC_VAR_D1, ORC_VAR_T4, ORC_VAR_T3, + ORC_VAR_D1); + + 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] = (void *) s1; + ex->arrays[ORC_VAR_S2] = (void *) s2; + ex->params[ORC_VAR_P1] = p1; + + func = p->code_exec; + func (ex); +} +#endif diff --git a/gst-libs/gst/video/videoblendorc-dist.h b/gst-libs/gst/video/videoblendorc-dist.h new file mode 100644 index 0000000000..ce7caabfa6 --- /dev/null +++ b/gst-libs/gst/video/videoblendorc-dist.h @@ -0,0 +1,107 @@ + +/* autogenerated from videoblendorc.orc */ + +#ifndef _VIDEOBLENDORC_H_ +#define _VIDEOBLENDORC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef _ORC_INTEGER_TYPEDEFS_ +#define _ORC_INTEGER_TYPEDEFS_ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +typedef int8_t orc_int8; +typedef int16_t orc_int16; +typedef int32_t orc_int32; +typedef int64_t orc_int64; +typedef uint8_t orc_uint8; +typedef uint16_t orc_uint16; +typedef uint32_t orc_uint32; +typedef uint64_t orc_uint64; +#define ORC_UINT64_C(x) UINT64_C(x) +#elif defined(_MSC_VER) +typedef signed __int8 orc_int8; +typedef signed __int16 orc_int16; +typedef signed __int32 orc_int32; +typedef signed __int64 orc_int64; +typedef unsigned __int8 orc_uint8; +typedef unsigned __int16 orc_uint16; +typedef unsigned __int32 orc_uint32; +typedef unsigned __int64 orc_uint64; +#define ORC_UINT64_C(x) (x##Ui64) +#define inline __inline +#else +#include +typedef signed char orc_int8; +typedef short orc_int16; +typedef int orc_int32; +typedef unsigned char orc_uint8; +typedef unsigned short orc_uint16; +typedef unsigned int orc_uint32; +#if INT_MAX == LONG_MAX +typedef long long orc_int64; +typedef unsigned long long orc_uint64; +#define ORC_UINT64_C(x) (x##ULL) +#else +typedef long orc_int64; +typedef unsigned long orc_uint64; +#define ORC_UINT64_C(x) (x##UL) +#endif +#endif +typedef union { orc_int16 i; orc_int8 x2[2]; } orc_union16; +typedef union { orc_int32 i; float f; orc_int16 x2[2]; orc_int8 x4[4]; } orc_union32; +typedef union { orc_int64 i; double f; orc_int32 x2[2]; float x2f[2]; orc_int16 x4[4]; } orc_union64; +#endif +#ifndef ORC_RESTRICT +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define ORC_RESTRICT restrict +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ORC_RESTRICT __restrict__ +#else +#define ORC_RESTRICT +#endif +#endif +void orc_blend_little (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void orc_blend_big (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_I420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_I420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_YUY2 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_UYVY (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_YUV9 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); +void cogorc_getline_Y42B (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_Y42B (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y444 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int n); +void cogorc_putline_Y444 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, guint8 * ORC_RESTRICT d3, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_Y800 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_Y16 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_RGBA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_putline_ABGR (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_NV12 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void cogorc_putline_NV12 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_NV21 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, int n); +void cogorc_putline_NV21 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, const guint8 * ORC_RESTRICT s1, int n); +void cogorc_getline_A420 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, const guint8 * ORC_RESTRICT s4, int n); +void cogorc_putline_A420 (guint8 * ORC_RESTRICT d1, guint8 * ORC_RESTRICT d2, guint8 * ORC_RESTRICT d3, guint8 * ORC_RESTRICT d4, const guint8 * ORC_RESTRICT s1, int n); +void orc_resample_bilinear_u32 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int p1, int p2, int n); +void orc_merge_linear_u8 (orc_uint8 * ORC_RESTRICT d1, const orc_uint8 * ORC_RESTRICT s1, const orc_uint8 * ORC_RESTRICT s2, int p1, int n); + +#ifdef __cplusplus +} +#endif + +#endif + From a7a3f969b306c1747972f5e662fd4b186cd6ecaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 23 Nov 2011 00:31:18 +0000 Subject: [PATCH 13/31] video: hide private video-blend.[ch] from gobject-introspection And remove unused fields from helper structure. --- gst-libs/gst/video/Makefile.am | 5 +++-- gst-libs/gst/video/video-blend.h | 6 +----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 5ab524f082..f5a12ba296 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -51,8 +51,9 @@ BUILT_GIRSOURCES = GstVideo-@GST_MAJORMINOR@.gir gir_headers=$(patsubst %,$(srcdir)/%, $(libgstvideo_@GST_MAJORMINOR@include_HEADERS)) gir_headers+=$(patsubst %,$(builddir)/%, $(built_headers)) -gir_sources=$(patsubst %,$(srcdir)/%, $(libgstvideo_@GST_MAJORMINOR@_la_SOURCES)) -gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources)) +video_gir_sources=$(patsubst %,$(srcdir)/%, $(libgstvideo_@GST_MAJORMINOR@_la_SOURCES)) +video_gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources)) +gir_sources=$(subst $(srcdir)/video-blend.h,,$(subst $(srcdir)/video-blend.c,,$(video_gir_sources))) gir_cincludes=$(patsubst %,--c-include='gst/video/%',$(libgstvideo_@GST_MAJORMINOR@include_HEADERS)) gir_cincludes+=$(patsubst %,--c-include='gst/video/%',$(nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS)) diff --git a/gst-libs/gst/video/video-blend.h b/gst-libs/gst/video/video-blend.h index 3d9402ebee..3f5e0cd69b 100644 --- a/gst-libs/gst/video/video-blend.h +++ b/gst-libs/gst/video/video-blend.h @@ -31,8 +31,7 @@ typedef struct _GstBlendVideoFormatInfo GstBlendVideoFormatInfo; -/** - * GstBlendVideoFormatInfo: +/* GstBlendVideoFormatInfo: * @fmt: The #GstVideoFormat describing the video format * @width: The width of the video * @height: The height of the video @@ -51,9 +50,6 @@ struct _GstBlendVideoFormatInfo gint width; gint height; - gint dest_width; - gint dest_height; - guint8 * pixels; gsize size; From 6630236af4e7ab3dfbce2265c7ad7ff9b59c302c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 12 Nov 2011 14:59:35 +0000 Subject: [PATCH 14/31] video: add video overlay composition API for subtitles Basic API to attach overlay rectangles to buffers, or blend them directly onto raw video buffers. To be used primarily for things like subtitles or logo overlays, not meant to replace videomixer. Allows us to associate subtitle overlays with non-raw video surface buffers, so that subtitles are not lost and can instead be rendered later when those surfaces are displayed or converted, whilst re-using all the existing overlay plugins and not having to teach them about our special video surfaces. Could also have been made part of the surface buffer abstraction of course, but a secondary goal was to consolidate the blending code for raw video into libgstvideo, and this kind of API allows us to do both in a way that's minimally invasive to existing elements, and at the same time is fairly intuitive. More features and extensions like the ability to pass the source data or text/markup directly will be added later. https://bugzilla.gnome.org/show_bug.cgi?id=665080 API: gst_video_buffer_get_overlay_composition() API: gst_video_buffer_set_overlay_composition() API: gst_video_overlay_composition_new() API: gst_video_overlay_composition_add_rectangle() API: gst_video_overlay_composition_n_rectangles() API: gst_video_overlay_composition_get_rectangle() API: gst_video_overlay_composition_make_writable() API: gst_video_overlay_composition_copy() API: gst_video_overlay_composition_ref() API: gst_video_overlay_composition_unref() API: gst_video_overlay_composition_blend() API: gst_video_overlay_rectangle_new_argb() API: gst_video_overlay_rectangle_get_pixels_argb() API: gst_video_overlay_rectangle_get_pixels_unscaled_argb() API: gst_video_overlay_rectangle_get_render_rectangle() API: gst_video_overlay_rectangle_set_render_rectangle() API: gst_video_overlay_rectangle_copy() API: gst_video_overlay_rectangle_ref() API: gst_video_overlay_rectangle_unref() --- gst-libs/gst/video/Makefile.am | 4 +- .../gst/video/video-overlay-composition.c | 940 ++++++++++++++++++ .../gst/video/video-overlay-composition.h | 231 +++++ win32/common/libgstvideo.def | 17 + 4 files changed, 1190 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/video/video-overlay-composition.c create mode 100644 gst-libs/gst/video/video-overlay-composition.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index f5a12ba296..854b0b3db7 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -20,13 +20,13 @@ CLEANFILES = $(BUILT_SOURCES) # video-blend.h should be disted but not installed into the includedir libgstvideo_@GST_MAJORMINOR@_la_SOURCES = \ video.c gstvideosink.c gstvideofilter.c convertframe.c \ - video-blend.c video-blend.h + video-blend.c video-blend.h video-overlay-composition.c nodist_libgstvideo_@GST_MAJORMINOR@_la_SOURCES = \ $(built_sources) $(built_headers) \ $(ORC_NODIST_SOURCES) libgstvideo_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video libgstvideo_@GST_MAJORMINOR@include_HEADERS = \ - video.h gstvideosink.h gstvideofilter.h + video.h gstvideosink.h gstvideofilter.h video-overlay-composition.h nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS = $(built_headers) libgstvideo_@GST_MAJORMINOR@_la_CFLAGS = \ diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c new file mode 100644 index 0000000000..c3e75524d7 --- /dev/null +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -0,0 +1,940 @@ +/* GStreamer Video Overlay Composition + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Copyright (C) 2011 Tim-Philipp Müller + * + * 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:video-overlay-composition + * @short_description: Video Buffer Overlay Compositions (Subtitles, Logos) + * + * + * + * Functions to create and handle overlay compositions on video buffers. + * + * + * An overlay composition describes one or more overlay rectangles to be + * blended on top of a video buffer. + * + * + * This API serves two main purposes: + * + * + * it can be used to attach overlay information (subtitles or logos) + * to non-raw video buffers such as GL/VAAPI/VDPAU surfaces. The actual + * blending of the overlay can then be done by e.g. the video sink that + * processes these non-raw buffers. + * + * + * it can also be used to blend overlay rectangles on top of raw video + * buffers, thus consolidating blending functionality for raw video in + * one place. + * + * Together, this allows existing overlay elements to easily handle raw + * and non-raw video as input in without major changes (once the overlays + * have been put into a #GstOverlayComposition object anyway) - for raw + * video the overlay can just use the blending function to blend the data + * on top of the video, and for surface buffers it can just attach them to + * the buffer and let the sink render the overlays. + * + * + * + * + * Since: 0.10.36 + */ + +/* TODO: + * - provide accessors for seq_num and other fields (as needed) + * - allow overlay to set/get original pango markup string on/from rectangle + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "video-overlay-composition.h" +#include "video-blend.h" + +struct _GstVideoOverlayComposition +{ + GstMiniObject parent; + + guint num_rectangles; + GstVideoOverlayRectangle **rectangles; + + /* lowest rectangle sequence number still used by the upstream + * overlay element. This way a renderer maintaining some kind of + * rectangles <-> surface cache can know when to free cached + * surfaces/rectangles. */ + guint min_seq_num_used; + + /* sequence number for the composition (same series as rectangles) */ + guint seq_num; +}; + +struct _GstVideoOverlayCompositionClass +{ + GstMiniObjectClass parent_class; +}; + +struct _GstVideoOverlayRectangle +{ + GstMiniObject parent; + + /* Position on video frame and dimension of output rectangle in + * output frame terms (already adjusted for the PAR of the output + * frame). x/y can be negative (overlay will be clipped then) */ + gint x, y; + guint render_width, render_height; + + /* Dimensions of overlay pixels */ + guint width, height, stride; + + /* The format of the data in pixels */ + GstVideoFormat format; + + /* Refcounted blob of memory, no caps or timestamps */ + GstBuffer *pixels; + + /* FIXME: how to express source like text or pango markup? + * (just add source type enum + source buffer with data) + * + * FOR 0.10: always send pixel blobs, but attach source data in + * addition (reason: if downstream changes, we can't renegotiate + * that properly, if we just do a query of supported formats from + * the start). Sink will just ignore pixels and use pango markup + * from source data if it supports that. + * + * FOR 0.11: overlay should query formats (pango markup, pixels) + * supported by downstream and then only send that. We can + * renegotiate via the reconfigure event. + */ + + /* sequence number: useful for backends/renderers/sinks that want + * to maintain a cache of rectangles <-> surfaces. The value of + * the min_seq_num_used in the composition tells the renderer which + * rectangles have expired. */ + guint seq_num; + + /* FIXME: we may also need a (private) way to cache converted/scaled + * pixel blobs */ + GStaticMutex lock; + GList *scaled_rectangles; +}; + +struct _GstVideoOverlayRectangleClass +{ + GstMiniObjectClass parent_class; +}; + +static void gst_video_overlay_composition_class_init (GstMiniObjectClass * k); +static void gst_video_overlay_composition_finalize (GstMiniObject * comp); +static void gst_video_overlay_rectangle_class_init (GstMiniObjectClass * klass); +static void gst_video_overlay_rectangle_finalize (GstMiniObject * rect); + +/* --------------------------- utility functions --------------------------- */ + +#ifndef GST_DISABLE_GST_DEBUG + +#define GST_CAT_DEFAULT ensure_debug_category() + +static GstDebugCategory * +ensure_debug_category (void) +{ + static gsize cat_gonce = 0; + + if (g_once_init_enter (&cat_gonce)) { + gsize cat_done; + + cat_done = (gsize) _gst_debug_category_new ("video-composition", 0, + "video overlay composition"); + + g_once_init_leave (&cat_gonce, cat_done); + } + + return (GstDebugCategory *) cat_gonce; +} + +#else + +#define ensure_debug_category() /* NOOP */ + +#endif /* GST_DISABLE_GST_DEBUG */ + +static guint +gst_video_overlay_get_seqnum (void) +{ + static gint seqnum; /* 0 */ + +#if GLIB_CHECK_VERSION(2,29,5) + return (guint) g_atomic_int_add (&seqnum, 1); +#else + return (guint) g_atomic_int_exchange_and_add (&seqnum, 1); +#endif +} + +#define GST_OVERLAY_COMPOSITION_QUARK gst_overlay_composition_quark_get() +static GQuark +gst_overlay_composition_quark_get (void) +{ + static gsize quark_gonce = 0; + + if (g_once_init_enter (&quark_gonce)) { + gsize quark; + + quark = (gsize) g_quark_from_static_string ("GstVideoOverlayComposition"); + + g_once_init_leave (&quark_gonce, quark); + } + + return (GQuark) quark_gonce; +} + +#define COMPOSITION_QUARK composition_quark_get() +static GQuark +composition_quark_get (void) +{ + static gsize quark_gonce = 0; + + if (g_once_init_enter (&quark_gonce)) { + gsize quark; + + quark = (gsize) g_quark_from_static_string ("composition"); + + g_once_init_leave (&quark_gonce, quark); + } + + return (GQuark) quark_gonce; +} + +/** + * gst_video_buffer_set_overlay_composition: + * @buf: a #GstBuffer + * @comp: (allow-none): a #GstVideoOverlayComposition, or NULL to clear a + * previously-set composition + * + * Sets an overlay composition on a buffer. The buffer will obtain its own + * reference to the composition, meaning this function does not take ownership + * of @comp. + * + * Since: 0.10.36 + */ +void +gst_video_buffer_set_overlay_composition (GstBuffer * buf, + GstVideoOverlayComposition * comp) +{ + gst_buffer_set_qdata (buf, GST_OVERLAY_COMPOSITION_QUARK, + gst_structure_id_new (GST_OVERLAY_COMPOSITION_QUARK, + COMPOSITION_QUARK, GST_TYPE_VIDEO_OVERLAY_COMPOSITION, comp, NULL)); +} + +/** + * gst_video_buffer_get_overlay_composition: + * @buf: a #GstBuffer + * + * Get the overlay composition that has previously been attached to a buffer + * with gst_video_buffer_get_overlay_composition(), usually by another element + * upstream. + * + * Returns: (transfer none): the #GstVideoOverlayComposition attached to + * this buffer, or NULL. Does not return a reference to the composition, + * caller must obtain her own ref via gst_video_overlay_composition_ref() + * if needed. + * + * Since: 0.10.36 + */ +GstVideoOverlayComposition * +gst_video_buffer_get_overlay_composition (GstBuffer * buf) +{ + const GstStructure *s; + const GValue *val; + + s = gst_buffer_get_qdata (buf, GST_OVERLAY_COMPOSITION_QUARK); + if (s == NULL) + return NULL; + + val = gst_structure_id_get_value (s, COMPOSITION_QUARK); + if (val == NULL) + return NULL; + + return GST_VIDEO_OVERLAY_COMPOSITION (gst_value_get_mini_object (val)); +} + +/* ------------------------------ composition ------------------------------ */ + +#define RECTANGLE_ARRAY_STEP 4 /* premature optimization */ + +GType +gst_video_overlay_composition_get_type (void) +{ + static volatile gsize type_id = 0; + + if (g_once_init_enter (&type_id)) { + GType new_type_id = g_type_register_static_simple (GST_TYPE_MINI_OBJECT, + g_intern_static_string ("GstVideoOverlayComposition"), + sizeof (GstVideoOverlayCompositionClass), + (GClassInitFunc) gst_video_overlay_composition_class_init, + sizeof (GstVideoOverlayComposition), + NULL, + (GTypeFlags) 0); + + g_once_init_leave (&type_id, new_type_id); + } + + return type_id; +} + +static void +gst_video_overlay_composition_finalize (GstMiniObject * mini_obj) +{ + GstVideoOverlayComposition *comp = (GstVideoOverlayComposition *) mini_obj; + guint num; + + num = comp->num_rectangles; + + while (num > 0) { + gst_video_overlay_rectangle_unref (comp->rectangles[num - 1]); + --num; + } + + g_free (comp->rectangles); + comp->rectangles = NULL; + comp->num_rectangles = 0; + + /* not chaining up to GstMiniObject's finalize for now, we know it's empty */ +} + +static void +gst_video_overlay_composition_class_init (GstMiniObjectClass * klass) +{ + klass->finalize = gst_video_overlay_composition_finalize; + klass->copy = (GstMiniObjectCopyFunction) gst_video_overlay_composition_copy; +} + +/** + * gst_video_overlay_composition_new: + * @rectangle: (transfer none): a #GstVideoOverlayRectangle to add to the + * composition + * + * Creates a new video overlay composition object to hold one or more + * overlay rectangles. + * + * Returns: (transfer full): a new #GstVideoOverlayComposition. Unref with + * gst_video_overlay_composition_unref() when no longer needed. + * + * Since: 0.10.36 + */ +GstVideoOverlayComposition * +gst_video_overlay_composition_new (GstVideoOverlayRectangle * rectangle) +{ + GstVideoOverlayComposition *comp; + + + /* FIXME: should we allow empty compositions? Could also be expressed as + * buffer without a composition on it. Maybe there are cases where doing + * an empty new + _add() in a loop is easier? */ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL); + + comp = (GstVideoOverlayComposition *) + gst_mini_object_new (GST_TYPE_VIDEO_OVERLAY_COMPOSITION); + + comp->rectangles = g_new0 (GstVideoOverlayRectangle *, RECTANGLE_ARRAY_STEP); + comp->rectangles[0] = gst_video_overlay_rectangle_ref (rectangle); + comp->num_rectangles = 1; + + comp->seq_num = gst_video_overlay_get_seqnum (); + + /* since the rectangle was created earlier, its seqnum is smaller than ours */ + comp->min_seq_num_used = rectangle->seq_num; + + GST_LOG ("new composition %p: seq_num %u with rectangle %p", comp, + comp->seq_num, rectangle); + + return comp; +} + +/** + * gst_video_overlay_composition_add_rectangle: + * @comp: a #GstVideoOverlayComposition + * @rectangle: (transfer none): a #GstVideoOverlayRectangle to add to the + * composition + * + * Adds an overlay rectangle to an existing overlay composition object. This + * must be done right after creating the overlay composition. + * + * Since: 0.10.36 + */ +void +gst_video_overlay_composition_add_rectangle (GstVideoOverlayComposition * comp, + GstVideoOverlayRectangle * rectangle) +{ + g_return_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp)); + g_return_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle)); + g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (comp) == 1); + + if (comp->num_rectangles % RECTANGLE_ARRAY_STEP == 0) { + comp->rectangles = + g_renew (GstVideoOverlayRectangle *, comp->rectangles, + comp->num_rectangles + RECTANGLE_ARRAY_STEP); + } + + comp->rectangles[comp->num_rectangles] = + gst_video_overlay_rectangle_ref (rectangle); + comp->num_rectangles += 1; + + comp->min_seq_num_used = MIN (comp->min_seq_num_used, rectangle->seq_num); + + GST_LOG ("composition %p: added rectangle %p", comp, rectangle); +} + +/** + * gst_video_overlay_composition_n_rectangles: + * @comp: a #GstVideoOverlayComposition + * + * Returns the number of #GstVideoOverlayRectangles contained in @comp. + * + * Returns: the number of rectangles + * + * Since: 0.10.36 + */ +guint +gst_video_overlay_composition_n_rectangles (GstVideoOverlayComposition * comp) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), 0); + + return comp->num_rectangles; +} + +/** + * gst_video_overlay_composition_get_rectangle: + * @comp: a #GstVideoOverlayComposition + * @n: number of the rectangle to get + * + * Returns the @n-th #GstVideoOverlayRectangle contained in @comp. + * + * Returns: (transfer none): the @n-th rectangle, or NULL if @n is out of + * bounds. Will not return a new reference, the caller will need to + * obtain her own reference using gst_video_overlay_rectangle_ref() + * if needed. + * + * Since: 0.10.36 + */ +GstVideoOverlayRectangle * +gst_video_overlay_composition_get_rectangle (GstVideoOverlayComposition * comp, + guint n) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL); + + if (n >= comp->num_rectangles) + return NULL; + + return comp->rectangles[n]; +} + +static gboolean +gst_video_overlay_rectangle_needs_scaling (GstVideoOverlayRectangle * r) +{ + return (r->width != r->render_width || r->height != r->render_height); +} + +void +gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, + GstBuffer * video_buf) +{ + GstBlendVideoFormatInfo video_info, rectangle_info; + GstVideoFormat fmt; + guint n, num; + int w, h; + + g_return_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp)); + g_return_if_fail (GST_IS_BUFFER (video_buf)); + g_return_if_fail (gst_buffer_is_writable (video_buf)); + g_return_if_fail (GST_BUFFER_CAPS (video_buf) != NULL); + + if (!gst_video_format_parse_caps (GST_BUFFER_CAPS (video_buf), &fmt, &w, &h)) { + gchar *str = gst_caps_to_string (GST_BUFFER_CAPS (video_buf)); + g_warning ("%s: could not parse video buffer caps '%s'", GST_FUNCTION, str); + g_free (str); + return; + } + + video_blend_format_info_init (&video_info, GST_BUFFER_DATA (video_buf), + h, w, fmt); + + num = comp->num_rectangles; + GST_LOG ("Blending composition %p with %u rectangles onto video buffer %p " + "(%ux%u, format %u)", comp, num, video_buf, w, h, fmt); + + for (n = 0; n < num; ++n) { + GstVideoOverlayRectangle *rect; + gboolean needs_scaling; + + rect = comp->rectangles[n]; + + GST_LOG (" rectangle %u %p: %ux%u, format %u", n, rect, rect->height, + rect->width, rect->format); + + video_blend_format_info_init (&rectangle_info, + GST_BUFFER_DATA (rect->pixels), rect->height, rect->width, + rect->format); + + needs_scaling = gst_video_overlay_rectangle_needs_scaling (rect); + if (needs_scaling) { + video_blend_scale_linear_RGBA (&rectangle_info, rect->render_height, + rect->render_width); + } + + if (!video_blend (&video_info, &rectangle_info, rect->x, rect->y)) { + GST_WARNING ("Could not blend overlay rectangle onto video buffer"); + } + + /* FIXME: should cache scaled pixels in the rectangle struct */ + if (needs_scaling) + g_free (rectangle_info.pixels); + } +} + +/** + * gst_video_overlay_composition_copy: + * @comp: (transfer none): a #GstVideoOverlayComposition to copy + * + * Makes a copy of @comp and all contained rectangles, so that it is possible + * to modify the composition and contained rectangles (e.g. add additional + * rectangles or change the render co-ordinates or render dimension). The + * actual overlay pixel data buffers contained in the rectangles are not + * copied. + * + * Returns: (transfer full): a new #GstVideoOverlayComposition equivalent + * to @comp. + * + * Since: 0.10.36 + */ +GstVideoOverlayComposition * +gst_video_overlay_composition_copy (GstVideoOverlayComposition * comp) +{ + GstVideoOverlayComposition *copy; + GstVideoOverlayRectangle *rect; + guint n; + + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL); + + if (G_LIKELY (comp->num_rectangles == 0)) + return gst_video_overlay_composition_new (NULL); + + rect = gst_video_overlay_rectangle_copy (comp->rectangles[0]); + copy = gst_video_overlay_composition_new (rect); + gst_video_overlay_rectangle_unref (rect); + + for (n = 1; n < comp->num_rectangles; ++n) { + rect = gst_video_overlay_rectangle_copy (comp->rectangles[n]); + gst_video_overlay_composition_add_rectangle (copy, rect); + gst_video_overlay_rectangle_unref (rect); + } + + return copy; +} + +/** + * gst_video_overlay_composition_make_writable: + * @comp: (transfer full): a #GstVideoOverlayComposition to copy + * + * Takes ownership of @comp and returns a version of @comp that is writable + * (i.e. can be modified). Will either return @comp right away, or create a + * new writable copy of @comp and unref @comp itself. All the contained + * rectangles will also be copied, but the actual overlay pixel data buffers + * contained in the rectangles are not copied. + * + * Returns: (transfer full): a writable #GstVideoOverlayComposition + * equivalent to @comp. + * + * Since: 0.10.36 + */ +GstVideoOverlayComposition * +gst_video_overlay_composition_make_writable (GstVideoOverlayComposition * comp) +{ + GstVideoOverlayComposition *writable_comp; + + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL); + + if (GST_MINI_OBJECT_REFCOUNT_VALUE (comp) == 1) { + guint n; + + for (n = 0; n < comp->num_rectangles; ++n) { + if (GST_MINI_OBJECT_REFCOUNT_VALUE (comp->rectangles[n]) != 1) + goto copy; + } + return comp; + } + +copy: + + writable_comp = gst_video_overlay_composition_copy (comp); + gst_video_overlay_composition_unref (comp); + + return writable_comp; +} + +/* ------------------------------ rectangles ------------------------------ -*/ + +static void gst_video_overlay_rectangle_instance_init (GstMiniObject * miniobj); + +GType +gst_video_overlay_rectangle_get_type (void) +{ + static volatile gsize type_id = 0; + + if (g_once_init_enter (&type_id)) { + GType new_type_id = g_type_register_static_simple (GST_TYPE_MINI_OBJECT, + g_intern_static_string ("GstVideoOverlayRectangle"), + sizeof (GstVideoOverlayRectangleClass), + (GClassInitFunc) gst_video_overlay_rectangle_class_init, + sizeof (GstVideoOverlayRectangle), + (GInstanceInitFunc) gst_video_overlay_rectangle_instance_init, + (GTypeFlags) 0); + + g_once_init_leave (&type_id, new_type_id); + } + + return type_id; +} + +static void +gst_video_overlay_rectangle_finalize (GstMiniObject * mini_obj) +{ + GstVideoOverlayRectangle *rect = (GstVideoOverlayRectangle *) mini_obj; + + gst_buffer_replace (&rect->pixels, NULL); + + while (rect->scaled_rectangles != NULL) { + GstVideoOverlayRectangle *scaled_rect = rect->scaled_rectangles->data; + + gst_video_overlay_rectangle_unref (scaled_rect); + + rect->scaled_rectangles = + g_list_delete_link (rect->scaled_rectangles, rect->scaled_rectangles); + } + g_static_mutex_free (&rect->lock); + + /* not chaining up to GstMiniObject's finalize for now, we know it's empty */ +} + +static void +gst_video_overlay_rectangle_class_init (GstMiniObjectClass * klass) +{ + klass->finalize = gst_video_overlay_rectangle_finalize; + klass->copy = (GstMiniObjectCopyFunction) gst_video_overlay_rectangle_copy; +} + +static void +gst_video_overlay_rectangle_instance_init (GstMiniObject * mini_obj) +{ + GstVideoOverlayRectangle *rect = (GstVideoOverlayRectangle *) mini_obj; + + g_static_mutex_init (&rect->lock); +} + +/** + * gst_video_overlay_rectangle_new_argb: + * @pixels: (transfer none): a #GstBuffer pointing to the pixel memory + * @width: the width of the rectangle in @pixels + * @height: the height of the rectangle in @pixels + * @stride: the stride of the rectangle in @pixels in bytes (>= 4*width) + * @x: the X co-ordinate on the video where the top-left corner of this + * overlay rectangle should be rendered to + * @y: the Y co-ordinate on the video where the top-left corner of this + * overlay rectangle should be rendered to + * @render_width: the render width of this rectangle on the video + * @render_height: the render height of this rectangle on the video + * @flags: flags (currently unused) + * + * Creates a new video overlay rectangle with ARGB pixel data. The layout + * of the components in memory is B-G-R-A on little-endian platforms + * (corresponding to #GST_VIDEO_FORMAT_BGRA) and A-R-G-B on big-endian + * platforms (corresponding to #GST_VIDEO_FORMAT_ARGB). In other words, + * pixels are treated as 32-bit words and the lowest 8 bits then contain + * the blue component value and the highest 8 bits contain the alpha + * component value. The RGB values are non-premultiplied. This is the + * format that is used by most hardware, and also many rendering libraries + * such as Cairo, for example. + * + * Returns: (transfer full): a new #GstVideoOverlayRectangle. Unref with + * gst_video_overlay_rectangle_unref() when no longer needed. + * + * Since: 0.10.36 + */ +GstVideoOverlayRectangle * +gst_video_overlay_rectangle_new_argb (GstBuffer * pixels, + guint width, guint height, guint stride, gint render_x, gint render_y, + guint render_width, guint render_height, GstVideoOverlayFormatFlags flags) +{ + GstVideoOverlayRectangle *rect; + + g_return_val_if_fail (GST_IS_BUFFER (pixels), NULL); + /* technically ((height-1)*stride)+width might be okay too */ + g_return_val_if_fail (GST_BUFFER_SIZE (pixels) >= height * stride, NULL); + g_return_val_if_fail (stride >= (4 * width), NULL); + g_return_val_if_fail (height > 0 && width > 0, NULL); + g_return_val_if_fail (render_height > 0 && render_width > 0, NULL); + g_return_val_if_fail (flags == 0, NULL); + + rect = (GstVideoOverlayRectangle *) + gst_mini_object_new (GST_TYPE_VIDEO_OVERLAY_RECTANGLE); + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + rect->format = GST_VIDEO_FORMAT_BGRA; +#else + rect->format = GST_VIDEO_FORMAT_ARGB; +#endif + rect->pixels = gst_buffer_ref (pixels); + + rect->width = width; + rect->height = height; + rect->stride = stride; + + rect->x = render_x; + rect->y = render_y; + rect->render_width = render_width; + rect->render_height = render_height; + + rect->seq_num = gst_video_overlay_get_seqnum (); + + GST_LOG ("new rectangle %p: %ux%u => %ux%u @ %u,%u, seq_num %u, format %u, " + "pixels %p", rect, width, height, render_width, render_height, render_x, + render_y, rect->seq_num, rect->format, pixels); + + return rect; +} + +/** + * gst_video_overlay_rectangle_get_render_rectangle: + * @rectangle: a #GstVideoOverlayRectangle + * @render_x: (out) (allow-none): address where to store the X render offset + * @render_y: (out) (allow-none): address where to store the Y render offset + * @render_width: (out) (allow-none): address where to store the render width + * @render_height: (out) (allow-none): address where to store the render height + * + * Retrieves the render position and render dimension of the overlay + * rectangle on the video. + * + * Returns: TRUE if valid render dimensions were retrieved. + * + * Since: 0.10.36 + */ +gboolean +gst_video_overlay_rectangle_get_render_rectangle (GstVideoOverlayRectangle * + rectangle, gint * render_x, gint * render_y, guint * render_width, + guint * render_height) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), FALSE); + + if (render_x) + *render_x = rectangle->x; + if (render_y) + *render_y = rectangle->y; + if (render_width) + *render_width = rectangle->render_width; + if (render_height) + *render_height = rectangle->render_height; + + return TRUE; +} + +/** + * gst_video_overlay_rectangle_set_render_rectangle: + * @rectangle: a #GstVideoOverlayRectangle + * @render_x: render X position of rectangle on video + * @render_y: render Y position of rectangle on video + * @render_width: render width of rectangle + * @render_height: render height of rectangle + * + * Sets the render position and dimensions of the rectangle on the video. + * This function is mainly for elements that modify the size of the video + * in some way (e.g. through scaling or cropping) and need to adjust the + * details of any overlays to match the operation that changed the size. + * + * @rectangle must be writable, meaning its refcount must be 1. You can + * make the rectangles inside a #GstVideoOverlayComposition writable using + * gst_video_overlay_composition_make_writable() or + * gst_video_overlay_composition_copy(). + * + * Since: 0.10.36 + */ +void +gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle * + rectangle, gint render_x, gint render_y, guint render_width, + guint render_height) +{ + g_return_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle)); + g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (rectangle) == 1); + + rectangle->x = render_x; + rectangle->y = render_y; + rectangle->render_width = render_width; + rectangle->render_height = render_height; +} + +/** + * gst_video_overlay_rectangle_get_pixels_argb: + * @rectangle: a #GstVideoOverlayRectangle + * @stride: (out) (allow-none): address of guint variable where to store the + * row stride of the ARGB pixel data in the buffer + * @flags: flags (unused) + * + * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with + * row stride @stride and width and height of the render dimensions as per + * gst_video_overlay_rectangle_get_render_rectangle(). This function does + * not return a reference, the caller should obtain a reference of her own + * with gst_buffer_ref() if needed. + * + * Since: 0.10.36 + */ +GstBuffer * +gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * + rectangle, guint * stride, GstVideoOverlayFormatFlags flags) +{ + GstVideoOverlayRectangle *scaled_rect = NULL; + GstBlendVideoFormatInfo info; + GstBuffer *buf; + GList *l; + + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL); + g_return_val_if_fail (flags == 0, NULL); + g_return_val_if_fail (stride != NULL, NULL); + + /* This assumes we don't need to adjust the format */ + if (rectangle->render_width == rectangle->width && + rectangle->render_height == rectangle->height) { + *stride = rectangle->stride; + return rectangle->pixels; + } + + /* see if we've got one cached already */ + g_static_mutex_lock (&rectangle->lock); + for (l = rectangle->scaled_rectangles; l != NULL; l = l->next) { + GstVideoOverlayRectangle *r = l->data; + + if (r->width == rectangle->render_width && + r->height == rectangle->render_height) { + /* we'll keep these rectangles around until finalize, so it's ok not + * to take our own ref here */ + scaled_rect = r; + break; + } + } + g_static_mutex_unlock (&rectangle->lock); + + if (scaled_rect != NULL) + goto done; + + /* not cached yet, do the scaling and put the result into our cache */ + video_blend_format_info_init (&info, GST_BUFFER_DATA (rectangle->pixels), + rectangle->height, rectangle->width, rectangle->format); + + video_blend_scale_linear_RGBA (&info, rectangle->render_height, + rectangle->render_width); + + buf = gst_buffer_new (); + GST_BUFFER_DATA (buf) = info.pixels; + GST_BUFFER_MALLOCDATA (buf) = info.pixels; + GST_BUFFER_SIZE (buf) = info.size; + + scaled_rect = gst_video_overlay_rectangle_new_argb (buf, + rectangle->render_width, rectangle->render_height, info.stride[0], + 0, 0, rectangle->render_width, rectangle->render_height, 0); + + gst_buffer_unref (buf); + + g_static_mutex_lock (&rectangle->lock); + rectangle->scaled_rectangles = + g_list_prepend (rectangle->scaled_rectangles, scaled_rect); + g_static_mutex_unlock (&rectangle->lock); + +done: + + *stride = scaled_rect->stride; + return scaled_rect->pixels; +} + +/** + * gst_video_overlay_rectangle_get_pixels_unscaled_argb: + * @rectangle: a #GstVideoOverlayRectangle + * @width: (out): address where to store the width of the unscaled + * rectangle in pixels + * @width: (out): address where to store the height of the unscaled + * rectangle in pixels + * @stride: (out): address of guint variable where to store the row + * stride of the ARGB pixel data in the buffer + * @flags: flags for future use (unused) + * + * Retrieves the pixel data as it is. This is useful if the caller can + * do the scaling itself when handling the overlaying. The rectangle will + * need to be scaled to the render dimensions, which can be retrieved using + * gst_video_overlay_rectangle_get_render_rectangle(). + * + * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with + * row stride @stride. This function does not return a reference, the caller + * should obtain a reference of her own with gst_buffer_ref() if needed. + * + * Since: 0.10.36 + */ +GstBuffer * +gst_video_overlay_rectangle_get_pixels_unscaled_argb (GstVideoOverlayRectangle * + rectangle, guint * width, guint * height, guint * stride, + GstVideoOverlayFormatFlags flags) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL); + g_return_val_if_fail (width != NULL, NULL); + g_return_val_if_fail (height != NULL, NULL); + g_return_val_if_fail (stride != NULL, NULL); + g_return_val_if_fail (flags == 0, NULL); + + *width = rectangle->width; + *height = rectangle->height; + *stride = rectangle->stride; + + return rectangle->pixels; +} + +/** + * gst_video_overlay_rectangle_copy: + * @rectangle: (transfer none): a #GstVideoOverlayRectangle to copy + * + * Makes a copy of @rectangle, so that it is possible to modify it + * (e.g. to change the render co-ordinates or render dimension). The + * actual overlay pixel data buffers contained in the rectangle are not + * copied. + * + * Returns: (transfer full): a new #GstVideoOverlayRectangle equivalent + * to @rectangle. + * + * Since: 0.10.36 + */ +GstVideoOverlayRectangle * +gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle) +{ + GstVideoOverlayRectangle *copy; + + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL); + + copy = gst_video_overlay_rectangle_new_argb (rectangle->pixels, + rectangle->width, rectangle->height, rectangle->stride, + rectangle->x, rectangle->y, + rectangle->render_width, rectangle->render_height, 0); + + return copy; +} diff --git a/gst-libs/gst/video/video-overlay-composition.h b/gst-libs/gst/video/video-overlay-composition.h new file mode 100644 index 0000000000..9b6c3ca114 --- /dev/null +++ b/gst-libs/gst/video/video-overlay-composition.h @@ -0,0 +1,231 @@ +/* GStreamer Video Overlay Composition + * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011 Collabora Ltd. + * Copyright (C) 2011 Tim-Philipp Müller + * + * 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_VIDEO_OVERLAY_COMPOSITION_H__ +#define __GST_VIDEO_OVERLAY_COMPOSITION_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * GstVideoOverlayRectangle: + * + * An opaque video overlay rectangle object. A rectangle contains a single + * overlay rectangle which can be added to a composition. + * + * Since: 0.10.36 + */ +#define GST_TYPE_VIDEO_OVERLAY_RECTANGLE \ + (gst_video_overlay_rectangle_get_type ()) +#define GST_VIDEO_OVERLAY_RECTANGLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_OVERLAY_RECTANGLE, GstVideoOverlayRectangle)) +#define GST_IS_VIDEO_OVERLAY_RECTANGLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_OVERLAY_RECTANGLE)) + +typedef struct _GstVideoOverlayRectangle GstVideoOverlayRectangle; +typedef struct _GstVideoOverlayRectangleClass GstVideoOverlayRectangleClass; + +/** + * gst_video_overlay_rectangle_ref: + * @comp: a a #GstVideoOverlayRectangle. + * + * Increases the refcount of the given rectangle by one. + * + * Note that the refcount affects the writeability + * of @comp, use gst_video_overlay_rectangle_copy() to ensure a rectangle can + * be modified (there is no gst_video_overlay_rectangle_make_writable() because + * it is unlikely that someone will hold the single reference to the rectangle + * and not know that that's the case). + * + * Returns: (transfer full): @comp + * + * Since: 0.10.36 + */ +#ifdef _FOOL_GTK_DOC_ +G_INLINE_FUNC GstVideoOverlayRectangle * +gst_video_overlay_rectangle_ref (GstVideoOverlayRectangle * comp); +#endif + +static inline GstVideoOverlayRectangle * +gst_video_overlay_rectangle_ref (GstVideoOverlayRectangle * comp) +{ + return (GstVideoOverlayRectangle *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (comp)); +} + +/** + * gst_video_overlay_rectangle_unref: + * @comp: (transfer full): a #GstVideoOverlayRectangle. + * + * Decreases the refcount of the rectangle. If the refcount reaches 0, the + * rectangle will be freed. + * + * Since: 0.10.36 + */ +#ifdef _FOOL_GTK_DOC_ +G_INLINE_FUNC void +gst_video_overlay_rectangle_unref (GstVideoOverlayRectangle * comp); +#endif + +static inline void +gst_video_overlay_rectangle_unref (GstVideoOverlayRectangle * comp) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (comp)); +} + +/** + * GstVideoOverlayFormatFlags: + * @GST_VIDEO_OVERLAY_RECTANGLE_FLAG_NONE: no flags + * + * Overlay format flags. + * + * Since: 0.10.36 + */ +typedef enum { + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE = 0 +} GstVideoOverlayFormatFlags; + +GType gst_video_overlay_rectangle_get_type (void); + +GstVideoOverlayRectangle * gst_video_overlay_rectangle_new_argb (GstBuffer * pixels, + guint width, guint height, guint stride, + gint render_x, gint render_y, + guint render_width, guint render_height, + GstVideoOverlayFormatFlags flags); + +GstVideoOverlayRectangle * gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle); + +void gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle * rectangle, + gint render_x, + gint render_y, + guint render_width, + guint render_height); + +gboolean gst_video_overlay_rectangle_get_render_rectangle (GstVideoOverlayRectangle * rectangle, + gint * render_x, + gint * render_y, + guint * render_width, + guint * render_height); + +GstBuffer * gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * rectangle, + guint * stride, + GstVideoOverlayFormatFlags flags); + +GstBuffer * gst_video_overlay_rectangle_get_pixels_unscaled_argb (GstVideoOverlayRectangle * rectangle, + guint * width, + guint * height, + guint * stride, + GstVideoOverlayFormatFlags flags); + +/** + * GstVideoOverlayComposition: + * + * An opaque video overlay composition object. A composition contains + * multiple overlay rectangles. + * + * Since: 0.10.36 + */ +#define GST_TYPE_VIDEO_OVERLAY_COMPOSITION \ + (gst_video_overlay_composition_get_type ()) +#define GST_VIDEO_OVERLAY_COMPOSITION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_OVERLAY_COMPOSITION, GstVideoOverlayComposition)) +#define GST_IS_VIDEO_OVERLAY_COMPOSITION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_OVERLAY_COMPOSITION)) + +typedef struct _GstVideoOverlayComposition GstVideoOverlayComposition; +typedef struct _GstVideoOverlayCompositionClass GstVideoOverlayCompositionClass; + +/** + * gst_video_overlay_composition_ref: + * @comp: a a #GstVideoOverlayComposition. + * + * Increases the refcount of the given composition by one. + * + * Note that the refcount affects the writeability + * of @comp, use gst_video_overlay_composition_make_writable() to ensure + * a composition and its rectangles can be modified. + * + * Returns: (transfer full): @comp + * + * Since: 0.10.36 + */ +#ifdef _FOOL_GTK_DOC_ +G_INLINE_FUNC GstVideoOverlayComposition * +gst_video_overlay_composition_ref (GstVideoOverlayComposition * comp); +#endif + +static inline GstVideoOverlayComposition * +gst_video_overlay_composition_ref (GstVideoOverlayComposition * comp) +{ + return (GstVideoOverlayComposition *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (comp)); +} + +/** + * gst_video_overlay_composition_unref: + * @comp: (transfer full): a #GstVideoOverlayComposition. + * + * Decreases the refcount of the composition. If the refcount reaches 0, the + * composition will be freed. + * + * Since: 0.10.36 + */ +#ifdef _FOOL_GTK_DOC_ +G_INLINE_FUNC void +gst_video_overlay_composition_unref (GstVideoOverlayComposition * comp); +#endif + +static inline void +gst_video_overlay_composition_unref (GstVideoOverlayComposition * comp) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (comp)); +} + +GType gst_video_overlay_composition_get_type (void); + +GstVideoOverlayComposition * gst_video_overlay_composition_copy (GstVideoOverlayComposition * comp); + +GstVideoOverlayComposition * gst_video_overlay_composition_make_writable (GstVideoOverlayComposition * comp); + +GstVideoOverlayComposition * gst_video_overlay_composition_new (GstVideoOverlayRectangle * rectangle); + +void gst_video_overlay_composition_add_rectangle (GstVideoOverlayComposition * comp, + GstVideoOverlayRectangle * rectangle); + +guint gst_video_overlay_composition_n_rectangles (GstVideoOverlayComposition * comp); + +GstVideoOverlayRectangle * gst_video_overlay_composition_get_rectangle (GstVideoOverlayComposition * comp, guint n); + +/* blend composition onto raw video buffer */ + +void gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, + GstBuffer * video_buf); + +/* attach/retrieve composition from buffers */ + +void gst_video_buffer_set_overlay_composition (GstBuffer * buf, + GstVideoOverlayComposition * comp); + +GstVideoOverlayComposition * gst_video_buffer_get_overlay_composition (GstBuffer * buf); + +G_END_DECLS + +#endif /* __GST_VIDEO_OVERLAY_COMPOSITION_H__ */ diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index 4e2e592991..fee972a2f3 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -1,4 +1,6 @@ EXPORTS + gst_video_buffer_get_overlay_composition + gst_video_buffer_set_overlay_composition gst_video_calculate_display_ratio gst_video_convert_frame gst_video_convert_frame_async @@ -33,6 +35,21 @@ EXPORTS gst_video_frame_rate gst_video_get_size gst_video_get_size_from_caps + gst_video_overlay_composition_add_rectangle + gst_video_overlay_composition_blend + gst_video_overlay_composition_copy + gst_video_overlay_composition_get_rectangle + gst_video_overlay_composition_get_type + gst_video_overlay_composition_make_writable + gst_video_overlay_composition_n_rectangles + gst_video_overlay_composition_new + gst_video_overlay_rectangle_copy + gst_video_overlay_rectangle_get_pixels_argb + gst_video_overlay_rectangle_get_pixels_unscaled_argb + gst_video_overlay_rectangle_get_render_rectangle + gst_video_overlay_rectangle_get_type + gst_video_overlay_rectangle_new_argb + gst_video_overlay_rectangle_set_render_rectangle gst_video_parse_caps_chroma_site gst_video_parse_caps_color_matrix gst_video_parse_caps_framerate From 00d6ffd9f56e6ce636f7d61bc1ab2e9ff1227889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 25 Nov 2011 16:46:09 +0000 Subject: [PATCH 15/31] tests: add basic unit test for video overlay composition and rectangles --- tests/check/libs/video.c | 128 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index 47327d4825..bd9674a0cc 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -2,7 +2,7 @@ * * Copyright (C) <2003> David A. Schleef * Copyright (C) <2006> Jan Schmidt - * Copyright (C) <2008> Tim-Philipp Müller + * Copyright (C) <2008,2011> Tim-Philipp Müller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,6 +29,7 @@ #include #include +#include #include /* These are from the current/old videotestsrc; we check our new public API @@ -774,6 +775,130 @@ GST_START_TEST (test_video_size_from_caps) GST_END_TEST; +#undef ASSERT_CRITICAL +#define ASSERT_CRITICAL(code) while(0){} /* nothing */ + +GST_START_TEST (test_overlay_composition) +{ + GstVideoOverlayComposition *comp1, *comp2; + GstVideoOverlayRectangle *rect1, *rect2; + GstBuffer *pix1, *pix2, *buf; + guint w, h, stride; + gint x, y; + + pix1 = gst_buffer_new_and_alloc (200 * sizeof (guint32) * 50); + memset (GST_BUFFER_DATA (pix1), 0, GST_BUFFER_SIZE (pix1)); + + rect1 = gst_video_overlay_rectangle_new_argb (pix1, 200, 50, 200 * 4, + 600, 50, 300, 50, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + gst_buffer_unref (pix1); + pix1 = NULL; + + comp1 = gst_video_overlay_composition_new (rect1); + fail_unless (gst_video_overlay_composition_n_rectangles (comp1) == 1); + fail_unless (gst_video_overlay_composition_get_rectangle (comp1, 0) == rect1); + fail_unless (gst_video_overlay_composition_get_rectangle (comp1, 1) == NULL); + + /* composition took own ref, so refcount is 2 now, so this should fail */ + ASSERT_CRITICAL (gst_video_overlay_rectangle_set_render_rectangle (rect1, 50, + 600, 300, 50)); + + /* drop our ref, so refcount is 1 (we know it will continue to be valid) */ + gst_video_overlay_rectangle_unref (rect1); + gst_video_overlay_rectangle_set_render_rectangle (rect1, 50, 600, 300, 50); + + comp2 = gst_video_overlay_composition_new (rect1); + fail_unless (gst_video_overlay_composition_n_rectangles (comp2) == 1); + fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 0) == rect1); + fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 1) == NULL); + + /* now refcount is 2 again because comp2 has also taken a ref, so must fail */ + ASSERT_CRITICAL (gst_video_overlay_rectangle_set_render_rectangle (rect1, 0, + 0, 1, 1)); + + /* this should make a copy of the rectangles so drop the original + * second ref on rect1 */ + comp2 = gst_video_overlay_composition_make_writable (comp2); + gst_video_overlay_rectangle_set_render_rectangle (rect1, 51, 601, 301, 51); + + rect2 = gst_video_overlay_composition_get_rectangle (comp2, 0); + fail_unless (gst_video_overlay_composition_n_rectangles (comp2) == 1); + fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 0) == rect2); + fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 1) == NULL); + fail_unless (rect1 != rect2); + + gst_video_overlay_composition_add_rectangle (comp1, rect2); + gst_video_overlay_composition_ref (comp1); + ASSERT_CRITICAL (gst_video_overlay_composition_add_rectangle (comp1, rect2)); + gst_video_overlay_composition_unref (comp1); + + /* make sure the copy really worked */ + gst_video_overlay_rectangle_get_render_rectangle (rect1, &x, &y, &w, &h); + fail_unless_equals_int (x, 51); + fail_unless_equals_int (y, 601); + fail_unless_equals_int (w, 301); + fail_unless_equals_int (h, 51); + + /* get scaled pixbuf and touch last byte */ + pix1 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + + gst_video_overlay_rectangle_get_render_rectangle (rect2, &x, &y, &w, &h); + fail_unless_equals_int (x, 50); + fail_unless_equals_int (y, 600); + fail_unless_equals_int (w, 300); + fail_unless_equals_int (h, 50); + + /* get scaled pixbuf and touch last byte */ + pix2 = gst_video_overlay_rectangle_get_pixels_argb (rect2, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + + /* get scaled pixbuf again, should be the same buffer as before (caching) */ + pix1 = gst_video_overlay_rectangle_get_pixels_argb (rect2, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless (pix1 == pix2); + + /* now compare the original unscaled ones */ + pix1 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w, &h, + &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + pix2 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect2, &w, &h, + &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + /* the original pixel buffers should be identical */ + fail_unless (pix1 == pix2); + fail_unless_equals_int (w, 200); + fail_unless_equals_int (h, 50); + + /* touch last byte */ + fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + + /* test attaching and retrieving of compositions to/from buffers */ + buf = gst_buffer_new (); + fail_unless (gst_video_buffer_get_overlay_composition (buf) == NULL); + + gst_buffer_ref (buf); + ASSERT_CRITICAL (gst_video_buffer_set_overlay_composition (buf, comp1)); + gst_buffer_unref (buf); + gst_video_buffer_set_overlay_composition (buf, comp1); + fail_unless (gst_video_buffer_get_overlay_composition (buf) == comp1); + gst_video_buffer_set_overlay_composition (buf, comp2); + fail_unless (gst_video_buffer_get_overlay_composition (buf) == comp2); + gst_video_buffer_set_overlay_composition (buf, NULL); + fail_unless (gst_video_buffer_get_overlay_composition (buf) == NULL); + + /* make sure the buffer cleans up its composition ref when unreffed */ + gst_video_buffer_set_overlay_composition (buf, comp2); + gst_buffer_unref (buf); + + gst_video_overlay_composition_unref (comp2); + gst_video_overlay_composition_unref (comp1); +} + +GST_END_TEST; + static Suite * video_suite (void) { @@ -790,6 +915,7 @@ video_suite (void) tcase_add_test (tc_chain, test_convert_frame); tcase_add_test (tc_chain, test_convert_frame_async); tcase_add_test (tc_chain, test_video_size_from_caps); + tcase_add_test (tc_chain, test_overlay_composition); return s; } From a018c187a0b6ad1010d8b9142e4606b069f0c55c Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 16 Nov 2011 17:54:43 -0300 Subject: [PATCH 16/31] textoverlay: Make use of the new video blending utility --- ext/pango/gsttextoverlay.c | 671 +++++-------------------------------- ext/pango/gsttextoverlay.h | 95 +++--- 2 files changed, 137 insertions(+), 629 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 76b8f7448b..65d363ae72 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -133,36 +133,6 @@ GST_DEBUG_CATEGORY (pango_debug); #define MINIMUM_OUTLINE_OFFSET 1.0 #define DEFAULT_SCALE_BASIS 640 -#define COMP_Y(ret, r, g, b) \ -{ \ - ret = (int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); \ - ret = CLAMP (ret, 0, 255); \ -} - -#define COMP_U(ret, r, g, b) \ -{ \ - ret = (int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + 128); \ - ret = CLAMP (ret, 0, 255); \ -} - -#define COMP_V(ret, r, g, b) \ -{ \ - ret = (int) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + 128); \ - ret = CLAMP (ret, 0, 255); \ -} - -#define BLEND(ret, alpha, v0, v1) \ -{ \ - ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \ -} - -#define OVER(ret, alphaA, Ca, alphaB, Cb, alphaNew) \ -{ \ - gint _tmp; \ - _tmp = (Ca * alphaA + Cb * alphaB * (255 - alphaA) / 255) / alphaNew; \ - ret = CLAMP (_tmp, 0, 255); \ -} - #if G_BYTE_ORDER == G_LITTLE_ENDIAN # define CAIRO_ARGB_A 3 # define CAIRO_ARGB_R 2 @@ -596,6 +566,11 @@ gst_text_overlay_finalize (GObject * object) g_free (overlay->default_text); + if (overlay->composition) { + gst_video_overlay_composition_unref (overlay->composition); + overlay->composition = NULL; + } + if (overlay->text_image) { g_free (overlay->text_image); overlay->text_image = NULL; @@ -702,7 +677,7 @@ gst_text_overlay_init (GstTextOverlay * overlay, GstTextOverlayClass * klass) overlay->default_text = g_strdup (DEFAULT_PROP_TEXT); overlay->need_render = TRUE; - overlay->text_image = NULL; + overlay->composition = NULL; overlay->use_vertical_render = DEFAULT_PROP_VERTICAL_RENDER; gst_text_overlay_update_render_mode (overlay); @@ -1178,154 +1153,98 @@ gst_text_overlay_adjust_values_with_fontdesc (GstTextOverlay * overlay, g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \ r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \ } G_STMT_END - -static inline void -gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos, - gint ypos, guchar * text_image, guint dest_stride) +static void +gst_text_overlay_get_pos (GstTextOverlay * overlay, gint * xpos, gint * ypos) { - gint i, j = 0; - gint x, y; - guchar r, g, b, a; - guchar *pimage; - guchar *py; - gint width = overlay->image_width; - gint height = overlay->image_height; + gint width, height; + GstTextOverlayVAlign valign; + GstTextOverlayHAlign halign; - if (xpos < 0) { - xpos = 0; + width = overlay->image_width; + height = overlay->image_height; + + if (overlay->use_vertical_render) + halign = GST_TEXT_OVERLAY_HALIGN_RIGHT; + else + halign = overlay->halign; + + switch (halign) { + case GST_TEXT_OVERLAY_HALIGN_LEFT: + *xpos = overlay->xpad; + break; + case GST_TEXT_OVERLAY_HALIGN_CENTER: + *xpos = (overlay->width - width) / 2; + break; + case GST_TEXT_OVERLAY_HALIGN_RIGHT: + *xpos = overlay->width - width - overlay->xpad; + break; + case GST_TEXT_OVERLAY_HALIGN_POS: + *xpos = (gint) (overlay->width * overlay->xpos) - width / 2; + *xpos = CLAMP (*xpos, 0, overlay->width - width); + if (*xpos < 0) + *xpos = 0; + break; + default: + *xpos = 0; } + *xpos += overlay->deltax; - if (xpos + width > overlay->width) { - width = overlay->width - xpos; - } - - if (ypos + height > overlay->height) { - height = overlay->height - ypos; - } - - dest += (ypos / 1) * dest_stride; - - for (i = 0; i < height; i++) { - pimage = text_image + 4 * (i * overlay->image_width); - py = dest + i * dest_stride + xpos; - for (j = 0; j < width; j++) { - b = pimage[CAIRO_ARGB_B]; - g = pimage[CAIRO_ARGB_G]; - r = pimage[CAIRO_ARGB_R]; - a = pimage[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a, r, g, b); - - pimage += 4; - if (a == 0) { - py++; - continue; - } - COMP_Y (y, r, g, b); - x = *py; - BLEND (*py++, a, y, x); - } + if (overlay->use_vertical_render) + valign = GST_TEXT_OVERLAY_VALIGN_TOP; + else + valign = overlay->valign; + + switch (valign) { + case GST_TEXT_OVERLAY_VALIGN_BOTTOM: + *ypos = overlay->height - height - overlay->ypad; + break; + case GST_TEXT_OVERLAY_VALIGN_BASELINE: + *ypos = overlay->height - (height + overlay->ypad); + break; + case GST_TEXT_OVERLAY_VALIGN_TOP: + *ypos = overlay->ypad; + break; + case GST_TEXT_OVERLAY_VALIGN_POS: + *ypos = (gint) (overlay->height * overlay->ypos) - height / 2; + *ypos = CLAMP (*ypos, 0, overlay->height - height); + break; + case GST_TEXT_OVERLAY_VALIGN_CENTER: + *ypos = (overlay->height - height) / 2; + break; + default: + *ypos = overlay->ypad; + break; } + *ypos += overlay->deltay; } static inline void -gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay, - guchar * destcb, guchar * destcr, gint xpos, gint ypos, guchar * text_image, - guint destcb_stride, guint destcr_stride, guint pix_stride) +gst_text_overlay_set_composition (GstTextOverlay * overlay) { - gint i, j; - gint x, cb, cr; - gushort r, g, b, a; - gushort r1, g1, b1, a1; - guchar *pimage1, *pimage2; - guchar *pcb, *pcr; - gint width = overlay->image_width - 2; - gint height = overlay->image_height - 2; + gint xpos, ypos; + GstVideoOverlayRectangle *rectangle; - xpos *= pix_stride; + gst_text_overlay_get_pos (overlay, &xpos, &ypos); - if (xpos < 0) { - xpos = 0; - } + if (overlay->text_image) { + GstBuffer *buffer = gst_buffer_new (); - if (xpos + width > overlay->width) { - width = overlay->width - xpos; - } + GST_BUFFER_DATA (buffer) = overlay->text_image; + GST_BUFFER_SIZE (buffer) = gst_video_format_get_size (GST_VIDEO_FORMAT_ARGB, + overlay->image_width, overlay->image_height); - if (ypos + height > overlay->height) { - height = overlay->height - ypos; - } + rectangle = gst_video_overlay_rectangle_new_argb (buffer, + overlay->image_width, overlay->image_height, 4 * overlay->image_width, + 1, 1, xpos, ypos, overlay->image_width, overlay->image_height); - destcb += (ypos / 2) * destcb_stride; - destcr += (ypos / 2) * destcr_stride; + if (overlay->composition) + gst_video_overlay_composition_unref (overlay->composition); + overlay->composition = gst_video_overlay_composition_new (rectangle); + gst_video_overlay_rectangle_unref (rectangle); - for (i = 0; i < height; i += 2) { - pimage1 = text_image + 4 * (i * overlay->image_width); - pimage2 = pimage1 + 4 * overlay->image_width; - pcb = destcb + (i / 2) * destcb_stride + xpos / 2; - pcr = destcr + (i / 2) * destcr_stride + xpos / 2; - for (j = 0; j < width; j += 2) { - b = pimage1[CAIRO_ARGB_B]; - g = pimage1[CAIRO_ARGB_G]; - r = pimage1[CAIRO_ARGB_R]; - a = pimage1[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a, r, g, b); - pimage1 += 4; - - b1 = pimage1[CAIRO_ARGB_B]; - g1 = pimage1[CAIRO_ARGB_G]; - r1 = pimage1[CAIRO_ARGB_R]; - a1 = pimage1[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a1, r1, g1, b1); - b += b1; - g += g1; - r += r1; - a += a1; - pimage1 += 4; - - b1 = pimage2[CAIRO_ARGB_B]; - g1 = pimage2[CAIRO_ARGB_G]; - r1 = pimage2[CAIRO_ARGB_R]; - a1 = pimage2[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a1, r1, g1, b1); - b += b1; - g += g1; - r += r1; - a += a1; - pimage2 += 4; - - /* + 2 for rounding */ - b1 = pimage2[CAIRO_ARGB_B]; - g1 = pimage2[CAIRO_ARGB_G]; - r1 = pimage2[CAIRO_ARGB_R]; - a1 = pimage2[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a1, r1, g1, b1); - b += b1 + 2; - g += g1 + 2; - r += r1 + 2; - a += a1 + 2; - pimage2 += 4; - - b /= 4; - g /= 4; - r /= 4; - a /= 4; - - if (a == 0) { - pcb += pix_stride; - pcr += pix_stride; - continue; - } - COMP_U (cb, r, g, b); - COMP_V (cr, r, g, b); - - x = *pcb; - BLEND (*pcb, a, cb, x); - x = *pcr; - BLEND (*pcr, a, cr, x); - - pcb += pix_stride; - pcr += pix_stride; - } + } else if (overlay->composition) { + gst_video_overlay_composition_unref (overlay->composition); + overlay->composition = NULL; } } @@ -1477,6 +1396,8 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay, overlay->baseline_y = ink_rect.y; g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock); + + gst_text_overlay_set_composition (overlay); } #define BOX_XPAD 6 @@ -1607,307 +1528,6 @@ ARGB_SHADE_FUNCTION (RGBA, 0); ARGB_SHADE_FUNCTION (BGRA, 0); -/* FIXME: - * - use proper strides and offset for I420 - * - don't draw over the edge of the picture (try a longer - * text with a huge font size) - */ - -static inline void -gst_text_overlay_blit_NV12_NV21 (GstTextOverlay * overlay, - guint8 * yuv_pixels, gint xpos, gint ypos) -{ - int y_stride, uv_stride; - int u_offset, v_offset; - int h, w; - - /* because U/V is 2x2 subsampled, we need to round, either up or down, - * to a boundary of integer number of U/V pixels: - */ - xpos = GST_ROUND_UP_2 (xpos); - ypos = GST_ROUND_UP_2 (ypos); - - w = overlay->width; - h = overlay->height; - - y_stride = gst_video_format_get_row_stride (overlay->format, 0, w); - uv_stride = gst_video_format_get_row_stride (overlay->format, 1, w); - u_offset = gst_video_format_get_component_offset (overlay->format, 1, w, h); - v_offset = gst_video_format_get_component_offset (overlay->format, 2, w, h); - - gst_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos, overlay->text_image, - y_stride); - gst_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset, - yuv_pixels + v_offset, xpos, ypos, overlay->text_image, uv_stride, - uv_stride, 2); -} - -static inline void -gst_text_overlay_blit_I420_YV12 (GstTextOverlay * overlay, - guint8 * yuv_pixels, gint xpos, gint ypos) -{ - int y_stride, u_stride, v_stride; - int u_offset, v_offset; - int h, w; - - /* because U/V is 2x2 subsampled, we need to round, either up or down, - * to a boundary of integer number of U/V pixels: - */ - xpos = GST_ROUND_UP_2 (xpos); - ypos = GST_ROUND_UP_2 (ypos); - - w = overlay->width; - h = overlay->height; - - y_stride = gst_video_format_get_row_stride (overlay->format, 0, w); - u_stride = gst_video_format_get_row_stride (overlay->format, 1, w); - v_stride = gst_video_format_get_row_stride (overlay->format, 2, w); - u_offset = gst_video_format_get_component_offset (overlay->format, 1, w, h); - v_offset = gst_video_format_get_component_offset (overlay->format, 2, w, h); - - gst_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos, overlay->text_image, - y_stride); - gst_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset, - yuv_pixels + v_offset, xpos, ypos, overlay->text_image, u_stride, - v_stride, 1); -} - -static inline void -gst_text_overlay_blit_UYVY (GstTextOverlay * overlay, - guint8 * yuv_pixels, gint xpos, gint ypos) -{ - int a0, r0, g0, b0; - int a1, r1, g1, b1; - int y0, y1, u, v; - int i, j; - int h, w; - guchar *pimage, *dest; - - /* because U/V is 2x horizontally subsampled, we need to round to a - * boundary of integer number of U/V pixels in x dimension: - */ - xpos = GST_ROUND_UP_2 (xpos); - - w = overlay->image_width - 2; - h = overlay->image_height - 2; - - if (xpos < 0) { - xpos = 0; - } - - if (xpos + w > overlay->width) { - w = overlay->width - xpos; - } - - if (ypos + h > overlay->height) { - h = overlay->height - ypos; - } - - for (i = 0; i < h; i++) { - pimage = overlay->text_image + i * overlay->image_width * 4; - dest = yuv_pixels + (i + ypos) * overlay->width * 2 + xpos * 2; - for (j = 0; j < w; j += 2) { - b0 = pimage[CAIRO_ARGB_B]; - g0 = pimage[CAIRO_ARGB_G]; - r0 = pimage[CAIRO_ARGB_R]; - a0 = pimage[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a0, r0, g0, b0); - pimage += 4; - - b1 = pimage[CAIRO_ARGB_B]; - g1 = pimage[CAIRO_ARGB_G]; - r1 = pimage[CAIRO_ARGB_R]; - a1 = pimage[CAIRO_ARGB_A]; - CAIRO_UNPREMULTIPLY (a1, r1, g1, b1); - pimage += 4; - - a0 += a1 + 2; - a0 /= 2; - if (a0 == 0) { - dest += 4; - continue; - } - - COMP_Y (y0, r0, g0, b0); - COMP_Y (y1, r1, g1, b1); - - b0 += b1 + 2; - g0 += g1 + 2; - r0 += r1 + 2; - - b0 /= 2; - g0 /= 2; - r0 /= 2; - - COMP_U (u, r0, g0, b0); - COMP_V (v, r0, g0, b0); - - BLEND (*dest, a0, u, *dest); - dest++; - BLEND (*dest, a0, y0, *dest); - dest++; - BLEND (*dest, a0, v, *dest); - dest++; - BLEND (*dest, a0, y1, *dest); - dest++; - } - } -} - -static inline void -gst_text_overlay_blit_AYUV (GstTextOverlay * overlay, - guint8 * rgb_pixels, gint xpos, gint ypos) -{ - int a, r, g, b, a1; - int y, u, v; - int i, j; - int h, w; - guchar *pimage, *dest; - - w = overlay->image_width; - h = overlay->image_height; - - if (xpos < 0) { - xpos = 0; - } - - if (xpos + w > overlay->width) { - w = overlay->width - xpos; - } - - if (ypos + h > overlay->height) { - h = overlay->height - ypos; - } - - for (i = 0; i < h; i++) { - pimage = overlay->text_image + i * overlay->image_width * 4; - dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; - for (j = 0; j < w; j++) { - a = pimage[CAIRO_ARGB_A]; - b = pimage[CAIRO_ARGB_B]; - g = pimage[CAIRO_ARGB_G]; - r = pimage[CAIRO_ARGB_R]; - - CAIRO_UNPREMULTIPLY (a, r, g, b); - - // convert background to yuv - COMP_Y (y, r, g, b); - COMP_U (u, r, g, b); - COMP_V (v, r, g, b); - - // preform text "OVER" background alpha compositing - a1 = a + (dest[0] * (255 - a)) / 255 + 1; // add 1 to prevent divide by 0 - OVER (dest[1], a, y, dest[0], dest[1], a1); - OVER (dest[2], a, u, dest[0], dest[2], a1); - OVER (dest[3], a, v, dest[0], dest[3], a1); - dest[0] = a1 - 1; // remove the temporary 1 we added - - pimage += 4; - dest += 4; - } - } -} - -#define xRGB_BLIT_FUNCTION(name, R, G, B) \ -static inline void \ -gst_text_overlay_blit_##name (GstTextOverlay * overlay, \ - guint8 * rgb_pixels, gint xpos, gint ypos) \ -{ \ - int a, r, g, b; \ - int i, j; \ - int h, w; \ - guchar *pimage, *dest; \ - \ - w = overlay->image_width; \ - h = overlay->image_height; \ - \ - if (xpos < 0) { \ - xpos = 0; \ - } \ - \ - if (xpos + w > overlay->width) { \ - w = overlay->width - xpos; \ - } \ - \ - if (ypos + h > overlay->height) { \ - h = overlay->height - ypos; \ - } \ - \ - for (i = 0; i < h; i++) { \ - pimage = overlay->text_image + i * overlay->image_width * 4; \ - dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \ - for (j = 0; j < w; j++) { \ - a = pimage[CAIRO_ARGB_A]; \ - b = pimage[CAIRO_ARGB_B]; \ - g = pimage[CAIRO_ARGB_G]; \ - r = pimage[CAIRO_ARGB_R]; \ - CAIRO_UNPREMULTIPLY (a, r, g, b); \ - b = (b*a + dest[B] * (255-a)) / 255; \ - g = (g*a + dest[G] * (255-a)) / 255; \ - r = (r*a + dest[R] * (255-a)) / 255; \ - \ - dest[B] = b; \ - dest[G] = g; \ - dest[R] = r; \ - pimage += 4; \ - dest += 4; \ - } \ - } \ -} -xRGB_BLIT_FUNCTION (xRGB, 1, 2, 3); -xRGB_BLIT_FUNCTION (BGRx, 2, 1, 0); -xRGB_BLIT_FUNCTION (xBGR, 3, 2, 1); -xRGB_BLIT_FUNCTION (RGBx, 0, 1, 2); - -#define ARGB_BLIT_FUNCTION(name, A, R, G, B) \ -static inline void \ -gst_text_overlay_blit_##name (GstTextOverlay * overlay, \ - guint8 * rgb_pixels, gint xpos, gint ypos) \ -{ \ - int a, r, g, b, a1; \ - int i, j; \ - int h, w; \ - guchar *pimage, *dest; \ - \ - w = overlay->image_width; \ - h = overlay->image_height; \ - \ - if (xpos < 0) { \ - xpos = 0; \ - } \ - \ - if (xpos + w > overlay->width) { \ - w = overlay->width - xpos; \ - } \ - \ - if (ypos + h > overlay->height) { \ - h = overlay->height - ypos; \ - } \ - \ - for (i = 0; i < h; i++) { \ - pimage = overlay->text_image + i * overlay->image_width * 4; \ - dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \ - for (j = 0; j < w; j++) { \ - a = pimage[CAIRO_ARGB_A]; \ - b = pimage[CAIRO_ARGB_B]; \ - g = pimage[CAIRO_ARGB_G]; \ - r = pimage[CAIRO_ARGB_R]; \ - CAIRO_UNPREMULTIPLY (a, r, g, b); \ - a1 = a + (dest[A] * (255 - a)) / 255 + 1; \ - OVER (dest[R], a, r, dest[0], dest[R], a1); \ - OVER (dest[G], a, g, dest[0], dest[G], a1); \ - OVER (dest[B], a, b, dest[0], dest[B], a1); \ - dest[A] = a1 - 1; \ - pimage += 4; \ - dest += 4; \ - } \ - } \ -} -ARGB_BLIT_FUNCTION (RGBA, 3, 0, 1, 2); -ARGB_BLIT_FUNCTION (BGRA, 3, 2, 1, 0); -ARGB_BLIT_FUNCTION (ARGB, 0, 1, 2, 3); -ARGB_BLIT_FUNCTION (ABGR, 0, 3, 2, 1); - static void gst_text_overlay_render_text (GstTextOverlay * overlay, const gchar * text, gint textlen) @@ -1946,69 +1566,10 @@ static GstFlowReturn gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) { gint xpos, ypos; - gint width, height; - GstTextOverlayVAlign valign; - GstTextOverlayHAlign halign; - - width = overlay->image_width; - height = overlay->image_height; video_frame = gst_buffer_make_writable (video_frame); - if (overlay->use_vertical_render) - halign = GST_TEXT_OVERLAY_HALIGN_RIGHT; - else - halign = overlay->halign; - - switch (halign) { - case GST_TEXT_OVERLAY_HALIGN_LEFT: - xpos = overlay->xpad; - break; - case GST_TEXT_OVERLAY_HALIGN_CENTER: - xpos = (overlay->width - width) / 2; - break; - case GST_TEXT_OVERLAY_HALIGN_RIGHT: - xpos = overlay->width - width - overlay->xpad; - break; - case GST_TEXT_OVERLAY_HALIGN_POS: - xpos = (gint) (overlay->width * overlay->xpos) - width / 2; - xpos = CLAMP (xpos, 0, overlay->width - width); - if (xpos < 0) - xpos = 0; - break; - default: - xpos = 0; - } - xpos += overlay->deltax; - - if (overlay->use_vertical_render) - valign = GST_TEXT_OVERLAY_VALIGN_TOP; - else - valign = overlay->valign; - - switch (valign) { - case GST_TEXT_OVERLAY_VALIGN_BOTTOM: - ypos = overlay->height - height - overlay->ypad; - break; - case GST_TEXT_OVERLAY_VALIGN_BASELINE: - ypos = overlay->height - (height + overlay->ypad); - break; - case GST_TEXT_OVERLAY_VALIGN_TOP: - ypos = overlay->ypad; - break; - case GST_TEXT_OVERLAY_VALIGN_POS: - ypos = (gint) (overlay->height * overlay->ypos) - height / 2; - ypos = CLAMP (ypos, 0, overlay->height - height); - break; - case GST_TEXT_OVERLAY_VALIGN_CENTER: - ypos = (overlay->height - height) / 2; - break; - default: - ypos = overlay->ypad; - break; - } - ypos += overlay->deltay; - + gst_text_overlay_get_pos (overlay, &xpos, &ypos); /* shaded background box */ if (overlay->want_shading) { switch (overlay->format) { @@ -2071,65 +1632,9 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) } } - if (ypos < 0) - ypos = 0; + if (overlay->composition) + gst_video_overlay_composition_blend (overlay->composition, video_frame); - if (overlay->text_image) { - switch (overlay->format) { - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - gst_text_overlay_blit_I420_YV12 (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_NV12: - case GST_VIDEO_FORMAT_NV21: - gst_text_overlay_blit_NV12_NV21 (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_UYVY: - gst_text_overlay_blit_UYVY (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_AYUV: - gst_text_overlay_blit_AYUV (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_BGRx: - gst_text_overlay_blit_BGRx (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_xRGB: - gst_text_overlay_blit_xRGB (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_RGBx: - gst_text_overlay_blit_RGBx (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_xBGR: - gst_text_overlay_blit_xBGR (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_ARGB: - gst_text_overlay_blit_ARGB (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_ABGR: - gst_text_overlay_blit_ABGR (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_RGBA: - gst_text_overlay_blit_RGBA (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - case GST_VIDEO_FORMAT_BGRA: - gst_text_overlay_blit_BGRA (overlay, - GST_BUFFER_DATA (video_frame), xpos, ypos); - break; - default: - g_assert_not_reached (); - } - } return gst_pad_push (overlay->srcpad, video_frame); } diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index 73a26f0b0b..a378b04e7b 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -95,65 +96,67 @@ typedef enum { * Opaque textoverlay object structure */ struct _GstTextOverlay { - GstElement element; + GstElement element; - GstPad *video_sinkpad; - GstPad *text_sinkpad; - GstPad *srcpad; + GstPad *video_sinkpad; + GstPad *text_sinkpad; + GstPad *srcpad; - GstSegment segment; - GstSegment text_segment; - GstBuffer *text_buffer; - gboolean text_linked; - gboolean video_flushing; - gboolean video_eos; - gboolean text_flushing; - gboolean text_eos; + GstSegment segment; + GstSegment text_segment; + GstBuffer *text_buffer; + gboolean text_linked; + gboolean video_flushing; + gboolean video_eos; + gboolean text_flushing; + gboolean text_eos; - GCond *cond; /* to signal removal of a queued text + GCond *cond; /* to signal removal of a queued text * buffer, arrival of a text buffer, * a text segment update, or a change * in status (e.g. shutdown, flushing) */ - gint width; - gint height; - gint fps_n; - gint fps_d; - GstVideoFormat format; + gint width; + gint height; + gint fps_n; + gint fps_d; + GstVideoFormat format; - GstTextOverlayVAlign valign; - GstTextOverlayHAlign halign; - GstTextOverlayWrapMode wrap_mode; - GstTextOverlayLineAlign line_align; + GstTextOverlayVAlign valign; + GstTextOverlayHAlign halign; + GstTextOverlayWrapMode wrap_mode; + GstTextOverlayLineAlign line_align; - gint xpad; - gint ypad; - gint deltax; - gint deltay; - gdouble xpos; - gdouble ypos; - gchar *default_text; - gboolean want_shading; - gboolean silent; - gboolean wait_text; - guint color, outline_color; + gint xpad; + gint ypad; + gint deltax; + gint deltay; + gdouble xpos; + gdouble ypos; + gchar *default_text; + gboolean want_shading; + gboolean silent; + gboolean wait_text; + guint color, outline_color; - PangoLayout *layout; - gdouble shadow_offset; - gboolean want_shadow; - gdouble outline_offset; - guchar *text_image; - gint image_width; - gint image_height; - gint baseline_y; + PangoLayout *layout; + gdouble shadow_offset; + gboolean want_shadow; + gdouble outline_offset; + guchar *text_image; + gint image_width; + gint image_height; + gint baseline_y; - gboolean auto_adjust_size; - gboolean need_render; + gboolean auto_adjust_size; + gboolean need_render; - gint shading_value; /* for timeoverlay subclass */ + gint shading_value; /* for timeoverlay subclass */ - gboolean have_pango_markup; - gboolean use_vertical_render; + gboolean have_pango_markup; + gboolean use_vertical_render; + + GstVideoOverlayComposition *composition; }; struct _GstTextOverlayClass { From a741c0cf11e1747cb58023c2ad3f979fc5b23b79 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 18 Nov 2011 11:04:47 -0300 Subject: [PATCH 17/31] textoverlay: Sync the caps with the new supported formats Thanks to the use of the new video composition library, we gain support to more colospaces and formats, let's state it. --- ext/pango/gsttextoverlay.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 65d363ae72..5f7379840a 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -178,6 +178,8 @@ static GstStaticPadTemplate src_template_factory = GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" + GST_VIDEO_CAPS_RGB ";" + GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" @@ -185,7 +187,9 @@ static GstStaticPadTemplate src_template_factory = GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";" - GST_VIDEO_CAPS_YUV ("{AYUV, I420, YV12, UYVY, NV12, NV21}")) + GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," + " v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," + " YUV9, IYU1}")) ); static GstStaticPadTemplate video_sink_template_factory = @@ -193,6 +197,8 @@ static GstStaticPadTemplate video_sink_template_factory = GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" + GST_VIDEO_CAPS_RGB ";" + GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" @@ -200,7 +206,9 @@ static GstStaticPadTemplate video_sink_template_factory = GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";" - GST_VIDEO_CAPS_YUV ("{AYUV, I420, YV12, UYVY, NV12, NV21}")) + GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," + " v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," + " YUV9, IYU1}")) ); static GstStaticPadTemplate text_sink_template_factory = From 2a687b6dfb6226055f539a980e01b7e00d1ac4a0 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 18 Nov 2011 13:22:52 -0300 Subject: [PATCH 18/31] textoverlay: Make the text_image data a buffer This way we won't free data that would be attached to some buffer. --- ext/pango/gsttextoverlay.c | 25 ++++++++++++------------- ext/pango/gsttextoverlay.h | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 5f7379840a..afed974cea 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -580,7 +580,7 @@ gst_text_overlay_finalize (GObject * object) } if (overlay->text_image) { - g_free (overlay->text_image); + gst_buffer_unref (overlay->text_image); overlay->text_image = NULL; } @@ -1235,15 +1235,10 @@ gst_text_overlay_set_composition (GstTextOverlay * overlay) gst_text_overlay_get_pos (overlay, &xpos, &ypos); if (overlay->text_image) { - GstBuffer *buffer = gst_buffer_new (); - - GST_BUFFER_DATA (buffer) = overlay->text_image; - GST_BUFFER_SIZE (buffer) = gst_video_format_get_size (GST_VIDEO_FORMAT_ARGB, - overlay->image_width, overlay->image_height); - - rectangle = gst_video_overlay_rectangle_new_argb (buffer, + rectangle = gst_video_overlay_rectangle_new_argb (overlay->text_image, overlay->image_width, overlay->image_height, 4 * overlay->image_width, - 1, 1, xpos, ypos, overlay->image_width, overlay->image_height); + xpos, ypos, overlay->image_width, overlay->image_height, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); if (overlay->composition) gst_video_overlay_composition_unref (overlay->composition); @@ -1267,7 +1262,8 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay, int width, height; double scalef = 1.0; double a, r, g, b; - + GstBuffer *buffer; + guint8 *text_image; g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock); if (overlay->auto_adjust_size) { @@ -1333,10 +1329,13 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay, cairo_matrix_init_scale (&cairo_matrix, scalef, scalef); } - /* reallocate surface */ - overlay->text_image = g_realloc (overlay->text_image, 4 * width * height); + /* reallocate overlay buffer */ + buffer = gst_buffer_new_and_alloc (4 * width * height); + gst_buffer_replace (&overlay->text_image, buffer); + text_image = GST_BUFFER_DATA (buffer); + gst_buffer_unref (buffer); - surface = cairo_image_surface_create_for_data (overlay->text_image, + surface = cairo_image_surface_create_for_data (text_image, CAIRO_FORMAT_ARGB32, width, height, width * 4); cr = cairo_create (surface); diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index a378b04e7b..940e5632c9 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -143,7 +143,7 @@ struct _GstTextOverlay { gdouble shadow_offset; gboolean want_shadow; gdouble outline_offset; - guchar *text_image; + GstBuffer *text_image; gint image_width; gint image_height; gint baseline_y; From cbcf1e0b463033168ef0c93a43447fa4a7454e46 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 23 Nov 2011 12:49:02 -0300 Subject: [PATCH 19/31] textoverlay: Attach OverlayComposition to buffers when needed Add video/x-surface support in the caps We should then attach it whenever the sink supports it, but this is working for the time being --- ext/pango/gsttextoverlay.c | 26 ++++++++++++++++++++++++-- ext/pango/gsttextoverlay.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index afed974cea..766ba97806 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -173,6 +173,7 @@ enum PROP_LAST }; +/* FIXME Use GST_VIDEO_CAPS_SURFACE when it lands in base */ static GstStaticPadTemplate src_template_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, @@ -187,6 +188,7 @@ static GstStaticPadTemplate src_template_factory = GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";" + "video/x-surface;" GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," " v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," " YUV9, IYU1}")) @@ -206,6 +208,7 @@ static GstStaticPadTemplate video_sink_template_factory = GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";" + "video/x-surface;" GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," " v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," " YUV9, IYU1}")) @@ -797,8 +800,20 @@ gst_text_overlay_setcaps (GstPad * pad, GstCaps * caps) overlay->fps_d = gst_value_get_fraction_denominator (fps); if (ret) { + GstStructure *structure; + GST_OBJECT_LOCK (overlay); g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock); + + /* FIXME Use the query to the sink to do that when implemented */ + /* Update wether to attach composition to buffer or do the composition + * ourselves */ + structure = gst_caps_get_structure (caps, 0); + if (gst_structure_has_name (structure, "video/x-surface")) + overlay->attach_compo_to_buffer = TRUE; + else + overlay->attach_compo_to_buffer = FALSE; + gst_text_overlay_update_wrap_mode (overlay); g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock); GST_OBJECT_UNLOCK (overlay); @@ -1639,8 +1654,15 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) } } - if (overlay->composition) - gst_video_overlay_composition_blend (overlay->composition, video_frame); + if (overlay->composition) { + if (overlay->attach_compo_to_buffer) { + GST_DEBUG_OBJECT (overlay, "Attaching text to the buffer"); + gst_video_buffer_set_overlay_composition (video_frame, + overlay->composition); + } else { + gst_video_overlay_composition_blend (overlay->composition, video_frame); + } + } return gst_pad_push (overlay->srcpad, video_frame); } diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index 940e5632c9..d36e4761a4 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -156,6 +156,8 @@ struct _GstTextOverlay { gboolean have_pango_markup; gboolean use_vertical_render; + gboolean attach_compo_to_buffer; + GstVideoOverlayComposition *composition; }; From 785e006de93d4175e3f5cb1e3e2c492e46a14b2c Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 28 Nov 2011 10:05:50 -0300 Subject: [PATCH 20/31] textoverlay: unpremultiply text image The GstVideoOverlayComposition only supports unpremultiplied ARGB (for now anyway, support for pre-multiplied alpha is planned.) --- ext/pango/gsttextoverlay.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 766ba97806..a92659f1eb 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -1172,10 +1172,11 @@ gst_text_overlay_adjust_values_with_fontdesc (GstTextOverlay * overlay, } #define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \ - b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \ - g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \ - r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \ + *b = (a > 0) ? MIN ((*b * 255 + a / 2) / a, 255) : 0; \ + *g = (a > 0) ? MIN ((*g * 255 + a / 2) / a, 255) : 0; \ + *r = (a > 0) ? MIN ((*r * 255 + a / 2) / a, 255) : 0; \ } G_STMT_END + static void gst_text_overlay_get_pos (GstTextOverlay * overlay, gint * xpos, gint * ypos) { @@ -1241,6 +1242,23 @@ gst_text_overlay_get_pos (GstTextOverlay * overlay, gint * xpos, gint * ypos) *ypos += overlay->deltay; } +static inline void +gst_text_overlay_unpremultiply (GstTextOverlay * overlay) +{ + guint i, j; + guint8 *pimage, *text_image = GST_BUFFER_DATA (overlay->text_image); + + for (i = 0; i < overlay->image_height; i++) { + pimage = text_image + 4 * (i * overlay->image_width); + for (j = 0; j < overlay->image_width; j++) { + CAIRO_UNPREMULTIPLY (pimage[CAIRO_ARGB_A], &pimage[CAIRO_ARGB_R], + &pimage[CAIRO_ARGB_G], &pimage[CAIRO_ARGB_B]); + + pimage += 4; + } + } +} + static inline void gst_text_overlay_set_composition (GstTextOverlay * overlay) { @@ -1419,6 +1437,9 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay, g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock); + /* As the GstVideoOverlayComposition supports only unpremultiply ARGB, + * we need to unpermultiply it */ + gst_text_overlay_unpremultiply (overlay); gst_text_overlay_set_composition (overlay); } From 8b8dd06de4aefd101a91b670ccc1c8942ff7ea55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 5 Dec 2011 15:34:42 +0000 Subject: [PATCH 21/31] examples: dist fft sub-directory --- tests/examples/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index 475ca45695..d765419b34 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -10,7 +10,7 @@ endif SUBDIRS = app audio dynamic fft $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec v4l encoding -DIST_SUBDIRS = app audio dynamic gio overlay seek snapshot playrec v4l encoding +DIST_SUBDIRS = app audio dynamic fft gio overlay seek snapshot playrec v4l encoding include $(top_srcdir)/common/parallel-subdirs.mak From 7d20a7bdb95fa9047d4b6bc78e6755d5023772b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 5 Dec 2011 15:48:07 +0000 Subject: [PATCH 22/31] video: don't use deprecated GStaticMutex with newer glib versions --- .../gst/video/video-overlay-composition.c | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index c3e75524d7..d5ed836146 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -133,7 +133,12 @@ struct _GstVideoOverlayRectangle /* FIXME: we may also need a (private) way to cache converted/scaled * pixel blobs */ +#if !GLIB_CHECK_VERSION (2, 31, 0) GStaticMutex lock; +#else + GMutex lock; +#endif + GList *scaled_rectangles; }; @@ -142,6 +147,14 @@ struct _GstVideoOverlayRectangleClass GstMiniObjectClass parent_class; }; +#if !GLIB_CHECK_VERSION (2, 31, 0) +#define GST_RECTANGLE_LOCK(rect) g_static_mutex_lock(&rect->lock) +#define GST_RECTANGLE_UNLOCK(rect) g_static_mutex_unlock(&rect->lock) +#else +#define GST_RECTANGLE_LOCK(rect) g_mutex_lock(&rect->lock) +#define GST_RECTANGLE_UNLOCK(rect) g_mutex_unlock(&rect->lock) +#endif + static void gst_video_overlay_composition_class_init (GstMiniObjectClass * k); static void gst_video_overlay_composition_finalize (GstMiniObject * comp); static void gst_video_overlay_rectangle_class_init (GstMiniObjectClass * klass); @@ -628,8 +641,11 @@ gst_video_overlay_rectangle_finalize (GstMiniObject * mini_obj) rect->scaled_rectangles = g_list_delete_link (rect->scaled_rectangles, rect->scaled_rectangles); } +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_mutex_free (&rect->lock); - +#else + g_mutex_clear (&rect->lock); +#endif /* not chaining up to GstMiniObject's finalize for now, we know it's empty */ } @@ -645,7 +661,11 @@ gst_video_overlay_rectangle_instance_init (GstMiniObject * mini_obj) { GstVideoOverlayRectangle *rect = (GstVideoOverlayRectangle *) mini_obj; +#if !GLIB_CHECK_VERSION (2, 31, 0) g_static_mutex_init (&rect->lock); +#else + g_mutex_init (&rect->lock); +#endif } /** @@ -824,7 +844,7 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * } /* see if we've got one cached already */ - g_static_mutex_lock (&rectangle->lock); + GST_RECTANGLE_LOCK (rectangle); for (l = rectangle->scaled_rectangles; l != NULL; l = l->next) { GstVideoOverlayRectangle *r = l->data; @@ -836,7 +856,7 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * break; } } - g_static_mutex_unlock (&rectangle->lock); + GST_RECTANGLE_UNLOCK (rectangle); if (scaled_rect != NULL) goto done; @@ -859,10 +879,10 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * gst_buffer_unref (buf); - g_static_mutex_lock (&rectangle->lock); + GST_RECTANGLE_LOCK (rectangle); rectangle->scaled_rectangles = g_list_prepend (rectangle->scaled_rectangles, scaled_rect); - g_static_mutex_unlock (&rectangle->lock); + GST_RECTANGLE_UNLOCK (rectangle); done: From 8728023f001101fea8b87056f88c54c67cf9a561 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 23 Nov 2011 15:43:46 -0300 Subject: [PATCH 23/31] subtitleoverlay: add suport for hardware accelerated videos Don't plug converters for non-raw video. --- gst/playback/gstsubtitleoverlay.c | 309 ++++++++++++++++++------------ 1 file changed, 189 insertions(+), 120 deletions(-) diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c index 8ca5184bf0..061d049428 100644 --- a/gst/playback/gstsubtitleoverlay.c +++ b/gst/playback/gstsubtitleoverlay.c @@ -193,11 +193,12 @@ _is_raw_video (GstStructure * s) } static gboolean -_is_raw_video_pad (GstPad * pad) +_is_video_pad (GstPad * pad, gboolean * hw_accelerated) { GstPad *peer = gst_pad_get_peer (pad); GstCaps *caps; - gboolean raw = TRUE; + gboolean ret; + const gchar *name; if (peer) { caps = gst_pad_get_negotiated_caps (peer); @@ -209,11 +210,27 @@ _is_raw_video_pad (GstPad * pad) caps = gst_pad_get_caps_reffed (pad); } - raw = _is_raw_video (gst_caps_get_structure (caps, 0)); + + name = gst_structure_get_name (gst_caps_get_structure (caps, 0)); + if (g_str_has_prefix (name, "video/x-raw-")) { + ret = TRUE; + if (hw_accelerated) + *hw_accelerated = FALSE; + + } else if (g_str_has_prefix (name, "video/x-surface")) { + ret = TRUE; + if (hw_accelerated) + *hw_accelerated = TRUE; + } else { + + ret = FALSE; + if (hw_accelerated) + *hw_accelerated = FALSE; + } gst_caps_unref (caps); - return raw; + return ret; } static GstCaps * @@ -853,7 +870,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) for (l = factories; l; l = l->next) { GstElementFactory *factory = l->data; - gboolean is_renderer = _is_renderer (factory); + gboolean is_video, is_hw, is_renderer = _is_renderer (factory); GstElement *element; GstPad *sink, *src; @@ -884,6 +901,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) element = is_renderer ? self->renderer : self->parser; + is_video = _is_video_pad (self->video_sinkpad, &is_hw); /* If this is a parser, create textoverlay and link video and the parser to it * Else link the renderer to the output colorspace */ if (!is_renderer) { @@ -961,84 +979,113 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) gst_object_unref (sink); gst_object_unref (src); - if (G_UNLIKELY (!_create_element (self, &self->post_colorspace, - COLORSPACE, NULL, "post-colorspace", FALSE))) { - continue; - } + /* If we are working with video/x-surface, we do not add + * colorspace conversion elements */ + if (is_video && !is_hw) { + if (G_UNLIKELY (!_create_element (self, &self->post_colorspace, + COLORSPACE, NULL, "post-colorspace", FALSE))) { + continue; + } - src = gst_element_get_static_pad (overlay, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get src pad from overlay"); - continue; - } + src = gst_element_get_static_pad (overlay, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from overlay"); + continue; + } - sink = gst_element_get_static_pad (self->post_colorspace, "sink"); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); - gst_object_unref (src); - continue; - } + sink = gst_element_get_static_pad (self->post_colorspace, "sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); + gst_object_unref (src); + continue; + } - if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { - GST_WARNING_OBJECT (self, "Can't link overlay with " COLORSPACE); + if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { + GST_WARNING_OBJECT (self, "Can't link overlay with " COLORSPACE); + gst_object_unref (src); + gst_object_unref (sink); + continue; + } gst_object_unref (src); gst_object_unref (sink); - continue; - } - gst_object_unref (src); - gst_object_unref (sink); - if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace, - COLORSPACE, NULL, "pre-colorspace", FALSE))) { - continue; - } + if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace, + "identity", NULL, "pre-colorspace", FALSE))) { + continue; + } - sink = gst_element_get_static_pad (overlay, "video_sink"); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get video sink from textoverlay"); - continue; - } + sink = gst_element_get_static_pad (overlay, "video_sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get video sink from textoverlay"); + continue; + } - src = gst_element_get_static_pad (self->pre_colorspace, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE); - gst_object_unref (sink); - continue; - } + src = gst_element_get_static_pad (self->pre_colorspace, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE); + gst_object_unref (sink); + continue; + } - if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { - GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to textoverlay"); + if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { + GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to textoverlay"); + gst_object_unref (src); + gst_object_unref (sink); + continue; + } gst_object_unref (src); gst_object_unref (sink); - continue; - } - gst_object_unref (src); - gst_object_unref (sink); - /* Set src ghostpad target */ - src = gst_element_get_static_pad (self->post_colorspace, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE); - continue; - } + /* Set src ghostpad target */ + src = gst_element_get_static_pad (self->post_colorspace, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE); + continue; + } - if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST - (self->srcpad), src))) { - GST_WARNING_OBJECT (self, "Can't set srcpad target"); + if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST + (self->srcpad), src))) { + GST_WARNING_OBJECT (self, "Can't set srcpad target"); + gst_object_unref (src); + continue; + } + gst_object_unref (src); + } else if (is_hw) { + GST_DEBUG_OBJECT (self, + "Is Hardware, not adding colorspace converters, "); + /* Set src ghostpad target */ + src = gst_element_get_static_pad (self->overlay, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from textoverlay"); + continue; + } + + if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST + (self->srcpad), src))) { + GST_WARNING_OBJECT (self, "Can't set srcpad target"); + gst_object_unref (src); + continue; + } gst_object_unref (src); - continue; } - gst_object_unref (src); /* Send segments to the parser/overlay if necessary. These are not sent * outside this element because of the proxy pad event function */ if (self->video_segment.format != GST_FORMAT_UNDEFINED) { GstEvent *event1, *event2; - sink = gst_element_get_static_pad (self->pre_colorspace, "sink"); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); - continue; + if (is_video) { + sink = gst_element_get_static_pad (self->pre_colorspace, "sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); + continue; + } + } else { + sink = gst_element_get_static_pad (self->overlay, "video_sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from textoverlay"); + continue; + } } _generate_update_newsegment_event (&self->video_segment, &event1, @@ -1079,10 +1126,19 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) } /* Set the sink ghostpad targets */ - sink = gst_element_get_static_pad (self->pre_colorspace, "sink"); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); - continue; + if (is_video && !is_hw) { + sink = gst_element_get_static_pad (self->pre_colorspace, "sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); + continue; + } + } else if (is_video && is_hw) { + GST_DEBUG_OBJECT (self, "Setting ghostpad to overlay video sink"); + sink = gst_element_get_static_pad (self->overlay, "video_sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from overlay"); + continue; + } } if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST @@ -1110,7 +1166,6 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) } else { const gchar *name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)); - gboolean is_raw_video = _is_raw_video_pad (self->video_sinkpad); if (strcmp (name, "textoverlay") == 0) { /* Set some textoverlay specific properties */ @@ -1130,82 +1185,96 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data) g_object_set (self->renderer, "font-desc", self->font_desc, NULL); } - if (is_raw_video) { - /* First check that renderer also supports raw video */ + if (is_video) { + gboolean render_is_hw; + + /* First check that renderer also supports the video format */ sink = _get_video_pad (element); if (G_UNLIKELY (!sink)) { GST_WARNING_OBJECT (self, "Can't get video sink from renderer"); continue; } - if (G_UNLIKELY (!_is_raw_video_pad (sink))) { - GST_DEBUG_OBJECT (self, "Renderer doesn't support raw video"); + if (is_video != _is_video_pad (sink, &render_is_hw) || + is_hw != render_is_hw) { + GST_DEBUG_OBJECT (self, "Renderer doesn't support %s video", + is_hw ? "surface" : "raw"); gst_object_unref (sink); continue; } gst_object_unref (sink); - /* First link everything internally */ - if (G_UNLIKELY (!_create_element (self, &self->post_colorspace, - COLORSPACE, NULL, "post-colorspace", FALSE))) { - continue; - } - src = gst_element_get_static_pad (element, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get src pad from renderer"); - continue; - } + if (!is_hw) { + /* First link everything internally */ + if (G_UNLIKELY (!_create_element (self, &self->post_colorspace, + COLORSPACE, NULL, "post-colorspace", FALSE))) { + continue; + } + src = gst_element_get_static_pad (element, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from renderer"); + continue; + } - sink = gst_element_get_static_pad (self->post_colorspace, "sink"); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); - gst_object_unref (src); - continue; - } + sink = gst_element_get_static_pad (self->post_colorspace, "sink"); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE); + gst_object_unref (src); + continue; + } - if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { - GST_WARNING_OBJECT (self, "Can't link renderer with " COLORSPACE); + if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { + GST_WARNING_OBJECT (self, "Can't link renderer with " COLORSPACE); + gst_object_unref (src); + gst_object_unref (sink); + continue; + } gst_object_unref (src); gst_object_unref (sink); - continue; - } - gst_object_unref (src); - gst_object_unref (sink); - if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace, - COLORSPACE, NULL, "pre-colorspace", FALSE))) { - continue; - } + if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace, + COLORSPACE, NULL, "pre-colorspace", FALSE))) { + continue; + } - sink = _get_video_pad (element); - if (G_UNLIKELY (!sink)) { - GST_WARNING_OBJECT (self, "Can't get video sink from renderer"); - continue; - } + sink = _get_video_pad (element); + if (G_UNLIKELY (!sink)) { + GST_WARNING_OBJECT (self, "Can't get video sink from renderer"); + continue; + } - src = gst_element_get_static_pad (self->pre_colorspace, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE); - gst_object_unref (sink); - continue; - } + src = gst_element_get_static_pad (self->pre_colorspace, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE); + gst_object_unref (sink); + continue; + } - if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { - GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to renderer"); + if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) { + GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to renderer"); + gst_object_unref (src); + gst_object_unref (sink); + continue; + } gst_object_unref (src); gst_object_unref (sink); - continue; - } - gst_object_unref (src); - gst_object_unref (sink); - /* Set src ghostpad target */ - src = gst_element_get_static_pad (self->post_colorspace, "src"); - if (G_UNLIKELY (!src)) { - GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE); - continue; + /* Set src ghostpad target */ + src = gst_element_get_static_pad (self->post_colorspace, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE); + continue; + } + } else { + /* Set src ghostpad target in the harware accelerated case */ + + src = gst_element_get_static_pad (self->renderer, "src"); + if (G_UNLIKELY (!src)) { + GST_WARNING_OBJECT (self, "Can't get src pad from renderer"); + continue; + } } - } else { /* No raw video pad */ + } else { /* No video pad */ GstCaps *allowed_caps, *video_caps = NULL; GstPad *video_peer; gboolean can_intersect = FALSE; From 61d0ab1faaca4cd77a2c5ce245ad9119e1abefdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 6 Dec 2011 14:55:38 +0000 Subject: [PATCH 24/31] video: fix leak in gst_video_format_new_template_caps() g_value_reset() is not the same as g_value_unset() --- gst-libs/gst/video/video.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index af5091c1f1..2ad97f290b 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -762,11 +762,9 @@ gst_video_format_new_template_caps (GstVideoFormat format) gst_value_list_append_value (&value, &v); g_value_set_boolean (&v, FALSE); gst_value_list_append_value (&value, &v); + g_value_unset (&v); - gst_structure_set_value (structure, "interlaced", &value); - - g_value_reset (&value); - g_value_reset (&v); + gst_structure_take_value (structure, "interlaced", &value); } return caps; From d59648a47f8c62828d500c559bc062754c983444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 6 Dec 2011 15:01:05 +0000 Subject: [PATCH 25/31] examples: fix build of fft example Should link against our own libgstfft-0.10. --- tests/examples/fft/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/examples/fft/Makefile.am b/tests/examples/fft/Makefile.am index c71f18d4eb..c5a2d96fae 100644 --- a/tests/examples/fft/Makefile.am +++ b/tests/examples/fft/Makefile.am @@ -2,5 +2,7 @@ noinst_PROGRAMS = fftrange fftrange_SOURCES = fftrange.c fftrange_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) -fftrange_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstfft-$(GST_MAJORMINOR) $(GST_LIBS) +fftrange_LDADD = \ + $(top_builddir)/gst-libs/gst/fft/libgstfft-$(GST_MAJORMINOR).la \ + $(GST_LIBS) From b58b8b1ba58f77904ce211d2e4e9f6bd3b9e8909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 6 Dec 2011 20:30:55 +0000 Subject: [PATCH 26/31] tests: fix calculation of last pixel offset in video unit test And check the right buffer (pix2) in one case. --- tests/check/libs/video.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index bd9674a0cc..18a64172f5 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -843,7 +843,11 @@ GST_START_TEST (test_overlay_composition) /* get scaled pixbuf and touch last byte */ pix1 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); - fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + fail_unless (GST_BUFFER_SIZE (pix1) > ((h - 1) * stride + (w * 4) - 1), + "size %u vs. last pixel offset %u", GST_BUFFER_SIZE (pix1), + ((h - 1) * stride + (w * 4) - 1)); + fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + ((h - 1) * stride + + (w * 4) - 1)), 0); gst_video_overlay_rectangle_get_render_rectangle (rect2, &x, &y, &w, &h); fail_unless_equals_int (x, 50); @@ -854,7 +858,11 @@ GST_START_TEST (test_overlay_composition) /* get scaled pixbuf and touch last byte */ pix2 = gst_video_overlay_rectangle_get_pixels_argb (rect2, &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); - fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + fail_unless (GST_BUFFER_SIZE (pix2) > ((h - 1) * stride + (w * 4) - 1), + "size %u vs. last pixel offset %u", GST_BUFFER_SIZE (pix1), + ((h - 1) * stride + (w * 4) - 1)); + fail_unless_equals_int (*(GST_BUFFER_DATA (pix2) + ((h - 1) * stride + + (w * 4) - 1)), 0); /* get scaled pixbuf again, should be the same buffer as before (caching) */ pix1 = gst_video_overlay_rectangle_get_pixels_argb (rect2, &stride, @@ -873,7 +881,11 @@ GST_START_TEST (test_overlay_composition) fail_unless_equals_int (h, 50); /* touch last byte */ - fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + (h * stride + w - 1)), 0); + fail_unless (GST_BUFFER_SIZE (pix1) > ((h - 1) * stride + (w * 4) - 1), + "size %u vs. last pixel offset %u", GST_BUFFER_SIZE (pix1), + ((h - 1) * stride + (w * 4) - 1)); + fail_unless_equals_int (*(GST_BUFFER_DATA (pix1) + ((h - 1) * stride + + (w * 4) - 1)), 0); /* test attaching and retrieving of compositions to/from buffers */ buf = gst_buffer_new (); From 99c7a519088cf441a2fe536e652fe1018bb74098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 6 Dec 2011 21:57:32 +0000 Subject: [PATCH 27/31] videorate: don't leak previous buffer when shutting down Implement stop vfunc after port to basetransform, so we can clean up properly. Fixes make elements/videorate.valgrind --- gst/videorate/gstvideorate.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index 98fc92e363..e4ba16cb0b 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -147,6 +147,7 @@ static GstFlowReturn gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buf); static gboolean gst_video_rate_start (GstBaseTransform * trans); +static gboolean gst_video_rate_stop (GstBaseTransform * trans); static void gst_video_rate_set_property (GObject * object, @@ -195,6 +196,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass) GST_DEBUG_FUNCPTR (gst_video_rate_prepare_output_buffer); base_class->event = GST_DEBUG_FUNCPTR (gst_video_rate_event); base_class->start = GST_DEBUG_FUNCPTR (gst_video_rate_start); + base_class->stop = GST_DEBUG_FUNCPTR (gst_video_rate_stop); base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps); base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query); @@ -1175,6 +1177,13 @@ gst_video_rate_start (GstBaseTransform * trans) return TRUE; } +static gboolean +gst_video_rate_stop (GstBaseTransform * trans) +{ + gst_video_rate_reset (GST_VIDEO_RATE (trans)); + return TRUE; +} + static void gst_video_rate_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) From 39c5015ed0983d19f4d5e8b43c99571e2dd2626f Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 23 Nov 2011 15:45:57 -0300 Subject: [PATCH 28/31] video: support any type of video in _parse_caps Slight change in semantics for convenience. Shouldn't cause any problems since this function is usually only used on pre-filtered caps and not random caps, and it's hard to imagine a situation where someone would want to rely on the previous behaviour. --- gst-libs/gst/video/video.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index 2ad97f290b..f22ff4c12f 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -317,8 +317,10 @@ gst_video_parse_caps_chroma_site (GstCaps * caps) * Determines the #GstVideoFormat of @caps and places it in the location * pointed to by @format. Extracts the size of the video and places it * in the location pointed to by @width and @height. If @caps does not - * represent one of the raw video formats listed in #GstVideoFormat, the - * function will fail and return FALSE. + * represent a video format or does not contain height and width, the + * function will fail and return FALSE. If @caps does not represent a raw + * video format listed in #GstVideoFormat, but still contains video caps, + * this function will return TRUE and set @format to #GST_VIDEO_FORMAT_UNKNOWN. * * Since: 0.10.16 * @@ -429,6 +431,8 @@ gst_video_format_parse_caps (const GstCaps * caps, GstVideoFormat * format, } else { ok = FALSE; } + } else if (g_str_has_prefix (gst_structure_get_name (structure), "video/")) { + *format = GST_VIDEO_FORMAT_UNKNOWN; } else { ok = FALSE; } From 5037b39883ca615ba7b68f378f8836af85cb60d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 7 Dec 2011 17:57:08 +0000 Subject: [PATCH 29/31] video: add seqnum getters for overlay compositions and rectangles API: gst_video_overlay_composition_get_seqnum() API: gst_video_overlay_rectangle_get_seqnum() --- .../gst/video/video-overlay-composition.c | 42 +++++++++++++++++++ .../gst/video/video-overlay-composition.h | 4 ++ tests/check/libs/video.c | 9 ++++ win32/common/libgstvideo.def | 2 + 4 files changed, 57 insertions(+) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index d5ed836146..3cc289cc27 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -602,6 +602,27 @@ copy: return writable_comp; } +/** + * gst_video_overlay_composition_get_seqnum: + * @comp: a #GstVideoOverlayComposition + * + * Returns the sequence number of this composition. Sequence numbers are + * monotonically increasing and unique for overlay compositions and rectangles + * (meaning there will never be a rectangle with the same sequence number as + * a composition). + * + * Returns: the sequence number of @comp + * + * Since: 0.10.36 + */ +guint +gst_video_overlay_composition_get_seqnum (GstVideoOverlayComposition * comp) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), 0); + + return comp->seq_num; +} + /* ------------------------------ rectangles ------------------------------ -*/ static void gst_video_overlay_rectangle_instance_init (GstMiniObject * miniobj); @@ -958,3 +979,24 @@ gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle) return copy; } + +/** + * gst_video_overlay_rectangle_get_seqnum: + * @rectangle: a #GstVideoOverlayRectangle + * + * Returns the sequence number of this rectangle. Sequence numbers are + * monotonically increasing and unique for overlay compositions and rectangles + * (meaning there will never be a rectangle with the same sequence number as + * a composition). + * + * Returns: the sequence number of @rectangle + * + * Since: 0.10.36 + */ +guint +gst_video_overlay_rectangle_get_seqnum (GstVideoOverlayRectangle * rectangle) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), 0); + + return rectangle->seq_num; +} diff --git a/gst-libs/gst/video/video-overlay-composition.h b/gst-libs/gst/video/video-overlay-composition.h index 9b6c3ca114..8e35efa76e 100644 --- a/gst-libs/gst/video/video-overlay-composition.h +++ b/gst-libs/gst/video/video-overlay-composition.h @@ -114,6 +114,8 @@ GstVideoOverlayRectangle * gst_video_overlay_rectangle_new_argb (GstBuffer * p GstVideoOverlayRectangle * gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle); +guint gst_video_overlay_rectangle_get_seqnum (GstVideoOverlayRectangle * rectangle); + void gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle * rectangle, gint render_x, gint render_y, @@ -214,6 +216,8 @@ guint gst_video_overlay_composition_n_rectangles (GstVid GstVideoOverlayRectangle * gst_video_overlay_composition_get_rectangle (GstVideoOverlayComposition * comp, guint n); +guint gst_video_overlay_composition_get_seqnum (GstVideoOverlayComposition * comp); + /* blend composition onto raw video buffer */ void gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index 18a64172f5..fd3178dcfc 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -783,6 +783,7 @@ GST_START_TEST (test_overlay_composition) GstVideoOverlayComposition *comp1, *comp2; GstVideoOverlayRectangle *rect1, *rect2; GstBuffer *pix1, *pix2, *buf; + guint seq1, seq2; guint w, h, stride; gint x, y; @@ -800,6 +801,11 @@ GST_START_TEST (test_overlay_composition) fail_unless (gst_video_overlay_composition_get_rectangle (comp1, 0) == rect1); fail_unless (gst_video_overlay_composition_get_rectangle (comp1, 1) == NULL); + /* rectangle was created first, sequence number should be smaller */ + seq1 = gst_video_overlay_rectangle_get_seqnum (rect1); + seq2 = gst_video_overlay_composition_get_seqnum (comp1); + fail_unless (seq1 < seq2); + /* composition took own ref, so refcount is 2 now, so this should fail */ ASSERT_CRITICAL (gst_video_overlay_rectangle_set_render_rectangle (rect1, 50, 600, 300, 50)); @@ -813,6 +819,9 @@ GST_START_TEST (test_overlay_composition) fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 0) == rect1); fail_unless (gst_video_overlay_composition_get_rectangle (comp2, 1) == NULL); + fail_unless (seq1 < gst_video_overlay_composition_get_seqnum (comp2)); + fail_unless (seq2 < gst_video_overlay_composition_get_seqnum (comp2)); + /* now refcount is 2 again because comp2 has also taken a ref, so must fail */ ASSERT_CRITICAL (gst_video_overlay_rectangle_set_render_rectangle (rect1, 0, 0, 1, 1)); diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index fee972a2f3..dd6e2b0157 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -39,6 +39,7 @@ EXPORTS gst_video_overlay_composition_blend gst_video_overlay_composition_copy gst_video_overlay_composition_get_rectangle + gst_video_overlay_composition_get_seqnum gst_video_overlay_composition_get_type gst_video_overlay_composition_make_writable gst_video_overlay_composition_n_rectangles @@ -47,6 +48,7 @@ EXPORTS gst_video_overlay_rectangle_get_pixels_argb gst_video_overlay_rectangle_get_pixels_unscaled_argb gst_video_overlay_rectangle_get_render_rectangle + gst_video_overlay_rectangle_get_seqnum gst_video_overlay_rectangle_get_type gst_video_overlay_rectangle_new_argb gst_video_overlay_rectangle_set_render_rectangle From 6757afc0bc46620da9df6b8e7df50337d5e2f7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 7 Dec 2011 18:31:58 +0000 Subject: [PATCH 30/31] docs: add new API to docs --- docs/libs/gst-plugins-base-libs-docs.sgml | 1 + docs/libs/gst-plugins-base-libs-sections.txt | 50 +++++++++++++++++++ .../gst/video/video-overlay-composition.c | 15 +++++- .../gst/video/video-overlay-composition.h | 2 +- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-docs.sgml b/docs/libs/gst-plugins-base-libs-docs.sgml index 9902258ba9..1fc3e83ea7 100644 --- a/docs/libs/gst-plugins-base-libs-docs.sgml +++ b/docs/libs/gst-plugins-base-libs-docs.sgml @@ -225,6 +225,7 @@ -lgstvideo-&GST_MAJORMINOR; to the library flags. + diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index a4a61cd2c4..3f60d565e4 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -2312,6 +2312,56 @@ gst_video_format_get_type GST_TYPE_VIDEO_FORMAT +
+gstvideooverlaycomposition +gst/video/video-overlay-composition.h + +GstVideoOverlayComposition +GstVideoOverlayCompositionClass +gst_video_overlay_composition_new +gst_video_overlay_composition_ref +gst_video_overlay_composition_unref +gst_video_overlay_composition_add_rectangle +gst_video_overlay_composition_n_rectangles +gst_video_overlay_composition_get_rectangle +gst_video_overlay_composition_get_seqnum +gst_video_overlay_composition_copy +gst_video_overlay_composition_make_writable +gst_video_overlay_composition_blend + +gst_video_buffer_get_overlay_composition +gst_video_buffer_set_overlay_composition + +GstVideoOverlayFormatFlags +GstVideoOverlayRectangle +GstVideoOverlayRectangleClass +gst_video_overlay_rectangle_new_argb +gst_video_overlay_rectangle_ref +gst_video_overlay_rectangle_unref +gst_video_overlay_rectangle_get_pixels_argb +gst_video_overlay_rectangle_get_pixels_unscaled_argb +gst_video_overlay_rectangle_get_render_rectangle +gst_video_overlay_rectangle_get_seqnum +gst_video_overlay_rectangle_set_render_rectangle +gst_video_overlay_rectangle_copy + +GST_TYPE_VIDEO_OVERLAY_COMPOSITION +GST_VIDEO_OVERLAY_COMPOSITION +GST_VIDEO_OVERLAY_COMPOSITION_CLASS +GST_VIDEO_OVERLAY_COMPOSITION_GET_CLASS +GST_IS_VIDEO_OVERLAY_COMPOSITION +GST_IS_VIDEO_VIDEO_OVERLAY_COMPOSITION_CLASS +gst_video_overlay_composition_get_type + +GST_TYPE_VIDEO_OVERLAY_RECTANGLE +GST_VIDEO_OVERLAY_RECTANGLE +GST_VIDEO_OVERLAY_RECTANGLE_CLASS +GST_VIDEO_OVERLAY_RECTANGLE_GET_CLASS +GST_IS_VIDEO_OVERLAY_RECTANGLE +GST_IS_VIDEO_VIDEO_OVERLAY_RECTANGLE_CLASS +gst_video_overlay_rectangle_get_type +
+
gstvideofilter gst/video/gstvideofilter.h diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index 3cc289cc27..a3e360c0ce 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -20,7 +20,7 @@ */ /** - * SECTION:video-overlay-composition + * SECTION:gstvideooverlaycomposition * @short_description: Video Buffer Overlay Compositions (Subtitles, Logos) * * @@ -465,6 +465,19 @@ gst_video_overlay_rectangle_needs_scaling (GstVideoOverlayRectangle * r) return (r->width != r->render_width || r->height != r->render_height); } +/** + * gst_video_overlay_composition_blend: + * @comp: a #GstVideoOverlayComposition + * @video_buf: a #GstBuffer containing raw video data in a supported format + * + * Blends the overlay rectangles in @comp on top of the raw video data + * contained in @video_buf. The data in @video_buf must be writable. If + * needed, use gst_buffer_make_writable() before calling this function to + * ensure a buffer is writable. @video_buf must also have valid raw video + * caps set on it. + * + * Since: 0.10.36 + */ void gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, GstBuffer * video_buf) diff --git a/gst-libs/gst/video/video-overlay-composition.h b/gst-libs/gst/video/video-overlay-composition.h index 8e35efa76e..1a1a234341 100644 --- a/gst-libs/gst/video/video-overlay-composition.h +++ b/gst-libs/gst/video/video-overlay-composition.h @@ -94,7 +94,7 @@ gst_video_overlay_rectangle_unref (GstVideoOverlayRectangle * comp) /** * GstVideoOverlayFormatFlags: - * @GST_VIDEO_OVERLAY_RECTANGLE_FLAG_NONE: no flags + * @GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE: no flags * * Overlay format flags. * From 91bbfbd819f6a347be114ee280dd5bb5b0ab1385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 7 Dec 2011 18:45:28 +0000 Subject: [PATCH 31/31] video: make composition_blend() return a boolean Not that anyone will ever check that, and it's not clear what they're supposed to do if it fails, but at least it's there. --- gst-libs/gst/video/video-overlay-composition.c | 18 +++++++++++------- gst-libs/gst/video/video-overlay-composition.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index a3e360c0ce..3bfbad1bbe 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -478,25 +478,26 @@ gst_video_overlay_rectangle_needs_scaling (GstVideoOverlayRectangle * r) * * Since: 0.10.36 */ -void +gboolean gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, GstBuffer * video_buf) { GstBlendVideoFormatInfo video_info, rectangle_info; GstVideoFormat fmt; + gboolean ret = TRUE; guint n, num; int w, h; - g_return_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp)); - g_return_if_fail (GST_IS_BUFFER (video_buf)); - g_return_if_fail (gst_buffer_is_writable (video_buf)); - g_return_if_fail (GST_BUFFER_CAPS (video_buf) != NULL); + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), FALSE); + g_return_val_if_fail (GST_IS_BUFFER (video_buf), FALSE); + g_return_val_if_fail (gst_buffer_is_writable (video_buf), FALSE); + g_return_val_if_fail (GST_BUFFER_CAPS (video_buf) != NULL, FALSE); if (!gst_video_format_parse_caps (GST_BUFFER_CAPS (video_buf), &fmt, &w, &h)) { gchar *str = gst_caps_to_string (GST_BUFFER_CAPS (video_buf)); g_warning ("%s: could not parse video buffer caps '%s'", GST_FUNCTION, str); g_free (str); - return; + return FALSE; } video_blend_format_info_init (&video_info, GST_BUFFER_DATA (video_buf), @@ -525,7 +526,8 @@ gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, rect->render_width); } - if (!video_blend (&video_info, &rectangle_info, rect->x, rect->y)) { + ret = video_blend (&video_info, &rectangle_info, rect->x, rect->y); + if (!ret) { GST_WARNING ("Could not blend overlay rectangle onto video buffer"); } @@ -533,6 +535,8 @@ gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, if (needs_scaling) g_free (rectangle_info.pixels); } + + return ret; } /** diff --git a/gst-libs/gst/video/video-overlay-composition.h b/gst-libs/gst/video/video-overlay-composition.h index 1a1a234341..5ff7ce36c6 100644 --- a/gst-libs/gst/video/video-overlay-composition.h +++ b/gst-libs/gst/video/video-overlay-composition.h @@ -220,7 +220,7 @@ guint gst_video_overlay_composition_get_seqnum (GstVid /* blend composition onto raw video buffer */ -void gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, +gboolean gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, GstBuffer * video_buf); /* attach/retrieve composition from buffers */