MediaCodec ES流

来源:互联网 发布:软件开发模式有几种 编辑:程序博客网 时间:2024/06/18 06:02

Android自带的MediaCodec Sample使用MediaCodec+MediaExtrator可以实现视频播放,但不支持ES流的播放。MediaExtractor不能读取ES流, MediaCodec输入为NAL,所以需要自己写个函数来分解出各个NAL。

 

 

先说ES文件的提取,我们摄像机默认录像文件为asf文件,从中提取ES流。以下命令的意义不是太清楚,也是网上超来的,实际可用。命令a应该是分解出ES流,命令b应该是重现再打包,还是ES流

命令affmpeg -i hi.asf -vcodec copy -an -f m4vtest.264

命令bffmpeg -i test.264 -vcodec h264 -s1920*1080 -an -f m4v t.264

 

书上说,可以根据文件中的00 00 01序列作为边界来提取每个NAL。

使用命令a提取的 SPS、I帧、P帧为00 00 00 01,SEI、PPS为00 00 01.使用命令b再编码后的SPS、I、P、SEI、PPS都为00 00 00 01。原因不太了解,实测发现:1、无论添加多少个0,都是没问题的。2、将SPS PPS SEI I帧作为一帧一起输入MediaCodec与将三者分别输入效果是一样的。,

 

 

 

分离NAL的函数,需要注意的是,如果每次都去读存储会很慢,需要尽量一次多读点缓冲。

public int nextFrame2(ByteBuffer buffer){        int size = 0;        byte[] b_array= new byte[1];//        Log.d("myapp","nextFrame");        int stage = 0;        try {            if(!has_find_frame_head) {                while (true) {                    getByteFromCache(b_array);//                    Log.d("myapp", "b=" + b_array[0]);                    if (stage == 0 ) {                        if(b_array[0] == 0) {                            stage = 1;//                            buffer.put(b_array[0]);//                            size++;                        }else{                            stage=0;//                            buffer.clear();//                            size = 0;                        }                    } else if (stage == 1) {                        if (b_array[0] == 0) {                            stage = 2;//                            buffer.put(b_array[0]);//                            size++;                        } else {                            stage = 0;//                            buffer.clear();//                            size = 0;                        }                    } else if (stage == 2) {                        if (b_array[0] == 1) {//                            buffer.put(b_array[0]);//                            size++;                            break;                        } else if (b_array[0] == 0) {                            stage = 2;//                            buffer.put(b_array[0]);//                            size++;                        } else {                            stage = 0;//                            buffer.clear();//                            size = 0;                        }                    }                }            }            size = 3;            byte b = 0;            buffer.put(b);            b=0;            buffer.put(b);            b=1;            buffer.put(b);            has_find_frame_head = false;            //has find start flag 001 or 0001 or 0000001            while(true){//                inputStream.read(b_array);                getByteFromCache(b_array);                buffer.put(b_array[0]);                if(size >=2 && buffer.get(size)==1 && buffer.get(size - 1)==0 && buffer.get(size-2)==0) {                    has_find_frame_head = true;                    size -= 2;                    break;                }else {                    size++;                }            }        }catch (Exception e){            e.printStackTrace();            return 0;        }//        Log.d("myapp","size="+size);        if(size<=0)            EOS=true;        return size;    } 


0 0
原创粉丝点击