コード例 #1
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static void gst_imx_blitter_video_sink_close_framebuffer_device(GstImxBlitterVideoSink *blitter_video_sink)
{
	/* must be called with lock held */

	g_assert(blitter_video_sink != NULL);

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

	GST_INFO_OBJECT(blitter_video_sink, "closing framebuffer %s with FD %d", blitter_video_sink->framebuffer_name, blitter_video_sink->framebuffer_fd);

	if (blitter_video_sink->blitter != NULL)
	{
		/* switch back to the first page if vsync was used */
		if (blitter_video_sink->use_vsync)
		{
			GST_DEBUG_OBJECT(blitter_video_sink, "cleaning up page flipping by flipping to page 0");
			gst_imx_blitter_video_sink_select_fb_page(blitter_video_sink, 0);
			gst_imx_blitter_video_sink_flip_to_selected_fb_page(blitter_video_sink);

			if (blitter_video_sink->original_fb_virt_height != 0)
				gst_imx_blitter_video_sink_restore_original_fb_config(blitter_video_sink);
		}

		gst_imx_blitter_flush(blitter_video_sink->blitter);
	}

	gst_buffer_unref(blitter_video_sink->framebuffer);
	close(blitter_video_sink->framebuffer_fd);
	blitter_video_sink->framebuffer = NULL;
	blitter_video_sink->framebuffer_fd = -1;
}
コード例 #2
0
ファイル: blitter.c プロジェクト: FrankBau/gstreamer-imx
static void gst_imx_blitter_dispose(GObject *object)
{
	GstImxBlitter *blitter = GST_IMX_BLITTER(object);

	gst_imx_blitter_flush(blitter);

	if (blitter->dma_bufferpool != NULL)
	{
		gst_object_unref(GST_OBJECT(blitter->dma_bufferpool));
		blitter->dma_bufferpool = NULL;
	}

	G_OBJECT_CLASS(gst_imx_blitter_parent_class)->dispose(object);
}
コード例 #3
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static gboolean gst_imx_blitter_video_sink_event(GstBaseSink *sink, GstEvent *event)
{
	GstImxBlitterVideoSink *blitter_video_sink = GST_IMX_BLITTER_VIDEO_SINK(sink);

	switch (GST_EVENT_TYPE(event))
	{
		case GST_EVENT_FLUSH_STOP:
		{
			GST_IMX_BLITTER_VIDEO_SINK_LOCK(blitter_video_sink);
			if (blitter_video_sink->blitter != NULL)
				gst_imx_blitter_flush(blitter_video_sink->blitter);
			GST_IMX_BLITTER_VIDEO_SINK_UNLOCK(blitter_video_sink);

			break;
		}

		default:
			break;
	}

	return GST_BASE_SINK_CLASS(gst_imx_blitter_video_sink_parent_class)->event(sink, event);
}
コード例 #4
0
static gboolean gst_imx_blitter_video_transform_sink_event(GstBaseTransform *transform, GstEvent *event)
{
	GstImxBlitterVideoTransform *blitter_video_transform = GST_IMX_BLITTER_VIDEO_TRANSFORM(transform);

	switch (GST_EVENT_TYPE(event))
	{
		case GST_EVENT_FLUSH_STOP:
		{
			GST_IMX_BLITTER_VIDEO_TRANSFORM_LOCK(blitter_video_transform);
			if (blitter_video_transform->blitter != NULL)
				gst_imx_blitter_flush(blitter_video_transform->blitter);
			GST_IMX_BLITTER_VIDEO_TRANSFORM_UNLOCK(blitter_video_transform);

			break;
		}

		default:
			break;
	}

	return GST_BASE_TRANSFORM_CLASS(gst_imx_blitter_video_transform_parent_class)->sink_event(transform, event);
}
コード例 #5
0
ファイル: video_sink.c プロジェクト: RafaelPita/gstreamer-imx
static GstFlowReturn gst_imx_blitter_video_sink_show_frame(GstVideoSink *video_sink, GstBuffer *buf)
{
	GstImxBlitterVideoSink *blitter_video_sink = GST_IMX_BLITTER_VIDEO_SINK_CAST(video_sink);
	GstVideoCropMeta *video_crop_meta;

	GST_IMX_BLITTER_VIDEO_SINK_LOCK(blitter_video_sink);

	if (blitter_video_sink->input_crop && ((video_crop_meta = gst_buffer_get_video_crop_meta(buf)) != NULL))
	{
		/* Crop metadata present. Reconfigure canvas. */

		GstImxRegion source_region;
		source_region.x1 = video_crop_meta->x;
		source_region.y1 = video_crop_meta->y;
		source_region.x2 = video_crop_meta->x + video_crop_meta->width;
		source_region.y2 = video_crop_meta->y + video_crop_meta->height;

		/* Make sure the source region does not exceed valid bounds */
		source_region.x1 = MAX(0, source_region.x1);
		source_region.y1 = MAX(0, source_region.y1);
		source_region.x2 = MIN(GST_VIDEO_INFO_WIDTH(&(blitter_video_sink->input_video_info)), source_region.x2);
		source_region.y2 = MIN(GST_VIDEO_INFO_HEIGHT(&(blitter_video_sink->input_video_info)), source_region.y2);

		GST_LOG_OBJECT(blitter_video_sink, "retrieved crop rectangle %" GST_IMX_REGION_FORMAT, GST_IMX_REGION_ARGS(&source_region));

		/* Canvas needs to be updated if either one of these applies:
		 * - the current frame has crop metadata, the last one didn't
		 * - the new crop rectangle and the last are different */
		if (!(blitter_video_sink->last_frame_with_cropdata) || !gst_imx_region_equal(&source_region, &(blitter_video_sink->last_source_region)))
		{
			GST_LOG_OBJECT(blitter_video_sink, "using new crop rectangle %" GST_IMX_REGION_FORMAT, GST_IMX_REGION_ARGS(&source_region));
			blitter_video_sink->last_source_region = source_region;
			blitter_video_sink->canvas_needs_update = TRUE;
		}

		blitter_video_sink->last_frame_with_cropdata = TRUE;

		/* Update canvas and input region if necessary */
		if (blitter_video_sink->canvas_needs_update)
			gst_imx_blitter_video_sink_update_canvas(blitter_video_sink, &(blitter_video_sink->last_source_region));
	}
	else
	{
		/* Force an update if this frame has no crop metadata but the last one did */
		if (blitter_video_sink->last_frame_with_cropdata)
			blitter_video_sink->canvas_needs_update = TRUE;
		blitter_video_sink->last_frame_with_cropdata = FALSE;

		/* Update canvas and input region if necessary */
		if (blitter_video_sink->canvas_needs_update)
			gst_imx_blitter_video_sink_update_canvas(blitter_video_sink, NULL);
	}

	if (blitter_video_sink->canvas.visibility_mask == 0)
	{
		/* Visibility mask 0 -> nothing to blit */
		GST_IMX_BLITTER_VIDEO_SINK_UNLOCK(blitter_video_sink);
		return GST_FLOW_OK;
	}

	gst_imx_blitter_set_input_frame(blitter_video_sink->blitter, buf);

	/* If using vsync, blit to the backbuffer, and flip
	 * The flipping is done by scrolling in Y direction
	 * by the same number of rows as there are on screen
	 * The scrolling is implicitely vsync'ed */
	if (blitter_video_sink->use_vsync)
	{
		/* Select which page to write/blit to */
		++blitter_video_sink->old_fb_page;
		blitter_video_sink->old_fb_page %= 3;
		gst_imx_blitter_video_sink_select_fb_page(blitter_video_sink, blitter_video_sink->old_fb_page);

		/* The actual blitting */
		gst_imx_blitter_blit(blitter_video_sink->blitter, 255);
		/* Flush the blitter to make sure it does not use any cached output
		 * information (for example, the physical address of the previously
		 * selected fb page) */
		gst_imx_blitter_flush(blitter_video_sink->blitter);

		/* Move the current_fb_page index to the next page. See the explanation
		 * at the set_property PROP_USE_VSYNC block for the reason why three
		 * pages are expected instead of 2. */
		blitter_video_sink->current_fb_page++;
		blitter_video_sink->current_fb_page %= 3;

		/* Flip pages now */
		gst_imx_blitter_video_sink_flip_to_selected_fb_page(blitter_video_sink);
	}
	else
	{
		gst_imx_blitter_blit(blitter_video_sink->blitter, 255);
	}

	GST_IMX_BLITTER_VIDEO_SINK_UNLOCK(blitter_video_sink);

	return GST_FLOW_OK;
}