Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
581fe424
Commit
581fe424
authored
Apr 18, 2016
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add multichannel support to quantization_tables.c, fix formatting
parent
aca0c9b9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1033 additions
and
931 deletions
+1033
-931
circbuf.c
src/drivers/elphel/circbuf.c
+11
-11
jpeghead.c
src/drivers/elphel/jpeghead.c
+20
-6
jpeghead.h
src/drivers/elphel/jpeghead.h
+1
-1
quantization_tables.c
src/drivers/elphel/quantization_tables.c
+969
-904
quantization_tables.h
src/drivers/elphel/quantization_tables.h
+28
-7
sensor_common.c
src/drivers/elphel/sensor_common.c
+0
-2
x393_macro.h
src/drivers/elphel/x393_macro.h
+4
-0
No files found.
src/drivers/elphel/circbuf.c
View file @
581fe424
...
...
@@ -95,14 +95,14 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
if
(
pElphel_buf
!=
NULL
)
{
ccam_dma_buf_ptr
=
pElphel_buf
->
vaddr
;
dma_handle
=
pElphel_buf
->
paddr
;
dev_info
(
dev
,
"using %
d bytes of DMA memory from pElphel_buf at address 0x%08p
"
,
pElphel_buf
->
size
*
PAGE_SIZE
,
dma_handle
);
dev_info
(
dev
,
"using %
lu bytes of DMA memory from pElphel_buf at address 0x%08x
"
,
pElphel_buf
->
size
*
PAGE_SIZE
,
dma_handle
);
}
else
{
ccam_dma_buf_ptr
=
dmam_alloc_coherent
(
dev
,
dma_size
,
&
dma_handle
,
GFP_KERNEL
);
if
(
!
ccam_dma_buf_ptr
)
{
dev_err
(
dev
,
"unable to allocate DMA buffer
\n
"
);
return
-
ENOMEM
;
}
else
{
dev_info
(
dev
,
"%d bytes of DMA memory allocated at address 0x%08
p
"
,
dma_size
,
dma_handle
);
dev_info
(
dev
,
"%d bytes of DMA memory allocated at address 0x%08
x
"
,
dma_size
,
dma_handle
);
}
}
...
...
@@ -263,7 +263,7 @@ unsigned int circbuf_all_poll (struct file *file, poll_table *wait)
int
circbuf_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
inode
->
i_size
=
CCAM_DMA_SIZE
;
dev_dbg
(
g_dev_ptr
,
"inode->i_size = 0x%x
\n
"
);
dev_dbg
(
g_dev_ptr
,
"inode->i_size = 0x%x
\n
"
,
inode
->
i_size
);
return
0
;
}
...
...
@@ -286,7 +286,7 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
last_image_chunk
+=
CCAM_DMA_SIZE
;
len32
=
circbuf_priv
[
chn
].
buf_ptr
[
BYTE2DW
(
last_image_chunk
+
(
CHUNK_SIZE
-
CCAM_MMAP_META_LENGTH
))];
dev_dbg
(
g_dev_ptr
,
"got len32 = 0x%x at 0x%x
\n
"
,
len32
,
last_image_chunk
+
(
CHUNK_SIZE
-
CCAM_MMAP_META_LENGTH
));
dev_dbg
(
g_dev_ptr
,
"got len32 = 0x%
l
x at 0x%x
\n
"
,
len32
,
last_image_chunk
+
(
CHUNK_SIZE
-
CCAM_MMAP_META_LENGTH
));
if
(
last_chunk_offset
!=
NULL
)
*
last_chunk_offset
=
last_image_chunk
;
...
...
@@ -481,13 +481,13 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
file
->
f_pos
=
img_start
;
break
;
case
LSEEK_CIRC_NEXT
:
dev_dbg
(
g_dev_ptr
,
"LSEEK_CIRC_NEXT: file->f_pos = 0x%
x, fvld = %d, fp->len32 = 0x%
x
\n
"
,
file
->
f_pos
,
fvld
,
fp
->
frame_length
);
dev_dbg
(
g_dev_ptr
,
"LSEEK_CIRC_NEXT: file->f_pos = 0x%
lx, fvld = %d, fp->len32 = 0x%l
x
\n
"
,
file
->
f_pos
,
fvld
,
fp
->
frame_length
);
if
(
fvld
<=
0
)
return
-
EOVERFLOW
;
//! no frames after current
// calculate the full length of current frame and advance file pointer by this value
padded_frame
=
fp
->
frame_length
+
INSERTED_BYTES
(
fp
->
frame_length
)
+
CHUNK_SIZE
+
CCAM_MMAP_META
;
file
->
f_pos
=
X393_BUFFADD
(
file
->
f_pos
,
padded_frame
);
// do it even if the next frame does not yet exist
dev_dbg
(
g_dev_ptr
,
"LSEEK_CIRC_NEXT: moving file->f_pos to 0x%x
\n
"
,
file
->
f_pos
);
dev_dbg
(
g_dev_ptr
,
"LSEEK_CIRC_NEXT: moving file->f_pos to 0x%
ll
x
\n
"
,
file
->
f_pos
);
break
;
case
LSEEK_CIRC_FIRST
:
case
LSEEK_CIRC_SCND
:
...
...
@@ -503,7 +503,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
nf
++
;
preprev_p
=
prev_p
;
// second known good (at least first one)
prev_p
=
rp
;
// now - current, known good
len32
=
get_image_length
(
DW2BYTE
(
rp
),
chn
,
last_image_chunk
);
len32
=
get_image_length
(
DW2BYTE
(
rp
),
chn
,
&
last_image_chunk
);
dev_dbg
(
g_dev_ptr
,
"LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x"
,
nf
,
rp
,
fvld
,
len32
);
if
((
len32
&
MARKER_FF
)
!=
MARKER_FF
)
break
;
//! no frames before rp (==prev_p)
//! move rp to the previous frame
...
...
@@ -519,7 +519,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
break
;
}
case
LSEEK_CIRC_SETP
:
dev_dbg
(
g_dev_ptr
,
"LSEK_CIRC_SETP: Setting jpeg_rp for channel %d to file->f_pos = 0x%x
\n
"
,
chn
,
file
->
f_pos
);
dev_dbg
(
g_dev_ptr
,
"LSEK_CIRC_SETP: Setting jpeg_rp for channel %d to file->f_pos = 0x%
ll
x
\n
"
,
chn
,
file
->
f_pos
);
camseq_set_jpeg_rp
(
chn
,
file
->
f_pos
>>
2
);
break
;
case
LSEEK_CIRC_VALID
:
...
...
@@ -569,7 +569,7 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
unsigned
long
p
;
unsigned
int
minor
=
MINOR
(
file
->
f_inode
->
i_rdev
);
unsigned
int
chn
=
minor_to_chn
(
minor
,
NULL
);
dev_dbg
(
g_dev_ptr
,
"minor = 0x%x, count = 0x%x, off = 0x%x"
,
minor
,
count
,
off
);
dev_dbg
(
g_dev_ptr
,
"minor = 0x%x, count = 0x%x, off = 0x%
ll
x"
,
minor
,
count
,
off
);
/* debug code follows*/
switch
(
buf
[
0
]
-
0x30
)
{
...
...
@@ -609,7 +609,7 @@ ssize_t circbuf_read(struct file *file, char *buf, size_t count, loff_t *off)
unsigned
long
p
;
unsigned
int
minor
=
MINOR
(
file
->
f_inode
->
i_rdev
);
unsigned
int
chn
=
minor_to_chn
(
minor
,
NULL
);
dev_dbg
(
g_dev_ptr
,
"minor = 0x%x, count = 0x%x, off = 0x%x"
,
minor
,
count
,
off
);
dev_dbg
(
g_dev_ptr
,
"minor = 0x%x, count = 0x%x, off = 0x%
ll
x"
,
minor
,
count
,
off
);
p
=
*
off
;
if
(
p
>=
CCAM_DMA_SIZE
)
...
...
@@ -674,7 +674,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait)
rslt
=
circbuf_valid_ptr
(
file
->
f_pos
,
&
fp
,
chn
);
if
(
rslt
<
0
)
{
// not a valid read pointer, probable buffer overrun
dev_dbg
(
g_dev_ptr
,
"invalid pointer file->f_pos = 0x%x
\n
"
,
file
->
f_pos
);
dev_dbg
(
g_dev_ptr
,
"invalid pointer file->f_pos = 0x%
ll
x
\n
"
,
file
->
f_pos
);
return
POLLHUP
;
}
else
if
(
rslt
>
0
)
{
return
POLLIN
|
POLLRDNORM
;
//! there was frame already available
...
...
src/drivers/elphel/jpeghead.c
View file @
581fe424
...
...
@@ -104,12 +104,13 @@ static struct jpeghead_priv_t {
* @brief Copy two quantization tables for the current frame (for the RTP streamer)
* @param[in] params pointer to an array of parameters stored for the frame
* @param[out] buf buffer to put the header to
* @param[in] chn compressor channel number
* @return header length if successful, < 0 - error
*/
int
qtables_create
(
struct
interframe_params_t
*
params
,
unsigned
char
*
buf
)
int
qtables_create
(
struct
interframe_params_t
*
params
,
unsigned
char
*
buf
,
unsigned
int
chn
)
{
dev_dbg
(
g_dev_ptr
,
"params->quality2 = 0x%x
\n
"
,
params
->
quality2
);
int
rslt
=
get_qtable
(
params
->
quality2
,
&
buf
[
0
],
&
buf
[
64
]);
/// will copy both quantization tables
int
rslt
=
get_qtable
(
params
->
quality2
,
&
buf
[
0
],
&
buf
[
64
]
,
chn
);
/// will copy both quantization tables
if
(
rslt
<
0
)
return
rslt
;
/// bad quality table
return
128
;
}
...
...
@@ -192,16 +193,16 @@ int jpegheader_create(struct interframe_params_t *params, unsigned char *buf, un
0x07
,
0x11
};
struct
huff_tables_t
*
huff_tables
=
&
jpeghead_priv
[
chn
].
huff_tables
;
unsigned
char
*
p
=
(
unsigned
char
*
)
params
;
if
(
buf
==
NULL
)
return
-
1
;
/// buffer is not provided
unsigned
char
*
p
=
(
char
*
)
params
;
dev_dbg
(
g_dev_ptr
,
"list of parameters:
\n
"
);
print_hex_dump_bytes
(
""
,
DUMP_PREFIX_OFFSET
,
p
,
32
);
memcpy
((
void
*
)
&
buf
[
0
],
(
void
*
)
jfif1
,
sizeof
(
jfif1
));
/// including DQT0 header
memcpy
((
void
*
)
&
buf
[
header_cqtable_hd
],
(
void
*
)
jfif2
,
sizeof
(
jfif2
));
/// DQT1 header
rslt
=
get_qtable
(
params
->
quality2
,
&
buf
[
header_yqtable
],
&
buf
[
header_cqtable
]);
/// will copy both quantization tables
rslt
=
get_qtable
(
params
->
quality2
,
&
buf
[
header_yqtable
],
&
buf
[
header_cqtable
]
,
chn
);
/// will copy both quantization tables
if
(
rslt
<
0
)
return
rslt
;
/// bad quality table
bp
=
header_sof
;
buf
[
bp
++
]
=
0xff
;
buf
[
bp
++
]
=
0xc0
;
...
...
@@ -364,7 +365,7 @@ loff_t jpeghead_lseek(struct file *file, loff_t offset, int orig,
if
((
fp
->
signffff
!=
MARKER_FFFF
)
||
// signature is overwritten
((
fp
->
timestamp_sec
)
&
X313_LENGTH_MASK
))
return
-
EINVAL
;
//! acquisition of this frame is not done yet - length word high byte is non-zero
if
((
offset
&
0x1f
)
==
0x2
)
jpeghead_priv
[
chn
].
jpeg_h_sz
=
qtables_create
(
fp
,
jpeghead_priv
[
chn
].
header
);
/// just qunatization tables (128 bytes) - for the streamer
jpeghead_priv
[
chn
].
jpeg_h_sz
=
qtables_create
(
fp
,
jpeghead_priv
[
chn
].
header
,
chn
);
/// just qunatization tables (128 bytes) - for the streamer
else
jpeghead_priv
[
chn
].
jpeg_h_sz
=
jpegheader_create
(
fp
,
jpeghead_priv
[
chn
].
header
,
chn
);
/// full JPEG header
if
(
jpeghead_priv
[
chn
].
jpeg_h_sz
<
0
)
{
...
...
@@ -669,20 +670,23 @@ int jpeg_htable_is_programmed(unsigned int chn)
/**
* @brief program FPGA Huffman table (fram static array)
* @param[in] chn compressor channel number
* return none
*
@
return none
*/
void
jpeg_htable_fpga_pgm
(
unsigned
int
chn
)
{
int
i
;
unsigned
long
flags
;
x393_cmprs_table_addr_t
table_addr
;
struct
huff_tables_t
*
huff_tables
=
&
jpeghead_priv
[
chn
].
huff_tables
;
table_addr
.
addr32
=
0
;
table_addr
.
type
=
3
;
local_irq_save
(
flags
);
x393_cmprs_tables_address
(
table_addr
,
chn
);
for
(
i
=
0
;
i
<
sizeof
(
huff_tables
->
fpga_huffman_table
);
i
++
)
{
x393_cmprs_tables_data
((
u32
)
huff_tables
->
fpga_huffman_table
[
i
],
chn
);
}
local_irq_restore
(
flags
);
jpeghead_priv
[
chn
].
fpga_programmed
=
1
;
}
...
...
@@ -749,5 +753,15 @@ int jpeghead_init(struct platform_device *pdev)
jpeg_htable_init
(
i
);
}
qt_init
(
pdev
);
dev_dbg
(
g_dev_ptr
,
"reset quantization tables
\n
"
);
// force initialization at next access
if
(
get_cache_policy
()
==
COMMON_CACHE
)
{
reset_qtables
(
0
);
}
else
if
(
get_cache_policy
()
==
PER_CHN_CACHE
)
{
for
(
i
=
0
;
i
<
IMAGE_CHN_NUM
;
i
++
)
reset_qtables
(
i
);
}
return
0
;
}
src/drivers/elphel/jpeghead.h
View file @
581fe424
...
...
@@ -9,7 +9,7 @@ struct huffman_fpga_code_t {
unsigned
short
value
;
/// code value
unsigned
short
length
;
/// code length
};
int
qtables_create
(
struct
interframe_params_t
*
params
,
unsigned
char
*
buf
);
int
qtables_create
(
struct
interframe_params_t
*
params
,
unsigned
char
*
buf
,
unsigned
int
chn
);
int
jpegheader_create
(
struct
interframe_params_t
*
params
,
unsigned
char
*
buf
,
unsigned
int
chn
);
int
jpeghead_open
(
struct
inode
*
inode
,
struct
file
*
filp
);
// set filesize
loff_t
jpeghead_lseek
(
struct
file
*
file
,
loff_t
offset
,
int
orig
,
struct
interframe_params_t
*
fp
);
...
...
src/drivers/elphel/quantization_tables.c
View file @
581fe424
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/drivers/elphel/quantization_tables.h
View file @
581fe424
/// @file quantization_tables.h
#ifndef _QUANTIZATION_TABLES_H
#define _QUANTIZATION_TABLES_H
/** @brief Quantization tables cache usage policy */
enum
{
// @brief Use common cache for all compressors
COMMON_CACHE
=
0
,
// @brief Use separate cache for each compressor
PER_CHN_CACHE
};
/**
* @brief initialization of quantization tables (direct - JPEG header ones) cache
* \n TODO: add \b init_qtable_head_cache to module initialization
*
* used in quantization_tables.c only
*/
void
init_qtable_head_cache
(
void
);
void
init_qtable_head_cache
(
unsigned
int
chn
);
/**
* @brief calculates a pair of direct (JPEG header) tables for the specified quality (2-bytes )
* @param quality2 single byte (standard) or a pair of bytes (see file header description)
* @param y_tab caller-provided pointer to a 64-byte Y (intensity) quantization table (NULL - don't copy)
* @param c_tab caller-provided pointer to a 64-byte C (color) quantization table (NULL - don't copy)
* @return 0 - cache hit, 1 - cache miss (recalculated), -1 - invalid quality
*
* used in quantization_tables.c and jpeghead.c
*/
int
get_qtable
(
int
quality2
,
unsigned
char
*
y_tab
,
unsigned
char
*
c_tab
);
int
get_qtable
(
int
quality2
,
unsigned
char
*
y_tab
,
unsigned
char
*
c_tab
,
unsigned
int
chn
);
/**
* @brief initialization of quantization tables (reverse, for the FPGA) cache
* \n TODO: add \b init_qtable_fpga to module initialization
*
* used in quantization_tables.c only
*/
void
init_qtable_fpga
(
void
);
void
init_qtable_fpga
(
unsigned
int
chn
);
/**
* @brief Finds an already programmed FPGA page or calculates (an programms FPGA with) a new one
* @param quality2 single byte (standard) or a pair of bytes (see file header description)
* @return table page number used (0..7) or -1 - invalid q
*
* used in quantization_table.c and pgm_functions.c
*/
int
set_qtable_fpga
(
int
quality2
);
int
set_qtable_fpga
(
int
quality2
,
unsigned
int
chn
);
/**
* @brief Temporary function to directly set one of the coring LUTs (currently 100 0.0 to 9.9 with 0.1 step)
...
...
@@ -32,10 +49,14 @@ int set_qtable_fpga(int quality2);
* @param coring_number 0..99 - function number
* @param fpga_number 0.. 15 - fpga table number
* @return table page number used (0..7) or -1 - invalid q
*
* used in quantization_table.c and pgm_functions.c
*/
void
set_coring_fpga
(
int
coring_number
,
int
fpga_number
);
void
set_coring_fpga
(
unsigned
int
coring_number
,
int
fpga_number
,
unsigned
int
chn
);
void
reset_qtables
(
unsigned
int
chn
);
void
reset_qtables
(
void
);
int
get_cache_policy
(
void
);
void
set_cache_policy
(
int
policy
);
void
qt_init
(
struct
platform_device
*
pdev
);
#endif
src/drivers/elphel/sensor_common.c
View file @
581fe424
...
...
@@ -764,8 +764,6 @@ int image_acq_init(struct platform_device *pdev)
//MDD1(printk("init_pgm_proc ()\n"));
//init_pgm_proc (); /// setup pointers to functions (not sensor-specific)
//MDD1(printk("reset_qtables()\n"));
dev_dbg
(
dev
,
"reset quantization tables
\n
"
);
reset_qtables
();
/// force initialization at next access
return
0
;
}
...
...
src/drivers/elphel/x393_macro.h
View file @
581fe424
...
...
@@ -41,6 +41,10 @@
#define X393_BUFFSUB(x, y) (((x) >= (y)) ? ((x)-(y)) : ((x) + (CCAM_DMA_SIZE -(y))))
#define X393_BUFFADD(x, y) ((((x) + (y)) <= CCAM_DMA_SIZE) ? ((x) + (y)) : ((x) - (CCAM_DMA_SIZE -(y))))
#define TABLE_TYPE_QUANT 0
#define TABLE_TYPE_CORING 1
#define TABLE_TYPE_FOCUS 2
#define TABLE_TYPE_HUFFMAN 3
/**
* @brief Converts file minor number to image compressor channel.
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment