MediaCodec类可用于访问低级媒体编解码器,即编码器/解码器组件。它是Android低级多媒体支持基础设施的一部分(通常与MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface,以及AudioTrack.)。
1.1数据类型
编解码器处理三种数据:压缩数据、原始音频数据和原始视频数据。 所有这三种数据都可以使用ByteBuffers,但您应该使用Surface用于原始视频数据以提高编解码器性能。Surface使用原生视频缓冲区,而不将其映射或复制到ByteBuffers因此,它的效率更高。
使用Surface时,通常无法访问原始视频数据,但可以使用ImageReader类来访问不安全的解码(原始)视频帧。这可能仍然比使用字节缓冲区更有效,因为一些本机缓冲区可以映射到直接的字节缓冲区。使用ByteBuffer模式时,可以使用Image类别和getInput/OutputImage(int)访问原始视频帧。
(1)压缩缓冲区
压缩数据可以作为解码器的输入、编码器的输出,需要指定数据的格式,这样codec才知道如何处理这些压缩数据
MediaFormat.KEY_MIME格式类型。
对于视频类型,通常是一个单独的压缩视频帧。
对于音频数据,通常是一个单独的访问单元(一个编码的音频段通常包含由格式类型决定的几毫秒的音频),但是这个要求稍微宽松一些,因为一个buffer可能包含多个编码的音频访问单元。
在这两种情况下,buffer都不会在任意字节边界上开始或结束,而是在帧/访问单元边界上开始或结束,除非它们被BUFFER_FLAG_PARTIAL_FRAME标记。
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
(2)原始音频缓冲区
原始音频数据 — PCM音频数据帧,这是每个通道按通道顺序的一个样本。
(3)原始视频缓冲区
在ByteBuffer模式下,视频buffer根据它们的MediaFormat.KEY_COLOR_FORMAT进行布局。可以从getCodecInfo(). MediaCodecInfo.getCapabilitiesForType.CodecCapability.colorFormats获取支持的颜色格式。视频编解码器可以支持三种颜色格式:
native raw video format: CodecCapabilities.COLOR_FormatSurface,可以与输入/输出的Surface一起使用。
flexible YUV buffers 例如CodecCapabilities.COLOR_FormatYUV420Flexible, 可以使用getInput/OutputImage(int)与输入/输出Surface一起使用,也可以在ByteBuffer模式下使用。
other, specific formats: 通常只支持ByteBuffer模式。有些颜色格式是厂商特有的,其他定义在CodecCapabilities。对于等价于flexible格式的颜色格式,可以使用getInput/OutputImage(int)。
从Build.VERSION_CODES.LOLLIPOP_MR1.开始,所有视频编解码器都支持flexible的YUV 4:2:0 buffer。
1.2 MediaCodec API
(1)MediaCodec创建:
createDecoderByType/createEncoderByType:根据特定MIME类型(如"video/avc")创建codec。然而,这不能用于注入特征,并且可能创建不能处理特定期望媒体格式的编解码器。
createByCodecName:知道组件的确切名称(如OMX.google.mp3.decoder)的时候,根据组件名创建codec。使用MediaCodecList可以获取组件的名称。
(2)MediaCodec配置与启动:
configure:配置解码器或者编码器。
四个参数:
MediaFormat format:输入数据的格式(解码器)或输出数据的所需格式(编码器)。传null等同于传递MediaFormat.MediaFormat作为空的MediaFormat。
Surface surface:指定Surface,用于解码器输出的渲染。如果编解码器不生成原始视频输出(例如,不是视频解码器)和/或想配置解码器输出ByteBuffer,则传null。
MediaCrypto crypto:指定一个crypto对象,用于对媒体数据进行安全解密。对于非安全的编解码器,传null。
int flags:当组件是编码器时,flags指定为常量CONFIGURE_FLAG_ENCODE。
MediaCodec可以处理具体的视频流,主要有这几个方法:
getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组
getInputBuffer(index) : 获取InputBuffers数组index下标的ByteBuffer
queueInputBuffer:输入流入队列
dequeueInputBuffer:从输入流队列中取数据进行编码操作
getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组
getOutputBuffer(index) : 获取OutputBuffers数组index下标的ByteBuffer
dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
releaseOutputBuffer:处理完成,释放ByteBuffer数据
(4)处理完之后的操作:
flush:清空的输入和输出端口。
stop:终止decode/encode会话
release:释放编解码器实例使用的资源。
MediaFormat的格式被指定为键/值对。keys是字符串。values可以是整数、长整型、浮点型、字符串或ByteBuffer。(要素元数据被指定为 字符串/布尔 对。)
2.1 所有音频/视频格式通用的键,所有未标记为可选的键都是强制性的:


2.3 音频格式有以下键:

2.4 字幕格式有以下关键字:
线格式的类型。KEY_LANGUAGE线内容的语言。KEY_CAPTION_SERVICE_NUMBER(同Internationalorganizations)国际组织可选,隐藏字幕服务或频道号。

2.5 图像格式有以下键: 
与媒体源一起使用的单个完整图像缓冲区,例如 MediaCodec或 CameraDevice 。
该类允许通过一个或多个ByteBuffers高效地直接应用程序访问图像的像素数据。 每个缓冲区都封装在描述该平面中像素数据布局的Image.Plane中。 由于这种直接访问方式,与Bitmap类不同,图像不能直接用作UI资源。
由于图像通常由硬件组件直接生成或使用,因此它们是整个系统共享的有限资源,应在不再需要时立即关闭。
例如,当使用ImageReader类从各种媒体源读出图像时,一旦达到the maximum outstanding image count ,不关闭旧的图像对象将阻止新图像的可用性。 发生这种情况时,获取新图像的函数通常会抛出IllegalStateException 。
3.1 getPlanes() 方法
获取该图像的像素平面阵列,平面的数量由图像的格式决定。这个需要了解ImageFormat的格式了,这个以后再了解。
3.2 ImageFormat.getBitsPerPixel()方法
使用此函数可检索ImageFormat的每个像素的位数。
这个在此就点一下算了,之后在单独开一节来具体讲解。
//解码操作,返回YUV加载的bitmap图片
public class ImageShowActivity extends Activity {
private TextView tv_yun;
//图片的个数
private int imageNum = 0;
private final String mVideoPath = Environment.getExternalStorageDirectory() + "/Pictures/music.mp4";
private MediaExtractor extractor;//用于解封装
private MediaFormat videoFormat;//保存视频轨道的媒体格式
private MediaCodec mediaCodec;//解码视频轨道资源
private int rotation;
private long duration;
//用于代表YUV的种类
public static final int YUV420P = 0;
public static final int YUV420SP = 1;
public static final int NV21 = 2;
//保存YUV数据的byte[]
private byte[] bytes;
private static int width;
private static int height;
//1.创建MediaExtractor和MediaCodec : MediaExtractor负责解封装,MediaCodec负责解码视频轨道资源
//2.解码获取图片,并进行转换:YUV_420_888-->NV21
//3.YuvImage 加载nv21,转化成Bitmap用于显示。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_show);
tv_yun = findViewById(R.id.tv_image_yuv);
GetVideo();
}
}
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl