当前位置: 首页 > news >正文

Android笔记--MediaCodec(一)

         这一节主要来了解一下MediaCodec,Android MediaCodec 是 Android 平台提供的一个用于处理音频和视频数据的 API。它允许开发者对音频和视频数据进行编码和解码,支持多种格式和编解码器。MediaCodec API 通常用于实现实时音视频处理,如视频录制、播放、转码等。

基本概念:

编解码器(Codec):编解码器是负责将原始音视频数据压缩成特定格式(编码)或将压缩数据还原为原始数据(解码)的组件。
输入缓冲区(Input Buffers):用于向编解码器提供待处理的数据。
输出缓冲区(Output Buffers):编解码器处理后的数据存储在这里,开发者可以从这里读取处理后的数据。

优点:

高效的硬件加速:MediaCodec 支持硬件加速功能,这意味着它可以利用设备的硬件资源来提高音视频处理的效率和性能。硬件加速对于实现流畅且高质量的音视频处理至关重要,特别是在处理高分辨率或高帧率的内容时。
直接访问底层编解码器:通过 MediaCodec,开发者可以直接访问底层的编解码器,从而实现更高效的音视频处理。这有助于减少不必要的中间层开销,提高整体性能。
节省包体积:与常规的编解码库相比,MediaCodec 通常具有更小的体积,因此使用它可以帮助减小应用程序的包大小,降低用户的下载和安装成本。

缺点:
API 复杂性:MediaCodec 的 API 相对较为复杂,需要开发者具备较深的音视频处理知识和编程经验。这使得学习和使用 MediaCodec 的门槛相对较高,可能会增加开发难度和成本。
版本兼容性问题:MediaCodec 在不同版本的 Android 系统上可能存在兼容性问题。某些旧版本的 Android 系统可能不支持 MediaCodec 或支持有限,这可能导致开发者需要针对不同版本进行额外的适配工作。
硬件依赖:虽然 MediaCodec 支持硬件加速,但这也意味着它的性能受限于设备的硬件能力。不同设备的硬件性能差异可能导致音视频处理效果的差异,这要求开发者在设计和优化应用时需要考虑设备的硬件条件。

主要步骤

使用 MediaCodec API 通常涉及以下步骤:
创建编解码器实例:使用 MediaCodec.createDecoderByType 或 MediaCodec.createEncoderByType 方法创建编解码器实例。
配置编解码器:通过调用 MediaCodec.configure 方法配置编解码器的参数,如输入/输出格式、回调等。
启动编解码器:调用 MediaCodec.start 方法启动编解码器。

处理数据:
编码:从输入缓冲区获取数据,传递给编解码器进行编码,然后从输出缓冲区获取编码后的数据。
解码:将压缩数据写入输入缓冲区,从编解码器获取解码后的数据(通常写入输出缓冲区)。
停止和释放编解码器:完成数据处理后,调用 MediaCodec.stop 方法停止编解码器,并调用 MediaCodec.release 方法释放资源。

关键方法
configure:配置编解码器的参数。
start 和 stop:启动和停止编解码器。
dequeueInputBuffer 和 queueInputBuffer:获取输入缓冲区的索引并将数据送入编解码器。
dequeueOutputBuffer 和 releaseOutputBuffer:获取输出缓冲区的索引并读取处理后的数据,然后释放缓冲区。
getInputBuffers 和 getOutputBuffers:获取输入和输出缓冲区的直接引用。

栗子(设置编码器,输入原始视频帧,并从编码器获取编码后的数据):

