欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MediaCodec实现视频硬解码

程序员文章站 2022-07-05 16:18:28
...

什么是MediaCodec
MediaCodec是安卓原生提供的多媒体编解码器,大体工作流程就是MediaCodec提供一个输入流的缓冲数组,我们将需要编解码的流给MediaCodec,MediaCodec内部进行编解码然后输出你想要的编解码后的流。
在其他场景中也有surfaceview作为数据源的,而我的流程大体就是通过私有协议获取h264裸数据,然后解码成yuv格式,下面将描述我的实现过程。
1.创建解码器

MediaCodec mMediaCodec = MediaCodec.createDecoderByType("video/avc");

type类型还有很多,这里是对h264的解码,因此采用"video/avc"。

2.MediaCodec配置,用到的就是MediaFormat,类似的帧率、码率参数都是用这个来配置。

MediaFormat mediaformat = MediaFormat.createVideoFormat("video/avc", width, height);
        mediaformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
        mMediaCodec.configure(mediaformat, null, null, 0);

3.打开解码器

mMediaCodec.start();

4.解码部分

  • 获取可用缓冲区索引
int inIndex = mMediaCodec.dequeueInputBuffer(-1);

参数是等待的时间,单位是毫秒,小于0意味着此处为阻塞一直等待有可用的缓冲区,等于0意味着立即返回,大于0就是等待几毫秒。如果有可用的缓冲区,此时会返回可用的索引(有效的索引都是大于等于0的)。

  • 获取缓冲区然后塞入裸数据
mMediaCodec.getInputBuffer(inIndex).put(data, 0, length);

输入有效的索引获取空的缓冲区,然后将需要解码的data塞进去,0是偏移量,length是data的长度。

  • 通知解码器进行解码
mMediaCodec.queueInputBuffer(inIndex, 0, data.length, 0, 0);
  • 获取可用的输出缓冲区
int index = mMediaCodec.dequeueOutputBuffer(info, 0)

info:MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
第二个参数表示超时时间,如果小于0代表着一直等待

  • 获取解码后的数据
mMediaCodec.getOutputBuffer(index)

此处索引是获取可用输出缓冲区返回的索引

  • 释放缓冲区
mMediaCodec.releaseOutputBuffer(indexOutputbuffer, false);

此处索引是获取可用输出缓冲区返回的索引,第二个参数,如果你是要解码显示在surfaceview上就设置为true,我这里只是获取解码后的视频不做渲染所以设置了为false。
5.释放MediaCodec

mMediaCodec.stop();
mMediaCodec.release();