📄 ebcot_encoder.c
字号:
/*****************************************************************************/
static void
complete_quality_layers(ebcot_encoder_ref self, int header_size)
/* See the comments appearing with `get_layer_specs' to understand the
role played by this function. */
{
int tnum, c;
ebcot_tile_ptr tile;
ebcot_component_info_ptr comp_info;
int min_layer_bytes, diff_bytes, max_bytes, last_included_diff_bytes;
int from_idx, to_idx, n;
ebcot_layer_info_ptr info;
double from_log, to_log;
min_layer_bytes = 0;
for (tnum=0; tnum < self->num_tiles; tnum++)
{
tile = self->tiles + tnum;
for (c=0; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=0; n <= comp_info->num_levels; n++)
min_layer_bytes += comp_info->levels[n].total_precincts * 16;
}
}
info = self->layer_info;
max_bytes = info[self->num_layers-1].max_cumulative_bytes - header_size;
last_included_diff_bytes = min_layer_bytes;
from_idx = 0;
while (from_idx < (self->num_layers-1))
{
assert(info[from_idx].optimize); /* Must have a specified bit-rate. */
for (to_idx=from_idx+1; to_idx < self->num_layers; to_idx++)
if (info[to_idx].optimize)
break;
assert((to_idx < self->num_layers) &&
(info[from_idx].max_cumulative_bytes > 0) &&
(info[to_idx].max_cumulative_bytes > 0));
from_log = log((double)(info[from_idx].max_cumulative_bytes));
to_log = log((double)(info[to_idx].max_cumulative_bytes));
while (from_idx < to_idx)
{
info[from_idx].max_cumulative_bytes =
((int) exp(from_log)) - header_size;
from_log += (to_log - from_log) / ((double)(to_idx-from_idx));
diff_bytes = info[from_idx].max_cumulative_bytes -
((from_idx == 0)?0:(info[from_idx-1].max_cumulative_bytes));
if (diff_bytes < min_layer_bytes)
{ /* Skip this layer. */
self->num_layers--;
for (n=from_idx; n < self->num_layers; n++)
info[n] = info[n+1];
to_idx--;
continue;
}
if (info[from_idx].max_cumulative_bytes < max_bytes)
last_included_diff_bytes = diff_bytes;
from_idx++;
}
}
/* Now work on the last layer. */
min_layer_bytes = last_included_diff_bytes - 1;
info[from_idx].max_cumulative_bytes = max_bytes;
diff_bytes = info[from_idx].max_cumulative_bytes -
((from_idx == 0)?0:(info[from_idx-1].max_cumulative_bytes));
while (diff_bytes < min_layer_bytes)
{
if (from_idx == 0)
{
if (diff_bytes <= 0)
local_error("Requested target bit-rate is probably too small "
"to accommodate the global header, let alone "
"any coded subband samples!");
else
break;
}
/* Discard previous layer. */
info[from_idx-1] = info[from_idx];
from_idx--;
self->num_layers--;
diff_bytes = info[from_idx].max_cumulative_bytes -
((from_idx == 0)?0:(info[from_idx-1].max_cumulative_bytes));
}
/* Finally, make sure that the first layer has the `optimize' flag set. */
self->layer_info[0].optimize = 1;
}
/* ========================================================================= */
/* ---------------------- Structure Management Functions ------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC construct_layer_progression */
/*****************************************************************************/
static int
construct_layer_progression(ebcot_tile_ptr tile, int tpart,
ebcot_sequence_ptr seq,
int min_level, int min_component,
int max_layers, int max_levels,
int max_components)
{
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_precinct_info_ptr precinct;
int new_packets;
int layer, n, c, p;
new_packets = 0;
for (layer=0; layer < max_layers; layer++)
for (n=min_level; n < max_levels; n++)
for (c=min_component; c < max_components; c++)
{
comp_info = tile->components + c;
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
if (precinct->included_layers > layer)
continue;
assert(precinct->included_layers == layer);
precinct->included_layers++;
seq->layer_idx = layer;
seq->precinct = precinct;
seq->tpart = tpart; /* DST POC mod */
new_packets++;
seq++;
}
}
return(new_packets);
}
/*****************************************************************************/
/* STATIC construct_resolution_layer_progression */
/*****************************************************************************/
static int
construct_resolution_layer_progression(ebcot_tile_ptr tile, int tpart,
ebcot_sequence_ptr seq,
int min_level, int min_component,
int max_layers, int max_levels,
int max_components)
{
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_precinct_info_ptr precinct;
int new_packets;
int layer, n, c, p;
new_packets = 0;
for (n=min_level; n < max_levels; n++)
for (layer=0; layer < max_layers; layer++)
for (c=min_component; c < max_components; c++)
{
comp_info = tile->components + c;
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
if (precinct->included_layers > layer)
continue;
assert(precinct->included_layers == layer);
precinct->included_layers++;
seq->layer_idx = layer;
seq->precinct = precinct;
seq->tpart = tpart; /* DST POC mod */
new_packets++;
seq++;
}
}
return(new_packets);
}
/*****************************************************************************/
/* STATIC construct_resolution_position_progression */
/*****************************************************************************/
static int
construct_resolution_position_progression(ebcot_tile_ptr tile, int tpart,
ebcot_sequence_ptr seq,
int min_level, int min_component,
int max_layers, int max_levels,
int max_components)
{
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_precinct_info_ptr precinct;
canvas_dims dims;
int new_packets;
int n, c, p;
int x_inc, y_inc, inc, x0, x1, y0, y1, x, y;
/* Reset `next_precinct_idx' fields. */
for (c=min_component; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=min_level; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels +n;
lev->next_precinct_idx = 0;
}
}
new_packets = 0;
for (n=min_level; n < max_levels; n++)
{
/* Determine spatial progression parameters. */
x_inc = y_inc = 0;
for (c=min_component; c < max_components; c++)
{
comp_info = tile->components + c;
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
if ((!is_power_of_2(comp_info->hor_subsampling)) ||
(!is_power_of_2(comp_info->vert_subsampling)))
local_error("Cannot use packet progressions where spatial "
"progression dominates component progression unless "
"component sub-sampling factors are exact "
"powers of 2!");
if (lev->ppx >= 0)
{
/* SAIC General Decomp. Begin mods */
int xfact = 0;
int l;
for (l=comp_info->num_levels; l>n; l--) {
switch(comp_info->levels[l].decomp_sequence[0]) {
case 1:
xfact++;
break;
case 2:
xfact++;
break;
case 3:
break;
}
}
inc = comp_info->hor_subsampling;
inc <<= lev->ppx + xfact;
/* SAIC General Decomp. End mods */
if ((x_inc == 0) || (inc < x_inc))
x_inc = inc;
}
if (lev->ppy >= 0)
{
/* SAIC General Decomp. Begin mods */
int yfact = 0;
int l;
for (l=comp_info->num_levels; l>n; l--) {
switch(comp_info->levels[l].decomp_sequence[0]) {
case 1:
yfact++;
break;
case 2:
break;
case 3:
yfact++;
break;
}
}
inc = comp_info->vert_subsampling;
inc <<= lev->ppy + yfact;
/* SAIC General Decomp. End mods */
if ((y_inc == 0) || (inc < y_inc))
y_inc = inc;
}
}
dims = tile->reference_dims;
if (tile->overlapped)
local_error("Spatially oriented packet progressions not defined "
"for overlapping tiles!");
if (x_inc == 0)
{ /* Only one precinct horizontally. */
x0 = 0; x1 = x_inc = 1;
}
else
{
x0 = dims.left_col; x1 = x0 + dims.cols;
x0 &= ~(x_inc-1); /* Start on integer multiple of x_inc. */
}
if (y_inc == 0)
{ /* Only one precinct vertically. */
y0 = 0; y1 = y_inc = 1;
}
else
{
y0 = dims.top_row; y1 = y0 + dim
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -