我有一个三星Galaxy S3 Mini(GT-I8190@4.1.1),我无法将原始视频帧编码为H.264。我已经测试了几个其他设备与不同的编码器供应商和我能够得到工作添加一些供应商/版本特定的怪癖。
没有一个通常的怀疑工作,(对齐缓冲区...等),我发现了几个自定义ROM与修复的奇数输入像素格式:示例。这给了我一些进展,直到我无法配置MediaCodec导致断言:
我挖了一些更多,并找到了这个问题的一个修复的帖子。这样我就可以创建和启动MediaCodec,但是现在我面临一个缓冲区问题,因为编码器只为每个输入缓冲区提供12字节,这是非常奇怪的。
有什么问题吗?
示例代码:
MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
format.setInteger(MediaFormat.KEY_WIDTH, width);
format.setInteger(MediaFormat.KEY_HEIGHT, height);
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, capabilities.getH264EncoderPixelFormat());
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
format.setInteger("stride", stride);
format.setInteger("slice-height", sliceHeight);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
codec = MediaCodec.createEncoderByType("video/avc");
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
codec.getInputBuffers()之后的内容ByteBuffer[]inputBuffers:
[java.nio.ReadWriteDirectByteBuffer,Status:Capacity=12 Position=0 Limit=12,java.nio.ReadWriteDirectByteBuffer,Status:Capacity=12 Position=0 Limit=12]
看起来您选择了供应商特定的颜色格式。根据注释链接的补丁,0x7FA00000为omx_ste_color_formatyuv420packedsemiplanarmb
。从它只提供12字节缓冲区的事实来看,我认为这实际上是向缓冲区传递句柄,而不是向缓冲区内容传递句柄(类似于color_formatsurface
)。
由于您正在尝试输入原始数据的缓冲区,因此除非您能够对它们的分配器和自定义的像素格式进行反向工程(例如,我看到在该补丁中定义的pixel_format_ycbcr42xmbn
),否则您可能无法使其工作。
我建议从一组已知格式中选择输入格式。您可以在SelectColorFormat()
方法中的EncodeDecodeTest中看到一个示例。对于API>=18的所有设备的支持,您只需处理两种情况:平面和半平面YUV420。