diff --git a/modules/demux/mp4/essetup.c b/modules/demux/mp4/essetup.c
index 19b5ff16fc641d93c6b715ca27da24fb8e5a2e9b..a1be66f556149fc1712aba3692502be677f94394 100644
--- a/modules/demux/mp4/essetup.c
+++ b/modules/demux/mp4/essetup.c
@@ -280,13 +280,25 @@ int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
             p_track->fmt.video.orientation = ORIENT_ROTATED_90;
             break;
         case 180:
-            p_track->fmt.video.orientation = ORIENT_ROTATED_180;
+            if (p_track->i_flip == 1) {
+                p_track->fmt.video.orientation = ORIENT_VFLIPPED;
+            } else {
+                p_track->fmt.video.orientation = ORIENT_ROTATED_180;
+            }
             break;
         case 270:
             p_track->fmt.video.orientation = ORIENT_ROTATED_270;
             break;
     }
 
+    /* Flip, unless already flipped */
+    if (p_track->i_flip == 1 && (int)p_track->f_rotation != 180) {
+        video_transform_t transform = (video_transform_t)p_track->fmt.video.orientation;
+        /* Flip first then rotate */
+        p_track->fmt.video.orientation = ORIENT_HFLIPPED;
+        video_format_TransformBy(&p_track->fmt.video, transform);
+    }
+
     /* Set 360 video mode */
     p_track->fmt.video.projection_mode = PROJECTION_MODE_RECTANGULAR;
     const MP4_Box_t *p_uuid = MP4_BoxGet( p_track->p_track, "uuid" );
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index cf9eeadf42fd6a37b9277be0deb59f986c2b8d5c..0f5e91fd40c329f7c3dfafaaa0b7903d8f46ef68 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -1227,6 +1227,15 @@ static int MP4_ReadBox_tkhd(  stream_t *p_stream, MP4_Box_t *p_box )
     double scale[2];    // scale factor; sx = scale[0] , sy = scale[1]
     int32_t *matrix = p_box->data.p_tkhd->i_matrix;
 
+    int64_t det = (int64_t)matrix[0] * matrix[4] - (int64_t)matrix[1] * matrix[3];
+    if (det < 0) {
+        /* If determinant is negative copy the matrix and flip it horizontally. */
+        const int flip[] = { -1, 1, 1 };
+        for (int j = 0; j < 9; j++)
+            matrix[j] *= flip[j % 3];
+        p_box->data.p_tkhd->i_flip = 1;
+    }
+
     scale[0] = sqrt(conv_fx(matrix[0]) * conv_fx(matrix[0]) +
                     conv_fx(matrix[3]) * conv_fx(matrix[3]));
     scale[1] = sqrt(conv_fx(matrix[1]) * conv_fx(matrix[1]) +
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index bfab16515f70a7da8bbef2f59f859037aafca338..dd3082d66ae1bce9a3a7d9c06c4d615b34e17b76 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -509,6 +509,7 @@ typedef struct MP4_Box_data_tkhd_s
     int32_t  i_width;
     int32_t  i_height;
     float    f_rotation;
+    int      i_flip;
 
 } MP4_Box_data_tkhd_t;
 
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index a5178d860f2dd815944f937a578aeb8d0aa5be38..908890183bf94fdf9aaae97d811330136cd0d5cd 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -3367,6 +3367,7 @@ static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
     p_track->i_width = BOXDATA(p_tkhd)->i_width / BLOCK16x16;
     p_track->i_height = BOXDATA(p_tkhd)->i_height / BLOCK16x16;
     p_track->f_rotation = BOXDATA(p_tkhd)->f_rotation;
+    p_track->i_flip = BOXDATA(p_tkhd)->i_flip;
 
     /* FIXME: unhandled box: tref */
 
diff --git a/modules/demux/mp4/mp4.h b/modules/demux/mp4/mp4.h
index b7c6cdf3d718834fbe0ba98bd7f8d3843f0cd83c..d2855246a32477c3f9dfb209e840efcfd5af598a 100644
--- a/modules/demux/mp4/mp4.h
+++ b/modules/demux/mp4/mp4.h
@@ -99,6 +99,7 @@ typedef struct
     int i_width;
     int i_height;
     float f_rotation;