通常需要在 AndroidManifest.xml 中添加如下权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />  
<uses-permission android:name="android.permission.CAMERA" />  
<uses-feature android:name="android.hardware.camera" />  
<uses-feature android:name="android.hardware.camera.autofocus" />
import android.media.MediaCodec;  
import android.media.MediaCodecInfo;  
import android.media.MediaFormat;  
import android.util.Log;  
import java.nio.ByteBuffer;  public class VideoEncoder {  private static final String TAG = "VideoEncoderTest";  private MediaCodec encoder;  private boolean isRunning;  public void start(int width, int height, int bitrate) {  isRunning = true;  encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);  MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);  format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);  format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);  format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);  format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);  encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);  encoder.start();  }  public ByteBuffer[] getInputBuffers() {  return encoder.getInputBuffers();  }  public int dequeueInputBuffer(long timeoutUs) {  return encoder.dequeueInputBuffer(-1);  }  public void queueInputBuffer(int inputBufferIndex, int offset, int size, long presentationTimeUs, int flags) {  encoder.queueInputBuffer(inputBufferIndex, offset, size, presentationTimeUs, flags);  }  public ByteBuffer[] getOutputBuffers() {  return encoder.getOutputBuffers();  }  public MediaCodec.BufferInfo dequeueOutputBuffer(long timeoutUs) {  MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();  int outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, timeoutUs);  while (outputBufferIndex >= 0) {  // 处理输出缓冲区的数据  encoder.releaseOutputBuffer(outputBufferIndex, false);  outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);  }  return bufferInfo;  }  public void stop() {  if (isRunning) {  isRunning = false;  encoder.stop();  encoder.release();  encoder = null;  }  }  
}

相关文章:

Android笔记--MediaCodec(一)

这一节主要来了解一下MediaCodec&#xff0c;Android MediaCodec 是 Android 平台提供的一个用于处理音频和视频数据的 API。它允许开发者对音频和视频数据进行编码和解码&#xff0c;支持多种格式和编解码器。MediaCodec API 通常用于实现实时音视频处理&#xff0c;如视频录制…...

Linux简单介绍

Linux简单介绍 编译器VMware虚拟机Ubuntu——LinuxOS为什么使用LinuxOS&#xff1f; 目录结构Windows目录结构Linux操作系统home是不是家目录&#xff1f; Linux常用命令终端命令行提示符与权限切换命令tab 作用&#xff1a;自动补全上下箭头pwd命令ls命令mkdir命令touch命令rm…...

Servlet 的基本理解

Servlet 是JavaEE规范的一种&#xff0c;主要是为了扩展Java作为Web服务的功能&#xff0c;统一接口。由其他内部厂商如tomcat&#xff0c;jetty内部实现web的功能。如一个http请求到来&#xff1a;容器将请求封装为servlet中的HttpServletRequest对象&#xff0c;调用init()&a…...

JavaScript之applye、bind和call方法详解

Question Q1 apply()、bind()和call()方法的区别在哪&#xff1f; Q2 apply()和call()的应用场景 Q3 apply()、bind()和call()方法手写实现逻辑 来源 继承自Function.prototype&#xff0c;属于实例方法 console.log(Function.prototype.hasOwnProperty(call)) //trueconsole.l…...

Docker,anaconda环境的部署与迁移

功能上线将提上日程&#xff0c;但是如何将我windows环境下的程序放到linux服务器的测试环境跑通呢&#xff1f;这是我这整个清明假期将要解决的一件事&#xff0c;最蠢的办法就是看自己的环境下有哪些依赖&#xff0c;如何到服务器上一个一个下&#xff0c;但是首先这个方法很…...

【大数据运维】Hbase shell 常见操作

文章目录 一. DDL1. 表的DDL1.1. 创建表1.2. 删除表 2. 列族的DDL2.1. 增加一个列簇2.2. 删除列族2.3. 修改列族版本&#xff08;ing&#xff09; 二. DML1. 插入与更新数据2. 删除数据3. 清空表 三. DQL1. scan&#xff1a;查一批数据1.1. 查询全部1.2. 过滤rowkey1.3. 过滤列…...

LeetCode-217存在重复的元素

217 存在重复的元素 给定一个整数数组&#xff0c;判断是否存在重复元素。 如果存在一值在数组中出现至少两次&#xff0c;函数返回 true 。如果数组中每个元素都不相同&#xff0c;则返回 false 。 JavaScript的 Array 对象是用于构造数组的全局对象&#xff0c;数组是类似…...

基于两个单片机串行通信的电子密码锁设计

1.功能 电子号码锁在实际应用中应该有两部分&#xff0c;一部分在外部&#xff0c;有键盘部分和密码显示&#xff1b;另一部分内部&#xff0c;设置密码、显示密码。使用单片机自身带有的串口可以很方便的实现单片机之间的通信&#xff0c;使输入的密码值传送到主机检验是否是…...

产品经理功法修炼(3)之产品设计

