int TexDirectVIVMap (GLenum Target, GLsizei Width, GLsizei Height, GLenum Format, GLvoid **Logical, GLvoid **Physical)
{

	glTexDirectVIVMap (Target, Width, Height, Format, Logical, Physical);
	
	return glGetError ();
}
Ejemplo n.º 2
0
static gboolean gst_imx_egl_viv_sink_gles2_renderer_fill_texture(GstImxEglVivSinkGLES2Renderer *renderer, GstBuffer *buffer)
{
	GstVideoMeta *video_meta;
	GstMapInfo map_info;
	guint num_extra_lines, stride[3], offset[3], is_phys_buf;
	GstImxPhysMemMeta *phys_mem_meta;
	GstVideoFormat fmt;
	GLenum gl_format;
	GLuint w, h, total_w, total_h;
	
	phys_mem_meta = NULL;
	fmt = renderer->video_info.finfo->format;

	gl_format = gst_imx_egl_viv_sink_gles2_renderer_get_viv_format(fmt);
	w = renderer->video_info.width;
	h = renderer->video_info.height;

	phys_mem_meta = GST_IMX_PHYS_MEM_META_GET(buffer);
	is_phys_buf = (phys_mem_meta != NULL) && (phys_mem_meta->phys_addr != 0);

	/* Get the stride and number of extra lines */
	video_meta = gst_buffer_get_video_meta(buffer);
	if (video_meta != NULL)
	{
		for (guint i = 0; i < MIN(video_meta->n_planes, 3); ++i)
		{
			stride[i] = video_meta->stride[i];
			offset[i] = video_meta->offset[i];
		}
	}
	else
	{
		for (guint i = 0; i < MIN(GST_VIDEO_INFO_N_PLANES(&(renderer->video_info)), 3); ++i)
		{
			stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&(renderer->video_info), i);
			offset[i] = GST_VIDEO_INFO_PLANE_OFFSET(&(renderer->video_info), i);
		}
	}

	num_extra_lines = is_phys_buf ? (phys_mem_meta->padding / stride[0]) : 0;

	/* stride is in bytes, we need pixels */
	total_w = stride[0] / gst_imx_egl_viv_sink_gles2_renderer_bpp(fmt);
	total_h = h + num_extra_lines;

	GST_LOG("w/h: %d/%d total_w/h: %d/%d", w, h, total_w, total_h);

	glUniform2f(renderer->uv_scale_uloc, (float)w / (float)total_w, (float)h / (float)total_h);

	/* Only update texture if the video frame actually changed */
	if ((renderer->viv_planes[0] == NULL) || (renderer->video_info_updated))
	{
		GST_LOG("video frame did change");

		if (is_phys_buf)
		{
			GLvoid *virt_addr;
			GLuint phys_addr;

			phys_addr = (GLuint)(phys_mem_meta->phys_addr);

			GST_LOG("mapping physical address 0x%x of video frame in buffer %p into VIV texture", phys_addr, (gpointer)buffer);

			gst_buffer_map(buffer, &map_info, GST_MAP_READ);
			virt_addr = map_info.data;

			/* Just set to make sure the == NULL check above is false */
			renderer->viv_planes[0] = virt_addr;

			glTexDirectVIVMap(
				GL_TEXTURE_2D,
				total_w, total_h,
				gl_format,
				(GLvoid **)(&virt_addr), &phys_addr
			);

			gst_buffer_unmap(buffer, &map_info);
			GST_LOG("done showing frame in buffer %p with virtual address %p physical address 0x%x", (gpointer)buffer, virt_addr, phys_addr);

			if (!gst_imx_egl_viv_sink_gles2_renderer_check_gl_error("render", "glTexDirectVIVMap"))
				return FALSE;
		}
		else
		{
			glTexDirectVIV(
				GL_TEXTURE_2D,
				total_w, total_h,
				gl_format,
				(GLvoid **) &(renderer->viv_planes)
			);
			if (!gst_imx_egl_viv_sink_gles2_renderer_check_gl_error("render", "glTexDirectVIV"))
				return FALSE;

			GST_LOG("copying pixels into VIV direct texture buffer");

			gst_buffer_map(buffer, &map_info, GST_MAP_READ);
			switch (fmt)
			{
				case GST_VIDEO_FORMAT_I420:
				case GST_VIDEO_FORMAT_YV12:
					memcpy(renderer->viv_planes[0], map_info.data + offset[0], stride[0] * total_h);
					memcpy(renderer->viv_planes[1], map_info.data + offset[1], stride[1] * total_h / 2);
					memcpy(renderer->viv_planes[2], map_info.data + offset[2], stride[2] * total_h / 2);
					break;
				case GST_VIDEO_FORMAT_NV12:
				case GST_VIDEO_FORMAT_NV21:
					memcpy(renderer->viv_planes[0], map_info.data + offset[0], stride[0] * total_h);
					memcpy(renderer->viv_planes[1], map_info.data + offset[1], stride[1] * total_h / 2);
					break;
				default:
					memcpy(renderer->viv_planes[0], map_info.data, stride[0] * total_h);
			}
			gst_buffer_unmap(buffer, &map_info);

		}

		glTexDirectInvalidateVIV(GL_TEXTURE_2D);
		if (!gst_imx_egl_viv_sink_gles2_renderer_check_gl_error("render", "glTexDirectInvalidateVIV"))
			return FALSE;

		renderer->video_info_updated = FALSE;
	}
	else
	{
		GST_LOG("video frame did not change - not doing anything");
	}

	return TRUE;
}