前言

Android 开发中提供了实现音视频编解码工具 MediaCodec针对对应音视频解码类型通过该类创建对应解码器就能实现对数据进行解码操作

MediaCodec

MediaCodec 所支持的数据类型: 压缩的音视频数据、原始音频数据和原始视频数据;首先 show 代码,紧接着之前 MediaExtactor 提取资源, MediaCodecList 遍历支持格式,确认设置支持该资源格式后通过 MediaCodec 创建解码器(这里是做视频解码播放)

MediaCodec 编码过程

在整个编解码过程中, MediaCodec 的使用会经历配置、启动、数据处理、停止、释放几个过程,相应的状态可归纳为停止(Stopped),执行(Executing)以及释放(Released)三个状态,而Stopped状态又可细分为未初始化(Uninitialized)、配置(Configured)、异常( Error),Executing状态也可细分为读写数据(Flushed)、运行(Running)和流结束(End-of-Stream)

MediaCodec 整个状态结构图如下:

从上图可知,当 MediaCodec 被创建后会进入未初始化状态,待设置好配置信息并调用 start() 启动后, MediaCodec 会进入运行状态,并且可进行数据读写操作

如果在这个过程中出现了错误MediaCodec 会进入 Stopped 状态,我们就是要使用 reset 方法来重置编解码器,否则 MediaCodec 所持有的资源最终会被释放

当然,如果 MediaCodec 正常使用完毕,我们也可以向编解码器发送 EOS 指令,同时调用 stop 和 release 方法终止编解码器的使用

MediaCodec API 说明

MediaCodec可以处理具体的视频流,主要有这几个方法:

  • getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组
  • queueInputBuffer:输入流入队列
  • dequeueInputBuffer:从输入流队列中取数据进行编码操作
  • getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组
  • dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
  • releaseOutputBuffer:处理完成,释放ByteBuffer数据

基本使用

所有的同步模式的 MediaCodec API都遵循一个模式:

  • 创建并配置一个 MediaCodec 对象
  • 循环直到完成
  • 如果输入缓冲区就绪,读取一个输入块,并复制到输入缓冲区中
  • 如果输出缓冲区就绪,复制输出缓冲区的数据 释放 MediaCodec 对象

(1) 创建编/解码器

MediaCodec 主要提供了 createEncoderByType(String type)、createDecoderByType(String type) 两个方法来创建编解码器,它们均需要传入一个MIME类型多媒体格式

常见的MIME类型多媒体格式如下:

● “video/x-vnd.on2.vp8” - VP8 video (i.e. video in .webm)
● “video/x-vnd.on2.vp9” - VP9 video (i.e. video in .webm)
● “video/avc” - H.264/AVC video
● “video/mp4v-es” - MPEG4 video
● “video/3gpp” - H.263 video
● “audio/3gpp” - AMR narrowband audio
● “audio/amr-wb” - AMR wideband audio
● “audio/mpeg” - MPEG1/2 audio layer III
● “audio/mp4a-latm” - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
● “audio/vorbis” - vorbis audio
● “audio/g711-alaw” - G.711 alaw audio
● “audio/g711-mlaw” - G.711 ulaw audio

当然,MediaCodec 还提供了一个 createByCodecName (String name) 方法,支持使用组件的具体名称来创建编解码器;但是该方法使用起来有些麻烦,且官方是建议最好是配合 MediaCodecList 使用,因为 MediaCodecList 记录了所有可用的编解码器

当然,我们也可以使用该类对传入的 minmeType 参数进行判断,以匹配出 MediaCodec 对该mineType 类型的编解码器是否支持

以指定MIME类型为 “video/avc” 为例,代码如下:

