Codificación H.264 de la cámara con Android MediaCodec

Estoy tratando de hacer que esto funcione en Android 4.1 (usando una tableta Asus Transformer actualizada). Gracias aLa respuesta de Alex a mi pregunta anterior., Ya pude escribir algunos datos en bruto H.264 en un archivo, pero este archivo solo se puede reproducir conffplay -f h264, y parece que se ha perdido toda la información relacionada con la tasa de cuadros (reproducción extremadamente rápida). Además, el espacio de color se ve incorrecto (la atm usa el valor predeterminado de la cámara en el lado del codificador).

public class AvcEncoder {

private MediaCodec mediaCodec;
private BufferedOutputStream outputStream;

public AvcEncoder() { 
    File f = new File(Environment.getExternalStorageDirectory(), "Download/video_encoded.264");
    touch (f);
    try {
        outputStream = new BufferedOutputStream(new FileOutputStream(f));
        Log.i("AvcEncoder", "outputStream initialized");
    } catch (Exception e){ 
        e.printStackTrace();
    }

    mediaCodec = MediaCodec.createEncoderByType("video/avc");
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240);
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
    mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mediaCodec.start();
}

public void close() {
    try {
        mediaCodec.stop();
        mediaCodec.release();
        outputStream.flush();
        outputStream.close();
    } catch (Exception e){ 
        e.printStackTrace();
    }
}

// called from Camera.setPreviewCallbackWithBuffer(...) in other class
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);
            outputStream.write(outData, 0, outData.length);
            Log.i("AvcEncoder", outData.length + " bytes written");

            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);

        }
    } catch (Throwable t) {
        t.printStackTrace();
    }

}

Cambiar el tipo de codificador a "video / mp4" aparentemente resuelve el problema de la tasa de cuadros, pero como el objetivo principal es hacer un servicio de transmisión, esta no es una buena solución.

Soy consciente de que eliminé parte del código de Alex considerando los SPS y PPS NALU, pero esperaba que esto no fuera necesario ya que esa información también provenía deoutData y asumí que el codificador formatearía esto correctamente. Si este no es el caso, ¿cómo debo organizar los diferentes tipos de NALU en mi archivo / flujo?

Entonces, ¿qué me estoy perdiendo aquí para hacer una transmisión H.264 válida y en funcionamiento? ¿Y qué ajustes debo usar para hacer una coincidencia entre el espacio de color de la cámara y el espacio de color del codificador?

Tengo la sensación de que esto es más una cuestión relacionada con H.264 que un tema de Android / MediaCodec. ¿O todavía no estoy usando la API MediaCodec correctamente?

Gracias por adelantado.

Respuestas a la pregunta(5)

Su respuesta a la pregunta