package org.jcodec.codecs.h264.decode;
import static org.jcodec.codecs.h264.decode.CoeffTransformer.reorderDC4x4;
import static org.jcodec.codecs.h264.decode.MBlockDecoderUtils.collectPredictors;
import static org.jcodec.codecs.h264.decode.MBlockDecoderUtils.saveMvsIntra;
import static org.jcodec.codecs.h264.decode.MBlockDecoderUtils.saveVectIntra;
import org.jcodec.codecs.h264.decode.aso.Mapper;
import org.jcodec.codecs.h264.io.model.SliceHeader;
import org.jcodec.common.model.Picture8Bit;
/**
* A decoder for I16x16 macroblocks
*
* @author The JCodec project
*/
public class MBlockDecoderIntra16x16 extends MBlockDecoderBase {
private Mapper mapper;
public MBlockDecoderIntra16x16(Mapper mapper, SliceHeader sh, DeblockerInput di, int poc,
DecoderState decoderState) {
super(sh, di, poc, decoderState);
this.mapper = mapper;
}
public void decode(MBlock mBlock, Picture8Bit mb) {
int mbX = mapper.getMbX(mBlock.mbIdx);
int mbY = mapper.getMbY(mBlock.mbIdx);
int address = mapper.getAddress(mBlock.mbIdx);
boolean leftAvailable = mapper.leftAvailable(mBlock.mbIdx);
boolean topAvailable = mapper.topAvailable(mBlock.mbIdx);
s.qp = (s.qp + mBlock.mbQPDelta + 52) % 52;
di.mbQps[0][address] = s.qp;
residualLumaI16x16(mBlock, leftAvailable, topAvailable, mbX, mbY);
Intra16x16PredictionBuilder.predictWithMode(mBlock.luma16x16Mode, mBlock.ac[0], leftAvailable, topAvailable,
s.leftRow[0], s.topLine[0], s.topLeft[0], mbX << 4, mb.getPlaneData(0));
decodeChroma(mBlock, mbX, mbY, leftAvailable, topAvailable, mb, s.qp);
di.mbTypes[address] = mBlock.curMbType;
collectPredictors(s, mb, mbX);
saveMvsIntra(di, mbX, mbY);
saveVectIntra(s, mapper.getMbX(mBlock.mbIdx));
}
private void residualLumaI16x16(MBlock mBlock, boolean leftAvailable, boolean topAvailable, int mbX, int mbY) {
CoeffTransformer.invDC4x4(mBlock.dc);
CoeffTransformer.dequantizeDC4x4(mBlock.dc, s.qp);
reorderDC4x4(mBlock.dc);
for (int i = 0; i < 16; i++) {
if ((mBlock.cbpLuma() & (1 << (i >> 2))) != 0) {
CoeffTransformer.dequantizeAC(mBlock.ac[0][i], s.qp);
}
mBlock.ac[0][i][0] = mBlock.dc[i];
CoeffTransformer.idct4x4(mBlock.ac[0][i]);
}
}
}