Rendern Sie Bitmap-Frames zur Codierung auf Surface

Mein Ziel ist es, eine M4V-Videodatei aufzunehmen, ein Segment des Videos als PNG-Frames zu dekodieren, diese Frames zu ändern und das zugeschnittene Video neu zu kodieren (auch auf M4V).

Der Workflow sieht folgendermaßen aus:[Input Video] -> Export Frames -> Modify Frames -> Encode Frames -> [Output Video].

Für den Dekodierungsprozess habe ich das referenziertBigflake Beispiele. Verwendung derExtractMpegFramesTest Beispielcode, den ich generieren konnteBitmap Frames von einem.m4v Bilder als PNG-Dateien speichern und exportieren.

Jetzt versuche ich den Neucodierungsprozess mit derEncodeAndMuxTest Beispiel für den Versuch, einen anderen Satz von Klassen für die Codierung zu erstellen.

Das Problem, auf das ich stoße, ist, dass der Beispielcode scheinbar unformatierte Frames in OpenGL generiert. Ich habe eine Reihe vonBitmaps dass ich das verschlüsseln / rendern willCodecInputSurface Objekt. Ziemlich genau das Gegenteil von dem, was der Dekodierungsprozess macht.

Der Großteil des Beispielcodes ist in Ordnung, anscheinend muss ich ihn nur änderngenerateSurfaceFrame() um das zu rendernBitmap zumSurface mit OpenGL.

Hier ist der Code, den ich bisher habe:

// Member variables (see EncodeAndMuxTest example)
private MediaCodec encoder;
private CodeInputSurface inputSurface;
private MediaMuxer muxer;
private int trackIndex;
private boolean hasMuxerStarted;
private MediaCodec.BufferInfo bufferInfo;

// This is called for each frame to be rendered into the video file
private void encodeFrame(Bitmap bitmap)
{
    int textureId = 0;

    try
    {
        textureId = loadTexture(bitmap);

        // render the texture here?
    }
    finally
    {
        unloadTexture(textureId);
    }
}

// Loads a texture into OpenGL
private int loadTexture(Bitmap bitmap)
{
    final int[] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);

    int textureWidth = bitmap.getWidth();
    int textureHeight = bitmap.getHeight();

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);

    return textures[0];
}

// Unloads a texture from OpenGL
private void unloadTexture(int textureId)
{
    final int[] textures = new int[1];
    textures[0] = textureId;

    GLES20.glDeleteTextures(1, textures, 0);
}

Ich fühle mich wie ich in der Lage sein sollte, die zu verwendenSTextureRender von demExtractMpegFramesTest Beispiel ähnlich zu erreichen, aber es ist nur nicht für mich klicken.

Eine andere Sache ist Leistung, die ich wirklich versuche, leistungsfähige Kodierung zu erhalten. Ich werde 90-450 Videobilder (3-15 Sekunden bei 30 Bildern pro Sekunde) codieren, daher sollte dies hoffentlich nur einige Sekunden dauern.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage