From e5b2bade360bcf12ac389463019162a6ce64d9ef Mon Sep 17 00:00:00 2001 From: Jian 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 --- 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