android nv21数据用mediacodec编解码

在 Android 中使用 MediaCodec 进行 NV21 编码和解码的过程如下:

编码 NV21 数据:

// 创建 MediaCodec 编码器,并配置编码器格式和参数
val encoder = MediaCodec.createEncoderByType("video/avc")
val mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height)
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate)
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate)
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar)
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval)
encoder.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)// 启动编码器
encoder.start()// 创建输入缓冲区和输出缓冲区
val inputBuffers = encoder.inputBuffers
val outputBuffers = encoder.outputBuffers// 将 NV21 数据分割成 Y、U、V 平面
val yPlane = ByteArray(width * height)
val uvPlane = ByteArray(width * height / 2)
System.arraycopy(nv21Data, 0, yPlane, 0, width * height)
System.arraycopy(nv21Data, width * height, uvPlane, 0, width * height / 2)// 编码循环
while (isEncoding) {// 获取空闲的输入缓冲区索引val inputBufferIndex = encoder.dequeueInputBuffer(-1)if (inputBufferIndex >= 0) {val inputBuffer = inputBuffers[inputBufferIndex]inputBuffer.clear()inputBuffer.put(yPlane) // 将 Y 平面数据放入输入缓冲区inputBuffer.position(0)encoder.queueInputBuffer(inputBufferIndex, 0, yPlane.size, presentationTimeUs, 0)presentationTimeUs += 1_000_000 / frameRate // 更新时间戳}// 获取编码后的输出数据var outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_US)while (outputBufferIndex >= 0) {val outputBuffer = outputBuffers[outputBufferIndex]// 处理编码后的输出数据// 释放输出缓冲区encoder.releaseOutputBuffer(outputBufferIndex, false)outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_US)}
}// 停止编码器并释放资源
encoder.stop()
encoder.release()

解码编码后的数据:

// 创建 MediaCodec 解码器,并配置解码器格式和参数
val decoder = MediaCodec.createDecoderByType("video/avc")
val mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height)
mediaFormat.setByteBuffer("csd-0", csdBuffer) // 设置解码器参数
decoder.configure(mediaFormat, surface, null, 0) // 设置渲染 Surface
decoder.start()// 解码循环
while (isDecoding) {// 获取空闲的输入缓冲区索引val inputBufferIndex = decoder.dequeueInputBuffer(-1)if (inputBufferIndex >= 0) {val inputBuffer = inputBuffers[inputBufferIndex]// 将解码后的数据放入输入缓冲区decoder.queueInputBuffer(inputBufferIndex, 0, data.size, timestamp, 0)timestamp += 1_000_000 / frameRate // 更新时间戳}// 获取解码后的输出数据var outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_US)while (outputBufferIndex >= 0) {val outputBuffer = outputBuffers[outputBufferIndex]// 处理解码后的输出数据// 渲染解码后的数据到 Surfacedecoder.releaseOutputBuffer(outputBufferIndex, true)outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_US)}
}// 停止解码器并释放资源
decoder.stop()
decoder.release()

上述代码中的变量和参数需要根据你的实际情况进行调整。此外,NV21 格式的数据需要根据具体需要进行分割和处理传入编码器和解码器。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django入门 - 路由Route的基本使用

文章目录 1. 直接访问视图函数,没有使用子路由2. 使用子路由 urls.py 我们一般叫它根路由 1. 直接访问视图函数,没有使用子路由 MyDjangoPro2\views.py 代码 from django.shortcuts import renderfrom django.http import HttpResponse# 视图函数Views …

消息队列 (9)-消费者核心类的实现

目录 前言消费者类设计思路核心API总体代码 前言 我们上一篇博客,写了虚拟主机的实现, 在虚拟主机中需要用到俩个未实现的类,分别是验证绑定关键字和消费者类,接下来我们实现消费者类的核心代码 消费者类设计思路 在这个类中,首先我们要持有virtualHost对象来操作数据, 然后…

【BASH】回顾与知识点梳理(十)

【BASH】回顾与知识点梳理 十 十. 文件的格式化与相关处理10.1 格式化打印: printf10.2 awk:好用的数据处理工具awk 的逻辑运算字符 10.3 文件比对工具diffcmppatch 10.4 文件打印准备: pr 该系列目录 --> 【BASH】回顾与知识点梳理&#…

移动端开发基础总结

