Skip to content

Commit d224270

Browse files
committed
drivers: video: introduce an API for collecting statistics
Introduce an abstraction layer handling the diversity of ways hardware have to report statistics. This allows to take advantage of the various channel average or histograms present on some hardware, that skip the need to manually compute statistics. Fixes #85457 Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent a1b904f commit d224270

File tree

1 file changed

+112
-1
lines changed

1 file changed

+112
-1
lines changed

include/zephyr/drivers/video.h

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include <zephyr/device.h>
2525
#include <stddef.h>
2626
#include <zephyr/kernel.h>
27-
2827
#include <zephyr/types.h>
2928

3029
#ifdef __cplusplus
@@ -202,6 +201,71 @@ struct video_frmival_enum {
202201
};
203202
};
204203

204+
/** Custom statistics allowing applications to implement their own format. */
205+
#define VIDEO_STATS_CUSTOM BIT(0)
206+
207+
/** Channel statistics for the Y (luma) channel. */
208+
#define VIDEO_STATS_CHANNELS_Y BIT(1)
209+
210+
/** Channel statistics for the R, G, B channels. */
211+
#define VIDEO_STATS_CHANNELS_RGB BIT(2)
212+
213+
/** Bitmap to ask for all statistics compatible with @struct video_stats_channels */
214+
#define VIDEO_STATS_CHANNELS (VIDEO_STATS_CHANNELS_RGB | VIDEO_STATS_CHANNELS_Y)
215+
216+
/** Statistics in the form of an histogram with the Y (luma) channel present. */
217+
#define VIDEO_STATS_HISTOGRAM_Y BIT(3)
218+
219+
/** Statistics in the form of an histogram with the R, G, B channels present. */
220+
#define VIDEO_STATS_HISTOGRAM_RGB BIT(4)
221+
222+
/** Bitmap to ask for one of the statistics compatible with @struct video_stats_histogram */
223+
#define VIDEO_STATS_HISTOGRAM (VIDEO_STATS_HISTOGRAM_RGB | VIDEO_STATS_HISTOGRAM_Y)
224+
225+
/**
226+
* @brief Statistics base type, present as the first field of the other types.
227+
*
228+
* This type is to be casted to one of the other "video_..._stats" types. This permits to define
229+
* new custom types in application and still use the upstream video API.
230+
*/
231+
struct video_stats {
232+
/** Bitmak that describes the type of the stats filled */
233+
uint16_t flags;
234+
/** Frame counter to know if a frame elapsed since the last call. Quickly overflowing. */
235+
uint16_t frame_counter;
236+
};
237+
238+
/**
239+
* @brief Per-channel average values.
240+
*
241+
* Each field represent 8-bit integer values that corresponds to the average value of a channel.
242+
*/
243+
struct video_stats_channels {
244+
/** Base structure with fields common to all types of statistics. */
245+
struct video_stats base;
246+
/** The luma channel average. */
247+
uint8_t y;
248+
/** RGB24-formatted averages. */
249+
uint8_t rgb[3];
250+
};
251+
252+
/**
253+
* @brief Statistics about the video image color content.
254+
*
255+
* Used by software algorithms to control the color balance such as White Balance (AWB),
256+
* Black Level Correction (BLC), or control sensors such as Exposure/Gain Control (AEC/AGC).
257+
*/
258+
struct video_stats_histogram {
259+
/** Base structure with fields common to all types of statistics. */
260+
struct video_stats base;
261+
/** The histogram content for the Y or the R, G, B channels as defined by @c base.flags. */
262+
uint16_t *buckets;
263+
/** Total number of values in @c buckets. */
264+
size_t num_buckets;
265+
/** Total number of values added to the historam. */
266+
uint32_t num_values;
267+
};
268+
205269
/**
206270
* @brief video_endpoint_id enum
207271
*
@@ -348,6 +412,19 @@ typedef int (*video_api_get_caps_t)(const struct device *dev, enum video_endpoin
348412
typedef int (*video_api_set_signal_t)(const struct device *dev, enum video_endpoint_id ep,
349413
struct k_poll_signal *signal);
350414

415+
/**
416+
* @typedef video_api_get_stats_t
417+
* @brief Register/Unregister poll signal for buffer events.
418+
*
419+
* See video_set_signal() for argument descriptions.
420+
* @param dev Pointer to the device structure.
421+
* @param ep Endpoint ID.
422+
* @param stats Pointer to the statistics structure, which must have enough storage for the
423+
type of stats requested by the @p stats flags.
424+
*/
425+
typedef int (*video_api_get_stats_t)(const struct device *dev, enum video_endpoint_id ep,
426+
struct video_stats *stats);
427+
351428
__subsystem struct video_driver_api {
352429
/* mandatory callbacks */
353430
video_api_set_format_t set_format;
@@ -364,6 +441,7 @@ __subsystem struct video_driver_api {
364441
video_api_set_frmival_t set_frmival;
365442
video_api_get_frmival_t get_frmival;
366443
video_api_enum_frmival_t enum_frmival;
444+
video_api_get_stats_t get_stats;
367445
};
368446

369447
/**
@@ -500,6 +578,39 @@ static inline int video_enum_frmival(const struct device *dev, enum video_endpoi
500578
return api->enum_frmival(dev, ep, fie);
501579
}
502580

581+
/**
582+
* @brief Get image statistics out of the video devices.
583+
*
584+
* This permits to implement algorithms reacting to statistics about the images
585+
* collected by the hadware. For instance, in order to implement an image signal
586+
* processor with auto-controls (AEC, AGC, AWB...).
587+
*
588+
* The driver will read the @p stats flags fields to learn about what the caller wants for
589+
* statistics, and update them with the statistics effectively added.
590+
*
591+
* All memory buffers of @p stats are to be provided by the caller, and the driver will update
592+
* the @c size field with the size effectively filled with statistics data.
593+
*
594+
* @param dev Pointer to the device structure that collects the statistics.
595+
* @param ep Endpoint ID from which collect the statistics.
596+
* @param stats Pointer to a video statistic structure filled by this device.
597+
*
598+
* @retval 0 If successful.
599+
* @retval -ENOSYS If API is not implemented.
600+
* @return other error number otherwise.
601+
*/
602+
static inline int video_get_stats(const struct device *dev, enum video_endpoint_id ep,
603+
struct video_stats *stats)
604+
{
605+
const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
606+
607+
if (api->get_stats == NULL) {
608+
return -ENOSYS;
609+
}
610+
611+
return api->get_stats(dev, ep, stats);
612+
}
613+
503614
/**
504615
* @brief Enqueue a video buffer.
505616
*

0 commit comments

Comments
 (0)