+    int i_flip;
 
     /* more internal data */
     uint32_t        i_timescale;    /* time scale for this track only */
diff --git a/src/misc/es_format.c b/src/misc/es_format.c
index c2a09132d1b3c8cd91834955065476a46c476287..63f5584ef02dccc79bf730cc2edd3a6ce699edd4 100644
--- a/src/misc/es_format.c
+++ b/src/misc/es_format.c
@@ -142,6 +142,7 @@ void video_format_Setup( video_format_t *p_fmt, vlc_fourcc_t i_chroma,
     p_fmt->i_visible_height = i_visible_height;
     p_fmt->i_x_offset       =
     p_fmt->i_y_offset       = 0;
+    p_fmt->orientation      = ORIENT_NORMAL;
     vlc_ureduce( &p_fmt->i_sar_num, &p_fmt->i_sar_den,
                  i_sar_num, i_sar_den, 0 );
 
diff --git a/test/Makefile.am b/test/Makefile.am
index c2b0d082c9b0ae8dfc4b3d213730e33dfce16be1..c9eaa59d2b6d76ec430f947fc4e59a85423050a8 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -36,6 +36,15 @@ check_PROGRAMS = \
 if ENABLE_SOUT
 check_PROGRAMS += test_modules_tls
 endif
+
+if HAVE_GL
+check_PROGRAMS += test_modules_video_output_opengl_filters
+endif
+
+if HAVE_GLES2
+check_PROGRAMS += test_modules_video_output_opengl_es2_filters
+endif
+
 if UPDATE_CHECK
 check_PROGRAMS += test_src_crypto_update
 endif
@@ -130,6 +139,72 @@ test_modules_keystore_SOURCES = modules/keystore/test.c
 test_modules_keystore_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_modules_tls_SOURCES = modules/misc/tls.c
 test_modules_tls_LDADD = $(LIBVLCCORE) $(LIBVLC)
+<<<<<<< HEAD
+=======
+test_modules_demux_timestamps_filter_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_demux_timestamps_filter_SOURCES = modules/demux/timestamps_filter.c
+test_modules_demux_ts_pes_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_demux_ts_pes_SOURCES = modules/demux/ts_pes.c \
+				../modules/demux/mpeg/ts_pes.c \
+				../modules/demux/mpeg/ts_pes.h
+test_modules_playlist_m3u_SOURCES = modules/demux/playlist/m3u.c
+test_modules_playlist_m3u_LDADD = $(LIBVLCCORE) $(LIBVLC)
+
+test_modules_codec_hxxx_helper_SOURCES = modules/codec/hxxx_helper.c \
+                                      ../modules/codec/hxxx_helper.c \
+                                      ../modules/packetizer/hxxx_nal.c \
+                                      ../modules/packetizer/h264_slice.c \
+                                      ../modules/packetizer/h264_nal.c \
+                                      ../modules/packetizer/hevc_nal.c
+test_modules_codec_hxxx_helper_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_video_output_opengl_filters_SOURCES = \
+	modules/video_output/opengl/filters.c \
+	../modules/video_output/opengl/filters.c \
+	../modules/video_output/opengl/filters.h \
+	../modules/video_output/opengl/filter.c \
+	../modules/video_output/opengl/gl_api.c \
+	../modules/video_output/opengl/gl_api.h \
+	../modules/video_output/opengl/interop.c \
+	../modules/video_output/opengl/interop.h \
+	../modules/video_output/opengl/importer.c \
+	../modules/video_output/opengl/importer.h
+test_modules_video_output_opengl_filters_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_video_output_opengl_filters_CPPFLAGS = $(AM_CPPFLAGS) -DVLC_TEST_OPENGL_API=VLC_OPENGL
+test_modules_video_output_opengl_es2_filters_SOURCES = $(test_modules_video_output_opengl_filters_SOURCES)
+test_modules_video_output_opengl_es2_filters_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_video_output_opengl_es2_filters_CPPFLAGS = $(AM_CPPFLAGS) -DVLC_TEST_OPENGL_API=VLC_OPENGL_ES2
+
+
+test_src_video_output_SOURCES = \
+	src/video_output/video_output.c \
+	src/video_output/video_output.h \
+	src/video_output/video_output_scenarios.c
+test_src_video_output_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_src_video_output_opengl_SOURCES = src/video_output/opengl.c
+test_src_video_output_opengl_LDADD = $(LIBVLCCORE) $(LIBVLC)
+
+test_modules_stream_out_transcode_SOURCES = \
+	modules/stream_out/transcode.c \
+	modules/stream_out/transcode.h \
+	modules/stream_out/transcode_scenarios.c
+test_modules_stream_out_transcode_LDADD = $(LIBVLCCORE) $(LIBVLC)
+
+test_modules_stream_out_pcr_sync_SOURCES = modules/stream_out/pcr_sync.c \
+	../modules/stream_out/transcode/pcr_sync.c \
+	../modules/stream_out/transcode/pcr_sync.h \
+	../modules/stream_out/transcode/pcr_helper.h \
+	../modules/stream_out/transcode/pcr_helper.c
+test_modules_stream_out_pcr_sync_LDADD = $(LIBVLCCORE)
+
+test_src_input_decoder_SOURCES = \
+	src/input/decoder/input_decoder.c \
+	src/input/decoder/input_decoder.h \
+	src/input/decoder/input_decoder_scenarios.c
+test_src_input_decoder_LDADD = $(LIBVLCCORE) $(LIBVLC)
+
+test_src_misc_image_SOURCES = src/misc/image.c
+test_src_misc_image_LDADD = $(LIBVLCCORE) $(LIBVLC)
+>>>>>>> 8ae846de79 (test: opengl: add test for filters)
 
 checkall:
 	$(MAKE) check_PROGRAMS="$(check_PROGRAMS) $(EXTRA_PROGRAMS)" check
diff --git a/test/modules/video_output/opengl/filters.c b/test/modules/video_output/opengl/filters.c
new file mode 100644
index 0000000000000000000000000000000000000000..4cf04cbd0ac55d61241cd0377645896e94d6f0c0
--- /dev/null
+++ b/test/modules/video_output/opengl/filters.c
@@ -0,0 +1,333 @@
+/*****************************************************************************
+ * opengl.c: test for the OpenGL client code
+ *****************************************************************************
+ * Copyright (C) 2023 VideoLabs
+ *
+ * Authors: Alexandre Janniaux <ajanni@videolabs.io>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef VLC_TEST_OPENGL_API
+# error "Define VLC_TEST_OPENGL_API to the VLC_OPENGL API to use"
+#endif
+
+/* Define a builtin module for mocked parts */
+#define MODULE_NAME test_opengl
+#undef VLC_DYNAMIC_PLUGIN
+
+#include "../../../libvlc/test.h"
+#include "../../../lib/libvlc_internal.h"
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_opengl.h>
+#include <vlc_filter.h>
+#include <vlc_modules.h>
+#include <vlc_vout_display.h>
+
+#include "../../../modules/video_output/opengl/filters.h"
+#include "../../../modules/video_output/opengl/gl_api.h"
+
+static_assert(
+    VLC_TEST_OPENGL_API == VLC_OPENGL ||
+    VLC_TEST_OPENGL_API == VLC_OPENGL_ES2);
+
+const char vlc_module_name[] = MODULE_STRING;
+static const uint8_t green[] = { 0x0, 0xff, 0x00, 0xff };
+static const uint8_t red[] = { 0xff, 0x0, 0x0, 0xff };
+static const uint8_t blue[] = { 0x00, 0x0, 0xff, 0xff };
+
+struct test_point
+{
+    int x, y;
+    const uint8_t *color;
+};
+
+static void test_opengl_offscreen(
+        vlc_object_t *root,
+        video_orientation_t orientation,
+        struct test_point *points,
+        size_t points_count
+){
+    struct vlc_decoder_device *device =
+        vlc_decoder_device_Create(root, NULL);
+    vlc_gl_t *gl = vlc_gl_CreateOffscreen(
+            root, device, 3, 3, VLC_TEST_OPENGL_API, NULL, NULL);
+    assert(gl != NULL);
+    if (device != NULL)
+        vlc_decoder_device_Release(device);
+
+    int ret = vlc_gl_MakeCurrent(gl);
+    assert(ret == VLC_SUCCESS);
+
+    struct vlc_gl_api api;
+    ret = vlc_gl_api_Init(&api, gl);
+    assert(ret == VLC_SUCCESS);
+
+    GLuint out_tex;
+    api.vt.GenTextures(1, &out_tex);
+    api.vt.BindTexture(GL_TEXTURE_2D, out_tex);
+    api.vt.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    api.vt.BindTexture(GL_TEXTURE_2D, 0);
+
+    GLuint out_fb;
+    api.vt.GenFramebuffers(1, &out_fb);
+    api.vt.BindFramebuffer(GL_FRAMEBUFFER, out_fb);
+    api.vt.BindFramebuffer(GL_READ_FRAMEBUFFER, out_fb);
+    api.vt.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                GL_TEXTURE_2D, out_tex, 0);
+
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    video_format_t fmt;
+    video_format_Setup(&fmt, VLC_CODEC_RGBA, 3, 3, 3, 3, 1, 1);
+    fmt.primaries = COLOR_PRIMARIES_SRGB;
+    fmt.space = COLOR_SPACE_SRGB;
+    fmt.transfer = TRANSFER_FUNC_SRGB;
+    fmt.projection_mode = PROJECTION_MODE_RECTANGULAR;
+
+    struct vlc_gl_interop *interop =
+        vlc_gl_interop_New(gl, NULL, &fmt);
+    assert(interop != NULL);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    GLint fbo_binding;
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+
+    struct vlc_gl_filters *filters =
+        vlc_gl_filters_New(gl, &api, interop, orientation);
+    assert(filters != NULL);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+
+    struct vlc_gl_filter *filter =
+        vlc_gl_filters_Append(filters, "renderer", NULL);
+    assert(filter != NULL);
+    GL_ASSERT_NOERROR(&api.vt);
+    assert((GLuint)fbo_binding == out_fb);
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+    (void)filter;
+
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+
+    ret = vlc_gl_filters_InitFramebuffers(filters);
+    assert(ret == VLC_SUCCESS);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+    assert(api.vt.CheckFramebufferStatus(GL_FRAMEBUFFER)
+            == GL_FRAMEBUFFER_COMPLETE);
+
+    vlc_gl_filters_SetViewport(filters, 0, 0, 3, 3);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    vlc_gl_filters_SetOutputSize(filters, 3, 3);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    picture_t *picture = picture_NewFromFormat(&fmt);
+    assert(picture != NULL);
+
+    size_t size = picture->p[0].i_lines * picture->p[0].i_pitch / picture->p[0].i_pixel_pitch;
+    for (size_t i=0; i < size; ++i)
+        memcpy(&picture->p[0].p_pixels[i * 4], green, sizeof(green));
+
+    memcpy(&picture->p[0].p_pixels[0 * 4], red, sizeof(red));
+    memcpy(&picture->p[0].p_pixels[2 * 4], blue, sizeof(blue));
+
+    ret = vlc_gl_filters_UpdatePicture(filters, picture);
+    assert(ret == VLC_SUCCESS);
+    GL_ASSERT_NOERROR(&api.vt);
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+
+    ret = vlc_gl_filters_Draw(filters);
+    assert(ret == VLC_SUCCESS);
+    GL_ASSERT_NOERROR(&api.vt);
+    api.vt.GetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo_binding);
+    assert((GLuint)fbo_binding == out_fb);
+
+    api.vt.Finish();
+    GL_ASSERT_NOERROR(&api.vt);
+
+    /* Disable pixel packing to use glReadPixels. */
+    api.vt.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    uint8_t pixel[4];
+
+    fprintf(stderr, "Results (vertically flipped):\n");
+    for (size_t i = 0; i < 3; ++i)
+    {
+        for (size_t j = 0; j < 3; ++j)
+        {
+            api.vt.ReadPixels(j, i, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+            fprintf(stderr, "    %u:%u:%u:%u", pixel[0], pixel[1], pixel[2], pixel[3]);
+        }
+        fprintf(stderr, "\n");
+    }
+
+    for (size_t i = 0; i < points_count; ++i)
+    {
+        api.vt.ReadPixels(points[i].x, points[i].y, 1, 1, GL_RGBA,
+                          GL_UNSIGNED_BYTE, &pixel);
+        GL_ASSERT_NOERROR(&api.vt);
+        assert(memcmp(pixel, points[i].color, sizeof(pixel)) == 0);
+    }
+
+    vlc_gl_filters_Delete(filters);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    vlc_gl_interop_Delete(interop);
+    GL_ASSERT_NOERROR(&api.vt);
+
+    vlc_gl_ReleaseCurrent(gl);
+    vlc_gl_Delete(gl);
+}
+
+int main( int argc, char **argv )
+{
+    (void)argc; (void)argv;
+    test_init();
+
+    const char * const vlc_argv[] = {
+        "-vvv", "--aout=dummy", "--text-renderer=dummy",
+    };
+
+    libvlc_instance_t *vlc = libvlc_new(ARRAY_SIZE(vlc_argv), vlc_argv);
+    vlc_object_t *root = &vlc->p_libvlc_int->obj;
+
+    const char *cap =
+        (VLC_TEST_OPENGL_API == VLC_OPENGL)     ? "opengl offscreen" :
+        (VLC_TEST_OPENGL_API == VLC_OPENGL_ES2) ? "opengl es2 offscreen" :
+        NULL;
+    assert(cap != NULL);
+
+    fprintf(stderr, "Looking for cap %s\n", cap);
+
+    module_t **providers;
+    size_t strict_matches;
+    ssize_t provider_available = vlc_module_match(
+            cap, NULL, false, &providers, &strict_matches);
+    (void)strict_matches;
+    free(providers);
+
+    if (provider_available <= 0)
+    {
+        libvlc_release(vlc);
+        return 77;
+    }
+
+    struct vlc_decoder_device *device =
+        vlc_decoder_device_Create(root, NULL);
+    vlc_gl_t *gl = vlc_gl_CreateOffscreen(
+            root, device, 3, 3, VLC_TEST_OPENGL_API, NULL, NULL);
+    if (device != NULL)
+        vlc_decoder_device_Release(device);
+
+    if (gl == NULL)
+    {
+        libvlc_release(vlc);
+        return 77;
+    }
+    vlc_gl_Delete(gl);
+
+    struct test_point points_normal[] = {
+        { 1, 1, green },
+        { 0, 2, red },
+        { 2, 2, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_NORMAL,
+                          points_normal, ARRAY_SIZE(points_normal));
+
+    struct test_point points_rotated_90[] = {
+        { 1, 1, green },
+        { 0, 0, red },
+        { 0, 2, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_ROTATED_90,
+                          points_rotated_90, ARRAY_SIZE(points_rotated_90));
+
+    struct test_point points_rotated_180[] = {
+        { 1, 1, green },
+        { 2, 0, red },
+        { 0, 0, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_ROTATED_180,
+                          points_rotated_180, ARRAY_SIZE(points_rotated_180));
+
+    struct test_point points_rotated_270[] = {
+        { 1, 1, green },
+        { 2, 2, red },
+        { 2, 0, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_ROTATED_270,
+                          points_rotated_270, ARRAY_SIZE(points_rotated_270));
+
+    struct test_point points_hflip[] = {
+        { 1, 1, green },
+        { 2, 2, red },
+        { 0, 2, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_HFLIPPED,
+                          points_hflip, ARRAY_SIZE(points_hflip));
+
+    struct test_point points_vflip[] = {
+        { 1, 1, green },
+        { 0, 0, red },
+        { 2, 0, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_VFLIPPED,
+                          points_vflip, ARRAY_SIZE(points_vflip));
+
+    struct test_point points_transposed[] = {
+        { 1, 1, green },
+        { 2, 0, red },
+        { 2, 2, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_TRANSPOSED,
+                          points_transposed, ARRAY_SIZE(points_transposed));
+
+    struct test_point points_antitransposed[] = {
+        { 1, 1, green },
+        { 0, 2, red },
+        { 0, 0, blue },
+    };
+    test_opengl_offscreen(root, ORIENT_ANTI_TRANSPOSED,
+                          points_antitransposed, ARRAY_SIZE(points_antitransposed));
+
+
+
+    libvlc_release(vlc);
+    return 0;
+}