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
50e586e1
Commit
50e586e1
authored
Sep 16, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made qtables/cache to work correctly with multiple sensor ports
parent
922aaa72
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
39 deletions
+35
-39
quantization_tables.c
src/drivers/elphel/quantization_tables.c
+35
-39
No files found.
src/drivers/elphel/quantization_tables.c
View file @
50e586e1
...
@@ -133,11 +133,11 @@ struct qtables_set_t {
...
@@ -133,11 +133,11 @@ struct qtables_set_t {
int
qtable_cache_next
[
QTABLE_HEAD_CACHE
]
;
///< index of the next (not used longer than this) slot
int
qtable_cache_next
[
QTABLE_HEAD_CACHE
]
;
///< index of the next (not used longer than this) slot
int
qtable_cache_mre
;
///< index of most recently used slot
int
qtable_cache_mre
;
///< index of most recently used slot
int
qtable_fpga_values
[
FPGA_NQTAB
];
///< quality values for the tables in FPGA
int
qtable_fpga_values
[
SENSOR_PORTS
][
FPGA_NQTAB
];
///< quality values for the tables in FPGA
int
qtable_fpga_next
[
FPGA_NQTAB
]
;
///< index of the next (not used longer than this) slot in FPGA quantization tables
int
qtable_fpga_next
[
SENSOR_PORTS
][
FPGA_NQTAB
]
;
///< index of the next (not used longer than this) slot in FPGA quantization tables
int
qtable_fpga_mre
;
///< index of most recently used slot
int
qtable_fpga_mre
[
SENSOR_PORTS
];
///< index of most recently used slot
int
qtable_cache_initialized
;
int
qtable_cache_initialized
;
int
qtable_fpga_initialized
;
int
qtable_fpga_initialized
[
SENSOR_PORTS
]
;
};
};
/** @brief \e qtables_set contains quantization tables caches for all compressor channels plus one common cache for all channels.
/** @brief \e qtables_set contains quantization tables caches for all compressor channels plus one common cache for all channels.
* Common cache has fixed index #COMMON_CACHE_INDEX and will be used to save computational time in cases when all compressors have
* Common cache has fixed index #COMMON_CACHE_INDEX and will be used to save computational time in cases when all compressors have
...
@@ -181,7 +181,7 @@ void reset_qtables(unsigned int chn)
...
@@ -181,7 +181,7 @@ void reset_qtables(unsigned int chn)
{
{
int
ind
=
get_cache_index
(
chn
);
int
ind
=
get_cache_index
(
chn
);
qtables_set
[
ind
].
qtable_cache_initialized
=
0
;
qtables_set
[
ind
].
qtable_cache_initialized
=
0
;
qtables_set
[
ind
].
qtable_fpga_initialized
=
0
;
qtables_set
[
ind
].
qtable_fpga_initialized
[
chn
]
=
0
;
}
}
/**
/**
...
@@ -204,15 +204,12 @@ void init_qtable_head_cache(unsigned int chn)
...
@@ -204,15 +204,12 @@ void init_qtable_head_cache(unsigned int chn)
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
}
}
/**
/** Calculates a pair of direct (JPEG header) tables for the specified quality (2-bytes ) */
* @brief Calculates a pair of direct (JPEG header) tables for the specified quality (2-bytes )
int
get_qtable
(
int
quality2
,
///< single byte (standard) or a pair of bytes (see file header description)
* @param[in] quality2 single byte (standard) or a pair of bytes (see file header description)
unsigned
char
*
y_tab
,
///< caller-provided pointer to a 64-byte Y (intensity) quantization table (NULL - don't copy)
* @param[out] y_tab caller-provided pointer to a 64-byte Y (intensity) quantization table (NULL - don't copy)
unsigned
char
*
c_tab
,
///< caller-provided pointer to a 64-byte C (color) quantization table (NULL - don't copy)
* @param[out] c_tab caller-provided pointer to a 64-byte C (color) quantization table (NULL - don't copy)
unsigned
int
chn
)
///< compressor channel number
* @param[in] chn compressor channel number
///< @return 0 - cache hit, 1 - cache miss (recalculated), -1 - invalid quality
* @return 0 - cache hit, 1 - cache miss (recalculated), -1 - invalid quality
*/
int
get_qtable
(
int
quality2
,
unsigned
char
*
y_tab
,
unsigned
char
*
c_tab
,
unsigned
int
chn
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
int
i
,
transpose
;
int
i
,
transpose
;
...
@@ -239,7 +236,6 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
...
@@ -239,7 +236,6 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
if
(
qtables_set
[
ind
].
qtable_cache_initialized
==
0
)
if
(
qtables_set
[
ind
].
qtable_cache_initialized
==
0
)
init_qtable_head_cache
(
chn
);
init_qtable_head_cache
(
chn
);
dev_dbg
(
g_dev_ptr
,
"received quality2 = %d
\n
"
,
quality2
);
dev_dbg
(
g_dev_ptr
,
"received quality2 = %d
\n
"
,
quality2
);
if
(
quality2
<
0
)
return
-
1
;
if
(
quality2
<
0
)
return
-
1
;
...
@@ -248,7 +244,7 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
...
@@ -248,7 +244,7 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
dev_dbg
(
g_dev_ptr
,
"transformed quality2 = %d
\n
"
,
quality2
);
dev_dbg
(
g_dev_ptr
,
"transformed quality2 = %d
\n
"
,
quality2
);
local_irq_save
(
flags
);
local_irq_save
(
flags
);
//
/
look if such q value is already in cache
// look if such q value is already in cache
cache_index
=
qtables_set
[
ind
].
qtable_cache_mre
;
cache_index
=
qtables_set
[
ind
].
qtable_cache_mre
;
cache_index_prev
=
-
1
;
cache_index_prev
=
-
1
;
for
(
i
=
0
;
for
(
i
=
0
;
...
@@ -261,7 +257,7 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
...
@@ -261,7 +257,7 @@ int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigne
dev_dbg
(
g_dev_ptr
,
"i = %d, cache_index_prev = %d, cache_index = %d
\n
"
,
i
,
cache_index_prev
,
cache_index
);
dev_dbg
(
g_dev_ptr
,
"i = %d, cache_index_prev = %d, cache_index = %d
\n
"
,
i
,
cache_index_prev
,
cache_index
);
}
}
//
/
cache_index is invalid if (i==FPGA_NQTAB), but cache_index_prev is OK
// cache_index is invalid if (i==FPGA_NQTAB), but cache_index_prev is OK
/// End of cache?
/// End of cache?
if
(
i
==
QTABLE_HEAD_CACHE
)
{
if
(
i
==
QTABLE_HEAD_CACHE
)
{
...
@@ -344,11 +340,11 @@ void init_qtable_fpga(unsigned int chn)
...
@@ -344,11 +340,11 @@ void init_qtable_fpga(unsigned int chn)
local_irq_save
(
flags
);
local_irq_save
(
flags
);
for
(
i
=
0
;
i
<
FPGA_NQTAB
;
i
++
)
{
for
(
i
=
0
;
i
<
FPGA_NQTAB
;
i
++
)
{
qtables_set
[
ind
].
qtable_fpga_values
[
i
]
=
-
1
;
// undefined
qtables_set
[
ind
].
qtable_fpga_values
[
chn
][
i
]
=
-
1
;
// undefined
qtables_set
[
ind
].
qtable_fpga_next
[
i
]
=
i
+
1
;
// last value is invalid, but that's OK - it should not be used
qtables_set
[
ind
].
qtable_fpga_next
[
chn
][
i
]
=
i
+
1
;
// last value is invalid, but that's OK - it should not be used
}
}
qtables_set
[
ind
].
qtable_fpga_mre
=
0
;
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
=
0
;
qtables_set
[
ind
].
qtable_fpga_initialized
=
1
;
qtables_set
[
ind
].
qtable_fpga_initialized
[
chn
]
=
1
;
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
}
}
...
@@ -367,10 +363,10 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
...
@@ -367,10 +363,10 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
x393_cmprs_table_addr_t table_addr;
x393_cmprs_table_addr_t table_addr;
#endif
#endif
int
ind
=
get_cache_index
(
chn
);
int
ind
=
get_cache_index
(
chn
);
int
*
qtable_fpga_values
=
qtables_set
[
ind
].
qtable_fpga_values
;
int
*
qtable_fpga_values
=
qtables_set
[
ind
].
qtable_fpga_values
[
chn
]
;
int
*
qtable_fpga_next
=
qtables_set
[
ind
].
qtable_fpga_next
;
int
*
qtable_fpga_next
=
qtables_set
[
ind
].
qtable_fpga_next
[
chn
]
;
if
(
qtables_set
[
ind
].
qtable_fpga_initialized
==
0
)
if
(
qtables_set
[
ind
].
qtable_fpga_initialized
[
chn
]
==
0
)
init_qtable_fpga
(
chn
);
init_qtable_fpga
(
chn
);
dev_dbg
(
g_dev_ptr
,
"received quality2 = 0x%x
\n
"
,
quality2
);
dev_dbg
(
g_dev_ptr
,
"received quality2 = 0x%x
\n
"
,
quality2
);
...
@@ -381,8 +377,8 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
...
@@ -381,8 +377,8 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
dev_dbg
(
g_dev_ptr
,
"transformed quality2 = 0x%x
\n
"
,
quality2
);
dev_dbg
(
g_dev_ptr
,
"transformed quality2 = 0x%x
\n
"
,
quality2
);
// local_ irq_save(flags);
// local_ irq_save(flags);
/// look if such q value is already
in cache
/// look if such q value is already
loaded to fpga
fpga_index
=
qtables_set
[
ind
].
qtable_fpga_mre
;
fpga_index
=
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
;
fpga_index_prev
=
-
1
;
fpga_index_prev
=
-
1
;
for
(
i
=
0
;
for
(
i
=
0
;
(
i
<
FPGA_NQTAB
)
&&
(
i
<
FPGA_NQTAB
)
&&
...
@@ -399,22 +395,22 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
...
@@ -399,22 +395,22 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
/// End of cache?
/// End of cache?
if
(
i
==
FPGA_NQTAB
)
{
if
(
i
==
FPGA_NQTAB
)
{
/// yes, re-use the LRE slot
/// yes, re-use the LRE slot
qtable_fpga_next
[
fpga_index_prev
]
=
qtables_set
[
ind
].
qtable_fpga_mre
;
qtable_fpga_next
[
fpga_index_prev
]
=
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
;
qtables_set
[
ind
].
qtable_fpga_mre
=
fpga_index_prev
;
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
=
fpga_index_prev
;
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
= %d
\n
"
,
qtables_set
[
ind
].
qtable_fpga_mre
);
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
[%d] = %d
\n
"
,
chn
,
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
);
}
else
if
(
fpga_index_prev
>=
0
)
{
}
else
if
(
fpga_index_prev
>=
0
)
{
/// no, hit or never used so far, and not the latest - anyway use this slot
/// no, hit or never used so far, and not the latest - anyway use this slot
qtable_fpga_next
[
fpga_index_prev
]
=
qtable_fpga_next
[
fpga_index
];
/// bypass this
qtable_fpga_next
[
fpga_index_prev
]
=
qtable_fpga_next
[
fpga_index
];
/// bypass this
qtable_fpga_next
[
fpga_index
]
=
qtables_set
[
ind
].
qtable_fpga_mre
;
/// this points to the old mre
qtable_fpga_next
[
fpga_index
]
=
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
;
/// this points to the old mre
qtables_set
[
ind
].
qtable_fpga_mre
=
fpga_index
;
/// this is now mre
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
=
fpga_index
;
/// this is now mre
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
= %d
\n
"
,
qtables_set
[
ind
].
qtable_fpga_mre
);
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
[%d] = %d
\n
"
,
chn
,
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
);
}
}
/// is it a hit or miss?
/// is it a hit or miss?
if
(
qtable_fpga_values
[
qtables_set
[
ind
].
qtable_fpga_mre
]
!=
quality2
)
{
if
(
qtable_fpga_values
[
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
]
!=
quality2
)
{
/// miss, calculate the table and send it to the FPGA
/// miss, calculate the table and send it to the FPGA
qtable_fpga_values
[
qtables_set
[
ind
].
qtable_fpga_mre
]
=
quality2
;
qtable_fpga_values
[
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
]
=
quality2
;
transpose
=
(
quality2
>>
7
)
&
1
;
/// 0 - landscape mode, 1 - portrait mode
transpose
=
(
quality2
>>
7
)
&
1
;
/// 0 - landscape mode, 1 - portrait mode
for
(
q_type
=
0
;
q_type
<
2
;
q_type
++
)
{
//Y/C
for
(
q_type
=
0
;
q_type
<
2
;
q_type
++
)
{
//Y/C
quality
=
q_type
?
((
quality2
>>
8
)
^
0x80
)
:
(
quality2
&
0x7f
);
quality
=
q_type
?
((
quality2
>>
8
)
^
0x80
)
:
(
quality2
&
0x7f
);
...
@@ -462,8 +458,8 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
...
@@ -462,8 +458,8 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
#if 0
#if 0
table_addr.type = TABLE_TYPE_QUANT;
table_addr.type = TABLE_TYPE_QUANT;
// **** NC393 TODO: Find why address should be x4 - answer: it is in bytes in FPGA ****
// **** NC393 TODO: Find why address should be x4 - answer: it is in bytes in FPGA ****
// table_addr.addr32 = qtables_set[ind].qtable_fpga_mre * QTABLE_SIZE;
// table_addr.addr32 = qtables_set[ind].qtable_fpga_mre
[chn]
* QTABLE_SIZE;
table_addr.addr32 = qtables_set[ind].qtable_fpga_mre * QTABLE_SIZE*4;
table_addr.addr32 = qtables_set[ind].qtable_fpga_mre
[chn]
* QTABLE_SIZE*4;
dev_dbg(g_dev_ptr, "table_addr=0x%08x\n", table_addr.d32);
dev_dbg(g_dev_ptr, "table_addr=0x%08x\n", table_addr.d32);
x393_cmprs_tables_address(table_addr, chn);
x393_cmprs_tables_address(table_addr, chn);
...
@@ -475,16 +471,16 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
...
@@ -475,16 +471,16 @@ int set_qtable_fpga(int quality2, ///< single byte (standard) or a pair of
#endif
#endif
write_compressor_table
(
chn
,
write_compressor_table
(
chn
,
TABLE_TYPE_QUANT
,
TABLE_TYPE_QUANT
,
qtables_set
[
ind
].
qtable_fpga_mre
,
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
,
QTABLE_SIZE
,
QTABLE_SIZE
,
qtable_fpga_dw
);
qtable_fpga_dw
);
}
/// now table pair is calculated and stored in cache
}
/// now table pair is calculated and stored in cache
/// copy tables to the FPGA
/// copy tables to the FPGA
// local_ irq_restore(flags);
// local_ irq_restore(flags);
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
= %d
\n
"
,
qtables_set
[
ind
].
qtable_fpga_mre
);
dev_dbg
(
g_dev_ptr
,
"qtable_fpga_mre
[%d] = %d
\n
"
,
chn
,
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
);
return
qtables_set
[
ind
].
qtable_fpga_mre
;
return
qtables_set
[
ind
].
qtable_fpga_mre
[
chn
]
;
}
}
/**
/**
...
...
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