Commit 24ae633a authored by Faizel K B's avatar Faizel K B Committed by Hans Verkuil
Browse files

media: vimc: streamer: Apply sensor frame rate in streamer thread



Use the sensor's pre-calculated jiffies value to add appropriate
delay between frames according to the configured timing value.
The actual frame rate  will vary depending on processing delays in
other media pipeline components.

Tested using yavta frame rate display with QCIF resolution:
yavta <video-node> --capture=<no_of_frames>

Signed-off-by: default avatarFaizel K B <faizel.kb@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil+cisco@kernel.org>
parent ec1e620b
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -139,6 +139,29 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
	return -EINVAL;
}

/**
 * vimc_streamer_get_sensor() - Get sensor from pipeline
 * @stream: the pipeline
 *
 * Helper function to find the sensor device in the pipeline.
 * Returns pointer to sensor device or NULL if not found.
 */
static struct vimc_sensor_device *vimc_streamer_get_sensor(struct vimc_stream *stream)
{
	int i;

	for (i = 0; i < stream->pipe_size; i++) {
		struct vimc_ent_device *ved = stream->ved_pipeline[i];

		if (ved && ved->ent &&
		    ved->ent->function == MEDIA_ENT_F_CAM_SENSOR) {
			return container_of(ved, struct vimc_sensor_device, ved);
		}
	}

	return NULL;
}

/**
 * vimc_streamer_thread - Process frames through the pipeline
 *
@@ -154,25 +177,31 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
static int vimc_streamer_thread(void *data)
{
	struct vimc_stream *stream = data;
	struct vimc_sensor_device *vsensor;
	u8 *frame = NULL;
	int i;
	unsigned long fps_jiffies;
	const unsigned long default_jiffies = HZ / 30;

	set_freezable();
	vsensor = vimc_streamer_get_sensor(stream);

	for (;;) {
		try_to_freeze();
		if (kthread_should_stop())
			break;

		/* Read from hardware configuration */
		fps_jiffies = vsensor ? vsensor->hw.fps_jiffies : default_jiffies;

		for (i = stream->pipe_size - 1; i >= 0; i--) {
			frame = stream->ved_pipeline[i]->process_frame(
					stream->ved_pipeline[i], frame);
			if (!frame || IS_ERR(frame))
				break;
		}
		//wait for 60hz
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(HZ / 60);
		schedule_timeout(fps_jiffies);
	}

	return 0;