Skip to content

Commit 2931381

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 413043b commit 2931381

File tree

1 file changed

+116
-1
lines changed

1 file changed

+116
-1
lines changed

include/zephyr/drivers/video.h

Lines changed: 116 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,75 @@ 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 any statistics compatible with a @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 any statistics compatible with a @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+
/** Storage for the histogram buckets for Y, R, G, B channels in this order.
262+
* The presence of a channel is determined by the bits of @c base.flags.
263+
*/
264+
uint16_t *data;
265+
/** Total number of buckets effectively used, to be divided by the number of channels to
266+
* get the per-channel size.
267+
*/
268+
size_t size;
269+
/** Total number of values added to the historam. */
270+
uint32_t nval;
271+
};
272+
205273
/**
206274
* @brief video_endpoint_id enum
207275
*
@@ -348,6 +416,19 @@ typedef int (*video_api_get_caps_t)(const struct device *dev, enum video_endpoin
348416
typedef int (*video_api_set_signal_t)(const struct device *dev, enum video_endpoint_id ep,
349417
struct k_poll_signal *signal);
350418

419+
/**
420+
* @typedef video_api_get_stats_t
421+
* @brief Register/Unregister poll signal for buffer events.
422+
*
423+
* See video_set_signal() for argument descriptions.
424+
* @param dev Pointer to the device structure.
425+
* @param ep Endpoint ID.
426+
* @param stats Pointer to the statistics structure, which must have enough storage for the
427+
type of stats requested by the @p stats flags.
428+
*/
429+
typedef int (*video_api_get_stats_t)(const struct device *dev, enum video_endpoint_id ep,
430+
struct video_stats *stats);
431+
351432
__subsystem struct video_driver_api {
352433
/* mandatory callbacks */
353434
video_api_set_format_t set_format;
@@ -364,6 +445,7 @@ __subsystem struct video_driver_api {
364445
video_api_set_frmival_t set_frmival;
365446
video_api_get_frmival_t get_frmival;
366447
video_api_enum_frmival_t enum_frmival;
448+
video_api_get_stats_t get_stats;
367449
};
368450

369451
/**
@@ -500,6 +582,39 @@ static inline int video_enum_frmival(const struct device *dev, enum video_endpoi
500582
return api->enum_frmival(dev, ep, fie);
501583
}
502584

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

0 commit comments

Comments
 (0)