点击下载《产品经理功法修炼(3)之产品设计》 1. 前言 产品经理的能力修炼并非局限于某一技能的速成,而是需要全面参与到产品的整个生命周期中,通过不断的实践来逐步提升自己的各项能力。尽管在企业的日常运作中,我们不可能身兼数职去扮演每一个角色,但作为产品的核心负…...

Qt 的发展历史、现状与启示

Qt 最早在1991年由挪威的两位程序员 Eirik Chambe-Eng 和 Haavard Nord 开发&#xff0c;他们在1994年创立 Trolltech 公司&#xff08;奇趣科技&#xff09;正式经营软件业务。Qt 的第一个公众预览版于1995年面世&#xff0c;之后在2008年被诺基亚收购&#xff1b;2011年到201…...

Quiet-STaR:让语言模型在“说话”前思考

大型语言模型(llm)已经变得越来越复杂&#xff0c;能够根据各种提示和问题生成人类质量的文本。但是他们的推理能力让仍然是个问题&#xff0c;与人类不同LLM经常在推理中涉及的隐含步骤中挣扎&#xff0c;这回导致输出可能在事实上不正确或缺乏逻辑。 考虑以下场景:正在阅读一…...

【Kotlin】匿名类和伴生类

1 匿名类 1&#xff09;无继承 fun main() {var obj object {var name: String "zhang"override fun toString(): String {return name}}println(obj) // zhang } 2&#xff09;有继承 fun main() {var obj object: People {var name: String "zhang"…...

【机器学习算法介绍】(3)决策树

决策树是一种常见的机器学习算法&#xff0c;用于分类和回归任务。它模拟了人类决策过程&#xff0c;通过一系列的问题来引导决策。决策树的构建涉及三个主要步骤&#xff1a;特征选择、树的构建和树的剪枝。 1. 特征选择 特征选择是决策树构建过程中的第一步&#xff0c;目的…...

算法之查找

1、顺序查找&#xff1a; package com.arithmetic.search; //顺序查找 //sequentialSearch 方法接收一个整数数组和一个目标元素作为参数&#xff0c;并使用顺序查找的方式在数组中查找目标元素。 //它通过循环遍历数组元素&#xff0c;逐个与目标元素比较&#xff0c;如果找到…...

LInux脚本学习

1.注释 #单行注释 以 # 字符开头就是单行注释 当然第一行除外&#xff0c;比较特殊 2.多行注释 3.Shell文件的作用 Shell文件就是linux命令集 4.sh脚本的执行方式 bash xxx.sh 5.新建的文件会没有执行权限 #为文件赋予执行权限 chmod ux xxx.sh 6.编写规范 #!/bin/bash #…...

JavaWeb基础(计网 socket 数据库 JDBC lombok Mybatis JUnit Maven)

本文用于检验学习效果&#xff0c;忘记知识就去文末的链接复习 1. 网络基础 1.1 计网基础 区分设备&#xff1a;IP地址 区分网络&#xff1a;网络地址 网络互联&#xff1a;路由器 主机上进程间通信&#xff1a;端口 http是常用的协议&#xff0c;基于TCP协议 TCP VS U…...

【HBase】

什么是HBase HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据。 访问层次&#xff08;数据…...

Vue3:使用Pinia存储、读取、修改数据

一、存储数据 Pinia插件中&#xff0c;存储数据的配置项是state count.ts import {defineStore} from piniaexport const useCountStore defineStore(count,{// 真正存储数据的地方state(){return {sum:6}} })loveTalk.ts import {defineStore} from piniaexport const use…...

基于 Quartz.NET 可视化任务调度平台 QuartzUI

一、简介 QuartzUI 是基于 Quartz.NET3.0 的定时任务 Web 可视化管理&#xff0c;Docker 打包开箱即用、内置 SQLite 持久化、语言无关、业务代码零污染、支持 RESTful 风格接口、傻瓜式配置、异常请求邮件通知等。 二、部署 QuartzUI 从 2022 年到现在没有提交记录&#xf…...

前端三剑客 —— CSS (第三节)

目录 上节回顾&#xff1a; 1.CSS使用有以下几种样式; 2.选择器 1.基本选择器 2.包含选择器 3.属性选择器 [] 4.伪类选择器 &#xff1a; 5.伪元素选择器 ::before :after 3.常见样式的使用 常见样式参考表 一些特殊样式 媒体查询 自定义字体 变换效果 translate&…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...