从原理到实践:使用Mediacodec编码H265并实现解码H265码流

news/2024/7/10 21:40:02 标签: ffmpeg, java, Android开发, 音视频, h.265

H265

H265,也称为HEVC(High Efficiency Video Coding),是一种高效视频编码格式。它是H264(AVC)的后继者,也是ITU-T和ISO/IEC联合开发的标准。相比H264,H265可以在同样的视频质量下,使用更少的码率传输数据,实现更高的压缩率,同时支持更高的分辨率和比特率。这使得H265在视频传输、视频会议、视频监控等领域有着广泛的应用。

H265编码采用了新的算法和技术,包括更多的预测模式、更好的运动估计和补偿、更高效的量化和熵编码等,以实现更高效的视频压缩。与H264相比,H265还支持8K(7680x4320)和10K(10240x4320)分辨率的视频,以及更高的比特率和更多的色彩空间。

虽然H265编码技术成熟,但由于其复杂度较高,需要更多的计算和存储资源,所以在实际应用中需要根据具体场景进行优化和适配。同时,为了得到更好的视频质量和更高的压缩率,也需要对H265编码的参数进行调整和优化。

Mediacodec

Mediacodec是Android系统提供的用于音视频编解码的API。通过Mediacodec,开发者可以对视频和音频进行硬编解码或软编解码,实现高效的音视频处理。Mediacodec提供了相对底层的API,需要开发者自己管理多个编码器、解码器和输入缓冲区、输出缓冲区等资源,但使用Mediacodec可以获得更高的性能和更优秀的质量。

Mediacodec的使用包含以下几个步骤:

创建Mediacodec对象和MediaFormat对象

创建名为“video/avc”或“audio/mp4a-latm”的MediaFormat对象,表示要编解码的音视频格式。然后创建名为“video/avc”或“audio/mp4a-latm”的Mediacodec对象,使用MediaCodec.createEncoderByType或MediaCodec.createDecoderByType方法创建编解码器。

MediaCodec mediaCodec = MediaCodec.createDecoderByType("video/hevc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/hevc", width, height);

配置Mediacodec对象

通过Mediacodec的configure方法,设置输入格式、输出格式、编解码器参数等信息,然后调用start方法启动编解码器。

mediaCodec.configure(mediaFormat, surface, null, 0);
mediaCodec.start();

输入数据

通过dequeueInputBuffer方法获取一个输入缓冲区,从输入流中读取音视频数据,将数据填充到输入缓冲区中,然后通过queueInputBuffer方法将输入缓冲区加入编码队列。

int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
    ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
    inputBuffer.clear();
    int sampleSize = extractor.readSampleData(inputBuffer, 0);
    if (sampleSize < 0) {
        // end of stream, signal EOS to decoder
        mediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
    } else {
        long presentationTimeUs = extractor.getSampleTime();
        mediaCodec.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
        extractor.advance();
    }
}

处理数据

通过dequeueOutputBuffer方法获取一个输出缓冲区,从编码队列中取出编码数据,将数据填充到输出缓冲区中,然后通过releaseOutputBuffer方法将输出缓冲区加入输出队列。如果需要编解码速度更快,可以使用异步模式,使用Mediacodec.Callback回调处理输入输出缓冲区。

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US);
while (outputBufferIndex >= 0) {
    mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
    outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US);
}
if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
    // handle format change
    MediaFormat newFormat = mediaCodec.getOutputFormat();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
    // handle buffer change
}

停止Mediacodec

通过stop和release方法停止和释放编解码器。

需要注意的是,使用Mediacodec进行音视频编解码时,要根据具体的设备和编解码器,进行相应的参数设置和优化。使用硬件编解码可以获得更好的性能和更优秀的质量,但也需要注意硬件加速器的兼容性和使用方式。

mediaCodec.stop();
mediaCodec.release();

更多有关音视频开发的开发技术,可以参考音视频全套入门精通手册》点击查看详细内容。

最后 注意事項

使用Mediacodec实现解码H265码流需要注意以下几点:

设备需要支持H265解码器

H265解码需要硬件支持,所以设备需要有H265解码器才能进行解码,否则只能使用软解。

