gldownloadelement: fix downloading of 'RGBA' EGLImages

NXP has broken basic standard use like
source ! glupload ! glcolorconvert ! gldownload ! video/x-raw,format=RGBA ! sink
in their fork. In this pipeline, if source produces dmabufs, the
pipeline output is always just black. That's because the dmabuf wrapped
EGLImage marked as RGBA is never drawn. glcolorconvert will pass through
of same RGBA caps but the buffer isn't RGBA in traditional GStreamer
sense, it can simply just be sampled as a RGBA texture by hardware when
drawing.

Detect this situation and force drawing to an actual RGBA texture that
can be efficiently downloaded. This restores standard GStreamer
behavior.

BUG: 148157331

Change-Id: I229efde22f49d9540c85b38923dbea4d4eb257bc
diff --git a/ext/gl/gstgldownloadelement.c b/ext/gl/gstgldownloadelement.c
index 845dd6e..31bf814 100644
--- a/ext/gl/gstgldownloadelement.c
+++ b/ext/gl/gstgldownloadelement.c
@@ -35,6 +35,7 @@
 #endif
 
 #if GST_GL_HAVE_IONDMA
+#include <gst/gl/egl/gstglmemoryegl.h>
 #include <gst/gl/gstglmemorydma.h>
 #include <gst/allocators/gstionmemory.h>
 #include <libdrm/drm_fourcc.h>
@@ -865,6 +866,7 @@
   GstMemory *memory = gst_buffer_peek_memory (inbuf, 0);
   GstGLContext *context = GST_GL_BASE_MEMORY_CAST (memory)->context;
   GstBuffer *export_buf = NULL, *src_buf = NULL, *outbuf = NULL;
+  GstGLColorConvert *glconverter = NULL;
   struct ExportParams params = { 0 };
 
   if (!dl->glExportTexImageDMA) {
@@ -878,6 +880,48 @@
     context = dl->export_context;
   }
 
+  /* YUV dma-bufs are uploaded to GL textures as EGLImage and stamped as RGBA
+   * as they can be sampled by HW as such when drawing. However we can't get
+   * CPU accessible RGBA data out of them without drawing at least once.
+   * This is analogous to the disable-passthrough property NXP added to the
+   * glcolorconvert element.
+   */
+  if (gst_is_gl_memory_egl (memory)) {
+    if (G_UNLIKELY (dl->glconverter == NULL)) {
+      GstCaps *sink_caps = NULL;
+
+      sink_caps = gst_pad_get_current_caps (GST_BASE_TRANSFORM (dl)->sinkpad);
+      glconverter = gst_gl_color_convert_new (context);
+
+      if (!gst_gl_color_convert_set_caps (glconverter, sink_caps, sink_caps)) {
+        gst_caps_unref (sink_caps);
+        GST_ERROR_OBJECT (dl, "failed to set gl converter caps");
+        goto beach;
+      }
+
+      gst_caps_unref (sink_caps);
+      dl->glconverter = gst_object_ref (glconverter);
+      GST_DEBUG_OBJECT (dl, "created gl color converter %p", dl->glconverter);
+    } else {
+      glconverter = gst_object_ref (dl->glconverter);
+    }
+  }
+
+  if (glconverter) {
+    GstBuffer *tmp_buf;
+
+    tmp_buf = gst_gl_color_convert_perform (glconverter, inbuf);
+    if (!tmp_buf) {
+      inbuf = NULL;
+      GST_ERROR_OBJECT (dl, "failed to convert inbuf");
+      goto beach;
+    }
+    gst_buffer_copy_into (tmp_buf, inbuf,
+        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+    inbuf = tmp_buf;
+    memory = gst_buffer_peek_memory (inbuf, 0);
+  }
+
   if (gst_buffer_pool_acquire_buffer (dl->export_pool, &export_buf, NULL) !=
       GST_FLOW_OK) {
     GST_ERROR_OBJECT (dl, "gst_buffer_pool_acquire_buffer failed");
@@ -960,6 +1004,12 @@
 beach:
   gst_buffer_replace (&export_buf, NULL);
   gst_buffer_replace (&src_buf, NULL);
+  if (glconverter) {
+    gst_object_unref (glconverter);
+    if (inbuf) {
+      gst_buffer_unref (inbuf);
+    }
+  }
   return outbuf;
 }
 
@@ -991,6 +1041,11 @@
     download->converter = NULL;
   }
 
+  if (download->glconverter) {
+    gst_object_unref (download->glconverter);
+    download->glconverter = NULL;
+  }
+
   if (download->export_context) {
     gst_object_unref (download->export_context);
     download->export_context = NULL;
diff --git a/ext/gl/gstgldownloadelement.h b/ext/gl/gstgldownloadelement.h
index 7019f62..c6f89a4 100644
--- a/ext/gl/gstgldownloadelement.h
+++ b/ext/gl/gstgldownloadelement.h
@@ -58,6 +58,7 @@
   GstVideoInfo src_info;
   GstVideoInfo export_info;
   GstVideoConverter *converter;
+  GstGLColorConvert *glconverter;
 };
 
 struct _GstGLDownloadElementClass