之前有博客介绍了android端H265硬解码的实现,见文章:http://blog.csdn.net/jyt0551/article/details/74502627
现在我们介绍一下在EasyPlayer端如何实现H265解码.
我们的策略是,在能支持硬解码的手机上使用硬解码,但是如果手机不支持,那也可以使用软解码来实现.
我们可以通过编译ffmpeg,使能hevc解码库,从而支持265的软解.ffmpeg如何支持265,这个就无需多说了,相关文章已经很多.
我们看看相关代码的改动吧,首先增加了H265解码算法标识:
public static final int EASY_SDK_VIDEO_CODEC_H265 = 0x48323635; /*H265*/
EasyRTSPClient库会把H265视频流从RTSP协议中剥离出来,并通过onRTSPSourceCallBack回调给上层.在回调后,首先需要等到第一个关键帧再开始播放,之前的非关键帧简单丢弃即可:
if (mWaitingKeyFrame) {
...
if (frameInfo.type != 1) {
Log.w(TAG, String.format("discard p frame."));
return;
}
mWaitingKeyFrame = false;
}
当我们得到第一个关键帧后,首先从码流中取出vps_sps_pps等信息,这些信息是使用硬解码所必须的.
byte[] spsPps = getvps_sps_pps(frameInfo.buffer, 0, 256);
if (spsPps != null) {
mCSD0 = ByteBuffer.wrap(spsPps);
}
然后我们把265视频帧放到一个缓冲队列中,这样就可以持续地进行buffering.需要注意的是,这个缓冲队列实现了根据时间戳来自动排序,这样可以有效进行音视频同步.
在另外的音视频消费者线程中,我们进行音视频的渲染工作,主要看下视频解码部分,包括264和265解码算法.
初始化解码库:
frameInfo = mQueue.takeVideoFrame();
try {
final String mime = frameInfo.codec == EASY_SDK_VIDEO_CODEC_H264 ? "video/avc" : "video/hevc";
MediaFormat format = MediaFormat.createVideoFormat(mime, mWidth, mHeight);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
format.setInteger(MediaFormat.KEY_PUSH_BLANK_BUFFERS_ON_STOP, pushBlankBuffersOnStop ? 1 :