Android 音视频编解码 -- MediaCodec

引言

如果我们只是简单玩一下音频、视频播放,那么使用 MediaPlayer + SurfaceView 播放就可以了,但如果想加个水印,加点其他特效什么的,那就不行了;

 

学习 Android 自带的硬件码类 – MediaCodec。

 

 

MediaCodec 介绍

 

在Android中是使用MediaCodec类进行编解码。

 

MediaCodec是什么呢?

MediaCodec是Android提供的用于对音视频进行编码(压缩)和解码(解压缩)的类,它通过访问底层的codec来实现编解码的功能。

比如你要把摄像头的视频yuv数据编码为h264/h265,pcm编码为aac,h264/h265解码为yuv,aac解码为pcm等等。MediaCodec是Android 4.1 API16引入的,在Android 5.0 API21加入了异步模式。

 

通常与MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface, 以及AudioTrack一起使用;

 

数据交换

 

 

 

可以看到,MediaCodec 的数据分为两个部分,从数据的输入编解码后的数据的输出

input : MediaCodec 会通过getInputBuffer(int bufferId) 去拿到一个空的 ByteBuffer , 用来给客户端去填入数据(比如解码,编码的数据),MediaCodec 会用这些数据进行解码/编码处理。


output : MediaCodec 会把解码/编码的数据填充到一个空的 buffer 中,然后把这个填满数据的buffer给到客户端,之后需要释放这个 buffer,MediaCodec 才能继续填充数据。

MediaCodec 内部使用异步的方式对 input 和 output 进行数据处理,MediaCodec 会把 input 的数据处理好给到 output,共用户去渲染;
注意!output 的数据必须释放,不然会影响下一次的数据填充。

 

数据类型
 

编码器共支持3中数据类型:

  • 压缩数据
  • 原始视频数据
  • 原始音频数据

 

这三种数据都是可以通过 ByteBuffer 去处理;但是你可以使用 Surface 去解析原始的视频数据,Surface 使用底层的视频缓冲,而不是映射或拷贝到 ByteBuffer,这样会大大提高编码效率。
但使用 Surface 时,无法访问到原始的视频数据,所以,你可以使用 ImageReader 来访问未加密的解码(原始)数据。在 ByteBuffer 的模式下,你也可以使用 Image 或者 getInput/OutputImage(int) 来获取原始视频帧。

 

编解码的生命周期

 

Stopped,Executing 和 Released

 

Stopped 和 Executing 都有各自的生命周期:

 

  • Stopped:Error、Uninitialized 和 Configured

当调用 MediaCodec 时,此时会处于 Uninitialized 状态,当调用 configure 之后,就会处于 Configured 状态;然后调用 start() 进入 Executing 状态,接着就可以处理数据了。

 

  • Executing:Flushed、Running 和 End of Stream

当调用 start() 就会进入 Executing 下的 Flushed 状态,此时会拿到所有的 buffers,当第一帧数据从 dequeueInoutBuffer 队列流出时,就会进入 Running 状态,大部分时间都在这个状态处理数据,当队列中有 end-of-stream 标志时,就会进入 End of Stream 状态,此时不再接收 input buffer,但是会继续生成 output buffer,直到 output 也接收到 end-of-stream 标志。你可以使用 flush() 重新回到 Flushed 状态。

生命周期图:

 

 

可以使用 stop() 方法回到 Uninitialized 状态;当不再使用 MediaCodec ,还需要使用 release() 去释放该资源。

 

MediaCodec 的主要 API 如下:

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

 

使用

 

输入缓冲区

1、手动把数据输入缓冲区 参考下面文章:

Android 音视频编解码(二) -- MediaCodec 解码(同步和异步)_mediacodec config textureview-CSDN博客

2、Surface createInputSurface()  把数据给到surface 就行,surface 自动作为输入缓冲区(简单) 

 

输出缓冲区输出编码后的数据,然后封装 XXX、mp4 文件(封装格式文件)

过程: 原始数据 --->编码 --->压缩数据 ---> x x x.mp4 文件

 

难点: 输入缓冲区 ---> opengl 着色器执行后的数据 ---> surface

这里难点就是 怎么把数据绘制到surface 怎么绘制,以什么样的规则。。。。。。

 

这里就引出EGL。

opengl 着色器执行后的数据 --- 》【EGL】 ----》surface

 

EGL的由来

 OpenGL作为一个图形化API,允许我们操作GPU以绘制图形,但是当涉及到本地的窗口时,就需要一个与平台无关的API来与之进行交互,EGL应运而生,承担起OpenGl和原生窗口系统之间桥梁的作用。

如图:

 

 

EGL 知识点 看该篇:  Android 音视频 --- EGL介绍和使用-CSDN博客

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/963332.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文了解阿里的 Qwen2.5 模型

最近被DeepSeek刷屏了,但是在之外阿里在2025年1月28日推出了Qwen 2.5 Max模型。 Qwen2.5-Max 的特点:大规模的 MoE 模型,预训练于超 20 万亿 tokens,并经过 SFT 和 RLHF 后训练。 性能表现:在多个基准测试中与领先模型…

DeepSeek R1 linux云部署

云平台:AutoDL 模型加载工具:Ollama 参考:https://github.com/ollama/ollama/blob/main/docs/linux.md 下载Ollama 服务器上下载ollama比较慢,因此我使用浏览器先下载到本地电脑上。 https://ollama.com/download/ollama-linux…

