Объясните, как этот кодировщик работает с PPS и SPS? - PullRequest
0 голосов
/ 08 сентября 2018

Я нашел этот код в Интернете. Может кто-нибудь объяснить, что такое PPS и SPS?

Все, что есть после if (sps != null && pps != null) Я понимаю, что поскольку мы проверяем if (spsPpsBuffer.getInt() == 0x00000001), потому что NALU начинается с 0x00000001 но после этого я действительно не понимаю следующее:

  • Почему ppsIndex сначала устанавливается в 0, а затем spsPpsBuffer.position()?

  • Почему размер буфера SPS равен ppsIndex - 8?

  • Почему размер буфера PPS равен outData.length - ppsIndex?

Это код:

@Override
public void offerEncoder(byte[] input) {
    try {
        ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
        ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
            inputBuffer.clear();
            inputBuffer.put(input);
            mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
        }
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        while (outputBufferIndex >= 0) {
            ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
            byte[] outData = new byte[bufferInfo.size];
            outputBuffer.get(outData);
            if (sps != null && pps != null) {
                ByteBuffer frameBuffer = ByteBuffer.wrap(outData);
                frameBuffer.putInt(bufferInfo.size - 4);
                frameListener.frameReceived(outData, 0, outData.length);
            } else {
                ByteBuffer spsPpsBuffer = ByteBuffer.wrap(outData);
                if (spsPpsBuffer.getInt() == 0x00000001) {
                    System.out.println("parsing sps/pps");
                } else {
                    System.out.println("something is amiss?");
                }
                int ppsIndex = 0;
                while(!(spsPpsBuffer.get() == 0x00 && spsPpsBuffer.get() == 0x00 && spsPpsBuffer.get() == 0x00 && spsPpsBuffer.get() == 0x01)) {
                }
                ppsIndex = spsPpsBuffer.position();
                sps = new byte[ppsIndex - 8];
                System.arraycopy(outData, 4, sps, 0, sps.length);
                pps = new byte[outData.length - ppsIndex];
                System.arraycopy(outData, ppsIndex, pps, 0, pps.length);
                if (null != parameterSetsListener) {
                    parameterSetsListener.avcParametersSetsEstablished(sps, pps);
                }
            }
            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        }
    } catch (Throwable t) {
        t.printStackTrace();
    }
}

Большое спасибо.

1 Ответ

0 голосов
/ 10 сентября 2018

Общее представление о PPS / SPS можно получить из более раннего ответа: H264 с несколькими PPS и SPS

Приведенный выше код является узкоспециализированным и будет работать только с небольшим подмножеством потоков H.264. Код предполагает SPS фиксированной длины (8 байт) и делает еще несколько неверных предположений. Если код не для одного конкретного кодировщика - я бы, вероятно, не использовал его.

Кажется, это хороший парсер H.264: https://github.com/aizvorski/h264bitstream

...