您当前的位置: 首页 >  音视频

命运之手

暂无认证

  • 1浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android音视频开发】【015】通过MediaCodec和SurfaceView,对H264数据进行解帧和播放

命运之手 发布时间:2021-06-02 17:21:57 ,浏览量:1

功能点

  • 从连续的字节块中,解析分割出多个H264帧数据
  • 通过MediaCodec解码H264帧
  • 通过SurfaceView播放

代码


	//H264数据解析

	package com.easing.commons.android.MediaCodec.format;
	
	public class H264Format {
	
	    //从流数据中查找H264的header
	    public static int findH264Header(byte[] buffer, int length) {
	        //两个header之间的字节,即为一帧的数据
	        //因此我们实际是跳过第一个header,查找第二个header的位置
	        final int firsetOffset = 512;
	        for (int index = firsetOffset; index  {
        //循环播放H264文件
        WorkThread.postByLoop(() -> {
            final InputStream is = Resources.readAssetStream("abc.h264");
            final int maxFrameSize = 1024 * 1024; //大小要足够放下两帧以上的数据
            byte[] buffer = new byte[128 * 1024]; //读文件的缓存区
            byte[] frameBuffer = new byte[maxFrameSize]; //帧数据的缓存区
            int availableDataLength = 0; //FrameBuffer实际帧数据的长度
            //读文件,按帧解码
            //区分帧数据边界的逻辑是,两个H264.Header之间的字节即为一帧
            int length = 0;
            while (true) {
                //读取文件
                length = is.read(buffer);
                if (length  maxFrameSize)
                    availableDataLength = 0;
                //接着之前的位置,填充数据到缓存区
                System.arraycopy(buffer, 0, frameBuffer, availableDataLength, length);
                availableDataLength = availableDataLength + length;
                //查找第二个H264.Header
                int offset = H264Format.findH264Header(frameBuffer, availableDataLength);
                //递归查找所有的帧
                while (offset > 0) {
                    //FrameBuffer以H264.Header开头,则表示数据正常,否则表示数据异常
                    boolean startWithH264Header = H264Format.isH264Header(frameBuffer, 0);
                    //数据正常
                    if (startWithH264Header) {
                        //解码帧数据
                        boolean decodeResult = h264PlayView1.decodeFrame(frameBuffer, 0, offset);
                        //解码成功
                        if (decodeResult) {
                            //移除第二个Header之前的字节
                            byte[] temp = frameBuffer;
                            frameBuffer = new byte[maxFrameSize];
                            System.arraycopy(temp, offset, frameBuffer, 0, availableDataLength - offset);
                            availableDataLength = availableDataLength - offset;
                            //查找下个头
                            offset = H264Format.findH264Header(frameBuffer, availableDataLength);
                        }
                    }
                    //数据异常
                    else {
                        //移除第二个Header之前的字节
                        byte[] temp = frameBuffer;
                        frameBuffer = new byte[maxFrameSize];
                        System.arraycopy(temp, offset, frameBuffer, 0, availableDataLength - offset);
                        availableDataLength = availableDataLength - offset;
                        //查找下个头
                        offset = H264Format.findH264Header(frameBuffer, availableDataLength);
                    }
                }
            }
        });
    });

源码

Android H264数据解帧和播放.zip

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.6781s