Skip to content

Commit 80f83f7

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 29197ac commit 80f83f7

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
@@ -25,7 +25,6 @@
2525
#include <zephyr/device.h>
2626
#include <stddef.h>
2727
#include <zephyr/kernel.h>
28-
2928
#include <zephyr/types.h>
3029

3130
#ifdef __cplusplus
@@ -205,6 +204,71 @@ struct video_frmival_enum {
205204
};
206205
};
207206

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

411+
/**
412+
* @typedef video_api_get_stats_t
413+
* @brief Register/Unregister poll signal for buffer events.
414+
*
415+
* See video_set_signal() for argument descriptions.
416+
* @param dev Pointer to the device structure.
417+
* @param ep Endpoint ID.
418+
* @param stats Pointer to the statistics structure, which must have enough storage for the
419+
type of stats requested by the @p stats flags.
420+
*/
421+
typedef int (*video_api_get_stats_t)(const struct device *dev, enum video_endpoint_id ep,
422+
struct video_stats *stats);
423+
347424
__subsystem struct video_driver_api {
348425
/* mandatory callbacks */
349426
video_api_set_format_t set_format;
@@ -360,6 +437,7 @@ __subsystem struct video_driver_api {
360437
video_api_set_frmival_t set_frmival;
361438
video_api_get_frmival_t get_frmival;
362439
video_api_enum_frmival_t enum_frmival;
440+
video_api_get_stats_t get_stats;
363441
};
364442

365443
/**
@@ -496,6 +574,39 @@ static inline int video_enum_frmival(const struct device *dev, enum video_endpoi
496574
return api->enum_frmival(dev, ep, fie);
497575
}
498576

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

0 commit comments

Comments
 (0)