package org.jcodec.codecs.h264.conformance; import org.jcodec.Utils; import org.jcodec.codecs.h264.H264Decoder; import org.jcodec.common.model.ColorSpace; import org.jcodec.common.model.Picture8Bit; import org.junit.Test; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import static java.lang.Integer.parseInt; import static java.util.Collections.singletonList; import static org.jcodec.common.Assert.assertTrue; public class ConformanceTest { @Test public void testNoContainer() throws IOException { String dir = "src/test/resources/video/seq_h264_4"; String yuv = "src/test/resources/video/seq_h264_4.yuv"; String info = new String(readFile(dir + "/info.txt").array()); int width = parseInt(info.split(" ")[0]); int height = parseInt(info.split(" ")[1]); int frameCount = parseInt(info.split(" ")[2]); byte[][] picData = Picture8Bit.create(width, height, ColorSpace.YUV420J).getData(); H264Decoder decoder = new H264Decoder(); decoder.addSps(singletonList(readFile(dir + "/sps"))); decoder.addPps(singletonList(readFile(dir + "/pps"))); RawReader8Bit rawReader = new RawReader8Bit(new File(yuv), width, height); // OutputStream out = new FileOutputStream(dir + "/yuv"); for (int fn = 0; fn < frameCount; fn++) { ByteBuffer buf = readFile(dir + "/" + zeroPad3(fn)); Picture8Bit pic = decoder.decodeFrame8BitFromNals(extractNALUnits(buf), picData); // out.write(picData[0]); // out.write(picData[1]); // out.write(picData[2]); // Utils.saveImage(pic, "png", dir + "/" + zeroPad3(fn) + "_.png"); Picture8Bit ref = rawReader.readNextFrame(); assertTrue("frame=" + fn + " FAILED", compare(ref, pic)); } // out.close(); } private ByteBuffer readFile(String path) throws IOException { File file = new File(path); InputStream _in = new BufferedInputStream(new FileInputStream(file)); byte[] buf = new byte[(int) file.length()]; _in.read(buf); _in.close(); return ByteBuffer.wrap(buf); } private String zeroPad3(int n) { String s = n + ""; while (s.length() < 3) s = "0" + s; return s; } private List<ByteBuffer> extractNALUnits(ByteBuffer buf) { buf = buf.duplicate(); List<ByteBuffer> nalUnits = new ArrayList<ByteBuffer>(); while (buf.remaining() > 4) { int length = buf.getInt(); ByteBuffer nalUnit = ByteBuffer.allocate(length); for (int i = 0; i < length; i++) { nalUnit.put(buf.get()); } nalUnit.flip(); nalUnits.add(nalUnit); } return nalUnits; } private static boolean compare(Picture8Bit expected, Picture8Bit actual) { int size = expected.getWidth() * expected.getHeight(); byte[] expY = expected.getPlaneData(0); byte[] actY = actual.getPlaneData(0); for (int i = 0; i < size; i++) { if (expY[i] != actY[i]) return false; } byte[] expCb = expected.getPlaneData(1); byte[] actCb = actual.getPlaneData(1); for (int i = 0; i < (size >> 2); i++) { if (expCb[i] != actCb[i]) return false; } byte[] expCr = expected.getPlaneData(2); byte[] actCr = actual.getPlaneData(2); for (int i = 0; i < (size >> 2); i++) { if (expCr[i] != actCr[i]) return false; } return true; } }