package org.jcodec.api; import static org.jcodec.Utils.picturesRoughlyEqual; import org.jcodec.Utils; import org.jcodec.codecs.h264.io.model.Frame; import org.jcodec.common.io.FileChannelWrapper; import org.jcodec.common.io.IOUtils; import org.jcodec.common.io.NIOUtils; import org.jcodec.common.model.Picture8Bit; import org.junit.Assert; import org.junit.Test; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.System; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class FrameGrabTest { private static final String SEQ_1_MP4 = "src/test/resources/video/seq_h264_1.mp4"; private static final String SEQ_2_MP4 = "src/test/resources/video/seq_h264_2.mp4"; private static final String SEQ_3_MP4 = "src/test/resources/video/seq_h264_3.mp4"; private static final String SEQ_1_YUV = "src/test/resources/video/seq_1.yuv"; private static final String SEQ_2_YUV = "src/test/resources/video/seq_2.yuv"; private static final String SEQ_3_YUV = "src/test/resources/video/seq_3.yuv"; private boolean saveImages = false; @Test public void testFrameGrab() throws IOException, JCodecException { compareOneSequence(SEQ_1_MP4, SEQ_1_YUV); compareOneSequence(SEQ_2_MP4, SEQ_2_YUV); compareOneSequence(SEQ_3_MP4, SEQ_3_YUV); } private void compareOneSequence(String compressed, String uncompressed) throws FileNotFoundException, IOException, JCodecException { FileChannelWrapper ch1 = null, ch2 = null; try { ch1 = NIOUtils.readableChannel(new File(compressed)); ch2 = NIOUtils.readableChannel(new File(uncompressed)); FrameGrab8Bit frameGrab1 = FrameGrab8Bit.createFrameGrab8Bit(ch1); PictureWithMetadata8Bit fr1; List<PictureWithMetadata8Bit> decoded = new ArrayList<PictureWithMetadata8Bit>(); do { fr1 = frameGrab1.getNativeFrameWithMetadata(); if (fr1 == null) break; fr1 = new PictureWithMetadata8Bit(fr1.getPicture().cloneCropped(), fr1.getTimestamp(), fr1.getDuration()); decoded.add(fr1); } while (fr1 != null); Collections.sort(decoded, new Comparator<PictureWithMetadata8Bit>() { @Override public int compare(PictureWithMetadata8Bit o1, PictureWithMetadata8Bit o2) { return o1.getTimestamp() < o2.getTimestamp() ? -1 : (o1.getTimestamp() == o2.getTimestamp() ? 0 : 1); } }); for (PictureWithMetadata8Bit pic : decoded) { Frame frame = (Frame) pic.getPicture(); Picture8Bit fr2 = Utils.readYuvFrame(ch2, frame.getWidth(), frame.getHeight()); if (saveImages && Utils.maxDiff(frame, fr2) > 0) { System.out.println(String.format("POC: %d, pts: %f", frame.getPOC(), pic.getTimestamp())); Utils.saveImage(fr2, "png", String.format("/tmp/orig_%s_%f.%s", new File(compressed).getName(), pic.getTimestamp(), "png")); Utils.saveImage(frame, "png", String.format("/tmp/dec_%s_%f.%s", new File(compressed).getName(), pic.getTimestamp(), "png")); Utils.saveImage(Utils.diff(frame, fr2, 10), "png", String.format("/tmp/diff_%s_%f.%s", new File( compressed).getName(), pic.getTimestamp(), "png")); } Assert.assertTrue( String.format("Seq %s, poc %d, pts %f", compressed, frame.getPOC(), pic.getTimestamp()), picturesRoughlyEqual(frame, fr2, 50)); } } finally { IOUtils.closeQuietly(ch1); IOUtils.closeQuietly(ch2); } } }