#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/autoconf.h>
#include <linux/vmalloc.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/elphel/driver_numbers.h>
#include <asm/elphel/c313a.h>
#include <asm/elphel/exifa.h>
#include "fpgactrl.h"
#include "fpga_io.h"
#include "framepars.h"
#include "histograms.h"
Include dependency graph for histograms.c:
Go to the source code of this file.
Data Structures | |
struct | histograms_pd |
wait queue for all the other (R,G2,B) histograms (color) More... | |
Defines | |
#define | MDF21(x) |
#define | MDF22(x) |
#define | X3X3_HISTOGRAMS_DRIVER_NAME "Elphel (R) Model 353 Histograms device driver" |
#define | HISTOGRAMS_FILE_SIZE HISTOGRAM_CACHE_NUMBER |
Functions | |
static struct histogram_stuct_t histograms[HISTOGRAM_CACHE_NUMBER] | __attribute__ ((aligned(PAGE_SIZE))) |
int | histograms_open (struct inode *inode, struct file *file) |
Histograms driver OPEN method. | |
int | histograms_release (struct inode *inode, struct file *file) |
Histograms driver RELEASE method. | |
loff_t | histograms_lseek (struct file *file, loff_t offset, int orig) |
TODO: add flag that will allow driver to wakeup processes before the specified frame comes ? | |
int | histograms_mmap (struct file *file, struct vm_area_struct *vma) |
Histograms driver MMAP method to read out the histogram data (raw and calculated). | |
static int __init | histograms_init (void) |
Histograms driver init. | |
void | histogram_calc_cumul (unsigned long *hist, unsigned long *cumul_hist) |
calculate cumulative histogram (one color component) from the corresponding raw histogram | |
void | histogram_calc_percentiles (unsigned long *cumul_hist, unsigned char *percentile) |
Calculate reverse cumulative histograms (~percentiles) The reverse cumulative histogram (~percentiles) works as the following: for the given 1 byte input X (0 - 1/256 of all pixels, * ..., 255 - all pixels) it returns threshold value P (0..255), so that number of pixels with value less than x is less or equal to (P/256)*total_number_of_pixels, and number of pixels with value less than (x+1) is greater than (P/256)*total_number_of_pixels, P(0)=0, P(256)=256 (not included in the table). | |
void | init_histograms (void) |
wait queue for all the other (R,G2,B) histograms (color) | |
int | set_histograms (unsigned long frame, int needed, unsigned long *gammaHash) |
Get histograms from the FPGA (called as tasklet?). | |
int | get_histograms (unsigned long frame, int needed) |
Get histograms from the FPGA (called as tasklet?) and/or calculate derivatives (if needed). | |
module_init (histograms_init) | |
MODULE_LICENSE ("GPLv3.0") | |
MODULE_AUTHOR ("Andrey Filippov <andrey@elphel.com>.") | |
MODULE_DESCRIPTION (X3X3_HISTOGRAMS_DRIVER_NAME) | |
Variables | |
histogram_stuct_t * | histograms_p |
wait_queue_head_t | hist_y_wait_queue |
wait_queue_head_t | hist_c_wait_queue |
wait queue for the G1 histogram (used as Y) | |
static struct file_operations | histograms_fops |
#define HISTOGRAMS_FILE_SIZE HISTOGRAM_CACHE_NUMBER |
Definition at line 333 of file histograms.c.
Referenced by histograms_lseek(), and histograms_open().
#define MDF21 | ( | x | ) |
Definition at line 120 of file histograms.c.
Referenced by get_histograms(), histograms_lseek(), histograms_mmap(), histograms_open(), histograms_release(), and init_histograms().
#define MDF22 | ( | x | ) |
#define X3X3_HISTOGRAMS_DRIVER_NAME "Elphel (R) Model 353 Histograms device driver" |
static struct histogram_stuct_t histograms [HISTOGRAM_CACHE_NUMBER] __attribute__ | ( | (aligned(PAGE_SIZE)) | ) | [static] |
int get_histograms | ( | unsigned long | frame, | |
int | needed | |||
) |
Get histograms from the FPGA (called as tasklet?) and/or calculate derivatives (if needed).
frame | absolute frame number (Caller should match it to the hardware frame). TODO: should it be one frame behind current? - yes, exactly | |
needed | bits specify what histograms (color, type) are requested TODO: Add P_* parameter - what to read from tasklet, turn colors it off for high FPS/small window each group of 4 bits cover 4 colors of the same type:
|
if Y - never calculated, if C - maybe all the cache is used by Y
mask out FPGA read requests -= they are not handled here anymore (use set_histograms())
cumulative histograms are needed for percentile calculations
if ((needed >> 4) & (~histograms[index].valid) & 0x0f) return -2 ; /// some needed raw histograms are not available NOTE: now never comes here
Calculating cumulative histograms
Calculating percentiles
Definition at line 231 of file histograms.c.
References ELP_KERR, G_HIST_LAST_INDEX, GLOBALPARS, hist, HISTOGRAM_CACHE_NUMBER, histogram_calc_cumul(), histogram_calc_percentiles(), MDF21, MDF22, printk, and histogram_stuct_t::valid.
Referenced by histograms_lseek().
void histogram_calc_cumul | ( | unsigned long * | hist, | |
unsigned long * | cumul_hist | |||
) | [inline] |
calculate cumulative histogram (one color component) from the corresponding raw histogram
hist | input raw histogram array of unsigned long, single color (256) | |
cumul_hist | output cumulative histogram array of unsigned long, single color (256) |
Definition at line 276 of file histograms.c.
Referenced by get_histograms().
void histogram_calc_percentiles | ( | unsigned long * | cumul_hist, | |
unsigned char * | percentile | |||
) | [inline] |
Calculate reverse cumulative histograms (~percentiles) The reverse cumulative histogram (~percentiles) works as the following: for the given 1 byte input X (0 - 1/256 of all pixels, * ..., 255 - all pixels) it returns threshold value P (0..255), so that number of pixels with value less than x is less or equal to (P/256)*total_number_of_pixels, and number of pixels with value less than (x+1) is greater than (P/256)*total_number_of_pixels, P(0)=0, P(256)=256 (not included in the table).
Percentiles arrays are calculated without division for each element, interpolation (involving division) will be done only for the value of interest on demand, in the user space.
NOTE: - argument is FPGA pixel output-to-videoRAM value (after gamma-correction), reverse gamma table is needed to relate percentiles to amount of light (proportional to exposure)
Current algorithm will work up to 16 MPix/color_component (64 MPix total)
cumul_hist | ||
percentile |
running value to be compared against cumulative histogram (it is 256 larger than cumul_hist)
step of v256 increment
to protect from unlikely overflow at 16MPix - in the future)
current value of percentile
current percentile index
Definition at line 300 of file histograms.c.
References x.
Referenced by get_histograms().
static int __init histograms_init | ( | void | ) | [static] |
Histograms driver init.
wait queue for the G1 histogram (used as Y)
wait queue for all the other (R,G2,B) histograms (color)
Definition at line 544 of file histograms.c.
References hist_c_wait_queue, hist_y_wait_queue, histograms_fops, HISTOGRAMS_MAJOR, init_histograms(), init_waitqueue_head, KERN_ERR, printk, and X3X3_HISTOGRAMS_DRIVER_NAME.
loff_t histograms_lseek | ( | struct file * | file, | |
loff_t | offset, | |||
int | orig | |||
) |
TODO: add flag that will allow driver to wakeup processes before the specified frame comes ?
file | ||
offset | ||
orig | SEEK_SET, SEEK_CUR or SEEK_SET END |
ignore offset
Try to make some precautions to avoid waiting forever - if the past frame is requested - request histogram for the current frame, if the "immediate" future (fits into the array of frames) one - request that frame's histogram if in the far future (unsafe) do nothing -NOTE: far future should be avoided if the histograms are set request-only NOTE: there could be another wrong condition - request written w/o "JUST_THIS" modifier - then it will turn to always on until cleared. TODO: Save time on always enabled histograms? Don't request them additionally?
if the requested frame is in the past - try to get it first before requesting a new
request histogram(s)
make sure (harmful) interrupt did not happen since getThisFrameNumber()
just in case
enable requesting histogram for the specified frame (0 - rely on the available ones)
default after open
disable requesting histogram for the specified frame, rely on the available ones
set histogram waiting for the Y (actually G1) histogram (default after open)
set histogram waiting for the C (actually R, G2, B) histograms to become available - implies G1 too
wait for daemon enabled and histograms Y ready
wait for daemon enabled and histograms Y ready
not SEEK_SET/SEEK_CUR/SEEK_END
switch (orig)
other minors
Definition at line 418 of file histograms.c.
References CMOSCAM_MINOR_HISTOGRAMS, histograms_pd::frame, histograms_pd::frame_index, framepars, G_HIST_C_FRAME, G_HIST_Y_FRAME, get_histograms(), get_imageParamsThis, getThisFrameNumber(), GLOBALPARS, hist_c_wait_queue, hist_y_wait_queue, HISTOGRAMS_FILE_SIZE, LSEEK_DAEMON_HIST_C, LSEEK_DAEMON_HIST_Y, LSEEK_HIST_NEEDED, LSEEK_HIST_REQ_DIS, LSEEK_HIST_REQ_EN, LSEEK_HIST_WAIT_C, LSEEK_HIST_WAIT_Y, MDF21, histograms_pd::minor, histograms_pd::needed, P_DAEMON_EN, P_HISTRQ_C, P_HISTRQ_Y, PARS_FRAMES_MASK, printk, histograms_pd::request_en, SEEK_CUR, SEEK_END, SEEK_SET, setFramePar(), and histograms_pd::wait_mode.
int histograms_mmap | ( | struct file * | file, | |
struct vm_area_struct * | vma | |||
) |
Histograms driver MMAP method to read out the histogram data (raw and calculated).
file | ||
vma |
Should be page-aligned
Definition at line 522 of file histograms.c.
References CMOSCAM_MINOR_HISTOGRAMS, histograms_p, MDF21, histograms_pd::minor, and printk.
int histograms_open | ( | struct inode * | inode, | |
struct file * | file | |||
) |
Histograms driver OPEN method.
inode | inode | |
file | file pointer |
0 - wait just for G1 histogram, 1 - wait for all histograms
enable requesting histogram for the specified frame (0 - rely on the available ones)
Definition at line 348 of file histograms.c.
References CMOSCAM_MINOR_HISTOGRAMS, histograms_pd::frame, histograms_pd::frame_index, GFP_KERNEL, HISTOGRAMS_FILE_SIZE, kfree, kmalloc, MDF21, histograms_pd::minor, histograms_pd::needed, printk, histograms_pd::request_en, and histograms_pd::wait_mode.
int histograms_release | ( | struct inode * | inode, | |
struct file * | file | |||
) |
Histograms driver RELEASE method.
inode | inode | |
file | file pointer |
do not need to free anything - "wrong number"
Definition at line 379 of file histograms.c.
References CMOSCAM_MINOR_HISTOGRAMS, kfree, MDF21, and printk.
void init_histograms | ( | void | ) |
wait queue for all the other (R,G2,B) histograms (color)
Definition at line 169 of file histograms.c.
References flags, frame, HISTOGRAM_CACHE_NUMBER, histograms_p, local_irq_restore, local_irq_save, MDF21, printk, and histogram_stuct_t::valid.
Referenced by histograms_init().
MODULE_AUTHOR | ( | "Andrey Filippov <andrey@elphel.com>." | ) |
MODULE_DESCRIPTION | ( | X3X3_HISTOGRAMS_DRIVER_NAME | ) |
module_init | ( | histograms_init | ) |
MODULE_LICENSE | ( | "GPLv3.0" | ) |
int set_histograms | ( | unsigned long | frame, | |
int | needed, | |||
unsigned long * | gammaHash | |||
) |
Get histograms from the FPGA (called as tasklet?).
frame | absolute frame number (Caller should match it to the hardware frame) TODO: should it be one frame behind current? | |
needed | bits specify what histograms (color, type) are requested | |
gammaHash | array of 4 hash32 values to be saved with the histograms each group of 4 bits cover 4 colors of the same type:
|
overwrite all
add to existent
remove those that are already available from the request
Definition at line 193 of file histograms.c.
References fpga_hist_read_nice(), histogram_stuct_t::frame, G_HIST_LAST_INDEX, GLOBALPARS, hist, HISTOGRAM_CACHE_NUMBER, memcpy(), and histogram_stuct_t::valid.
Referenced by tasklet_fpga_function().
wait_queue_head_t hist_c_wait_queue |
wait queue for the G1 histogram (used as Y)
Definition at line 131 of file histograms.c.
Referenced by histograms_init(), and histograms_lseek().
wait_queue_head_t hist_y_wait_queue |
These wait queues will be advanced each frame after the histogram data is transferred to the FPGA. It will happen even if the corresponding task is disabled, with the only exception: hist_c_wait_queue will not be awaken in the current frame if it is too late (frame counter incremented while serving tasklet)
Definition at line 130 of file histograms.c.
Referenced by histograms_init(), histograms_lseek(), and tasklet_fpga_function().
struct file_operations histograms_fops [static] |
Initial value:
{ owner: THIS_MODULE, llseek: histograms_lseek, open: histograms_open, mmap: histograms_mmap, release: histograms_release }
Definition at line 334 of file histograms.c.
Referenced by histograms_init().
struct histogram_stuct_t* histograms_p |
Definition at line 128 of file histograms.c.
Referenced by histograms_mmap(), and init_histograms().