设置MediaFormat格式

H265码流的MediaFormat格式应该设置为"video/hevc",否则会无法解码。

注意输入数据的时间戳

H265码流中每一帧的时间戳可能不是递增的,需要解码器能够正确识别时间戳。在调用queueInputBuffer方法时,第四个参数presentationTimeUs就是该帧数据的时间戳,需要正确传入。

处理解码后的数据

解码后的数据可以通过MediaCodec.BufferInfo中的offset、size和presentationTimeUs等参数获取,可以将解码后的数据渲染到Surface上。

及时释放资源

使用完Mediacodec后需要及时调用stop()和release()方法释放资源,否则会导致内存泄漏等问题。

总之,在使用Mediacodec解码H265码流时需要注意以上几个问题,才能正确地进行解码和渲染。


http://www.niftyadmin.cn/n/425732.html

相关文章

技术视角 | 生成式 AI 对商业世界的革新与影响

2022 年底&#xff0c;ChatGPT 的横空出世让沉寂许久的 AI 产业重新焕发生机&#xff0c;围绕生成式 AI 的热烈讨论直到今天仍在继续。 根据国外一家数据网站 Digitalinformationworld 公布的新数据&#xff1a;ChatGPT 背后母公司 OpenAI 的网站流量&#xff0c;在 3 月份飙升…

【新版】系统架构设计师 - 计算机系统基础知识【补充】

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 计算机系统基础知识【补充内容】计算机语言多媒体系统工程霍尔的三维结构切克兰德方法并行工程方法综合集成法WSR&#xff08;物理-事理-人理&#xff09;系统方法系统工程生命周期7阶段生命周期方…

【C语言】整,浮点型数据存储,大小端。细节拉满!!

目录 一. 整型 1. C语言内置整型家族 类型的意义&#xff1a; 2.整型在内存如何存储的呢&#xff1f; 3. 原码&#xff0c;反码&#xff0c; 补码 原码 反码 补码 4. 当 整型遇上unsigned 会发生什么呢&#xff1f; 1. unsigned 与 signed 解析 2. printf 输出 有无…

redis 4.0.9 cluster 单台

安装redis yum install -y wget gcc wget http://download.redis.io/releases/redis-4.0.9.tar.gz tar xzf redis-4.0.9.tar.gz cd redis-4.0.9 #编译 make install 单台cluster 1 修改配置 新建6001 &#xff0c;6002 &#xff0c;6003&#xff0c;6004&#xff0c;6005 …

高阶复杂网络重建:从时间序列中重建高阶网络

论文链接&#xff1a;https://www.nature.com/articles/s41467-022-30706-9 一、为什么要研究高阶网络&#xff1f; 复杂网络跟我们生活息息相关&#xff0c;例如社交网络的信息传播&#xff0c;疾病的感染扩散和基因调控网络的相互作用等。越来越多的研究突破了传统网络中两…

一文走进 SQL 编译-语义解析

一、概述 SQL 引擎主要由三大部分构成&#xff1a;解析器、优化器和执行器。解析器的主要作用是将客户端传来的命令解析编译成数据库能识别运行的命令&#xff0c;其主要由词法解析、语法解析和语义解析三部分构成&#xff0c;如下图所示。 本文将重点介绍 KaiwuDB 语义解析部…

阿里iconfont的Symbol图标颜色无法改变

vue3里面引用阿里图标iconfont使用Symbol图标颜色无法改变 今天在vue3里面引入图标&#xff0c;去阿里图标库看了一下&#xff0c;Symbol可能是以后的趋势&#xff0c;就使用这个方式在项目里&#xff0c;中途一切顺利&#xff0c;就是等到改变图标颜色死活改不动&#xff0c;…

赢涛智慧工单 v2.4.3 公众号模块版

适用于&#xff1a;入驻加盟、运价查询、申请返礼、工单售后、商标注册、执照申请、汽车保养、年审代办、材料申请、流程审批、贷款申请、废品回收、投诉建议、业务登记、在线督导、购房申请、设备维修、门店报修、信息申请、材料提交、合作咨询、党群服务、入党申请、补贴申领…