mirror of
https://github.com/BinomialLLC/basis_universal.git
synced 2026-10-29 12:15:33 +00:00
Still a WIP - needs more testing (especially when video is disabled, which hasn't been tested on this branch yet):
- Adding conditional replenishment (CR) support to the system, so blocks which don't change their selectors or endpoints from the last frame don't need to be decoded. This can greatly increase the compression ratio on many video sequences. - Updating help text. - Adding support for slices to be marked as i-frames - Updating transcoder to support CR
This commit is contained in:
+240
-67
@@ -170,14 +170,13 @@ namespace basisu
|
||||
{
|
||||
{ -1, 0 },
|
||||
{ 0, -1 },
|
||||
{ -1, -1 }
|
||||
{ -1, -1 } // or conditional replenishment in videos
|
||||
};
|
||||
const uint32_t NUM_ENDPOINT_PREDS = BASISU_ARRAY_SIZE(g_endpoint_preds);
|
||||
const uint32_t NO_ENDPOINT_PRED_INDEX = 3;//NUM_ENDPOINT_PREDS;
|
||||
|
||||
|
||||
void basisu_backend::reoptimize_and_sort_endpoints_codebook(uint32_t total_block_endpoints_remapped, uint_vec &all_endpoint_indices)
|
||||
{
|
||||
basisu_frontend &r = *m_pFront_end;
|
||||
const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
|
||||
|
||||
if (total_block_endpoints_remapped)
|
||||
{
|
||||
@@ -292,10 +291,106 @@ namespace basisu
|
||||
for (uint32_t i = 0; i < m_selector_remap_table_new_to_old.size(); i++)
|
||||
m_selector_remap_table_old_to_new[m_selector_remap_table_new_to_old[i]] = i;
|
||||
}
|
||||
|
||||
int basisu_backend::find_video_frame(int slice_index, int delta)
|
||||
{
|
||||
for (uint32_t s = 0; s < m_slices.size(); s++)
|
||||
{
|
||||
if ((int)m_slices[s].m_source_file_index != (m_slices[slice_index].m_source_file_index + delta))
|
||||
continue;
|
||||
|
||||
if (m_slices[s].m_mip_index != m_slices[slice_index].m_mip_index)
|
||||
continue;
|
||||
|
||||
// Being super paranoid here.
|
||||
if (m_slices[s].m_num_blocks_x != (m_slices[slice_index].m_num_blocks_x))
|
||||
continue;
|
||||
if (m_slices[s].m_num_blocks_y != (m_slices[slice_index].m_num_blocks_y))
|
||||
continue;
|
||||
if (m_slices[s].m_alpha != (m_slices[slice_index].m_alpha))
|
||||
continue;
|
||||
return s;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void basisu_backend::check_for_valid_cr_blocks()
|
||||
{
|
||||
basisu_frontend& r = *m_pFront_end;
|
||||
const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
|
||||
|
||||
if (!is_video)
|
||||
return;
|
||||
|
||||
uint32_t total_crs = 0;
|
||||
uint32_t total_invalid_crs = 0;
|
||||
|
||||
for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
|
||||
{
|
||||
const bool is_iframe = m_slices[slice_index].m_iframe;
|
||||
const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
|
||||
|
||||
const uint32_t width = m_slices[slice_index].m_width;
|
||||
const uint32_t height = m_slices[slice_index].m_height;
|
||||
const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x;
|
||||
const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y;
|
||||
const int prev_frame_slice_index = find_video_frame(slice_index, -1);
|
||||
|
||||
// If we don't have a previous frame, and we're not an i-frame, something is wrong.
|
||||
if ((prev_frame_slice_index < 0) && (!is_iframe))
|
||||
{
|
||||
BASISU_BACKEND_VERIFY(0);
|
||||
}
|
||||
|
||||
if ((is_iframe) || (prev_frame_slice_index < 0))
|
||||
{
|
||||
// Ensure no blocks use CR's
|
||||
for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
|
||||
{
|
||||
for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
|
||||
{
|
||||
encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);
|
||||
BASISU_BACKEND_VERIFY(m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For blocks that use CR's, make sure the endpoints/selectors haven't really changed.
|
||||
for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
|
||||
{
|
||||
for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
|
||||
{
|
||||
encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);
|
||||
|
||||
if (m.m_endpoint_predictor == basist::CR_ENDPOINT_PRED_INDEX)
|
||||
{
|
||||
total_crs++;
|
||||
|
||||
encoder_block& prev_m = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y);
|
||||
|
||||
if ((m.m_endpoint_index != prev_m.m_endpoint_index) || (m.m_selector_index != prev_m.m_selector_index))
|
||||
{
|
||||
total_invalid_crs++;
|
||||
}
|
||||
}
|
||||
} // block_x
|
||||
} // block_y
|
||||
|
||||
} // !slice_index
|
||||
|
||||
} // slice_index
|
||||
|
||||
debug_printf("Total CR's: %u, Total invalid CR's: %u\n", total_crs, total_invalid_crs);
|
||||
|
||||
BASISU_BACKEND_VERIFY(total_invalid_crs == 0);
|
||||
}
|
||||
|
||||
void basisu_backend::create_encoder_blocks()
|
||||
{
|
||||
basisu_frontend &r = *m_pFront_end;
|
||||
const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
|
||||
|
||||
m_slice_encoder_blocks.resize(m_slices.size());
|
||||
|
||||
@@ -306,6 +401,9 @@ namespace basisu
|
||||
|
||||
for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
|
||||
{
|
||||
const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1;
|
||||
const bool is_iframe = m_slices[slice_index].m_iframe;
|
||||
|
||||
const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
|
||||
|
||||
const uint32_t width = m_slices[slice_index].m_width;
|
||||
@@ -328,29 +426,50 @@ namespace basisu
|
||||
|
||||
m.m_selector_index = r.get_block_selector_cluster_index(block_index);
|
||||
|
||||
m.m_endpoint_predictor = NO_ENDPOINT_PRED_INDEX;
|
||||
m.m_endpoint_predictor = basist::NO_ENDPOINT_PRED_INDEX;
|
||||
|
||||
const uint32_t block_endpoint = m.m_endpoint_index;
|
||||
|
||||
uint32_t best_endpoint_pred = UINT32_MAX;
|
||||
|
||||
for (uint32_t endpoint_pred = 0; endpoint_pred < NUM_ENDPOINT_PREDS; endpoint_pred++)
|
||||
|
||||
for (uint32_t endpoint_pred = 0; endpoint_pred < basist::NUM_ENDPOINT_PREDS; endpoint_pred++)
|
||||
{
|
||||
int pred_block_x = block_x + g_endpoint_preds[endpoint_pred].m_dx;
|
||||
if ((pred_block_x < 0) || (pred_block_x >= (int)num_blocks_x))
|
||||
continue;
|
||||
|
||||
int pred_block_y = block_y + g_endpoint_preds[endpoint_pred].m_dy;
|
||||
if ((pred_block_y < 0) || (pred_block_y >= (int)num_blocks_y))
|
||||
continue;
|
||||
|
||||
uint32_t pred_endpoint = m_slice_encoder_blocks[slice_index](pred_block_x, pred_block_y).m_endpoint_index;
|
||||
|
||||
if (pred_endpoint == block_endpoint)
|
||||
if ((is_video) && (endpoint_pred == basist::CR_ENDPOINT_PRED_INDEX))
|
||||
{
|
||||
if (endpoint_pred < best_endpoint_pred)
|
||||
if ((prev_frame_slice_index != -1) && (!is_iframe))
|
||||
{
|
||||
best_endpoint_pred = endpoint_pred;
|
||||
const uint32_t cur_endpoint = m_slice_encoder_blocks[slice_index](block_x, block_y).m_endpoint_index;
|
||||
const uint32_t cur_selector = m_slice_encoder_blocks[slice_index](block_x, block_y).m_selector_index;
|
||||
|
||||
const uint32_t prev_endpoint = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_endpoint_index;
|
||||
const uint32_t prev_selector = m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_selector_index;
|
||||
|
||||
if ((cur_endpoint == prev_endpoint) && (cur_selector == prev_selector))
|
||||
{
|
||||
best_endpoint_pred = basist::CR_ENDPOINT_PRED_INDEX;
|
||||
|
||||
m_slice_encoder_blocks[prev_frame_slice_index](block_x, block_y).m_is_cr_target = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int pred_block_x = block_x + g_endpoint_preds[endpoint_pred].m_dx;
|
||||
if ((pred_block_x < 0) || (pred_block_x >= (int)num_blocks_x))
|
||||
continue;
|
||||
|
||||
int pred_block_y = block_y + g_endpoint_preds[endpoint_pred].m_dy;
|
||||
if ((pred_block_y < 0) || (pred_block_y >= (int)num_blocks_y))
|
||||
continue;
|
||||
|
||||
uint32_t pred_endpoint = m_slice_encoder_blocks[slice_index](pred_block_x, pred_block_y).m_endpoint_index;
|
||||
|
||||
if (pred_endpoint == block_endpoint)
|
||||
{
|
||||
if (endpoint_pred < best_endpoint_pred)
|
||||
{
|
||||
best_endpoint_pred = endpoint_pred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,8 +500,11 @@ namespace basisu
|
||||
|
||||
best_endpoint_pred = UINT32_MAX;
|
||||
|
||||
for (uint32_t endpoint_pred = 0; endpoint_pred < NUM_ENDPOINT_PREDS; endpoint_pred++)
|
||||
for (uint32_t endpoint_pred = 0; endpoint_pred < basist::NUM_ENDPOINT_PREDS; endpoint_pred++)
|
||||
{
|
||||
if ((is_video) && (endpoint_pred == basist::CR_ENDPOINT_PRED_INDEX))
|
||||
continue;
|
||||
|
||||
int pred_block_x = block_x + g_endpoint_preds[endpoint_pred].m_dx;
|
||||
if ((pred_block_x < 0) || (pred_block_x >= (int)num_blocks_x))
|
||||
continue;
|
||||
@@ -441,7 +563,7 @@ namespace basisu
|
||||
total_endpoint_pred_missed++;
|
||||
}
|
||||
|
||||
if (m.m_endpoint_predictor == NO_ENDPOINT_PRED_INDEX)
|
||||
if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
|
||||
{
|
||||
all_endpoint_indices.push_back(m.m_endpoint_index);
|
||||
}
|
||||
@@ -456,10 +578,12 @@ namespace basisu
|
||||
total_endpoint_pred_missed, total_endpoint_pred_missed * 100.0f / get_total_blocks(),
|
||||
total_endpoint_pred_hits, total_endpoint_pred_hits * 100.0f / get_total_blocks(),
|
||||
total_block_endpoints_remapped, total_block_endpoints_remapped * 100.0f / get_total_blocks());
|
||||
|
||||
|
||||
reoptimize_and_sort_endpoints_codebook(total_block_endpoints_remapped, all_endpoint_indices);
|
||||
|
||||
sort_selector_codebook();
|
||||
|
||||
check_for_valid_cr_blocks();
|
||||
}
|
||||
|
||||
void basisu_backend::compute_slice_crcs()
|
||||
@@ -481,22 +605,22 @@ namespace basisu
|
||||
{
|
||||
const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x;
|
||||
|
||||
encoder_block &m = m_slice_encoder_blocks[slice_index](block_x, block_y);
|
||||
encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y);
|
||||
|
||||
{
|
||||
etc_block &output_block = *(etc_block *)gi.get_block_ptr(block_x, block_y);
|
||||
etc_block& output_block = *(etc_block*)gi.get_block_ptr(block_x, block_y);
|
||||
|
||||
output_block.set_diff_bit(true);
|
||||
output_block.set_flip_bit(true);
|
||||
|
||||
|
||||
const uint32_t endpoint_index = m.m_endpoint_index;
|
||||
|
||||
|
||||
output_block.set_block_color5_etc1s(m_endpoint_palette[endpoint_index].m_color5);
|
||||
output_block.set_inten_tables_etc1s(m_endpoint_palette[endpoint_index].m_inten5);
|
||||
|
||||
const uint32_t selector_idx = m.m_selector_index;
|
||||
|
||||
const basist::etc1_selector_palette_entry &selectors = m_selector_palette[selector_idx];
|
||||
const basist::etc1_selector_palette_entry& selectors = m_selector_palette[selector_idx];
|
||||
for (uint32_t sy = 0; sy < 4; sy++)
|
||||
for (uint32_t sx = 0; sx < 4; sx++)
|
||||
output_block.set_selector(sx, sy, selectors(sx, sy));
|
||||
@@ -520,7 +644,7 @@ namespace basisu
|
||||
#endif
|
||||
save_png(buf, gi_unpacked);
|
||||
}
|
||||
|
||||
|
||||
} // slice_index
|
||||
}
|
||||
|
||||
@@ -528,6 +652,7 @@ namespace basisu
|
||||
bool basisu_backend::encode_image()
|
||||
{
|
||||
basisu_frontend &r = *m_pFront_end;
|
||||
const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
|
||||
|
||||
uint32_t total_used_selector_history_buf = 0;
|
||||
uint32_t total_selector_indices_remapped = 0;
|
||||
@@ -555,6 +680,9 @@ namespace basisu
|
||||
|
||||
for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++)
|
||||
{
|
||||
const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1;
|
||||
const int next_frame_slice_index = is_video ? find_video_frame(slice_index, 1) : -1;
|
||||
|
||||
const uint32_t first_block_index = m_slices[slice_index].m_first_block_index;
|
||||
const uint32_t width = m_slices[slice_index].m_width;
|
||||
const uint32_t height = m_slices[slice_index].m_height;
|
||||
@@ -584,10 +712,21 @@ namespace basisu
|
||||
else if (m.m_endpoint_predictor == 1)
|
||||
block_endpoints_are_referenced(block_x, block_y - 1) = true;
|
||||
else if (m.m_endpoint_predictor == 2)
|
||||
block_endpoints_are_referenced(block_x - 1, block_y - 1) = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (!is_video)
|
||||
block_endpoints_are_referenced(block_x - 1, block_y - 1) = true;
|
||||
}
|
||||
|
||||
if (is_video)
|
||||
{
|
||||
if (m.m_is_cr_target)
|
||||
block_endpoints_are_referenced(block_x, block_y) = true;
|
||||
}
|
||||
|
||||
} // block_x
|
||||
|
||||
} // block_y
|
||||
|
||||
for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
|
||||
{
|
||||
for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
|
||||
@@ -607,7 +746,7 @@ namespace basisu
|
||||
const uint32_t bx = block_x + x;
|
||||
const uint32_t by = block_y + y;
|
||||
|
||||
uint32_t pred = NO_ENDPOINT_PRED_INDEX;
|
||||
uint32_t pred = basist::NO_ENDPOINT_PRED_INDEX;
|
||||
if ((bx < num_blocks_x) && (by < num_blocks_y))
|
||||
pred = m_slice_encoder_blocks[slice_index](bx, by).m_endpoint_predictor;
|
||||
|
||||
@@ -647,11 +786,11 @@ namespace basisu
|
||||
|
||||
prev_endpoint_pred_sym_bits = endpoint_pred_cur_sym_bits;
|
||||
}
|
||||
}
|
||||
} // if (((block_x & 1) == 0) && ((block_y & 1) == 0))
|
||||
|
||||
int new_endpoint_index = m_endpoint_remap_table_old_to_new[m.m_endpoint_index];
|
||||
|
||||
if (m.m_endpoint_predictor == NO_ENDPOINT_PRED_INDEX)
|
||||
if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
|
||||
{
|
||||
int endpoint_delta = new_endpoint_index - prev_endpoint_index;
|
||||
|
||||
@@ -719,17 +858,34 @@ namespace basisu
|
||||
endpoint_delta += (int)r.get_total_endpoint_clusters();
|
||||
|
||||
delta_endpoint_histogram.inc(endpoint_delta);
|
||||
}
|
||||
} // if (m.m_endpoint_predictor == NO_ENDPOINT_PRED_INDEX)
|
||||
|
||||
block_endpoint_indices.push_back(m_endpoint_remap_table_new_to_old[new_endpoint_index]);
|
||||
|
||||
prev_endpoint_index = new_endpoint_index;
|
||||
|
||||
if ((!is_video) || (m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX))
|
||||
{
|
||||
int new_selector_index = m_selector_remap_table_old_to_new[m.m_selector_index];
|
||||
|
||||
int selector_history_buf_index = -1;
|
||||
|
||||
if (m.m_is_cr_target)
|
||||
{
|
||||
for (uint32_t j = 0; j < selector_history_buf.size(); j++)
|
||||
{
|
||||
const int trial_idx = selector_history_buf[j];
|
||||
if (trial_idx == new_selector_index)
|
||||
{
|
||||
total_used_selector_history_buf++;
|
||||
selector_history_buf_index = j;
|
||||
selector_history_buf_histogram.inc(j);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const pixel_block &src_pixels = r.get_source_pixel_block(block_index);
|
||||
|
||||
@@ -796,11 +952,9 @@ namespace basisu
|
||||
selector_history_buf_histogram.inc(best_trial_history_buf_idx);
|
||||
}
|
||||
} // if (m_params.m_selector_rdo_quality_thresh > 0.0f)
|
||||
|
||||
|
||||
m.m_selector_index = m_selector_remap_table_new_to_old[new_selector_index];
|
||||
|
||||
block_selector_indices.push_back(m.m_selector_index);
|
||||
|
||||
if ((selector_history_buf_rle_count) && (selector_history_buf_index != 0))
|
||||
{
|
||||
if (selector_history_buf_rle_count >= (int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH)
|
||||
@@ -857,7 +1011,10 @@ namespace basisu
|
||||
selector_history_buf.add(new_selector_index);
|
||||
else if (selector_history_buf.size())
|
||||
selector_history_buf.use(selector_history_buf_index);
|
||||
}
|
||||
|
||||
} // if ((!is_video) || (m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX))
|
||||
|
||||
block_selector_indices.push_back(m.m_selector_index);
|
||||
|
||||
} // block_x
|
||||
|
||||
@@ -931,6 +1088,8 @@ namespace basisu
|
||||
create_endpoint_palette();
|
||||
}
|
||||
|
||||
check_for_valid_cr_blocks();
|
||||
|
||||
compute_slice_crcs();
|
||||
|
||||
double endpoint_pred_entropy = endpoint_pred_histogram.get_entropy() / endpoint_pred_histogram.get_total();
|
||||
@@ -939,6 +1098,9 @@ namespace basisu
|
||||
|
||||
debug_printf("Histogram entropy: EndpointPred: %3.3f DeltaEndpoint: %3.3f DeltaSelector: %3.3f\n", endpoint_pred_entropy, delta_endpoint_entropy, selector_entropy);
|
||||
|
||||
if (!endpoint_pred_histogram.get_total())
|
||||
endpoint_pred_histogram.inc(0);
|
||||
|
||||
huffman_encoding_table endpoint_pred_model;
|
||||
if (!endpoint_pred_model.init(endpoint_pred_histogram, 16))
|
||||
{
|
||||
@@ -946,6 +1108,9 @@ namespace basisu
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!delta_endpoint_histogram.get_total())
|
||||
delta_endpoint_histogram.inc(0);
|
||||
|
||||
huffman_encoding_table delta_endpoint_model;
|
||||
if (!delta_endpoint_model.init(delta_endpoint_histogram, 16))
|
||||
{
|
||||
@@ -953,6 +1118,9 @@ namespace basisu
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!selector_histogram.get_total())
|
||||
selector_histogram.inc(0);
|
||||
|
||||
huffman_encoding_table selector_model;
|
||||
if (!selector_model.init(selector_histogram, 16))
|
||||
{
|
||||
@@ -1047,11 +1215,11 @@ namespace basisu
|
||||
prev_endpoint_pred_sym = sym;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if (((block_x & 1) == 0) && ((block_y & 1) == 0))
|
||||
|
||||
const int new_endpoint_index = m_endpoint_remap_table_old_to_new[m.m_endpoint_index];
|
||||
|
||||
if (m.m_endpoint_predictor == NO_ENDPOINT_PRED_INDEX)
|
||||
if (m.m_endpoint_predictor == basist::NO_ENDPOINT_PRED_INDEX)
|
||||
{
|
||||
int endpoint_delta = new_endpoint_index - prev_endpoint_index;
|
||||
if (endpoint_delta < 0)
|
||||
@@ -1062,32 +1230,35 @@ namespace basisu
|
||||
|
||||
prev_endpoint_index = new_endpoint_index;
|
||||
|
||||
if (!selector_rle_count)
|
||||
if ((!is_video) || (m.m_endpoint_predictor != basist::CR_ENDPOINT_PRED_INDEX))
|
||||
{
|
||||
uint32_t selector_sym_index = selector_syms[slice_index][cur_selector_sym_ofs++];
|
||||
|
||||
if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
|
||||
selector_rle_count = selector_syms[slice_index][cur_selector_sym_ofs++];
|
||||
|
||||
total_selector_bits += coder.put_code(selector_sym_index, selector_model);
|
||||
|
||||
if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
|
||||
if (!selector_rle_count)
|
||||
{
|
||||
int run_sym = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
|
||||
if (run_sym >= ((int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
|
||||
{
|
||||
total_selector_bits += coder.put_code(basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1, selector_history_buf_rle_model);
|
||||
|
||||
uint32_t n = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
|
||||
total_selector_bits += coder.put_vlc(n, 7);
|
||||
}
|
||||
else
|
||||
total_selector_bits += coder.put_code(run_sym, selector_history_buf_rle_model);
|
||||
}
|
||||
}
|
||||
uint32_t selector_sym_index = selector_syms[slice_index][cur_selector_sym_ofs++];
|
||||
|
||||
if (selector_rle_count)
|
||||
selector_rle_count--;
|
||||
if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
|
||||
selector_rle_count = selector_syms[slice_index][cur_selector_sym_ofs++];
|
||||
|
||||
total_selector_bits += coder.put_code(selector_sym_index, selector_model);
|
||||
|
||||
if (selector_sym_index == SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX)
|
||||
{
|
||||
int run_sym = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
|
||||
if (run_sym >= ((int)basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
|
||||
{
|
||||
total_selector_bits += coder.put_code(basist::SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1, selector_history_buf_rle_model);
|
||||
|
||||
uint32_t n = selector_rle_count - basist::SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
|
||||
total_selector_bits += coder.put_vlc(n, 7);
|
||||
}
|
||||
else
|
||||
total_selector_bits += coder.put_code(run_sym, selector_history_buf_rle_model);
|
||||
}
|
||||
}
|
||||
|
||||
if (selector_rle_count)
|
||||
selector_rle_count--;
|
||||
}
|
||||
|
||||
} // block_x
|
||||
|
||||
@@ -1471,9 +1642,11 @@ namespace basisu
|
||||
|
||||
uint32_t basisu_backend::encode()
|
||||
{
|
||||
const bool is_video = m_pFront_end->get_params().m_tex_type == basist::cBASISTexTypeVideoFrames;
|
||||
|
||||
m_output.m_slice_desc = m_slices;
|
||||
m_output.m_etc1s = m_params.m_etc1s;
|
||||
|
||||
|
||||
create_endpoint_palette();
|
||||
create_selector_palette();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user