Refine rate estimation in trellis quant

Account for the more elaborate context modeling used for coding the DC
coefficient differences
This commit is contained in:
Frank Bossen
2014-12-21 21:36:06 +01:00
parent 933289f509
commit fa628eff6a
3 changed files with 21 additions and 6 deletions

View File

@@ -941,6 +941,8 @@ jget_arith_rates (j_compress_ptr cinfo, int dc_tbl_no, int ac_tbl_no, arith_rate
int i; int i;
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
r->arith_dc_L = cinfo->arith_dc_L[dc_tbl_no];
r->arith_dc_U = cinfo->arith_dc_U[dc_tbl_no];
r->arith_ac_K = cinfo->arith_ac_K[ac_tbl_no]; r->arith_ac_K = cinfo->arith_ac_K[ac_tbl_no];
for (i = 0; i < DC_STAT_BINS; i++) { for (i = 0; i < DC_STAT_BINS; i++) {

View File

@@ -1290,12 +1290,11 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
float *accumulated_dc_cost[DC_TRELLIS_CANDIDATES]; float *accumulated_dc_cost[DC_TRELLIS_CANDIDATES];
int *dc_cost_backtrack[DC_TRELLIS_CANDIDATES]; int *dc_cost_backtrack[DC_TRELLIS_CANDIDATES];
JCOEF *dc_candidate[DC_TRELLIS_CANDIDATES]; JCOEF *dc_candidate[DC_TRELLIS_CANDIDATES];
int *dc_context[DC_TRELLIS_CANDIDATES];
int mode = 1; int mode = 1;
float lambda_table[DCTSIZE2]; float lambda_table[DCTSIZE2];
/* Arithmetic coding context. Set to 0 for now but can refined */
int dc_context = 0;
Ss = cinfo->Ss; Ss = cinfo->Ss;
Se = cinfo->Se; Se = cinfo->Se;
if (Ss == 0) if (Ss == 0)
@@ -1308,9 +1307,11 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
accumulated_dc_cost[i] = (float *)malloc(num_blocks * sizeof(float)); accumulated_dc_cost[i] = (float *)malloc(num_blocks * sizeof(float));
dc_cost_backtrack[i] = (int *)malloc(num_blocks * sizeof(int)); dc_cost_backtrack[i] = (int *)malloc(num_blocks * sizeof(int));
dc_candidate[i] = (JCOEF *)malloc(num_blocks * sizeof(JCOEF)); dc_candidate[i] = (JCOEF *)malloc(num_blocks * sizeof(JCOEF));
dc_context[i] = (int *)malloc(num_blocks * sizeof(int));
if (!accumulated_dc_cost[i] || if (!accumulated_dc_cost[i] ||
!dc_cost_backtrack[i] || !dc_cost_backtrack[i] ||
!dc_candidate[i]) { !dc_candidate[i] ||
!dc_context[i]) {
ERREXIT(cinfo, JERR_OUT_OF_MEMORY); ERREXIT(cinfo, JERR_OUT_OF_MEMORY);
} }
} }
@@ -1364,7 +1365,6 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
int delta; int delta;
int dc_delta; int dc_delta;
float bits; float bits;
int st = dc_context;
int m; int m;
int v2; int v2;
@@ -1394,7 +1394,8 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
/* loop of candidates from previous block */ /* loop of candidates from previous block */
for (l = 0; l < (bi == 0 ? 1 : DC_TRELLIS_CANDIDATES); l++) { for (l = 0; l < (bi == 0 ? 1 : DC_TRELLIS_CANDIDATES); l++) {
int dc_pred = (bi == 0 ? *last_dc_val : dc_candidate[l][bi-1]); int dc_pred = (bi == 0 ? *last_dc_val : dc_candidate[l][bi-1]);
int updated_dc_context = 0;
int st = (bi == 0) ? 0 : dc_context[l][bi-1];
dc_delta = dc_candidate[k][bi] - dc_pred; dc_delta = dc_candidate[k][bi] - dc_pred;
bits = r->rate_dc[st][dc_delta != 0]; bits = r->rate_dc[st][dc_delta != 0];
@@ -1402,6 +1403,8 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
if (dc_delta != 0) { if (dc_delta != 0) {
bits += r->rate_dc[st+1][dc_delta < 0]; bits += r->rate_dc[st+1][dc_delta < 0];
st += 2 + (dc_delta < 0); st += 2 + (dc_delta < 0);
updated_dc_context = (dc_delta < 0) ? 8 : 4;
dc_delta = abs(dc_delta); dc_delta = abs(dc_delta);
m = 0; m = 0;
@@ -1417,6 +1420,12 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
} }
} }
bits += r->rate_dc[st][0]; bits += r->rate_dc[st][0];
if (m < (int) ((1L << r->arith_dc_L) >> 1))
updated_dc_context = 0; /* zero diff category */
else if (m > (int) ((1L << r->arith_dc_U) >> 1))
updated_dc_context += 8; /* large diff category */
st += 14; st += 14;
while (m >>= 1) while (m >>= 1)
bits += r->rate_dc[st][(m & dc_delta) ? 1 : 0]; bits += r->rate_dc[st][(m & dc_delta) ? 1 : 0];
@@ -1429,6 +1438,7 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
if (l == 0 || cost < accumulated_dc_cost[k][bi]) { if (l == 0 || cost < accumulated_dc_cost[k][bi]) {
accumulated_dc_cost[k][bi] = cost; accumulated_dc_cost[k][bi] = cost;
dc_cost_backtrack[k][bi] = (bi == 0 ? -1 : l); dc_cost_backtrack[k][bi] = (bi == 0 ? -1 : l);
dc_context[k][bi] = updated_dc_context;
} }
} }
} }
@@ -1590,6 +1600,7 @@ quantize_trellis_arith(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_bloc
free(accumulated_dc_cost[i]); free(accumulated_dc_cost[i]);
free(dc_cost_backtrack[i]); free(dc_cost_backtrack[i]);
free(dc_candidate[i]); free(dc_candidate[i]);
free(dc_context[i]);
} }
} }
} }

View File

@@ -110,6 +110,8 @@ struct jpeg_comp_master {
typedef struct { typedef struct {
float rate_dc[DC_STAT_BINS][2]; float rate_dc[DC_STAT_BINS][2];
float rate_ac[AC_STAT_BINS][2]; float rate_ac[AC_STAT_BINS][2];
int arith_dc_L;
int arith_dc_U;
int arith_ac_K; int arith_ac_K;
} arith_rates; } arith_rates;