Renderizar quadros de bitmap no Surface para codificação
Meu objetivo é capturar um arquivo de vídeo M4V, decodificar um segmento do vídeo como quadros PNG, modificar esses quadros e recodificar o vídeo cortado (também para M4V).
O fluxo de trabalho é assim:[Input Video] -> Export Frames -> Modify Frames -> Encode Frames -> [Output Video]
.
Para o processo de decodificação, estive referenciando obigflake exemplos. Usando oExtractMpegFramesTest código de exemplo que eu era capaz de gerarBitmap
quadros de um.m4v
arquivar e exportar quadros como arquivos PNG.
Agora estou tentando o processo de recodificação, usando oEncodeAndMuxTest exemplo, na tentativa de criar outro conjunto de classes para codificação.
O problema que estou enfrentando é que o código de exemplo parece gerar quadros brutos no OpenGL. Eu tenho uma série deBitmaps
que eu quero codificar / renderizar para oCodecInputSurface
objeto. Praticamente o contrário do que o processo de decodificação faz.
A maioria do código de exemplo é boa, parece que eu só preciso modificargenerateSurfaceFrame()
para renderizar oBitmap
aoSurface
com o OpenGL.
Aqui está o código que tenho até agora:
// 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);
}
Eu sinto que deveria poder usar oSTextureRender
deExtractMpegFramesTest exemplo para alcançar semelhante, mas não é só clicar para mim.
Outra coisa é o desempenho, que realmente estou tentando obter codificação eficiente. Codificarei 90-450 quadros de vídeo (3-15 segundos a 30fps), portanto, esperamos que isso leve apenas alguns segundos.