使用Android低级API解码H264流

9

我正在使用Android中的MediaCodec低级API来解码从IP相机接收到的h264原始流。从IP相机接收的原始流通过TCP/IP连接。

为了解码流,我的代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {

 MediaCodec mCodecc;
 MediaFormat mFormat;
 BufferInfo mInfo;
 ByteBuffer[] inputBuffers ;
 ByteBuffer[] outputBuffers ;

}
protected void Init_Codec()
{
  mCodecc = MediaCodec.createDecoderByType("video/avc");
  mFormat =  MediaFormat.createVideoFormat("video/avc", width, height);

  mInfo = new BufferInfo();
mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
  mCodecc.configure(mFormat, holder.getSurface(), null,0);
}

protected void Start_Codec()
{
  mCodecc.start();          
  inputBuffers = mCodecc.getInputBuffers();
  outputBuffers = mCodecc.getOutputBuffers();
}

private void OnRawStreamReceived(final ByteBuffer buffer)
{

 mHandler.postAtFrontOfQueue(new Runnable() {

@Override
public void run()
{
       int inIndex = mCodecc.dequeueInputBuffer(10000);
   if(inIndex>=0)
     {
    inputBuffers[inIndex] = buffer;
    mCodecc.queueInputBuffer(inIndex, 0,buffer.limit(),System.currentTimeMillis(), 0);
    }
       int outIndex = mCodecc.dequeueOutputBuffer(mInfo, 10000);
       switch (outIndex) {

    case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
    Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
    outputBuffers = mCodecc.getOutputBuffers();
    break;

    case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
    Log.d("DecodeActivity", "New format " + mCodecc.getOutputFormat());
    break;

        case MediaCodec.INFO_TRY_AGAIN_LATER:
    Log.d("DecodeActivity", "dequeueOutputBuffer timed out! --- size : " + mInfo.size );
    break;

    default:
    ByteBuffer buffer = outputBuffers[outIndex];

            mCodecc.releaseOutputBuffer(outIndex, true);
    break;
    }
}


int outIndex = mCodecc.dequeueOutputBuffer(mInfo, 10000);

但是在这行代码中,我一直收到“-1”。而且 mInfo.size() 的值也是“0”。并且它没有显示任何内容在给定的表面上。
我错过了哪一步,请指导我。谢谢。
1个回答

6
我假设您正在传递单个"访问单元",即每个缓冲区一个视频帧。
您似乎缺少编解码器设置块,它应该在提交的第一个缓冲区中(也可以通过 format.setByteBuffer("csd-0", ...) 将其隐藏在 MediaFormat 中)。假设数据从您特定的编码器输出,则只需使用 BUFFER_FLAG_CODEC_CONFIG 标志将第一个缓冲区排队即可。

@Arun 你搞定了吗? - nmxprime
@fadden。如何使用标志提供所需的csd数据,我的意思是,我在哪里可以获取H264的csd信息? - nmxprime
如果源代码没有提供,您需要构建它。它是一个包含SPS/PPS数据的字节块(参见例如http://www.cardinalpeak.com/blog/the-h-264-sequence-parameter-set/)。如果您使用`MediaCodec`编码器编码数据,则始终是第一个块;您可以查看该块以了解解码器期望的内容。 - fadden
1
嗨@Arun,我目前正在尝试从UDP流中获取h264原始流并做同样的事情。你解决了这个问题吗? - naike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接