zoukankan      html  css  js  c++  java
  • 音视频学习系列第(七)篇---MediaCodec的使用

    音视频系列

    什么是MediaCodec

    MediaCodec是安卓官方提供的一套用于音视频编码和解码的API,该API是在安卓4.1(API 16)引入的,因此只能用于4.1以上的手机

    MediaCodec工作原理

    先上一幅图


    MediaCodec工作原理.png

    从图中可以看出MediaCodec的架构采用了2个缓冲区队列,即input缓冲区队列和output缓冲区队列
    缓冲区队列
    它是一个队列,队列中的每个元素都是一个换种区
    Client,Codec
    Client指的是API的使用者
    Codec指的是数据的处理者(编码或解码)

    详细流程
    1.Client从Codec拿到input缓冲区队列[getInputBuffers]
    2.Client从input队列中申请一个empty buffer[dequeueInputBuffer]
    3.Client将需要编解码的数据拷贝到empty buffer,然后将其放入input队列[queueInputBuffer]
    4.Codec从input缓冲区取出一个buffer(一帧)数据,对其进行编解码处理
    5.编解码处理结束后,Codec将原始数据的buffer置为empty后放入input缓冲区队列,并将编解码后的数据放到output缓冲区队列

    6.Client从Codec拿到output缓冲区队列[getOutputBuffers]
    7.Client从output队列申请一个有编解码数据的buffer[dequeueOutputBuffer]
    8.Client对编解码的数据进行渲染/播放
    9.渲染/播放完成后,Client再将这个buffer放回output缓冲区队列[releaseOutputBuffer]

    注意
    虽然我标注了1到9,但两个Client和Codec模块是并行工作的,MediCodec在架构上采用的是一种基于环形缓冲区生产者-消费者设计模式

    在input端,Client就是这个环形缓冲区的生产者,Codec是消费者
    在output端,Codec是这个环形缓冲区的生产者,Client是消费者

    MediaCodec的使用流程

    1.创建编/解码器

    mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
    mMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
    

    2.设置参数

    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
    setInteger(String name, int value)
    mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mMediaCodec.configure(format, null, null, 0);
    

    3.开启编解码

    mMediaCodec.start();
    

    4.通过2个缓冲区队列进行数据的处理(编解码)

    while(1) {
        - dequeueInputBuffer
        - queueInputBuffer
        - dequeueOutputBuffer
        - releaseOutputBuffer
    }
    

    5.释放资源

    mMediaCodec.stop();
    mMediaCodec.release();
    mMediaCodec = null;
    

    MediaCodec的缺陷

    1.API的限制
    要去API>=16,有的甚至更高,不能很好的兼容低版本手机

    2.安卓机型适配问题
    每个安卓厂商都对系统底层(Native层)做了一些自己的修改,而MediaCodec的真正实现在Native层,因此不可避免的会出现在这个手机可以运行,在另外一个手机崩溃的问题

    3.出现问题难以定位
    前面说了,MediaCodec的真正实现在Native层,而这个Native层的代码是嵌在手机中的,我们不能对其进行调试
    不仅仅是MediaCodec这个API,多媒体相关的很多API都是这样,如MediaMuxer,在小米5 6.0.1中报如下错误

     WVMExtractor: Failed to open libwvm.so: dlopen failed: library "libwvm.so" not found
    

    猜测可能是手机缺少libwvm这个动态库

    鉴于这些问题,我觉得还是学习一些第三方的开源库,所有的过程都经过我们可调试的代码,将主动权窝在自己手中

    完整代码

    鉴于我的代码在我的手机还没跑通,等我将问题解决之后,在更新一下

    参考链接
    https://www.jianshu.com/p/e6c683d6dbbe
    https://blog.csdn.net/angcyo/article/details/51043367
    https://blog.csdn.net/guojin08/article/details/27555473

  • 相关阅读:
    自定义MyBatis
    SpringMVC基本
    Struts2访问Servlet
    Struts2的配置
    Rust开发环境搭建
    android webview和 javascript 进行交互
    C#开发step步骤条控件
    如何用cmd命令递归文件夹中的所有特定文件,拷贝到另一个文件夹中
    C#用DesignSurface实现一个简单的窗体设计器
    Roslyn如何实现简单的代码提示
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/10489400.html
Copyright © 2011-2022 走看看