www in docker support
This commit is contained in:
parent
539a848e95
commit
c227fce036
2145 changed files with 399596 additions and 58 deletions
|
|
@ -0,0 +1,334 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import org.jcodec.api.NotImplementedException;
|
||||
|
||||
public class FilterUtil {
|
||||
private static int clipPlus128(int v) {
|
||||
return clipSigned(v) + 128;
|
||||
}
|
||||
|
||||
public static class Segment {
|
||||
int p0;
|
||||
|
||||
int p1;
|
||||
|
||||
int p2;
|
||||
|
||||
int p3;
|
||||
|
||||
int q0;
|
||||
|
||||
int q1;
|
||||
|
||||
int q2;
|
||||
|
||||
int q3;
|
||||
|
||||
public boolean isFilterRequired(int interior, int edge) {
|
||||
return ((Math.abs(this.p0 - this.q0) << 2) + (Math.abs(this.p1 - this.q1) >> 2) <= edge &&
|
||||
Math.abs(this.p3 - this.p2) <= interior &&
|
||||
Math.abs(this.p2 - this.p1) <= interior &&
|
||||
Math.abs(this.p1 - this.p0) <= interior &&
|
||||
Math.abs(this.q3 - this.q2) <= interior &&
|
||||
Math.abs(this.q2 - this.q1) <= interior &&
|
||||
Math.abs(this.q1 - this.q0) <= interior);
|
||||
}
|
||||
|
||||
public boolean isHighVariance(int threshold) {
|
||||
return (Math.abs(this.p1 - this.p0) > threshold || Math.abs(this.q1 - this.q0) > threshold);
|
||||
}
|
||||
|
||||
public Segment getSigned() {
|
||||
Segment seg = new Segment();
|
||||
seg.p3 = FilterUtil.minus128(this.p3);
|
||||
seg.p2 = FilterUtil.minus128(this.p2);
|
||||
seg.p1 = FilterUtil.minus128(this.p1);
|
||||
seg.p0 = FilterUtil.minus128(this.p0);
|
||||
seg.q0 = FilterUtil.minus128(this.q0);
|
||||
seg.q1 = FilterUtil.minus128(this.q1);
|
||||
seg.q2 = FilterUtil.minus128(this.q2);
|
||||
seg.q3 = FilterUtil.minus128(this.q3);
|
||||
return seg;
|
||||
}
|
||||
|
||||
public static Segment horizontal(VPXMacroblock.Subblock right, VPXMacroblock.Subblock left, int a) {
|
||||
Segment seg = new Segment();
|
||||
seg.p0 = left.val[12 + a];
|
||||
seg.p1 = left.val[8 + a];
|
||||
seg.p2 = left.val[4 + a];
|
||||
seg.p3 = left.val[0 + a];
|
||||
seg.q0 = right.val[0 + a];
|
||||
seg.q1 = right.val[4 + a];
|
||||
seg.q2 = right.val[8 + a];
|
||||
seg.q3 = right.val[12 + a];
|
||||
return seg;
|
||||
}
|
||||
|
||||
public static Segment vertical(VPXMacroblock.Subblock lower, VPXMacroblock.Subblock upper, int a) {
|
||||
Segment seg = new Segment();
|
||||
seg.p0 = upper.val[a * 4 + 3];
|
||||
seg.p1 = upper.val[a * 4 + 2];
|
||||
seg.p2 = upper.val[a * 4 + 1];
|
||||
seg.p3 = upper.val[a * 4 + 0];
|
||||
seg.q0 = lower.val[a * 4 + 0];
|
||||
seg.q1 = lower.val[a * 4 + 1];
|
||||
seg.q2 = lower.val[a * 4 + 2];
|
||||
seg.q3 = lower.val[a * 4 + 3];
|
||||
return seg;
|
||||
}
|
||||
|
||||
public void applyHorizontally(VPXMacroblock.Subblock right, VPXMacroblock.Subblock left, int a) {
|
||||
left.val[12 + a] = this.p0;
|
||||
left.val[8 + a] = this.p1;
|
||||
left.val[4 + a] = this.p2;
|
||||
left.val[0 + a] = this.p3;
|
||||
right.val[0 + a] = this.q0;
|
||||
right.val[4 + a] = this.q1;
|
||||
right.val[8 + a] = this.q2;
|
||||
right.val[12 + a] = this.q3;
|
||||
}
|
||||
|
||||
public void applyVertically(VPXMacroblock.Subblock lower, VPXMacroblock.Subblock upper, int a) {
|
||||
upper.val[a * 4 + 3] = this.p0;
|
||||
upper.val[a * 4 + 2] = this.p1;
|
||||
upper.val[a * 4 + 1] = this.p2;
|
||||
upper.val[a * 4 + 0] = this.p3;
|
||||
lower.val[a * 4 + 0] = this.q0;
|
||||
lower.val[a * 4 + 1] = this.q1;
|
||||
lower.val[a * 4 + 2] = this.q2;
|
||||
lower.val[a * 4 + 3] = this.q3;
|
||||
}
|
||||
|
||||
void filterMb(int hevThreshold, int interiorLimit, int edgeLimit) {
|
||||
Segment signedSeg = getSigned();
|
||||
if (signedSeg.isFilterRequired(interiorLimit, edgeLimit))
|
||||
if (!signedSeg.isHighVariance(hevThreshold)) {
|
||||
int w = FilterUtil.clipSigned(FilterUtil.clipSigned(signedSeg.p1 - signedSeg.q1) + 3 * (signedSeg.q0 - signedSeg.p0));
|
||||
int a = 27 * w + 63 >> 7;
|
||||
this.q0 = FilterUtil.clipPlus128(signedSeg.q0 - a);
|
||||
this.p0 = FilterUtil.clipPlus128(signedSeg.p0 + a);
|
||||
a = 18 * w + 63 >> 7;
|
||||
this.q1 = FilterUtil.clipPlus128(signedSeg.q1 - a);
|
||||
this.p1 = FilterUtil.clipPlus128(signedSeg.p1 + a);
|
||||
a = 9 * w + 63 >> 7;
|
||||
this.q2 = FilterUtil.clipPlus128(signedSeg.q2 - a);
|
||||
this.p2 = FilterUtil.clipPlus128(signedSeg.p2 + a);
|
||||
} else {
|
||||
adjust(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void filterSb(int hev_threshold, int interior_limit, int edge_limit) {
|
||||
Segment signedSeg = getSigned();
|
||||
if (signedSeg.isFilterRequired(interior_limit, edge_limit)) {
|
||||
boolean hv = signedSeg.isHighVariance(hev_threshold);
|
||||
int a = adjust(hv) + 1 >> 1;
|
||||
if (!hv) {
|
||||
this.q1 = FilterUtil.clipPlus128(signedSeg.q1 - a);
|
||||
this.p1 = FilterUtil.clipPlus128(signedSeg.p1 + a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int adjust(boolean use_outer_taps) {
|
||||
int p1 = FilterUtil.minus128(this.p1);
|
||||
int p0 = FilterUtil.minus128(this.p0);
|
||||
int q0 = FilterUtil.minus128(this.q0);
|
||||
int q1 = FilterUtil.minus128(this.q1);
|
||||
int a = FilterUtil.clipSigned((use_outer_taps ? FilterUtil.clipSigned(p1 - q1) : 0) + 3 * (q0 - p0));
|
||||
int b = FilterUtil.clipSigned(a + 3) >> 3;
|
||||
a = FilterUtil.clipSigned(a + 4) >> 3;
|
||||
this.q0 = FilterUtil.clipPlus128(q0 - a);
|
||||
this.p0 = FilterUtil.clipPlus128(p0 + b);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
private static int clipSigned(int v) {
|
||||
return (v < -128) ? -128 : ((v > 127) ? 127 : v);
|
||||
}
|
||||
|
||||
private static int minus128(int v) {
|
||||
return v - 128;
|
||||
}
|
||||
|
||||
public static void loopFilterUV(VPXMacroblock[][] mbs, int sharpnessLevel, boolean keyFrame) {
|
||||
for (int y = 0; y < mbs.length - 2; y++) {
|
||||
for (int x = 0; x < (mbs[0]).length - 2; x++) {
|
||||
VPXMacroblock rmb = mbs[y + 1][x + 1];
|
||||
VPXMacroblock bmb = mbs[y + 1][x + 1];
|
||||
int loop_filter_level = rmb.filterLevel;
|
||||
if (loop_filter_level != 0) {
|
||||
int interior_limit = rmb.filterLevel;
|
||||
if (sharpnessLevel > 0) {
|
||||
interior_limit >>= (sharpnessLevel > 4) ? 2 : 1;
|
||||
if (interior_limit > 9 - sharpnessLevel)
|
||||
interior_limit = 9 - sharpnessLevel;
|
||||
}
|
||||
if (interior_limit == 0)
|
||||
interior_limit = 1;
|
||||
int hev_threshold = 0;
|
||||
if (keyFrame) {
|
||||
if (loop_filter_level >= 40) {
|
||||
hev_threshold = 2;
|
||||
} else if (loop_filter_level >= 15) {
|
||||
hev_threshold = 1;
|
||||
}
|
||||
} else {
|
||||
throw new NotImplementedException("TODO: non-key frames are not supported yet.");
|
||||
}
|
||||
int mbedge_limit = (loop_filter_level + 2) * 2 + interior_limit;
|
||||
int sub_bedge_limit = loop_filter_level * 2 + interior_limit;
|
||||
if (x > 0) {
|
||||
VPXMacroblock lmb = mbs[y + 1][x + 1 - 1];
|
||||
for (int b = 0; b < 2; b++) {
|
||||
VPXMacroblock.Subblock rsbU = rmb.uSubblocks[b][0];
|
||||
VPXMacroblock.Subblock lsbU = lmb.uSubblocks[b][1];
|
||||
VPXMacroblock.Subblock rsbV = rmb.vSubblocks[b][0];
|
||||
VPXMacroblock.Subblock lsbV = lmb.vSubblocks[b][1];
|
||||
for (int a = 0; a < 4; a++) {
|
||||
Segment seg = Segment.horizontal(rsbU, lsbU, a);
|
||||
seg.filterMb(hev_threshold, interior_limit, mbedge_limit);
|
||||
seg.applyHorizontally(rsbU, lsbU, a);
|
||||
seg = Segment.horizontal(rsbV, lsbV, a);
|
||||
seg.filterMb(hev_threshold, interior_limit, mbedge_limit);
|
||||
seg.applyHorizontally(rsbV, lsbV, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rmb.skipFilter)
|
||||
for (int a = 1; a < 2; a++) {
|
||||
for (int b = 0; b < 2; b++) {
|
||||
VPXMacroblock.Subblock lsbU = rmb.uSubblocks[b][a - 1];
|
||||
VPXMacroblock.Subblock rsbU = rmb.uSubblocks[b][a];
|
||||
VPXMacroblock.Subblock lsbV = rmb.vSubblocks[b][a - 1];
|
||||
VPXMacroblock.Subblock rsbV = rmb.vSubblocks[b][a];
|
||||
for (int c = 0; c < 4; c++) {
|
||||
Segment seg = Segment.horizontal(rsbU, lsbU, c);
|
||||
seg.filterSb(hev_threshold, interior_limit, sub_bedge_limit);
|
||||
seg.applyHorizontally(rsbU, lsbU, c);
|
||||
seg = Segment.horizontal(rsbV, lsbV, c);
|
||||
seg.filterSb(hev_threshold, interior_limit, sub_bedge_limit);
|
||||
seg.applyHorizontally(rsbV, lsbV, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (y > 0) {
|
||||
VPXMacroblock tmb = mbs[y + 1 - 1][x + 1];
|
||||
for (int b = 0; b < 2; b++) {
|
||||
VPXMacroblock.Subblock tsbU = tmb.uSubblocks[1][b];
|
||||
VPXMacroblock.Subblock bsbU = bmb.uSubblocks[0][b];
|
||||
VPXMacroblock.Subblock tsbV = tmb.vSubblocks[1][b];
|
||||
VPXMacroblock.Subblock bsbV = bmb.vSubblocks[0][b];
|
||||
for (int a = 0; a < 4; a++) {
|
||||
Segment seg = Segment.vertical(bsbU, tsbU, a);
|
||||
seg.filterMb(hev_threshold, interior_limit, mbedge_limit);
|
||||
seg.applyVertically(bsbU, tsbU, a);
|
||||
seg = Segment.vertical(bsbV, tsbV, a);
|
||||
seg.filterMb(hev_threshold, interior_limit, mbedge_limit);
|
||||
seg.applyVertically(bsbV, tsbV, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rmb.skipFilter)
|
||||
for (int a = 1; a < 2; a++) {
|
||||
for (int b = 0; b < 2; b++) {
|
||||
VPXMacroblock.Subblock tsbU = bmb.uSubblocks[a - 1][b];
|
||||
VPXMacroblock.Subblock bsbU = bmb.uSubblocks[a][b];
|
||||
VPXMacroblock.Subblock tsbV = bmb.vSubblocks[a - 1][b];
|
||||
VPXMacroblock.Subblock bsbV = bmb.vSubblocks[a][b];
|
||||
for (int c = 0; c < 4; c++) {
|
||||
Segment seg = Segment.vertical(bsbU, tsbU, c);
|
||||
seg.filterSb(hev_threshold, interior_limit, sub_bedge_limit);
|
||||
seg.applyVertically(bsbU, tsbU, c);
|
||||
seg = Segment.vertical(bsbV, tsbV, c);
|
||||
seg.filterSb(hev_threshold, interior_limit, sub_bedge_limit);
|
||||
seg.applyVertically(bsbV, tsbV, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loopFilterY(VPXMacroblock[][] mbs, int sharpnessLevel, boolean keyFrame) {
|
||||
for (int y = 0; y < mbs.length - 2; y++) {
|
||||
for (int x = 0; x < (mbs[0]).length - 2; x++) {
|
||||
VPXMacroblock rmb = mbs[y + 1][x + 1];
|
||||
VPXMacroblock bmb = mbs[y + 1][x + 1];
|
||||
int loopFilterLevel = rmb.filterLevel;
|
||||
if (loopFilterLevel != 0) {
|
||||
int interiorLimit = rmb.filterLevel;
|
||||
if (sharpnessLevel > 0) {
|
||||
interiorLimit >>= (sharpnessLevel > 4) ? 2 : 1;
|
||||
if (interiorLimit > 9 - sharpnessLevel)
|
||||
interiorLimit = 9 - sharpnessLevel;
|
||||
}
|
||||
if (interiorLimit == 0)
|
||||
interiorLimit = 1;
|
||||
int varianceThreshold = 0;
|
||||
if (keyFrame) {
|
||||
if (loopFilterLevel >= 40) {
|
||||
varianceThreshold = 2;
|
||||
} else if (loopFilterLevel >= 15) {
|
||||
varianceThreshold = 1;
|
||||
}
|
||||
} else {
|
||||
throw new NotImplementedException("TODO: non-key frames are not supported yet");
|
||||
}
|
||||
int edgeLimitMb = (loopFilterLevel + 2) * 2 + interiorLimit;
|
||||
int edgeLimitSb = loopFilterLevel * 2 + interiorLimit;
|
||||
if (x > 0) {
|
||||
VPXMacroblock lmb = mbs[y + 1][x - 1 + 1];
|
||||
for (int b = 0; b < 4; b++) {
|
||||
VPXMacroblock.Subblock rsb = rmb.ySubblocks[b][0];
|
||||
VPXMacroblock.Subblock lsb = lmb.ySubblocks[b][3];
|
||||
for (int a = 0; a < 4; a++) {
|
||||
Segment seg = Segment.horizontal(rsb, lsb, a);
|
||||
seg.filterMb(varianceThreshold, interiorLimit, edgeLimitMb);
|
||||
seg.applyHorizontally(rsb, lsb, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rmb.skipFilter)
|
||||
for (int a = 1; a < 4; a++) {
|
||||
for (int b = 0; b < 4; b++) {
|
||||
VPXMacroblock.Subblock lsb = rmb.ySubblocks[b][a - 1];
|
||||
VPXMacroblock.Subblock rsb = rmb.ySubblocks[b][a];
|
||||
for (int c = 0; c < 4; c++) {
|
||||
Segment seg = Segment.horizontal(rsb, lsb, c);
|
||||
seg.filterSb(varianceThreshold, interiorLimit, edgeLimitSb);
|
||||
seg.applyHorizontally(rsb, lsb, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (y > 0) {
|
||||
VPXMacroblock tmb = mbs[y - 1 + 1][x + 1];
|
||||
for (int b = 0; b < 4; b++) {
|
||||
VPXMacroblock.Subblock tsb = tmb.ySubblocks[3][b];
|
||||
VPXMacroblock.Subblock bsb = bmb.ySubblocks[0][b];
|
||||
for (int a = 0; a < 4; a++) {
|
||||
Segment seg = Segment.vertical(bsb, tsb, a);
|
||||
seg.filterMb(varianceThreshold, interiorLimit, edgeLimitMb);
|
||||
seg.applyVertically(bsb, tsb, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rmb.skipFilter)
|
||||
for (int a = 1; a < 4; a++) {
|
||||
for (int b = 0; b < 4; b++) {
|
||||
VPXMacroblock.Subblock tsb = bmb.ySubblocks[a - 1][b];
|
||||
VPXMacroblock.Subblock bsb = bmb.ySubblocks[a][b];
|
||||
for (int c = 0; c < 4; c++) {
|
||||
Segment seg = Segment.vertical(bsb, tsb, c);
|
||||
seg.filterSb(varianceThreshold, interiorLimit, edgeLimitSb);
|
||||
seg.applyVertically(bsb, tsb, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import org.jcodec.common.AudioCodecMeta;
|
||||
import org.jcodec.common.Codec;
|
||||
import org.jcodec.common.Muxer;
|
||||
import org.jcodec.common.MuxerTrack;
|
||||
import org.jcodec.common.VideoCodecMeta;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.io.SeekableByteChannel;
|
||||
import org.jcodec.common.model.Packet;
|
||||
import org.jcodec.common.model.Size;
|
||||
|
||||
public class IVFMuxer implements Muxer, MuxerTrack {
|
||||
private SeekableByteChannel ch;
|
||||
|
||||
private int nFrames;
|
||||
|
||||
private Size dim;
|
||||
|
||||
private int frameRate;
|
||||
|
||||
private boolean headerWritten;
|
||||
|
||||
public IVFMuxer(SeekableByteChannel ch) throws IOException {
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
public void addFrame(Packet pkt) throws IOException {
|
||||
if (!this.headerWritten) {
|
||||
this.frameRate = pkt.getTimescale();
|
||||
writeHeader();
|
||||
this.headerWritten = true;
|
||||
}
|
||||
ByteBuffer fh = ByteBuffer.allocate(12);
|
||||
fh.order(ByteOrder.LITTLE_ENDIAN);
|
||||
ByteBuffer frame = pkt.getData();
|
||||
fh.putInt(frame.remaining());
|
||||
fh.putLong((long)this.nFrames);
|
||||
fh.clear();
|
||||
this.ch.write(fh);
|
||||
this.ch.write(frame);
|
||||
this.nFrames++;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.ch.setPosition(24L);
|
||||
NIOUtils.writeIntLE(this.ch, this.nFrames);
|
||||
}
|
||||
|
||||
public MuxerTrack addVideoTrack(Codec codec, VideoCodecMeta meta) {
|
||||
if (this.dim != null)
|
||||
throw new RuntimeException("IVF can not have multiple video tracks.");
|
||||
this.dim = meta.getSize();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void writeHeader() throws IOException {
|
||||
ByteBuffer ivf = ByteBuffer.allocate(32);
|
||||
ivf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
ivf.put((byte)68);
|
||||
ivf.put((byte)75);
|
||||
ivf.put((byte)73);
|
||||
ivf.put((byte)70);
|
||||
ivf.putShort((short)0);
|
||||
ivf.putShort((short)32);
|
||||
ivf.putInt(808996950);
|
||||
ivf.putShort((short)this.dim.getWidth());
|
||||
ivf.putShort((short)this.dim.getHeight());
|
||||
ivf.putInt(this.frameRate);
|
||||
ivf.putInt(1);
|
||||
ivf.putInt(1);
|
||||
ivf.clear();
|
||||
this.ch.write(ivf);
|
||||
}
|
||||
|
||||
public MuxerTrack addAudioTrack(Codec codec, AudioCodecMeta meta) {
|
||||
throw new RuntimeException("Video-only container");
|
||||
}
|
||||
|
||||
public void finish() throws IOException {}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public class NopRateControl implements RateControl {
|
||||
private int qp;
|
||||
|
||||
public NopRateControl(int qp) {
|
||||
this.qp = qp;
|
||||
}
|
||||
|
||||
public int[] getSegmentQps() {
|
||||
return new int[] { this.qp };
|
||||
}
|
||||
|
||||
public int getSegment() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void report(int bits) {}
|
||||
|
||||
public void reset() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public interface RateControl {
|
||||
int[] getSegmentQps();
|
||||
|
||||
int getSegment();
|
||||
|
||||
void report(int paramInt);
|
||||
|
||||
void reset();
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public class VP8DCT {
|
||||
private static final int cospi8sqrt2minus1 = 20091;
|
||||
|
||||
private static final int sinpi8sqrt2 = 35468;
|
||||
|
||||
public static int[] decodeDCT(int[] input) {
|
||||
int offset = 0;
|
||||
int[] output = new int[16];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = input[offset + 0] + input[offset + 8];
|
||||
int b1 = input[offset + 0] - input[offset + 8];
|
||||
int temp1 = input[offset + 4] * 35468 >> 16;
|
||||
int temp2 = input[offset + 12] + (input[offset + 12] * 20091 >> 16);
|
||||
int c1 = temp1 - temp2;
|
||||
temp1 = input[offset + 4] + (input[offset + 4] * 20091 >> 16);
|
||||
temp2 = input[offset + 12] * 35468 >> 16;
|
||||
int d1 = temp1 + temp2;
|
||||
output[offset + 0] = a1 + d1;
|
||||
output[offset + 12] = a1 - d1;
|
||||
output[offset + 4] = b1 + c1;
|
||||
output[offset + 8] = b1 - c1;
|
||||
offset++;
|
||||
}
|
||||
offset = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = output[offset * 4 + 0] + output[offset * 4 + 2];
|
||||
int b1 = output[offset * 4 + 0] - output[offset * 4 + 2];
|
||||
int temp1 = output[offset * 4 + 1] * 35468 >> 16;
|
||||
int temp2 = output[offset * 4 + 3] + (output[offset * 4 + 3] * 20091 >> 16);
|
||||
int c1 = temp1 - temp2;
|
||||
temp1 = output[offset * 4 + 1] + (output[offset * 4 + 1] * 20091 >> 16);
|
||||
temp2 = output[offset * 4 + 3] * 35468 >> 16;
|
||||
int d1 = temp1 + temp2;
|
||||
output[offset * 4 + 0] = a1 + d1 + 4 >> 3;
|
||||
output[offset * 4 + 3] = a1 - d1 + 4 >> 3;
|
||||
output[offset * 4 + 1] = b1 + c1 + 4 >> 3;
|
||||
output[offset * 4 + 2] = b1 - c1 + 4 >> 3;
|
||||
offset++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static int[] encodeDCT(int[] input) {
|
||||
int ip = 0;
|
||||
int[] output = new int[input.length];
|
||||
int op = 0;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = input[ip + 0] + input[ip + 3] << 3;
|
||||
int b1 = input[ip + 1] + input[ip + 2] << 3;
|
||||
int c1 = input[ip + 1] - input[ip + 2] << 3;
|
||||
int d1 = input[ip + 0] - input[ip + 3] << 3;
|
||||
output[op + 0] = a1 + b1;
|
||||
output[op + 2] = a1 - b1;
|
||||
output[op + 1] = c1 * 2217 + d1 * 5352 + 14500 >> 12;
|
||||
output[op + 3] = d1 * 2217 - c1 * 5352 + 7500 >> 12;
|
||||
ip += 4;
|
||||
op += 4;
|
||||
}
|
||||
ip = 0;
|
||||
op = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = output[ip + 0] + output[ip + 12];
|
||||
int b1 = output[ip + 4] + output[ip + 8];
|
||||
int c1 = output[ip + 4] - output[ip + 8];
|
||||
int d1 = output[ip + 0] - output[ip + 12];
|
||||
output[op + 0] = a1 + b1 + 7 >> 4;
|
||||
output[op + 8] = a1 - b1 + 7 >> 4;
|
||||
output[op + 4] = (c1 * 2217 + d1 * 5352 + 12000 >> 16) + ((d1 != 0) ? 1 : 0);
|
||||
output[op + 12] = d1 * 2217 - c1 * 5352 + 51000 >> 16;
|
||||
ip++;
|
||||
op++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static int[] decodeWHT(int[] input) {
|
||||
int[] output = new int[16];
|
||||
int[][] diff = new int[4][4];
|
||||
int offset = 0;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = input[offset + 0] + input[offset + 12];
|
||||
int b1 = input[offset + 4] + input[offset + 8];
|
||||
int c1 = input[offset + 4] - input[offset + 8];
|
||||
int d1 = input[offset + 0] - input[offset + 12];
|
||||
output[offset + 0] = a1 + b1;
|
||||
output[offset + 4] = c1 + d1;
|
||||
output[offset + 8] = a1 - b1;
|
||||
output[offset + 12] = d1 - c1;
|
||||
offset++;
|
||||
}
|
||||
offset = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = output[offset + 0] + output[offset + 3];
|
||||
int b1 = output[offset + 1] + output[offset + 2];
|
||||
int c1 = output[offset + 1] - output[offset + 2];
|
||||
int d1 = output[offset + 0] - output[offset + 3];
|
||||
int a2 = a1 + b1;
|
||||
int b2 = c1 + d1;
|
||||
int c2 = a1 - b1;
|
||||
int d2 = d1 - c1;
|
||||
output[offset + 0] = a2 + 3 >> 3;
|
||||
output[offset + 1] = b2 + 3 >> 3;
|
||||
output[offset + 2] = c2 + 3 >> 3;
|
||||
output[offset + 3] = d2 + 3 >> 3;
|
||||
diff[0][i] = a2 + 3 >> 3;
|
||||
diff[1][i] = b2 + 3 >> 3;
|
||||
diff[2][i] = c2 + 3 >> 3;
|
||||
diff[3][i] = d2 + 3 >> 3;
|
||||
offset += 4;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static int[] encodeWHT(int[] input) {
|
||||
int inputOffset = 0;
|
||||
int outputOffset = 0;
|
||||
int[] output = new int[input.length];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = input[inputOffset + 0] + input[inputOffset + 2] << 2;
|
||||
int d1 = input[inputOffset + 1] + input[inputOffset + 3] << 2;
|
||||
int c1 = input[inputOffset + 1] - input[inputOffset + 3] << 2;
|
||||
int b1 = input[inputOffset + 0] - input[inputOffset + 2] << 2;
|
||||
output[outputOffset + 0] = a1 + d1 + ((a1 != 0) ? 1 : 0);
|
||||
output[outputOffset + 1] = b1 + c1;
|
||||
output[outputOffset + 2] = b1 - c1;
|
||||
output[outputOffset + 3] = a1 - d1;
|
||||
inputOffset += 4;
|
||||
outputOffset += 4;
|
||||
}
|
||||
inputOffset = 0;
|
||||
outputOffset = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = output[inputOffset + 0] + output[inputOffset + 8];
|
||||
int d1 = output[inputOffset + 4] + output[inputOffset + 12];
|
||||
int c1 = output[inputOffset + 4] - output[inputOffset + 12];
|
||||
int b1 = output[inputOffset + 0] - output[inputOffset + 8];
|
||||
int a2 = a1 + d1;
|
||||
int b2 = b1 + c1;
|
||||
int c2 = b1 - c1;
|
||||
int d2 = a1 - d1;
|
||||
a2 += (a2 < 0) ? 1 : 0;
|
||||
b2 += (b2 < 0) ? 1 : 0;
|
||||
c2 += (c2 < 0) ? 1 : 0;
|
||||
d2 += (d2 < 0) ? 1 : 0;
|
||||
output[outputOffset + 0] = a2 + 3 >> 3;
|
||||
output[outputOffset + 4] = b2 + 3 >> 3;
|
||||
output[outputOffset + 8] = c2 + 3 >> 3;
|
||||
output[outputOffset + 12] = d2 + 3 >> 3;
|
||||
inputOffset++;
|
||||
outputOffset++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.Preconditions;
|
||||
import org.jcodec.common.UsedViaReflection;
|
||||
import org.jcodec.common.VideoCodecMeta;
|
||||
import org.jcodec.common.VideoDecoder;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.common.model.Size;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class VP8Decoder extends VideoDecoder {
|
||||
private byte[][] segmentationMap;
|
||||
|
||||
private int[] refLoopFilterDeltas = new int[4];
|
||||
|
||||
private int[] modeLoopFilterDeltas = new int[4];
|
||||
|
||||
public Picture decodeFrame(ByteBuffer frame, byte[][] buffer) {
|
||||
byte[] firstThree = new byte[3];
|
||||
frame.get(firstThree);
|
||||
boolean keyFrame = (VP8Util.getBitInBytes(firstThree, 0) == 0);
|
||||
if (!keyFrame)
|
||||
return null;
|
||||
int version = VP8Util.getBitsInBytes(firstThree, 1, 3);
|
||||
boolean showFrame = (VP8Util.getBitInBytes(firstThree, 4) > 0);
|
||||
int partitionSize = VP8Util.getBitsInBytes(firstThree, 5, 19);
|
||||
String threeByteToken = printHexByte(frame.get()) + " " + printHexByte(frame.get()) + " " + printHexByte(frame.get());
|
||||
int twoBytesWidth = frame.get() & 0xFF | (frame.get() & 0xFF) << 8;
|
||||
int twoBytesHeight = frame.get() & 0xFF | (frame.get() & 0xFF) << 8;
|
||||
int width = twoBytesWidth & 0x3FFF;
|
||||
int height = twoBytesHeight & 0x3FFF;
|
||||
int numberOfMBRows = VP8Util.getMacroblockCount(height);
|
||||
int numberOfMBCols = VP8Util.getMacroblockCount(width);
|
||||
if (this.segmentationMap == null)
|
||||
this.segmentationMap = new byte[numberOfMBRows][numberOfMBCols];
|
||||
VPXMacroblock[][] mbs = new VPXMacroblock[numberOfMBRows + 2][numberOfMBCols + 2];
|
||||
for (int row = 0; row < numberOfMBRows + 2; row++) {
|
||||
for (int col = 0; col < numberOfMBCols + 2; col++)
|
||||
mbs[row][col] = new VPXMacroblock(row, col);
|
||||
}
|
||||
int headerOffset = frame.position();
|
||||
VPXBooleanDecoder headerDecoder = new VPXBooleanDecoder(frame, 0);
|
||||
boolean isYUVColorSpace = (headerDecoder.readBitEq() == 0);
|
||||
boolean clampingRequired = (headerDecoder.readBitEq() == 0);
|
||||
int segmentation = headerDecoder.readBitEq();
|
||||
SegmentBasedAdjustments segmentBased = null;
|
||||
if (segmentation != 0) {
|
||||
segmentBased = updateSegmentation(headerDecoder);
|
||||
for (int m = 0; m < numberOfMBRows; m++) {
|
||||
for (int col = 0; col < numberOfMBCols; col++)
|
||||
(mbs[m + 1][col + 1]).segment = this.segmentationMap[m][col];
|
||||
}
|
||||
}
|
||||
int simpleFilter = headerDecoder.readBitEq();
|
||||
int filterLevel = headerDecoder.decodeInt(6);
|
||||
int filterType = (filterLevel == 0) ? 0 : ((simpleFilter > 0) ? 1 : 2);
|
||||
int sharpnessLevel = headerDecoder.decodeInt(3);
|
||||
int loopFilterDeltaFlag = headerDecoder.readBitEq();
|
||||
if (loopFilterDeltaFlag == 1) {
|
||||
int loopFilterDeltaUpdate = headerDecoder.readBitEq();
|
||||
if (loopFilterDeltaUpdate == 1) {
|
||||
for (int n = 0; n < 4; n++) {
|
||||
if (headerDecoder.readBitEq() > 0) {
|
||||
this.refLoopFilterDeltas[n] = headerDecoder.decodeInt(6);
|
||||
if (headerDecoder.readBitEq() > 0)
|
||||
this.refLoopFilterDeltas[n] = this.refLoopFilterDeltas[n] * -1;
|
||||
}
|
||||
}
|
||||
for (int m = 0; m < 4; m++) {
|
||||
if (headerDecoder.readBitEq() > 0) {
|
||||
this.modeLoopFilterDeltas[m] = headerDecoder.decodeInt(6);
|
||||
if (headerDecoder.readBitEq() > 0)
|
||||
this.modeLoopFilterDeltas[m] = this.modeLoopFilterDeltas[m] * -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int log2OfPartCnt = headerDecoder.decodeInt(2);
|
||||
Preconditions.checkState((0 == log2OfPartCnt));
|
||||
int partitionsCount = 1;
|
||||
long runningSize = 0L;
|
||||
long zSize = (long)(frame.limit() - (partitionSize + headerOffset));
|
||||
ByteBuffer tokenBuffer = frame.duplicate();
|
||||
tokenBuffer.position(partitionSize + headerOffset);
|
||||
VPXBooleanDecoder decoder = new VPXBooleanDecoder(tokenBuffer, 0);
|
||||
int yacIndex = headerDecoder.decodeInt(7);
|
||||
int ydcDelta = (headerDecoder.readBitEq() > 0) ? VP8Util.delta(headerDecoder) : 0;
|
||||
int y2dcDelta = (headerDecoder.readBitEq() > 0) ? VP8Util.delta(headerDecoder) : 0;
|
||||
int y2acDelta = (headerDecoder.readBitEq() > 0) ? VP8Util.delta(headerDecoder) : 0;
|
||||
int chromaDCDelta = (headerDecoder.readBitEq() > 0) ? VP8Util.delta(headerDecoder) : 0;
|
||||
int chromaACDelta = (headerDecoder.readBitEq() > 0) ? VP8Util.delta(headerDecoder) : 0;
|
||||
boolean refreshProbs = (headerDecoder.readBitEq() == 0);
|
||||
VP8Util.QuantizationParams quants = new VP8Util.QuantizationParams(yacIndex, ydcDelta, y2dcDelta, y2acDelta, chromaDCDelta, chromaACDelta);
|
||||
int[][][][] coefProbs = VP8Util.getDefaultCoefProbs();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int m = 0; m < 8; m++) {
|
||||
for (int n = 0; n < 3; n++) {
|
||||
for (int l = 0; l < 11; l++) {
|
||||
if (headerDecoder.readBit(VP8Util.vp8CoefUpdateProbs[i][m][n][l]) > 0) {
|
||||
int newp = headerDecoder.decodeInt(8);
|
||||
coefProbs[i][m][n][l] = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int macroBlockNoCoeffSkip = headerDecoder.readBitEq();
|
||||
Preconditions.checkState((1 == macroBlockNoCoeffSkip));
|
||||
int probSkipFalse = headerDecoder.decodeInt(8);
|
||||
for (int j = 0; j < numberOfMBRows; j++) {
|
||||
for (int mbCol = 0; mbCol < numberOfMBCols; mbCol++) {
|
||||
VPXMacroblock mb = mbs[j + 1][mbCol + 1];
|
||||
if (segmentation != 0 && segmentBased != null && segmentBased.segmentProbs != null) {
|
||||
mb.segment = headerDecoder.readTree(VP8Util.segmentTree, segmentBased.segmentProbs);
|
||||
this.segmentationMap[j][mbCol] = (byte)mb.segment;
|
||||
}
|
||||
if (segmentation != 0 && segmentBased != null && segmentBased.qp != null) {
|
||||
int qIndex = yacIndex;
|
||||
if (segmentBased.abs != 0) {
|
||||
qIndex = segmentBased.qp[mb.segment];
|
||||
} else {
|
||||
qIndex += segmentBased.qp[mb.segment];
|
||||
}
|
||||
quants = new VP8Util.QuantizationParams(qIndex, ydcDelta, y2dcDelta, y2acDelta, chromaDCDelta, chromaACDelta);
|
||||
}
|
||||
mb.quants = quants;
|
||||
if (loopFilterDeltaFlag != 0) {
|
||||
int level = filterLevel;
|
||||
level += this.refLoopFilterDeltas[0];
|
||||
level = MathUtil.clip(level, 0, 63);
|
||||
mb.filterLevel = level;
|
||||
} else {
|
||||
mb.filterLevel = filterLevel;
|
||||
}
|
||||
if (segmentation != 0 && segmentBased != null && segmentBased.lf != null)
|
||||
if (segmentBased.abs != 0) {
|
||||
mb.filterLevel = segmentBased.lf[mb.segment];
|
||||
} else {
|
||||
mb.filterLevel += segmentBased.lf[mb.segment];
|
||||
mb.filterLevel = MathUtil.clip(mb.filterLevel, 0, 63);
|
||||
}
|
||||
if (macroBlockNoCoeffSkip > 0)
|
||||
mb.skipCoeff = headerDecoder.readBit(probSkipFalse);
|
||||
mb.lumaMode = headerDecoder.readTree(VP8Util.keyFrameYModeTree, VP8Util.keyFrameYModeProb);
|
||||
if (mb.lumaMode == 4) {
|
||||
for (int sbRow = 0; sbRow < 4; sbRow++) {
|
||||
for (int sbCol = 0; sbCol < 4; sbCol++) {
|
||||
VPXMacroblock.Subblock sb = mb.ySubblocks[sbRow][sbCol];
|
||||
VPXMacroblock.Subblock A = sb.getAbove(VP8Util.PLANE.Y1, mbs);
|
||||
VPXMacroblock.Subblock L = sb.getLeft(VP8Util.PLANE.Y1, mbs);
|
||||
sb.mode = headerDecoder.readTree(VP8Util.SubblockConstants.subblockModeTree, VP8Util.SubblockConstants.keyFrameSubblockModeProb[A.mode][L.mode]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int fixedMode;
|
||||
switch (mb.lumaMode) {
|
||||
case 0:
|
||||
fixedMode = 0;
|
||||
break;
|
||||
case 1:
|
||||
fixedMode = 2;
|
||||
break;
|
||||
case 2:
|
||||
fixedMode = 3;
|
||||
break;
|
||||
case 3:
|
||||
fixedMode = 1;
|
||||
break;
|
||||
default:
|
||||
fixedMode = 0;
|
||||
break;
|
||||
}
|
||||
mb.lumaMode = edgeEmu(mb.lumaMode, mbCol, j);
|
||||
for (int x = 0; x < 4; x++) {
|
||||
for (int y = 0; y < 4; y++)
|
||||
(mb.ySubblocks[y][x]).mode = fixedMode;
|
||||
}
|
||||
}
|
||||
mb.chromaMode = headerDecoder.readTree(VP8Util.vp8UVModeTree, VP8Util.vp8KeyFrameUVModeProb);
|
||||
}
|
||||
}
|
||||
for (int mbRow = 0; mbRow < numberOfMBRows; mbRow++) {
|
||||
for (int mbCol = 0; mbCol < numberOfMBCols; mbCol++) {
|
||||
VPXMacroblock mb = mbs[mbRow + 1][mbCol + 1];
|
||||
mb.decodeMacroBlock(mbs, decoder, coefProbs);
|
||||
mb.dequantMacroBlock(mbs);
|
||||
}
|
||||
}
|
||||
if (filterType > 0 && filterLevel != 0)
|
||||
if (filterType == 2) {
|
||||
FilterUtil.loopFilterUV(mbs, sharpnessLevel, keyFrame);
|
||||
FilterUtil.loopFilterY(mbs, sharpnessLevel, keyFrame);
|
||||
} else if (filterType == 1) {
|
||||
|
||||
}
|
||||
Picture p = Picture.createPicture(width, height, buffer, ColorSpace.YUV420);
|
||||
int mbWidth = VP8Util.getMacroblockCount(width);
|
||||
int mbHeight = VP8Util.getMacroblockCount(height);
|
||||
for (int k = 0; k < mbHeight; k++) {
|
||||
for (int mbCol = 0; mbCol < mbWidth; mbCol++) {
|
||||
VPXMacroblock mb = mbs[k + 1][mbCol + 1];
|
||||
mb.put(k, mbCol, p);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private int edgeEmu(int mode, int mbCol, int mbRow) {
|
||||
switch (mode) {
|
||||
case 1:
|
||||
return (mbRow == 0) ? 0 : mode;
|
||||
case 2:
|
||||
return (mbCol == 0) ? 0 : mode;
|
||||
case 3:
|
||||
return edgeEmuTm(mode, mbCol, mbRow);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
private int edgeEmuTm(int mode, int mbCol, int mbRow) {
|
||||
if (mbCol == 0)
|
||||
return (mbRow != 0) ? 1 : 0;
|
||||
return (mbRow != 0) ? mode : 2;
|
||||
}
|
||||
|
||||
private static class SegmentBasedAdjustments {
|
||||
private int[] segmentProbs;
|
||||
|
||||
private int[] qp;
|
||||
|
||||
private int[] lf;
|
||||
|
||||
private int abs;
|
||||
|
||||
public SegmentBasedAdjustments(int[] segmentProbs, int[] qp, int[] lf, int abs) {
|
||||
this.segmentProbs = segmentProbs;
|
||||
this.qp = qp;
|
||||
this.lf = lf;
|
||||
this.abs = abs;
|
||||
}
|
||||
}
|
||||
|
||||
private SegmentBasedAdjustments updateSegmentation(VPXBooleanDecoder headerDecoder) {
|
||||
int updateMBSegmentationMap = headerDecoder.readBitEq();
|
||||
int updateSegmentFeatureData = headerDecoder.readBitEq();
|
||||
int[] qp = null;
|
||||
int[] lf = null;
|
||||
int abs = 0;
|
||||
if (updateSegmentFeatureData != 0) {
|
||||
qp = new int[4];
|
||||
lf = new int[4];
|
||||
abs = headerDecoder.readBitEq();
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int quantizerUpdate = headerDecoder.readBitEq();
|
||||
if (quantizerUpdate != 0) {
|
||||
qp[j] = headerDecoder.decodeInt(7);
|
||||
qp[j] = (headerDecoder.readBitEq() != 0) ? -qp[j] : qp[j];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int loopFilterUpdate = headerDecoder.readBitEq();
|
||||
if (loopFilterUpdate != 0) {
|
||||
lf[i] = headerDecoder.decodeInt(6);
|
||||
lf[i] = (headerDecoder.readBitEq() != 0) ? -lf[i] : lf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] segmentProbs = new int[3];
|
||||
if (updateMBSegmentationMap != 0)
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int segmentProbUpdate = headerDecoder.readBitEq();
|
||||
if (segmentProbUpdate != 0) {
|
||||
segmentProbs[i] = headerDecoder.decodeInt(8);
|
||||
} else {
|
||||
segmentProbs[i] = 255;
|
||||
}
|
||||
}
|
||||
return new SegmentBasedAdjustments(segmentProbs, qp, lf, abs);
|
||||
}
|
||||
|
||||
@UsedViaReflection
|
||||
public static int probe(ByteBuffer data) {
|
||||
if ((data.get(3) & 0xFF) == 157 && (data.get(4) & 0xFF) == 1 && (data.get(5) & 0xFF) == 42)
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static String printHexByte(byte b) {
|
||||
return "0x" + Integer.toHexString(b & 0xFF);
|
||||
}
|
||||
|
||||
public VideoCodecMeta getCodecMeta(ByteBuffer frame) {
|
||||
NIOUtils.skip(frame, 6);
|
||||
int twoBytesWidth = frame.get() & 0xFF | (frame.get() & 0xFF) << 8;
|
||||
int twoBytesHeight = frame.get() & 0xFF | (frame.get() & 0xFF) << 8;
|
||||
int width = twoBytesWidth & 0x3FFF;
|
||||
int height = twoBytesHeight & 0x3FFF;
|
||||
return VideoCodecMeta.createSimpleVideoCodecMeta(new Size(width, height), ColorSpace.YUV420);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.common.ArrayUtil;
|
||||
import org.jcodec.common.VideoEncoder;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class VP8Encoder extends VideoEncoder {
|
||||
private VPXBitstream bitstream;
|
||||
|
||||
private byte[][] leftRow;
|
||||
|
||||
private byte[][] topLine;
|
||||
|
||||
private VPXQuantizer quantizer;
|
||||
|
||||
private int[] tmp;
|
||||
|
||||
private RateControl rc;
|
||||
|
||||
private ByteBuffer headerBuffer;
|
||||
|
||||
private ByteBuffer dataBuffer;
|
||||
|
||||
public static VP8Encoder createVP8Encoder(int qp) {
|
||||
return new VP8Encoder(new NopRateControl(qp));
|
||||
}
|
||||
|
||||
public VP8Encoder(RateControl rc) {
|
||||
this.rc = rc;
|
||||
this.tmp = new int[16];
|
||||
}
|
||||
|
||||
public VideoEncoder.EncodedFrame encodeFrame(Picture pic, ByteBuffer _buf) {
|
||||
ByteBuffer out = _buf.duplicate();
|
||||
int mbWidth = pic.getWidth() + 15 >> 4;
|
||||
int mbHeight = pic.getHeight() + 15 >> 4;
|
||||
prepareBuffers(mbWidth, mbHeight);
|
||||
this.bitstream = new VPXBitstream(VPXConst.tokenDefaultBinProbs, mbWidth);
|
||||
this.leftRow = new byte[][] { new byte[16], new byte[8], new byte[8] };
|
||||
this.topLine = new byte[][] { new byte[mbWidth << 4], new byte[mbWidth << 3], new byte[mbWidth << 3] };
|
||||
initValue(this.leftRow, (byte)1);
|
||||
initValue(this.topLine, (byte)-1);
|
||||
this.quantizer = new VPXQuantizer();
|
||||
Picture outMB = Picture.create(16, 16, ColorSpace.YUV420);
|
||||
int[] segmentQps = this.rc.getSegmentQps();
|
||||
VPXBooleanEncoder boolEnc = new VPXBooleanEncoder(this.dataBuffer);
|
||||
int[] segmentMap = new int[mbWidth * mbHeight];
|
||||
for (int mbY = 0, mbAddr = 0; mbY < mbHeight; mbY++) {
|
||||
initValue(this.leftRow, (byte)1);
|
||||
for (int mbX = 0; mbX < mbWidth; mbX++, mbAddr++) {
|
||||
int before = boolEnc.position();
|
||||
int segment = this.rc.getSegment();
|
||||
segmentMap[mbAddr] = segment;
|
||||
luma(pic, mbX, mbY, boolEnc, segmentQps[segment], outMB);
|
||||
chroma(pic, mbX, mbY, boolEnc, segmentQps[segment], outMB);
|
||||
this.rc.report(boolEnc.position() - before);
|
||||
collectPredictors(outMB, mbX);
|
||||
}
|
||||
}
|
||||
boolEnc.stop();
|
||||
this.dataBuffer.flip();
|
||||
boolEnc = new VPXBooleanEncoder(this.headerBuffer);
|
||||
int[] probs = calcSegmentProbs(segmentMap);
|
||||
writeHeader2(boolEnc, segmentQps, probs);
|
||||
for (int i = 0, j = 0; i < mbHeight; i++) {
|
||||
for (int mbX = 0; mbX < mbWidth; mbX++, j++) {
|
||||
writeSegmetId(boolEnc, segmentMap[j], probs);
|
||||
boolEnc.writeBit(145, 1);
|
||||
boolEnc.writeBit(156, 0);
|
||||
boolEnc.writeBit(163, 0);
|
||||
boolEnc.writeBit(142, 0);
|
||||
}
|
||||
}
|
||||
boolEnc.stop();
|
||||
this.headerBuffer.flip();
|
||||
out.order(ByteOrder.LITTLE_ENDIAN);
|
||||
writeHeader(out, pic.getWidth(), pic.getHeight(), this.headerBuffer.remaining());
|
||||
out.put(this.headerBuffer);
|
||||
out.put(this.dataBuffer);
|
||||
out.flip();
|
||||
return new VideoEncoder.EncodedFrame(out, true);
|
||||
}
|
||||
|
||||
private void prepareBuffers(int mbWidth, int mbHeight) {
|
||||
int dataBufSize = mbHeight * mbHeight << 10;
|
||||
int headerBufSize = 256 + mbWidth * mbHeight;
|
||||
if (this.headerBuffer == null || this.headerBuffer.capacity() < headerBufSize) {
|
||||
this.headerBuffer = ByteBuffer.allocate(headerBufSize);
|
||||
} else {
|
||||
this.headerBuffer.clear();
|
||||
}
|
||||
if (this.dataBuffer == null || this.dataBuffer.capacity() < dataBufSize) {
|
||||
this.dataBuffer = ByteBuffer.allocate(dataBufSize);
|
||||
} else {
|
||||
this.dataBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSegmetId(VPXBooleanEncoder boolEnc, int id, int[] probs) {
|
||||
int bit1 = id >> 1 & 0x1;
|
||||
boolEnc.writeBit(probs[0], bit1);
|
||||
boolEnc.writeBit(probs[1 + bit1], id & 0x1);
|
||||
}
|
||||
|
||||
private int[] calcSegmentProbs(int[] segmentMap) {
|
||||
int[] result = new int[3];
|
||||
for (int j = 0; j < segmentMap.length; j++) {
|
||||
switch (segmentMap[j]) {
|
||||
case 0:
|
||||
result[0] = result[0] + 1;
|
||||
result[1] = result[1] + 1;
|
||||
break;
|
||||
case 1:
|
||||
result[0] = result[0] + 1;
|
||||
break;
|
||||
case 2:
|
||||
result[2] = result[2] + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
result[i] = MathUtil.clip((result[i] << 8) / segmentMap.length, 1, 255);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void initValue(byte[][] leftRow2, byte val) {
|
||||
Arrays.fill(leftRow2[0], val);
|
||||
Arrays.fill(leftRow2[1], val);
|
||||
Arrays.fill(leftRow2[2], val);
|
||||
}
|
||||
|
||||
private void writeHeader2(VPXBooleanEncoder boolEnc, int[] segmentQps, int[] probs) {
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 1);
|
||||
boolEnc.writeBit(128, 1);
|
||||
boolEnc.writeBit(128, 1);
|
||||
boolEnc.writeBit(128, 1);
|
||||
for (int k = 0; k < segmentQps.length; k++) {
|
||||
boolEnc.writeBit(128, 1);
|
||||
writeInt(boolEnc, segmentQps[k], 7);
|
||||
boolEnc.writeBit(128, 0);
|
||||
}
|
||||
for (int j = segmentQps.length; j < 4; j++)
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
boolEnc.writeBit(128, 1);
|
||||
writeInt(boolEnc, probs[i], 8);
|
||||
}
|
||||
boolEnc.writeBit(128, 0);
|
||||
writeInt(boolEnc, 1, 6);
|
||||
writeInt(boolEnc, 0, 3);
|
||||
boolEnc.writeBit(128, 0);
|
||||
writeInt(boolEnc, 0, 2);
|
||||
writeInt(boolEnc, segmentQps[0], 7);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
boolEnc.writeBit(128, 0);
|
||||
int[][][][] probFlags = VPXConst.tokenProbUpdateFlagProbs;
|
||||
for (int m = 0; m < probFlags.length; m++) {
|
||||
for (int n = 0; n < (probFlags[m]).length; n++) {
|
||||
for (int i1 = 0; i1 < (probFlags[m][n]).length; i1++) {
|
||||
for (int l = 0; l < (probFlags[m][n][i1]).length; l++)
|
||||
boolEnc.writeBit(probFlags[m][n][i1][l], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolEnc.writeBit(128, 0);
|
||||
}
|
||||
|
||||
void writeInt(VPXBooleanEncoder boolEnc, int data, int bits) {
|
||||
for (int bit = bits - 1; bit >= 0; bit--)
|
||||
boolEnc.writeBit(128, 0x1 & data >> bit);
|
||||
}
|
||||
|
||||
private void writeHeader(ByteBuffer out, int width, int height, int firstPart) {
|
||||
int version = 0, type = 0, showFrame = 1;
|
||||
int header = firstPart << 5 | showFrame << 4 | version << 1 | type;
|
||||
out.put((byte)(header & 0xFF));
|
||||
out.put((byte)(header >> 8 & 0xFF));
|
||||
out.put((byte)(header >> 16 & 0xFF));
|
||||
out.put((byte)-99);
|
||||
out.put((byte)1);
|
||||
out.put((byte)42);
|
||||
out.putShort((short)width);
|
||||
out.putShort((short)height);
|
||||
}
|
||||
|
||||
private void collectPredictors(Picture outMB, int mbX) {
|
||||
System.arraycopy(outMB.getPlaneData(0), 240, this.topLine[0], mbX << 4, 16);
|
||||
System.arraycopy(outMB.getPlaneData(1), 56, this.topLine[1], mbX << 3, 8);
|
||||
System.arraycopy(outMB.getPlaneData(2), 56, this.topLine[2], mbX << 3, 8);
|
||||
copyCol(outMB.getPlaneData(0), 15, 16, this.leftRow[0]);
|
||||
copyCol(outMB.getPlaneData(1), 7, 8, this.leftRow[1]);
|
||||
copyCol(outMB.getPlaneData(2), 7, 8, this.leftRow[2]);
|
||||
}
|
||||
|
||||
private void copyCol(byte[] planeData, int off, int stride, byte[] out) {
|
||||
for (int i = 0; i < out.length; i++) {
|
||||
out[i] = planeData[off];
|
||||
off += stride;
|
||||
}
|
||||
}
|
||||
|
||||
private void luma(Picture pic, int mbX, int mbY, VPXBooleanEncoder out, int qp, Picture outMB) {
|
||||
int x = mbX << 4;
|
||||
int y = mbY << 4;
|
||||
int[][] ac = transform(pic, 0, qp, x, y);
|
||||
int[] dc = extractDC(ac);
|
||||
writeLumaDC(mbX, mbY, out, qp, dc);
|
||||
writeLumaAC(mbX, mbY, out, ac, qp);
|
||||
restorePlaneLuma(dc, ac, qp);
|
||||
putLuma(outMB.getPlaneData(0), lumaDCPred(x, y), ac, 4);
|
||||
}
|
||||
|
||||
private void writeLumaAC(int mbX, int mbY, VPXBooleanEncoder out, int[][] ac, int qp) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this.quantizer.quantizeY(ac[i], qp);
|
||||
this.bitstream.encodeCoeffsDCT15(out, zigzag(ac[i], this.tmp), mbX, i & 0x3, i >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLumaDC(int mbX, int mbY, VPXBooleanEncoder out, int qp, int[] dc) {
|
||||
VPXDCT.walsh4x4(dc);
|
||||
this.quantizer.quantizeY2(dc, qp);
|
||||
this.bitstream.encodeCoeffsWHT(out, zigzag(dc, this.tmp), mbX);
|
||||
}
|
||||
|
||||
private void writeChroma(int comp, int mbX, int mbY, VPXBooleanEncoder boolEnc, int[][] ac, int qp) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
this.quantizer.quantizeUV(ac[i], qp);
|
||||
this.bitstream.encodeCoeffsDCTUV(boolEnc, zigzag(ac[i], this.tmp), comp, mbX, i & 0x1, i >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] zigzag(int[] zz, int[] tmp2) {
|
||||
for (int i = 0; i < 16; i++)
|
||||
tmp2[i] = zz[VPXConst.zigzag[i]];
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
private void chroma(Picture pic, int mbX, int mbY, VPXBooleanEncoder boolEnc, int qp, Picture outMB) {
|
||||
int x = mbX << 3;
|
||||
int y = mbY << 3;
|
||||
int chromaPred1 = chromaPredBlk(1, x, y);
|
||||
int chromaPred2 = chromaPredBlk(2, x, y);
|
||||
int[][] ac1 = transformChroma(pic, 1, qp, x, y, outMB, chromaPred1);
|
||||
int[][] ac2 = transformChroma(pic, 2, qp, x, y, outMB, chromaPred2);
|
||||
writeChroma(1, mbX, mbY, boolEnc, ac1, qp);
|
||||
writeChroma(2, mbX, mbY, boolEnc, ac2, qp);
|
||||
restorePlaneChroma(ac1, qp);
|
||||
putChroma(outMB.getData()[1], 1, x, y, ac1, chromaPred1);
|
||||
restorePlaneChroma(ac2, qp);
|
||||
putChroma(outMB.getData()[2], 2, x, y, ac2, chromaPred2);
|
||||
}
|
||||
|
||||
private int[][] transformChroma(Picture pic, int comp, int qp, int x, int y, Picture outMB, int chromaPred) {
|
||||
int[][] ac = new int[4][16];
|
||||
for (int blk = 0; blk < ac.length; blk++) {
|
||||
int blkOffX = (blk & 0x1) << 2;
|
||||
int blkOffY = blk >> 1 << 2;
|
||||
takeSubtract(pic.getPlaneData(comp), pic.getPlaneWidth(comp), pic.getPlaneHeight(comp), x + blkOffX, y + blkOffY, ac[blk], chromaPred);
|
||||
VPXDCT.fdct4x4(ac[blk]);
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
private void putChroma(byte[] mb, int comp, int x, int y, int[][] ac, int chromaPred) {
|
||||
for (int blk = 0; blk < 4; blk++)
|
||||
putBlk(mb, chromaPred, ac[blk], 3, (blk & 0x1) << 2, blk >> 1 << 2);
|
||||
}
|
||||
|
||||
private final byte chromaPredOne(byte[] pix, int x) {
|
||||
return (byte)(pix[x] + pix[x + 1] + pix[x + 2] + pix[x + 3] + pix[x + 4] + pix[x + 5] + pix[x + 6] + pix[x + 7] + 4 >> 3);
|
||||
}
|
||||
|
||||
private final byte chromaPredTwo(byte[] pix1, byte[] pix2, int x, int y) {
|
||||
return (byte)(pix1[x] + pix1[x + 1] + pix1[x + 2] + pix1[x + 3] + pix1[x + 4] + pix1[x + 5] + pix1[x + 6] + pix1[x + 7] + pix2[y] + pix2[y + 1] + pix2[y + 2] + pix2[y + 3] + pix2[y + 4] + pix2[y + 5] + pix2[y + 6] + pix2[y + 7] + 8 >> 4);
|
||||
}
|
||||
|
||||
private byte chromaPredBlk(int comp, int x, int y) {
|
||||
int predY = y & 0x7;
|
||||
if (x != 0 && y != 0)
|
||||
return chromaPredTwo(this.leftRow[comp], this.topLine[comp], predY, x);
|
||||
if (x != 0)
|
||||
return chromaPredOne(this.leftRow[comp], predY);
|
||||
if (y != 0)
|
||||
return chromaPredOne(this.topLine[comp], x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void putLuma(byte[] planeData, int pred, int[][] ac, int log2stride) {
|
||||
for (int blk = 0; blk < ac.length; blk++) {
|
||||
int blkOffX = (blk & 0x3) << 2;
|
||||
int blkOffY = blk & 0xFFFFFFFC;
|
||||
putBlk(planeData, pred, ac[blk], log2stride, blkOffX, blkOffY);
|
||||
}
|
||||
}
|
||||
|
||||
private void putBlk(byte[] planeData, int pred, int[] block, int log2stride, int blkX, int blkY) {
|
||||
int stride = 1 << log2stride;
|
||||
for (int line = 0, srcOff = 0, dstOff = (blkY << log2stride) + blkX; line < 4; line++) {
|
||||
planeData[dstOff] = (byte)MathUtil.clip(block[srcOff] + pred, -128, 127);
|
||||
planeData[dstOff + 1] = (byte)MathUtil.clip(block[srcOff + 1] + pred, -128, 127);
|
||||
planeData[dstOff + 2] = (byte)MathUtil.clip(block[srcOff + 2] + pred, -128, 127);
|
||||
planeData[dstOff + 3] = (byte)MathUtil.clip(block[srcOff + 3] + pred, -128, 127);
|
||||
srcOff += 4;
|
||||
dstOff += stride;
|
||||
}
|
||||
}
|
||||
|
||||
private void restorePlaneChroma(int[][] ac, int qp) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
this.quantizer.dequantizeUV(ac[i], qp);
|
||||
VPXDCT.idct4x4(ac[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void restorePlaneLuma(int[] dc, int[][] ac, int qp) {
|
||||
this.quantizer.dequantizeY2(dc, qp);
|
||||
VPXDCT.iwalsh4x4(dc);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this.quantizer.dequantizeY(ac[i], qp);
|
||||
ac[i][0] = dc[i];
|
||||
VPXDCT.idct4x4(ac[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] extractDC(int[][] ac) {
|
||||
int[] dc = new int[ac.length];
|
||||
for (int i = 0; i < ac.length; i++)
|
||||
dc[i] = ac[i][0];
|
||||
return dc;
|
||||
}
|
||||
|
||||
private byte lumaDCPred(int x, int y) {
|
||||
if (x == 0 && y == 0)
|
||||
return 0;
|
||||
if (y == 0)
|
||||
return (byte)(ArrayUtil.sumByte(this.leftRow[0]) + 8 >> 4);
|
||||
if (x == 0)
|
||||
return (byte)(ArrayUtil.sumByte3(this.topLine[0], x, 16) + 8 >> 4);
|
||||
return (byte)(ArrayUtil.sumByte(this.leftRow[0]) + ArrayUtil.sumByte3(this.topLine[0], x, 16) + 16 >> 5);
|
||||
}
|
||||
|
||||
private int[][] transform(Picture pic, int comp, int qp, int x, int y) {
|
||||
int dcc = lumaDCPred(x, y);
|
||||
int[][] ac = new int[16][16];
|
||||
for (int i = 0; i < ac.length; i++) {
|
||||
int[] coeff = ac[i];
|
||||
int blkOffX = (i & 0x3) << 2;
|
||||
int blkOffY = i & 0xFFFFFFFC;
|
||||
takeSubtract(pic.getPlaneData(comp), pic.getPlaneWidth(comp), pic.getPlaneHeight(comp), x + blkOffX, y + blkOffY, coeff, dcc);
|
||||
VPXDCT.fdct4x4(coeff);
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
private final void takeSubtract(byte[] planeData, int planeWidth, int planeHeight, int x, int y, int[] coeff, int dc) {
|
||||
if (x + 4 < planeWidth && y + 4 < planeHeight) {
|
||||
takeSubtractSafe(planeData, planeWidth, planeHeight, x, y, coeff, dc);
|
||||
} else {
|
||||
takeSubtractUnsafe(planeData, planeWidth, planeHeight, x, y, coeff, dc);
|
||||
}
|
||||
}
|
||||
|
||||
private final void takeSubtractSafe(byte[] planeData, int planeWidth, int planeHeight, int x, int y, int[] coeff, int dc) {
|
||||
for (int i = 0, srcOff = y * planeWidth + x, dstOff = 0; i < 4; i++, srcOff += planeWidth, dstOff += 4) {
|
||||
coeff[dstOff] = planeData[srcOff] - dc;
|
||||
coeff[dstOff + 1] = planeData[srcOff + 1] - dc;
|
||||
coeff[dstOff + 2] = planeData[srcOff + 2] - dc;
|
||||
coeff[dstOff + 3] = planeData[srcOff + 3] - dc;
|
||||
}
|
||||
}
|
||||
|
||||
private final void takeSubtractUnsafe(byte[] planeData, int planeWidth, int planeHeight, int x, int y, int[] coeff, int dc) {
|
||||
int outOff = 0;
|
||||
int i;
|
||||
for (i = y; i < Math.min(y + 4, planeHeight); i++) {
|
||||
int off = i * planeWidth + Math.min(x, planeWidth);
|
||||
int j;
|
||||
for (j = x; j < Math.min(x + 4, planeWidth); j++)
|
||||
coeff[outOff++] = planeData[off++] - dc;
|
||||
off--;
|
||||
for (; j < x + 4; j++)
|
||||
coeff[outOff++] = planeData[off] - dc;
|
||||
}
|
||||
for (; i < y + 4; i++) {
|
||||
int off = planeHeight * planeWidth - planeWidth + Math.min(x, planeWidth);
|
||||
int j;
|
||||
for (j = x; j < Math.min(x + 4, planeWidth); j++)
|
||||
coeff[outOff++] = planeData[off++] - dc;
|
||||
off--;
|
||||
for (; j < x + 4; j++)
|
||||
coeff[outOff++] = planeData[off] - dc;
|
||||
}
|
||||
}
|
||||
|
||||
public ColorSpace[] getSupportedColorSpaces() {
|
||||
return new ColorSpace[] { ColorSpace.YUV420J };
|
||||
}
|
||||
|
||||
public int estimateBufferSize(Picture frame) {
|
||||
return frame.getWidth() * frame.getHeight() / 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public class VP8FixedRateControl implements RateControl {
|
||||
private int rate;
|
||||
|
||||
public VP8FixedRateControl(int rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public int[] getSegmentQps() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getSegment() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void report(int bits) {}
|
||||
|
||||
public void reset() {}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,168 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class VPXBitstream {
|
||||
public static final int[] coeffBandMapping = new int[] {
|
||||
0, 1, 2, 3, 6, 4, 5, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 7 };
|
||||
|
||||
private int[][][][] tokenBinProbs;
|
||||
|
||||
private int whtNzLeft = 0;
|
||||
|
||||
private int[] whtNzTop;
|
||||
|
||||
private int[][] dctNzLeft;
|
||||
|
||||
private int[][] dctNzTop;
|
||||
|
||||
public VPXBitstream(int[][][][] tokenBinProbs, int mbWidth) {
|
||||
this.dctNzLeft = new int[][] { new int[4], new int[2], new int[2] };
|
||||
this.tokenBinProbs = tokenBinProbs;
|
||||
this.whtNzTop = new int[mbWidth];
|
||||
this.dctNzTop = new int[][] { new int[mbWidth << 2], new int[mbWidth << 1], new int[mbWidth << 1] };
|
||||
}
|
||||
|
||||
public void encodeCoeffsWHT(VPXBooleanEncoder bc, int[] coeffs, int mbX) {
|
||||
int nCoeff = fastCountCoeffWHT(coeffs);
|
||||
encodeCoeffs(bc, coeffs, 0, nCoeff, 1, ((mbX == 0 || this.whtNzLeft <= 0) ? 0 : 1) + ((this.whtNzTop[mbX] > 0) ? 1 : 0));
|
||||
this.whtNzLeft = nCoeff;
|
||||
this.whtNzTop[mbX] = nCoeff;
|
||||
}
|
||||
|
||||
public void encodeCoeffsDCT15(VPXBooleanEncoder bc, int[] coeffs, int mbX, int blkX, int blkY) {
|
||||
int nCoeff = countCoeff(coeffs, 16);
|
||||
int blkAbsX = (mbX << 2) + blkX;
|
||||
encodeCoeffs(bc, coeffs, 1, nCoeff, 0, ((blkAbsX == 0 || this.dctNzLeft[0][blkY] <= 0) ? 0 : 1) + ((this.dctNzTop[0][blkAbsX] > 0) ? 1 : 0));
|
||||
this.dctNzLeft[0][blkY] = Math.max(nCoeff - 1, 0);
|
||||
this.dctNzTop[0][blkAbsX] = Math.max(nCoeff - 1, 0);
|
||||
}
|
||||
|
||||
public void encodeCoeffsDCT16(VPXBooleanEncoder bc, int[] coeffs, int mbX, int blkX, int blkY) {
|
||||
int nCoeff = countCoeff(coeffs, 16);
|
||||
int blkAbsX = (mbX << 2) + blkX;
|
||||
encodeCoeffs(bc, coeffs, 0, nCoeff, 3, ((blkAbsX == 0 || this.dctNzLeft[0][blkY] <= 0) ? 0 : 1) + ((this.dctNzTop[0][blkAbsX] > 0) ? 1 : 0));
|
||||
this.dctNzLeft[0][blkY] = nCoeff;
|
||||
this.dctNzTop[0][blkAbsX] = nCoeff;
|
||||
}
|
||||
|
||||
public void encodeCoeffsDCTUV(VPXBooleanEncoder bc, int[] coeffs, int comp, int mbX, int blkX, int blkY) {
|
||||
int nCoeff = countCoeff(coeffs, 16);
|
||||
int blkAbsX = (mbX << 1) + blkX;
|
||||
encodeCoeffs(bc, coeffs, 0, nCoeff, 2, ((blkAbsX == 0 || this.dctNzLeft[comp][blkY] <= 0) ? 0 : 1) + (
|
||||
(this.dctNzTop[comp][blkAbsX] > 0) ? 1 : 0));
|
||||
this.dctNzLeft[comp][blkY] = nCoeff;
|
||||
this.dctNzTop[comp][blkAbsX] = nCoeff;
|
||||
}
|
||||
|
||||
public void encodeCoeffs(VPXBooleanEncoder bc, int[] coeffs, int firstCoeff, int nCoeff, int blkType, int ctx) {
|
||||
boolean prevZero = false;
|
||||
int i;
|
||||
for (i = firstCoeff; i < nCoeff; i++) {
|
||||
int[] probs = this.tokenBinProbs[blkType][coeffBandMapping[i]][ctx];
|
||||
int coeffAbs = MathUtil.abs(coeffs[i]);
|
||||
if (!prevZero)
|
||||
bc.writeBit(probs[0], 1);
|
||||
if (coeffAbs == 0) {
|
||||
bc.writeBit(probs[1], 0);
|
||||
ctx = 0;
|
||||
} else {
|
||||
bc.writeBit(probs[1], 1);
|
||||
if (coeffAbs == 1) {
|
||||
bc.writeBit(probs[2], 0);
|
||||
ctx = 1;
|
||||
} else {
|
||||
ctx = 2;
|
||||
bc.writeBit(probs[2], 1);
|
||||
if (coeffAbs <= 4) {
|
||||
bc.writeBit(probs[3], 0);
|
||||
if (coeffAbs == 2) {
|
||||
bc.writeBit(probs[4], 0);
|
||||
} else {
|
||||
bc.writeBit(probs[4], 1);
|
||||
bc.writeBit(probs[5], coeffAbs - 3);
|
||||
}
|
||||
} else {
|
||||
bc.writeBit(probs[3], 1);
|
||||
if (coeffAbs <= 10) {
|
||||
bc.writeBit(probs[6], 0);
|
||||
if (coeffAbs <= 6) {
|
||||
bc.writeBit(probs[7], 0);
|
||||
bc.writeBit(159, coeffAbs - 5);
|
||||
} else {
|
||||
bc.writeBit(probs[7], 1);
|
||||
int d = coeffAbs - 7;
|
||||
bc.writeBit(165, d >> 1);
|
||||
bc.writeBit(145, d & 0x1);
|
||||
}
|
||||
} else {
|
||||
bc.writeBit(probs[6], 1);
|
||||
if (coeffAbs <= 34) {
|
||||
bc.writeBit(probs[8], 0);
|
||||
if (coeffAbs <= 18) {
|
||||
bc.writeBit(probs[9], 0);
|
||||
writeCat3Ext(bc, coeffAbs);
|
||||
} else {
|
||||
bc.writeBit(probs[9], 1);
|
||||
writeCat4Ext(bc, coeffAbs);
|
||||
}
|
||||
} else {
|
||||
bc.writeBit(probs[8], 1);
|
||||
if (coeffAbs <= 66) {
|
||||
bc.writeBit(probs[10], 0);
|
||||
writeCatExt(bc, coeffAbs, 35, VPXConst.probCoeffExtCat5);
|
||||
} else {
|
||||
bc.writeBit(probs[10], 1);
|
||||
writeCatExt(bc, coeffAbs, 67, VPXConst.probCoeffExtCat6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bc.writeBit(128, MathUtil.sign(coeffs[i]));
|
||||
}
|
||||
prevZero = (coeffAbs == 0);
|
||||
}
|
||||
if (nCoeff < 16) {
|
||||
int[] probs = this.tokenBinProbs[blkType][coeffBandMapping[i]][ctx];
|
||||
bc.writeBit(probs[0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeCat3Ext(VPXBooleanEncoder bc, int coeff) {
|
||||
int d = coeff - 11;
|
||||
bc.writeBit(173, d >> 2);
|
||||
bc.writeBit(148, d >> 1 & 0x1);
|
||||
bc.writeBit(140, d & 0x1);
|
||||
}
|
||||
|
||||
private static void writeCat4Ext(VPXBooleanEncoder bc, int coeff) {
|
||||
int d = coeff - 19;
|
||||
bc.writeBit(176, d >> 3);
|
||||
bc.writeBit(155, d >> 2 & 0x1);
|
||||
bc.writeBit(140, d >> 1 & 0x1);
|
||||
bc.writeBit(135, d & 0x1);
|
||||
}
|
||||
|
||||
private static final void writeCatExt(VPXBooleanEncoder bc, int coeff, int catOff, int[] cat) {
|
||||
int d = coeff - catOff;
|
||||
for (int b = cat.length - 1, i = 0; b >= 0; b--)
|
||||
bc.writeBit(cat[i++], d >> b & 0x1);
|
||||
}
|
||||
|
||||
private int fastCountCoeffWHT(int[] coeffs) {
|
||||
if (coeffs[15] != 0)
|
||||
return 16;
|
||||
return countCoeff(coeffs, 15);
|
||||
}
|
||||
|
||||
private int countCoeff(int[] coeffs, int nCoeff) {
|
||||
while (nCoeff > 0) {
|
||||
nCoeff--;
|
||||
if (coeffs[nCoeff] != 0)
|
||||
return nCoeff + 1;
|
||||
}
|
||||
return nCoeff;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class VPXBooleanDecoder {
|
||||
int bit_count;
|
||||
|
||||
ByteBuffer input;
|
||||
|
||||
int offset;
|
||||
|
||||
int range;
|
||||
|
||||
int value;
|
||||
|
||||
long callCounter = 0L;
|
||||
|
||||
private String debugName;
|
||||
|
||||
public VPXBooleanDecoder(ByteBuffer input, int offset) {
|
||||
this.input = input;
|
||||
this.offset = offset;
|
||||
initBoolDecoder();
|
||||
}
|
||||
|
||||
protected VPXBooleanDecoder() {}
|
||||
|
||||
void initBoolDecoder() {
|
||||
this.value = 0;
|
||||
this.value = (this.input.get() & 0xFF) << 8;
|
||||
this.offset++;
|
||||
this.range = 255;
|
||||
this.bit_count = 0;
|
||||
}
|
||||
|
||||
public int readBitEq() {
|
||||
return readBit(128);
|
||||
}
|
||||
|
||||
public int readBit(int probability) {
|
||||
int bit = 0;
|
||||
int range = this.range;
|
||||
int value = this.value;
|
||||
int split = 1 + ((range - 1) * probability >> 8);
|
||||
int bigsplit = split << 8;
|
||||
this.callCounter++;
|
||||
range = split;
|
||||
if (value >= bigsplit) {
|
||||
range = this.range - range;
|
||||
value -= bigsplit;
|
||||
bit = 1;
|
||||
}
|
||||
int count = this.bit_count;
|
||||
int shift = leadingZeroCountInByte((byte)range);
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
if (count <= 0) {
|
||||
value |= (this.input.get() & 0xFF) << -count;
|
||||
this.offset++;
|
||||
count += 8;
|
||||
}
|
||||
this.bit_count = count;
|
||||
this.value = value;
|
||||
this.range = range;
|
||||
return bit;
|
||||
}
|
||||
|
||||
public int decodeInt(int sizeInBits) {
|
||||
int v = 0;
|
||||
while (sizeInBits-- > 0)
|
||||
v = v << 1 | readBit(128);
|
||||
return v;
|
||||
}
|
||||
|
||||
public int readTree(int[] tree, int[] probability) {
|
||||
int i = 0;
|
||||
while ((i = tree[i + readBit(probability[i >> 1])]) > 0);
|
||||
return -i;
|
||||
}
|
||||
|
||||
public int readTree3(int[] tree, int prob0, int prob1) {
|
||||
int i = 0;
|
||||
if ((i = tree[i + readBit(prob0)]) > 0)
|
||||
while ((i = tree[i + readBit(prob1)]) > 0);
|
||||
return -i;
|
||||
}
|
||||
|
||||
public int readTreeSkip(int[] t, int[] p, int skip_branches) {
|
||||
int i = skip_branches * 2;
|
||||
while ((i = t[i + readBit(p[i >> 1])]) > 0);
|
||||
return -i;
|
||||
}
|
||||
|
||||
public void seek() {
|
||||
this.input.position(this.offset);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "bc: " + this.value;
|
||||
}
|
||||
|
||||
public static int getBitInBytes(byte[] bs, int i) {
|
||||
int byteIndex = i >> 3;
|
||||
int bitIndex = i & 0x7;
|
||||
return bs[byteIndex] >> 7 - bitIndex & 0x1;
|
||||
}
|
||||
|
||||
public static int getBitsInBytes(byte[] bytes, int idx, int len) {
|
||||
int val = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
val = val << 1 | getBitInBytes(bytes, idx + i);
|
||||
return val;
|
||||
}
|
||||
|
||||
public static int leadingZeroCountInByte(byte b) {
|
||||
int i = b & 0xFF;
|
||||
if (i >= 128 || i == 0)
|
||||
return 0;
|
||||
return Integer.numberOfLeadingZeros(b) - 24;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class VPXBooleanEncoder {
|
||||
private ByteBuffer out;
|
||||
|
||||
private int lowvalue;
|
||||
|
||||
private int range;
|
||||
|
||||
private int count;
|
||||
|
||||
public VPXBooleanEncoder(ByteBuffer out) {
|
||||
this.out = out;
|
||||
this.lowvalue = 0;
|
||||
this.range = 255;
|
||||
this.count = -24;
|
||||
}
|
||||
|
||||
public void writeBit(int prob, int bb) {
|
||||
int split = 1 + ((this.range - 1) * prob >> 8);
|
||||
if (bb != 0) {
|
||||
this.lowvalue += split;
|
||||
this.range -= split;
|
||||
} else {
|
||||
this.range = split;
|
||||
}
|
||||
int shift = VPXConst.vp8Norm[this.range];
|
||||
this.range <<= shift;
|
||||
this.count += shift;
|
||||
if (this.count >= 0) {
|
||||
int offset = shift - this.count;
|
||||
if ((this.lowvalue << offset - 1 & Integer.MIN_VALUE) != 0) {
|
||||
int x = this.out.position() - 1;
|
||||
while (x >= 0 && this.out.get(x) == -1) {
|
||||
this.out.put(x, (byte)0);
|
||||
x--;
|
||||
}
|
||||
this.out.put(x, (byte)((this.out.get(x) & 0xFF) + 1));
|
||||
}
|
||||
this.out.put((byte)(this.lowvalue >> 24 - offset));
|
||||
this.lowvalue <<= offset;
|
||||
shift = this.count;
|
||||
this.lowvalue &= 0xFFFFFF;
|
||||
this.count -= 8;
|
||||
}
|
||||
this.lowvalue <<= shift;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
for (int i = 0; i < 32; i++)
|
||||
writeBit(128, 0);
|
||||
}
|
||||
|
||||
public int position() {
|
||||
return this.out.position() + (this.count + 24 >> 3);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,459 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public class VPXConst {
|
||||
public static final int[] vp8Norm = new int[] {
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0 };
|
||||
|
||||
public static final int[][][][] tokenDefaultBinProbs = new int[][][][] { new int[][][] { new int[][] { new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
253, 136, 254, 255, 228, 219, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
189, 129, 242, 255, 227, 213, 255, 219, 128, 128,
|
||||
128 }, new int[] {
|
||||
106, 126, 227, 252, 214, 209, 255, 255, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 98, 248, 255, 236, 226, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
181, 133, 238, 254, 221, 234, 255, 154, 128, 128,
|
||||
128 }, new int[] {
|
||||
78, 134, 202, 247, 198, 180, 255, 219, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 185, 249, 255, 243, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
184, 150, 247, 255, 236, 224, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
77, 110, 216, 255, 236, 230, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 101, 251, 255, 241, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
170, 139, 241, 252, 236, 209, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
37, 116, 196, 243, 228, 255, 255, 255, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 204, 254, 255, 245, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
207, 160, 250, 255, 238, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
102, 103, 231, 255, 211, 171, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 152, 252, 255, 240, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
177, 135, 243, 255, 234, 225, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
80, 129, 211, 255, 194, 224, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
246, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
255, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } } }, new int[][][] { new int[][] { new int[] {
|
||||
198, 35, 237, 223, 193, 187, 162, 160, 145, 155,
|
||||
62 }, new int[] {
|
||||
131, 45, 198, 221, 172, 176, 220, 157, 252, 221,
|
||||
1 }, new int[] {
|
||||
68, 47, 146, 208, 149, 167, 221, 162, 255, 223,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 149, 241, 255, 221, 224, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
184, 141, 234, 253, 222, 220, 255, 199, 128, 128,
|
||||
128 }, new int[] {
|
||||
81, 99, 181, 242, 176, 190, 249, 202, 255, 255,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 129, 232, 253, 214, 197, 242, 196, 255, 255,
|
||||
128 }, new int[] {
|
||||
99, 121, 210, 250, 201, 198, 255, 202, 128, 128,
|
||||
128 }, new int[] {
|
||||
23, 91, 163, 242, 170, 187, 247, 210, 255, 255,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 200, 246, 255, 234, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
109, 178, 241, 255, 231, 245, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
44, 130, 201, 253, 205, 192, 255, 255, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 132, 239, 251, 219, 209, 255, 165, 128, 128,
|
||||
128 }, new int[] {
|
||||
94, 136, 225, 251, 218, 190, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
22, 100, 174, 245, 186, 161, 255, 199, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 182, 249, 255, 232, 235, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
124, 143, 241, 255, 227, 234, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
35, 77, 181, 251, 193, 211, 255, 205, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 157, 247, 255, 236, 231, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
121, 141, 235, 255, 225, 227, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
45, 99, 188, 251, 195, 217, 255, 224, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 1, 251, 255, 213, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
203, 1, 248, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
137, 1, 177, 255, 224, 255, 128, 128, 128, 128,
|
||||
128 } } }, new int[][][] { new int[][] { new int[] {
|
||||
253, 9, 248, 251, 207, 208, 255, 192, 128, 128,
|
||||
128 }, new int[] {
|
||||
175, 13, 224, 243, 193, 185, 249, 198, 255, 255,
|
||||
128 }, new int[] {
|
||||
73, 17, 171, 221, 161, 179, 236, 167, 255, 234,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 95, 247, 253, 212, 183, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
239, 90, 244, 250, 211, 209, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
155, 77, 195, 248, 188, 195, 255, 255, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 24, 239, 251, 218, 219, 255, 205, 128, 128,
|
||||
128 }, new int[] {
|
||||
201, 51, 219, 255, 196, 186, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
69, 46, 190, 239, 201, 218, 255, 228, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 191, 251, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
223, 165, 249, 255, 213, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
141, 124, 248, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 16, 248, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
190, 36, 230, 255, 236, 255, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
149, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 226, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
247, 192, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
240, 128, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 134, 252, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
213, 62, 250, 255, 255, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
55, 93, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } } }, new int[][][] { new int[][] { new int[] {
|
||||
202, 24, 213, 235, 186, 191, 220, 160, 240, 175,
|
||||
255 }, new int[] {
|
||||
126, 38, 182, 232, 169, 184, 228, 174, 255, 187,
|
||||
128 }, new int[] {
|
||||
61, 46, 138, 219, 151, 178, 240, 170, 255, 216,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 112, 230, 250, 199, 191, 247, 159, 255, 255,
|
||||
128 }, new int[] {
|
||||
166, 109, 228, 252, 211, 215, 255, 174, 128, 128,
|
||||
128 }, new int[] {
|
||||
39, 77, 162, 232, 172, 180, 245, 178, 255, 255,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 52, 220, 246, 198, 199, 249, 220, 255, 255,
|
||||
128 }, new int[] {
|
||||
124, 74, 191, 243, 183, 193, 250, 221, 255, 255,
|
||||
128 }, new int[] {
|
||||
24, 71, 130, 219, 154, 170, 243, 182, 255, 255,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 182, 225, 249, 219, 240, 255, 224, 128, 128,
|
||||
128 }, new int[] {
|
||||
149, 150, 226, 252, 216, 205, 255, 171, 128, 128,
|
||||
128 }, new int[] {
|
||||
28, 108, 170, 242, 183, 194, 254, 223, 255, 255,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 81, 230, 252, 204, 203, 255, 192, 128, 128,
|
||||
128 }, new int[] {
|
||||
123, 102, 209, 247, 188, 196, 255, 233, 128, 128,
|
||||
128 }, new int[] {
|
||||
20, 95, 153, 243, 164, 173, 255, 203, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 222, 248, 255, 216, 213, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
168, 175, 246, 252, 235, 205, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
47, 116, 215, 255, 211, 212, 255, 255, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 121, 236, 253, 212, 214, 255, 255, 128, 128,
|
||||
128 }, new int[] {
|
||||
141, 84, 213, 252, 201, 202, 255, 219, 128, 128,
|
||||
128 }, new int[] {
|
||||
42, 80, 160, 240, 162, 185, 255, 205, 128, 128,
|
||||
128 } }, new int[][] { new int[] {
|
||||
1, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
244, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 }, new int[] {
|
||||
238, 1, 255, 128, 128, 128, 128, 128, 128, 128,
|
||||
128 } } } };
|
||||
|
||||
public static int[][][][] tokenProbUpdateFlagProbs = new int[][][][] { new int[][][] { new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
176, 246, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
223, 241, 252, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
249, 253, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 244, 252, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
234, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
253, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 246, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
239, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 248, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
251, 255, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
251, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 253, 255, 254, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
250, 255, 254, 255, 254, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } } }, new int[][][] { new int[][] { new int[] {
|
||||
217, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
225, 252, 241, 253, 255, 255, 254, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
234, 250, 241, 250, 253, 255, 253, 254, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
223, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
238, 253, 254, 254, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 248, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
249, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 253, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
247, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
252, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
253, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
250, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } } }, new int[][][] { new int[][] { new int[] {
|
||||
186, 251, 250, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
234, 251, 244, 254, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
251, 251, 243, 253, 254, 255, 254, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
236, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
251, 253, 253, 254, 254, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 254, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } } }, new int[][][] { new int[][] { new int[] {
|
||||
248, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
250, 254, 252, 254, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
248, 254, 249, 253, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 253, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
246, 253, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
252, 254, 251, 254, 254, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 254, 252, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
248, 254, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
253, 255, 254, 254, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 251, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
245, 251, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
253, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 251, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
252, 253, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 254, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 252, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
249, 255, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 254, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 253, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
250, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } }, new int[][] { new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 }, new int[] {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255 } } } };
|
||||
|
||||
public static final int[] probCoeffExtCat6 = new int[] {
|
||||
254, 254, 243, 230, 196, 177, 153, 140, 133, 130,
|
||||
129 };
|
||||
|
||||
public static final int[] probCoeffExtCat5 = new int[] { 180, 157, 141, 134, 130 };
|
||||
|
||||
public static final int[] dc_qlookup = new int[] {
|
||||
4, 5, 6, 7, 8, 9, 10, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 17, 18, 19, 20, 20,
|
||||
21, 21, 22, 22, 23, 23, 24, 25, 25, 26,
|
||||
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 37, 38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 46, 47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
|
||||
75, 76, 76, 77, 78, 79, 80, 81, 82, 83,
|
||||
84, 85, 86, 87, 88, 89, 91, 93, 95, 96,
|
||||
98, 100, 101, 102, 104, 106, 108, 110, 112, 114,
|
||||
116, 118, 122, 124, 126, 128, 130, 132, 134, 136,
|
||||
138, 140, 143, 145, 148, 151, 154, 157 };
|
||||
|
||||
public static final int[] ac_qlookup = new int[] {
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 60, 62, 64, 66, 68,
|
||||
70, 72, 74, 76, 78, 80, 82, 84, 86, 88,
|
||||
90, 92, 94, 96, 98, 100, 102, 104, 106, 108,
|
||||
110, 112, 114, 116, 119, 122, 125, 128, 131, 134,
|
||||
137, 140, 143, 146, 149, 152, 155, 158, 161, 164,
|
||||
167, 170, 173, 177, 181, 185, 189, 193, 197, 201,
|
||||
205, 209, 213, 217, 221, 225, 229, 234, 239, 245,
|
||||
249, 254, 259, 264, 269, 274, 279, 284 };
|
||||
|
||||
public static final int[] zigzag = new int[] {
|
||||
0, 1, 4, 8, 5, 2, 3, 6, 9, 12,
|
||||
13, 10, 7, 11, 14, 15 };
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
public class VPXDCT {
|
||||
public static void fdct4x4(int[] coef) {
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
int a1 = coef[j] + coef[j + 3] << 3;
|
||||
int b1 = coef[j + 1] + coef[j + 2] << 3;
|
||||
int c1 = coef[j + 1] - coef[j + 2] << 3;
|
||||
int d1 = coef[j] - coef[j + 3] << 3;
|
||||
coef[j] = a1 + b1;
|
||||
coef[j + 2] = a1 - b1;
|
||||
coef[j + 1] = c1 * 2217 + d1 * 5352 + 14500 >> 12;
|
||||
coef[j + 3] = d1 * 2217 - c1 * 5352 + 7500 >> 12;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = coef[i] + coef[i + 12];
|
||||
int b1 = coef[i + 4] + coef[i + 8];
|
||||
int c1 = coef[i + 4] - coef[i + 8];
|
||||
int d1 = coef[i] - coef[i + 12];
|
||||
coef[i] = a1 + b1 + 7 >> 4;
|
||||
coef[i + 8] = a1 - b1 + 7 >> 4;
|
||||
coef[i + 4] = (c1 * 2217 + d1 * 5352 + 12000 >> 16) + ((d1 != 0) ? 1 : 0);
|
||||
coef[i + 12] = d1 * 2217 - c1 * 5352 + 51000 >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
public static void walsh4x4(int[] coef) {
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
int a1 = coef[j] + coef[j + 2] << 2;
|
||||
int d1 = coef[j + 1] + coef[j + 3] << 2;
|
||||
int c1 = coef[j + 1] - coef[j + 3] << 2;
|
||||
int b1 = coef[j] - coef[j + 2] << 2;
|
||||
coef[j] = a1 + d1 + ((a1 != 0) ? 1 : 0);
|
||||
coef[j + 1] = b1 + c1;
|
||||
coef[j + 2] = b1 - c1;
|
||||
coef[j + 3] = a1 - d1;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int a1 = coef[i] + coef[i + 8];
|
||||
int d1 = coef[i + 4] + coef[i + 12];
|
||||
int c1 = coef[i + 4] - coef[i + 12];
|
||||
int b1 = coef[i] - coef[i + 8];
|
||||
int a2 = a1 + d1;
|
||||
int b2 = b1 + c1;
|
||||
int c2 = b1 - c1;
|
||||
int d2 = a1 - d1;
|
||||
a2 += (a2 < 0) ? 1 : 0;
|
||||
b2 += (b2 < 0) ? 1 : 0;
|
||||
c2 += (c2 < 0) ? 1 : 0;
|
||||
d2 += (d2 < 0) ? 1 : 0;
|
||||
coef[i] = a2 + 3 >> 3;
|
||||
coef[i + 4] = b2 + 3 >> 3;
|
||||
coef[i + 8] = c2 + 3 >> 3;
|
||||
coef[i + 12] = d2 + 3 >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
public static int cospi8sqrt2minus1 = 20091;
|
||||
|
||||
public static int sinpi8sqrt2 = 35468;
|
||||
|
||||
public static void idct4x4(int[] coef) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = coef[j] + coef[j + 8];
|
||||
int b1 = coef[j] - coef[j + 8];
|
||||
int temp1 = coef[j + 4] * sinpi8sqrt2 >> 16;
|
||||
int temp2 = coef[j + 12] + (coef[j + 12] * cospi8sqrt2minus1 >> 16);
|
||||
int c1 = temp1 - temp2;
|
||||
temp1 = coef[j + 4] + (coef[j + 4] * cospi8sqrt2minus1 >> 16);
|
||||
temp2 = coef[j + 12] * sinpi8sqrt2 >> 16;
|
||||
int d1 = temp1 + temp2;
|
||||
coef[j] = a1 + d1;
|
||||
coef[j + 12] = a1 - d1;
|
||||
coef[j + 4] = b1 + c1;
|
||||
coef[j + 8] = b1 - c1;
|
||||
}
|
||||
for (int i = 0; i < 16; i += 4) {
|
||||
int a1 = coef[i] + coef[i + 2];
|
||||
int b1 = coef[i] - coef[i + 2];
|
||||
int temp1 = coef[i + 1] * sinpi8sqrt2 >> 16;
|
||||
int temp2 = coef[i + 3] + (coef[i + 3] * cospi8sqrt2minus1 >> 16);
|
||||
int c1 = temp1 - temp2;
|
||||
temp1 = coef[i + 1] + (coef[i + 1] * cospi8sqrt2minus1 >> 16);
|
||||
temp2 = coef[i + 3] * sinpi8sqrt2 >> 16;
|
||||
int d1 = temp1 + temp2;
|
||||
coef[i] = a1 + d1 + 4 >> 3;
|
||||
coef[i + 3] = a1 - d1 + 4 >> 3;
|
||||
coef[i + 1] = b1 + c1 + 4 >> 3;
|
||||
coef[i + 2] = b1 - c1 + 4 >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
public static void iwalsh4x4(int[] coef) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int a1 = coef[j] + coef[j + 12];
|
||||
int b1 = coef[j + 4] + coef[j + 8];
|
||||
int c1 = coef[j + 4] - coef[j + 8];
|
||||
int d1 = coef[j] - coef[j + 12];
|
||||
coef[j] = a1 + b1;
|
||||
coef[j + 4] = c1 + d1;
|
||||
coef[j + 8] = a1 - b1;
|
||||
coef[j + 12] = d1 - c1;
|
||||
}
|
||||
for (int i = 0; i < 16; i += 4) {
|
||||
int a1 = coef[i] + coef[i + 3];
|
||||
int b1 = coef[i + 1] + coef[i + 2];
|
||||
int c1 = coef[i + 1] - coef[i + 2];
|
||||
int d1 = coef[i] - coef[i + 3];
|
||||
int a2 = a1 + b1;
|
||||
int b2 = c1 + d1;
|
||||
int c2 = a1 - b1;
|
||||
int d2 = d1 - c1;
|
||||
coef[i] = a2 + 3 >> 3;
|
||||
coef[i + 1] = b2 + 3 >> 3;
|
||||
coef[i + 2] = c2 + 3 >> 3;
|
||||
coef[i + 3] = d2 + 3 >> 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,758 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.api.NotImplementedException;
|
||||
import org.jcodec.api.NotSupportedException;
|
||||
import org.jcodec.common.model.Picture;
|
||||
|
||||
public class VPXMacroblock {
|
||||
public int filterLevel;
|
||||
|
||||
public int chromaMode;
|
||||
|
||||
public int skipCoeff;
|
||||
|
||||
public final Subblock[][] ySubblocks;
|
||||
|
||||
public final Subblock y2;
|
||||
|
||||
public final Subblock[][] uSubblocks;
|
||||
|
||||
public final Subblock[][] vSubblocks;
|
||||
|
||||
public final int Rrow;
|
||||
|
||||
public final int column;
|
||||
|
||||
public int lumaMode;
|
||||
|
||||
boolean skipFilter;
|
||||
|
||||
public int segment = 0;
|
||||
|
||||
public boolean debug = false;
|
||||
|
||||
public VP8Util.QuantizationParams quants;
|
||||
|
||||
public VPXMacroblock(int y, int x) {
|
||||
this.ySubblocks = new Subblock[4][4];
|
||||
this.y2 = new Subblock(this, 0, 0, VP8Util.PLANE.Y2);
|
||||
this.uSubblocks = new Subblock[2][2];
|
||||
this.vSubblocks = new Subblock[2][2];
|
||||
this.Rrow = y;
|
||||
this.column = x;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int col = 0; col < 4; col++)
|
||||
this.ySubblocks[i][col] = new Subblock(this, i, col, VP8Util.PLANE.Y1);
|
||||
}
|
||||
for (int row = 0; row < 2; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
this.uSubblocks[row][col] = new Subblock(this, row, col, VP8Util.PLANE.U);
|
||||
this.vSubblocks[row][col] = new Subblock(this, row, col, VP8Util.PLANE.V);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dequantMacroBlock(VPXMacroblock[][] mbs) {
|
||||
VP8Util.QuantizationParams p = this.quants;
|
||||
if (this.lumaMode != 4) {
|
||||
int acQValue = p.y2AC;
|
||||
int dcQValue = p.y2DC;
|
||||
int[] input = new int[16];
|
||||
input[0] = this.y2.tokens[0] * dcQValue;
|
||||
for (int x = 1; x < 16; x++)
|
||||
input[x] = this.y2.tokens[x] * acQValue;
|
||||
this.y2.residue = VP8DCT.decodeWHT(input);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int col = 0; col < 4; col++)
|
||||
this.ySubblocks[i][col].dequantSubblock(p.yDC, p.yAC, Integer.valueOf(this.y2.residue[i * 4 + col]));
|
||||
}
|
||||
predictY(mbs);
|
||||
predictUV(mbs);
|
||||
for (int row = 0; row < 2; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
this.uSubblocks[row][col].dequantSubblock(p.chromaDC, p.chromaAC, null);
|
||||
this.vSubblocks[row][col].dequantSubblock(p.chromaDC, p.chromaAC, null);
|
||||
}
|
||||
}
|
||||
reconstruct();
|
||||
} else {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
Subblock sb = this.ySubblocks[j][col];
|
||||
sb.dequantSubblock(p.yDC, p.yAC, null);
|
||||
sb.predict(mbs);
|
||||
sb.reconstruct();
|
||||
}
|
||||
}
|
||||
predictUV(mbs);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
Subblock sb = this.uSubblocks[i][col];
|
||||
sb.dequantSubblock(p.chromaDC, p.chromaAC, null);
|
||||
sb.reconstruct();
|
||||
}
|
||||
}
|
||||
for (int row = 0; row < 2; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
Subblock sb = this.vSubblocks[row][col];
|
||||
sb.dequantSubblock(p.chromaDC, p.chromaAC, null);
|
||||
sb.reconstruct();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reconstruct() {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int col = 0; col < 4; col++)
|
||||
this.ySubblocks[j][col].reconstruct();
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int col = 0; col < 2; col++)
|
||||
this.uSubblocks[i][col].reconstruct();
|
||||
}
|
||||
for (int row = 0; row < 2; row++) {
|
||||
for (int col = 0; col < 2; col++)
|
||||
this.vSubblocks[row][col].reconstruct();
|
||||
}
|
||||
}
|
||||
|
||||
public void predictUV(VPXMacroblock[][] mbs) {
|
||||
boolean up_available, left_available;
|
||||
int uAvg, vAvg, expected_udc, expected_vdc, ufill[], aRow, vfill[], i;
|
||||
Subblock[] aboveUSb, aboveVSb;
|
||||
int aCol, j;
|
||||
Subblock[] leftUSb, leftVSb;
|
||||
int m, k;
|
||||
VPXMacroblock ALMb;
|
||||
Subblock ALUSb;
|
||||
int alu;
|
||||
Subblock ALVSb;
|
||||
int alv, x, sbRow;
|
||||
VPXMacroblock aboveMb = mbs[this.Rrow - 1][this.column];
|
||||
VPXMacroblock leftMb = mbs[this.Rrow][this.column - 1];
|
||||
switch (this.chromaMode) {
|
||||
case 0:
|
||||
up_available = false;
|
||||
left_available = false;
|
||||
uAvg = 0;
|
||||
vAvg = 0;
|
||||
expected_udc = 128;
|
||||
expected_vdc = 128;
|
||||
if (this.column > 1)
|
||||
left_available = true;
|
||||
if (this.Rrow > 1)
|
||||
up_available = true;
|
||||
if (up_available || left_available) {
|
||||
if (up_available)
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Subblock usb = aboveMb.uSubblocks[1][n];
|
||||
Subblock vsb = aboveMb.vSubblocks[1][n];
|
||||
for (int i1 = 0; i1 < 4; i1++) {
|
||||
uAvg += usb.val[12 + i1];
|
||||
vAvg += vsb.val[12 + i1];
|
||||
}
|
||||
}
|
||||
if (left_available)
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Subblock usb = leftMb.uSubblocks[n][1];
|
||||
Subblock vsb = leftMb.vSubblocks[n][1];
|
||||
for (int i1 = 0; i1 < 4; i1++) {
|
||||
uAvg += usb.val[i1 * 4 + 3];
|
||||
vAvg += vsb.val[i1 * 4 + 3];
|
||||
}
|
||||
}
|
||||
int shift = 2;
|
||||
if (up_available)
|
||||
shift++;
|
||||
if (left_available)
|
||||
shift++;
|
||||
expected_udc = uAvg + (1 << shift - 1) >> shift;
|
||||
expected_vdc = vAvg + (1 << shift - 1) >> shift;
|
||||
}
|
||||
ufill = new int[16];
|
||||
for (aRow = 0; aRow < 4; aRow++) {
|
||||
for (int n = 0; n < 4; n++)
|
||||
ufill[aRow * 4 + n] = expected_udc;
|
||||
}
|
||||
vfill = new int[16];
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (int n = 0; n < 4; n++)
|
||||
vfill[i * 4 + n] = expected_vdc;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Subblock usb = this.uSubblocks[i][n];
|
||||
Subblock vsb = this.vSubblocks[i][n];
|
||||
usb._predict = ufill;
|
||||
vsb._predict = vfill;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
aboveUSb = new Subblock[2];
|
||||
aboveVSb = new Subblock[2];
|
||||
for (aCol = 0; aCol < 2; aCol++) {
|
||||
aboveUSb[aCol] = aboveMb.uSubblocks[1][aCol];
|
||||
aboveVSb[aCol] = aboveMb.vSubblocks[1][aCol];
|
||||
}
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Subblock usb = this.uSubblocks[j][n];
|
||||
Subblock vsb = this.vSubblocks[j][n];
|
||||
int[] ublock = new int[16];
|
||||
int[] vblock = new int[16];
|
||||
for (int pRow = 0; pRow < 4; pRow++) {
|
||||
for (int pCol = 0; pCol < 4; pCol++) {
|
||||
ublock[pRow * 4 + pCol] = ((aboveUSb[n]).val != null) ? (aboveUSb[n]).val[12 + pCol] : 127;
|
||||
vblock[pRow * 4 + pCol] = ((aboveVSb[n]).val != null) ? (aboveVSb[n]).val[12 + pCol] : 127;
|
||||
}
|
||||
}
|
||||
usb._predict = ublock;
|
||||
vsb._predict = vblock;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
leftUSb = new Subblock[2];
|
||||
leftVSb = new Subblock[2];
|
||||
for (m = 0; m < 2; m++) {
|
||||
leftUSb[m] = leftMb.uSubblocks[m][1];
|
||||
leftVSb[m] = leftMb.vSubblocks[m][1];
|
||||
}
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (int n = 0; n < 2; n++) {
|
||||
Subblock usb = this.uSubblocks[k][n];
|
||||
Subblock vsb = this.vSubblocks[k][n];
|
||||
int[] ublock = new int[16];
|
||||
int[] vblock = new int[16];
|
||||
for (int pRow = 0; pRow < 4; pRow++) {
|
||||
for (int pCol = 0; pCol < 4; pCol++) {
|
||||
ublock[pRow * 4 + pCol] = ((leftUSb[k]).val != null) ? (leftUSb[k]).val[pRow * 4 + 3] : 129;
|
||||
vblock[pRow * 4 + pCol] = ((leftVSb[k]).val != null) ? (leftVSb[k]).val[pRow * 4 + 3] : 129;
|
||||
}
|
||||
}
|
||||
usb._predict = ublock;
|
||||
vsb._predict = vblock;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ALMb = mbs[this.Rrow - 1][this.column - 1];
|
||||
ALUSb = ALMb.uSubblocks[1][1];
|
||||
alu = ALUSb.val[15];
|
||||
ALVSb = ALMb.vSubblocks[1][1];
|
||||
alv = ALVSb.val[15];
|
||||
aboveUSb = new Subblock[2];
|
||||
leftUSb = new Subblock[2];
|
||||
aboveVSb = new Subblock[2];
|
||||
leftVSb = new Subblock[2];
|
||||
for (x = 0; x < 2; x++) {
|
||||
aboveUSb[x] = aboveMb.uSubblocks[1][x];
|
||||
leftUSb[x] = leftMb.uSubblocks[x][1];
|
||||
aboveVSb[x] = aboveMb.vSubblocks[1][x];
|
||||
leftVSb[x] = leftMb.vSubblocks[x][1];
|
||||
}
|
||||
for (sbRow = 0; sbRow < 2; sbRow++) {
|
||||
for (int pRow = 0; pRow < 4; pRow++) {
|
||||
for (int sbCol = 0; sbCol < 2; sbCol++) {
|
||||
if ((this.uSubblocks[sbRow][sbCol]).val == null)
|
||||
(this.uSubblocks[sbRow][sbCol]).val = new int[16];
|
||||
if ((this.vSubblocks[sbRow][sbCol]).val == null)
|
||||
(this.vSubblocks[sbRow][sbCol]).val = new int[16];
|
||||
for (int pCol = 0; pCol < 4; pCol++) {
|
||||
int upred = (leftUSb[sbRow]).val[pRow * 4 + 3] + (aboveUSb[sbCol]).val[12 + pCol] - alu;
|
||||
upred = VP8Util.QuantizationParams.clip255(upred);
|
||||
(this.uSubblocks[sbRow][sbCol]).val[pRow * 4 + pCol] = upred;
|
||||
int vpred = (leftVSb[sbRow]).val[pRow * 4 + 3] + (aboveVSb[sbCol]).val[12 + pCol] - alv;
|
||||
vpred = VP8Util.QuantizationParams.clip255(vpred);
|
||||
(this.vSubblocks[sbRow][sbCol]).val[pRow * 4 + pCol] = vpred;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.err.println("TODO predict_mb_uv: " + this.lumaMode);
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void predictY(VPXMacroblock[][] mbs) {
|
||||
VPXMacroblock upperLeft;
|
||||
Subblock ALSb;
|
||||
int aboveLeft;
|
||||
VPXMacroblock aboveMb = mbs[this.Rrow - 1][this.column];
|
||||
VPXMacroblock leftMb = mbs[this.Rrow][this.column - 1];
|
||||
switch (this.lumaMode) {
|
||||
case 0:
|
||||
predictLumaDC(aboveMb, leftMb);
|
||||
break;
|
||||
case 1:
|
||||
predictLumaV(aboveMb);
|
||||
break;
|
||||
case 2:
|
||||
predictLumaH(leftMb);
|
||||
break;
|
||||
case 3:
|
||||
upperLeft = mbs[this.Rrow - 1][this.column - 1];
|
||||
ALSb = upperLeft.ySubblocks[3][3];
|
||||
aboveLeft = ALSb.val[15];
|
||||
predictLumaTM(aboveMb, leftMb, aboveLeft);
|
||||
break;
|
||||
default:
|
||||
System.err.println("TODO predict_mb_y: " + this.lumaMode);
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void predictLumaDC(VPXMacroblock above, VPXMacroblock left) {
|
||||
boolean hasAbove = (this.Rrow > 1);
|
||||
boolean hasLeft = (this.column > 1);
|
||||
int expected_dc = 128;
|
||||
if (hasAbove || hasLeft) {
|
||||
int average = 0;
|
||||
if (hasAbove)
|
||||
for (int j = 0; j < 4; j++) {
|
||||
Subblock sb = above.ySubblocks[3][j];
|
||||
for (int k = 0; k < 4; k++)
|
||||
average += sb.val[12 + k];
|
||||
}
|
||||
if (hasLeft)
|
||||
for (int j = 0; j < 4; j++) {
|
||||
Subblock sb = left.ySubblocks[j][3];
|
||||
for (int k = 0; k < 4; k++)
|
||||
average += sb.val[k * 4 + 3];
|
||||
}
|
||||
int shift = 3;
|
||||
if (hasAbove)
|
||||
shift++;
|
||||
if (hasLeft)
|
||||
shift++;
|
||||
expected_dc = average + (1 << shift - 1) >> shift;
|
||||
}
|
||||
int[] fill = new int[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
fill[i] = expected_dc;
|
||||
for (int y = 0; y < 4; y++) {
|
||||
for (int x = 0; x < 4; x++)
|
||||
(this.ySubblocks[y][x])._predict = fill;
|
||||
}
|
||||
}
|
||||
|
||||
private void predictLumaH(VPXMacroblock leftMb) {
|
||||
Subblock[] leftYSb = new Subblock[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
leftYSb[i] = leftMb.ySubblocks[i][3];
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
Subblock sb = this.ySubblocks[row][col];
|
||||
int[] block = new int[16];
|
||||
for (int bRow = 0; bRow < 4; bRow++) {
|
||||
for (int bCol = 0; bCol < 4; bCol++)
|
||||
block[bRow * 4 + bCol] = ((leftYSb[row]).val != null) ? (leftYSb[row]).val[bRow * 4 + 3] : 129;
|
||||
}
|
||||
sb._predict = block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void predictLumaTM(VPXMacroblock above, VPXMacroblock left, int aboveLeft) {
|
||||
Subblock[] aboveYSb = new Subblock[4];
|
||||
Subblock[] leftYSb = new Subblock[4];
|
||||
for (int col = 0; col < 4; col++)
|
||||
aboveYSb[col] = above.ySubblocks[3][col];
|
||||
for (int i = 0; i < 4; i++)
|
||||
leftYSb[i] = left.ySubblocks[i][3];
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int pRow = 0; pRow < 4; pRow++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if ((this.ySubblocks[row][j]).val == null)
|
||||
(this.ySubblocks[row][j]).val = new int[16];
|
||||
for (int pCol = 0; pCol < 4; pCol++) {
|
||||
int pred = (leftYSb[row]).val[pRow * 4 + 3] + (aboveYSb[j]).val[12 + pCol] - aboveLeft;
|
||||
(this.ySubblocks[row][j]).val[pRow * 4 + pCol] = VP8Util.QuantizationParams.clip255(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void predictLumaV(VPXMacroblock above) {
|
||||
Subblock[] aboveYSb = new Subblock[4];
|
||||
for (int col = 0; col < 4; col++)
|
||||
aboveYSb[col] = above.ySubblocks[3][col];
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Subblock sb = this.ySubblocks[row][i];
|
||||
int[] block = new int[16];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int k = 0; k < 4; k++)
|
||||
block[j * 4 + k] = ((aboveYSb[i]).val != null) ? (aboveYSb[i]).val[12 + k] : 127;
|
||||
}
|
||||
sb._predict = block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Subblock getBottomSubblock(int x, VP8Util.PLANE plane) {
|
||||
if (plane == VP8Util.PLANE.Y1)
|
||||
return this.ySubblocks[3][x];
|
||||
if (plane == VP8Util.PLANE.U)
|
||||
return this.uSubblocks[1][x];
|
||||
if (plane == VP8Util.PLANE.V)
|
||||
return this.vSubblocks[1][x];
|
||||
if (plane == VP8Util.PLANE.Y2)
|
||||
return this.y2;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Subblock getRightSubBlock(int y, VP8Util.PLANE plane) {
|
||||
if (plane == VP8Util.PLANE.Y1)
|
||||
return this.ySubblocks[y][3];
|
||||
if (plane == VP8Util.PLANE.U)
|
||||
return this.uSubblocks[y][1];
|
||||
if (plane == VP8Util.PLANE.V)
|
||||
return this.vSubblocks[y][1];
|
||||
if (plane == VP8Util.PLANE.Y2)
|
||||
return this.y2;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void decodeMacroBlock(VPXMacroblock[][] mbs, VPXBooleanDecoder tockenDecoder, int[][][][] coefProbs) {
|
||||
if (this.skipCoeff > 0) {
|
||||
this.skipFilter = (this.lumaMode != 4);
|
||||
} else if (this.lumaMode != 4) {
|
||||
decodeMacroBlockTokens(true, mbs, tockenDecoder, coefProbs);
|
||||
} else {
|
||||
decodeMacroBlockTokens(false, mbs, tockenDecoder, coefProbs);
|
||||
}
|
||||
}
|
||||
|
||||
private void decodeMacroBlockTokens(boolean withY2, VPXMacroblock[][] mbs, VPXBooleanDecoder decoder, int[][][][] coefProbs) {
|
||||
this.skipFilter = false;
|
||||
if (withY2)
|
||||
this.skipFilter |= decodePlaneTokens(1, VP8Util.PLANE.Y2, false, mbs, decoder, coefProbs);
|
||||
this.skipFilter |= decodePlaneTokens(4, VP8Util.PLANE.Y1, withY2, mbs, decoder, coefProbs);
|
||||
this.skipFilter |= decodePlaneTokens(2, VP8Util.PLANE.U, false, mbs, decoder, coefProbs);
|
||||
this.skipFilter |= decodePlaneTokens(2, VP8Util.PLANE.V, false, mbs, decoder, coefProbs);
|
||||
this.skipFilter = !this.skipFilter;
|
||||
}
|
||||
|
||||
private boolean decodePlaneTokens(int dimentions, VP8Util.PLANE plane, boolean withY2, VPXMacroblock[][] mbs, VPXBooleanDecoder decoder, int[][][][] coefProbs) {
|
||||
boolean r = false;
|
||||
for (int row = 0; row < dimentions; row++) {
|
||||
for (int col = 0; col < dimentions; col++) {
|
||||
int lc = 0;
|
||||
Subblock sb = null;
|
||||
if (VP8Util.PLANE.Y1.equals(plane)) {
|
||||
sb = this.ySubblocks[row][col];
|
||||
} else if (VP8Util.PLANE.U.equals(plane)) {
|
||||
sb = this.uSubblocks[row][col];
|
||||
} else if (VP8Util.PLANE.V.equals(plane)) {
|
||||
sb = this.vSubblocks[row][col];
|
||||
} else if (VP8Util.PLANE.Y2.equals(plane)) {
|
||||
sb = this.y2;
|
||||
} else {
|
||||
throw new IllegalStateException("unknown plane type " + String.valueOf(plane));
|
||||
}
|
||||
Subblock l = sb.getLeft(plane, mbs);
|
||||
Subblock a = sb.getAbove(plane, mbs);
|
||||
lc = (l.someValuePresent ? 1 : 0) + (a.someValuePresent ? 1 : 0);
|
||||
sb.decodeSubBlock(decoder, coefProbs, lc, VP8Util.planeToType(plane, Boolean.valueOf(withY2)), withY2);
|
||||
r |= sb.someValuePresent;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static class Subblock {
|
||||
public int[] val;
|
||||
|
||||
public int[] _predict;
|
||||
|
||||
public int[] residue;
|
||||
|
||||
private int col;
|
||||
|
||||
private int row;
|
||||
|
||||
private VP8Util.PLANE plane;
|
||||
|
||||
public int mode;
|
||||
|
||||
public boolean someValuePresent;
|
||||
|
||||
private int[] tokens;
|
||||
|
||||
private VPXMacroblock self;
|
||||
|
||||
public Subblock(VPXMacroblock self, int row, int col, VP8Util.PLANE plane) {
|
||||
this.self = self;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
this.plane = plane;
|
||||
this.tokens = new int[16];
|
||||
}
|
||||
|
||||
public void predict(VPXMacroblock[][] mbs) {
|
||||
int aboveLeft;
|
||||
Subblock aboveSb = getAbove(this.plane, mbs);
|
||||
Subblock leftSb = getLeft(this.plane, mbs);
|
||||
int[] above = new int[4];
|
||||
int[] left = new int[4];
|
||||
int[] aboveValues = (aboveSb.val != null) ? aboveSb.val : VP8Util.PRED_BLOCK_127;
|
||||
above[0] = aboveValues[12];
|
||||
above[1] = aboveValues[13];
|
||||
above[2] = aboveValues[14];
|
||||
above[3] = aboveValues[15];
|
||||
int[] leftValues = (leftSb.val != null) ? leftSb.val : VP8Util.pickDefaultPrediction(this.mode);
|
||||
left[0] = leftValues[3];
|
||||
left[1] = leftValues[7];
|
||||
left[2] = leftValues[11];
|
||||
left[3] = leftValues[15];
|
||||
Subblock aboveLeftSb = aboveSb.getLeft(this.plane, mbs);
|
||||
if (leftSb.val == null && aboveSb.val == null) {
|
||||
aboveLeft = 127;
|
||||
} else if (aboveSb.val == null) {
|
||||
aboveLeft = 127;
|
||||
} else {
|
||||
aboveLeft = (aboveLeftSb.val != null) ? aboveLeftSb.val[15] : VP8Util.pickDefaultPrediction(this.mode)[15];
|
||||
}
|
||||
int[] ar = getAboveRightLowestRow(mbs);
|
||||
switch (this.mode) {
|
||||
case 0:
|
||||
this._predict = VP8Util.predictDC(above, left);
|
||||
break;
|
||||
case 1:
|
||||
this._predict = VP8Util.predictTM(above, left, aboveLeft);
|
||||
break;
|
||||
case 2:
|
||||
this._predict = VP8Util.predictVE(above, aboveLeft, ar);
|
||||
break;
|
||||
case 3:
|
||||
this._predict = VP8Util.predictHE(left, aboveLeft);
|
||||
break;
|
||||
case 4:
|
||||
this._predict = VP8Util.predictLD(above, ar);
|
||||
break;
|
||||
case 5:
|
||||
this._predict = VP8Util.predictRD(above, left, aboveLeft);
|
||||
break;
|
||||
case 6:
|
||||
this._predict = VP8Util.predictVR(above, left, aboveLeft);
|
||||
break;
|
||||
case 7:
|
||||
this._predict = VP8Util.predictVL(above, ar);
|
||||
break;
|
||||
case 8:
|
||||
this._predict = VP8Util.predictHD(above, left, aboveLeft);
|
||||
break;
|
||||
case 9:
|
||||
this._predict = VP8Util.predictHU(left);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("TODO: unknowwn mode: " + this.mode);
|
||||
}
|
||||
}
|
||||
|
||||
public void reconstruct() {
|
||||
int[] p = (this.val != null) ? this.val : this._predict;
|
||||
int[] dest = new int[16];
|
||||
for (int aRow = 0; aRow < 4; aRow++) {
|
||||
for (int aCol = 0; aCol < 4; aCol++) {
|
||||
int a = VP8Util.QuantizationParams.clip255(this.residue[aRow * 4 + aCol] + p[aRow * 4 + aCol]);
|
||||
dest[aRow * 4 + aCol] = a;
|
||||
}
|
||||
}
|
||||
this.val = dest;
|
||||
}
|
||||
|
||||
public Subblock getAbove(VP8Util.PLANE plane, VPXMacroblock[][] mbs) {
|
||||
if (this.row > 0) {
|
||||
if (VP8Util.PLANE.Y1.equals(this.plane))
|
||||
return this.self.ySubblocks[this.row - 1][this.col];
|
||||
if (VP8Util.PLANE.U.equals(this.plane))
|
||||
return this.self.uSubblocks[this.row - 1][this.col];
|
||||
if (VP8Util.PLANE.V.equals(this.plane))
|
||||
return this.self.vSubblocks[this.row - 1][this.col];
|
||||
}
|
||||
int x = this.col;
|
||||
VPXMacroblock mb2 = mbs[this.self.Rrow - 1][this.self.column];
|
||||
if (plane == VP8Util.PLANE.Y2)
|
||||
while (mb2.lumaMode == 4)
|
||||
mb2 = mbs[mb2.Rrow - 1][mb2.column];
|
||||
return mb2.getBottomSubblock(x, plane);
|
||||
}
|
||||
|
||||
public Subblock getLeft(VP8Util.PLANE p, VPXMacroblock[][] mbs) {
|
||||
if (this.col > 0) {
|
||||
if (VP8Util.PLANE.Y1.equals(this.plane))
|
||||
return this.self.ySubblocks[this.row][this.col - 1];
|
||||
if (VP8Util.PLANE.U.equals(this.plane))
|
||||
return this.self.uSubblocks[this.row][this.col - 1];
|
||||
if (VP8Util.PLANE.V.equals(this.plane))
|
||||
return this.self.vSubblocks[this.row][this.col - 1];
|
||||
}
|
||||
int y = this.row;
|
||||
VPXMacroblock mb2 = mbs[this.self.Rrow][this.self.column - 1];
|
||||
if (p == VP8Util.PLANE.Y2)
|
||||
while (mb2.lumaMode == 4)
|
||||
mb2 = mbs[mb2.Rrow][mb2.column - 1];
|
||||
return mb2.getRightSubBlock(y, p);
|
||||
}
|
||||
|
||||
private int[] getAboveRightLowestRow(VPXMacroblock[][] mbs) {
|
||||
int[] aboveRightDistValues;
|
||||
if (!VP8Util.PLANE.Y1.equals(this.plane))
|
||||
throw new NotImplementedException("Decoder.getAboveRight: not implemented for Y2 and chroma planes");
|
||||
if (this.row == 0 && this.col < 3) {
|
||||
VPXMacroblock mb2 = mbs[this.self.Rrow - 1][this.self.column];
|
||||
Subblock aboveRight = mb2.ySubblocks[3][this.col + 1];
|
||||
aboveRightDistValues = aboveRight.val;
|
||||
} else if (this.row > 0 && this.col < 3) {
|
||||
Subblock aboveRight = this.self.ySubblocks[this.row - 1][this.col + 1];
|
||||
aboveRightDistValues = aboveRight.val;
|
||||
} else if (this.row == 0 && this.col == 3) {
|
||||
VPXMacroblock aboveRightMb = mbs[this.self.Rrow - 1][this.self.column + 1];
|
||||
if (aboveRightMb.column < (mbs[0]).length - 1) {
|
||||
Subblock aboveRightSb = aboveRightMb.ySubblocks[3][0];
|
||||
aboveRightDistValues = aboveRightSb.val;
|
||||
} else {
|
||||
aboveRightDistValues = new int[16];
|
||||
int fillVal = (aboveRightMb.Rrow == 0) ? 127 : ((mbs[this.self.Rrow - 1][this.self.column]).ySubblocks[3][3]).val[15];
|
||||
Arrays.fill(aboveRightDistValues, fillVal);
|
||||
}
|
||||
} else {
|
||||
Subblock sb2 = this.self.ySubblocks[0][3];
|
||||
return sb2.getAboveRightLowestRow(mbs);
|
||||
}
|
||||
if (aboveRightDistValues == null)
|
||||
aboveRightDistValues = VP8Util.PRED_BLOCK_127;
|
||||
int[] ar = new int[4];
|
||||
ar[0] = aboveRightDistValues[12];
|
||||
ar[1] = aboveRightDistValues[13];
|
||||
ar[2] = aboveRightDistValues[14];
|
||||
ar[3] = aboveRightDistValues[15];
|
||||
return ar;
|
||||
}
|
||||
|
||||
public void decodeSubBlock(VPXBooleanDecoder decoder, int[][][][] allProbs, int ilc, int type, boolean withY2) {
|
||||
int startAt = 0;
|
||||
if (withY2)
|
||||
startAt = 1;
|
||||
int lc = ilc;
|
||||
int count = 0;
|
||||
int v = 1;
|
||||
boolean skip = false;
|
||||
this.someValuePresent = false;
|
||||
while (v != 11 && count + startAt < 16) {
|
||||
int[] probs = allProbs[type][VP8Util.SubblockConstants.vp8CoefBands[count + startAt]][lc];
|
||||
if (!skip) {
|
||||
v = decoder.readTree(VP8Util.SubblockConstants.vp8CoefTree, probs);
|
||||
} else {
|
||||
v = decoder.readTreeSkip(VP8Util.SubblockConstants.vp8CoefTree, probs, 1);
|
||||
}
|
||||
int dv = decodeToken(decoder, v);
|
||||
lc = 0;
|
||||
skip = false;
|
||||
if (dv == 1 || dv == -1) {
|
||||
lc = 1;
|
||||
} else if (dv > 1 || dv < -1) {
|
||||
lc = 2;
|
||||
} else if (dv == 0) {
|
||||
skip = true;
|
||||
}
|
||||
if (v != 11)
|
||||
this.tokens[VP8Util.SubblockConstants.vp8defaultZigZag1d[count + startAt]] = dv;
|
||||
count++;
|
||||
}
|
||||
for (int x = 0; x < 16; x++) {
|
||||
if (this.tokens[x] != 0)
|
||||
this.someValuePresent = true;
|
||||
}
|
||||
}
|
||||
|
||||
private int decodeToken(VPXBooleanDecoder decoder, int initialValue) {
|
||||
int token = initialValue;
|
||||
if (initialValue == 5)
|
||||
token = 5 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat1);
|
||||
if (initialValue == 6)
|
||||
token = 7 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat2);
|
||||
if (initialValue == 7)
|
||||
token = 11 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat3);
|
||||
if (initialValue == 8)
|
||||
token = 19 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat4);
|
||||
if (initialValue == 9)
|
||||
token = 35 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat5);
|
||||
if (initialValue == 10)
|
||||
token = 67 + DCTextra(decoder, VP8Util.SubblockConstants.Pcat6);
|
||||
if (initialValue != 0 && initialValue != 11 &&
|
||||
decoder.readBitEq() > 0)
|
||||
token = -token;
|
||||
return token;
|
||||
}
|
||||
|
||||
private int DCTextra(VPXBooleanDecoder decoder, int[] p) {
|
||||
int v = 0;
|
||||
int offset = 0;
|
||||
while (true) {
|
||||
v += v + decoder.readBit(p[offset]);
|
||||
offset++;
|
||||
if (p[offset] <= 0)
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
public void dequantSubblock(int dc, int ac, Integer Dc) {
|
||||
int[] adjustedValues = new int[16];
|
||||
adjustedValues[0] = this.tokens[0] * dc;
|
||||
for (int i = 1; i < 16; i++)
|
||||
adjustedValues[i] = this.tokens[i] * ac;
|
||||
if (Dc != null)
|
||||
adjustedValues[0] = Dc;
|
||||
this.residue = VP8DCT.decodeDCT(adjustedValues);
|
||||
}
|
||||
}
|
||||
|
||||
public void put(int mbRow, int mbCol, Picture p) {
|
||||
byte[] luma = p.getPlaneData(0);
|
||||
byte[] cb = p.getPlaneData(1);
|
||||
byte[] cr = p.getPlaneData(2);
|
||||
int strideLuma = p.getPlaneWidth(0);
|
||||
int strideChroma = p.getPlaneWidth(1);
|
||||
for (int lumaRow = 0; lumaRow < 4; lumaRow++) {
|
||||
for (int lumaCol = 0; lumaCol < 4; lumaCol++) {
|
||||
for (int lumaPRow = 0; lumaPRow < 4; lumaPRow++) {
|
||||
for (int lumaPCol = 0; lumaPCol < 4; lumaPCol++) {
|
||||
int y = (mbRow << 4) + (lumaRow << 2) + lumaPRow;
|
||||
int x = (mbCol << 4) + (lumaCol << 2) + lumaPCol;
|
||||
if (x < strideLuma && y < luma.length / strideLuma) {
|
||||
int yy = (this.ySubblocks[lumaRow][lumaCol]).val[lumaPRow * 4 + lumaPCol];
|
||||
luma[strideLuma * y + x] = (byte)(yy - 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int chromaRow = 0; chromaRow < 2; chromaRow++) {
|
||||
for (int chromaCol = 0; chromaCol < 2; chromaCol++) {
|
||||
for (int chromaPRow = 0; chromaPRow < 4; chromaPRow++) {
|
||||
for (int chromaPCol = 0; chromaPCol < 4; chromaPCol++) {
|
||||
int y = (mbRow << 3) + (chromaRow << 2) + chromaPRow;
|
||||
int x = (mbCol << 3) + (chromaCol << 2) + chromaPCol;
|
||||
if (x < strideChroma && y < cb.length / strideChroma) {
|
||||
int u = (this.uSubblocks[chromaRow][chromaCol]).val[chromaPRow * 4 + chromaPCol];
|
||||
int v = (this.vSubblocks[chromaRow][chromaCol]).val[chromaPRow * 4 + chromaPCol];
|
||||
cb[strideChroma * y + x] = (byte)(u - 128);
|
||||
cr[strideChroma * y + x] = (byte)(v - 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package org.jcodec.codecs.vpx;
|
||||
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class VPXQuantizer {
|
||||
private int y1_dc_delta_q;
|
||||
|
||||
private int uv_dc_delta_q;
|
||||
|
||||
private int uv_ac_delta_q;
|
||||
|
||||
private int y2_dc_delta_q;
|
||||
|
||||
private int y2_ac_delta_q;
|
||||
|
||||
public final void quantizeY(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.y1_dc_delta_q], 8, 132);
|
||||
int invFactAC = MathUtil.clip(VPXConst.ac_qlookup[qp], 8, 132);
|
||||
quantize(coeffs, factDC, invFactAC);
|
||||
}
|
||||
|
||||
public final void quantizeUV(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.uv_dc_delta_q], 8, 132);
|
||||
int invFactAC = MathUtil.clip(VPXConst.ac_qlookup[qp + this.uv_ac_delta_q], 8, 132);
|
||||
quantize(coeffs, factDC, invFactAC);
|
||||
}
|
||||
|
||||
public final void quantizeY2(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.y2_dc_delta_q] * 2, 8, 132);
|
||||
int invFactAC = MathUtil.clip(VPXConst.ac_qlookup[qp + this.y2_ac_delta_q] * 155 / 100, 8, 132);
|
||||
quantize(coeffs, factDC, invFactAC);
|
||||
}
|
||||
|
||||
private final void quantize(int[] coeffs, int factDC, int factAC) {
|
||||
coeffs[0] = coeffs[0] / factDC;
|
||||
for (int i = 1; i < 16; i++)
|
||||
coeffs[i] = coeffs[i] / factAC;
|
||||
}
|
||||
|
||||
public final void dequantizeY(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.y1_dc_delta_q], 8, 132);
|
||||
int factAC = MathUtil.clip(VPXConst.ac_qlookup[qp], 8, 132);
|
||||
dequantize(coeffs, factDC, factAC);
|
||||
}
|
||||
|
||||
public final void dequantizeUV(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.uv_dc_delta_q], 8, 132);
|
||||
int factAC = MathUtil.clip(VPXConst.ac_qlookup[qp + this.uv_ac_delta_q], 8, 132);
|
||||
dequantize(coeffs, factDC, factAC);
|
||||
}
|
||||
|
||||
public final void dequantizeY2(int[] coeffs, int qp) {
|
||||
int factDC = MathUtil.clip(VPXConst.dc_qlookup[qp + this.y2_dc_delta_q] * 2, 8, 132);
|
||||
int factAC = MathUtil.clip(VPXConst.ac_qlookup[qp + this.y2_ac_delta_q] * 155 / 100, 8, 132);
|
||||
dequantize(coeffs, factDC, factAC);
|
||||
}
|
||||
|
||||
private final void dequantize(int[] coeffs, int factDC, int factAC) {
|
||||
coeffs[0] = coeffs[0] * factDC;
|
||||
for (int i = 1; i < 16; i++)
|
||||
coeffs[i] = coeffs[i] * factAC;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
import org.jcodec.codecs.vpx.VPXBooleanDecoder;
|
||||
|
||||
public class CodedBlock {
|
||||
public static final CodedBlock[] EMPTY_ARR = new CodedBlock[0];
|
||||
|
||||
private ModeInfo mode;
|
||||
|
||||
private Residual residual;
|
||||
|
||||
public CodedBlock(ModeInfo mode, Residual r) {
|
||||
this.mode = mode;
|
||||
this.residual = r;
|
||||
}
|
||||
|
||||
public ModeInfo getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public Residual getResidual() {
|
||||
return this.residual;
|
||||
}
|
||||
|
||||
public static CodedBlock read(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
ModeInfo mode;
|
||||
if (c.isKeyIntraFrame()) {
|
||||
mode = new ModeInfo().read(miCol, miRow, blSz, decoder, c);
|
||||
} else {
|
||||
mode = new InterModeInfo().read(miCol, miRow, blSz, decoder, c);
|
||||
}
|
||||
Residual r = Residual.readResidual(miCol, miRow, blSz, decoder, c, mode);
|
||||
return new CodedBlock(mode, r);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jcodec.codecs.vpx.VPXBooleanDecoder;
|
||||
|
||||
public class CodedSuperBlock {
|
||||
private CodedBlock[] codedBlocks;
|
||||
|
||||
public CodedSuperBlock(CodedBlock[] codedBlocks) {
|
||||
this.codedBlocks = codedBlocks;
|
||||
}
|
||||
|
||||
protected CodedSuperBlock() {}
|
||||
|
||||
public CodedBlock[] getCodedBlocks() {
|
||||
return this.codedBlocks;
|
||||
}
|
||||
|
||||
public static CodedSuperBlock read(int miCol, int miRow, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
List<CodedBlock> blocks = new ArrayList<>();
|
||||
CodedSuperBlock result = new CodedSuperBlock();
|
||||
result.readSubPartition(miCol, miRow, 3, decoder, c, blocks);
|
||||
result.codedBlocks = blocks.<CodedBlock>toArray(CodedBlock.EMPTY_ARR);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected CodedBlock readBlock(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
return CodedBlock.read(miCol, miRow, blSz, decoder, c);
|
||||
}
|
||||
|
||||
protected void readSubPartition(int miCol, int miRow, int logBlkSize, VPXBooleanDecoder decoder, DecodingContext c, List<CodedBlock> blocks) {
|
||||
int part = readPartition(miCol, miRow, logBlkSize, decoder, c);
|
||||
int nextBlkSize = 1 << logBlkSize >> 1;
|
||||
if (logBlkSize > 0) {
|
||||
if (part == 0) {
|
||||
CodedBlock blk = readBlock(miCol, miRow, Consts.blSizeLookup[1 + logBlkSize][1 + logBlkSize], decoder, c);
|
||||
blocks.add(blk);
|
||||
saveAboveSizes(miCol, 1 + logBlkSize, c);
|
||||
saveLeftSizes(miRow, 1 + logBlkSize, c);
|
||||
} else if (part == 1) {
|
||||
CodedBlock blk = readBlock(miCol, miRow, Consts.blSizeLookup[1 + logBlkSize][logBlkSize], decoder, c);
|
||||
blocks.add(blk);
|
||||
saveAboveSizes(miCol, 1 + logBlkSize, c);
|
||||
saveLeftSizes(miRow, logBlkSize, c);
|
||||
if (miRow + nextBlkSize < c.getMiTileHeight()) {
|
||||
blk = readBlock(miCol, miRow + nextBlkSize, Consts.blSizeLookup[1 + logBlkSize][logBlkSize], decoder, c);
|
||||
blocks.add(blk);
|
||||
saveLeftSizes(miRow + nextBlkSize, logBlkSize, c);
|
||||
}
|
||||
} else if (part == 2) {
|
||||
CodedBlock blk = readBlock(miCol, miRow, Consts.blSizeLookup[logBlkSize][1 + logBlkSize], decoder, c);
|
||||
blocks.add(blk);
|
||||
saveLeftSizes(miRow, 1 + logBlkSize, c);
|
||||
saveAboveSizes(miCol, logBlkSize, c);
|
||||
if (miCol + nextBlkSize < c.getMiTileWidth()) {
|
||||
blk = readBlock(miCol + nextBlkSize, miRow, Consts.blSizeLookup[logBlkSize][1 + logBlkSize], decoder, c);
|
||||
blocks.add(blk);
|
||||
saveAboveSizes(miCol + nextBlkSize, logBlkSize, c);
|
||||
}
|
||||
} else {
|
||||
readSubPartition(miCol, miRow, logBlkSize - 1, decoder, c, blocks);
|
||||
if (miCol + nextBlkSize < c.getMiTileWidth())
|
||||
readSubPartition(miCol + nextBlkSize, miRow, logBlkSize - 1, decoder, c, blocks);
|
||||
if (miRow + nextBlkSize < c.getMiTileHeight())
|
||||
readSubPartition(miCol, miRow + nextBlkSize, logBlkSize - 1, decoder, c, blocks);
|
||||
if (miCol + nextBlkSize < c.getMiTileWidth() && miRow + nextBlkSize < c.getMiTileHeight())
|
||||
readSubPartition(miCol + nextBlkSize, miRow + nextBlkSize, logBlkSize - 1, decoder, c, blocks);
|
||||
}
|
||||
} else {
|
||||
int subBlSz = Consts.sub8x8PartitiontoBlockType[part];
|
||||
CodedBlock blk = readBlock(miCol, miRow, subBlSz, decoder, c);
|
||||
blocks.add(blk);
|
||||
saveAboveSizes(miCol, 1 + logBlkSize - ((subBlSz == 0 || subBlSz == 1) ? 1 : 0), c);
|
||||
saveLeftSizes(miRow, 1 + logBlkSize - ((subBlSz == 0 || subBlSz == 2) ? 1 : 0), c);
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveLeftSizes(int miRow, int blkSize4x4, DecodingContext c) {
|
||||
int blkSize8x8 = (blkSize4x4 == 0) ? 0 : (blkSize4x4 - 1);
|
||||
int miBlkSize = 1 << blkSize8x8;
|
||||
int[] leftSizes = c.getLeftPartitionSizes();
|
||||
for (int i = 0; i < miBlkSize; i++)
|
||||
leftSizes[miRow % 8 + i] = blkSize4x4;
|
||||
}
|
||||
|
||||
private static void saveAboveSizes(int miCol, int blkSize4x4, DecodingContext c) {
|
||||
int blkSize8x8 = (blkSize4x4 == 0) ? 0 : (blkSize4x4 - 1);
|
||||
int miBlkSize = 1 << blkSize8x8;
|
||||
int[] aboveSizes = c.getAbovePartitionSizes();
|
||||
for (int i = 0; i < miBlkSize; i++)
|
||||
aboveSizes[miCol + i] = blkSize4x4;
|
||||
}
|
||||
|
||||
protected static int readPartition(int miCol, int miRow, int blkSize, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx = calcPartitionContext(miCol, miRow, blkSize, c);
|
||||
int[] probs = c.getPartitionProbs()[ctx];
|
||||
int halfBlk = 1 << blkSize >> 1;
|
||||
boolean rightEdge = (miCol + halfBlk >= c.getMiTileWidth());
|
||||
boolean bottomEdge = (miRow + halfBlk >= c.getMiTileHeight());
|
||||
if (rightEdge && bottomEdge)
|
||||
return 3;
|
||||
if (rightEdge)
|
||||
return (decoder.readBit(probs[2]) == 1) ? 3 : 2;
|
||||
if (bottomEdge)
|
||||
return (decoder.readBit(probs[1]) == 1) ? 3 : 1;
|
||||
return decoder.readTree(Consts.TREE_PARTITION, probs);
|
||||
}
|
||||
|
||||
private static int calcPartitionContext(int miCol, int miRow, int blkSize, DecodingContext c) {
|
||||
boolean left = false, above = false;
|
||||
int[] aboveSizes = c.getAbovePartitionSizes();
|
||||
above = (aboveSizes[miCol] <= blkSize);
|
||||
int[] leftSizes = c.getLeftPartitionSizes();
|
||||
left |= (leftSizes[miRow % 8] <= blkSize) ? true : false;
|
||||
return blkSize * 4 + (left ? 2 : 0) + (above ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,568 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
public class Consts {
|
||||
public static final int KEY_FRAME = 0;
|
||||
|
||||
public static final int INTER_FRAME = 1;
|
||||
|
||||
public static final int ONLY_4X4 = 0;
|
||||
|
||||
public static final int ALLOW_8X8 = 1;
|
||||
|
||||
public static final int ALLOW_16X16 = 2;
|
||||
|
||||
public static final int ALLOW_32X32 = 3;
|
||||
|
||||
public static final int TX_MODE_SELECT = 4;
|
||||
|
||||
public static final int PARTITION_NONE = 0;
|
||||
|
||||
public static final int PARTITION_HORZ = 1;
|
||||
|
||||
public static final int PARTITION_VERT = 2;
|
||||
|
||||
public static final int PARTITION_SPLIT = 3;
|
||||
|
||||
public static final int BLOCK_INVALID = -1;
|
||||
|
||||
public static final int BLOCK_4X4 = 0;
|
||||
|
||||
public static final int BLOCK_4X8 = 1;
|
||||
|
||||
public static final int BLOCK_8X4 = 2;
|
||||
|
||||
public static final int BLOCK_8X8 = 3;
|
||||
|
||||
public static final int BLOCK_8X16 = 4;
|
||||
|
||||
public static final int BLOCK_16X8 = 5;
|
||||
|
||||
public static final int BLOCK_16X16 = 6;
|
||||
|
||||
public static final int BLOCK_16X32 = 7;
|
||||
|
||||
public static final int BLOCK_32X16 = 8;
|
||||
|
||||
public static final int BLOCK_32X32 = 9;
|
||||
|
||||
public static final int BLOCK_32X64 = 10;
|
||||
|
||||
public static final int BLOCK_64X32 = 11;
|
||||
|
||||
public static final int BLOCK_64X64 = 12;
|
||||
|
||||
public static final int TX_4X4 = 0;
|
||||
|
||||
public static final int TX_8X8 = 1;
|
||||
|
||||
public static final int TX_16X16 = 2;
|
||||
|
||||
public static final int TX_32X32 = 3;
|
||||
|
||||
public static final int INTRA_FRAME = 0;
|
||||
|
||||
public static final int LAST_FRAME = 1;
|
||||
|
||||
public static final int ALTREF_FRAME = 2;
|
||||
|
||||
public static final int GOLDEN_FRAME = 3;
|
||||
|
||||
public static final int DC_PRED = 0;
|
||||
|
||||
public static final int V_PRED = 1;
|
||||
|
||||
public static final int H_PRED = 2;
|
||||
|
||||
public static final int D45_PRED = 3;
|
||||
|
||||
public static final int D135_PRED = 4;
|
||||
|
||||
public static final int D117_PRED = 5;
|
||||
|
||||
public static final int D153_PRED = 6;
|
||||
|
||||
public static final int D207_PRED = 7;
|
||||
|
||||
public static final int D63_PRED = 8;
|
||||
|
||||
public static final int TM_PRED = 9;
|
||||
|
||||
public static final int NEARESTMV = 10;
|
||||
|
||||
public static final int NEARMV = 11;
|
||||
|
||||
public static final int ZEROMV = 12;
|
||||
|
||||
public static final int NEWMV = 13;
|
||||
|
||||
public static final int SINGLE_REF = 0;
|
||||
|
||||
public static final int COMPOUND_REF = 1;
|
||||
|
||||
public static final int REFERENCE_MODE_SELECT = 2;
|
||||
|
||||
public static final int NORMAL = 0;
|
||||
|
||||
public static final int SMOOTH = 1;
|
||||
|
||||
public static final int SHARP = 2;
|
||||
|
||||
public static final int SWITCHABLE = 3;
|
||||
|
||||
public static final int MV_JOINT_ZERO = 0;
|
||||
|
||||
public static final int MV_JOINT_HNZVZ = 1;
|
||||
|
||||
public static final int MV_JOINT_HZVNZ = 2;
|
||||
|
||||
public static final int MV_JOINT_HNZVNZ = 3;
|
||||
|
||||
public static final int ZERO_TOKEN = 0;
|
||||
|
||||
public static final int ONE_TOKEN = 1;
|
||||
|
||||
public static final int TWO_TOKEN = 2;
|
||||
|
||||
public static final int THREE_TOKEN = 3;
|
||||
|
||||
public static final int FOUR_TOKEN = 4;
|
||||
|
||||
public static final int DCT_VAL_CAT1 = 5;
|
||||
|
||||
public static final int DCT_VAL_CAT2 = 6;
|
||||
|
||||
public static final int DCT_VAL_CAT3 = 7;
|
||||
|
||||
public static final int DCT_VAL_CAT4 = 8;
|
||||
|
||||
public static final int DCT_VAL_CAT5 = 9;
|
||||
|
||||
public static final int DCT_VAL_CAT6 = 10;
|
||||
|
||||
public static final int[] TREE_SEGMENT_ID = new int[] {
|
||||
2, 4, 6, 8, 10, 12, 0, -1, -2, -3,
|
||||
-4, -5, -6, -7 };
|
||||
|
||||
public static final int[][] TREE_TX_SIZE = new int[][] { null, new int[] { 0, -1 }, new int[] { 0, 2, -1, -2 }, new int[] { 0, 2, -1, 4, -2, -3 } };
|
||||
|
||||
public static final int[] maxTxLookup = new int[] {
|
||||
0, 0, 0, 1, 1, 1, 2, 2, 2, 3,
|
||||
3, 3, 3 };
|
||||
|
||||
public static final int[] blW = new int[] {
|
||||
1, 1, 1, 1, 1, 2, 2, 2, 4, 4,
|
||||
4, 8, 8 };
|
||||
|
||||
public static final int[] blH = new int[] {
|
||||
1, 1, 1, 1, 2, 1, 2, 4, 2, 4,
|
||||
8, 4, 8 };
|
||||
|
||||
public static final int[] TREE_INTRA_MODE = new int[] {
|
||||
0, 2, -9, 4, -1, 6, 8, 12, -2, 10,
|
||||
-4, -5, -3, 14, -8, 16, -6, -7 };
|
||||
|
||||
public static final int[] size_group_lookup = new int[] {
|
||||
0, 0, 0, 1, 1, 1, 2, 2, 2, 3,
|
||||
3, 3, 3 };
|
||||
|
||||
public static final int[] TREE_INTERP_FILTER = new int[] { 0, 2, -1, -2 };
|
||||
|
||||
public static final int[] TREE_INTER_MODE = new int[] { -2, 2, 0, 4, -1, -3 };
|
||||
|
||||
public static final int[][] mv_ref_blocks_sm = new int[][] {
|
||||
new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 1, 0 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 1, 0 }, new int[] { 0, 1 }, new int[] { 2, 3 },
|
||||
new int[] { 1, 0 }, new int[] { 0, 1 }, new int[] { 4, 5 } };
|
||||
|
||||
public static final int[][] mv_ref_blocks = new int[][] {
|
||||
new int[] { 0, 1, 11, 12, 13, 16, 17, 18 }, new int[] { 0, 1, 11, 12, 13, 16, 17, 18 }, new int[] { 0, 1, 11, 12, 13, 16, 17, 18 }, new int[] { 0, 1, 11, 12, 13, 16, 17, 18 }, new int[] { 1, 0, 3, 11, 13, 12, 16, 17 }, new int[] { 0, 1, 2, 11, 12, 13, 17, 16 }, new int[] { 0, 1, 2, 3, 11, 14, 15, 19 }, new int[] { 1, 0, 7, 11, 2, 15, 14, 19 }, new int[] { 0, 1, 6, 11, 3, 14, 15, 19 }, new int[] { 2, 3, 6, 7, 11, 14, 15, 19 },
|
||||
new int[] { 1, 0, 9, 6, 11, 15, 14, 7 }, new int[] { 0, 1, 8, 7, 11, 14, 15, 6 }, new int[] { 4, 5, 8, 9, 11, 0, 1, 10 } };
|
||||
|
||||
public static final int[] TREE_MV_JOINT = new int[] { 0, 2, -1, 4, -2, -3 };
|
||||
|
||||
public static final int[] MV_CLASS_TREE = new int[] {
|
||||
0, 2, -1, 4, 6, 8, -2, -3, 10, 12,
|
||||
-4, -5, -6, 14, 16, 18, -7, -8, -9, -10 };
|
||||
|
||||
public static final int[] MV_FR_TREE = new int[] { 0, 2, -1, 4, -2, -3 };
|
||||
|
||||
public static final int[] LITERAL_TO_FILTER_TYPE = new int[] { 1, 0, 2, 3 };
|
||||
|
||||
public static final int[][] PARETO_TABLE = new int[][] {
|
||||
new int[] { 3, 86, 128, 6, 86, 23, 88, 29 }, new int[] { 6, 86, 128, 11, 87, 42, 91, 52 }, new int[] { 9, 86, 129, 17, 88, 61, 94, 76 }, new int[] { 12, 86, 129, 22, 88, 77, 97, 93 }, new int[] { 15, 87, 129, 28, 89, 93, 100, 110 }, new int[] { 17, 87, 129, 33, 90, 105, 103, 123 }, new int[] { 20, 88, 130, 38, 91, 118, 106, 136 }, new int[] { 23, 88, 130, 43, 91, 128, 108, 146 }, new int[] { 26, 89, 131, 48, 92, 139, 111, 156 }, new int[] { 28, 89, 131, 53, 93, 147, 114, 163 },
|
||||
new int[] { 31, 90, 131, 58, 94, 156, 117, 171 }, new int[] { 34, 90, 131, 62, 94, 163, 119, 177 }, new int[] { 37, 90, 132, 66, 95, 171, 122, 184 }, new int[] { 39, 90, 132, 70, 96, 177, 124, 189 }, new int[] { 42, 91, 132, 75, 97, 183, 127, 194 }, new int[] { 44, 91, 132, 79, 97, 188, 129, 198 }, new int[] { 47, 92, 133, 83, 98, 193, 132, 202 }, new int[] { 49, 92, 133, 86, 99, 197, 134, 205 }, new int[] { 52, 93, 133, 90, 100, 201, 137, 208 }, new int[] { 54, 93, 133, 94, 100, 204, 139, 211 },
|
||||
new int[] { 57, 94, 134, 98, 101, 208, 142, 214 }, new int[] { 59, 94, 134, 101, 102, 211, 144, 216 }, new int[] { 62, 94, 135, 105, 103, 214, 146, 218 }, new int[] { 64, 94, 135, 108, 103, 216, 148, 220 }, new int[] { 66, 95, 135, 111, 104, 219, 151, 222 }, new int[] { 68, 95, 135, 114, 105, 221, 153, 223 }, new int[] { 71, 96, 136, 117, 106, 224, 155, 225 }, new int[] { 73, 96, 136, 120, 106, 225, 157, 226 }, new int[] { 76, 97, 136, 123, 107, 227, 159, 228 }, new int[] { 78, 97, 136, 126, 108, 229, 160, 229 },
|
||||
new int[] { 80, 98, 137, 129, 109, 231, 162, 231 }, new int[] { 82, 98, 137, 131, 109, 232, 164, 232 }, new int[] { 84, 98, 138, 134, 110, 234, 166, 233 }, new int[] { 86, 98, 138, 137, 111, 235, 168, 234 }, new int[] { 89, 99, 138, 140, 112, 236, 170, 235 }, new int[] { 91, 99, 138, 142, 112, 237, 171, 235 }, new int[] { 93, 100, 139, 145, 113, 238, 173, 236 }, new int[] { 95, 100, 139, 147, 114, 239, 174, 237 }, new int[] { 97, 101, 140, 149, 115, 240, 176, 238 }, new int[] { 99, 101, 140, 151, 115, 241, 177, 238 },
|
||||
new int[] { 101, 102, 140, 154, 116, 242, 179, 239 }, new int[] { 103, 102, 140, 156, 117, 242, 180, 239 }, new int[] { 105, 103, 141, 158, 118, 243, 182, 240 }, new int[] { 107, 103, 141, 160, 118, 243, 183, 240 }, new int[] { 109, 104, 141, 162, 119, 244, 185, 241 }, new int[] { 111, 104, 141, 164, 119, 244, 186, 241 }, new int[] { 113, 104, 142, 166, 120, 245, 187, 242 }, new int[] { 114, 104, 142, 168, 121, 245, 188, 242 }, new int[] { 116, 105, 143, 170, 122, 246, 190, 243 }, new int[] { 118, 105, 143, 171, 122, 246, 191, 243 },
|
||||
new int[] { 120, 106, 143, 173, 123, 247, 192, 244 }, new int[] { 121, 106, 143, 175, 124, 247, 193, 244 }, new int[] { 123, 107, 144, 177, 125, 248, 195, 244 }, new int[] { 125, 107, 144, 178, 125, 248, 196, 244 }, new int[] { 127, 108, 145, 180, 126, 249, 197, 245 }, new int[] { 128, 108, 145, 181, 127, 249, 198, 245 }, new int[] { 130, 109, 145, 183, 128, 249, 199, 245 }, new int[] { 132, 109, 145, 184, 128, 249, 200, 245 }, new int[] { 134, 110, 146, 186, 129, 250, 201, 246 }, new int[] { 135, 110, 146, 187, 130, 250, 202, 246 },
|
||||
new int[] { 137, 111, 147, 189, 131, 251, 203, 246 }, new int[] { 138, 111, 147, 190, 131, 251, 204, 246 }, new int[] { 140, 112, 147, 192, 132, 251, 205, 247 }, new int[] { 141, 112, 147, 193, 132, 251, 206, 247 }, new int[] { 143, 113, 148, 194, 133, 251, 207, 247 }, new int[] { 144, 113, 148, 195, 134, 251, 207, 247 }, new int[] { 146, 114, 149, 197, 135, 252, 208, 248 }, new int[] { 147, 114, 149, 198, 135, 252, 209, 248 }, new int[] { 149, 115, 149, 199, 136, 252, 210, 248 }, new int[] { 150, 115, 149, 200, 137, 252, 210, 248 },
|
||||
new int[] { 152, 115, 150, 201, 138, 252, 211, 248 }, new int[] { 153, 115, 150, 202, 138, 252, 212, 248 }, new int[] { 155, 116, 151, 204, 139, 253, 213, 249 }, new int[] { 156, 116, 151, 205, 139, 253, 213, 249 }, new int[] { 158, 117, 151, 206, 140, 253, 214, 249 }, new int[] { 159, 117, 151, 207, 141, 253, 215, 249 }, new int[] { 161, 118, 152, 208, 142, 253, 216, 249 }, new int[] { 162, 118, 152, 209, 142, 253, 216, 249 }, new int[] { 163, 119, 153, 210, 143, 253, 217, 249 }, new int[] { 164, 119, 153, 211, 143, 253, 217, 249 },
|
||||
new int[] { 166, 120, 153, 212, 144, 254, 218, 250 }, new int[] { 167, 120, 153, 212, 145, 254, 219, 250 }, new int[] { 168, 121, 154, 213, 146, 254, 220, 250 }, new int[] { 169, 121, 154, 214, 146, 254, 220, 250 }, new int[] { 171, 122, 155, 215, 147, 254, 221, 250 }, new int[] { 172, 122, 155, 216, 147, 254, 221, 250 }, new int[] { 173, 123, 155, 217, 148, 254, 222, 250 }, new int[] { 174, 123, 155, 217, 149, 254, 222, 250 }, new int[] { 176, 124, 156, 218, 150, 254, 223, 250 }, new int[] { 177, 124, 156, 219, 150, 254, 223, 250 },
|
||||
new int[] { 178, 125, 157, 220, 151, 254, 224, 251 }, new int[] { 179, 125, 157, 220, 151, 254, 224, 251 }, new int[] { 180, 126, 157, 221, 152, 254, 225, 251 }, new int[] { 181, 126, 157, 221, 152, 254, 225, 251 }, new int[] { 183, 127, 158, 222, 153, 254, 226, 251 }, new int[] { 184, 127, 158, 223, 154, 254, 226, 251 }, new int[] { 185, 128, 159, 224, 155, 255, 227, 251 }, new int[] { 186, 128, 159, 224, 155, 255, 227, 251 }, new int[] { 187, 129, 160, 225, 156, 255, 228, 251 }, new int[] { 188, 130, 160, 225, 156, 255, 228, 251 },
|
||||
new int[] { 189, 131, 160, 226, 157, 255, 228, 251 }, new int[] { 190, 131, 160, 226, 158, 255, 228, 251 }, new int[] { 191, 132, 161, 227, 159, 255, 229, 251 }, new int[] { 192, 132, 161, 227, 159, 255, 229, 251 }, new int[] { 193, 133, 162, 228, 160, 255, 230, 252 }, new int[] { 194, 133, 162, 229, 160, 255, 230, 252 }, new int[] { 195, 134, 163, 230, 161, 255, 231, 252 }, new int[] { 196, 134, 163, 230, 161, 255, 231, 252 }, new int[] { 197, 135, 163, 231, 162, 255, 231, 252 }, new int[] { 198, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new int[] { 199, 136, 164, 232, 163, 255, 232, 252 }, new int[] { 200, 136, 164, 232, 164, 255, 232, 252 }, new int[] { 201, 137, 165, 233, 165, 255, 233, 252 }, new int[] { 201, 137, 165, 233, 165, 255, 233, 252 }, new int[] { 202, 138, 166, 233, 166, 255, 233, 252 }, new int[] { 203, 138, 166, 233, 166, 255, 233, 252 }, new int[] { 204, 139, 166, 234, 167, 255, 234, 252 }, new int[] { 205, 139, 166, 234, 167, 255, 234, 252 }, new int[] { 206, 140, 167, 235, 168, 255, 235, 252 }, new int[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new int[] { 207, 141, 168, 236, 169, 255, 235, 252 }, new int[] { 208, 141, 168, 236, 170, 255, 235, 252 }, new int[] { 209, 142, 169, 237, 171, 255, 236, 252 }, new int[] { 209, 143, 169, 237, 171, 255, 236, 252 }, new int[] { 210, 144, 169, 237, 172, 255, 236, 252 }, new int[] { 211, 144, 169, 237, 172, 255, 236, 252 }, new int[] { 212, 145, 170, 238, 173, 255, 237, 252 }, new int[] { 213, 145, 170, 238, 173, 255, 237, 252 }, new int[] { 214, 146, 171, 239, 174, 255, 237, 253 }, new int[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new int[] { 215, 147, 172, 240, 175, 255, 238, 253 }, new int[] { 215, 147, 172, 240, 175, 255, 238, 253 }, new int[] { 216, 148, 173, 240, 176, 255, 238, 253 }, new int[] { 217, 148, 173, 240, 176, 255, 238, 253 }, new int[] { 218, 149, 173, 241, 177, 255, 239, 253 }, new int[] { 218, 149, 173, 241, 178, 255, 239, 253 }, new int[] { 219, 150, 174, 241, 179, 255, 239, 253 }, new int[] { 219, 151, 174, 241, 179, 255, 239, 253 }, new int[] { 220, 152, 175, 242, 180, 255, 240, 253 }, new int[] { 221, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new int[] { 222, 153, 176, 242, 181, 255, 240, 253 }, new int[] { 222, 153, 176, 242, 181, 255, 240, 253 }, new int[] { 223, 154, 177, 243, 182, 255, 240, 253 }, new int[] { 223, 154, 177, 243, 182, 255, 240, 253 }, new int[] { 224, 155, 178, 244, 183, 255, 241, 253 }, new int[] { 224, 155, 178, 244, 183, 255, 241, 253 }, new int[] { 225, 156, 178, 244, 184, 255, 241, 253 }, new int[] { 225, 157, 178, 244, 184, 255, 241, 253 }, new int[] { 226, 158, 179, 244, 185, 255, 242, 253 }, new int[] { 227, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new int[] { 228, 159, 180, 245, 186, 255, 242, 253 }, new int[] { 228, 159, 180, 245, 186, 255, 242, 253 }, new int[] { 229, 160, 181, 245, 187, 255, 242, 253 }, new int[] { 229, 160, 181, 245, 187, 255, 242, 253 }, new int[] { 230, 161, 182, 246, 188, 255, 243, 253 }, new int[] { 230, 162, 182, 246, 188, 255, 243, 253 }, new int[] { 231, 163, 183, 246, 189, 255, 243, 253 }, new int[] { 231, 163, 183, 246, 189, 255, 243, 253 }, new int[] { 232, 164, 184, 247, 190, 255, 243, 253 }, new int[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new int[] { 233, 165, 185, 247, 191, 255, 244, 253 }, new int[] { 233, 165, 185, 247, 191, 255, 244, 253 }, new int[] { 234, 166, 185, 247, 192, 255, 244, 253 }, new int[] { 234, 167, 185, 247, 192, 255, 244, 253 }, new int[] { 235, 168, 186, 248, 193, 255, 244, 253 }, new int[] { 235, 168, 186, 248, 193, 255, 244, 253 }, new int[] { 236, 169, 187, 248, 194, 255, 244, 253 }, new int[] { 236, 169, 187, 248, 194, 255, 244, 253 }, new int[] { 236, 170, 188, 248, 195, 255, 245, 253 }, new int[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new int[] { 237, 171, 189, 249, 196, 255, 245, 254 }, new int[] { 237, 172, 189, 249, 196, 255, 245, 254 }, new int[] { 238, 173, 190, 249, 197, 255, 245, 254 }, new int[] { 238, 173, 190, 249, 197, 255, 245, 254 }, new int[] { 239, 174, 191, 249, 198, 255, 245, 254 }, new int[] { 239, 174, 191, 249, 198, 255, 245, 254 }, new int[] { 240, 175, 192, 249, 199, 255, 246, 254 }, new int[] { 240, 176, 192, 249, 199, 255, 246, 254 }, new int[] { 240, 177, 193, 250, 200, 255, 246, 254 }, new int[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new int[] { 241, 178, 194, 250, 201, 255, 246, 254 }, new int[] { 241, 178, 194, 250, 201, 255, 246, 254 }, new int[] { 242, 179, 195, 250, 202, 255, 246, 254 }, new int[] { 242, 180, 195, 250, 202, 255, 246, 254 }, new int[] { 242, 181, 196, 250, 203, 255, 247, 254 }, new int[] { 242, 181, 196, 250, 203, 255, 247, 254 }, new int[] { 243, 182, 197, 251, 204, 255, 247, 254 }, new int[] { 243, 183, 197, 251, 204, 255, 247, 254 }, new int[] { 244, 184, 198, 251, 205, 255, 247, 254 }, new int[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new int[] { 244, 185, 199, 251, 206, 255, 247, 254 }, new int[] { 244, 185, 199, 251, 206, 255, 247, 254 }, new int[] { 245, 186, 200, 251, 207, 255, 247, 254 }, new int[] { 245, 187, 200, 251, 207, 255, 247, 254 }, new int[] { 246, 188, 201, 252, 207, 255, 248, 254 }, new int[] { 246, 188, 201, 252, 207, 255, 248, 254 }, new int[] { 246, 189, 202, 252, 208, 255, 248, 254 }, new int[] { 246, 190, 202, 252, 208, 255, 248, 254 }, new int[] { 247, 191, 203, 252, 209, 255, 248, 254 }, new int[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new int[] { 247, 192, 204, 252, 210, 255, 248, 254 }, new int[] { 247, 193, 204, 252, 210, 255, 248, 254 }, new int[] { 248, 194, 205, 252, 211, 255, 248, 254 }, new int[] { 248, 194, 205, 252, 211, 255, 248, 254 }, new int[] { 248, 195, 206, 252, 212, 255, 249, 254 }, new int[] { 248, 196, 206, 252, 212, 255, 249, 254 }, new int[] { 249, 197, 207, 253, 213, 255, 249, 254 }, new int[] { 249, 197, 207, 253, 213, 255, 249, 254 }, new int[] { 249, 198, 208, 253, 214, 255, 249, 254 }, new int[] { 249, 199, 209, 253, 214, 255, 249, 254 },
|
||||
new int[] { 250, 200, 210, 253, 215, 255, 249, 254 }, new int[] { 250, 200, 210, 253, 215, 255, 249, 254 }, new int[] { 250, 201, 211, 253, 215, 255, 249, 254 }, new int[] { 250, 202, 211, 253, 215, 255, 249, 254 }, new int[] { 250, 203, 212, 253, 216, 255, 249, 254 }, new int[] { 250, 203, 212, 253, 216, 255, 249, 254 }, new int[] { 251, 204, 213, 253, 217, 255, 250, 254 }, new int[] { 251, 205, 213, 253, 217, 255, 250, 254 }, new int[] { 251, 206, 214, 254, 218, 255, 250, 254 }, new int[] { 251, 206, 215, 254, 218, 255, 250, 254 },
|
||||
new int[] { 252, 207, 216, 254, 219, 255, 250, 254 }, new int[] { 252, 208, 216, 254, 219, 255, 250, 254 }, new int[] { 252, 209, 217, 254, 220, 255, 250, 254 }, new int[] { 252, 210, 217, 254, 220, 255, 250, 254 }, new int[] { 252, 211, 218, 254, 221, 255, 250, 254 }, new int[] { 252, 212, 218, 254, 221, 255, 250, 254 }, new int[] { 253, 213, 219, 254, 222, 255, 250, 254 }, new int[] { 253, 213, 220, 254, 222, 255, 250, 254 }, new int[] { 253, 214, 221, 254, 223, 255, 250, 254 }, new int[] { 253, 215, 221, 254, 223, 255, 250, 254 },
|
||||
new int[] { 253, 216, 222, 254, 224, 255, 251, 254 }, new int[] { 253, 217, 223, 254, 224, 255, 251, 254 }, new int[] { 253, 218, 224, 254, 225, 255, 251, 254 }, new int[] { 253, 219, 224, 254, 225, 255, 251, 254 }, new int[] { 254, 220, 225, 254, 225, 255, 251, 254 }, new int[] { 254, 221, 226, 254, 225, 255, 251, 254 }, new int[] { 254, 222, 227, 255, 226, 255, 251, 254 }, new int[] { 254, 223, 227, 255, 226, 255, 251, 254 }, new int[] { 254, 224, 228, 255, 227, 255, 251, 254 }, new int[] { 254, 225, 229, 255, 227, 255, 251, 254 },
|
||||
new int[] { 254, 226, 230, 255, 228, 255, 251, 254 }, new int[] { 254, 227, 230, 255, 229, 255, 251, 254 }, new int[] { 255, 228, 231, 255, 230, 255, 251, 254 }, new int[] { 255, 229, 232, 255, 230, 255, 251, 254 }, new int[] { 255, 230, 233, 255, 231, 255, 252, 254 }, new int[] { 255, 231, 234, 255, 231, 255, 252, 254 }, new int[] { 255, 232, 235, 255, 232, 255, 252, 254 }, new int[] { 255, 233, 236, 255, 232, 255, 252, 254 }, new int[] { 255, 235, 237, 255, 233, 255, 252, 254 }, new int[] { 255, 236, 238, 255, 234, 255, 252, 254 },
|
||||
new int[] { 255, 238, 240, 255, 235, 255, 252, 255 }, new int[] { 255, 239, 241, 255, 235, 255, 252, 254 }, new int[] { 255, 241, 243, 255, 236, 255, 252, 254 }, new int[] { 255, 243, 245, 255, 237, 255, 252, 254 }, new int[] { 255, 246, 247, 255, 239, 255, 253, 255 } };
|
||||
|
||||
public static final int[][] extra_bits = new int[][] {
|
||||
new int[] { 0, 0, 0 }, new int[] { 0, 0, 1 }, new int[] { 0, 0, 2 }, new int[] { 0, 0, 3 }, new int[] { 0, 0, 4 }, new int[] { 1, 1, 5 }, new int[] { 2, 2, 7 }, new int[] { 3, 3, 11 }, new int[] { 4, 4, 19 }, new int[] { 5, 5, 35 },
|
||||
new int[] { 6, 14, 67 } };
|
||||
|
||||
public static final int[][] cat_probs = new int[][] { new int[] { 0 }, new int[] { 159 }, new int[] { 165, 145 }, new int[] { 173, 148, 140 }, new int[] { 176, 155, 140, 135 }, new int[] { 180, 157, 141, 134, 130 }, new int[] {
|
||||
254, 254, 254, 252, 249, 243, 230, 196, 177, 153,
|
||||
140, 133, 130, 129 } };
|
||||
|
||||
public static final int[] TOKEN_TREE = new int[] {
|
||||
2, 6, -2, 4, -3, -4, 8, 10, -5, -6,
|
||||
12, 14, -7, -8, -9, -10 };
|
||||
|
||||
public static final int[] coefband_4x4 = new int[] {
|
||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 5, 5, 5 };
|
||||
|
||||
public static final int[] coefband_8x8plus = new int[] {
|
||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5 };
|
||||
|
||||
public static final int SZ_8x8 = 0;
|
||||
|
||||
public static final int SZ_16x16 = 1;
|
||||
|
||||
public static final int SZ_32x32 = 2;
|
||||
|
||||
public static final int SZ_64x64 = 3;
|
||||
|
||||
public static final int[][] blSizeLookup_ = new int[][] { new int[] {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12 }, new int[] {
|
||||
-1, -1, -1, 2, -1, -1, 5, -1, -1, 8,
|
||||
-1, -1, 11 }, new int[] {
|
||||
-1, -1, -1, 1, -1, 1, 4, -1, -1, 7,
|
||||
-1, -1, 10 }, new int[] {
|
||||
-1, -1, -1, 0, -1, -1, 3, -1, -1, 6,
|
||||
-1, -1, 9 } };
|
||||
|
||||
public static final int[][] blSizeLookup = new int[][] { new int[] { 0, 1 }, new int[] { 2, 3, 4 }, new int[] { -1, 5, 6, 7 }, new int[] { -1, -1, 8, 9 } };
|
||||
|
||||
public static final int[] sub8x8PartitiontoBlockType = new int[] { 3, 2, 1, 0 };
|
||||
|
||||
public static final int[] TREE_PARTITION = new int[] { 0, 2, -1, 4, -2, -3 };
|
||||
|
||||
public static final int[] TREE_PARTITION_RIGHT_E = new int[] { 0, -2 };
|
||||
|
||||
public static final int[] TREE_PARTITION_BOTTOM_E = new int[] { 0, -1 };
|
||||
|
||||
public static final int[] INV_REMAP_TABLE = new int[] {
|
||||
7, 20, 33, 46, 59, 72, 85, 98, 111, 124,
|
||||
137, 150, 163, 176, 189, 202, 215, 228, 241, 254,
|
||||
1, 2, 3, 4, 5, 6, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 21, 22,
|
||||
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 60, 61, 62, 63, 64, 65,
|
||||
66, 67, 68, 69, 70, 71, 73, 74, 75, 76,
|
||||
77, 78, 79, 80, 81, 82, 83, 84, 86, 87,
|
||||
88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
|
||||
99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
|
||||
109, 110, 112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
|
||||
131, 132, 133, 134, 135, 136, 138, 139, 140, 141,
|
||||
142, 143, 144, 145, 146, 147, 148, 149, 151, 152,
|
||||
153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
|
||||
164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
|
||||
174, 175, 177, 178, 179, 180, 181, 182, 183, 184,
|
||||
185, 186, 187, 188, 190, 191, 192, 193, 194, 195,
|
||||
196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
|
||||
207, 208, 209, 210, 211, 212, 213, 214, 216, 217,
|
||||
218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
|
||||
239, 240, 242, 243, 244, 245, 246, 247, 248, 249,
|
||||
250, 251, 252, 253, 253 };
|
||||
|
||||
public static final int REFS_PER_FRAME = 3;
|
||||
|
||||
public static final int MV_FR_SIZE = 4;
|
||||
|
||||
public static final int MVREF_NEIGHBOURS = 8;
|
||||
|
||||
public static final int BLOCK_SIZE_GROUPS = 4;
|
||||
|
||||
public static final int BLOCK_SIZES = 13;
|
||||
|
||||
public static final int PARTITION_CONTEXTS = 16;
|
||||
|
||||
public static final int MI_SIZE = 8;
|
||||
|
||||
public static final int MIN_TILE_WIDTH_B64 = 4;
|
||||
|
||||
public static final int MAX_TILE_WIDTH_B64 = 64;
|
||||
|
||||
public static final int MAX_MV_REF_CANDIDATES = 2;
|
||||
|
||||
public static final int NUM_REF_FRAMES = 8;
|
||||
|
||||
public static final int MAX_REF_FRAMES = 4;
|
||||
|
||||
public static final int IS_INTER_CONTEXTS = 4;
|
||||
|
||||
public static final int COMP_MODE_CONTEXTS = 5;
|
||||
|
||||
public static final int REF_CONTEXTS = 5;
|
||||
|
||||
public static final int MAX_SEGMENTS = 8;
|
||||
|
||||
public static final int SEG_LVL_ALT_Q = 0;
|
||||
|
||||
public static final int SEG_LVL_ALT_L = 1;
|
||||
|
||||
public static final int SEG_LVL_REF_FRAME = 2;
|
||||
|
||||
public static final int SEG_LVL_SKIP = 3;
|
||||
|
||||
public static final int SEG_LVL_MAX = 4;
|
||||
|
||||
public static final int BLOCK_TYPES = 2;
|
||||
|
||||
public static final int REF_TYPES = 2;
|
||||
|
||||
public static final int COEF_BANDS = 6;
|
||||
|
||||
public static final int PREV_COEF_CONTEXTS = 6;
|
||||
|
||||
public static final int UNCONSTRAINED_NODES = 3;
|
||||
|
||||
public static final int TX_SIZE_CONTEXTS = 2;
|
||||
|
||||
public static final int SWITCHABLE_FILTERS = 3;
|
||||
|
||||
public static final int INTERP_FILTER_CONTEXTS = 4;
|
||||
|
||||
public static final int SKIP_CONTEXTS = 3;
|
||||
|
||||
public static final int PARTITION_TYPES = 4;
|
||||
|
||||
public static final int TX_SIZES = 4;
|
||||
|
||||
public static final int TX_MODES = 5;
|
||||
|
||||
public static final int DCT_DCT = 0;
|
||||
|
||||
public static final int ADST_DCT = 1;
|
||||
|
||||
public static final int DCT_ADST = 2;
|
||||
|
||||
public static final int ADST_ADST = 3;
|
||||
|
||||
public static final int MB_MODE_COUNT = 14;
|
||||
|
||||
public static final int INTRA_MODES = 10;
|
||||
|
||||
public static final int INTER_MODES = 4;
|
||||
|
||||
public static final int INTER_MODE_CONTEXTS = 7;
|
||||
|
||||
public static final int MV_JOINTS = 4;
|
||||
|
||||
public static final int MV_CLASSES = 11;
|
||||
|
||||
public static final int CLASS0_SIZE = 2;
|
||||
|
||||
public static final int MV_OFFSET_BITS = 10;
|
||||
|
||||
public static final int MAX_PROB = 255;
|
||||
|
||||
public static final int MAX_MODE_LF_DELTAS = 2;
|
||||
|
||||
public static final int COMPANDED_MVREF_THRESH = 8;
|
||||
|
||||
public static final int MAX_LOOP_FILTER = 63;
|
||||
|
||||
public static final int REF_SCALE_SHIFT = 14;
|
||||
|
||||
public static final int SUBPEL_BITS = 4;
|
||||
|
||||
public static final int SUBPEL_SHIFTS = 16;
|
||||
|
||||
public static final int SUBPEL_MASK = 15;
|
||||
|
||||
public static final int MV_BORDER = 128;
|
||||
|
||||
public static final int INTERP_EXTEND = 4;
|
||||
|
||||
public static final int BORDERINPIXELS = 160;
|
||||
|
||||
public static final int MAX_UPDATE_FACTOR = 128;
|
||||
|
||||
public static final int COUNT_SAT = 20;
|
||||
|
||||
public static final int BOTH_ZERO = 0;
|
||||
|
||||
public static final int ZERO_PLUS_PREDICTED = 1;
|
||||
|
||||
public static final int BOTH_PREDICTED = 2;
|
||||
|
||||
public static final int NEW_PLUS_NON_INTRA = 3;
|
||||
|
||||
public static final int BOTH_NEW = 4;
|
||||
|
||||
public static final int INTRA_PLUS_NON_INTRA = 5;
|
||||
|
||||
public static final int BOTH_INTRA = 6;
|
||||
|
||||
public static final int INVALID_CASE = 9;
|
||||
|
||||
int CS_UNKNOWN = 0;
|
||||
|
||||
public static final int CS_BT_601 = 1;
|
||||
|
||||
public static final int CS_BT_709 = 2;
|
||||
|
||||
public static final int CS_SMPTE_170 = 3;
|
||||
|
||||
public static final int CS_SMPTE_240 = 4;
|
||||
|
||||
public static final int CS_BT_2020 = 5;
|
||||
|
||||
public static final int CS_RESERVED = 6;
|
||||
|
||||
public static final int CS_RGB = 7;
|
||||
|
||||
public static final int[] SEGMENTATION_FEATURE_BITS = new int[] { 8, 6, 2, 0 };
|
||||
|
||||
public static final int[] SEGMENTATION_FEATURE_SIGNED = new int[] { 1, 1, 0, 0 };
|
||||
|
||||
public static final int[] tx_mode_to_biggest_tx_size = new int[] { 0, 1, 2, 3, 3 };
|
||||
|
||||
public static final int[] intra_mode_to_tx_type_lookup = new int[] { 0, 1, 2, 0, 3, 1, 2, 2, 1, 3 };
|
||||
|
||||
public static final int CAT1_MIN_VAL = 5;
|
||||
|
||||
public static final int CAT2_MIN_VAL = 7;
|
||||
|
||||
public static final int CAT3_MIN_VAL = 11;
|
||||
|
||||
public static final int CAT4_MIN_VAL = 19;
|
||||
|
||||
public static final int CAT5_MIN_VAL = 35;
|
||||
|
||||
public static final int CAT6_MIN_VAL = 67;
|
||||
|
||||
public static final int[] catMinVal = new int[] { 5, 7, 11, 19, 35, 67 };
|
||||
|
||||
public static final int[][][][] uv_txsize_lookup = new int[][][][] {
|
||||
new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 0 }, new int[] { 0, 0 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 0, 0 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 0 }, new int[] { 1, 0 } }, new int[][] { new int[] { 1, 0 }, new int[] { 1, 1 } }, new int[][] { new int[] { 1, 0 }, new int[] { 1, 1 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 1 }, new int[] { 1, 1 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 1, 1 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 1 }, new int[] { 2, 1 } }, new int[][] { new int[] { 2, 1 }, new int[] { 2, 1 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 2, 2 } }, new int[][] { new int[] { 3, 2 }, new int[] { 2, 2 } } },
|
||||
new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 2, 2 } }, new int[][] { new int[] { 3, 3 }, new int[] { 2, 2 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 2, 2 } }, new int[][] { new int[] { 3, 2 }, new int[] { 3, 2 } } }, new int[][][] { new int[][] { new int[] { 0, 0 }, new int[] { 0, 0 } }, new int[][] { new int[] { 1, 1 }, new int[] { 1, 1 } }, new int[][] { new int[] { 2, 2 }, new int[] { 2, 2 } }, new int[][] { new int[] { 3, 3 }, new int[] { 3, 3 } } } };
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,941 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
import org.jcodec.codecs.common.biari.Packed4BitList;
|
||||
import org.jcodec.codecs.vpx.VPXBooleanDecoder;
|
||||
|
||||
public class InterModeInfo extends ModeInfo {
|
||||
private long mvl0;
|
||||
|
||||
private long mvl1;
|
||||
|
||||
private long mvl2;
|
||||
|
||||
private long mvl3;
|
||||
|
||||
InterModeInfo() {}
|
||||
|
||||
public InterModeInfo(int segmentId, boolean skip, int txSize, int yMode, int subModes, int uvMode) {
|
||||
super(segmentId, skip, txSize, yMode, subModes, uvMode);
|
||||
}
|
||||
|
||||
public InterModeInfo(int segmentId, boolean skip, int txSize, int yMode, int subModes, int uvMode, long mvl0, long mvl1, long mvl2, long mvl3) {
|
||||
super(segmentId, skip, txSize, yMode, subModes, uvMode);
|
||||
this.mvl0 = mvl0;
|
||||
this.mvl1 = mvl1;
|
||||
this.mvl2 = mvl2;
|
||||
this.mvl3 = mvl3;
|
||||
}
|
||||
|
||||
public boolean isInter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getMvl0() {
|
||||
return this.mvl0;
|
||||
}
|
||||
|
||||
public long getMvl1() {
|
||||
return this.mvl1;
|
||||
}
|
||||
|
||||
public long getMvl2() {
|
||||
return this.mvl2;
|
||||
}
|
||||
|
||||
public long getMvl3() {
|
||||
return this.mvl3;
|
||||
}
|
||||
|
||||
public InterModeInfo read(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int segmentId = 0;
|
||||
if (c.isSegmentationEnabled()) {
|
||||
segmentId = predicSegmentId(miCol, miRow, blSz, c);
|
||||
if (c.isUpdateSegmentMap() && (
|
||||
!c.isSegmentMapConditionalUpdate() || !readSegIdPredicted(miCol, miRow, blSz, decoder, c)))
|
||||
segmentId = readSegmentId(decoder, c);
|
||||
}
|
||||
boolean skip = true;
|
||||
if (!c.isSegmentFeatureActive(segmentId, 3))
|
||||
skip = readSkipFlag(miCol, miRow, blSz, decoder, c);
|
||||
boolean isInter = (c.getSegmentFeature(segmentId, 2) != 0);
|
||||
if (!c.isSegmentFeatureActive(segmentId, 2))
|
||||
isInter = readIsInter(miCol, miRow, blSz, decoder, c);
|
||||
int txSize = readTxSize(miCol, miRow, blSz, (!skip || !isInter), decoder, c);
|
||||
if (!isInter)
|
||||
return readInterIntraMode(miCol, miRow, blSz, decoder, c, segmentId, skip, txSize);
|
||||
return readInterInterMode(miCol, miRow, blSz, decoder, c, segmentId, skip, txSize);
|
||||
}
|
||||
|
||||
private InterModeInfo readInterInterMode(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int segmentId, boolean skip, int txSize) {
|
||||
int packedRefFrames = readRefFrames(miCol, miRow, blSz, segmentId, decoder, c);
|
||||
int lumaMode = 12;
|
||||
if (!c.isSegmentFeatureActive(segmentId, 3) &&
|
||||
blSz >= 3)
|
||||
lumaMode = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
int interpFilter = c.getInterpFilter();
|
||||
if (interpFilter == 3)
|
||||
interpFilter = readInterpFilter(miCol, miRow, blSz, decoder, c);
|
||||
if (blSz < 3) {
|
||||
if (blSz == 0) {
|
||||
long[] mv4x4 = readMV4x4(miCol, miRow, blSz, decoder, c, packedRefFrames);
|
||||
return new InterModeInfo(segmentId, skip, txSize, -1, 0, -1, mv4x4[0], mv4x4[1], mv4x4[2], mv4x4[3]);
|
||||
}
|
||||
long[] mv12 = readMvSub8x8(miCol, miRow, blSz, decoder, c, packedRefFrames);
|
||||
return new InterModeInfo(segmentId, skip, txSize, 0, 0, 0, mv12[0], mv12[1], 0L, 0L);
|
||||
}
|
||||
long mvl = readMV8x8AndAbove(miCol, miRow, blSz, decoder, c, packedRefFrames, lumaMode);
|
||||
return new InterModeInfo(segmentId, skip, txSize, lumaMode, 0, lumaMode, mvl, 0L, 0L, 0L);
|
||||
}
|
||||
|
||||
protected long readMV8x8AndAbove(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int packedRefFrames, int lumaMode) {
|
||||
long mvl = readSub0(miCol, miRow, blSz, decoder, c, lumaMode, packedRefFrames);
|
||||
updateMVLineBuffers(miCol, miRow, blSz, c, mvl);
|
||||
updateMVLineBuffers4x4(miCol, miRow, blSz, c, mvl, mvl);
|
||||
return mvl;
|
||||
}
|
||||
|
||||
protected long[] readMvSub8x8(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int packedRefFrames) {
|
||||
int subMode0 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
long mvl0 = readSub0(miCol, miRow, blSz, decoder, c, subMode0, packedRefFrames);
|
||||
int subMode1 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
int blk = (blSz == 1) ? 1 : 2;
|
||||
long mvl1 = readSub12(miCol, miRow, blSz, decoder, c, mvl0, subMode1, blk, packedRefFrames);
|
||||
if (blSz == 1) {
|
||||
updateMVLineBuffers4x4(miCol, miRow, blSz, c, mvl1, mvl0);
|
||||
} else {
|
||||
updateMVLineBuffers4x4(miCol, miRow, blSz, c, mvl0, mvl1);
|
||||
}
|
||||
updateMVLineBuffers(miCol, miRow, blSz, c, mvl1);
|
||||
return new long[] { mvl0, mvl1 };
|
||||
}
|
||||
|
||||
protected long[] readMV4x4(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int packedRefFrames) {
|
||||
int subMode0 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
long mvl0 = readSub0(miCol, miRow, blSz, decoder, c, subMode0, packedRefFrames);
|
||||
int subMode1 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
long mvl1 = readSub12(miCol, miRow, blSz, decoder, c, mvl0, subMode1, 1, packedRefFrames);
|
||||
int subMode2 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
long mvl2 = readSub12(miCol, miRow, blSz, decoder, c, mvl0, subMode2, 2, packedRefFrames);
|
||||
int subMode3 = readInterMode(miCol, miRow, blSz, decoder, c);
|
||||
long mvl3 = readMvSub3(miCol, miRow, blSz, decoder, c, mvl0, mvl1, mvl2, subMode3, packedRefFrames);
|
||||
updateMVLineBuffers(miCol, miRow, blSz, c, mvl3);
|
||||
updateMVLineBuffers4x4(miCol, miRow, blSz, c, mvl1, mvl2);
|
||||
return new long[] { mvl0, mvl1, mvl2, mvl3 };
|
||||
}
|
||||
|
||||
private static long readSub0(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int lumaMode, int packedRefFrames) {
|
||||
int ref0 = Packed4BitList.get(packedRefFrames, 0);
|
||||
int ref1 = Packed4BitList.get(packedRefFrames, 1);
|
||||
boolean compoundPred = (Packed4BitList.get(packedRefFrames, 2) == 1);
|
||||
long nearestNearMv00 = findBestMv(miCol, miRow, blSz, ref0, 0, c, true);
|
||||
long nearestNearMv01 = 0L;
|
||||
if (compoundPred)
|
||||
nearestNearMv01 = findBestMv(miCol, miRow, blSz, ref1, 0, c, true);
|
||||
int mv0 = 0, mv1 = 0;
|
||||
if (lumaMode == 13) {
|
||||
mv0 = readDiffMv(decoder, c, nearestNearMv00);
|
||||
if (compoundPred)
|
||||
mv1 = readDiffMv(decoder, c, nearestNearMv01);
|
||||
} else if (lumaMode != 12) {
|
||||
mv0 = MVList.get(nearestNearMv00, lumaMode - 10);
|
||||
mv1 = MVList.get(nearestNearMv01, lumaMode - 10);
|
||||
}
|
||||
return MVList.create(mv0, mv1);
|
||||
}
|
||||
|
||||
private static long readSub12(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, long mvl0, int subMode1, int blk, int packedRefFrames) {
|
||||
int ref0 = Packed4BitList.get(packedRefFrames, 0);
|
||||
int ref1 = Packed4BitList.get(packedRefFrames, 1);
|
||||
boolean compoundPred = (Packed4BitList.get(packedRefFrames, 2) == 1);
|
||||
int mv10 = 0, mv11 = 0;
|
||||
long nearestNearMv00 = findBestMv(miCol, miRow, blSz, ref0, 0, c, true);
|
||||
long nearestNearMv01 = 0L;
|
||||
if (compoundPred)
|
||||
nearestNearMv01 = findBestMv(miCol, miRow, blSz, ref1, 0, c, true);
|
||||
if (subMode1 == 13) {
|
||||
mv10 = readDiffMv(decoder, c, nearestNearMv00);
|
||||
if (compoundPred)
|
||||
mv11 = readDiffMv(decoder, c, nearestNearMv01);
|
||||
} else if (subMode1 != 12) {
|
||||
long nearestNearMv10 = prepandSubMvBlk12(findBestMv(miCol, miRow, blSz, ref0, blk, c, false),
|
||||
MVList.get(mvl0, 0));
|
||||
long nearestNearMv11 = 0L;
|
||||
if (compoundPred)
|
||||
nearestNearMv11 = prepandSubMvBlk12(findBestMv(miCol, miRow, blSz, ref1, blk, c, false),
|
||||
MVList.get(mvl0, 1));
|
||||
mv10 = MVList.get(nearestNearMv10, subMode1 - 10);
|
||||
mv11 = MVList.get(nearestNearMv11, subMode1 - 10);
|
||||
}
|
||||
return MVList.create(mv10, mv11);
|
||||
}
|
||||
|
||||
private static long readMvSub3(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, long mvl0, long mvl1, long mvl2, int subMode3, int packedRefFrames) {
|
||||
int ref0 = Packed4BitList.get(packedRefFrames, 0);
|
||||
int ref1 = Packed4BitList.get(packedRefFrames, 1);
|
||||
boolean compoundPred = (Packed4BitList.get(packedRefFrames, 2) == 1);
|
||||
long nearestNearMv00 = findBestMv(miCol, miRow, blSz, ref0, 0, c, true);
|
||||
long nearestNearMv01 = 0L;
|
||||
if (compoundPred)
|
||||
nearestNearMv01 = findBestMv(miCol, miRow, blSz, ref1, 0, c, true);
|
||||
int mv30 = 0, mv31 = 0;
|
||||
if (subMode3 == 13) {
|
||||
mv30 = readDiffMv(decoder, c, nearestNearMv00);
|
||||
if (compoundPred)
|
||||
mv31 = readDiffMv(decoder, c, nearestNearMv01);
|
||||
} else if (subMode3 != 12) {
|
||||
long nearestNearMv30 = prepandSubMvBlk3(findBestMv(miCol, miRow, blSz, ref0, 3, c, false),
|
||||
MVList.get(mvl0, 0), MVList.get(mvl1, 0), MVList.get(mvl2, 0));
|
||||
long nearestNearMv31 = 0L;
|
||||
if (compoundPred)
|
||||
nearestNearMv31 = prepandSubMvBlk3(findBestMv(miCol, miRow, blSz, ref1, 3, c, false),
|
||||
MVList.get(mvl0, 1), MVList.get(mvl1, 1), MVList.get(mvl2, 1));
|
||||
mv30 = MVList.get(nearestNearMv30, subMode3 - 10);
|
||||
mv31 = MVList.get(nearestNearMv31, subMode3 - 10);
|
||||
}
|
||||
return MVList.create(mv30, mv31);
|
||||
}
|
||||
|
||||
private int readRefFrames(int miCol, int miRow, int blSz, int segmentId, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ref0 = c.getSegmentFeature(segmentId, 2), ref1 = 0;
|
||||
boolean compoundPred = false;
|
||||
if (!c.isSegmentFeatureActive(segmentId, 2)) {
|
||||
int refMode = c.getRefMode();
|
||||
compoundPred = (refMode == 1);
|
||||
if (refMode == 2)
|
||||
compoundPred = readRefMode(miCol, miRow, decoder, c);
|
||||
if (compoundPred) {
|
||||
int compRef = readCompRef(miCol, miRow, blSz, decoder, c);
|
||||
int fixedRef = c.getCompFixedRef();
|
||||
if (c.refFrameSignBias(fixedRef) == 0) {
|
||||
ref0 = fixedRef;
|
||||
ref1 = compRef;
|
||||
} else {
|
||||
ref0 = compRef;
|
||||
ref1 = fixedRef;
|
||||
}
|
||||
} else {
|
||||
ref0 = readSingleRef(miCol, miRow, decoder, c);
|
||||
}
|
||||
}
|
||||
updateRefFrameLineBuffers(miCol, miRow, blSz, c, ref0, ref1, compoundPred);
|
||||
return Packed4BitList._3(ref0, ref1, compoundPred ? 1 : 0);
|
||||
}
|
||||
|
||||
private static void updateMVLineBuffers(int miCol, int miRow, int blSz, DecodingContext c, long mv) {
|
||||
long[][] leftMVs = c.getLeftMVs();
|
||||
long[][] aboveMVs = c.getAboveMVs();
|
||||
long[][] aboveLeftMVs = c.getAboveLeftMVs();
|
||||
for (int m = 0; m < Math.max(3, Consts.blW[blSz]); m++) {
|
||||
aboveLeftMVs[2][m] = aboveLeftMVs[1][m];
|
||||
aboveLeftMVs[1][m] = aboveLeftMVs[0][m];
|
||||
aboveLeftMVs[0][m] = aboveMVs[m][miCol + m];
|
||||
}
|
||||
for (int i = 0; i < Math.max(3, Consts.blH[blSz]); i++) {
|
||||
int offTop = (miRow + i) % 8;
|
||||
aboveLeftMVs[i][2] = aboveLeftMVs[i][1];
|
||||
aboveLeftMVs[i][1] = aboveLeftMVs[i][0];
|
||||
aboveLeftMVs[i][0] = leftMVs[i][offTop];
|
||||
}
|
||||
for (int k = 0; k < Math.max(3, Consts.blH[blSz]); k++) {
|
||||
for (int n = 0; n < Consts.blW[blSz]; n++) {
|
||||
int offLeft = miCol + n;
|
||||
aboveMVs[2][offLeft] = aboveMVs[1][offLeft];
|
||||
aboveMVs[1][offLeft] = aboveMVs[0][offLeft];
|
||||
aboveMVs[0][offLeft] = mv;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < Math.max(3, Consts.blW[blSz]); j++) {
|
||||
for (int n = 0; n < Consts.blH[blSz]; n++) {
|
||||
int offTop = (miRow + n) % 8;
|
||||
leftMVs[2][offTop] = leftMVs[1][offTop];
|
||||
leftMVs[1][offTop] = leftMVs[0][offTop];
|
||||
leftMVs[0][offTop] = mv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateMVLineBuffers4x4(int miCol, int miRow, int blSz, DecodingContext c, long mvLeft, long mvAbove) {
|
||||
long[] leftMVs = c.getLeft4x4MVs();
|
||||
long[] aboveMVs = c.getAbove4x4MVs();
|
||||
aboveMVs[miCol] = mvAbove;
|
||||
leftMVs[miRow % 8] = mvLeft;
|
||||
}
|
||||
|
||||
public static int ref(int ref0, int ref1) {
|
||||
return (ref0 & 0x3) << 2 | ref1 & 0x3;
|
||||
}
|
||||
|
||||
public static int getRef(int packed, int n) {
|
||||
if (n == 0)
|
||||
return packed & 0x3;
|
||||
return packed >> 2 & 0x3;
|
||||
}
|
||||
|
||||
private static void updateRefFrameLineBuffers(int miCol, int miRow, int blSz, DecodingContext c, int ref0, int ref1, boolean compoundPred) {
|
||||
boolean[] aboveCompound = c.getAboveCompound();
|
||||
boolean[] leftCompound = c.getLeftCompound();
|
||||
for (int m = 0; m < Consts.blW[blSz]; m++)
|
||||
aboveCompound[m + miCol] = compoundPred;
|
||||
for (int i = 0; i < Consts.blH[blSz]; i++)
|
||||
leftCompound[miRow + i & 0x7] = compoundPred;
|
||||
for (int j = 0; j < Consts.blW[blSz]; j++)
|
||||
c.getAboveRefs()[j] = ref(ref0, ref1);
|
||||
for (int k = 0; k < Consts.blH[blSz]; k++)
|
||||
c.getLeftRefs()[k & 0x7] = ref(ref0, ref1);
|
||||
}
|
||||
|
||||
private static int readDiffMv(VPXBooleanDecoder decoder, DecodingContext c, long nearNearest) {
|
||||
int bestMv = MVList.get(nearNearest, 0);
|
||||
boolean useHp = (c.isAllowHpMv() && !largeMv(bestMv));
|
||||
int joint = decoder.readTree(Consts.TREE_MV_JOINT, c.getMvJointProbs());
|
||||
int diffMv0 = 0, diffMv1 = 0;
|
||||
if (joint == 2 || joint == 3)
|
||||
diffMv0 = readMvComponent(decoder, c, 0, useHp);
|
||||
if (joint == 1 || joint == 3)
|
||||
diffMv1 = readMvComponent(decoder, c, 1, useHp);
|
||||
return MV.create(MV.x(bestMv) + diffMv0, MV.y(bestMv) + diffMv1, MV.ref(bestMv));
|
||||
}
|
||||
|
||||
private static int readMvComponent(VPXBooleanDecoder decoder, DecodingContext c, int comp, boolean useHp) {
|
||||
int mag;
|
||||
boolean sign = (decoder.readBitEq() == 1);
|
||||
int mvClass = decoder.readTree(Consts.MV_CLASS_TREE, c.getMvClassProbs()[comp]);
|
||||
if (mvClass == 0) {
|
||||
int mvClass0Bit = decoder.readBit(c.getMvClass0BitProbs()[comp]);
|
||||
int mvClass0Fr = decoder.readTree(Consts.MV_FR_TREE, c.getMvClass0FrProbs()[comp][mvClass0Bit]);
|
||||
int mvClass0Hp = useHp ? decoder.readBit(c.getMvClass0HpProbs()[comp]) : 1;
|
||||
mag = (mvClass0Bit << 3 | mvClass0Fr << 1 | mvClass0Hp) + 1;
|
||||
} else {
|
||||
int d = 0;
|
||||
for (int i = 0; i < mvClass; i++) {
|
||||
int mvBit = decoder.readBit(c.getMvBitsProb()[comp][i]);
|
||||
d |= mvBit << i;
|
||||
}
|
||||
mag = 2 << mvClass + 2;
|
||||
int mvFr = decoder.readTree(Consts.MV_FR_TREE, c.getMvFrProbs()[comp]);
|
||||
int mvHp = useHp ? decoder.readBit(c.getMvHpProbs()[comp]) : 1;
|
||||
mag += (d << 3 | mvFr << 1 | mvHp) + 1;
|
||||
}
|
||||
return sign ? -mag : mag;
|
||||
}
|
||||
|
||||
private static boolean largeMv(int mv) {
|
||||
return ((MV.x(mv) >= 64 || MV.x(mv) <= -64) && (MV.y(mv) >= 64 || MV.y(mv) <= -64));
|
||||
}
|
||||
|
||||
public static long findBestMv(int miCol, int miRow, int blSz, int ref, int blk, DecodingContext c, boolean clearHp) {
|
||||
long[][] leftMVs = c.getLeftMVs();
|
||||
long[][] aboveMVs = c.getAboveMVs();
|
||||
long[][] aboveLeftMVs = c.getAboveLeftMVs();
|
||||
long[] left4x4MVs = c.getLeft4x4MVs();
|
||||
long[] above4x4MVs = c.getAbove4x4MVs();
|
||||
long list = 0L;
|
||||
boolean checkDifferentRef = false;
|
||||
int pt0 = Consts.mv_ref_blocks[blSz][0];
|
||||
int pt1 = Consts.mv_ref_blocks[blSz][1];
|
||||
long mvp0 = getMV(leftMVs, aboveMVs, aboveLeftMVs, pt0, miRow, miCol, c);
|
||||
long mvp1 = getMV(leftMVs, aboveMVs, aboveLeftMVs, pt1, miRow, miCol, c);
|
||||
if (blk == 1) {
|
||||
mvp0 = (mvp0 == -1L) ? -1L : left4x4MVs[miRow % 8];
|
||||
} else if (blk == 2) {
|
||||
mvp1 = (mvp1 == -1L) ? -1L : above4x4MVs[miCol];
|
||||
}
|
||||
checkDifferentRef = ((mvp0 != 0L)) | ((mvp1 != 0L));
|
||||
list = processCandidate(ref, list, mvp0);
|
||||
list = processCandidate(ref, list, mvp1);
|
||||
for (int i = 2; i < (Consts.mv_ref_blocks[blSz]).length && MVList.size(list) < 2; i++) {
|
||||
long mvi = getMV(leftMVs, aboveMVs, aboveLeftMVs, Consts.mv_ref_blocks[blSz][i], miRow, miCol, c);
|
||||
checkDifferentRef |= (mvi != 0L) ? true : false;
|
||||
list = processCandidate(ref, list, mvi);
|
||||
}
|
||||
if (MVList.size(list) < 2 && c.isUsePrevFrameMvs()) {
|
||||
long[][] prevFrameMv = c.getPrevFrameMv();
|
||||
long prevMv = prevFrameMv[miCol][miRow];
|
||||
list = processCandidate(ref, list, prevMv);
|
||||
}
|
||||
if (MVList.size(list) < 2 && checkDifferentRef)
|
||||
for (int j = 0; j < (Consts.mv_ref_blocks[blSz]).length && MVList.size(list) < 2; j++) {
|
||||
long mvp = getMV(leftMVs, aboveMVs, aboveLeftMVs, Consts.mv_ref_blocks[blSz][j], miRow, miCol, c);
|
||||
list = processNECandidate(ref, c, list, mvp);
|
||||
}
|
||||
if (MVList.size(list) < 2 && c.isUsePrevFrameMvs()) {
|
||||
long[][] prevFrameMv = c.getPrevFrameMv();
|
||||
long prevMv = prevFrameMv[miCol][miRow];
|
||||
list = processNECandidate(ref, c, list, prevMv);
|
||||
}
|
||||
list = clampMvs(miCol, miRow, blSz, c, list);
|
||||
if (clearHp)
|
||||
list = clearHp(c, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static long clearHp(DecodingContext c, long list) {
|
||||
int mv0 = MVList.get(list, 0);
|
||||
if (!c.isAllowHpMv() || largeMv(mv0))
|
||||
mv0 = MV.create(MV.x(mv0) & 0xFFFFFFFE, MV.y(mv0) & 0xFFFFFFFE, MV.ref(mv0));
|
||||
int mv1 = MVList.get(list, 1);
|
||||
if (!c.isAllowHpMv() || largeMv(mv1))
|
||||
mv1 = MV.create(MV.x(mv1) & 0xFFFFFFFE, MV.y(mv1) & 0xFFFFFFFE, MV.ref(mv1));
|
||||
list = MVList.create(mv0, mv1);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static long clampMvs(int miCol, int miRow, int blSz, DecodingContext c, long list) {
|
||||
int mv0 = MVList.get(list, 0);
|
||||
int mv1 = MVList.get(list, 1);
|
||||
int mv0xCl = clampMvCol(miCol, blSz, c, MV.x(mv0));
|
||||
int mv0yCl = clampMvRow(miRow, blSz, c, MV.y(mv0));
|
||||
int mv1xCl = clampMvCol(miCol, blSz, c, MV.x(mv1));
|
||||
int mv1yCl = clampMvRow(miRow, blSz, c, MV.y(mv1));
|
||||
return MVList.create(MV.create(mv0xCl, mv0yCl, MV.ref(mv0)), MV.create(mv1xCl, mv1yCl, MV.ref(mv1)));
|
||||
}
|
||||
|
||||
private static long processNECandidate(int ref, DecodingContext c, long list, long mvp) {
|
||||
int mv0 = MVList.get(mvp, 0);
|
||||
int mv1 = MVList.get(mvp, 1);
|
||||
boolean matchMv = (MV.x(mv0) == MV.x(mv1) && MV.y(mv0) == MV.y(mv1));
|
||||
list = processNEComponent(ref, c, list, mv0);
|
||||
if (!matchMv)
|
||||
list = processNEComponent(ref, c, list, mv1);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static long processNEComponent(int ref, DecodingContext c, long list, int mv0) {
|
||||
int ref0 = MV.ref(mv0);
|
||||
if (ref0 != 0 && ref0 != ref) {
|
||||
int q = c.refFrameSignBias(ref0) * c.refFrameSignBias(ref);
|
||||
int mv = MV.create(MV.x(mv0) * q, MV.y(mv0), ref);
|
||||
list = MVList.addUniq(list, mv);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static long processCandidate(int ref, long list, long mvp0) {
|
||||
int mv00 = MVList.get(mvp0, 0);
|
||||
int mv01 = MVList.get(mvp0, 1);
|
||||
if (MV.ref(mv00) == ref) {
|
||||
list = MVList.addUniq(list, mv00);
|
||||
} else if (MV.ref(mv01) == ref) {
|
||||
list = MVList.addUniq(list, mv01);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static long prepandSubMvBlk12(long list, int blkMv) {
|
||||
long nlist = 0L;
|
||||
nlist = MVList.add(nlist, blkMv);
|
||||
nlist = MVList.addUniq(nlist, MVList.get(list, 0));
|
||||
nlist = MVList.addUniq(nlist, MVList.get(list, 0));
|
||||
return nlist;
|
||||
}
|
||||
|
||||
private static long prepandSubMvBlk3(long list, int blk0Mv, int blk1Mv, int blk2Mv) {
|
||||
long nlist = 0L;
|
||||
nlist = MVList.add(nlist, blk2Mv);
|
||||
nlist = MVList.addUniq(nlist, blk1Mv);
|
||||
nlist = MVList.addUniq(nlist, blk0Mv);
|
||||
nlist = MVList.addUniq(nlist, MVList.get(list, 0));
|
||||
nlist = MVList.addUniq(nlist, MVList.get(list, 0));
|
||||
return nlist;
|
||||
}
|
||||
|
||||
private static int clampMvRow(int miRow, int blSz, DecodingContext c, int mv) {
|
||||
int mbToTopEdge = -(miRow << 6);
|
||||
int mbToBottomEdge = c.getMiFrameHeight() - Consts.blH[blSz] - miRow << 6;
|
||||
return clip3(mbToTopEdge - 128, mbToBottomEdge + 128, mv);
|
||||
}
|
||||
|
||||
private static int clip3(int from, int to, int v) {
|
||||
return (v < from) ? from : ((v > to) ? to : v);
|
||||
}
|
||||
|
||||
private static int clampMvCol(int miCol, int blSz, DecodingContext c, int mv) {
|
||||
int mbToLeftEdge = -(miCol << 6);
|
||||
int mbToRightEdge = c.getMiFrameWidth() - Consts.blW[blSz] - miCol << 6;
|
||||
return clip3(mbToLeftEdge - 128, mbToRightEdge + 128, mv);
|
||||
}
|
||||
|
||||
protected int readInterpFilter(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx;
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
int[] aboveRefs = c.getAboveRefs();
|
||||
int[] leftRefs = c.getLeftRefs();
|
||||
int aboveRefFrame0 = getRef(aboveRefs[miCol], 0);
|
||||
int leftRefFrame0 = getRef(leftRefs[miRow & 0x7], 0);
|
||||
int[] leftInterpFilters = c.getLeftInterpFilters();
|
||||
int[] aboveInterpFilters = c.getAboveInterpFilters();
|
||||
int leftInterp = (availLeft && leftRefFrame0 > 0) ? leftInterpFilters[miRow & 0x7] : 3;
|
||||
int aboveInterp = (availAbove && aboveRefFrame0 > 0) ? aboveInterpFilters[miCol] : 3;
|
||||
if (leftInterp == aboveInterp) {
|
||||
ctx = leftInterp;
|
||||
} else if (leftInterp == 3 && aboveInterp != 3) {
|
||||
ctx = aboveInterp;
|
||||
} else if (leftInterp != 3 && aboveInterp == 3) {
|
||||
ctx = leftInterp;
|
||||
} else {
|
||||
ctx = 3;
|
||||
}
|
||||
int[][] probs = c.getInterpFilterProbs();
|
||||
int ret = decoder.readTree(Consts.TREE_INTERP_FILTER, probs[ctx]);
|
||||
for (int j = 0; j < Consts.blW[blSz]; j++)
|
||||
aboveInterpFilters[miCol + j] = ret;
|
||||
for (int i = 0; i < Consts.blH[blSz]; i++)
|
||||
leftInterpFilters[miRow + i & 0x7] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readInterMode(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx;
|
||||
int ind0 = Consts.mv_ref_blocks_sm[blSz][0];
|
||||
int ind1 = Consts.mv_ref_blocks_sm[blSz][1];
|
||||
int[] leftModes = c.getLeftModes();
|
||||
int[] aboveModes = c.getAboveModes();
|
||||
int mode0 = getMode(leftModes, aboveModes, ind0, miRow, miCol, c);
|
||||
int mode1 = getMode(leftModes, aboveModes, ind1, miRow, miCol, c);
|
||||
if (mode0 == 11 || mode0 == 10) {
|
||||
if (mode1 == 11 || mode1 == 10) {
|
||||
ctx = 2;
|
||||
} else if (mode1 == 13) {
|
||||
ctx = 3;
|
||||
} else if (mode1 == 12) {
|
||||
ctx = 1;
|
||||
} else {
|
||||
ctx = 5;
|
||||
}
|
||||
} else if (mode0 == 12) {
|
||||
if (mode1 == 11 || mode1 == 10) {
|
||||
ctx = 1;
|
||||
} else if (mode1 == 13) {
|
||||
ctx = 3;
|
||||
} else if (mode1 == 12) {
|
||||
ctx = 0;
|
||||
} else {
|
||||
ctx = 5;
|
||||
}
|
||||
} else if (mode0 == 13) {
|
||||
if (mode1 == 11 || mode1 == 10) {
|
||||
ctx = 3;
|
||||
} else if (mode1 == 13) {
|
||||
ctx = 4;
|
||||
} else if (mode1 == 12) {
|
||||
ctx = 3;
|
||||
} else {
|
||||
ctx = 3;
|
||||
}
|
||||
} else {
|
||||
ctx = (mode1 >= 10) ? 5 : 6;
|
||||
}
|
||||
System.out.println(String.format("inter_mode_ctx: %d\n", ctx));
|
||||
int[][] probs = c.getInterModeProbs();
|
||||
int ret = 10 + decoder.readTree(Consts.TREE_INTER_MODE, probs[ctx]);
|
||||
for (int j = 0; j < Consts.blW[blSz]; j++)
|
||||
aboveModes[miCol + j] = ret;
|
||||
for (int i = 0; i < Consts.blH[blSz]; i++)
|
||||
leftModes[(miRow + i) % 8] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static int getMode(int[] leftModes, int[] aboveModes, int ind0, int miRow, int miCol, DecodingContext c) {
|
||||
switch (ind0) {
|
||||
case 0:
|
||||
return (miCol > c.getMiTileStartCol()) ? leftModes[miRow % 8] : 10;
|
||||
case 1:
|
||||
return (miRow > 0) ? aboveModes[miCol] : 10;
|
||||
case 2:
|
||||
return (miCol > c.getMiTileStartCol() && miRow < c.getMiFrameHeight() - 1) ? leftModes[miRow % 8 + 1] :
|
||||
10;
|
||||
case 3:
|
||||
return (miCol < c.getMiTileWidth() - 1 && miRow > 0) ? aboveModes[miCol + 1] : 10;
|
||||
case 4:
|
||||
return (miCol > c.getMiTileStartCol() && miRow < c.getMiFrameHeight() - 3) ? leftModes[miRow % 8 + 3] :
|
||||
10;
|
||||
case 5:
|
||||
return (miCol < c.getMiTileWidth() - 3 && miRow > 0) ? aboveModes[miCol + 3] : 10;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
|
||||
private static long getMV(long[][] leftMV, long[][] aboveMV, long[][] aboveLeftMV, int ind0, int miRow, int miCol, DecodingContext c) {
|
||||
int th = c.getMiTileHeight();
|
||||
int tw = c.getMiTileWidth();
|
||||
switch (ind0) {
|
||||
case 0:
|
||||
return (miCol >= c.getMiTileStartCol()) ? leftMV[0][miRow % 8] : 0L;
|
||||
case 1:
|
||||
return (miRow > 0) ? aboveMV[0][miCol] : 0L;
|
||||
case 2:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow < th - 1) ? leftMV[0][miRow % 8 + 1] : 0L;
|
||||
case 3:
|
||||
return (miRow > 0 && miCol < tw - 1) ? aboveMV[0][miCol + 1] : 0L;
|
||||
case 4:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow < th - 3) ? leftMV[0][miRow % 8 + 3] : 0L;
|
||||
case 5:
|
||||
return (miRow > 0 && miCol < tw - 3) ? aboveMV[0][miCol + 3] : 0L;
|
||||
case 6:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow < th - 2) ? leftMV[0][miRow % 8 + 2] : 0L;
|
||||
case 7:
|
||||
return (miRow > 0 && miCol < tw - 2) ? aboveMV[0][miCol + 2] : 0L;
|
||||
case 8:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow < th - 4) ? leftMV[0][miRow % 8 + 4] : 0L;
|
||||
case 9:
|
||||
return (miRow > 0 && miCol < tw - 4) ? aboveMV[0][miCol + 4] : 0L;
|
||||
case 10:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow < th - 6) ? leftMV[0][miRow % 8 + 6] : 0L;
|
||||
case 11:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow > 0) ? aboveLeftMV[0][0] : 0L;
|
||||
case 12:
|
||||
return (miCol >= c.getMiTileStartCol() + 1) ? leftMV[1][miRow % 8] : 0L;
|
||||
case 13:
|
||||
return (miRow > 1) ? aboveMV[1][miCol] : 0L;
|
||||
case 14:
|
||||
return (miCol >= c.getMiTileStartCol() + 2) ? leftMV[2][miRow % 8] : 0L;
|
||||
case 15:
|
||||
return (miRow > 2) ? aboveMV[2][miCol] : 0L;
|
||||
case 16:
|
||||
return (miCol >= c.getMiTileStartCol() + 1 && miRow > 0) ? aboveLeftMV[0][1] : 0L;
|
||||
case 17:
|
||||
return (miCol >= c.getMiTileStartCol() && miRow > 1) ? aboveLeftMV[1][0] : 0L;
|
||||
case 18:
|
||||
return (miCol >= c.getMiTileStartCol() + 1 && miRow > 1) ? aboveLeftMV[1][1] : 0L;
|
||||
case 19:
|
||||
return (miCol >= c.getMiTileStartCol() + 2 && miRow > 2) ? aboveLeftMV[2][2] : 0L;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
protected int readCompRef(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int aboveVarRefFrame, leftVarRefFrame, ctx;
|
||||
int compFixedRef = c.getCompFixedRef();
|
||||
int fixRefIdx = c.refFrameSignBias(compFixedRef);
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
boolean[] aboveCompound = c.getAboveCompound();
|
||||
boolean[] leftCompound = c.getLeftCompound();
|
||||
int aboveRefFrame0 = getRef(c.getAboveRefs()[miCol], 0);
|
||||
int leftRefFrame0 = getRef(c.getLeftRefs()[miRow & 0x7], 0);
|
||||
int aboveRefFrame1 = getRef(c.getAboveRefs()[miCol], 1);
|
||||
int leftRefFrame1 = getRef(c.getLeftRefs()[miRow & 0x7], 1);
|
||||
boolean aboveIntra = (aboveRefFrame0 <= 0);
|
||||
boolean leftIntra = (leftRefFrame0 <= 0);
|
||||
boolean aboveSingle = !aboveCompound[miCol];
|
||||
boolean leftSingle = !leftCompound[miRow % 8];
|
||||
if (fixRefIdx == 0) {
|
||||
aboveVarRefFrame = aboveRefFrame1;
|
||||
leftVarRefFrame = leftRefFrame1;
|
||||
} else {
|
||||
aboveVarRefFrame = aboveRefFrame0;
|
||||
leftVarRefFrame = leftRefFrame0;
|
||||
}
|
||||
int compVarRef0 = c.getCompVarRef(0);
|
||||
int compVarRef1 = c.getCompVarRef(1);
|
||||
if (availAbove && availLeft) {
|
||||
if (aboveIntra && leftIntra) {
|
||||
ctx = 2;
|
||||
} else if (leftIntra) {
|
||||
if (aboveSingle) {
|
||||
ctx = 1 + 2 * ((aboveRefFrame0 != compVarRef1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 1 + 2 * ((aboveVarRefFrame != compVarRef1) ? 1 : 0);
|
||||
}
|
||||
} else if (aboveIntra) {
|
||||
if (leftSingle) {
|
||||
ctx = 1 + 2 * ((leftRefFrame0 != compVarRef1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 1 + 2 * ((leftVarRefFrame != compVarRef1) ? 1 : 0);
|
||||
}
|
||||
} else {
|
||||
int vrfa = aboveSingle ? aboveRefFrame0 : aboveVarRefFrame;
|
||||
int vrfl = leftSingle ? leftRefFrame0 : leftVarRefFrame;
|
||||
if (vrfa == vrfl && compVarRef1 == vrfa) {
|
||||
ctx = 0;
|
||||
} else if (leftSingle && aboveSingle) {
|
||||
if ((vrfa == compFixedRef && vrfl == compVarRef0) || (vrfl == compFixedRef && vrfa == compVarRef0)) {
|
||||
ctx = 4;
|
||||
} else if (vrfa == vrfl) {
|
||||
ctx = 3;
|
||||
} else {
|
||||
ctx = 1;
|
||||
}
|
||||
} else if (leftSingle || aboveSingle) {
|
||||
int vrfc = leftSingle ? vrfa : vrfl;
|
||||
int rfs = aboveSingle ? vrfa : vrfl;
|
||||
if (vrfc == compVarRef1 && rfs != compVarRef1) {
|
||||
ctx = 1;
|
||||
} else if (rfs == compVarRef1 && vrfc != compVarRef1) {
|
||||
ctx = 2;
|
||||
} else {
|
||||
ctx = 4;
|
||||
}
|
||||
} else if (vrfa == vrfl) {
|
||||
ctx = 4;
|
||||
} else {
|
||||
ctx = 2;
|
||||
}
|
||||
}
|
||||
} else if (availAbove) {
|
||||
if (aboveIntra) {
|
||||
ctx = 2;
|
||||
} else if (aboveSingle) {
|
||||
ctx = 3 * ((aboveRefFrame0 != compVarRef1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 4 * ((aboveVarRefFrame != compVarRef1) ? 1 : 0);
|
||||
}
|
||||
} else if (availLeft) {
|
||||
if (leftIntra) {
|
||||
ctx = 2;
|
||||
} else if (leftSingle) {
|
||||
ctx = 3 * ((leftRefFrame0 != compVarRef1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 4 * ((leftVarRefFrame != compVarRef1) ? 1 : 0);
|
||||
}
|
||||
} else {
|
||||
ctx = 2;
|
||||
}
|
||||
int[] probs = c.getCompRefProbs();
|
||||
return decoder.readBit(probs[ctx]);
|
||||
}
|
||||
|
||||
protected int readSingleRef(int miCol, int miRow, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
boolean singleRefP1 = readSingRefBin(0, miCol, miRow, decoder, c);
|
||||
if (singleRefP1) {
|
||||
boolean singleRefP2 = readSingRefBin(2, miCol, miRow, decoder, c);
|
||||
return singleRefP2 ? 2 : 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private boolean readSingRefBin(int bin, int miCol, int miRow, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx;
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
boolean[] aboveCompound = c.getAboveCompound();
|
||||
boolean[] leftCompound = c.getLeftCompound();
|
||||
int aboveRefFrame0 = getRef(c.getAboveRefs()[miCol], 0);
|
||||
int leftRefFrame0 = getRef(c.getLeftRefs()[miRow & 0x7], 0);
|
||||
int aboveRefFrame1 = getRef(c.getAboveRefs()[miCol], 1);
|
||||
int leftRefFrame1 = getRef(c.getLeftRefs()[miRow & 0x7], 1);
|
||||
boolean aboveIntra = (aboveRefFrame0 <= 0);
|
||||
boolean leftIntra = (leftRefFrame0 <= 0);
|
||||
boolean aboveSingle = !aboveCompound[miCol];
|
||||
boolean leftSingle = !leftCompound[miRow % 8];
|
||||
if (availAbove && availLeft) {
|
||||
if (aboveIntra && leftIntra) {
|
||||
ctx = 2;
|
||||
} else if (leftIntra) {
|
||||
if (aboveSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 4 * ((aboveRefFrame0 == 1) ? 1 : 0);
|
||||
} else if (aboveRefFrame0 == 1) {
|
||||
ctx = 3;
|
||||
} else {
|
||||
ctx = 4 * ((aboveRefFrame0 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (bin == 0) {
|
||||
ctx = 1 + ((aboveRefFrame0 == 1 || aboveRefFrame1 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 1 + 2 * ((aboveRefFrame0 == 3 || aboveRefFrame1 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (aboveIntra) {
|
||||
if (leftSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 4 * ((leftRefFrame0 == 1) ? 1 : 0);
|
||||
} else if (leftRefFrame0 == 1) {
|
||||
ctx = 3;
|
||||
} else {
|
||||
ctx = 4 * ((leftRefFrame0 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (bin == 0) {
|
||||
ctx = 1 + ((leftRefFrame0 == 1 || leftRefFrame1 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 1 + 2 * ((leftRefFrame0 == 3 || leftRefFrame1 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (aboveSingle && leftSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 2 * ((aboveRefFrame0 == 1) ? 1 : 0) + 2 * ((leftRefFrame0 == 1) ? 1 : 0);
|
||||
} else if (aboveRefFrame0 == 1 && leftRefFrame0 == 1) {
|
||||
ctx = 3;
|
||||
} else if (aboveRefFrame0 == 1) {
|
||||
ctx = 4 * ((leftRefFrame0 == 3) ? 1 : 0);
|
||||
} else if (leftRefFrame0 == 1) {
|
||||
ctx = 4 * ((aboveRefFrame0 == 3) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 2 * ((aboveRefFrame0 == 3) ? 1 : 0) + 2 * ((leftRefFrame0 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (!aboveSingle && !leftSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 1 + ((aboveRefFrame0 == 1 || aboveRefFrame1 == 1 || leftRefFrame0 == 1 || leftRefFrame1 == 1) ? 1 : 0);
|
||||
} else if (aboveRefFrame0 == leftRefFrame0 && aboveRefFrame1 == leftRefFrame1) {
|
||||
ctx = 3 * ((aboveRefFrame0 == 3 || aboveRefFrame1 == 3) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 2;
|
||||
}
|
||||
} else {
|
||||
int rfs = aboveSingle ? aboveRefFrame0 : leftRefFrame0;
|
||||
int crf1 = aboveSingle ? leftRefFrame0 : aboveRefFrame0;
|
||||
int crf2 = aboveSingle ? leftRefFrame1 : aboveRefFrame1;
|
||||
if (bin == 0) {
|
||||
if (rfs == 1) {
|
||||
ctx = 3 + ((crf1 == 1 || crf2 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = (crf1 == 1 || crf2 == 1) ? 1 : 0;
|
||||
}
|
||||
} else if (rfs == 3) {
|
||||
ctx = 3 + ((crf1 == 3 || crf2 == 3) ? 1 : 0);
|
||||
} else if (rfs == 2) {
|
||||
ctx = (crf1 == 3 || crf2 == 3) ? 1 : 0;
|
||||
} else {
|
||||
ctx = 1 + 2 * ((crf1 == 3 || crf2 == 3) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
} else if (availAbove) {
|
||||
if (aboveIntra || (bin == 1 && aboveRefFrame0 == 1 && aboveSingle)) {
|
||||
ctx = 2;
|
||||
} else if (aboveSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 4 * ((aboveRefFrame0 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 4 * ((aboveRefFrame0 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (bin == 0) {
|
||||
ctx = 1 + ((aboveRefFrame0 == 1 || aboveRefFrame1 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 3 * ((aboveRefFrame0 == 3 || aboveRefFrame1 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (availLeft) {
|
||||
if (leftIntra || (bin == 1 && leftRefFrame0 == 1 && leftSingle)) {
|
||||
ctx = 2;
|
||||
} else if (leftSingle) {
|
||||
if (bin == 0) {
|
||||
ctx = 4 * ((leftRefFrame0 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 4 * ((leftRefFrame0 == 3) ? 1 : 0);
|
||||
}
|
||||
} else if (bin == 0) {
|
||||
ctx = 1 + ((leftRefFrame0 == 1 || leftRefFrame1 == 1) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 3 * ((leftRefFrame0 == 3 || leftRefFrame1 == 3) ? 1 : 0);
|
||||
}
|
||||
} else {
|
||||
ctx = 2;
|
||||
}
|
||||
int[][] probs = c.getSingleRefProbs();
|
||||
return (decoder.readBit(probs[ctx][bin]) == 1);
|
||||
}
|
||||
|
||||
protected boolean readRefMode(int miCol, int miRow, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx;
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
boolean[] aboveCompound = c.getAboveCompound();
|
||||
boolean[] leftCompound = c.getLeftCompound();
|
||||
int aboveRefFrame0 = getRef(c.getAboveRefs()[miCol], 0);
|
||||
int leftRefFrame0 = getRef(c.getLeftRefs()[miRow & 0x7], 0);
|
||||
int compFixedRef = c.getCompFixedRef();
|
||||
boolean aboveSingle = !aboveCompound[miCol];
|
||||
boolean leftSingle = !leftCompound[miRow % 8];
|
||||
boolean aboveIntra = (aboveRefFrame0 <= 0);
|
||||
boolean leftIntra = (leftRefFrame0 <= 0);
|
||||
if (availAbove && availLeft) {
|
||||
if (aboveSingle && leftSingle) {
|
||||
ctx = (((aboveRefFrame0 == compFixedRef) ? true : false) ^ ((leftRefFrame0 == compFixedRef) ? true : false)) ? 1 : 0;
|
||||
} else if (aboveSingle) {
|
||||
ctx = 2 + ((aboveRefFrame0 == compFixedRef || aboveIntra) ? 1 : 0);
|
||||
} else if (leftSingle) {
|
||||
ctx = 2 + ((leftRefFrame0 == compFixedRef || leftIntra) ? 1 : 0);
|
||||
} else {
|
||||
ctx = 4;
|
||||
}
|
||||
} else if (availAbove) {
|
||||
if (aboveSingle) {
|
||||
ctx = (aboveRefFrame0 == compFixedRef) ? 1 : 0;
|
||||
} else {
|
||||
ctx = 3;
|
||||
}
|
||||
} else if (availLeft) {
|
||||
if (leftSingle) {
|
||||
ctx = (leftRefFrame0 == compFixedRef) ? 1 : 0;
|
||||
} else {
|
||||
ctx = 3;
|
||||
}
|
||||
} else {
|
||||
ctx = 1;
|
||||
}
|
||||
int[] probs = c.getCompModeProb();
|
||||
return (decoder.readBit(probs[ctx]) == 1);
|
||||
}
|
||||
|
||||
private InterModeInfo readInterIntraMode(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, int segmentId, boolean skip, int txSize) {
|
||||
int yMode;
|
||||
int subModes = 0;
|
||||
if (blSz >= 3) {
|
||||
yMode = readInterIntraMode(miCol, miRow, blSz, decoder, c);
|
||||
} else {
|
||||
subModes = readInterIntraModeSub(miCol, miRow, blSz, decoder, c);
|
||||
yMode = subModes & 0xFF;
|
||||
}
|
||||
int uvMode = readKfUvMode(yMode, decoder, c);
|
||||
return new InterModeInfo(segmentId, skip, txSize, yMode, subModes, uvMode, 0L, 0L, 0L, 0L);
|
||||
}
|
||||
|
||||
protected int readInterIntraMode(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[][] probs = c.getYModeProbs();
|
||||
return decoder.readTree(Consts.TREE_INTRA_MODE, probs[Consts.size_group_lookup[blSz]]);
|
||||
}
|
||||
|
||||
protected int readInterIntraModeSub(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[][] probs = c.getYModeProbs();
|
||||
int mode0 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[0]);
|
||||
int mode1 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[0]);
|
||||
int mode2 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[0]);
|
||||
int mode3 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[0]);
|
||||
return ModeInfo.vect4(mode0, mode1, mode2, mode3);
|
||||
}
|
||||
|
||||
public int readKfUvMode(int yMode, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[][] probs = c.getUvModeProbs();
|
||||
return decoder.readTree(Consts.TREE_INTRA_MODE, probs[yMode]);
|
||||
}
|
||||
|
||||
protected boolean readIsInter(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
int aboveRefFrame0 = getRef(c.getAboveRefs()[miCol], 0);
|
||||
int leftRefFrame0 = getRef(c.getLeftRefs()[miRow & 0x7], 0);
|
||||
boolean leftIntra = availLeft ? ((leftRefFrame0 <= 0)) : true;
|
||||
boolean aboveIntra = availAbove ? ((aboveRefFrame0 <= 0)) : true;
|
||||
int ctx = 0;
|
||||
if (availAbove && availLeft) {
|
||||
ctx = (leftIntra && aboveIntra) ? 3 : ((leftIntra || aboveIntra) ? 1 : 0);
|
||||
} else if (availAbove || availLeft) {
|
||||
ctx = 2 * (availAbove ? (aboveIntra ? 1 : 0) : (leftIntra ? 1 : 0));
|
||||
}
|
||||
int[] probs = c.getIsInterProbs();
|
||||
return (decoder.readBit(probs[ctx]) == 1);
|
||||
}
|
||||
|
||||
private static boolean readSegIdPredicted(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
boolean[] aboveSegIdPredicted = c.getAboveSegIdPredicted();
|
||||
boolean[] leftSegIdPredicted = c.getLeftSegIdPredicted();
|
||||
int ctx = (aboveSegIdPredicted[miRow] ? 1 : 0) + (leftSegIdPredicted[miCol] ? 1 : 0);
|
||||
int[] prob = c.getSegmentationPredProbs();
|
||||
boolean ret = (decoder.readBit(prob[ctx]) == 1);
|
||||
for (int j = 0; j < Consts.blH[blSz]; j++)
|
||||
aboveSegIdPredicted[miCol + j] = ret;
|
||||
for (int i = 0; i < Consts.blW[blSz]; i++)
|
||||
leftSegIdPredicted[miRow + i] = ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int predicSegmentId(int miCol, int miRow, int blSz, DecodingContext c) {
|
||||
int blWcl = Math.min(c.getMiTileWidth() - miCol, Consts.blW[blSz]);
|
||||
int blHcl = Math.min(c.getMiTileHeight() - miRow, Consts.blH[blSz]);
|
||||
int[][] prevSegmentIds = c.getPrevSegmentIds();
|
||||
int seg = 7;
|
||||
for (int y = 0; y < blHcl; y++) {
|
||||
for (int x = 0; x < blWcl; x++)
|
||||
seg = Math.min(seg, prevSegmentIds[miRow + y][miCol + x]);
|
||||
}
|
||||
return seg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
public class MV {
|
||||
public static int create(int x, int y, int ref) {
|
||||
return ref << 28 | (y & 0x3FFF) << 14 | x & 0x3FFF;
|
||||
}
|
||||
|
||||
public static int x(int mv) {
|
||||
return mv << 18 >> 18;
|
||||
}
|
||||
|
||||
public static int y(int mv) {
|
||||
return mv << 4 >> 18;
|
||||
}
|
||||
|
||||
public static int ref(int mv) {
|
||||
return mv >> 28 & 0x3;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
public class MVList {
|
||||
private static long LO_MASK = Integer.MAX_VALUE;
|
||||
|
||||
private static long HI_MASK = LO_MASK << 31L;
|
||||
|
||||
private static long HI_MASK_NEG = (HI_MASK | 0xC000000000000000L) ^ 0xFFFFFFFFFFFFFFFFL;
|
||||
|
||||
private static long LO_MASK_NEG = (LO_MASK | 0xC000000000000000L) ^ 0xFFFFFFFFFFFFFFFFL;
|
||||
|
||||
public static long create(int mv0, int mv1) {
|
||||
return Long.MIN_VALUE | (long)mv1 << 31L | (long)mv0 & LO_MASK;
|
||||
}
|
||||
|
||||
public static long addUniq(long list, int mv) {
|
||||
long cnt = list >> 62L & 0x3L;
|
||||
if (cnt == 2L)
|
||||
return list;
|
||||
if (cnt == 0L)
|
||||
return 0x4000000000000000L | list & LO_MASK_NEG | (long)mv & LO_MASK;
|
||||
int first = (int)(list & LO_MASK);
|
||||
if (first != mv)
|
||||
return Long.MIN_VALUE | list & HI_MASK_NEG | (long)mv << 31L & HI_MASK;
|
||||
return list;
|
||||
}
|
||||
|
||||
public static long add(long list, int mv) {
|
||||
long cnt = list >> 62L & 0x3L;
|
||||
if (cnt == 2L)
|
||||
return list;
|
||||
if (cnt == 0L)
|
||||
return 0x4000000000000000L | list & LO_MASK_NEG | (long)mv & LO_MASK;
|
||||
return Long.MIN_VALUE | list & HI_MASK_NEG | (long)mv << 31L & HI_MASK;
|
||||
}
|
||||
|
||||
public static int get(long list, int n) {
|
||||
if (n == 0)
|
||||
return (int)(list & LO_MASK);
|
||||
return (int)(list >> 31L & LO_MASK);
|
||||
}
|
||||
|
||||
public static long set(long list, int n, int mv) {
|
||||
long cnt = list >> 62L & 0x3L;
|
||||
long newc = (long)(n + 1);
|
||||
cnt = (newc > cnt) ? newc : cnt;
|
||||
if (n == 0)
|
||||
return cnt << 62L | list & LO_MASK_NEG | (long)mv & LO_MASK;
|
||||
return cnt << 62L | list & HI_MASK_NEG | (long)mv << 31L & HI_MASK;
|
||||
}
|
||||
|
||||
public static int size(long list) {
|
||||
return (int)(list >> 62L & 0x3L);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
import org.jcodec.codecs.vpx.VPXBooleanDecoder;
|
||||
|
||||
public class ModeInfo {
|
||||
private int segmentId;
|
||||
|
||||
private boolean skip;
|
||||
|
||||
private int txSize;
|
||||
|
||||
private int yMode;
|
||||
|
||||
private int subModes;
|
||||
|
||||
private int uvMode;
|
||||
|
||||
ModeInfo() {}
|
||||
|
||||
public ModeInfo(int segmentId, boolean skip, int txSize, int yMode, int subModes, int uvMode) {
|
||||
this.segmentId = segmentId;
|
||||
this.skip = skip;
|
||||
this.txSize = txSize;
|
||||
this.yMode = yMode;
|
||||
this.subModes = subModes;
|
||||
this.uvMode = uvMode;
|
||||
}
|
||||
|
||||
public int getSegmentId() {
|
||||
return this.segmentId;
|
||||
}
|
||||
|
||||
public boolean isSkip() {
|
||||
return this.skip;
|
||||
}
|
||||
|
||||
public int getTxSize() {
|
||||
return this.txSize;
|
||||
}
|
||||
|
||||
public int getYMode() {
|
||||
return this.yMode;
|
||||
}
|
||||
|
||||
public int getSubModes() {
|
||||
return this.subModes;
|
||||
}
|
||||
|
||||
public int getUvMode() {
|
||||
return this.uvMode;
|
||||
}
|
||||
|
||||
public ModeInfo read(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int yMode;
|
||||
int segmentId = 0;
|
||||
if (c.isSegmentationEnabled() && c.isUpdateSegmentMap())
|
||||
segmentId = readSegmentId(decoder, c);
|
||||
boolean skip = true;
|
||||
if (!c.isSegmentFeatureActive(segmentId, 3))
|
||||
skip = readSkipFlag(miCol, miRow, blSz, decoder, c);
|
||||
int txSize = readTxSize(miCol, miRow, blSz, true, decoder, c);
|
||||
int subModes = 0;
|
||||
if (blSz >= 3) {
|
||||
yMode = readKfIntraMode(miCol, miRow, blSz, decoder, c);
|
||||
} else {
|
||||
subModes = readKfIntraModeSub(miCol, miRow, blSz, decoder, c);
|
||||
yMode = subModes & 0xFF;
|
||||
}
|
||||
int uvMode = readInterIntraUvMode(yMode, decoder, c);
|
||||
return new ModeInfo(segmentId, skip, txSize, yMode, subModes, uvMode);
|
||||
}
|
||||
|
||||
public int readKfIntraMode(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
int[] aboveIntraModes = c.getAboveModes();
|
||||
int[] leftIntraModes = c.getLeftModes();
|
||||
int aboveMode = availAbove ? aboveIntraModes[miCol] : 0;
|
||||
int leftMode = availLeft ? leftIntraModes[miRow % 8] : 0;
|
||||
int[][][] probs = c.getKfYModeProbs();
|
||||
int intraMode = decoder.readTree(Consts.TREE_INTRA_MODE, probs[aboveMode][leftMode]);
|
||||
aboveIntraModes[miCol] = intraMode;
|
||||
leftIntraModes[miRow % 8] = intraMode;
|
||||
return intraMode;
|
||||
}
|
||||
|
||||
public int readKfIntraModeSub(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
int[] aboveIntraModes = c.getAboveModes();
|
||||
int[] leftIntraModes = c.getLeftModes();
|
||||
int[][][] probs = c.getKfYModeProbs();
|
||||
int aboveMode = availAbove ? aboveIntraModes[miCol] : 0;
|
||||
int leftMode = availLeft ? leftIntraModes[miRow & 0x7] : 0;
|
||||
int mode0 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[aboveMode][leftMode]);
|
||||
int mode1 = 0, mode2 = 0, mode3 = 0;
|
||||
if (blSz == 0) {
|
||||
mode1 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[aboveMode][mode0]);
|
||||
mode2 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[mode0][leftMode]);
|
||||
mode3 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[mode1][mode2]);
|
||||
aboveIntraModes[miCol] = mode2;
|
||||
leftIntraModes[miRow & 0x7] = mode1;
|
||||
return vect4(mode0, mode1, mode2, mode3);
|
||||
}
|
||||
if (blSz == 1) {
|
||||
mode1 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[aboveMode][mode0]);
|
||||
aboveIntraModes[miCol] = mode0;
|
||||
leftIntraModes[miRow & 0x7] = mode1;
|
||||
return vect4(mode0, mode1, mode0, mode1);
|
||||
}
|
||||
if (blSz == 2) {
|
||||
mode1 = decoder.readTree(Consts.TREE_INTRA_MODE, probs[mode0][leftMode]);
|
||||
aboveIntraModes[miCol] = mode1;
|
||||
leftIntraModes[miRow & 0x7] = mode0;
|
||||
return vect4(mode0, mode0, mode1, mode1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int vect4(int val0, int val1, int val2, int val3) {
|
||||
return val0 | val1 << 8 | val2 << 16 | val3 << 24;
|
||||
}
|
||||
|
||||
public static int vect4get(int vect, int ind) {
|
||||
return vect >> ind << 3 & 0xFF;
|
||||
}
|
||||
|
||||
public int readTxSize(int miCol, int miRow, int blSz, boolean allowSelect, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
if (blSz < 3)
|
||||
return 0;
|
||||
int maxTxSize = Consts.maxTxLookup[blSz];
|
||||
int txSize = Math.min(maxTxSize, c.getTxMode());
|
||||
if (allowSelect && c.getTxMode() == 4) {
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
int above = maxTxSize;
|
||||
int left = maxTxSize;
|
||||
if (availAbove && !c.getAboveSkipped()[miCol])
|
||||
above = c.getAboveTxSizes()[miCol];
|
||||
if (availLeft && !c.getLeftSkipped()[miRow & 0x7])
|
||||
left = c.getLeftTxSizes()[miRow & 0x7];
|
||||
if (!availLeft)
|
||||
left = above;
|
||||
if (!availAbove)
|
||||
above = left;
|
||||
int ctx = (above + left > maxTxSize) ? 1 : 0;
|
||||
int[][] probs = null;
|
||||
switch (maxTxSize) {
|
||||
case 3:
|
||||
probs = c.getTx32x32Probs();
|
||||
break;
|
||||
case 2:
|
||||
probs = c.getTx16x16Probs();
|
||||
break;
|
||||
case 1:
|
||||
probs = c.getTx8x8Probs();
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Shouldn't happen");
|
||||
}
|
||||
txSize = decoder.readTree(Consts.TREE_TX_SIZE[maxTxSize], probs[ctx]);
|
||||
} else {
|
||||
txSize = Math.min(maxTxSize, c.getTxMode());
|
||||
}
|
||||
for (int i = 0; i < Consts.blH[blSz]; i++)
|
||||
c.getLeftTxSizes()[miRow + i & 0x7] = txSize;
|
||||
for (int j = 0; j < Consts.blW[blSz]; j++)
|
||||
c.getAboveTxSizes()[miCol + j & 0x7] = txSize;
|
||||
return txSize;
|
||||
}
|
||||
|
||||
public static int readSegmentId(VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[] probs = c.getSegmentationTreeProbs();
|
||||
return decoder.readTree(Consts.TREE_SEGMENT_ID, probs);
|
||||
}
|
||||
|
||||
public boolean readSkipFlag(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int ctx = 0;
|
||||
boolean availAbove = (miRow > 0);
|
||||
boolean availLeft = (miCol > c.getMiTileStartCol());
|
||||
boolean[] aboveSkipped = c.getAboveSkipped();
|
||||
boolean[] leftSkipped = c.getLeftSkipped();
|
||||
if (availAbove)
|
||||
ctx += aboveSkipped[miCol] ? 1 : 0;
|
||||
if (availLeft)
|
||||
ctx += leftSkipped[miRow & 0x7] ? 1 : 0;
|
||||
System.out.println("SKIP CTX: " + ctx);
|
||||
int[] probs = c.getSkipProbs();
|
||||
boolean ret = (decoder.readBit(probs[ctx]) == 1);
|
||||
for (int i = 0; i < Consts.blH[blSz]; i++)
|
||||
leftSkipped[i + miRow & 0x7] = ret;
|
||||
for (int j = 0; j < Consts.blW[blSz]; j++)
|
||||
aboveSkipped[j + miCol] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean isInter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int readInterIntraUvMode(int yMode, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[][] probs = c.getKfUVModeProbs();
|
||||
return decoder.readTree(Consts.TREE_INTRA_MODE, probs[yMode]);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,159 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
import org.jcodec.codecs.vpx.VPXBooleanDecoder;
|
||||
|
||||
public class Residual {
|
||||
private int[][][] coefs;
|
||||
|
||||
public Residual(int[][][] coefs) {
|
||||
this.coefs = coefs;
|
||||
}
|
||||
|
||||
protected Residual() {}
|
||||
|
||||
public static Residual readResidual(int miCol, int miRow, int blSz, VPXBooleanDecoder decoder, DecodingContext c, ModeInfo mode) {
|
||||
Residual ret = new Residual();
|
||||
ret.read(miCol, miRow, blSz, decoder, c, mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void read(int miCol, int miRow, int blType, VPXBooleanDecoder decoder, DecodingContext c, ModeInfo modeInfo) {
|
||||
if (modeInfo.isSkip())
|
||||
return;
|
||||
int subXRound = (1 << c.getSubX()) - 1;
|
||||
int subYRound = (1 << c.getSubY()) - 1;
|
||||
int[][][] coefs = new int[3][][];
|
||||
for (int pl = 0; pl < 3; pl++) {
|
||||
int txSize = (pl == 0) ? modeInfo.getTxSize() :
|
||||
Consts.uv_txsize_lookup[blType][modeInfo.getTxSize()][c.getSubX()][c.getSubY()];
|
||||
int step4x4 = 1 << txSize;
|
||||
int n4w = 1 << Consts.blW[blType];
|
||||
int n4h = 1 << Consts.blH[blType];
|
||||
if (pl != 0) {
|
||||
n4w >>= c.getSubX();
|
||||
n4h >>= c.getSubY();
|
||||
}
|
||||
int extra4w = (miCol << 1) + n4w - (c.getFrameWidth() + 3 >> 2);
|
||||
int extra4h = (miRow << 1) + n4h - (c.getFrameHeight() + 3 >> 2);
|
||||
int startBlkX = miCol << 1;
|
||||
int startBlkY = miRow << 1;
|
||||
if (pl != 0) {
|
||||
extra4w = extra4w + subXRound >> c.getSubX();
|
||||
extra4h = extra4h + subYRound >> c.getSubY();
|
||||
startBlkX >>= c.getSubX();
|
||||
startBlkY >>= c.getSubY();
|
||||
}
|
||||
int max4w = n4w - ((extra4w > 0) ? extra4w : 0);
|
||||
int max4h = n4h - ((extra4h > 0) ? extra4h : 0);
|
||||
coefs[pl] = new int[n4w * n4h][];
|
||||
for (int y = 0; y < max4h; y += step4x4) {
|
||||
for (int x = 0; x < max4w; x += step4x4) {
|
||||
int predMode;
|
||||
int blkCol = startBlkX + x;
|
||||
int blkRow = startBlkY + y;
|
||||
if (pl == 0) {
|
||||
predMode = modeInfo.getYMode();
|
||||
if (blType < 3)
|
||||
predMode = ModeInfo.vect4get(modeInfo.getSubModes(), (y << 1) + x);
|
||||
} else {
|
||||
predMode = modeInfo.getUvMode();
|
||||
}
|
||||
coefs[pl][x + n4w * y] = readOneTU((pl == 0) ? 0 : 1, blkCol, blkRow, txSize, modeInfo.isInter(), predMode, decoder, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.coefs = coefs;
|
||||
}
|
||||
|
||||
public static int[][] blk_size_lookup = new int[][] { new int[] { -1, 0, 2 }, new int[] { 1, 3, 5 }, new int[] { 4, 6, 8 }, new int[] { 7, 9, 11 }, new int[] { 10, 12, -1 } };
|
||||
|
||||
public int[] readOneTU(int plane, int blkCol, int blkRow, int txSz, boolean isInter, int intraMode, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int[] tokenCache = new int[16 << txSz << 1];
|
||||
int maxCoeff = 16 << txSz << 1;
|
||||
boolean expectMoreCoefs = false;
|
||||
int txType = (plane == 0 && !isInter) ? Consts.intra_mode_to_tx_type_lookup[intraMode] : 0;
|
||||
int[] scan = (plane == 0 && !isInter) ? Scan.vp9_scan_orders[txSz][txType][0] :
|
||||
Scan.vp9_default_scan_orders[txSz][0];
|
||||
int[] neighbors = (plane == 0 && !isInter) ? Scan.vp9_scan_orders[txSz][txType][2] :
|
||||
Scan.vp9_default_scan_orders[txSz][2];
|
||||
int[] coefs = new int[maxCoeff];
|
||||
int ctx = calcTokenContextCoef0(plane, txSz, blkCol, blkRow, c);
|
||||
for (int cf = 0; cf < maxCoeff; cf++) {
|
||||
int band = (txSz == 0) ? Consts.coefband_4x4[cf] : Consts.coefband_8x8plus[cf];
|
||||
int pos = scan[cf];
|
||||
int[] probs = c.getCoefProbs()[txSz][(plane > 0) ? 1 : 0][isInter ? 1 : 0][band][ctx];
|
||||
if (!expectMoreCoefs) {
|
||||
boolean moreCoefs = (decoder.readBit(probs[0]) == 1);
|
||||
if (!moreCoefs)
|
||||
break;
|
||||
}
|
||||
if (decoder.readBit(probs[1]) == 0) {
|
||||
tokenCache[pos] = 0;
|
||||
expectMoreCoefs = true;
|
||||
} else {
|
||||
int coef;
|
||||
expectMoreCoefs = false;
|
||||
if (decoder.readBit(probs[2]) == 0) {
|
||||
tokenCache[pos] = 1;
|
||||
coef = 1;
|
||||
} else {
|
||||
int token = decoder.readTree(Consts.TOKEN_TREE, Consts.PARETO_TABLE[probs[2] - 1]);
|
||||
if (token < 5) {
|
||||
coef = token;
|
||||
if (token == 2) {
|
||||
tokenCache[pos] = 2;
|
||||
} else {
|
||||
tokenCache[pos] = 3;
|
||||
}
|
||||
} else {
|
||||
if (token < 7) {
|
||||
tokenCache[pos] = 4;
|
||||
} else {
|
||||
tokenCache[pos] = 5;
|
||||
}
|
||||
coef = readCoef(token, decoder, c);
|
||||
}
|
||||
}
|
||||
int sign = decoder.readBitEq();
|
||||
coefs[pos] = (sign == 1) ? -coef : coef;
|
||||
}
|
||||
ctx = 1 + tokenCache[neighbors[2 * cf + 2]] + tokenCache[neighbors[2 * cf + 3]] >> 1;
|
||||
System.out.println("CTX: " + ctx);
|
||||
}
|
||||
return coefs;
|
||||
}
|
||||
|
||||
private static int readCoef(int token, VPXBooleanDecoder decoder, DecodingContext c) {
|
||||
int cat = Consts.extra_bits[token][0];
|
||||
int numExtra = Consts.extra_bits[token][1];
|
||||
int coef = Consts.extra_bits[token][2];
|
||||
for (int bit = 0; bit < numExtra; bit++) {
|
||||
int coef_bit = decoder.readBit(Consts.cat_probs[cat][bit]);
|
||||
coef += coef_bit << numExtra - 1 - bit;
|
||||
}
|
||||
return coef;
|
||||
}
|
||||
|
||||
private static int calcTokenContextCoef0(int plane, int txSz, int blkCol, int blkRow, DecodingContext c) {
|
||||
int[][] aboveNonzeroContext = c.getAboveNonzeroContext();
|
||||
int[][] leftNonzeroContext = c.getLeftNonzeroContext();
|
||||
int subX = (plane > 0) ? c.getSubX() : 0;
|
||||
int subY = (plane > 0) ? c.getSubY() : 0;
|
||||
int max4x = c.getMiFrameWidth() << 1 >> subX;
|
||||
int max4y = c.getMiFrameHeight() << 1 >> subY;
|
||||
int tx4 = 1 << txSz;
|
||||
int aboveNz = 0;
|
||||
int leftNz = 0;
|
||||
for (int i = 0; i < tx4; i++) {
|
||||
if (blkCol + i < max4x)
|
||||
aboveNz |= aboveNonzeroContext[plane][blkCol + i];
|
||||
if (blkRow + i < max4y)
|
||||
leftNz |= leftNonzeroContext[plane][blkRow + i & 0xF];
|
||||
}
|
||||
return aboveNz + leftNz;
|
||||
}
|
||||
|
||||
public int[][][] getCoefs() {
|
||||
return this.coefs;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,895 @@
|
|||
package org.jcodec.codecs.vpx.vp9;
|
||||
|
||||
public class Scan {
|
||||
private static final int[] default_scan_4x4 = new int[] {
|
||||
0, 4, 1, 5, 8, 2, 12, 9, 3, 6,
|
||||
13, 10, 7, 14, 11, 15 };
|
||||
|
||||
private static final int[] col_scan_4x4 = new int[] {
|
||||
0, 4, 8, 1, 12, 5, 9, 2, 13, 6,
|
||||
10, 3, 7, 14, 11, 15 };
|
||||
|
||||
private static final int[] row_scan_4x4 = new int[] {
|
||||
0, 1, 4, 2, 5, 3, 6, 8, 9, 7,
|
||||
12, 10, 13, 11, 14, 15 };
|
||||
|
||||
private static final int[] default_scan_8x8 = new int[] {
|
||||
0, 8, 1, 16, 9, 2, 17, 24, 10, 3,
|
||||
18, 25, 32, 11, 4, 26, 33, 19, 40, 12,
|
||||
34, 27, 5, 41, 20, 48, 13, 35, 42, 28,
|
||||
21, 6, 49, 56, 36, 43, 29, 7, 14, 50,
|
||||
57, 44, 22, 37, 15, 51, 58, 30, 45, 23,
|
||||
52, 59, 38, 31, 60, 53, 46, 39, 61, 54,
|
||||
47, 62, 55, 63 };
|
||||
|
||||
private static final int[] col_scan_8x8 = new int[] {
|
||||
0, 8, 16, 1, 24, 9, 32, 17, 2, 40,
|
||||
25, 10, 33, 18, 48, 3, 26, 41, 11, 56,
|
||||
19, 34, 4, 49, 27, 42, 12, 35, 20, 57,
|
||||
50, 28, 5, 43, 13, 36, 58, 51, 21, 44,
|
||||
6, 29, 59, 37, 14, 52, 22, 7, 45, 60,
|
||||
30, 15, 38, 53, 23, 46, 31, 61, 39, 54,
|
||||
47, 62, 55, 63 };
|
||||
|
||||
private static final int[] row_scan_8x8 = new int[] {
|
||||
0, 1, 2, 8, 9, 3, 16, 10, 4, 17,
|
||||
11, 24, 5, 18, 25, 12, 19, 26, 32, 6,
|
||||
13, 20, 33, 27, 7, 34, 40, 21, 28, 41,
|
||||
14, 35, 48, 42, 29, 36, 49, 22, 43, 15,
|
||||
56, 37, 50, 44, 30, 57, 23, 51, 58, 45,
|
||||
38, 52, 31, 59, 53, 46, 60, 39, 61, 47,
|
||||
54, 55, 62, 63 };
|
||||
|
||||
private static final int[] default_scan_16x16 = new int[] {
|
||||
0, 16, 1, 32, 17, 2, 48, 33, 18, 3,
|
||||
64, 34, 49, 19, 65, 80, 50, 4, 35, 66,
|
||||
20, 81, 96, 51, 5, 36, 82, 97, 67, 112,
|
||||
21, 52, 98, 37, 83, 113, 6, 68, 128, 53,
|
||||
22, 99, 114, 84, 7, 129, 38, 69, 100, 115,
|
||||
144, 130, 85, 54, 23, 8, 145, 39, 70, 116,
|
||||
101, 131, 160, 146, 55, 86, 24, 71, 132, 117,
|
||||
161, 40, 9, 102, 147, 176, 162, 87, 56, 25,
|
||||
133, 118, 177, 148, 72, 103, 41, 163, 10, 192,
|
||||
178, 88, 57, 134, 149, 119, 26, 164, 73, 104,
|
||||
193, 42, 179, 208, 11, 135, 89, 165, 120, 150,
|
||||
58, 194, 180, 27, 74, 209, 105, 151, 136, 43,
|
||||
90, 224, 166, 195, 181, 121, 210, 59, 12, 152,
|
||||
106, 167, 196, 75, 137, 225, 211, 240, 182, 122,
|
||||
91, 28, 197, 13, 226, 168, 183, 153, 44, 212,
|
||||
138, 107, 241, 60, 29, 123, 198, 184, 227, 169,
|
||||
242, 76, 213, 154, 45, 92, 14, 199, 139, 61,
|
||||
228, 214, 170, 185, 243, 108, 77, 155, 30, 15,
|
||||
200, 229, 124, 215, 244, 93, 46, 186, 171, 201,
|
||||
109, 140, 230, 62, 216, 245, 31, 125, 78, 156,
|
||||
231, 47, 187, 202, 217, 94, 246, 141, 63, 232,
|
||||
172, 110, 247, 157, 79, 218, 203, 126, 233, 188,
|
||||
248, 95, 173, 142, 219, 111, 249, 234, 158, 127,
|
||||
189, 204, 250, 235, 143, 174, 220, 205, 159, 251,
|
||||
190, 221, 175, 236, 237, 191, 206, 252, 222, 253,
|
||||
207, 238, 223, 254, 239, 255 };
|
||||
|
||||
private static final int[] col_scan_16x16 = new int[] {
|
||||
0, 16, 32, 48, 1, 64, 17, 80, 33, 96,
|
||||
49, 2, 65, 112, 18, 81, 34, 128, 50, 97,
|
||||
3, 66, 144, 19, 113, 35, 82, 160, 98, 51,
|
||||
129, 4, 67, 176, 20, 114, 145, 83, 36, 99,
|
||||
130, 52, 192, 5, 161, 68, 115, 21, 146, 84,
|
||||
208, 177, 37, 131, 100, 53, 162, 224, 69, 6,
|
||||
116, 193, 147, 85, 22, 240, 132, 38, 178, 101,
|
||||
163, 54, 209, 117, 70, 7, 148, 194, 86, 179,
|
||||
225, 23, 133, 39, 164, 8, 102, 210, 241, 55,
|
||||
195, 118, 149, 71, 180, 24, 87, 226, 134, 165,
|
||||
211, 40, 103, 56, 72, 150, 196, 242, 119, 9,
|
||||
181, 227, 88, 166, 25, 135, 41, 104, 212, 57,
|
||||
151, 197, 120, 73, 243, 182, 136, 167, 213, 89,
|
||||
10, 228, 105, 152, 198, 26, 42, 121, 183, 244,
|
||||
168, 58, 137, 229, 74, 214, 90, 153, 199, 184,
|
||||
11, 106, 245, 27, 122, 230, 169, 43, 215, 59,
|
||||
200, 138, 185, 246, 75, 12, 91, 154, 216, 231,
|
||||
107, 28, 44, 201, 123, 170, 60, 247, 232, 76,
|
||||
139, 13, 92, 217, 186, 248, 155, 108, 29, 124,
|
||||
45, 202, 233, 171, 61, 14, 77, 140, 15, 249,
|
||||
93, 30, 187, 156, 218, 46, 109, 125, 62, 172,
|
||||
78, 203, 31, 141, 234, 94, 47, 188, 63, 157,
|
||||
110, 250, 219, 79, 126, 204, 173, 142, 95, 189,
|
||||
111, 235, 158, 220, 251, 127, 174, 143, 205, 236,
|
||||
159, 190, 221, 252, 175, 206, 237, 191, 253, 222,
|
||||
238, 207, 254, 223, 239, 255 };
|
||||
|
||||
private static final int[] row_scan_16x16 = new int[] {
|
||||
0, 1, 2, 16, 3, 17, 4, 18, 32, 5,
|
||||
33, 19, 6, 34, 48, 20, 49, 7, 35, 21,
|
||||
50, 64, 8, 36, 65, 22, 51, 37, 80, 9,
|
||||
66, 52, 23, 38, 81, 67, 10, 53, 24, 82,
|
||||
68, 96, 39, 11, 54, 83, 97, 69, 25, 98,
|
||||
84, 40, 112, 55, 12, 70, 99, 113, 85, 26,
|
||||
41, 56, 114, 100, 13, 71, 128, 86, 27, 115,
|
||||
101, 129, 42, 57, 72, 116, 14, 87, 130, 102,
|
||||
144, 73, 131, 117, 28, 58, 15, 88, 43, 145,
|
||||
103, 132, 146, 118, 74, 160, 89, 133, 104, 29,
|
||||
59, 147, 119, 44, 161, 148, 90, 105, 134, 162,
|
||||
120, 176, 75, 135, 149, 30, 60, 163, 177, 45,
|
||||
121, 91, 106, 164, 178, 150, 192, 136, 165, 179,
|
||||
31, 151, 193, 76, 122, 61, 137, 194, 107, 152,
|
||||
180, 208, 46, 166, 167, 195, 92, 181, 138, 209,
|
||||
123, 153, 224, 196, 77, 168, 210, 182, 240, 108,
|
||||
197, 62, 154, 225, 183, 169, 211, 47, 139, 93,
|
||||
184, 226, 212, 241, 198, 170, 124, 155, 199, 78,
|
||||
213, 185, 109, 227, 200, 63, 228, 242, 140, 214,
|
||||
171, 186, 156, 229, 243, 125, 94, 201, 244, 215,
|
||||
216, 230, 141, 187, 202, 79, 172, 110, 157, 245,
|
||||
217, 231, 95, 246, 232, 126, 203, 247, 233, 173,
|
||||
218, 142, 111, 158, 188, 248, 127, 234, 219, 249,
|
||||
189, 204, 143, 174, 159, 250, 235, 205, 220, 175,
|
||||
190, 251, 221, 191, 206, 236, 207, 237, 252, 222,
|
||||
253, 223, 238, 239, 254, 255 };
|
||||
|
||||
private static final int[] default_scan_32x32 = new int[] {
|
||||
0, 32, 1, 64, 33, 2, 96, 65, 34, 128,
|
||||
3, 97, 66, 160, 129, 35, 98, 4, 67, 130,
|
||||
161, 192, 36, 99, 224, 5, 162, 193, 68, 131,
|
||||
37, 100, 225, 194, 256, 163, 69, 132, 6, 226,
|
||||
257, 288, 195, 101, 164, 38, 258, 7, 227, 289,
|
||||
133, 320, 70, 196, 165, 290, 259, 228, 39, 321,
|
||||
102, 352, 8, 197, 71, 134, 322, 291, 260, 353,
|
||||
384, 229, 166, 103, 40, 354, 323, 292, 135, 385,
|
||||
198, 261, 72, 9, 416, 167, 386, 355, 230, 324,
|
||||
104, 293, 41, 417, 199, 136, 262, 387, 448, 325,
|
||||
356, 10, 73, 418, 231, 168, 449, 294, 388, 105,
|
||||
419, 263, 42, 200, 357, 450, 137, 480, 74, 326,
|
||||
232, 11, 389, 169, 295, 420, 106, 451, 481, 358,
|
||||
264, 327, 201, 43, 138, 512, 482, 390, 296, 233,
|
||||
170, 421, 75, 452, 359, 12, 513, 265, 483, 328,
|
||||
107, 202, 514, 544, 422, 391, 453, 139, 44, 234,
|
||||
484, 297, 360, 171, 76, 515, 545, 266, 329, 454,
|
||||
13, 423, 203, 108, 546, 485, 576, 298, 235, 140,
|
||||
361, 330, 172, 547, 45, 455, 267, 577, 486, 77,
|
||||
204, 362, 608, 14, 299, 578, 109, 236, 487, 609,
|
||||
331, 141, 579, 46, 15, 173, 610, 363, 78, 205,
|
||||
16, 110, 237, 611, 142, 47, 174, 79, 206, 17,
|
||||
111, 238, 48, 143, 80, 175, 112, 207, 49, 18,
|
||||
239, 81, 113, 19, 50, 82, 114, 51, 83, 115,
|
||||
640, 516, 392, 268, 144, 20, 672, 641, 548, 517,
|
||||
424, 393, 300, 269, 176, 145, 52, 21, 704, 673,
|
||||
642, 580, 549, 518, 456, 425, 394, 332, 301, 270,
|
||||
208, 177, 146, 84, 53, 22, 736, 705, 674, 643,
|
||||
612, 581, 550, 519, 488, 457, 426, 395, 364, 333,
|
||||
302, 271, 240, 209, 178, 147, 116, 85, 54, 23,
|
||||
737, 706, 675, 613, 582, 551, 489, 458, 427, 365,
|
||||
334, 303, 241, 210, 179, 117, 86, 55, 738, 707,
|
||||
614, 583, 490, 459, 366, 335, 242, 211, 118, 87,
|
||||
739, 615, 491, 367, 243, 119, 768, 644, 520, 396,
|
||||
272, 148, 24, 800, 769, 676, 645, 552, 521, 428,
|
||||
397, 304, 273, 180, 149, 56, 25, 832, 801, 770,
|
||||
708, 677, 646, 584, 553, 522, 460, 429, 398, 336,
|
||||
305, 274, 212, 181, 150, 88, 57, 26, 864, 833,
|
||||
802, 771, 740, 709, 678, 647, 616, 585, 554, 523,
|
||||
492, 461, 430, 399, 368, 337, 306, 275, 244, 213,
|
||||
182, 151, 120, 89, 58, 27, 865, 834, 803, 741,
|
||||
710, 679, 617, 586, 555, 493, 462, 431, 369, 338,
|
||||
307, 245, 214, 183, 121, 90, 59, 866, 835, 742,
|
||||
711, 618, 587, 494, 463, 370, 339, 246, 215, 122,
|
||||
91, 867, 743, 619, 495, 371, 247, 123, 896, 772,
|
||||
648, 524, 400, 276, 152, 28, 928, 897, 804, 773,
|
||||
680, 649, 556, 525, 432, 401, 308, 277, 184, 153,
|
||||
60, 29, 960, 929, 898, 836, 805, 774, 712, 681,
|
||||
650, 588, 557, 526, 464, 433, 402, 340, 309, 278,
|
||||
216, 185, 154, 92, 61, 30, 992, 961, 930, 899,
|
||||
868, 837, 806, 775, 744, 713, 682, 651, 620, 589,
|
||||
558, 527, 496, 465, 434, 403, 372, 341, 310, 279,
|
||||
248, 217, 186, 155, 124, 93, 62, 31, 993, 962,
|
||||
931, 869, 838, 807, 745, 714, 683, 621, 590, 559,
|
||||
497, 466, 435, 373, 342, 311, 249, 218, 187, 125,
|
||||
94, 63, 994, 963, 870, 839, 746, 715, 622, 591,
|
||||
498, 467, 374, 343, 250, 219, 126, 95, 995, 871,
|
||||
747, 623, 499, 375, 251, 127, 900, 776, 652, 528,
|
||||
404, 280, 156, 932, 901, 808, 777, 684, 653, 560,
|
||||
529, 436, 405, 312, 281, 188, 157, 964, 933, 902,
|
||||
840, 809, 778, 716, 685, 654, 592, 561, 530, 468,
|
||||
437, 406, 344, 313, 282, 220, 189, 158, 996, 965,
|
||||
934, 903, 872, 841, 810, 779, 748, 717, 686, 655,
|
||||
624, 593, 562, 531, 500, 469, 438, 407, 376, 345,
|
||||
314, 283, 252, 221, 190, 159, 997, 966, 935, 873,
|
||||
842, 811, 749, 718, 687, 625, 594, 563, 501, 470,
|
||||
439, 377, 346, 315, 253, 222, 191, 998, 967, 874,
|
||||
843, 750, 719, 626, 595, 502, 471, 378, 347, 254,
|
||||
223, 999, 875, 751, 627, 503, 379, 255, 904, 780,
|
||||
656, 532, 408, 284, 936, 905, 812, 781, 688, 657,
|
||||
564, 533, 440, 409, 316, 285, 968, 937, 906, 844,
|
||||
813, 782, 720, 689, 658, 596, 565, 534, 472, 441,
|
||||
410, 348, 317, 286, 1000, 969, 938, 907, 876, 845,
|
||||
814, 783, 752, 721, 690, 659, 628, 597, 566, 535,
|
||||
504, 473, 442, 411, 380, 349, 318, 287, 1001, 970,
|
||||
939, 877, 846, 815, 753, 722, 691, 629, 598, 567,
|
||||
505, 474, 443, 381, 350, 319, 1002, 971, 878, 847,
|
||||
754, 723, 630, 599, 506, 475, 382, 351, 1003, 879,
|
||||
755, 631, 507, 383, 908, 784, 660, 536, 412, 940,
|
||||
909, 816, 785, 692, 661, 568, 537, 444, 413, 972,
|
||||
941, 910, 848, 817, 786, 724, 693, 662, 600, 569,
|
||||
538, 476, 445, 414, 1004, 973, 942, 911, 880, 849,
|
||||
818, 787, 756, 725, 694, 663, 632, 601, 570, 539,
|
||||
508, 477, 446, 415, 1005, 974, 943, 881, 850, 819,
|
||||
757, 726, 695, 633, 602, 571, 509, 478, 447, 1006,
|
||||
975, 882, 851, 758, 727, 634, 603, 510, 479, 1007,
|
||||
883, 759, 635, 511, 912, 788, 664, 540, 944, 913,
|
||||
820, 789, 696, 665, 572, 541, 976, 945, 914, 852,
|
||||
821, 790, 728, 697, 666, 604, 573, 542, 1008, 977,
|
||||
946, 915, 884, 853, 822, 791, 760, 729, 698, 667,
|
||||
636, 605, 574, 543, 1009, 978, 947, 885, 854, 823,
|
||||
761, 730, 699, 637, 606, 575, 1010, 979, 886, 855,
|
||||
762, 731, 638, 607, 1011, 887, 763, 639, 916, 792,
|
||||
668, 948, 917, 824, 793, 700, 669, 980, 949, 918,
|
||||
856, 825, 794, 732, 701, 670, 1012, 981, 950, 919,
|
||||
888, 857, 826, 795, 764, 733, 702, 671, 1013, 982,
|
||||
951, 889, 858, 827, 765, 734, 703, 1014, 983, 890,
|
||||
859, 766, 735, 1015, 891, 767, 920, 796, 952, 921,
|
||||
828, 797, 984, 953, 922, 860, 829, 798, 1016, 985,
|
||||
954, 923, 892, 861, 830, 799, 1017, 986, 955, 893,
|
||||
862, 831, 1018, 987, 894, 863, 1019, 895, 924, 956,
|
||||
925, 988, 957, 926, 1020, 989, 958, 927, 1021, 990,
|
||||
959, 1022, 991, 1023 };
|
||||
|
||||
private static final int[] default_scan_4x4_neighbors = new int[] {
|
||||
0, 0, 0, 0, 0, 0, 1, 4, 4, 4,
|
||||
1, 1, 8, 8, 5, 8, 2, 2, 2, 5,
|
||||
9, 12, 6, 9, 3, 6, 10, 13, 7, 10,
|
||||
11, 14, 0, 0 };
|
||||
|
||||
private static final int[] col_scan_4x4_neighbors = new int[] {
|
||||
0, 0, 0, 0, 4, 4, 0, 0, 8, 8,
|
||||
1, 1, 5, 5, 1, 1, 9, 9, 2, 2,
|
||||
6, 6, 2, 2, 3, 3, 10, 10, 7, 7,
|
||||
11, 11, 0, 0 };
|
||||
|
||||
private static final int[] row_scan_4x4_neighbors = new int[] {
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 4, 4,
|
||||
2, 2, 5, 5, 4, 4, 8, 8, 6, 6,
|
||||
8, 8, 9, 9, 12, 12, 10, 10, 13, 13,
|
||||
14, 14, 0, 0 };
|
||||
|
||||
private static final int[] col_scan_8x8_neighbors = new int[] {
|
||||
0, 0, 0, 0, 8, 8, 0, 0, 16, 16,
|
||||
1, 1, 24, 24, 9, 9, 1, 1, 32, 32,
|
||||
17, 17, 2, 2, 25, 25, 10, 10, 40, 40,
|
||||
2, 2, 18, 18, 33, 33, 3, 3, 48, 48,
|
||||
11, 11, 26, 26, 3, 3, 41, 41, 19, 19,
|
||||
34, 34, 4, 4, 27, 27, 12, 12, 49, 49,
|
||||
42, 42, 20, 20, 4, 4, 35, 35, 5, 5,
|
||||
28, 28, 50, 50, 43, 43, 13, 13, 36, 36,
|
||||
5, 5, 21, 21, 51, 51, 29, 29, 6, 6,
|
||||
44, 44, 14, 14, 6, 6, 37, 37, 52, 52,
|
||||
22, 22, 7, 7, 30, 30, 45, 45, 15, 15,
|
||||
38, 38, 23, 23, 53, 53, 31, 31, 46, 46,
|
||||
39, 39, 54, 54, 47, 47, 55, 55, 0, 0 };
|
||||
|
||||
private static final int[] row_scan_8x8_neighbors = new int[] {
|
||||
0, 0, 0, 0, 1, 1, 0, 0, 8, 8,
|
||||
2, 2, 8, 8, 9, 9, 3, 3, 16, 16,
|
||||
10, 10, 16, 16, 4, 4, 17, 17, 24, 24,
|
||||
11, 11, 18, 18, 25, 25, 24, 24, 5, 5,
|
||||
12, 12, 19, 19, 32, 32, 26, 26, 6, 6,
|
||||
33, 33, 32, 32, 20, 20, 27, 27, 40, 40,
|
||||
13, 13, 34, 34, 40, 40, 41, 41, 28, 28,
|
||||
35, 35, 48, 48, 21, 21, 42, 42, 14, 14,
|
||||
48, 48, 36, 36, 49, 49, 43, 43, 29, 29,
|
||||
56, 56, 22, 22, 50, 50, 57, 57, 44, 44,
|
||||
37, 37, 51, 51, 30, 30, 58, 58, 52, 52,
|
||||
45, 45, 59, 59, 38, 38, 60, 60, 46, 46,
|
||||
53, 53, 54, 54, 61, 61, 62, 62, 0, 0 };
|
||||
|
||||
private static final int[] default_scan_8x8_neighbors = new int[] {
|
||||
0, 0, 0, 0, 0, 0, 8, 8, 1, 8,
|
||||
1, 1, 9, 16, 16, 16, 2, 9, 2, 2,
|
||||
10, 17, 17, 24, 24, 24, 3, 10, 3, 3,
|
||||
18, 25, 25, 32, 11, 18, 32, 32, 4, 11,
|
||||
26, 33, 19, 26, 4, 4, 33, 40, 12, 19,
|
||||
40, 40, 5, 12, 27, 34, 34, 41, 20, 27,
|
||||
13, 20, 5, 5, 41, 48, 48, 48, 28, 35,
|
||||
35, 42, 21, 28, 6, 6, 6, 13, 42, 49,
|
||||
49, 56, 36, 43, 14, 21, 29, 36, 7, 14,
|
||||
43, 50, 50, 57, 22, 29, 37, 44, 15, 22,
|
||||
44, 51, 51, 58, 30, 37, 23, 30, 52, 59,
|
||||
45, 52, 38, 45, 31, 38, 53, 60, 46, 53,
|
||||
39, 46, 54, 61, 47, 54, 55, 62, 0, 0 };
|
||||
|
||||
private static final int[] col_scan_16x16_neighbors = new int[] {
|
||||
0, 0, 0, 0, 16, 16, 32, 32, 0, 0,
|
||||
48, 48, 1, 1, 64, 64, 17, 17, 80, 80,
|
||||
33, 33, 1, 1, 49, 49, 96, 96, 2, 2,
|
||||
65, 65, 18, 18, 112, 112, 34, 34, 81, 81,
|
||||
2, 2, 50, 50, 128, 128, 3, 3, 97, 97,
|
||||
19, 19, 66, 66, 144, 144, 82, 82, 35, 35,
|
||||
113, 113, 3, 3, 51, 51, 160, 160, 4, 4,
|
||||
98, 98, 129, 129, 67, 67, 20, 20, 83, 83,
|
||||
114, 114, 36, 36, 176, 176, 4, 4, 145, 145,
|
||||
52, 52, 99, 99, 5, 5, 130, 130, 68, 68,
|
||||
192, 192, 161, 161, 21, 21, 115, 115, 84, 84,
|
||||
37, 37, 146, 146, 208, 208, 53, 53, 5, 5,
|
||||
100, 100, 177, 177, 131, 131, 69, 69, 6, 6,
|
||||
224, 224, 116, 116, 22, 22, 162, 162, 85, 85,
|
||||
147, 147, 38, 38, 193, 193, 101, 101, 54, 54,
|
||||
6, 6, 132, 132, 178, 178, 70, 70, 163, 163,
|
||||
209, 209, 7, 7, 117, 117, 23, 23, 148, 148,
|
||||
7, 7, 86, 86, 194, 194, 225, 225, 39, 39,
|
||||
179, 179, 102, 102, 133, 133, 55, 55, 164, 164,
|
||||
8, 8, 71, 71, 210, 210, 118, 118, 149, 149,
|
||||
195, 195, 24, 24, 87, 87, 40, 40, 56, 56,
|
||||
134, 134, 180, 180, 226, 226, 103, 103, 8, 8,
|
||||
165, 165, 211, 211, 72, 72, 150, 150, 9, 9,
|
||||
119, 119, 25, 25, 88, 88, 196, 196, 41, 41,
|
||||
135, 135, 181, 181, 104, 104, 57, 57, 227, 227,
|
||||
166, 166, 120, 120, 151, 151, 197, 197, 73, 73,
|
||||
9, 9, 212, 212, 89, 89, 136, 136, 182, 182,
|
||||
10, 10, 26, 26, 105, 105, 167, 167, 228, 228,
|
||||
152, 152, 42, 42, 121, 121, 213, 213, 58, 58,
|
||||
198, 198, 74, 74, 137, 137, 183, 183, 168, 168,
|
||||
10, 10, 90, 90, 229, 229, 11, 11, 106, 106,
|
||||
214, 214, 153, 153, 27, 27, 199, 199, 43, 43,
|
||||
184, 184, 122, 122, 169, 169, 230, 230, 59, 59,
|
||||
11, 11, 75, 75, 138, 138, 200, 200, 215, 215,
|
||||
91, 91, 12, 12, 28, 28, 185, 185, 107, 107,
|
||||
154, 154, 44, 44, 231, 231, 216, 216, 60, 60,
|
||||
123, 123, 12, 12, 76, 76, 201, 201, 170, 170,
|
||||
232, 232, 139, 139, 92, 92, 13, 13, 108, 108,
|
||||
29, 29, 186, 186, 217, 217, 155, 155, 45, 45,
|
||||
13, 13, 61, 61, 124, 124, 14, 14, 233, 233,
|
||||
77, 77, 14, 14, 171, 171, 140, 140, 202, 202,
|
||||
30, 30, 93, 93, 109, 109, 46, 46, 156, 156,
|
||||
62, 62, 187, 187, 15, 15, 125, 125, 218, 218,
|
||||
78, 78, 31, 31, 172, 172, 47, 47, 141, 141,
|
||||
94, 94, 234, 234, 203, 203, 63, 63, 110, 110,
|
||||
188, 188, 157, 157, 126, 126, 79, 79, 173, 173,
|
||||
95, 95, 219, 219, 142, 142, 204, 204, 235, 235,
|
||||
111, 111, 158, 158, 127, 127, 189, 189, 220, 220,
|
||||
143, 143, 174, 174, 205, 205, 236, 236, 159, 159,
|
||||
190, 190, 221, 221, 175, 175, 237, 237, 206, 206,
|
||||
222, 222, 191, 191, 238, 238, 207, 207, 223, 223,
|
||||
239, 239, 0, 0 };
|
||||
|
||||
private static final int[] row_scan_16x16_neighbors = new int[] {
|
||||
0, 0, 0, 0, 1, 1, 0, 0, 2, 2,
|
||||
16, 16, 3, 3, 17, 17, 16, 16, 4, 4,
|
||||
32, 32, 18, 18, 5, 5, 33, 33, 32, 32,
|
||||
19, 19, 48, 48, 6, 6, 34, 34, 20, 20,
|
||||
49, 49, 48, 48, 7, 7, 35, 35, 64, 64,
|
||||
21, 21, 50, 50, 36, 36, 64, 64, 8, 8,
|
||||
65, 65, 51, 51, 22, 22, 37, 37, 80, 80,
|
||||
66, 66, 9, 9, 52, 52, 23, 23, 81, 81,
|
||||
67, 67, 80, 80, 38, 38, 10, 10, 53, 53,
|
||||
82, 82, 96, 96, 68, 68, 24, 24, 97, 97,
|
||||
83, 83, 39, 39, 96, 96, 54, 54, 11, 11,
|
||||
69, 69, 98, 98, 112, 112, 84, 84, 25, 25,
|
||||
40, 40, 55, 55, 113, 113, 99, 99, 12, 12,
|
||||
70, 70, 112, 112, 85, 85, 26, 26, 114, 114,
|
||||
100, 100, 128, 128, 41, 41, 56, 56, 71, 71,
|
||||
115, 115, 13, 13, 86, 86, 129, 129, 101, 101,
|
||||
128, 128, 72, 72, 130, 130, 116, 116, 27, 27,
|
||||
57, 57, 14, 14, 87, 87, 42, 42, 144, 144,
|
||||
102, 102, 131, 131, 145, 145, 117, 117, 73, 73,
|
||||
144, 144, 88, 88, 132, 132, 103, 103, 28, 28,
|
||||
58, 58, 146, 146, 118, 118, 43, 43, 160, 160,
|
||||
147, 147, 89, 89, 104, 104, 133, 133, 161, 161,
|
||||
119, 119, 160, 160, 74, 74, 134, 134, 148, 148,
|
||||
29, 29, 59, 59, 162, 162, 176, 176, 44, 44,
|
||||
120, 120, 90, 90, 105, 105, 163, 163, 177, 177,
|
||||
149, 149, 176, 176, 135, 135, 164, 164, 178, 178,
|
||||
30, 30, 150, 150, 192, 192, 75, 75, 121, 121,
|
||||
60, 60, 136, 136, 193, 193, 106, 106, 151, 151,
|
||||
179, 179, 192, 192, 45, 45, 165, 165, 166, 166,
|
||||
194, 194, 91, 91, 180, 180, 137, 137, 208, 208,
|
||||
122, 122, 152, 152, 208, 208, 195, 195, 76, 76,
|
||||
167, 167, 209, 209, 181, 181, 224, 224, 107, 107,
|
||||
196, 196, 61, 61, 153, 153, 224, 224, 182, 182,
|
||||
168, 168, 210, 210, 46, 46, 138, 138, 92, 92,
|
||||
183, 183, 225, 225, 211, 211, 240, 240, 197, 197,
|
||||
169, 169, 123, 123, 154, 154, 198, 198, 77, 77,
|
||||
212, 212, 184, 184, 108, 108, 226, 226, 199, 199,
|
||||
62, 62, 227, 227, 241, 241, 139, 139, 213, 213,
|
||||
170, 170, 185, 185, 155, 155, 228, 228, 242, 242,
|
||||
124, 124, 93, 93, 200, 200, 243, 243, 214, 214,
|
||||
215, 215, 229, 229, 140, 140, 186, 186, 201, 201,
|
||||
78, 78, 171, 171, 109, 109, 156, 156, 244, 244,
|
||||
216, 216, 230, 230, 94, 94, 245, 245, 231, 231,
|
||||
125, 125, 202, 202, 246, 246, 232, 232, 172, 172,
|
||||
217, 217, 141, 141, 110, 110, 157, 157, 187, 187,
|
||||
247, 247, 126, 126, 233, 233, 218, 218, 248, 248,
|
||||
188, 188, 203, 203, 142, 142, 173, 173, 158, 158,
|
||||
249, 249, 234, 234, 204, 204, 219, 219, 174, 174,
|
||||
189, 189, 250, 250, 220, 220, 190, 190, 205, 205,
|
||||
235, 235, 206, 206, 236, 236, 251, 251, 221, 221,
|
||||
252, 252, 222, 222, 237, 237, 238, 238, 253, 253,
|
||||
254, 254, 0, 0 };
|
||||
|
||||
private static final int[] default_scan_16x16_neighbors = new int[] {
|
||||
0, 0, 0, 0, 0, 0, 16, 16, 1, 16,
|
||||
1, 1, 32, 32, 17, 32, 2, 17, 2, 2,
|
||||
48, 48, 18, 33, 33, 48, 3, 18, 49, 64,
|
||||
64, 64, 34, 49, 3, 3, 19, 34, 50, 65,
|
||||
4, 19, 65, 80, 80, 80, 35, 50, 4, 4,
|
||||
20, 35, 66, 81, 81, 96, 51, 66, 96, 96,
|
||||
5, 20, 36, 51, 82, 97, 21, 36, 67, 82,
|
||||
97, 112, 5, 5, 52, 67, 112, 112, 37, 52,
|
||||
6, 21, 83, 98, 98, 113, 68, 83, 6, 6,
|
||||
113, 128, 22, 37, 53, 68, 84, 99, 99, 114,
|
||||
128, 128, 114, 129, 69, 84, 38, 53, 7, 22,
|
||||
7, 7, 129, 144, 23, 38, 54, 69, 100, 115,
|
||||
85, 100, 115, 130, 144, 144, 130, 145, 39, 54,
|
||||
70, 85, 8, 23, 55, 70, 116, 131, 101, 116,
|
||||
145, 160, 24, 39, 8, 8, 86, 101, 131, 146,
|
||||
160, 160, 146, 161, 71, 86, 40, 55, 9, 24,
|
||||
117, 132, 102, 117, 161, 176, 132, 147, 56, 71,
|
||||
87, 102, 25, 40, 147, 162, 9, 9, 176, 176,
|
||||
162, 177, 72, 87, 41, 56, 118, 133, 133, 148,
|
||||
103, 118, 10, 25, 148, 163, 57, 72, 88, 103,
|
||||
177, 192, 26, 41, 163, 178, 192, 192, 10, 10,
|
||||
119, 134, 73, 88, 149, 164, 104, 119, 134, 149,
|
||||
42, 57, 178, 193, 164, 179, 11, 26, 58, 73,
|
||||
193, 208, 89, 104, 135, 150, 120, 135, 27, 42,
|
||||
74, 89, 208, 208, 150, 165, 179, 194, 165, 180,
|
||||
105, 120, 194, 209, 43, 58, 11, 11, 136, 151,
|
||||
90, 105, 151, 166, 180, 195, 59, 74, 121, 136,
|
||||
209, 224, 195, 210, 224, 224, 166, 181, 106, 121,
|
||||
75, 90, 12, 27, 181, 196, 12, 12, 210, 225,
|
||||
152, 167, 167, 182, 137, 152, 28, 43, 196, 211,
|
||||
122, 137, 91, 106, 225, 240, 44, 59, 13, 28,
|
||||
107, 122, 182, 197, 168, 183, 211, 226, 153, 168,
|
||||
226, 241, 60, 75, 197, 212, 138, 153, 29, 44,
|
||||
76, 91, 13, 13, 183, 198, 123, 138, 45, 60,
|
||||
212, 227, 198, 213, 154, 169, 169, 184, 227, 242,
|
||||
92, 107, 61, 76, 139, 154, 14, 29, 14, 14,
|
||||
184, 199, 213, 228, 108, 123, 199, 214, 228, 243,
|
||||
77, 92, 30, 45, 170, 185, 155, 170, 185, 200,
|
||||
93, 108, 124, 139, 214, 229, 46, 61, 200, 215,
|
||||
229, 244, 15, 30, 109, 124, 62, 77, 140, 155,
|
||||
215, 230, 31, 46, 171, 186, 186, 201, 201, 216,
|
||||
78, 93, 230, 245, 125, 140, 47, 62, 216, 231,
|
||||
156, 171, 94, 109, 231, 246, 141, 156, 63, 78,
|
||||
202, 217, 187, 202, 110, 125, 217, 232, 172, 187,
|
||||
232, 247, 79, 94, 157, 172, 126, 141, 203, 218,
|
||||
95, 110, 233, 248, 218, 233, 142, 157, 111, 126,
|
||||
173, 188, 188, 203, 234, 249, 219, 234, 127, 142,
|
||||
158, 173, 204, 219, 189, 204, 143, 158, 235, 250,
|
||||
174, 189, 205, 220, 159, 174, 220, 235, 221, 236,
|
||||
175, 190, 190, 205, 236, 251, 206, 221, 237, 252,
|
||||
191, 206, 222, 237, 207, 222, 238, 253, 223, 238,
|
||||
239, 254, 0, 0 };
|
||||
|
||||
private static final int[] default_scan_32x32_neighbors = new int[] {
|
||||
0, 0, 0, 0, 0, 0, 32, 32, 1, 32,
|
||||
1, 1, 64, 64, 33, 64, 2, 33, 96, 96,
|
||||
2, 2, 65, 96, 34, 65, 128, 128, 97, 128,
|
||||
3, 34, 66, 97, 3, 3, 35, 66, 98, 129,
|
||||
129, 160, 160, 160, 4, 35, 67, 98, 192, 192,
|
||||
4, 4, 130, 161, 161, 192, 36, 67, 99, 130,
|
||||
5, 36, 68, 99, 193, 224, 162, 193, 224, 224,
|
||||
131, 162, 37, 68, 100, 131, 5, 5, 194, 225,
|
||||
225, 256, 256, 256, 163, 194, 69, 100, 132, 163,
|
||||
6, 37, 226, 257, 6, 6, 195, 226, 257, 288,
|
||||
101, 132, 288, 288, 38, 69, 164, 195, 133, 164,
|
||||
258, 289, 227, 258, 196, 227, 7, 38, 289, 320,
|
||||
70, 101, 320, 320, 7, 7, 165, 196, 39, 70,
|
||||
102, 133, 290, 321, 259, 290, 228, 259, 321, 352,
|
||||
352, 352, 197, 228, 134, 165, 71, 102, 8, 39,
|
||||
322, 353, 291, 322, 260, 291, 103, 134, 353, 384,
|
||||
166, 197, 229, 260, 40, 71, 8, 8, 384, 384,
|
||||
135, 166, 354, 385, 323, 354, 198, 229, 292, 323,
|
||||
72, 103, 261, 292, 9, 40, 385, 416, 167, 198,
|
||||
104, 135, 230, 261, 355, 386, 416, 416, 293, 324,
|
||||
324, 355, 9, 9, 41, 72, 386, 417, 199, 230,
|
||||
136, 167, 417, 448, 262, 293, 356, 387, 73, 104,
|
||||
387, 418, 231, 262, 10, 41, 168, 199, 325, 356,
|
||||
418, 449, 105, 136, 448, 448, 42, 73, 294, 325,
|
||||
200, 231, 10, 10, 357, 388, 137, 168, 263, 294,
|
||||
388, 419, 74, 105, 419, 450, 449, 480, 326, 357,
|
||||
232, 263, 295, 326, 169, 200, 11, 42, 106, 137,
|
||||
480, 480, 450, 481, 358, 389, 264, 295, 201, 232,
|
||||
138, 169, 389, 420, 43, 74, 420, 451, 327, 358,
|
||||
11, 11, 481, 512, 233, 264, 451, 482, 296, 327,
|
||||
75, 106, 170, 201, 482, 513, 512, 512, 390, 421,
|
||||
359, 390, 421, 452, 107, 138, 12, 43, 202, 233,
|
||||
452, 483, 265, 296, 328, 359, 139, 170, 44, 75,
|
||||
483, 514, 513, 544, 234, 265, 297, 328, 422, 453,
|
||||
12, 12, 391, 422, 171, 202, 76, 107, 514, 545,
|
||||
453, 484, 544, 544, 266, 297, 203, 234, 108, 139,
|
||||
329, 360, 298, 329, 140, 171, 515, 546, 13, 44,
|
||||
423, 454, 235, 266, 545, 576, 454, 485, 45, 76,
|
||||
172, 203, 330, 361, 576, 576, 13, 13, 267, 298,
|
||||
546, 577, 77, 108, 204, 235, 455, 486, 577, 608,
|
||||
299, 330, 109, 140, 547, 578, 14, 45, 14, 14,
|
||||
141, 172, 578, 609, 331, 362, 46, 77, 173, 204,
|
||||
15, 15, 78, 109, 205, 236, 579, 610, 110, 141,
|
||||
15, 46, 142, 173, 47, 78, 174, 205, 16, 16,
|
||||
79, 110, 206, 237, 16, 47, 111, 142, 48, 79,
|
||||
143, 174, 80, 111, 175, 206, 17, 48, 17, 17,
|
||||
207, 238, 49, 80, 81, 112, 18, 18, 18, 49,
|
||||
50, 81, 82, 113, 19, 50, 51, 82, 83, 114,
|
||||
608, 608, 484, 515, 360, 391, 236, 267, 112, 143,
|
||||
19, 19, 640, 640, 609, 640, 516, 547, 485, 516,
|
||||
392, 423, 361, 392, 268, 299, 237, 268, 144, 175,
|
||||
113, 144, 20, 51, 20, 20, 672, 672, 641, 672,
|
||||
610, 641, 548, 579, 517, 548, 486, 517, 424, 455,
|
||||
393, 424, 362, 393, 300, 331, 269, 300, 238, 269,
|
||||
176, 207, 145, 176, 114, 145, 52, 83, 21, 52,
|
||||
21, 21, 704, 704, 673, 704, 642, 673, 611, 642,
|
||||
580, 611, 549, 580, 518, 549, 487, 518, 456, 487,
|
||||
425, 456, 394, 425, 363, 394, 332, 363, 301, 332,
|
||||
270, 301, 239, 270, 208, 239, 177, 208, 146, 177,
|
||||
115, 146, 84, 115, 53, 84, 22, 53, 22, 22,
|
||||
705, 736, 674, 705, 643, 674, 581, 612, 550, 581,
|
||||
519, 550, 457, 488, 426, 457, 395, 426, 333, 364,
|
||||
302, 333, 271, 302, 209, 240, 178, 209, 147, 178,
|
||||
85, 116, 54, 85, 23, 54, 706, 737, 675, 706,
|
||||
582, 613, 551, 582, 458, 489, 427, 458, 334, 365,
|
||||
303, 334, 210, 241, 179, 210, 86, 117, 55, 86,
|
||||
707, 738, 583, 614, 459, 490, 335, 366, 211, 242,
|
||||
87, 118, 736, 736, 612, 643, 488, 519, 364, 395,
|
||||
240, 271, 116, 147, 23, 23, 768, 768, 737, 768,
|
||||
644, 675, 613, 644, 520, 551, 489, 520, 396, 427,
|
||||
365, 396, 272, 303, 241, 272, 148, 179, 117, 148,
|
||||
24, 55, 24, 24, 800, 800, 769, 800, 738, 769,
|
||||
676, 707, 645, 676, 614, 645, 552, 583, 521, 552,
|
||||
490, 521, 428, 459, 397, 428, 366, 397, 304, 335,
|
||||
273, 304, 242, 273, 180, 211, 149, 180, 118, 149,
|
||||
56, 87, 25, 56, 25, 25, 832, 832, 801, 832,
|
||||
770, 801, 739, 770, 708, 739, 677, 708, 646, 677,
|
||||
615, 646, 584, 615, 553, 584, 522, 553, 491, 522,
|
||||
460, 491, 429, 460, 398, 429, 367, 398, 336, 367,
|
||||
305, 336, 274, 305, 243, 274, 212, 243, 181, 212,
|
||||
150, 181, 119, 150, 88, 119, 57, 88, 26, 57,
|
||||
26, 26, 833, 864, 802, 833, 771, 802, 709, 740,
|
||||
678, 709, 647, 678, 585, 616, 554, 585, 523, 554,
|
||||
461, 492, 430, 461, 399, 430, 337, 368, 306, 337,
|
||||
275, 306, 213, 244, 182, 213, 151, 182, 89, 120,
|
||||
58, 89, 27, 58, 834, 865, 803, 834, 710, 741,
|
||||
679, 710, 586, 617, 555, 586, 462, 493, 431, 462,
|
||||
338, 369, 307, 338, 214, 245, 183, 214, 90, 121,
|
||||
59, 90, 835, 866, 711, 742, 587, 618, 463, 494,
|
||||
339, 370, 215, 246, 91, 122, 864, 864, 740, 771,
|
||||
616, 647, 492, 523, 368, 399, 244, 275, 120, 151,
|
||||
27, 27, 896, 896, 865, 896, 772, 803, 741, 772,
|
||||
648, 679, 617, 648, 524, 555, 493, 524, 400, 431,
|
||||
369, 400, 276, 307, 245, 276, 152, 183, 121, 152,
|
||||
28, 59, 28, 28, 928, 928, 897, 928, 866, 897,
|
||||
804, 835, 773, 804, 742, 773, 680, 711, 649, 680,
|
||||
618, 649, 556, 587, 525, 556, 494, 525, 432, 463,
|
||||
401, 432, 370, 401, 308, 339, 277, 308, 246, 277,
|
||||
184, 215, 153, 184, 122, 153, 60, 91, 29, 60,
|
||||
29, 29, 960, 960, 929, 960, 898, 929, 867, 898,
|
||||
836, 867, 805, 836, 774, 805, 743, 774, 712, 743,
|
||||
681, 712, 650, 681, 619, 650, 588, 619, 557, 588,
|
||||
526, 557, 495, 526, 464, 495, 433, 464, 402, 433,
|
||||
371, 402, 340, 371, 309, 340, 278, 309, 247, 278,
|
||||
216, 247, 185, 216, 154, 185, 123, 154, 92, 123,
|
||||
61, 92, 30, 61, 30, 30, 961, 992, 930, 961,
|
||||
899, 930, 837, 868, 806, 837, 775, 806, 713, 744,
|
||||
682, 713, 651, 682, 589, 620, 558, 589, 527, 558,
|
||||
465, 496, 434, 465, 403, 434, 341, 372, 310, 341,
|
||||
279, 310, 217, 248, 186, 217, 155, 186, 93, 124,
|
||||
62, 93, 31, 62, 962, 993, 931, 962, 838, 869,
|
||||
807, 838, 714, 745, 683, 714, 590, 621, 559, 590,
|
||||
466, 497, 435, 466, 342, 373, 311, 342, 218, 249,
|
||||
187, 218, 94, 125, 63, 94, 963, 994, 839, 870,
|
||||
715, 746, 591, 622, 467, 498, 343, 374, 219, 250,
|
||||
95, 126, 868, 899, 744, 775, 620, 651, 496, 527,
|
||||
372, 403, 248, 279, 124, 155, 900, 931, 869, 900,
|
||||
776, 807, 745, 776, 652, 683, 621, 652, 528, 559,
|
||||
497, 528, 404, 435, 373, 404, 280, 311, 249, 280,
|
||||
156, 187, 125, 156, 932, 963, 901, 932, 870, 901,
|
||||
808, 839, 777, 808, 746, 777, 684, 715, 653, 684,
|
||||
622, 653, 560, 591, 529, 560, 498, 529, 436, 467,
|
||||
405, 436, 374, 405, 312, 343, 281, 312, 250, 281,
|
||||
188, 219, 157, 188, 126, 157, 964, 995, 933, 964,
|
||||
902, 933, 871, 902, 840, 871, 809, 840, 778, 809,
|
||||
747, 778, 716, 747, 685, 716, 654, 685, 623, 654,
|
||||
592, 623, 561, 592, 530, 561, 499, 530, 468, 499,
|
||||
437, 468, 406, 437, 375, 406, 344, 375, 313, 344,
|
||||
282, 313, 251, 282, 220, 251, 189, 220, 158, 189,
|
||||
127, 158, 965, 996, 934, 965, 903, 934, 841, 872,
|
||||
810, 841, 779, 810, 717, 748, 686, 717, 655, 686,
|
||||
593, 624, 562, 593, 531, 562, 469, 500, 438, 469,
|
||||
407, 438, 345, 376, 314, 345, 283, 314, 221, 252,
|
||||
190, 221, 159, 190, 966, 997, 935, 966, 842, 873,
|
||||
811, 842, 718, 749, 687, 718, 594, 625, 563, 594,
|
||||
470, 501, 439, 470, 346, 377, 315, 346, 222, 253,
|
||||
191, 222, 967, 998, 843, 874, 719, 750, 595, 626,
|
||||
471, 502, 347, 378, 223, 254, 872, 903, 748, 779,
|
||||
624, 655, 500, 531, 376, 407, 252, 283, 904, 935,
|
||||
873, 904, 780, 811, 749, 780, 656, 687, 625, 656,
|
||||
532, 563, 501, 532, 408, 439, 377, 408, 284, 315,
|
||||
253, 284, 936, 967, 905, 936, 874, 905, 812, 843,
|
||||
781, 812, 750, 781, 688, 719, 657, 688, 626, 657,
|
||||
564, 595, 533, 564, 502, 533, 440, 471, 409, 440,
|
||||
378, 409, 316, 347, 285, 316, 254, 285, 968, 999,
|
||||
937, 968, 906, 937, 875, 906, 844, 875, 813, 844,
|
||||
782, 813, 751, 782, 720, 751, 689, 720, 658, 689,
|
||||
627, 658, 596, 627, 565, 596, 534, 565, 503, 534,
|
||||
472, 503, 441, 472, 410, 441, 379, 410, 348, 379,
|
||||
317, 348, 286, 317, 255, 286, 969, 1000, 938, 969,
|
||||
907, 938, 845, 876, 814, 845, 783, 814, 721, 752,
|
||||
690, 721, 659, 690, 597, 628, 566, 597, 535, 566,
|
||||
473, 504, 442, 473, 411, 442, 349, 380, 318, 349,
|
||||
287, 318, 970, 1001, 939, 970, 846, 877, 815, 846,
|
||||
722, 753, 691, 722, 598, 629, 567, 598, 474, 505,
|
||||
443, 474, 350, 381, 319, 350, 971, 1002, 847, 878,
|
||||
723, 754, 599, 630, 475, 506, 351, 382, 876, 907,
|
||||
752, 783, 628, 659, 504, 535, 380, 411, 908, 939,
|
||||
877, 908, 784, 815, 753, 784, 660, 691, 629, 660,
|
||||
536, 567, 505, 536, 412, 443, 381, 412, 940, 971,
|
||||
909, 940, 878, 909, 816, 847, 785, 816, 754, 785,
|
||||
692, 723, 661, 692, 630, 661, 568, 599, 537, 568,
|
||||
506, 537, 444, 475, 413, 444, 382, 413, 972, 1003,
|
||||
941, 972, 910, 941, 879, 910, 848, 879, 817, 848,
|
||||
786, 817, 755, 786, 724, 755, 693, 724, 662, 693,
|
||||
631, 662, 600, 631, 569, 600, 538, 569, 507, 538,
|
||||
476, 507, 445, 476, 414, 445, 383, 414, 973, 1004,
|
||||
942, 973, 911, 942, 849, 880, 818, 849, 787, 818,
|
||||
725, 756, 694, 725, 663, 694, 601, 632, 570, 601,
|
||||
539, 570, 477, 508, 446, 477, 415, 446, 974, 1005,
|
||||
943, 974, 850, 881, 819, 850, 726, 757, 695, 726,
|
||||
602, 633, 571, 602, 478, 509, 447, 478, 975, 1006,
|
||||
851, 882, 727, 758, 603, 634, 479, 510, 880, 911,
|
||||
756, 787, 632, 663, 508, 539, 912, 943, 881, 912,
|
||||
788, 819, 757, 788, 664, 695, 633, 664, 540, 571,
|
||||
509, 540, 944, 975, 913, 944, 882, 913, 820, 851,
|
||||
789, 820, 758, 789, 696, 727, 665, 696, 634, 665,
|
||||
572, 603, 541, 572, 510, 541, 976, 1007, 945, 976,
|
||||
914, 945, 883, 914, 852, 883, 821, 852, 790, 821,
|
||||
759, 790, 728, 759, 697, 728, 666, 697, 635, 666,
|
||||
604, 635, 573, 604, 542, 573, 511, 542, 977, 1008,
|
||||
946, 977, 915, 946, 853, 884, 822, 853, 791, 822,
|
||||
729, 760, 698, 729, 667, 698, 605, 636, 574, 605,
|
||||
543, 574, 978, 1009, 947, 978, 854, 885, 823, 854,
|
||||
730, 761, 699, 730, 606, 637, 575, 606, 979, 1010,
|
||||
855, 886, 731, 762, 607, 638, 884, 915, 760, 791,
|
||||
636, 667, 916, 947, 885, 916, 792, 823, 761, 792,
|
||||
668, 699, 637, 668, 948, 979, 917, 948, 886, 917,
|
||||
824, 855, 793, 824, 762, 793, 700, 731, 669, 700,
|
||||
638, 669, 980, 1011, 949, 980, 918, 949, 887, 918,
|
||||
856, 887, 825, 856, 794, 825, 763, 794, 732, 763,
|
||||
701, 732, 670, 701, 639, 670, 981, 1012, 950, 981,
|
||||
919, 950, 857, 888, 826, 857, 795, 826, 733, 764,
|
||||
702, 733, 671, 702, 982, 1013, 951, 982, 858, 889,
|
||||
827, 858, 734, 765, 703, 734, 983, 1014, 859, 890,
|
||||
735, 766, 888, 919, 764, 795, 920, 951, 889, 920,
|
||||
796, 827, 765, 796, 952, 983, 921, 952, 890, 921,
|
||||
828, 859, 797, 828, 766, 797, 984, 1015, 953, 984,
|
||||
922, 953, 891, 922, 860, 891, 829, 860, 798, 829,
|
||||
767, 798, 985, 1016, 954, 985, 923, 954, 861, 892,
|
||||
830, 861, 799, 830, 986, 1017, 955, 986, 862, 893,
|
||||
831, 862, 987, 1018, 863, 894, 892, 923, 924, 955,
|
||||
893, 924, 956, 987, 925, 956, 894, 925, 988, 1019,
|
||||
957, 988, 926, 957, 895, 926, 989, 1020, 958, 989,
|
||||
927, 958, 990, 1021, 959, 990, 991, 1022, 0, 0 };
|
||||
|
||||
private static final int[] vp9_default_iscan_4x4 = new int[] {
|
||||
0, 2, 5, 8, 1, 3, 9, 12, 4, 7,
|
||||
11, 14, 6, 10, 13, 15 };
|
||||
|
||||
private static final int[] vp9_col_iscan_4x4 = new int[] {
|
||||
0, 3, 7, 11, 1, 5, 9, 12, 2, 6,
|
||||
10, 14, 4, 8, 13, 15 };
|
||||
|
||||
private static final int[] vp9_row_iscan_4x4 = new int[] {
|
||||
0, 1, 3, 5, 2, 4, 6, 9, 7, 8,
|
||||
11, 13, 10, 12, 14, 15 };
|
||||
|
||||
private static final int[] vp9_col_iscan_8x8 = new int[] {
|
||||
0, 3, 8, 15, 22, 32, 40, 47, 1, 5,
|
||||
11, 18, 26, 34, 44, 51, 2, 7, 13, 20,
|
||||
28, 38, 46, 54, 4, 10, 16, 24, 31, 41,
|
||||
50, 56, 6, 12, 21, 27, 35, 43, 52, 58,
|
||||
9, 17, 25, 33, 39, 48, 55, 60, 14, 23,
|
||||
30, 37, 45, 53, 59, 62, 19, 29, 36, 42,
|
||||
49, 57, 61, 63 };
|
||||
|
||||
private static final int[] vp9_row_iscan_8x8 = new int[] {
|
||||
0, 1, 2, 5, 8, 12, 19, 24, 3, 4,
|
||||
7, 10, 15, 20, 30, 39, 6, 9, 13, 16,
|
||||
21, 27, 37, 46, 11, 14, 17, 23, 28, 34,
|
||||
44, 52, 18, 22, 25, 31, 35, 41, 50, 57,
|
||||
26, 29, 33, 38, 43, 49, 55, 59, 32, 36,
|
||||
42, 47, 51, 54, 60, 61, 40, 45, 48, 53,
|
||||
56, 58, 62, 63 };
|
||||
|
||||
private static final int[] vp9_default_iscan_8x8 = new int[] {
|
||||
0, 2, 5, 9, 14, 22, 31, 37, 1, 4,
|
||||
8, 13, 19, 26, 38, 44, 3, 6, 10, 17,
|
||||
24, 30, 42, 49, 7, 11, 15, 21, 29, 36,
|
||||
47, 53, 12, 16, 20, 27, 34, 43, 52, 57,
|
||||
18, 23, 28, 35, 41, 48, 56, 60, 25, 32,
|
||||
39, 45, 50, 55, 59, 62, 33, 40, 46, 51,
|
||||
54, 58, 61, 63 };
|
||||
|
||||
private static final int[] vp9_col_iscan_16x16 = new int[] {
|
||||
0, 4, 11, 20, 31, 43, 59, 75, 85, 109,
|
||||
130, 150, 165, 181, 195, 198, 1, 6, 14, 23,
|
||||
34, 47, 64, 81, 95, 114, 135, 153, 171, 188,
|
||||
201, 212, 2, 8, 16, 25, 38, 52, 67, 83,
|
||||
101, 116, 136, 157, 172, 190, 205, 216, 3, 10,
|
||||
18, 29, 41, 55, 71, 89, 103, 119, 141, 159,
|
||||
176, 194, 208, 218, 5, 12, 21, 32, 45, 58,
|
||||
74, 93, 104, 123, 144, 164, 179, 196, 210, 223,
|
||||
7, 15, 26, 37, 49, 63, 78, 96, 112, 129,
|
||||
146, 166, 182, 200, 215, 228, 9, 19, 28, 39,
|
||||
54, 69, 86, 102, 117, 132, 151, 170, 187, 206,
|
||||
220, 230, 13, 24, 35, 46, 60, 73, 91, 108,
|
||||
122, 137, 154, 174, 189, 207, 224, 235, 17, 30,
|
||||
40, 53, 66, 82, 98, 115, 126, 142, 161, 180,
|
||||
197, 213, 227, 237, 22, 36, 48, 62, 76, 92,
|
||||
105, 120, 133, 147, 167, 186, 203, 219, 232, 240,
|
||||
27, 44, 56, 70, 84, 99, 113, 127, 140, 156,
|
||||
175, 193, 209, 226, 236, 244, 33, 51, 68, 79,
|
||||
94, 110, 125, 138, 149, 162, 184, 202, 217, 229,
|
||||
241, 247, 42, 61, 77, 90, 106, 121, 134, 148,
|
||||
160, 173, 191, 211, 225, 238, 245, 251, 50, 72,
|
||||
87, 100, 118, 128, 145, 158, 168, 183, 204, 222,
|
||||
233, 242, 249, 253, 57, 80, 97, 111, 131, 143,
|
||||
155, 169, 178, 192, 214, 231, 239, 246, 250, 254,
|
||||
65, 88, 107, 124, 139, 152, 163, 177, 185, 199,
|
||||
221, 234, 243, 248, 252, 255 };
|
||||
|
||||
private static final int[] vp9_row_iscan_16x16 = new int[] {
|
||||
0, 1, 2, 4, 6, 9, 12, 17, 22, 29,
|
||||
36, 43, 54, 64, 76, 86, 3, 5, 7, 11,
|
||||
15, 19, 25, 32, 38, 48, 59, 68, 84, 99,
|
||||
115, 130, 8, 10, 13, 18, 23, 27, 33, 42,
|
||||
51, 60, 72, 88, 103, 119, 142, 167, 14, 16,
|
||||
20, 26, 31, 37, 44, 53, 61, 73, 85, 100,
|
||||
116, 135, 161, 185, 21, 24, 30, 35, 40, 47,
|
||||
55, 65, 74, 81, 94, 112, 133, 154, 179, 205,
|
||||
28, 34, 39, 45, 50, 58, 67, 77, 87, 96,
|
||||
106, 121, 146, 169, 196, 212, 41, 46, 49, 56,
|
||||
63, 70, 79, 90, 98, 107, 122, 138, 159, 182,
|
||||
207, 222, 52, 57, 62, 69, 75, 83, 93, 102,
|
||||
110, 120, 134, 150, 176, 195, 215, 226, 66, 71,
|
||||
78, 82, 91, 97, 108, 113, 127, 136, 148, 168,
|
||||
188, 202, 221, 232, 80, 89, 92, 101, 105, 114,
|
||||
125, 131, 139, 151, 162, 177, 192, 208, 223, 234,
|
||||
95, 104, 109, 117, 123, 128, 143, 144, 155, 165,
|
||||
175, 190, 206, 219, 233, 239, 111, 118, 124, 129,
|
||||
140, 147, 157, 164, 170, 181, 191, 203, 224, 230,
|
||||
240, 243, 126, 132, 137, 145, 153, 160, 174, 178,
|
||||
184, 197, 204, 216, 231, 237, 244, 246, 141, 149,
|
||||
156, 166, 172, 180, 189, 199, 200, 210, 220, 228,
|
||||
238, 242, 249, 251, 152, 163, 171, 183, 186, 193,
|
||||
201, 211, 214, 218, 227, 236, 245, 247, 252, 253,
|
||||
158, 173, 187, 194, 198, 209, 213, 217, 225, 229,
|
||||
235, 241, 248, 250, 254, 255 };
|
||||
|
||||
private static final int[] vp9_default_iscan_16x16 = new int[] {
|
||||
0, 2, 5, 9, 17, 24, 36, 44, 55, 72,
|
||||
88, 104, 128, 143, 166, 179, 1, 4, 8, 13,
|
||||
20, 30, 40, 54, 66, 79, 96, 113, 141, 154,
|
||||
178, 196, 3, 7, 11, 18, 25, 33, 46, 57,
|
||||
71, 86, 101, 119, 148, 164, 186, 201, 6, 12,
|
||||
16, 23, 31, 39, 53, 64, 78, 92, 110, 127,
|
||||
153, 169, 193, 208, 10, 14, 19, 28, 37, 47,
|
||||
58, 67, 84, 98, 114, 133, 161, 176, 198, 214,
|
||||
15, 21, 26, 34, 43, 52, 65, 77, 91, 106,
|
||||
120, 140, 165, 185, 205, 221, 22, 27, 32, 41,
|
||||
48, 60, 73, 85, 99, 116, 130, 151, 175, 190,
|
||||
211, 225, 29, 35, 42, 49, 59, 69, 81, 95,
|
||||
108, 125, 139, 155, 182, 197, 217, 229, 38, 45,
|
||||
51, 61, 68, 80, 93, 105, 118, 134, 150, 168,
|
||||
191, 207, 223, 234, 50, 56, 63, 74, 83, 94,
|
||||
109, 117, 129, 147, 163, 177, 199, 213, 228, 238,
|
||||
62, 70, 76, 87, 97, 107, 122, 131, 145, 159,
|
||||
172, 188, 210, 222, 235, 242, 75, 82, 90, 102,
|
||||
112, 124, 138, 146, 157, 173, 187, 202, 219, 230,
|
||||
240, 245, 89, 100, 111, 123, 132, 142, 156, 167,
|
||||
180, 189, 203, 216, 231, 237, 246, 250, 103, 115,
|
||||
126, 136, 149, 162, 171, 183, 194, 204, 215, 224,
|
||||
236, 241, 248, 252, 121, 135, 144, 158, 170, 181,
|
||||
192, 200, 209, 218, 227, 233, 243, 244, 251, 254,
|
||||
137, 152, 160, 174, 184, 195, 206, 212, 220, 226,
|
||||
232, 239, 247, 249, 253, 255 };
|
||||
|
||||
private static final int[] vp9_default_iscan_32x32 = new int[] {
|
||||
0, 2, 5, 10, 17, 25, 38, 47, 62, 83,
|
||||
101, 121, 145, 170, 193, 204, 210, 219, 229, 233,
|
||||
245, 257, 275, 299, 342, 356, 377, 405, 455, 471,
|
||||
495, 527, 1, 4, 8, 15, 22, 30, 45, 58,
|
||||
74, 92, 112, 133, 158, 184, 203, 215, 222, 228,
|
||||
234, 237, 256, 274, 298, 317, 355, 376, 404, 426,
|
||||
470, 494, 526, 551, 3, 7, 12, 18, 28, 36,
|
||||
52, 64, 82, 102, 118, 142, 164, 189, 208, 217,
|
||||
224, 231, 235, 238, 273, 297, 316, 329, 375, 403,
|
||||
425, 440, 493, 525, 550, 567, 6, 11, 16, 23,
|
||||
31, 43, 60, 73, 90, 109, 126, 150, 173, 196,
|
||||
211, 220, 226, 232, 236, 239, 296, 315, 328, 335,
|
||||
402, 424, 439, 447, 524, 549, 566, 575, 9, 14,
|
||||
19, 29, 37, 50, 65, 78, 95, 116, 134, 157,
|
||||
179, 201, 214, 223, 244, 255, 272, 295, 341, 354,
|
||||
374, 401, 454, 469, 492, 523, 582, 596, 617, 645,
|
||||
13, 20, 26, 35, 44, 54, 72, 85, 105, 123,
|
||||
140, 163, 182, 205, 216, 225, 254, 271, 294, 314,
|
||||
353, 373, 400, 423, 468, 491, 522, 548, 595, 616,
|
||||
644, 666, 21, 27, 33, 42, 53, 63, 80, 94,
|
||||
113, 132, 151, 172, 190, 209, 218, 227, 270, 293,
|
||||
313, 327, 372, 399, 422, 438, 490, 521, 547, 565,
|
||||
615, 643, 665, 680, 24, 32, 39, 48, 57, 71,
|
||||
88, 104, 120, 139, 159, 178, 197, 212, 221, 230,
|
||||
292, 312, 326, 334, 398, 421, 437, 446, 520, 546,
|
||||
564, 574, 642, 664, 679, 687, 34, 40, 46, 56,
|
||||
68, 81, 96, 111, 130, 147, 167, 186, 243, 253,
|
||||
269, 291, 340, 352, 371, 397, 453, 467, 489, 519,
|
||||
581, 594, 614, 641, 693, 705, 723, 747, 41, 49,
|
||||
55, 67, 77, 91, 107, 124, 138, 161, 177, 194,
|
||||
252, 268, 290, 311, 351, 370, 396, 420, 466, 488,
|
||||
518, 545, 593, 613, 640, 663, 704, 722, 746, 765,
|
||||
51, 59, 66, 76, 89, 99, 119, 131, 149, 168,
|
||||
181, 200, 267, 289, 310, 325, 369, 395, 419, 436,
|
||||
487, 517, 544, 563, 612, 639, 662, 678, 721, 745,
|
||||
764, 777, 61, 69, 75, 87, 100, 114, 129, 144,
|
||||
162, 180, 191, 207, 288, 309, 324, 333, 394, 418,
|
||||
435, 445, 516, 543, 562, 573, 638, 661, 677, 686,
|
||||
744, 763, 776, 783, 70, 79, 86, 97, 108, 122,
|
||||
137, 155, 242, 251, 266, 287, 339, 350, 368, 393,
|
||||
452, 465, 486, 515, 580, 592, 611, 637, 692, 703,
|
||||
720, 743, 788, 798, 813, 833, 84, 93, 103, 110,
|
||||
125, 141, 154, 171, 250, 265, 286, 308, 349, 367,
|
||||
392, 417, 464, 485, 514, 542, 591, 610, 636, 660,
|
||||
702, 719, 742, 762, 797, 812, 832, 848, 98, 106,
|
||||
115, 127, 143, 156, 169, 185, 264, 285, 307, 323,
|
||||
366, 391, 416, 434, 484, 513, 541, 561, 609, 635,
|
||||
659, 676, 718, 741, 761, 775, 811, 831, 847, 858,
|
||||
117, 128, 136, 148, 160, 175, 188, 198, 284, 306,
|
||||
322, 332, 390, 415, 433, 444, 512, 540, 560, 572,
|
||||
634, 658, 675, 685, 740, 760, 774, 782, 830, 846,
|
||||
857, 863, 135, 146, 152, 165, 241, 249, 263, 283,
|
||||
338, 348, 365, 389, 451, 463, 483, 511, 579, 590,
|
||||
608, 633, 691, 701, 717, 739, 787, 796, 810, 829,
|
||||
867, 875, 887, 903, 153, 166, 174, 183, 248, 262,
|
||||
282, 305, 347, 364, 388, 414, 462, 482, 510, 539,
|
||||
589, 607, 632, 657, 700, 716, 738, 759, 795, 809,
|
||||
828, 845, 874, 886, 902, 915, 176, 187, 195, 202,
|
||||
261, 281, 304, 321, 363, 387, 413, 432, 481, 509,
|
||||
538, 559, 606, 631, 656, 674, 715, 737, 758, 773,
|
||||
808, 827, 844, 856, 885, 901, 914, 923, 192, 199,
|
||||
206, 213, 280, 303, 320, 331, 386, 412, 431, 443,
|
||||
508, 537, 558, 571, 630, 655, 673, 684, 736, 757,
|
||||
772, 781, 826, 843, 855, 862, 900, 913, 922, 927,
|
||||
240, 247, 260, 279, 337, 346, 362, 385, 450, 461,
|
||||
480, 507, 578, 588, 605, 629, 690, 699, 714, 735,
|
||||
786, 794, 807, 825, 866, 873, 884, 899, 930, 936,
|
||||
945, 957, 246, 259, 278, 302, 345, 361, 384, 411,
|
||||
460, 479, 506, 536, 587, 604, 628, 654, 698, 713,
|
||||
734, 756, 793, 806, 824, 842, 872, 883, 898, 912,
|
||||
935, 944, 956, 966, 258, 277, 301, 319, 360, 383,
|
||||
410, 430, 478, 505, 535, 557, 603, 627, 653, 672,
|
||||
712, 733, 755, 771, 805, 823, 841, 854, 882, 897,
|
||||
911, 921, 943, 955, 965, 972, 276, 300, 318, 330,
|
||||
382, 409, 429, 442, 504, 534, 556, 570, 626, 652,
|
||||
671, 683, 732, 754, 770, 780, 822, 840, 853, 861,
|
||||
896, 910, 920, 926, 954, 964, 971, 975, 336, 344,
|
||||
359, 381, 449, 459, 477, 503, 577, 586, 602, 625,
|
||||
689, 697, 711, 731, 785, 792, 804, 821, 865, 871,
|
||||
881, 895, 929, 934, 942, 953, 977, 981, 987, 995,
|
||||
343, 358, 380, 408, 458, 476, 502, 533, 585, 601,
|
||||
624, 651, 696, 710, 730, 753, 791, 803, 820, 839,
|
||||
870, 880, 894, 909, 933, 941, 952, 963, 980, 986,
|
||||
994, 1001, 357, 379, 407, 428, 475, 501, 532, 555,
|
||||
600, 623, 650, 670, 709, 729, 752, 769, 802, 819,
|
||||
838, 852, 879, 893, 908, 919, 940, 951, 962, 970,
|
||||
985, 993, 1000, 1005, 378, 406, 427, 441, 500, 531,
|
||||
554, 569, 622, 649, 669, 682, 728, 751, 768, 779,
|
||||
818, 837, 851, 860, 892, 907, 918, 925, 950, 961,
|
||||
969, 974, 992, 999, 1004, 1007, 448, 457, 474, 499,
|
||||
576, 584, 599, 621, 688, 695, 708, 727, 784, 790,
|
||||
801, 817, 864, 869, 878, 891, 928, 932, 939, 949,
|
||||
976, 979, 984, 991, 1008, 1010, 1013, 1017, 456, 473,
|
||||
498, 530, 583, 598, 620, 648, 694, 707, 726, 750,
|
||||
789, 800, 816, 836, 868, 877, 890, 906, 931, 938,
|
||||
948, 960, 978, 983, 990, 998, 1009, 1012, 1016, 1020,
|
||||
472, 497, 529, 553, 597, 619, 647, 668, 706, 725,
|
||||
749, 767, 799, 815, 835, 850, 876, 889, 905, 917,
|
||||
937, 947, 959, 968, 982, 989, 997, 1003, 1011, 1015,
|
||||
1019, 1022, 496, 528, 552, 568, 618, 646, 667, 681,
|
||||
724, 748, 766, 778, 814, 834, 849, 859, 888, 904,
|
||||
916, 924, 946, 958, 967, 973, 988, 996, 1002, 1006,
|
||||
1014, 1018, 1021, 1023 };
|
||||
|
||||
public static final int[][][] vp9_default_scan_orders = new int[][][] { new int[][] { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors }, new int[][] { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors }, new int[][] { default_scan_16x16, vp9_default_iscan_16x16, default_scan_16x16_neighbors }, new int[][] { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors } };
|
||||
|
||||
public static final int[][][][] vp9_scan_orders = new int[][][][] { new int[][][] { new int[][] { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors }, new int[][] { row_scan_4x4, vp9_row_iscan_4x4, row_scan_4x4_neighbors }, new int[][] { col_scan_4x4, vp9_col_iscan_4x4, col_scan_4x4_neighbors }, new int[][] { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors } }, new int[][][] { new int[][] { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors }, new int[][] { row_scan_8x8, vp9_row_iscan_8x8, row_scan_8x8_neighbors }, new int[][] { col_scan_8x8, vp9_col_iscan_8x8, col_scan_8x8_neighbors }, new int[][] { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors } }, new int[][][] { new int[][] { default_scan_16x16, vp9_default_iscan_16x16, default_scan_16x16_neighbors }, new int[][] { row_scan_16x16, vp9_row_iscan_16x16, row_scan_16x16_neighbors }, new int[][] { col_scan_16x16, vp9_col_iscan_16x16, col_scan_16x16_neighbors }, new int[][] { default_scan_16x16, vp9_default_iscan_16x16, default_scan_16x16_neighbors } }, new int[][][] { new int[][] { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors }, new int[][] { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors }, new int[][] { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors }, new int[][] { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors } } };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue