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

MediaCodec解码解析

程序员文章站 2022-07-05 16:12:06
...
  private void decode(MediaCodec.BufferInfo videoInfo, int inputIndex) {
        mMediaDecode.queueInputBuffer(inputIndex, 0, videoInfo.size, videoInfo.presentationTimeUs, videoInfo.flags);//通知MediaDecode解码刚刚传入的数据
        //获取解码得到的byte[]数据 参数BufferInfo上面已介绍 10000同样为等待时间 同上-1代表一直等待,0代表不等待。此处单位为微秒
        //此处建议不要填-1 有些时候并没有数据输出,那么他就会一直卡在这 等待
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputIndex = mMediaDecode.dequeueOutputBuffer(bufferInfo, 50000);
        switch (outputIndex) {
            case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
                Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED");
                mDecodeOutputBuffers = mMediaDecode.getOutputBuffers();
                break;
            case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                MediaFormat format = mMediaDecode.getOutputFormat();
                Log.d(TAG, "New mMediaFormat " + format);
                if (format != null && format.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
                    mVideoDecodeColor = format.getInteger(MediaFormat.KEY_COLOR_FORMAT);
                    Log.d(TAG, "decode extract get mVideoDecodeColor =" + mVideoDecodeColor);//解码得到视频颜色格式
                }
                initMediaEncode();//根据颜色格式初始化编码器
                break;
            case MediaCodec.INFO_TRY_AGAIN_LATER:
                Log.d(TAG, "dequeueOutputBuffer timed out!");
                break;
            default:
                ByteBuffer outputBuffer;
                byte[] frame;
                while (outputIndex >= 0) {//每次解码完成的数据不一定能一次吐出 所以用while循环,保证解码器吐出所有数据
                    outputBuffer = mDecodeOutputBuffers[outputIndex];//拿到用于存放PCM数据的Buffer
                    frame = new byte[bufferInfo.size];//BufferInfo内定义了此数据块的大小
                    outputBuffer.get(frame);//将Buffer内的数据取出到字节数组中
                    outputBuffer.clear();//数据取出后一定记得清空此Buffer MediaCodec是循环使用这些Buffer的,不清空下次会得到同样的数据
                    handleFrameData(frame, videoInfo);//自己定义的方法,供编码器所在的线程获取数据,下面会贴出代码
                    mMediaDecode.releaseOutputBuffer(outputIndex, false);//此操作一定要做,不然MediaCodec用完所有的Buffer后 将不能向外输出数据
                    outputIndex = mMediaDecode.dequeueOutputBuffer(mDecodeBufferInfo, 50000);//再次获取数据,如果没有数据输出则outputIndex=-1 循环结束
                }
                break;
        }
    }