separate block-parsing into a visible VP8DecodeMB()

This is to prepare for incremental decoding.

Change-Id: Ifc7e2df3e18eb56af3752cba8dfe08d370036d7f
This commit is contained in:
Pascal Massimino 2011-03-09 21:29:36 -08:00
parent a871de0255
commit 3db6525574
2 changed files with 44 additions and 40 deletions

View File

@ -432,7 +432,7 @@ static int GetCoeffs(VP8BitReader* const br, ProbaArray prob,
return 0; return 0;
} }
// alias-safe way of converting 4bytes to 32bits // Alias-safe way of converting 4bytes to 32bits.
typedef union { typedef union {
uint8_t i8[4]; uint8_t i8[4];
uint32_t i32; uint32_t i32;
@ -454,8 +454,8 @@ static const PackedNz kUnpackTab[16] = {
#endif #endif
#define PACK(X, S) ((((X).i32 * PACK_CST) & 0xff000000) >> (S)) #define PACK(X, S) ((((X).i32 * PACK_CST) & 0xff000000) >> (S))
static int ParseResiduals(VP8Decoder* const dec, static void ParseResiduals(VP8Decoder* const dec,
VP8MB* const mb, VP8BitReader* const token_br) { VP8MB* const mb, VP8BitReader* const token_br) {
int out_t_nz, out_l_nz, first; int out_t_nz, out_l_nz, first;
ProbaArray ac_prob; ProbaArray ac_prob;
const VP8QuantMatrix* q = &dec->dqm_[dec->segment_]; const VP8QuantMatrix* q = &dec->dqm_[dec->segment_];
@ -527,54 +527,60 @@ static int ParseResiduals(VP8Decoder* const dec,
dec->non_zero_ac_ = non_zero_ac; dec->non_zero_ac_ = non_zero_ac;
dec->non_zero_ = non_zero_ac | non_zero_dc; dec->non_zero_ = non_zero_ac | non_zero_dc;
mb->skip_ = !dec->non_zero_; mb->skip_ = !dec->non_zero_;
return 1;
} }
#undef PACK #undef PACK
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main loop // Main loop
static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
VP8BitReader* const br = &dec->br_; VP8BitReader* const br = &dec->br_;
VP8BitReader* token_br; VP8MB* const left = dec->mb_info_ - 1;
VP8MB* const info = dec->mb_info_ + dec->mb_x_;
// Note: we don't save segment map (yet), as we don't expect
// to decode more than 1 keyframe.
if (dec->segment_hdr_.update_map_) {
// Hardcoded tree parsing
dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ?
VP8GetBit(br, dec->proba_.segments_[1]) :
2 + VP8GetBit(br, dec->proba_.segments_[2]);
}
info->skip_ = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0;
VP8ParseIntraMode(br, dec);
if (br->eof_) {
return 0;
}
if (!info->skip_) {
ParseResiduals(dec, info, token_br);
} else {
left->nz_ = info->nz_ = 0;
if (!dec->is_i4x4_) {
left->dc_nz_ = info->dc_nz_ = 0;
}
dec->non_zero_ = 0;
dec->non_zero_ac_ = 0;
}
return (!token_br->eof_);
}
static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
for (dec->mb_y_ = 0; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) { for (dec->mb_y_ = 0; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
VP8MB* const left = dec->mb_info_ - 1; VP8MB* const left = dec->mb_info_ - 1;
VP8BitReader* const token_br =
memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
left->nz_ = 0; left->nz_ = 0;
left->dc_nz_ = 0; left->dc_nz_ = 0;
token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_));
for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) { for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) {
VP8MB* const info = dec->mb_info_ + dec->mb_x_; if (!VP8DecodeMB(dec, token_br)) {
return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
// Note: we don't save segment map (yet), as we don't expect "Premature end-of-file encountered.");
// to decode more than 1 keyframe.
if (dec->segment_hdr_.update_map_) {
// Hardcoded tree parsing
dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ?
VP8GetBit(br, dec->proba_.segments_[1]) :
2 + VP8GetBit(br, dec->proba_.segments_[2]);
}
info->skip_ = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0;
VP8ParseIntraMode(br, dec);
if (!info->skip_) {
if (!ParseResiduals(dec, info, token_br)) {
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
"Residual parsing failed.");
}
} else {
left->nz_ = info->nz_ = 0;
if (!dec->is_i4x4_) {
left->dc_nz_ = info->dc_nz_ = 0;
}
dec->non_zero_ = 0;
dec->non_zero_ac_ = 0;
} }
VP8ReconstructBlock(dec); VP8ReconstructBlock(dec);
@ -585,10 +591,6 @@ static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
return VP8SetError(dec, VP8_STATUS_USER_ABORT, return VP8SetError(dec, VP8_STATUS_USER_ABORT,
"Output aborted."); "Output aborted.");
} }
if (dec->br_.eof_ || token_br->eof_) {
return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
"Premature end-of-file encountered.");
}
} }
// Finish // Finish

View File

@ -265,6 +265,8 @@ void VP8ReconstructBlock(VP8Decoder* const dec);
void VP8StoreBlock(VP8Decoder* const dec); void VP8StoreBlock(VP8Decoder* const dec);
// Finalize and transmit a complete row. Return false in case of user-abort. // Finalize and transmit a complete row. Return false in case of user-abort.
int VP8FinishRow(VP8Decoder* const dec, VP8Io* io); int VP8FinishRow(VP8Decoder* const dec, VP8Io* io);
// Decode one macroblock. Returns false if there is not enough data.
int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
// in dsp.c // in dsp.c
typedef void (*VP8Idct)(const int16_t* coeffs, uint8_t* dst); typedef void (*VP8Idct)(const int16_t* coeffs, uint8_t* dst);