コード例 #1
0
static GstFlowReturn gst_imx_blitter_video_transform_transform_frame(GstBaseTransform *transform, GstBuffer *in, GstBuffer *out)
{
	gboolean ret = TRUE;
	GstImxBlitterVideoTransform *blitter_video_transform = GST_IMX_BLITTER_VIDEO_TRANSFORM(transform);

	g_assert(blitter_video_transform->blitter != NULL);

	if (!blitter_video_transform->inout_info_set)
	{
		GST_ELEMENT_ERROR(transform, CORE, NOT_IMPLEMENTED, (NULL), ("unknown format"));
		return GST_FLOW_NOT_NEGOTIATED;
	}

	if (in == out)
	{
		GST_LOG_OBJECT(transform, "passing buffer through");
		return GST_FLOW_OK;
	}

	GST_IMX_BLITTER_VIDEO_TRANSFORM_LOCK(blitter_video_transform);

	ret = ret && gst_imx_blitter_set_input_frame(blitter_video_transform->blitter, in);
	ret = ret && gst_imx_blitter_set_output_frame(blitter_video_transform->blitter, out);
	ret = ret && gst_imx_blitter_blit(blitter_video_transform->blitter, 255);
	ret = ret && gst_imx_blitter_set_output_frame(blitter_video_transform->blitter, NULL);

	GST_IMX_BLITTER_VIDEO_TRANSFORM_UNLOCK(blitter_video_transform);

	return ret ? GST_FLOW_OK : GST_FLOW_ERROR;
}
コード例 #2
0
ファイル: compositor.c プロジェクト: FrankBau/gstreamer-imx
gboolean gst_imx_blitter_compositor_set_output_frame(GstImxCompositor *compositor, GstBuffer *output_frame)
{
	GstImxBlitterCompositor *blitter_compositor = GST_IMX_BLITTER_COMPOSITOR(compositor);
	g_assert(blitter_compositor->blitter != NULL);

	return gst_imx_blitter_set_output_frame(blitter_compositor->blitter, output_frame);
}
コード例 #3
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static gboolean gst_imx_blitter_video_sink_select_fb_page(GstImxBlitterVideoSink *blitter_video_sink, guint page)
{
	GstImxPhysMemMeta *phys_mem_meta = GST_IMX_PHYS_MEM_META_GET(blitter_video_sink->framebuffer);
	guint height = GST_VIDEO_INFO_HEIGHT(&(blitter_video_sink->output_video_info));
	guint page_size = GST_VIDEO_INFO_PLANE_STRIDE(&(blitter_video_sink->output_video_info), 0) * height;

	if (blitter_video_sink->framebuffer_fd == -1)
		return FALSE;

	GST_LOG_OBJECT(blitter_video_sink, "switching to page %u", page);

	phys_mem_meta->phys_addr = (gst_imx_phys_addr_t)(blitter_video_sink->fb_fix.smem_start) + page_size * page;
	blitter_video_sink->fb_var.yoffset = height * page;

	return gst_imx_blitter_set_output_frame(blitter_video_sink->blitter, blitter_video_sink->framebuffer);
}
コード例 #4
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static gboolean gst_imx_blitter_video_sink_acquire_blitter(GstImxBlitterVideoSink *blitter_video_sink)
{
	/* must be called with lock held */

	GstImxBlitterVideoSinkClass *klass = GST_IMX_BLITTER_VIDEO_SINK_CLASS(G_OBJECT_GET_CLASS(blitter_video_sink));

	g_assert(blitter_video_sink != NULL);
	g_assert(blitter_video_sink->framebuffer != NULL);
	g_assert(klass->create_blitter != NULL);

	/* Do nothing if the blitter is already acquired */
	if (blitter_video_sink->blitter != NULL)
		return TRUE;

	if ((blitter_video_sink->blitter = klass->create_blitter(blitter_video_sink)) == NULL)
	{
		GST_ERROR_OBJECT(blitter_video_sink, "could not acquire blitter");
		return FALSE;
	}

	if (!gst_imx_blitter_set_output_frame(blitter_video_sink->blitter, blitter_video_sink->framebuffer))
	{
		GST_ERROR_OBJECT(blitter_video_sink, "could not set the output frame");
		return FALSE;
	}

	if (!gst_imx_blitter_set_output_canvas(blitter_video_sink->blitter, &(blitter_video_sink->canvas)))
	{
		GST_ERROR_OBJECT(blitter_video_sink, "could not set the output canvas");
		return FALSE;
	}

	if (!gst_imx_blitter_set_output_video_info(blitter_video_sink->blitter, &(blitter_video_sink->output_video_info)))
	{
		GST_ERROR_OBJECT(blitter_video_sink, "could not set the output video info");
		return FALSE;
	}

	if (!gst_imx_blitter_set_num_output_pages(blitter_video_sink->blitter, blitter_video_sink->use_vsync ? 3 : 1))
	{
		GST_ERROR_OBJECT(blitter_video_sink, "could not set the number of output pages");
		return FALSE;
	}

	return TRUE;
}
コード例 #5
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static gboolean gst_imx_blitter_video_sink_open_framebuffer_device(GstImxBlitterVideoSink *blitter_video_sink)
{
	/* must be called with lock held */

	gboolean ret = TRUE;
	int fd;
	guint fb_width, fb_height;
	GstVideoFormat fb_format;
	GstBuffer *buffer;
	GstImxPhysMemMeta *phys_mem_meta;
	struct fb_var_screeninfo fb_var;
	struct fb_fix_screeninfo fb_fix;

	g_assert(blitter_video_sink != NULL);
	g_assert(blitter_video_sink->framebuffer_name != NULL);


	/* Close any currently open framebuffer first */
	if (blitter_video_sink->framebuffer_fd != -1)
		gst_imx_blitter_video_sink_close_framebuffer_device(blitter_video_sink);

	GST_INFO_OBJECT(blitter_video_sink, "opening framebuffer %s", blitter_video_sink->framebuffer_name);


	/* Open framebuffer and get its variable and fixed information */

	fd = open(blitter_video_sink->framebuffer_name, O_RDWR, 0);
	if (fd < 0)
	{
		GST_ELEMENT_ERROR(blitter_video_sink, RESOURCE, OPEN_READ_WRITE, ("could not open %s: %s", blitter_video_sink->framebuffer_name, strerror(errno)), (NULL));
		return FALSE;
	}

	if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
	{
		close(fd);
		GST_ERROR_OBJECT(blitter_video_sink, "could not get fixed screen info: %s", strerror(errno));
		return FALSE;
	}

	if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) == -1)
	{
		close(fd);
		GST_ERROR_OBJECT(blitter_video_sink, "could not get variable screen info: %s", strerror(errno));
		return FALSE;
	}


	/* Copy FD, variable and fixed screen information structs
	 * These are also needed during the vsync setup below*/
	blitter_video_sink->framebuffer_fd = fd;
	blitter_video_sink->fb_var = fb_var;
	blitter_video_sink->fb_fix = fb_fix;


	/* Set up vsync (vsync is done via page flipping) */
	if (blitter_video_sink->use_vsync)
	{
		/* Check how many pages can currently be used. If this number is
		 * less than 3, reconfigure the framebuffer to allow for 3 pages.
		 * See the explanation at the set_property PROP_USE_VSYNC block
		 * for the reason why three pages are expected instead of 2. */

		guint cur_num_pages = fb_var.yres_virtual / fb_var.yres;
		if (cur_num_pages < 3)
		{
			GST_INFO_OBJECT(
				blitter_video_sink,
				"framebuffer configuration:  resolution is %u x %u , virtual %u x %u => need to reconfigure virtual height",
				fb_var.xres, fb_var.yres,
				fb_var.xres_virtual, fb_var.yres_virtual
			);
			if (!gst_imx_blitter_video_sink_reconfigure_fb(blitter_video_sink, 3))
			{
				GST_ERROR_OBJECT(blitter_video_sink, "could not reconfigure framebuffer");
				close(fd);
				blitter_video_sink->framebuffer_fd = -1;
				return FALSE;
			}
		}
		else
		{
			GST_INFO_OBJECT(
				blitter_video_sink,
				"framebuffer configuration:  resolution is %u x %u , virtual %u x %u => don't need to reconfigure virtual height",
				fb_var.xres, fb_var.yres,
				fb_var.xres_virtual, fb_var.yres_virtual
			);
		}

		/* Fetch fixed screen info again in case it changed after the FB reconfiguration */
		if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
		{
			GST_ERROR_OBJECT(blitter_video_sink, "could not open get fixed screen info: %s", strerror(errno));
			close(fd);
			blitter_video_sink->framebuffer_fd = -1;
			return FALSE;
		}

		/* Update the fixed screen info copy */
		blitter_video_sink->fb_fix = fb_fix;
	}


	/* Get width, height, format for framebuffer */
	fb_width = fb_var.xres;
	fb_height = fb_var.yres;
	fb_format = gst_imx_blitter_video_sink_get_format_from_fb(blitter_video_sink, &fb_var, &fb_fix);
	if (fb_format == GST_VIDEO_FORMAT_UNKNOWN)
	{
		GST_ELEMENT_ERROR(blitter_video_sink, RESOURCE, OPEN_READ_WRITE, ("framebuffer has unknown format"), (NULL));
		return FALSE;
	}


	/* Construct framebuffer and add meta to it
	 * Note: not adding any GstMemory blocks, since none are needed */
	buffer = gst_buffer_new();
	gst_buffer_add_video_meta(buffer, GST_VIDEO_FRAME_FLAG_NONE, fb_format, fb_width, fb_height);
	phys_mem_meta = GST_IMX_PHYS_MEM_META_ADD(buffer);
	phys_mem_meta->phys_addr = (gst_imx_phys_addr_t)(fb_fix.smem_start);


	/* Set up framebuffer related information */
	blitter_video_sink->framebuffer = buffer;
	blitter_video_sink->framebuffer_fd = fd;
	blitter_video_sink->framebuffer_region.x1 = 0;
	blitter_video_sink->framebuffer_region.y1 = 0;
	blitter_video_sink->framebuffer_region.x2 = fb_width;
	blitter_video_sink->framebuffer_region.y2 = fb_height;
	GST_INFO_OBJECT(blitter_video_sink, "framebuffer FD is %d", blitter_video_sink->framebuffer_fd);


	/* Create videoinfo structure for the framebuffer */
	gst_video_info_set_format(&(blitter_video_sink->output_video_info), fb_format, fb_width, fb_height);


	/* New framebuffer means the canvas most likely changed -> update */
	blitter_video_sink->canvas_needs_update = TRUE;


	/* If a blitter is present, set its output video info
	 * and output frame, since these two items changed */
	if (blitter_video_sink->blitter != NULL)
	{
		ret = ret && gst_imx_blitter_set_output_video_info(blitter_video_sink->blitter, &(blitter_video_sink->output_video_info));
		ret = ret && gst_imx_blitter_set_output_frame(blitter_video_sink->blitter, blitter_video_sink->framebuffer);
		ret = ret && gst_imx_blitter_set_num_output_pages(blitter_video_sink->blitter, blitter_video_sink->use_vsync ? 3 : 1);
	}

	if (!ret)
	{
		close(fd);
		blitter_video_sink->framebuffer_fd = -1;
	}

	return ret;
}