@Override public byte[][] allocatePicture() { return Picture.create(1920, 1088, ColorSpace.YUV444).getData(); } }
ByteBuffer bb = ... // Your frame data is stored in this buffer H264Decoder decoder = new H264Decoder(); Picture out = Picture.create(1920, 1088, ColorSpace.YUV_420); // Allocate output frame of max size Picture real = decoder.decodeFrame(bb, out.getData()); BufferedImage bi = JCodecUtil.toBufferedImage(real); // If you prefere AWT image
public Picture decodeVideo(ByteBuffer data, Picture target1) { return videoDecoder.decodeFrame(data, target1.getData()); }
@Override public void transform(Picture src, Picture dst) { for (int i = 0; i < Math.min(src.getData().length, dst.getData().length); i++) arraycopy(src.getPlaneData(i), 0, dst.getPlaneData(i), 0, Math.min(src.getPlaneData(i).length, dst.getPlaneData(i).length)); byte[][] srcLowBits = src.getLowBits(); byte[][] dstLowBits = dst.getLowBits(); if (srcLowBits != null && dstLowBits != null) { for (int i = 0; i < Math.min(src.getData().length, dst.getData().length); i++) arraycopy(srcLowBits[i], 0, dstLowBits[i], 0, Math.min(src.getPlaneData(i).length, dst.getPlaneData(i).length)); } } }
byte getPel(Picture pic, int plane, int x, int y) { if (x < 0) x = 0; if (y < 0) y = 0; int w = pic.getPlaneWidth(plane); if (x > w - 1) x = w - 1; int h = pic.getPlaneHeight(plane); if (y > h - 1) y = h - 1; return pic.getData()[plane][x + y * w]; }
private void chroma(Picture pic, int mbX, int mbY, BitWriter out, int qp, Picture outMB) { int x = mbX << 3; int y = mbY << 3; int[][] ac1 = new int[4][16]; int[][] ac2 = new int[4][16]; byte[][] pred1 = new byte[4][16]; byte[][] pred2 = new byte[4][16]; predictChroma(pic, ac1, pred1, 1, x, y); predictChroma(pic, ac2, pred2, 2, x, y); chromaResidual(pic, mbX, mbY, out, qp, ac1, ac2, cavlc[1], cavlc[2], I_16x16, I_16x16); putChroma(outMB.getData()[1], 1, x, y, ac1, pred1); putChroma(outMB.getData()[2], 2, x, y, ac2, pred2); }
@Override public void transform(Picture img, Picture dst) { byte[] y = img.getData()[0]; byte[] out1 = new byte[3]; byte[] out2 = new byte[3]; byte[][] dstData = dst.getData(); int off = 0, offSrc = 0; for (int i = 0; i < img.getHeight(); i++) { for (int j = 0; j < img.getWidth() >> 1; j++) { int offY = off << 1; RgbToYuv420p.rgb2yuv(y[offSrc++], y[offSrc++], y[offSrc++], out1); dstData[0][offY] = out1[0]; RgbToYuv420p.rgb2yuv(y[offSrc++], y[offSrc++], y[offSrc++], out2); dstData[0][offY + 1] = out2[0]; dstData[1][off] = (byte) ((out1[1] + out2[1] + 1) >> 1); dstData[2][off] = (byte) ((out1[2] + out2[2] + 1) >> 1); ++off; } } } }
public ByteBuffer encodeFrame(Picture picture) { if (picture.getColor() != ColorSpace.RGB) throw new IllegalArgumentException("Only RGB image can be stored in PPM"); ByteBuffer buffer = ByteBuffer.allocate(picture.getWidth() * picture.getHeight() * 3 + 200); buffer.put(JCodecUtil2.asciiString("P6 " + picture.getWidth() + " " + picture.getHeight() + " 255\n")); byte[][] data = picture.getData(); for (int i = 0; i < picture.getWidth() * picture.getHeight() * 3; i += 3) { buffer.put((byte) (data[0][i + 2] + 128)); buffer.put((byte) (data[0][i + 1] + 128)); buffer.put((byte) (data[0][i] + 128)); } buffer.flip(); return buffer; } }
@Override public byte[][] allocatePicture() { return Picture.create(size.getWidth(), size.getHeight(), ColorSpace.YUV444).getData(); }
public static Picture createCroppedHiBD(int width, int height, int lowBitsNum, ColorSpace colorSpace, Rect crop) { Picture result = createCropped(width, height, colorSpace, crop); if (lowBitsNum <= 0) return result; byte[][] data = result.getData(); int nPlanes = data.length; byte[][] lowBits = new byte[nPlanes][]; for (int i = 0, plane = 0; i < nPlanes; i++) { lowBits[plane++] = new byte[data[i].length]; } result.setLowBits(lowBits); result.setLowBitsNum(lowBitsNum); return result; }
public static Picture fromPictureHiBD(PictureHiBD pic) { int lowBitsNum = pic.getBitDepth() - 8; int lowBitsRound = (1 << lowBitsNum) >> 1; Picture result = Picture.createCroppedHiBD(pic.getWidth(), pic.getHeight(), lowBitsNum, pic.getColor(), pic.getCrop()); for (int i = 0; i < Math.min(pic.getData().length, result.getData().length); i++) { for (int j = 0; j < Math.min(pic.getData()[i].length, result.getData()[i].length); j++) { int val = pic.getData()[i][j]; int round = MathUtil.clip((val + lowBitsRound) >> lowBitsNum, 0, 255); result.getData()[i][j] = (byte) (round - 128); } } byte[][] lowBits = result.getLowBits(); if (lowBits != null) { for (int i = 0; i < Math.min(pic.getData().length, result.getData().length); i++) { for (int j = 0; j < Math.min(pic.getData()[i].length, result.getData()[i].length); j++) { int val = pic.getData()[i][j]; int round = MathUtil.clip((val + lowBitsRound) >> lowBitsNum, 0, 255); lowBits[i][j] = (byte) (val - (round << 2)); } } } return result; }
public Frame cropped() { Picture cropped = super.cropped(); return new Frame(cropped.getWidth(), cropped.getHeight(), cropped.getData(), cropped.getColor(), null, frameNo, frameType, mvs, refsUsed, poc); }
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); }
public static Frame createFrame(Frame pic) { Picture comp = pic.createCompatible(); return new Frame(comp.getWidth(), comp.getHeight(), comp.getData(), comp.getColor(), pic.getCrop(), pic.frameNo, pic.frameType, pic.mvs, pic.refsUsed, pic.poc); }
@Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof Picture)) return false; Picture other = (Picture) obj; if (other.getCroppedWidth() != getCroppedWidth() || other.getCroppedHeight() != getCroppedHeight() || other.getColor() != color) return false; for (int i = 0; i < getData().length; i++) if (!planeEquals(other, i)) return false; return true; }
/** * Get block of ( possibly interpolated ) luma pixels */ public void getBlockLuma(Picture pic, Picture out, int off, int x, int y, int w, int h) { int xInd = x & 0x3; int yInd = y & 0x3; int xFp = x >> 2; int yFp = y >> 2; if (xFp < 2 || yFp < 2 || xFp > pic.getWidth() - w - 5 || yFp > pic.getHeight() - h - 5) { unsafe[(yInd << 2) + xInd].getLuma(pic.getData()[0], pic.getWidth(), pic.getHeight(), out.getPlaneData(0), off, out.getPlaneWidth(0), xFp, yFp, w, h); } else { safe[(yInd << 2) + xInd].getLuma(pic.getData()[0], pic.getWidth(), pic.getHeight(), out.getPlaneData(0), off, out.getPlaneWidth(0), xFp, yFp, w, h); } }
private void split(Picture in, Picture out, int mbX, int mbY, int sliceMbCount, int vStep, int vOffset) { byte[][] inData = in.getData(); byte[][] inhbdData = in.getLowBits(); byte[][] outData = out.getData(); byte[][] outhbdData = out.getLowBits(); doSplit(inData[0], outData[0], in.getPlaneWidth(0), mbX, mbY, sliceMbCount, 0, vStep, vOffset); doSplit(inData[1], outData[1], in.getPlaneWidth(1), mbX, mbY, sliceMbCount, 1, vStep, vOffset); doSplit(inData[2], outData[2], in.getPlaneWidth(2), mbX, mbY, sliceMbCount, 1, vStep, vOffset); if (in.getLowBits() != null) { doSplit(inhbdData[0], outhbdData[0], in.getPlaneWidth(0), mbX, mbY, sliceMbCount, 0, vStep, vOffset); doSplit(inhbdData[1], outhbdData[1], in.getPlaneWidth(1), mbX, mbY, sliceMbCount, 1, vStep, vOffset); doSplit(inhbdData[2], outhbdData[2], in.getPlaneWidth(2), mbX, mbY, sliceMbCount, 1, vStep, vOffset); } }
@Override public Picture decodeField(ByteBuffer data, byte[][] data2, int field, int step) { Picture res = super.decodeField(data, data2, field, step); return new Picture(res.getWidth() >> 1, res.getHeight() >> 1, res.getData(), null, res.getColor(), 0, new Rect( 0, 0, res.getCroppedWidth() >> 1, res.getCroppedHeight() >> 1)); } }
@Override public Picture decodeField(ByteBuffer data, byte[][] data2, int field, int step) { Picture res = super.decodeField(data, data2, field, step); return new Picture(res.getWidth() >> 2, res.getHeight() >> 2, res.getData(), null, res.getColor(), 0, new Rect( 0, 0, res.getCroppedWidth() >> 2, res.getCroppedHeight() >> 2)); } }
public static void subImageWithFillPic8(Picture _in, Picture out, Rect rect) { int width = _in.getWidth(); int height = _in.getHeight(); ColorSpace color = _in.getColor(); byte[][] data = _in.getData(); for (int i = 0; i < data.length; i++) { subImageWithFill(data[i], width >> color.compWidth[i], height >> color.compHeight[i], out.getPlaneData(i), rect.getWidth() >> color.compWidth[i], rect.getHeight() >> color.compHeight[i], rect.getX() >> color.compWidth[i], rect.getY() >> color.compHeight[i]); } } }