当前位置:网站首页>MediaCodec的数据类型和使用方式
MediaCodec的数据类型和使用方式
2022-06-21 19:24:00 【HUI的技術筆記】
三种数据类型
编解码器处理三种数据:压缩数据、原始音频数据和原始视频数据。
所有三种类型的数据都可以使用ByteBuffer进行处理,但是您应该使用原始视频数据的surface来提高编解码器的性能。Surface使用native video buffer,而无需将它们映射或复制到ByteBuffers;因此,它的效率更高。
在使用Surface时,通常无法访问原始视频数据,但可以使用ImageReader类访问raw视频帧。这可能仍然比使用ByteBuffers更有效,因为一些native buffer可能映射到ByteBuffer#isDirect ByteBuffers。使用ByteBuffer模式时,可以使用Image类和getInput/OutputImage(int)访问原始视频帧。
现在的基本上api版本都是大于21的,所以用的较多的就后面两种:
- Synchronous API using buffers
- Asynchronous API using buffers
| Processing Mode | API version <= 20 | API version >= 21 |
|---|---|---|
| Synchronous API using buffer arrays | Supported | Deprecated |
| Synchronous API using buffers | Not Available | Supported |
| Asynchronous API using buffers | Not Available | Supported |
Raw Video Buffers
在ByteBuffer模式下,video buffer由MediaFormat::KEY_COLOR_FORMAT来确定。video codec支持三种颜色格式:
native raw video format:这是由COLOR_FormatSurface指定,可以与输入或输出surface一起使用。flexible YUV buffers:COLOR_FormatYUV420Flexible,这些可以用于输入/输出surface,也可以在ByteBuffer模式下使用getInput/OutputImage.other, specific formats:通常仅在ByteBuffer模式下支持这些格式。某些颜色格式是特定于供应商的,可以使用getInput/OutputImage.
MediaCodec的同步方式
java实现
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(…);
// fill inputBuffer with valid data
/// …
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is identical to outputFormat
// outputBuffer is ready to be processed or rendered.
/// …
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
}
codec.stop();
codec.release();
MediaCodec的异步实现方式
java实现
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
/// …
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// outputBuffer is ready to be processed or rendered.
/// …
codec.releaseOutputBuffer(outputBufferId, …);
}
@Override
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format; // option B
}
@Override
void onError(…) {
/// …
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
MediaCodec EOS
当需要结束时,必须向编解码器发送EOS信号,可以通过queueInputBuffer调用,指定buffer的flag为BUFFER_FLAG_END_OF_STREAM,可以在最后一个有效的输入输出buffer上执行,也可以通过指定一个额外的空输入输出buffer设置EOS flag来执行此操作,如果使用空buffer,时间戳会被忽略。
编解码器将继续返回输出buffer,直到它通过在dequeueOutputBuffer中的BufferInfo中获得相同EOS标志或通过Callback#onOutputBufferAvailable返回,最终发出EOS信号。这可以在最后一个有效输出buffer上设置,也可以在最后一个有效输出buffer之后的空缓冲区上设置,空buffer的时间戳需要忽略掉。
在发出输入end-of-stream信号后,不要提交额外的输入缓冲区,除非编解码器已经被flushed, or或者stopped and restarted。
Codec-specific Data
一些格式,尤其是AAC音频和MPEG4、H.264和H.265视频格式,需要在实际数据前有一个Codec-specific Data。在处理这种压缩格式时,这些数据必须在start()之后和实际frame数据之前提交到编解码器。在对queueInputBuffer的调用中,必须使用标志BUFFER_FLAG_CODEC_CONFIG来标记这些数据。
Codec-specific data也可以包含在key“csd-0”、“csd-1”等在ByteBuffer条目中配置的格式中。这些key始终包含在从MediaExtractor#getTrackFormat获得的track MediaFormat中。格式中的Codec-specific data在start()时自动提交到编解码器,您不能explicitly提交此数据。如果格式不包含Codec-specific数据,则可以根据格式要求选择使用指定数量的buffer按正确顺序提交。对于H.264 AVC,还可以连接所有Codec-specific data,并将其作为单个codec-config buffer提交给编解码器。
MediaCodec Surface
使用输入Surface
使用Input Surface时,没有可访问的输入buffer,因为buffer会自动从输入到Surface传递到编解码器。调用dequeueInputBuffer将引发IllegalStateException,getInputBuffers()返回一个不能写入的伪ByteBuffer[]数组。
调用signalEndOfInputStream()以发出流结束的信号。在此调用之后,输入Surface将立即停止向编解码器submit数据。
使用输出Surface
当使用输出Surface,数据处理与ByteBuffer模式几乎相同;但是,输出buffer将不可访问,并且表示为空值。getOutputBuffer/Image将返回null,getOutputBuffers()将返回仅包含null-s的数组。
使用输出surface,可以选择是否在surface上渲染每个输出buffer,您有三个选择:
- Do not render the buffer: Call
releaseOutputBuffer(bufferId, false) - Render the buffer with the default timestamp: Call
releaseOutputBuffer(bufferId, true) - Render the buffer with a specific timestamp: Call
releaseOutputBuffer(bufferId, timestamp)
边栏推荐
- Random forest learning notes
- XR34082A高效率升压DC/DC调整器IC
- The Summer Challenge realizes a standard layout of Huawei app with openharmony ETS
- Details, MySQL_ DATE_ FORMAT()_ Functions_ Detailed explanation (remember to collect)
- How to distinguish between machine learning and pattern recognition?
- 数据路:三人行,必有我师!
- What is redis hyperloglog? The use of these scenes makes me laugh like a dragon
- DO280OpenShift命令及故障排查--访问资源和资源类型
- YX2811景观装鉓驱动IC
- 什么是eGFP,绿色荧光蛋白
猜你喜欢

Servlet使用

高考后网上查询信息,注意防范没有 SSL证书的网站

Get the openharmony source code: get it from the deveco marketplace (1)

基于 PCA 的人脸识别系统及人脸姿态分析

【owt】p2p Signaling Server 运行

Advanced algebra_ Chapter 9: linear mapping

Vertical and horizontal network shooting range community Modbus Protocol

带你区分几种并行

Show you how to distinguish several kinds of parallelism

What is more advantageous than domestic spot silver?
随机推荐
UIButton实现左文字右图片
Shutter tabbarview component
It is said that the price of the iPhone 14 will rise; TikTok US user data is transferred to Oracle, and bytes cannot be accessed; Seatunnel 2.1.2 releases geek headlines
Kubernetes-23: explain how to make CPU manager more flexible
Servlet使用
高性能内网DNS系统介绍
MySQl学习(从入门到精通 1.2)
LeeCode70 爬楼梯
Quartus II 18.0软件安装包和安装教程
行业首家!极氪APP获中国网络安全审查技术与认证中心权威认证
随机森林(Random Forest)学习笔记
In May, I just came back from the Ali software testing post. I worked for Alibaba P7 at 3+1, with an annual salary of 28*15
模拟input输入并获得print输出的内容
Get the openharmony source code: get it from the deveco marketplace (1)
SQL教程之6种鲜为人知的 SQL 技术,可帮助您每月节省 100 小时
AB打包有的Shader没有触发IPreprocessShaders的回调
Extend the clean, fresh and dense bag, and put a "safety lock" on the ingredients
函数的声明方式
Alibaba cloud ack one and ACK cloud native AI suite have been newly released to meet the needs of the end of the computing era
How to implement chat robot in naturallanguageprocessing?