[英]Android MediaCodec decode h264 raw frame
我正在使用Android MediaCodec API来解码h264帧。 我可以在视图上解码和渲染帧。 我的问题是解码器错过了很多帧,特别是前几帧。 DecodeMediaCodec.dequeueOutputBuffer()返回-1。 a约150 h264帧,刚解码43帧。 我找不到问题所在。 这是我的代码。
/**
* init decoder
*/
private void initDecodeMediaCodec()
{
mDecodeMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE,
VIDEO_WIDTH_640,
VIDEO_HEIGHT_480);
mDecodeMediaCodec.configure(format,
new Surface(mRemoteVideoView.getSurfaceTexture()),
null,
0);
mDecodeMediaCodec.start();
mDecodeInputBuffers = mDecodeMediaCodec.getInputBuffers();
System.out.println("decode-----"
+ mDecodeMediaCodec.getCodecInfo().getName());
}
解码器初始化后,我将启动解码器线程。
/**
*
* @param frameData
*/
private void decode()
{
new Thread(new Runnable()
{
@Override
public void run()
{
while (true)
{
ByteBuffer decodeDataBuffer = null;
try
{
//take h264 frame from cache queue
decodeDataBuffer = decodeDataQuene.take();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
BufferInfo info = new BufferInfo();
int inputBufferIndex = mDecodeMediaCodec.dequeueInputBuffer(-1);
System.out.println("inputBufferIndex: " + inputBufferIndex);
if (inputBufferIndex >= 0)
{
ByteBuffer buffer = mDecodeInputBuffers[inputBufferIndex];
buffer.clear();
buffer.put(decodeDataBuffer.array());
mDecodeMediaCodec.queueInputBuffer(inputBufferIndex,
0,
decodeDataBuffer.array().length,
0,
0);
decodeDataBuffer.clear();
decodeDataBuffer = null;
}
int outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info,
1000);
System.out.println("outputBufferIndex: "
+ outputBufferIndex);
do
{
if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER)
{
//no output available yet
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
//encodeOutputBuffers = mDecodeMediaCodec.getOutputBuffers();
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
MediaFormat formats = mDecodeMediaCodec.getOutputFormat();
//mediaformat changed
}
else if (outputBufferIndex < 0)
{
//unexpected result from encoder.dequeueOutputBuffer
}
else
{
mDecodeMediaCodec.releaseOutputBuffer(outputBufferIndex,
true);
outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info,
0);
System.out.println("inner outputBufferIndex: "
+ outputBufferIndex);
}
} while (outputBufferIndex > 0);
}
}
}).start();
}
谁知道为什么?我希望你的帮助。我的Android设备是nexus 7。
从MediaCodec#dequeueOutputBuffer()
-1 MediaCodec#dequeueOutputBuffer()
是正常的。 它只是意味着它还没有准备好任何输出。
您不是将MediaCodec
作为编码数据缓冲区并立即获得解码缓冲区的情况。 你将它交给数据缓冲区,然后将其发送到mediaserver
进程,该进程将其提供给硬件AVC解码器,该解码器可能仍在初始化或者可能只是喜欢坐在几帧上。 解码过程完成后,解码后的数据将通过mediaserver
传递回您的应用程序进程。
诀窍是, queueInputBuffer()
调用立即返回。 在正常操作中,解码器的输入侧将在输出侧之前运行几帧。 当您完成输入输入时,您可以设置流结束标志,当您在输出上看到EOS设置时,您就知道已经到达终点。
你可以在bigflake和Grafika找到各种工作实例。 DecodeEditEncodeTest和EncodeDecodeTest示例仅使用原始H.264,其他使用MediaExtractor
和MediaMuxer
来处理MP4文件包装器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.