private static MediaCodecInfo selectCodec(String mimeType) {// 获取所有支持编解码器数量int numCodecs = MediaCodecList.getCodecCount();for (int i = 0; i < numCodecs; i++) {// 编解码器相关性信息存储在MediaCodecInfo中MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);// 判断是否为编码器if (!codecInfo.isEncoder()) {continue;}// 获取编码器支持的MIME类型,并进行匹配String[] types = codecInfo.getSupportedTypes();for (int j = 0; j < types.length; j++) {if (types[j].equalsIgnoreCase(mimeType)) {return codecInfo;}}}return null;}
123456789101112131415161718192021

(2) 配置、启动编/解码器

编解码器配置使用的是 MediaCodec 的 configure 方法,该方法首先对 MediaFormat 存储的数据 map 进行提取,然后调用本地方法 native-configure 实现对编解码器的配置工作

在配置时,configure 方法需要传入format、surface、crypto、flags 参数,其中 format 为 MediaFormat 的实例,它使用 ”key-value” 键值对的形式存储多媒体数据格式信息; surface 用于指明解码器的数据源来自于该 surface

crypto 用于指定一个 MediaCrypto 对象,以便对媒体数据进行安全解密;flags指明配置的是编码器(CONFIGURE_FLAG_ENCODE)

MediaFormat mFormat = MediaFormat.createVideoFormat("video/avc", 640 ,480);     // 创建MediaFormat
mFormat.setInteger(MediaFormat.KEY_BIT_RATE,600);       // 指定比特率
mFormat.setInteger(MediaFormat.KEY_FRAME_RATE,30);  // 指定帧率
mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);  // 指定编码器颜色格式
mFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,10); // 指定关键帧时间间隔
mVideoEncodec.configure(mFormat,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
1234567

从上面代码可知,当编解码器 start 后,会进入一个 for(;;)循环,该循环是一个死循环,以实现不断地去从编解码器的输入缓存池中获取包含数据的一个缓存区,然后再从输出缓存池中获取编解码好的输出数据

  • 在一个 Java 应用程序的执行过程中,只要在同一个对象上多次调用它 hashCode 方法必须始终返回相同的整数,前提是在equals对象上的比较被修改;这个整数不需要从一个应用的一次执行到同一应用的另一次执行保持一致

  • 如果两个对象根据 equals(Object) 方法,然后调用 hashCode 方法必须产生相同的整数结果

  • 这是要求如果两个对象根据 equals(java.lang.Object) 方法,然后调用 hashCode 方法必须产生不同的整数结果;但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高性能

尽可能实际地,由类定义的 hashCode 方法 Object 为不同的对象返回不同的整数(这通常是通过将对象的内部地址转换成整数来实现的,但是Java编程语言并不要求这种实现技术)

本文 全面介绍了 LiveData 的生命周期是如何变化的 希望大家在开发时尽量避免出现 因生命周期变化而出现的问题

为了是大家能够更好的学习 音视频开发, 在这里特别提供一份 高级音视频开发学习笔记;里面包含了这些年学习 音视频开发所遇到的难题及其解决方案; 有需要这份 高级音视频开发学习笔记 的朋友: 可以私信 发送 “笔记” 即可 免费获取; 希望大家阅读过后,能够 查漏补缺;早日成为高级音视频开发者

内容展示如下:

高级音视频开发学习笔记目录

H264 编码基础 06 – 编码标准之战

  • 一个视频标准的普及其实是商业利益博弈的结果。
  • 一个视频标准能普及还在于他的对手
  • WMV
  • VP8
  • AV1

H264 编码基础 01 帧与场

  • 视频序列帧、场编码方式
  • H264 编码(帧内预测)
  • 视频流 H264 的组装
  • 三种帧的说明
  • 压缩算法的说明
  • 手写 H264 编码器

有需要完整版高级音视频开发学习笔记的朋友: 可以 私信 发送 “笔记” 即可 免费获取

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

加油!让我们早日成为音视频高级开发者

实现音视频编解码工具 MediaCodec 创建解码器相关推荐

  1. Android 音视频编解码(一) -- MediaCodec 初探

    音视频 系列文章 Android 音视频开发(一) – 使用AudioRecord 录制PCM(录音):AudioTrack播放音频 Android 音视频开发(二) – Camera1 实现预览.拍 ...

  2. Android 音视频编解码 MediaCodec

    MediaCodec 简介 Android中的MediaCodec是一个用于音视频编解码功能的API,使用它可以实现对音视频数据进行压缩.解压缩.编辑和转换.以下是MediaCodec的主要功能: 支 ...

  3. 各种音视频编解码学习详解之 编解码学习笔记(四):Mpeg系列——Mpeg 4

    最近在研究音视频编解码这一块儿,看到@bitbit大神写的[各种音视频编解码学习详解]这篇文章,非常感谢,佩服的五体投地.奈何大神这边文章太长,在这里我把它分解成很多小的篇幅,方便阅读.大神博客传送门 ...

  4. 流媒体传输协议及音视频编解码技术

    说明:本文来自一篇出处不明的老文章,有些内容已过时,但仍有很大的参考价值. 一.音视频编解码技术 1.MPEG4 MPEG全称是Moving Pictures Experts Group,它是&quo ...

  5. 音视频编解码学习详解

    音视频编解码学习详解 目录(?)[+] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列A ...

  6. 音视频编解码知识学习详解(分多部分进行详细分析)

    1. 常用的基本知识 基本概念 编解码 编解码器(codec)指的是一个能够对一个信号或者一个数据流进行变换的设备或者程序.这里指的变换既包括将信号或者数据流进行编码(通常是为了传输.存储或者加密)或 ...

  7. Android视频编解码之MediaCodec简单入门

    本篇只是简单入门,后面会继续写文章详细讲解: 由于MediaCodec涉及内容众多,原本想一篇文章把所有内容概括,但是后来发现不太可能,限于自己能力,想要考虑全面太难,我也是刚开始学习需要借助网上的代 ...

  8. WebRTC 中收集音视频编解码能力

    在 WebRTC 中,交互的两端在建立连接过程中,需要通过 ICE 协议,交换各自的音视频编解码能力,如编解码器和编解码器的一些参数配置,并协商出一组配置和参数,用于后续的音视频传输过程. 对于音频, ...

  9. 音视频编解码的一些源代码

    音视频编解码的一些源代码 (转) 资料名称:音视频编解码的一些源代码 资料成文时间:不详 语言:英文 页数:很多 何人所著(来源): 文件格式:原代码 开发工具:vc++ 说明: 以下上传的源码是我以 ...

  10. 【ffmpeg for wince】音视频编解码多平台移植(for window/wince)

    from: http://www.cnblogs.com/windwithlife/archive/2009/05/31/1492728.html 终于完成了了第二个Client side原型(for ...

最新文章

  1. 服务器需不需要虚拟内存,服务器需不需要虚拟内存
  2. matlab 用fplot和plot作出函数图像
  3. 单机 搭建kafka集群 本地_单机快速搭建多节点kafka集群
  4. 字母s开头的c语言的工具,C语言库函数(S类字母) - 3
  5. java带参数的构造方法_崤云说 | JAVA面向对象
  6. Angular 下的 function
  7. 线段树-Chossing Ads-分治,主元素思想,神题
  8. Spring Boot 2.0.0.M7 生产环境部署
  9. oracle 随机数重复吗,Oracle生成不重复随机数
  10. python怎么读写文件-python读写文件
  11. android模拟器模拟nfc功能吗,android – 开始使用NFC模拟器
  12. rk3288 android7.1.2 4g模块调试(四)
  13. yuki翻译器钩子_YUKI GALGAME翻译器
  14. OpenCL优化案例研究 (4)
  15. 数仓建设之IP库的匹配
  16. [Note] 多项式全家桶 小球与盒子 分拆数
  17. 【R语言】常用基本函数
  18. SAAS(软件即服务) 离我们还有多远?
  19. bash下的特殊符号与通配符
  20. 实战 J2EE 开发购物网站 开发环境篇

热门文章

  1. 数学建模常用算法—模糊综合评价
  2. m7405d粉盒清零方法_联想m7605d清零方法
  3. jieba库和wordcloud库
  4. 纯js浏览器h5调用摄像头扫描识别解析 条形码+二维码
  5. 两款导航网站源码 支持自动收录、自动审核、自动检测友链功能.
  6. 谷歌大脑2017总结下篇:Jeff Dean梳理6大领域研究
  7. 数学建模-lingo使用
  8. VB VBA 文本框回车键换行
  9. 国际标准 ANIS/ IES,各环境场所灯光照明的设计使用规划
  10. linux中如何编译成bin文件,gcc 如何编译成bin文件