Commit a2a841fa authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add PageNumber field to Exif and use it as sensor port number storage

parent 97a0469d
......@@ -176,12 +176,24 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi
}
ssize_t minor_max_size(int minor) { //return max file size for different minors
switch (minor) {
case X3X3_EXIF_TEMPLATE: return MAX_EXIF_SIZE;
case X3X3_EXIF_EXIF: return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case X3X3_EXIF_META: return MAX_EXIF_SIZE;
case X3X3_EXIF_METADIR: return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t);
case X3X3_EXIF_TIME: return sizeof(struct exif_time_t);
default:return 0;
case X3X3_EXIF_TEMPLATE:
return MAX_EXIF_SIZE;
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
return MAX_EXIF_SIZE;
case X3X3_EXIF_METADIR:
return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t);
case X3X3_EXIF_TIME:
return sizeof(struct exif_time_t);
default:
return 0;
}
}
void exif_invalidate(void) { // 393: OK, only invalidates all ayt once
......@@ -231,6 +243,7 @@ int exif_rebuild_chn(int sensor_port, int frames) {
return -1;
}
memset(meta_buffer, 0, aexif_meta_size[sensor_port] * (MAX_EXIF_FRAMES+1));
ameta_buffer[sensor_port] = meta_buffer;
aexif_valid[sensor_port] = 1;
return 0;
}
......@@ -507,7 +520,6 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
int maxsize=minor_max_size(p);
// int sensor_port;
int fp;
switch (orig) {
case SEEK_SET:
file->f_pos = offset;
......
......@@ -149,14 +149,15 @@ static struct image_acq_pd_t image_acq_priv;
static volatile int JPEG_wp;
static volatile int JPEG_rp;
static int fpga_counter_prev=0; /// Previous value of the FPGA transfer counter (to find out if it did change)
static struct meta_offsets_t { // works like a cache to time save on looking for tags in the directory (forced to recalcualte if does not match)
static struct meta_offsets_t { // works like a cache to time save on looking for tags in the directory (forced to recalculate if does not match)
int Image_DateTime; // will have offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page)
int Photo_DateTimeOriginal;
int Photo_ExposureTime;
int Image_FrameNumber;
int Image_Orientation;
int Photo_MakerNote;
} meta_offsets;
int PageNumber;
} meta_offsets;
#ifdef TEST_DISABLE_CODE
int camSeqGetJPEG_wp(void) {return JPEG_wp;}
......@@ -168,7 +169,7 @@ void camSeqSetJPEG_rp(int p) {
(((get_globalParam(G_CIRCBUFRP) <= get_globalParam(G_CIRCBUFWP))?
get_globalParam(G_CIRCBUFSIZE):0)+ get_globalParam(G_CIRCBUFRP))
- get_globalParam(G_CIRCBUFWP));
}
}
#endif /* TEST_DISABLE_CODE */
int camseq_get_jpeg_wp(unsigned int chn)
......@@ -190,7 +191,7 @@ void camseq_set_jpeg_rp(unsigned int chn, int ptr)
/*!
End of compressor-related code - TODO: move to a separate file?
*/
*/
static const struct of_device_id elphel393_sensor_of_match[];
static struct sensorproc_t as_sensorproc[SENSOR_PORTS]; // sensor parameters and functions to call
......@@ -251,7 +252,7 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
{
phys_addr_t phys_addr;
void *virt_addr;
// int prev_dword;
// int prev_dword;
int xferred; /// number of 32-byte chunks transferred since compressor was reset
x393_afimux_status_t stat = x393_afimux0_status(jptr->chn_num);
......@@ -275,53 +276,53 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
/* Correct frame length and re-adjust interframe params.
* This operations was scheduled on previous interrupt.
*/
// if (jptr->flags & SENS_FLAG_HW_OFF) {
// int len32;
// int len32_ptr = jptr->jpeg_wp - INTERFRAME_PARAMS_SZ - 1;
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + DW2BYTE(jptr->jpeg_wp) - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + jptr->jpeg_wp - INTERFRAME_PARAMS_SZ;
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr];
// len32 -= INTERFRAME_PARAMS_SZ;
// circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr] = len32;
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// jptr->flags &= ~SENS_FLAG_HW_OFF;
// }
// if (jptr->flags & SENS_FLAG_HW_OFF) {
// int len32;
// int len32_ptr = jptr->jpeg_wp - INTERFRAME_PARAMS_SZ - 1;
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + DW2BYTE(jptr->jpeg_wp) - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + jptr->jpeg_wp - INTERFRAME_PARAMS_SZ;
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr];
// len32 -= INTERFRAME_PARAMS_SZ;
// circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr] = len32;
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// jptr->flags &= ~SENS_FLAG_HW_OFF;
// }
/* Looks like compressor is not writing 32 zero bytes when last frame ends precisely at the
* end of buffer. Try to detect this situation and set a flag so that we can overwrite first
* 32 bytes of the buffer on next interrupt. These bytes will be used as interframe parameters and current frame length
* will be decreased by these 32 bytes. Such a measure will corrupt the frame but preserve the structure.
*/
// if (jptr->jpeg_wp == 0) {
// // we need to invalidate two cache lines in order to
// // estimate the situation correctly: one line after the pointer, which should be the line of
// // 32 bytes of newly compressed frame(or zero bytes?), and one line before the pointer, which should be the last line of the frame. If this is not done
// // then the data read from memory can be incorrect and error detection will give false result. Barrier is set to
// // prevent compiler from reordering operations.
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr;
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + CCAM_DMA_SIZE - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + BYTE2DW(CCAM_DMA_SIZE - CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// barrier();
// prev_dword = X393_BUFFSUB(DW2BYTE(jptr->jpeg_wp), 4);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp]);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)]);
//// if (circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] == 0x00 &&
// if ((circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] & MARKER_FF) == MARKER_FF) {
//// jptr->jpeg_wp += INTERFRAME_PARAMS_SZ;
// jptr->flags |= SENS_FLAG_HW_OFF;
// corrected_offset[jptr->chn_num] += 1;
// }
// }
// if (jptr->jpeg_wp == 0) {
// // we need to invalidate two cache lines in order to
// // estimate the situation correctly: one line after the pointer, which should be the line of
// // 32 bytes of newly compressed frame(or zero bytes?), and one line before the pointer, which should be the last line of the frame. If this is not done
// // then the data read from memory can be incorrect and error detection will give false result. Barrier is set to
// // prevent compiler from reordering operations.
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr;
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + CCAM_DMA_SIZE - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + BYTE2DW(CCAM_DMA_SIZE - CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// barrier();
// prev_dword = X393_BUFFSUB(DW2BYTE(jptr->jpeg_wp), 4);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp]);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)]);
//// if (circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] == 0x00 &&
// if ((circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] & MARKER_FF) == MARKER_FF) {
//// jptr->jpeg_wp += INTERFRAME_PARAMS_SZ;
// jptr->flags |= SENS_FLAG_HW_OFF;
// corrected_offset[jptr->chn_num] += 1;
// }
// }
// invalidate CPU L1 and L2 caches
// the code below was used to find cache coherence issues
......@@ -361,11 +362,11 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr)
inline static void set_default_interframe(struct interframe_params_t *params)
{
// params->height = 1936;
// params->width = 2592;
// params->height = 1936;
// params->width = 2592;
params->height = circbuf_height;
params->width = circbuf_width;
// params->byrshift = 3;
// params->byrshift = 3;
params->byrshift = circbuf_byrshift;
params->color = 0;
params->quality2 = circbuf_quality;
......@@ -422,39 +423,39 @@ inline struct interframe_params_t* updateIRQ_interframe(struct jpeg_ptr_t *jptr)
* @param interframe pointer to interframe parameters structure
*/
inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t* interframe) {
// int index_time = aJPEG_wp-11[sensor_port]; if (index_time<0) index_time+=get_globalParam (sensor_port, G_CIRCBUFSIZE)>>2;
int sensor_port = jptr->chn_num;
unsigned char short_buff[2];
unsigned int sensor_port = jptr->chn_num;
int index_time = jptr->jpeg_wp - 11; if (index_time<0) index_time+=get_globalParam (sensor_port, G_CIRCBUFSIZE)>>2;
// struct exif_datetime_t
/// calculates datetime([20] and subsec[7], returns pointer to char[27]
// struct exif_datetime_t
/// calculates datetime([20] and subsec[7], returns pointer to char[27]
char time_buff[27];
char * exif_meta_time_string=encode_time(time_buff, ccam_dma_buf_ptr[sensor_port][index_time], ccam_dma_buf_ptr[sensor_port][index_time+1]);
/// may be split in datetime/subsec - now it will not notice missing subseq field in template
/// may be split in datetime/subsec - now it will not notice missing subseq field in template
write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Photo_DateTimeOriginal, Exif_Photo_DateTimeOriginal, 27);
write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Image_DateTime, Exif_Image_DateTime, 20); // may use 27 if room is provided
putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_EXPOS), &meta_offsets.Photo_ExposureTime, Exif_Photo_ExposureTime);
putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_FRAME), &meta_offsets.Image_FrameNumber, Exif_Image_FrameNumber);
//Exif_Photo_MakerNote
//Exif_Photo_MakerNote
int global_flips=(get_imageParamsThis(sensor_port, P_FLIPH) & 1) | ((get_imageParamsThis(sensor_port, P_FLIPV)<<1) & 2);
int extra_flips=0;
if (get_imageParamsThis(sensor_port, P_MULTI_MODE)!=0) {
extra_flips=get_imageParamsThis(sensor_port, P_MULTI_MODE_FLIPS);
global_flips=extra_flips & 3;
}
/* unsigned char orientations[]={1,6,3,8,
2,7,4,5,
4,5,2,7,
3,8,1,6};
*/
unsigned char orientations[]="1638274545273816";
unsigned char orientations[]="1638274545273816";
unsigned char orientation_short[2];
orientation_short[0]=0;
orientation_short[1]=0xf & orientations[(get_imageParamsThis(sensor_port, P_PORTRAIT)&3) | (global_flips<<2)];
write_meta_irq(sensor_port, orientation_short, &meta_offsets.Image_Orientation, Exif_Image_Orientation, 2);
//TODO - use memcpy
// write sensor number
// short_buff[0] = 0xf & (jptr->chn_num >> 8);
short_buff[0] = 0;
short_buff[1] = 0xf & sensor_port;
write_meta_irq(sensor_port, short_buff, &meta_offsets.PageNumber, Exif_Image_PageNumber, 2);
//TODO - use memcpy
int maker_offset;
maker_offset=putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_GAINR), &meta_offsets.Photo_MakerNote, Exif_Photo_MakerNote);
if (maker_offset>0) {
......@@ -477,12 +478,12 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t*
(extra_flips <<24) , maker_offset+40);
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK1), maker_offset+44);
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK2), maker_offset+48);
// putlong_meta_raw_irq(0x1234567, maker_offset+52); // just testing
// putlong_meta_raw_irq(0x1234567, maker_offset+52); // just testing
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_QUALITY) | ((get_imageParamsThis(sensor_port, P_PORTRAIT)&1)<<7) | (get_imageParamsThis(sensor_port, P_CORING_INDEX)<<16), maker_offset+52);
putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE01), maker_offset+56); // data should be provided by a running daemon
putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE23), maker_offset+60);
//get_globalParam(G_TASKLET_CTL)
// left 1 long spare (+44)
//get_globalParam(G_TASKLET_CTL)
// left 1 long spare (+44)
}
interframe->meta_index=store_meta(sensor_port);
......@@ -538,9 +539,9 @@ static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id)
{
struct jpeg_ptr_t *jptr = dev_id;
// update_frame_pars();
// update_frame_pars();
wake_up_interruptible(&aframepars_wait_queue[jptr->chn_num]);
// tasklet_schedule(&tasklet_fpga);
// tasklet_schedule(&tasklet_fpga);
tasklet_schedule(tasklets[jptr->chn_num]);
return IRQ_HANDLED;
......@@ -571,7 +572,7 @@ static irqreturn_t compressor_irq_handler(int irq, void *dev_id)
}
//wake_up_interruptible(&framepars_wait_queue);
// tasklet_schedule(&tasklet_fpga);
// tasklet_schedule(&tasklet_fpga);
tasklet_schedule(tasklets[jptr->chn_num]);
irq_ctrl.interrupt_cmd = IRQ_CLEAR;
x393_cmprs_interrupts(irq_ctrl, jptr->chn_num);
......@@ -600,7 +601,7 @@ Modify waiting (LSEEK_*) for histogrames so they will only unfreeze if the histo
For displaying histograms - try use latest available - not waiting fro a particular frame.
*/
*/
/// HISTOGRAMS_WAKEUP_ALWAYS if 0 will only wakeup processes waiting for histograms when they become available, maybe never if they are disabled
/// if defined 1 - will wakeup each frame, regardless of the availability of the histograms
......@@ -640,11 +641,11 @@ void tasklet_fpga_function(unsigned long arg) {
#ifdef TEST_DISABLE_CODE
/// Time is out?
/// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#endif /* TEST_DISABLE_CODE */
/// Histograms are available for the previous frame (that is already in circbuf if compressor was running)
/// Is Y histogram needed?
/// Histograms are available for the previous frame (that is already in circbuf if compressor was running)
/// Is Y histogram needed?
PROFILE_NOW(2);
switch ((tasklet_disable >> TASKLET_CTL_HISTY_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate
......@@ -668,71 +669,71 @@ void tasklet_fpga_function(unsigned long arg) {
}
#ifdef TEST_DISABLE_CODE
if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1]
/// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, (1 << COLOR_Y_NUMBER), hash32p, framep); /// 0x2 Green1
GLOBALPARS(G_HIST_Y_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame
PROFILE_NOW(3);
/// Time is out?
/// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#if HISTOGRAMS_WAKEUP_ALWAYS
}
wake_up_interruptible(&hist_y_wait_queue); /// wait queue for the G1 histogram (used as Y)
#else
wake_up_interruptible(&hist_y_wait_queue); /// wait queue for the G1 histogram (used as Y)
}
}
#endif
#endif /* TEST_DISABLE_CODE */
/// Process parameters
if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) {
if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) {
processPars (sensor_port, sensorproc, getThisFrameNumber(sensor_port), get_globalParam(sensor_port, G_MAXAHEAD)); /// program parameters
PROFILE_NOW(4);
}
}
#ifdef TEST_DISABLE_CODE
/// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
/// Are C histograms needed?
#endif /* TEST_DISABLE_CODE */
switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate
switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate
hist_en=0;
break;
case TASKLET_HIST_HALF: /// calculate each even (0,2,4,6 frme of 8)
case TASKLET_HIST_HALF: /// calculate each even (0,2,4,6 frme of 8)
hist_en= ((thisFrameNumber & 1) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break;
case TASKLET_HIST_QUATER: /// calculate twice per 8 (0, 4)
case TASKLET_HIST_QUATER: /// calculate twice per 8 (0, 4)
hist_en= ((thisFrameNumber & 3) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break;
case TASKLET_HIST_ONCE: /// calculate once per 8 (0)
case TASKLET_HIST_ONCE: /// calculate once per 8 (0)
hist_en= ((thisFrameNumber & 7) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break;
case TASKLET_HIST_RQONLY: /// calculate only when specifically requested
case TASKLET_HIST_RQONLY: /// calculate only when specifically requested
hist_en= (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break;
case TASKLET_HIST_ALL: /// calculate each frame
default: /// calculate always (safer)
case TASKLET_HIST_ALL: /// calculate each frame
default: /// calculate always (safer)
hist_en=1;
}
}
/*
GLOBALPARS(0x1040)=((thisFrameNumber & 1) ==0);
GLOBALPARS(0x1041)=((thisFrameNumber & 3) ==0);
GLOBALPARS(0x1042)=((thisFrameNumber & 7) ==0);
GLOBALPARS(0x1043)=hist_en;
GLOBALPARS(0x1044)=thisFrameNumber;
*/
*/
#ifdef TEST_DISABLE_CODE
if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1]
if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, 0xf, hash32p, framep); /// all 4 colors, including Y (it will be skipped)
GLOBALPARS(G_HIST_C_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame
PROFILE_NOW(5);
/// Time is out?
/// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#if HISTOGRAMS_WAKEUP_ALWAYS
}
wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
}
wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
#else
wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
}
wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
}
#endif
#endif /* TEST_DISABLE_CODE */
}
......
......@@ -4,7 +4,7 @@
*/
#ifndef _ASM_CMOSCAM_H
#define _ASM_CMOSCAM_HPARS_FRAMES
#define _ASM_CMOSCAM_H
#define SAFE_CHECK 1 // perform more verification on the paremeters
//#define ELPHEL_DEBUG 0 //global debug on/off in multiple files
//#define ELPHEL_DEBUG_STARTUP 000a4c00 ;
......
......@@ -66,6 +66,8 @@ struct exif_dir_table_t {
// hack, reusing field to keep it protected
#define Exif_Image_IPTCNAA 0x083bb
#define Exif_Image_FrameNumber 0x083bb
// used for sensor number
#define Exif_Image_PageNumber 0x00129
#define Exif_Image_ExifTag 0x08769
#define Exif_Image_GPSTag 0x08825
......@@ -178,13 +180,32 @@ struct meta_CompassInfo_t {
#define Exif_GPSInfo_CompassRoll_Index 0x12
#define Exif_Image_FrameNumber_Index 0x13
#define Exif_Image_Orientation_Index 0x14
#define Exif_Photo_MakerNote_Index 0x15
#define Exif_Image_PageNumber_Index 0x15
#define Exif_Photo_MakerNote_Index 0x16
/// update ExifKmlNumber to be total number of *_Index entries
#define ExifKmlNumber Exif_Photo_MakerNote_Index+1
#define EXIF_DEV_NAME "/dev/exif_exif"
//#define EXIF_DEV_NAME "/dev/exif_exif"
#define EXIFDIR_DEV_NAME "/dev/exif_metadir"
#define EXIFMETA_DEV_NAME "/dev/exif_meta"
#endif
//#define EXIFMETA_DEV_NAME "/dev/exif_meta"
/**
* @brief This macro is used to construct file names in user space applications. Example
* of usage: <e>const char *exif_file_names[SENSOR_PORTS] = { EXIF_DEV_NAMES };</e>. Then the
* sensor port number can be used to access file name.
*/
#define EXIF_DEV_NAMES "/dev/exif_exif0", \
"/dev/exif_exif1", \
"/dev/exif_exif2", \
"/dev/exif_exif3"
/**
* @brief This macro is used to construct file names in user space applications. Example
* of usage: <e>const char *exifmeta_file_names[SENSOR_PORTS] = { EXIFMETA_DEV_NAMES };</e>. Then
* the sensor port number can be used to access file name.
*/
#define EXIFMETA_DEV_NAMES "/dev/exif_meta0", \
"/dev/exif_meta1", \
"/dev/exif_meta2", \
"/dev/exif_meta3"
#endif /* _ASM_EXIF_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment