172 lines
5.7 KiB
Diff
172 lines
5.7 KiB
Diff
From e5b2bade360bcf12ac389463019162a6ce64d9ef Mon Sep 17 00:00:00 2001
|
||
From: Jian <Jian.Li@freescale.com>
|
||
Date: Thu, 26 Mar 2015 14:22:07 +0800
|
||
Subject: [PATCH] Support croping and alignment handling
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Upstream Status: Inappropriate [i.MX specific]
|
||
|
||
Signed-off-by: Jian <Jian.Li@freescale.com>
|
||
---
|
||
ext/gl/gstglimagesink.c | 57 ++++++++++++++++++++++++++++++-
|
||
ext/gl/gstglimagesink.h | 3 ++
|
||
gst-libs/gst/gl/gstglvivdirecttexture.c | 22 ++++++------
|
||
3 files changed, 71 insertions(+), 11 deletions(-)
|
||
|
||
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
|
||
index cd3a9ff..1d60e1d 100644
|
||
--- a/ext/gl/gstglimagesink.c
|
||
+++ b/ext/gl/gstglimagesink.c
|
||
@@ -302,6 +302,8 @@ gst_glimage_sink_init (GstGLImageSink * glimage_sink)
|
||
glimage_sink->pool = NULL;
|
||
glimage_sink->stored_buffer = NULL;
|
||
glimage_sink->redisplay_texture = 0;
|
||
+ glimage_sink->cropmeta = NULL;
|
||
+ glimage_sink->videometa = NULL;
|
||
|
||
g_mutex_init (&glimage_sink->drawing_lock);
|
||
}
|
||
@@ -602,6 +604,10 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
||
gst_object_unref (glimage_sink->display);
|
||
glimage_sink->display = NULL;
|
||
}
|
||
+
|
||
+ glimage_sink->cropmeta = NULL;
|
||
+ glimage_sink->videometa = NULL;
|
||
+
|
||
break;
|
||
}
|
||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||
@@ -804,6 +810,9 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||
if (stored_buffer)
|
||
gst_buffer_unref (stored_buffer);
|
||
|
||
+ glimage_sink->cropmeta = gst_buffer_get_video_crop_meta (buf);
|
||
+ glimage_sink->videometa = gst_buffer_get_video_meta (buf);
|
||
+
|
||
/* Ask the underlying window to redraw its content */
|
||
if (!gst_glimage_sink_redisplay (glimage_sink))
|
||
goto redisplay_failed;
|
||
@@ -1155,7 +1164,7 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
|
||
#endif
|
||
#if GST_GL_HAVE_GLES2
|
||
if (USING_GLES2 (gl_sink->context)) {
|
||
- const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
|
||
+ GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
|
||
1.0f, 0.0f,
|
||
-1.0f, 1.0f, 0.0f,
|
||
0.0f, 0.0f,
|
||
@@ -1165,6 +1174,52 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
|
||
1.0f, 1.0f
|
||
};
|
||
|
||
+ // recalculate the texcoords based on video crop and alignment
|
||
+ {
|
||
+ gint bufw, bufh;
|
||
+ gint x,y,width,height;
|
||
+
|
||
+ if (gl_sink->videometa
|
||
+ && (gl_sink->videometa->format == GST_VIDEO_FORMAT_I420
|
||
+ || gl_sink->videometa->format == GST_VIDEO_FORMAT_NV12)) {
|
||
+ bufw = gl_sink->videometa->stride[0];
|
||
+ bufh = gl_sink->videometa->offset[1] / bufw;
|
||
+ }
|
||
+ else {
|
||
+ bufw = GST_VIDEO_SINK_WIDTH (gl_sink);
|
||
+ bufh = GST_VIDEO_SINK_HEIGHT (gl_sink);
|
||
+ }
|
||
+
|
||
+ //g_print ("buffer res: %d, %d\n", bufw, bufh);
|
||
+
|
||
+ if (gl_sink->cropmeta) {
|
||
+ x = gl_sink->cropmeta->x;
|
||
+ y = gl_sink->cropmeta->y;
|
||
+ width = gl_sink->cropmeta->width;
|
||
+ height = gl_sink->cropmeta->height;
|
||
+ }
|
||
+ else {
|
||
+ x = y = 0;
|
||
+ width = GST_VIDEO_SINK_WIDTH (gl_sink);
|
||
+ height = GST_VIDEO_SINK_HEIGHT (gl_sink);
|
||
+ }
|
||
+
|
||
+ vVertices[8] = (float)(x) / bufw;
|
||
+ vVertices[9] = (float)(y) / bufh;
|
||
+
|
||
+ vVertices[3] = (float)(x + width) / bufw;
|
||
+ vVertices[4] = vVertices[9];
|
||
+
|
||
+ vVertices[13] = vVertices[8];
|
||
+ vVertices[14] = (float)(y + height) / bufh;
|
||
+
|
||
+ vVertices[18] = vVertices[3];
|
||
+ vVertices[19] = vVertices[14];
|
||
+
|
||
+ //g_print ("vVertices, (%f, %f), (%f, %f), (%f, %f), (%f, %f)\n", vVertices[8], vVertices[9], vVertices[3], vVertices[4],
|
||
+ // vVertices[13], vVertices[14], vVertices[18], vVertices[19]);
|
||
+ }
|
||
+
|
||
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
|
||
|
||
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
|
||
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
|
||
index 25e6a13..1805e94 100644
|
||
--- a/ext/gl/gstglimagesink.h
|
||
+++ b/ext/gl/gstglimagesink.h
|
||
@@ -82,6 +82,9 @@ struct _GstGLImageSink
|
||
guint window_width;
|
||
guint window_height;
|
||
|
||
+ GstVideoCropMeta *cropmeta;
|
||
+ GstVideoMeta *videometa;
|
||
+
|
||
#if GST_GL_HAVE_GLES2
|
||
GstGLShader *redisplay_shader;
|
||
GLint redisplay_attr_position_loc;
|
||
diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c
|
||
index 4806335..9131101 100644
|
||
--- a/gst-libs/gst/gl/gstglvivdirecttexture.c
|
||
+++ b/gst-libs/gst/gl/gstglvivdirecttexture.c
|
||
@@ -89,8 +89,18 @@ gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideo
|
||
PhyMemBlock *memblk = &memphy->block;
|
||
|
||
GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info);
|
||
- guint viv_fmt;
|
||
+ gint width, height;
|
||
+ GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer);
|
||
+ if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) {
|
||
+ width = vmeta->stride[0];
|
||
+ height = vmeta->offset[1] / width;
|
||
+ }
|
||
+ else {
|
||
+ width = GST_VIDEO_INFO_WIDTH (info);
|
||
+ height = GST_VIDEO_INFO_HEIGHT (info);
|
||
+ }
|
||
|
||
+ guint viv_fmt;
|
||
switch (fmt) {
|
||
case GST_VIDEO_FORMAT_I420:
|
||
viv_fmt = GL_VIV_I420;
|
||
@@ -107,15 +117,7 @@ gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideo
|
||
return FALSE;
|
||
}
|
||
|
||
- GstVivDirectTexture viv_tex = {
|
||
- tex_id,
|
||
- GST_VIDEO_INFO_WIDTH (info),
|
||
- GST_VIDEO_INFO_HEIGHT (info),
|
||
- viv_fmt,
|
||
- memblk->vaddr,
|
||
- memblk->paddr,
|
||
- FALSE};
|
||
-
|
||
+ GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE};
|
||
gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex);
|
||
|
||
return viv_tex.ret;
|
||
--
|
||
1.7.9.5
|
||
|