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

  • 相关阅读:
    洛谷 P1194 飞扬的小鸟 题解
    洛谷 P1197 星球大战 题解
    洛谷 P1879 玉米田Corn Fields 题解
    洛谷 P2796 Facer的程序 题解
    洛谷 P2398 GCD SUM 题解
    洛谷 P2051 中国象棋 题解
    洛谷 P1472 奶牛家谱 Cow Pedigrees 题解
    洛谷 P1004 方格取数 题解
    洛谷 P2331 最大子矩阵 题解
    洛谷 P1073 最优贸易 题解
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/10489400.html
Copyright © 2011-2022 走看看