FlashAttention v1 论文解读

论文标题:FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness 论文地址:https://arxiv.org/pdf/2205.14135 FlashAttention 是一种重新排序注意力计算的算法,它无需任何近似即可加速注意力计算并减少内存占用。…

Vue - shallowRef 和 shallowReactive

一、shallowRef 和 shallowReactive (一)shallowRef 在 Vue 3 中,shallowRef 是一个用于创建响应式引用的 API,它与 ref 相似,但它只会使引用的基本类型(如对象、数组等)表现为响应式&#xf…

【深度学习】softmax回归的简洁实现

softmax回归的简洁实现 我们发现(通过深度学习框架的高级API能够使实现)(softmax)线性(回归变得更加容易)。 同样,通过深度学习框架的高级API也能更方便地实现softmax回归模型。 本节继续使用Fashion-MNIST数据集,并保持批量大小为256。 import torch …

ESP32-c3实现获取土壤湿度(ADC模拟量)

1硬件实物图 2引脚定义 3使用说明 4实例代码 // 定义土壤湿度传感器连接的模拟输入引脚 const int soilMoisturePin 2; // 假设连接到GPIO2void setup() {// 初始化串口通信Serial.begin(115200); }void loop() {// 读取土壤湿度传感器的模拟值int sensorValue analogRead…

【python】python油田数据分析与可视化(源码+数据集)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 【python】python油田数据分析与可视化&#xff08…

代码讲解系列-CV(一)——CV基础框架

文章目录 一、环境配置IDE选择一套完整复现安装自定义cuda算子 二、Linux基础文件和目录操作查看显卡状态压缩和解压 三、常用工具和pipeline远程文件工具版本管理代码辅助工具 随手记录下一个晚课 一、环境配置 pytorch是AI框架用的很多,或者 其他是国内的框架 an…

HTB:Alert[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用ffuf对alert.htb域名进行子域名FUZZ 使用go…

小红的合数寻找

A-小红的合数寻找_牛客周赛 Round 79 题目描述 小红拿到了一个正整数 x,她希望你在 [x,2x] 区间内找到一个合数,你能帮帮她吗? 一个数为合数,当且仅当这个数是大于1的整数,并且不是质数。 输入描述 在一行上输入一…

Linux环境下的Java项目部署技巧:安装 Mysql

查看 myslq 是否安装: rpm -qa|grep mysql 如果已经安装,可执行命令来删除软件包: rpm -e --nodeps 包名 下载 repo 源: http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm 执行命令安装 rpm 源(根据下载的…

基于springboot+vue的哈利波特书影音互动科普网站

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步:创建模块counterStore 第二步:在store的入口文件进行子模块的导入组合 第三步:在index.js中进行store的全局注入 第四步:在组件中进行使用 第五步:在组件中…

记录 | 基于MaxKB的文字生成视频

目录 前言一、安装SDK二、创建视频函数库三、调试更新时间 前言 参考文章:如何利用智谱全模态免费模型,生成大家都喜欢的图、文、视并茂的文章! 自己的感想 本文记录了创建文字生成视频的函数库的过程。如果想复现本文,需要你逐一…

Redis|前言

文章目录 什么是 Redis?Redis 主流功能与应用 什么是 Redis? Redis,Remote Dictionary Server(远程字典服务器)。Redis 是完全开源的,使用 ANSIC 语言编写,遵守 BSD 协议,是一个高性…

安全防护前置

就业概述 网络安全工程师/安全运维工程师/安全工程师 安全架构师/安全专员/研究院(数学要好) 厂商工程师(售前/售后) 系统集成工程师(所有计算机知识都要会一点) 学习目标 前言 网络安全事件 蠕虫病毒--&…

开源2 + 1链动模式AI智能名片S2B2C商城小程序视角下从产品经营到会员经营的转型探究

摘要:本文聚焦于开源2 1链动模式AI智能名片S2B2C商城小程序,深入探讨在其应用场景下,企业从产品经营向会员经营转型的必要性与策略。通过分析如何借助该平台优化会员权益与价值,解决付费办卡的接受度问题,揭示其在提升…

让banner.txt可以自动读取项目版本

文章目录 1.sunrays-dependencies1.配置插件2.pluginManagement统一指定版本 2.common-log4j2-starter1.banner.txt使用$ 符号取出2.查看效果 1.sunrays-dependencies 1.配置插件 <!-- 为了让banner.txt自动获取版本号 --><plugin><groupId>org.apache.mave…

音视频多媒体编解码器基础-codec

如果要从事编解码多媒体的工作&#xff0c;需要准备哪些更为基础的内容&#xff0c;这里帮你总结完。 因为数据类型不同所以编解码算法不同&#xff0c;分为图像、视频和音频三大类&#xff1b;因为流程不同&#xff0c;可以分为编码和解码两部分&#xff1b;因为编码器实现不…

openmv运行时突然中断并且没断联只是跟复位了一样

就是 # 内存不足时硬件复位 except MemoryError as me: print("Memory Error:", me) pyb.hard_reset() # 内存不足时硬件复位 很有可能是你的代码加了内存溢出的复位&#xff0c;没加的话他会报错的