Codec2简介

[注]  该文章简要介绍了Codec 2.0是什么,如有错误与遗漏之处,欢迎指出。

谷歌在2019年发布的Android Q上提供了一套新的MediaCodec实现框架--Codec 2.0,这一套新的框架是相对于旧的ACodec与OMX而言的。Codec 2.0的顶层接口与ACodec是一致的,MediaCodec作为提供给开发者的多媒体接口,其内部实现从JAVA层至Native层,Native层的实现所主要调用的接口类,原先是ACodec,现在既可以是ACodec,也可以是Codec 2.0。

为什么谷歌不打算继续沿用原先成熟的ACodec+OMX中间件,而要推出新的一套Codec 2.0中间件,并打算在不久的版本取而代之?

一,在Android Q上,谷歌推出mainline计划,在mainline计划中,所涉及的模块是可通过Google Play商店进行升级的,同时也是不允许厂商在SDK上进行修改的,在该主线方式下,厂商对于mainline模块的修改只能通过向主线提交代码的方式进行,从而mainline模块减小了安卓生态的碎片化。谷歌的Codec 2.0属于mainline模块,厂商无法修改其代码,这样子的话,各家厂商的安卓设备都在多媒体中间件模块保持一致性,如果厂商想要在中间件模块上添加特性或者修复某个BUG,厂商只能向谷歌主线提交代码或者补丁,如果为主线所合并,这将同时让谷歌与其他厂商受益。

二,相比于ACodec+OMX的中间件框架,Codec 2.0将具备若干特性:组件连通(component chaining),过滤器(filters),配置可查询(configureation querying)。组件包括解码组件,编码组件,组件连通按目前的信息应该理解为类似OMX Component chaining一样的特性,解码组件连接编码组件,或者,编码组件连接解码组件,前者的场景包括编码格式转换,后者的场景包括直播推流。对于过滤器与配置可查询的特性,目前没有足够信息了解到其内容。

三,在性能上,相比于ACodec+OMX框架,Codec 2.0将具备更多的优势与可能性。原因在于,Codec 2.0的解码组件与编码组件所依赖的Buffer管理机制具备零拷贝特性,避免大块数据的拷贝所引起的性能降低。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
将 mp4 视频格式转换为 RGB 图像,需要经过以下几个步骤: 1. 使用 `MediaExtractor` 解析视频文件,获取视频中每个音视频轨道的信息。 2. 使用 `MediaCodec` 解码视频轨道中的数据,得到原始的 YUV 数据。 3. 将 YUV 数据转换为 RGB 数据。 4. 将 RGB 数据渲染到屏幕上。 下面是一个简单的示例代码,可以将 mp4 视频格式转换为 RGB 图像并显示在屏幕上: ```java private void decodeVideo(String videoPath) { try { // 创建 MediaExtractor 并指定要解析的视频文件路径 MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(videoPath); // 获取视频中的视频轨道 MediaFormat format = null; int videoTrackIndex = -1; for (int i = 0; i < extractor.getTrackCount(); i++) { format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { videoTrackIndex = i; break; } } if (videoTrackIndex == -1) { // 没有找到视频轨道 return; } // 创建 MediaCodec 并配置为解码器 extractor.selectTrack(videoTrackIndex); MediaCodec codec = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME)); codec.configure(format, null, null, 0); codec.start(); // 获取视频帧的 YUV 数据 ByteBuffer[] inputBuffers = codec.getInputBuffers(); ByteBuffer[] outputBuffers = codec.getOutputBuffers(); MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); boolean isEOS = false; long presentationTimeUs = 0; while (!Thread.interrupted()) { if (!isEOS) { int inIndex = codec.dequeueInputBuffer(10000); if (inIndex >= 0) { ByteBuffer buffer = inputBuffers[inIndex]; int sampleSize = extractor.readSampleData(buffer, 0); if (sampleSize < 0) { // 已经读到了视频末尾 codec.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); isEOS = true; } else { presentationTimeUs = extractor.getSampleTime(); codec.queueInputBuffer(inIndex, 0, sampleSize, presentationTimeUs, 0); extractor.advance(); } } } int outIndex = codec.dequeueOutputBuffer(info, 10000); switch (outIndex) { case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: outputBuffers = codec.getOutputBuffers(); break; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: // 获取解码后的视频格式 format = codec.getOutputFormat(); break; case MediaCodec.INFO_TRY_AGAIN_LATER: break; default: ByteBuffer buffer = outputBuffers[outIndex]; // 将 YUV 数据转换为 RGB 数据 byte[] yuvData = new byte[info.size]; buffer.get(yuvData); byte[] rgbData = convertYUVtoRGB(yuvData, format.getInteger(MediaFormat.KEY_WIDTH), format.getInteger(MediaFormat.KEY_HEIGHT)); // 渲染 RGB 数据到屏幕上 renderRGB(rgbData, format.getInteger(MediaFormat.KEY_WIDTH), format.getInteger(MediaFormat.KEY_HEIGHT)); codec.releaseOutputBuffer(outIndex, true); break; } if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { // 已经处理完所有的视频帧 break; } } codec.stop(); codec.release(); extractor.release(); } catch (IOException e) { e.printStackTrace(); } } private byte[] convertYUVtoRGB(byte[] yuvData, int width, int height) { // TODO: 将 YUV 数据转换为 RGB 数据 return null; } private void renderRGB(byte[] rgbData, int width, int height) { // TODO: 渲染 RGB 数据到屏幕上 } ``` 需要注意的是,YUV 数据和 RGB 数据的转换算法比较复杂,具体实现可以参考一些开源库,如 FFmpeg、libyuv 等。另外,在渲染 RGB 数据到屏幕上时,可以使用 OpenGL ES 来实现,具体的 OpenGL ES 代码可以参考其他资料。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值