package org.jcodec.containers.mkv;
import static java.lang.String.format;
import static org.jcodec.codecs.h264.H264Utils.splitMOVPacket;
import static org.jcodec.common.model.ColorSpace.RGB;
import org.jcodec.codecs.h264.H264Decoder;
import org.jcodec.codecs.h264.H264Utils;
import org.jcodec.codecs.h264.mp4.AvcCBox;
import org.jcodec.common.DemuxerTrack;
import org.jcodec.common.io.IOUtils;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Packet;
import org.jcodec.common.model.Picture8Bit;
import org.jcodec.containers.mkv.demuxer.MKVDemuxer;
import org.jcodec.containers.mkv.demuxer.MKVDemuxer.VideoTrack;
import org.jcodec.scale.AWTUtil;
import org.jcodec.scale.Transform8Bit;
import org.jcodec.scale.Yuv420pToRgb8Bit;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.System;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
public class MKVFrameReadingTest {
static MKVTestSuite suite;
static String outPattern = "/tmp/frame%d.png";
/*
@BeforeClass
public static void setUpTestSuite() throws Exception {
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");
}
*/
MKVParser par;
MKVDemuxer dem;
SeekableByteChannel demInputStream;
/*
@Before
public void setUp() throws IOException {
FileInputStream inputStream = new FileInputStream(suite.test5);
par = new MKVParser(new FileChannelWrapper(inputStream.getChannel()));
List<EbmlMaster> t = null;
try {
t = par.parse();
} finally {
closeQuietly(inputStream);
}
FileInputStream fis = new FileInputStream(suite.test5);
demInputStream = new FileChannelWrapper(fis.getChannel());
dem = new MKVDemuxer(t, demInputStream);
}
*/
@Ignore @Test
public void test() throws Exception {
H264Decoder decoder = new H264Decoder();
Transform8Bit transform = new Yuv420pToRgb8Bit();
DemuxerTrack inTrack = dem.getVideoTracks().get(0);
Picture8Bit rgb = Picture8Bit.create(dem.getPictureWidth(), dem.getPictureHeight(), ColorSpace.RGB);
BufferedImage bi = new BufferedImage(dem.getPictureWidth(), dem.getPictureHeight(), BufferedImage.TYPE_3BYTE_BGR);
AvcCBox avcC = AvcCBox.parseAvcCBox(((VideoTrack) inTrack).getCodecState());
decoder.addSps(avcC.getSpsList());
decoder.addPps(avcC.getPpsList());
Packet inFrame;
for (int i = 1; (inFrame = inTrack.nextFrame()) != null && i <= 200; i++) {
Picture8Bit buf = Picture8Bit.create(dem.getPictureWidth(), dem.getPictureHeight(), ColorSpace.YUV422);
Picture8Bit pic = decoder.decodeFrame8BitFromNals(splitMOVPacket(inFrame.getData(), avcC), buf.getData());
if (bi == null)
bi = new BufferedImage(pic.getWidth(), pic.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
if (rgb == null)
rgb = Picture8Bit.create(pic.getWidth(), pic.getHeight(), RGB);
transform.transform(pic, rgb);
AWTUtil.toBufferedImage8Bit2(rgb, bi);
ImageIO.write(bi, "png", new File(format(outPattern, i++)));
}
}
@Ignore @Test
public void testFirstFrame() throws Exception {
Transform8Bit transform = new Yuv420pToRgb8Bit();
H264Decoder decoder = new H264Decoder();
DemuxerTrack inTrack = dem.getVideoTracks().get(0);
AvcCBox avcC = AvcCBox.parseAvcCBox(((VideoTrack) inTrack).getCodecState());
Assert.assertNotNull(avcC.getSpsList());
Assert.assertFalse(avcC.getSpsList().isEmpty());
Assert.assertNotNull(avcC.getPpsList());
Assert.assertFalse(avcC.getPpsList().isEmpty());
decoder.addSps(avcC.getSpsList());
decoder.addPps(avcC.getPpsList());
Packet inFrame = inTrack.nextFrame();
Assert.assertNotNull(inFrame);
ByteBuffer bb = inFrame.getData();
Assert.assertNotNull(bb);
File file = new File(suite.base, "test5_frame0.h264");
byte[] rawFrame = IOUtils.readFileToByteArray(file);
Assert.assertArrayEquals(rawFrame, MKVMuxerTest.bufferToArray(bb));
Picture8Bit buf = Picture8Bit.create(dem.getPictureWidth(), dem.getPictureHeight(), ColorSpace.YUV422);
Picture8Bit pic = decoder.decodeFrame8BitFromNals(H264Utils.splitMOVPacket(inFrame.getData(), avcC), buf.getData());
Picture8Bit rgb = Picture8Bit.create(dem.getPictureWidth(), dem.getPictureHeight(), ColorSpace.RGB);
BufferedImage bi = new BufferedImage(dem.getPictureWidth(), dem.getPictureHeight(), BufferedImage.TYPE_3BYTE_BGR);
transform.transform(pic, rgb);
AWTUtil.toBufferedImage8Bit2(rgb, bi);
File f = new File(format(outPattern, 0));
System.out.println("Writing to file: "+f.getAbsolutePath());
ImageIO.write(bi, "png", f);
}
}