Android MediaCodec解码h264原始帧

我正在使用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。

Solutions Collecting From Web of "Android MediaCodec解码h264原始帧"

MediaCodec#dequeueOutputBuffer()返回-1 MediaCodec#dequeueOutputBuffer()是正常的。 这只是意味着它还没有任何输出。

MediaCodec并不是一个编码数据的缓冲区,而是立即得到一个解码的缓冲区。 你把一个数据缓冲区发送到mediaserver进程,将其传送到硬件AVC解码器,这个解码器可能还在初始化,或者只是坐在几个帧上。 解码过程完成后,解码的数据将通过mediaserver传回您的应用程序进程。

诀窍是, queueInputBuffer()调用立即返回。 在正常操作中,解码器的input端将在输出端之前运行数帧。 当你完成喂料input时,你设置了stream结束标志,当你看到输出EOS设置,你知道你已经达到了最后。

你可以在大片和Grafika上find各种实例。 DecodeEditEncodeTest和EncodeDecodeTest示例仅使用原始H.264,其他使用MediaExtractorMediaMuxer处理MP4文件包装。