diff --git a/src/dec/tree.c b/src/dec/tree.c index 7e7c4aae..82a58b88 100644 --- a/src/dec/tree.c +++ b/src/dec/tree.c @@ -327,7 +327,7 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { void VP8ResetProba(VP8Proba* const proba) { memset(proba->segments_, 255u, sizeof(proba->segments_)); - memcpy(proba->coeffs_, CoeffsProba0, sizeof(CoeffsProba0)); + // proba->bands_[][] is initialized later #ifndef ONLY_KEYFRAME_CODE memcpy(proba->mv_, kMVProba0, sizeof(kMVProba0)); memcpy(proba->ymode_, kYModeProbaInter0, sizeof(kYModeProbaInter0)); @@ -547,9 +547,9 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) { for (b = 0; b < NUM_BANDS; ++b) { for (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { - if (VP8GetBit(br, CoeffsUpdateProba[t][b][c][p])) { - proba->coeffs_[t][b][c][p] = VP8GetValue(br, 8); - } + const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ? + VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p]; + proba->bands_[t][b].probas_[c][p] = v; } } } diff --git a/src/dec/vp8.c b/src/dec/vp8.c index 59efb71c..1ee6cfa0 100644 --- a/src/dec/vp8.c +++ b/src/dec/vp8.c @@ -439,9 +439,6 @@ static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; -typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting -typedef const uint8_t (*ProbaCtxArray)[NUM_PROBAS]; - // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { int v; @@ -476,15 +473,15 @@ static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { // Returns the position of the last non-zero coeff plus one // (and 0 if there's no coeff at all) -static int GetCoeffs(VP8BitReader* const br, ProbaArray prob, +static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob, int ctx, const quant_t dq, int n, int16_t* out) { // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'. - const uint8_t* p = prob[n][ctx]; + const uint8_t* p = prob[n].probas_[ctx]; if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit. return 0; } for (; n < 16; ++n) { - const ProbaCtxArray p_ctx = prob[kBands[n + 1]]; + const VP8ProbaArray *p_ctx = &prob[kBands[n + 1]].probas_[0]; if (!VP8GetBit(br, p[1])) { p = p_ctx[0]; } else { // non zero coeff @@ -507,9 +504,8 @@ static int GetCoeffs(VP8BitReader* const br, ProbaArray prob, static int ParseResiduals(VP8Decoder* const dec, VP8MB* const mb, VP8BitReader* const token_br) { - uint32_t out_t_nz, out_l_nz; - int first; - ProbaArray ac_prob; + VP8BandProbas (* const bands)[NUM_BANDS] = dec->proba_.bands_; + const VP8BandProbas* ac_proba; const VP8QuantMatrix* const q = &dec->dqm_[dec->segment_]; VP8MBData* const block = dec->mb_data_; int16_t* dst = block->coeffs_; @@ -518,20 +514,21 @@ static int ParseResiduals(VP8Decoder* const dec, uint32_t non_zero_ac = 0; uint32_t non_zero_dc = 0; int x, y, ch; + uint32_t out_t_nz, out_l_nz; + int first; memset(dst, 0, 384 * sizeof(*dst)); if (!block->is_i4x4_) { // parse DC int16_t dc[16] = { 0 }; const int ctx = mb->nz_dc_ + left_mb->nz_dc_; mb->nz_dc_ = left_mb->nz_dc_ = - (GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[1], - ctx, q->y2_mat_, 0, dc) > 0); - first = 1; - ac_prob = (ProbaArray)dec->proba_.coeffs_[0]; + (GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc) > 0); VP8TransformWHT(dc, dst); + first = 1; + ac_proba = bands[0]; } else { first = 0; - ac_prob = (ProbaArray)dec->proba_.coeffs_[3]; + ac_proba = bands[3]; } tnz = mb->nz_ & 0x0f; @@ -541,8 +538,7 @@ static int ParseResiduals(VP8Decoder* const dec, uint32_t nz_dc = 0, nz_ac = 0; for (x = 0; x < 4; ++x) { const int ctx = l + (tnz & 1); - const int nz = GetCoeffs(token_br, ac_prob, ctx, - q->y1_mat_, first, dst); + const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst); l = (nz > 0); tnz = (tnz >> 1) | (l << 7); nz_dc = (nz_dc << 1) | (dst[0] != 0); @@ -565,9 +561,7 @@ static int ParseResiduals(VP8Decoder* const dec, int l = lnz & 1; for (x = 0; x < 2; ++x) { const int ctx = l + (tnz & 1); - const int nz = - GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[2], - ctx, q->uv_mat_, 0, dst); + const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst); l = (nz > 0); tnz = (tnz >> 1) | (l << 3); nz_dc = (nz_dc << 1) | (dst[0] != 0); diff --git a/src/dec/vp8i.h b/src/dec/vp8i.h index 308b61d6..ba1e819c 100644 --- a/src/dec/vp8i.h +++ b/src/dec/vp8i.h @@ -128,11 +128,19 @@ typedef struct { int8_t filter_strength_[NUM_MB_SEGMENTS]; // filter strength for segments } VP8SegmentHeader; + +// probas associated to one of the contexts +typedef uint8_t VP8ProbaArray[NUM_PROBAS]; + +typedef struct { // all the probas associated to one band + VP8ProbaArray probas_[NUM_CTX]; +} VP8BandProbas; + // Struct collecting all frame-persistent probabilities. typedef struct { uint8_t segments_[MB_FEATURE_TREE_PROBS]; // Type: 0:Intra16-AC 1:Intra16-DC 2:Chroma 3:Intra4 - uint8_t coeffs_[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS]; + VP8BandProbas bands_[NUM_TYPES][NUM_BANDS]; #ifndef ONLY_KEYFRAME_CODE uint8_t ymode_[4], uvmode_[3]; uint8_t mv_[2][NUM_MV_PROBAS];