]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: vimc: streamer: Apply sensor frame rate in streamer thread
authorFaizel K B <faizel.kb@gmail.com>
Thu, 12 Mar 2026 23:16:16 +0000 (16:16 -0700)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Tue, 17 Mar 2026 09:50:19 +0000 (10:50 +0100)
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: Faizel K B <faizel.kb@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/test-drivers/vimc/vimc-streamer.c

index 15d863f97cbf96b7ca7fbf3d7b6b6ec39fcc8ae3..3ebf5798fa3d55fe93d16b5092913d7144ec7241 100644 (file)
@@ -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;