移动端学习总结 (适合于复习) 移动端基础 技术选型: 单独制作移动端页面(主流) 流式布局(百分比布局)flex弹性布局(强烈推荐)lessrem媒体查询布局混合布局 响应式页面兼容移动端(…

postman----传参格式(json格式、表单格式)

本文主要讲解postman使用post请求方法的2中传参方式:json格式、表单格式 首先了解下,postman进行接口测试,必须条件是: ♥请求地址 ♥请求协议 ♥请求方式 ♥请求头 ♥参数 json格式 先看一下接口文档,根据接口文档&…

深度学习环境安装依赖时常见错误解决

1.pydantic 安装pydantic时报以下错误: ImportError: cannot import name Annotated from pydantic.typing (C:\Users\duole\anaconda3\envs\vrh\lib\site-packages\pydantic\typing.py) 这个是版本错误,删除装好的版本,重新指定版本安装就…

项目规范 编写规范(范例)

项目目录 目录接口参考 项目目录结构设计,增加部分领域模型后缀强制定义,方便统一编码风格。 controller:请求处理 RestController module:按大业务区分,对多个业务对象数据聚合处理 Component manager:…

web-xss

一、简介 XSS 又称CSS(Cross Site Scripting)或跨站脚本攻击,攻击者在网页中插入由JavaScript编写的恶意代码,当用户浏览被嵌入恶意代码的网页时,恶意代码将会在用户的浏览器上执行。 二、xss的攻击方式 Dom:这是一种将任意 Jav…

zookeeper入门学习

zookeeper入门学习 zookeeper应用场景 分布式协调组件 客户端第一次请求发给服务器2,将flag值修改为false,第二次请求被负载均衡到服务器1,访问到的flag也会是false 一旦有节点发生改变,就会通知所有监听方改变自己的值&#…

一键开启ChatGPT“危险发言”

‍ ‍ 大数据文摘授权转载自学术头条 作者:Hazel Yan 编辑:佩奇 随着大模型技术的普及,AI 聊天机器人已成为社交娱乐、客户服务和教育辅助的常见工具之一。 然而,不安全的 AI 聊天机器人可能会被部分人用于传播虚假信息、操纵舆…

“深入探索JVM:Java虚拟机的工作原理解析“

标题:深入探索JVM:Java虚拟机的工作原理解析 摘要:本文将深入探索Java虚拟机(JVM)的工作原理,从类加载、内存管理、垃圾回收、即时编译器等方面进行详细解析,帮助读者更好地理解JVM的内部机制。…

SSH 免密登录

SSH SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录、远程复制等功能 SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令 SSH 为建立在应用层和传输层基础上的安全协议。对数…

命令行非明文密码连接 TiDB

作者: GangShen 原文来源: https://tidb.net/blog/6794a34b 在命令行中连接TiDB的过程中,为了保护密码不被明文获取,可以使用非明文密码连接。本文记录了几种非明文连接 TiDB 的方式。 方式一:命令行输入方式 [ro…

使用go获取链上数据之主动拉取-搭建环境(一)

使用go获取链上数据之主动拉取-搭建环境(一) 1、配置文件1.1、新建配置文件1.2、新建setting.go文件1.3、新建config.go文件 2、全局变量配置2.1、新建global.go2.2、初始化配置2.3、验证配置 在我们实际开发项目中,很多时候都需要从链上获取…

PyTorch 微调终极指南:第 1 部分 — 预训练模型及其配置

一、说明 如今,在训练深度学习模型时,通过在自己的数据上微调预训练模型来迁移学习已成为首选方法。通过微调这些模型,我们可以利用他们的专业知识并使其适应我们的特定任务,从而节省宝贵的时间和计算资源。本文分为四个部分&…

数据结构:插入排序

直接插入排序 插入排序算法是所有排序方法中最简单的一种算法,其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据。 直接插入排序是插入排序算法中的一种,采用的方法是:在…

解析隧道代理被封的几个主要原因

Hey,各位爬虫高手,你是不是经常遇到爬虫代理HTTP被封的问题?不要慌,今天我来分享一些信息,帮你解析这个问题!告别封禁,让你的爬虫工作更顺利,赶快跟随我一起了解吧! 在爬…

opencv基础45-图像金字塔01-高斯金字塔cv2.pyrDown()

什么是图像金字塔? 图像金字塔(Image> Pyramid)是一种用于多尺度图像处理和分析的技术,它通过构建一系列不同分辨率的图像,从而使得图像可以在不同尺度下进行处理和分析。图像金字塔在计算机视觉、图像处理和计算机…

APT80DQ60BG-ASEMI快恢复二极管APT80DQ60BG

编辑:ll APT80DQ60BG-ASEMI快恢复二极管APT80DQ60BG 型号:APT80DQ60BG 品牌:ASEMI 芯片个数:双芯片 封装:TO-3P 恢复时间:≤80ns 工作温度:-55C~150C 浪涌电流:600A 正向电…

UEFI build报错:‘build‘ is not recognized as an internal or external command

UEFI学习,某一次进行build时,提示: build is not recognized as an internal or external command,operable program or batch file. 用的命令是: C:\UEFIWorkspace>build -a X64 -p edk2\OvmfPkg\OvmfPkgX64.dsc -b NOOPT -…