Android MediaCodec简单总结

#.MedaiCodec简介
    MediaCodec是Android中提供的音视频编码、解码工具。它主要是完成上层接口的封装,提供给开发者使用,编解码功能实际是在native底层服务中完成的。
#.MediaCodec工作的宏观流程:
##.包换两个缓冲区队列
一个输入缓冲区队列,包含一组输入缓冲区(格式ByteBuffer);
一个输出缓冲区队列,包含一组输出缓冲区(格式ByteBuffer);
##.使用中,需要不断重复以下过程
1.把原始数据放入输入缓冲区队列中一个空缓冲区上;
2.编/解码器从输入缓冲队列中获取缓冲区上数据,进行编码处理,结果存放到输出缓冲区上一个空缓冲区上,
       处理完毕后,释放该输入缓冲区,它会被重新放回输入缓冲区队列,以便下次重复使用;
3.对输出缓冲区上数据做自己需要的业务处理处理,处理完毕后,释放该输出缓冲区,
       它会被重新放回输出缓冲区队列,以便下次重复使用。
##.当对视频帧进行编/解码时,一般会用编码器创建一个输入Surface或为编码器设置一个输出Surface,在这里Surface充当着数据缓冲区的角色。
使用Surface可以提高编/解码器的性能,Surface直接使用native视频数据缓存,没有映射或复制它们到ByteBuffers,这种方式会更加高效。
#.内部的状态机和处理流程
##.状态机,三类状态:
1.停止态(Stopped):
    1.1 未初始化状态(Uninitialized)
    1.2 配置状态(Configured)
    1.3 错误状态(Error)
2.执行态(Executing):
    2.1 刷新状态(Flushed)
    2.2 运行状态( Running)
    2.3 流结束状态(End-of-Stream)
3.释放态(Released)
##.操作流程:
1.一般流程为创建编/解码器,此时处于未初始化状态(Uninitialized);
2.调用configure(…)方法对编解码器进行配置,使编解码器转入配置状态(Configured);
3.调用start()方法,使其转入执行刷新状态(Flushed);
4.此时编解码器已经拥有其输入/输出缓存,当第一个输入缓存区被移出队列,编解码器转入运行状态( Running);
5.在运行状态( Running)中,编解码器不断对输入缓冲区中数据做编解码操作,结果存到输出缓冲区;
6.当一个带有end-of-stream标记的输入缓存入队列时,编解码器将转入流结束状态(End-of-Stream)。
    在这种状态下,编解码器不再接收新的输入缓存,但它仍然产生输出缓存。直到
7.当输入缓存中所有数据都被处理完,带有end-of-stream标记的数据帧到达输出缓存后,转入释放态(Released)。
    当我们处理完输出数据后,在此状态下可以用release()进行相关资源的释放。
##.状态转化其它相关要点:
1.在执行状态(Executing)下的任何时候,通过调用flush()方法使编解码器重新返回到刷新子状态(Flushed);
2.通过调用stop()方法使编解码器返回到未初始化状态(Uninitialized),此时这个编解码器可以再次重新配置;
3.编解码器遇到错误时会进入错误状态(Error),此时应调用reset()方法使编解码器再次可用。
4.任何状态下调用reset()方法使编解码器返回到未初始化状态(Uninitialized)
##.MediaCodec相关API介绍:
createDecoderByType:获取解码器对象
createEncoderBytype:获取编码器对象
configure:对编解码器进行配置,使编解码器转入配置状态
start:使编码器转入执行刷新状态
stop:结束并返回到未初始化状态
release:释放实例资源
createInputSurface:创建输入缓冲Surface
setOutputSurface:设置输出缓冲Surface
getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组
queueInputBuffer:输入流入队列
dequeueInputBuffer:从输入流队列中取数据进行编码操作
getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组
dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
releaseOutputBuffer:处理完成,释放ByteBuffer数据
##.MediaCodec的两种工作方式
1.同步方式:数据输入和数据输出依次进行。
           要等待上一次数据输入后,才能数据输出;
           等待上一次数据输出后,才能再次进行数据输入。
2.异步方式:数据输入和数据输出操作顺序相互独立。
           是底层服务来判断何时输入/输出可以进行,然后进行相应回调,
           开发者在回调中进行数据输入/输出处理。
 
//异步处理方式时,需要设置回调接口。
//在回调中进行数据处理
mEncoder.setCallback(new MediaCodec.Callback() {
    //有可用的输入缓冲区时回调
    @Override
    public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
       
    }

    //有可用的输出缓冲区时回调
    @Override
    public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {

    }

    //输出格式变化时回调
    @Override
    public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {

    }
   
    //出错时回调
    @Override
    public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {

    }
});

猜你喜欢

转载自blog.csdn.net/u013914309/article/details/124697462
今日推荐