package org.jcodec.containers.mkv;
import static org.jcodec.containers.mkv.MKVType.Block;
import static org.jcodec.containers.mkv.MKVType.Cluster;
import static org.jcodec.containers.mkv.MKVType.Segment;
import static org.jcodec.containers.mkv.MKVType.SimpleBlock;
import static org.jcodec.containers.mkv.MKVType.findAllTree;
import static org.junit.Assert.assertArrayEquals;
import org.jcodec.common.io.FileChannelWrapper;
import org.jcodec.common.io.IOUtils;
import org.jcodec.containers.mkv.boxes.MkvBlock;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.io.FileInputStream;
import java.lang.System;
import java.nio.ByteBuffer;
public class MkvBlockTest {
@Test
public void testXiph() {
int[] _in = new int[]{187, 630, 255, 60, 0xFFFFFF};
byte[] expecteds = new byte[]{(byte)187, (byte)255, (byte)255, 120, (byte)255, 0, 60};
assertArrayEquals(expecteds, MkvBlock.muxXiphLacing(_in));
}
@Test
public void testReadEbmlInt() throws Exception {
Assert.assertEquals(577, MkvBlock.ebmlDecode(ByteBuffer.wrap(new byte[] { 0x42, 0x41 })));
Assert.assertEquals(33, MkvBlock.ebmlDecode(ByteBuffer.wrap(new byte[] { (byte) 0xA1 })));
Assert.assertEquals(577, MkvBlock.ebmlDecode(ByteBuffer.wrap(new byte[] { 0x42, 0x41, 0x22, 0x22, 0x22 })));
}
@Test
public void testEbml() {
int[] _in = new int[]{187, 630, 255, 60, 0xFFFFFF};
long[] expecteds = new long[]{187, 443, -375, -195};
assertArrayEquals(expecteds, MkvBlock.calcEbmlLacingDiffs(_in));
_in = new int[]{480, 576, 672, 672, 672, 672, 576, 672};
expecteds = new long[]{480, 96, 96, 0, 0, 0, -96};
assertArrayEquals(expecteds, MkvBlock.calcEbmlLacingDiffs(_in));
}
@Test
public void testMuxEbml() throws Exception {
int[] frameSizes = new int[]{480, 576, 672, 672, 672, 672, 576, 672};
byte[] expected = new byte[]{0x41, (byte)0xE0, 0x60, 0x5F, 0x60, 0x5F, (byte)0xBF, (byte)0xBF, (byte)0xBF, 0x5F, (byte)0x9F};
Assert.assertArrayEquals(expected, MkvBlock.muxEbmlLacing(frameSizes));
frameSizes = new int[]{480, 576};
expected = new byte[]{0x41, (byte)0xE0};
Assert.assertArrayEquals(expected, MkvBlock.muxEbmlLacing(frameSizes));
frameSizes = new int[]{480, 576, 672};
expected = new byte[]{0x41, (byte)0xE0, 0x60, 0x5F};
Assert.assertArrayEquals(expected, MkvBlock.muxEbmlLacing(frameSizes));
}
@Test
public void testReadingEbml() throws Exception {
ByteBuffer bb = ByteBuffer.wrap(new byte[]{(byte)0x82, 0x00, 0x00, (byte)0x86, 0x07, 0x41, (byte)0xE0, 0x60, 0x5F, 0x60, 0x5F, (byte)0xBF, (byte)0xBF, (byte)0xBF, 0x5F, (byte)0x9F});
int startPosition = 5;
bb.position(startPosition);
MkvBlock be = new MkvBlock(SimpleBlock.id);
be.offset = 0x112;
be.dataOffset = 0x115;
be.dataLen = 0x1390;
int[] sizes = new int[bb.get(4)+1];
be.headerSize = MkvBlock.readEBMLLaceSizes(bb, sizes, (int) be.dataLen, startPosition);
Assert.assertNotNull(sizes);
Assert.assertEquals(bb.capacity(), be.headerSize);
Assert.assertEquals(480, sizes[0]);
Assert.assertEquals(480+96, sizes[1]);
Assert.assertEquals(480+96+96, sizes[2]);
Assert.assertEquals(480+96+96+0, sizes[3]);
Assert.assertEquals(480+96+96+0+0, sizes[4]);
Assert.assertEquals(480+96+96+0+0+0, sizes[5]);
Assert.assertEquals(480+96+96+0+0+0-96, sizes[6]);
Assert.assertEquals(be.dataLen-((480+96+96+0+0+0-96)+(480+96+96+0+0+0)+(480+96+96+0+0)+(480+96+96+0)+(480+96+96)+(480+96)+480+be.headerSize), sizes[7]);
}
@Test
public void testReadingXiph() throws Exception {
ByteBuffer bb = ByteBuffer.wrap(new byte[]{(byte)0x82, 0x00, (byte)0xAE, 0x02, 0x07, 0x51, (byte)0x92, (byte)0x92, 0x50, 0x4F, 0x4B, 0x54, (byte)0xD4, (byte)0xFD});
int startPosition = 5;
bb.position(startPosition);
MkvBlock be = new MkvBlock(Block.id);
be.offset = 0x149B0;
be.dataOffset = 0x149B3;
be.dataLen = 0x353;
int[] sizes = new int[bb.get(4)+1];
be.headerSize = MkvBlock.readXiphLaceSizes(bb, sizes, (int)be.dataLen, startPosition);
Assert.assertEquals(12, be.headerSize);
int third = bb.get(7) & 0xFF;
int second = bb.get(6) & 0xFF;
int eightth = (int)(be.dataLen) - (bb.get(5) + second + third + bb.get(8) + bb.get(9) + bb.get(10) + bb.get(11) + be.headerSize);
Assert.assertArrayEquals(new int[]{bb.get(5), second, third, bb.get(8), bb.get(9), bb.get(10), bb.get(11), eightth }, sizes);
}
@Test
public void testReadingXiphV2() throws Exception {
ByteBuffer bb = ByteBuffer.wrap(new byte[]{(byte)0x82, 0x00, (byte)0xAE, 0x02, 0x04, (byte)187, (byte)255, (byte)255, 120, (byte)255, 0, 60});
int startPosition = 5;
bb.position(startPosition);
MkvBlock be = new MkvBlock(Block.id);
be.offset = 0x149B0;
be.dataOffset = 0x149B3;
be.dataLen = 0x353;
int[] sizes = new int[bb.get(4)+1];
be.headerSize = MkvBlock.readXiphLaceSizes(bb, sizes, (int)be.dataLen, startPosition);
Assert.assertEquals(12, be.headerSize);
Assert.assertArrayEquals(new int[]{187, 630, 255, 60, (int)(be.dataLen) - (187 + 630 + 255 + 60 + be.headerSize) }, sizes);
}
@Ignore @Test
public void testGetSize() throws Exception {
MKVTestSuite suite = MKVTestSuite.read();
if (!suite.isSuitePresent())
Assert.fail("MKV test suite is missing, please download from http://www.matroska.org/downloads/test_w1.html, and save to the path recorded in src/test/resources/mkv/suite.properties");
System.out.println("Scanning file: " + suite.test1.getAbsolutePath());
FileInputStream inputStream = new FileInputStream(suite.test1);
try {
MKVParser reader = new MKVParser(new FileChannelWrapper(inputStream.getChannel()));
MKVType[] path = { Segment, Cluster, SimpleBlock };
MkvBlock[] blocks = findAllTree(reader.parse(), MkvBlock.class, path);
for (MkvBlock be : blocks)
if (be.lacingPresent){
Assert.assertEquals(" "+be.lacing+" Lacing block offset "+be.offset, be.dataLen+(be.dataOffset-be.offset), be.size());
}
} finally {
IOUtils.closeQuietly(inputStream);
}
}
@Test
public void testReadingSignedInt() throws Exception {
Assert.assertEquals(-30, MkvBlock.ebmlDecodeSigned(ByteBuffer.wrap(new byte[]{ (byte) 0xA1})));
Assert.assertEquals(-7614, MkvBlock.ebmlDecodeSigned(ByteBuffer.wrap(new byte[]{0x42, 0x41})));
}
}