JCodec простой H264 кодировать / декодировать - PullRequest
5 голосов
/ 01 июля 2019

Хорошо, поэтому пытаюсь разобраться с jcodec. По сути, я хочу записать то, что на экране, как BufferedImages, закодировать буферизованные изображения в кадры H264, а затем декодировать их и преобразовать обратно в буферизованное изображение.

Это код, который у меня есть, класс ScreenRecorder расширяет поток и в основном захватывает экран во время истинного цикла. Эта часть работает. Затем кажется, что кодирование BufferedImage из ScreenRecorder в качестве кадра H264 тоже работает, но затем, когда я пытаюсь его декодировать, я получаю AIOBE

ScreenRecorder sc = new ScreenRecorder();
sc.start();

    H264Encoder enc = H264Encoder.createH264Encoder();
    ColorSpace cs = enc.getSupportedColorSpaces()[0];
    System.out.println("cs= " + cs);
    H264Decoder dec = new H264Decoder();
    byte[][] buff = new byte[4096][4096];
    while (true) {
        BufferedImage bi = sc.getSnapshot();
        System.out.println("Got bi " + bi);
        if (bi != null) {
            Picture pi = AWTUtil.fromBufferedImage(bi, cs);
            int bufSize = enc.estimateBufferSize(pi);
            ByteBuffer bb = ByteBuffer.allocate(bufSize);
            VideoEncoder.EncodedFrame ef = enc.encodeFrame(pi, bb);
            System.out.println("Data = " + Arrays.toString(ef.getData().array()));
            Frame f = dec.decodeFrame(ef.getData(), buff);
            System.out.println("Decoded frame = " + f);
        }
    }

Производит:

Got bi BufferedImage@506e1b77: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 1920 height = 1080 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0
org.jcodec.common.VideoEncoder$EncodedFrame@1a93a7ca
Data = [0, 0, 0, 1, 103, 66, 0, 40, -83, 0, -16, 4, 75, -54, -128, 0, 0, 0, 1, 104, -50, 56, -128, 0, 0, 0, 1, 101, -72, 32, 13, 12, 98, -128, 0, -111, 127, -1, -3, 127, -61, 24, 0, 36, 9, 112, -96, 28, 13, -108, -43, 45, -92, -57, 7, 101, 39, 31, -4, 0, 121, -104, 17, -86, 9, 84, -111, -94, 39, 125, 94, -57, 64, 2, 67, 56, 28, 0, 4, 0, 118, -97, -128, 40, 124, 20, 39, 122, 111, -117, -124, 25, 72, -76, -107, 90, -1, -122, 48, 0, 67, 41, 10, -64, 0, 32, 106, 0, 5, -128, -108, -13, 80, 51, 112, 113, 112, 107, -1, -17, -32, 32, 85, -60, -76, 52, 70, -67, 124, 3, 113, 111, 51, 0, 1, 0, -64, 0, 16, 15, -5, -48, 3, -80, -21, -2, 24, -64, 25, -48, 0, 16, 39, 0, 1, 0, 105, -112, 13, 9, 11, -35, -16, 56, 0, 8, 6, -128, 0, -128, 80, 0, -69, -112, -32, 0, 32, 26, 0, 2, 1, 64, 2, -18, 124, 56, 0, 8, 6, -128, 0, -128, 80, 0, -69, -112, -32, 0, 32, 26, 0, 2, 1, 64, 2, -18, 47, -8, 98, 56, 0, -112, 15, 21, 96, 3, 102, 59, -124, 48, 83, 96, 55, -10, 1, 55, -6, 27, 0, 67, 19, 47, -12, 90, 112, -125, -108, 64, 38, 9, 83, 29, 101, -56, 75, -126, -85, -96, 113, 17, -105, 2, 57, 98, 56, -66, 28, 88, -105, ...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.jcodec.codecs.h264.decode.SliceDecoder.putMacroblock(SliceDecoder.java:198)
    at org.jcodec.codecs.h264.decode.SliceDecoder.decodeMacroblocks(SliceDecoder.java:104)
    at org.jcodec.codecs.h264.decode.SliceDecoder.decodeFromReader(SliceDecoder.java:73)
    at org.jcodec.codecs.h264.H264Decoder$FrameDecoder.decodeFrame(H264Decoder.java:152)
    at org.jcodec.codecs.h264.H264Decoder.decodeFrameFromNals(H264Decoder.java:103)
    at org.jcodec.codecs.h264.H264Decoder.decodeFrame(H264Decoder.java:99)
    at uno.anahata.satgyara.screen.ScreenRecorder.main(ScreenRecorder.java:148)

Просто пытаюсь понять, как работает jcodec. Любые идеи относительно того, что я делаю неправильно? Любая помощь будет оценена

...