简单解释一下,经由过程 getInputBuffers 获取输入队列,然后调用 dequeueInputBuffer 获取输入队列余暇数组下标,留意 dequeueOutputBuffer 会有几个特别的返回值表示当前编解码状况的变更,然后再经由过程 queueInputBuffer 把原始YUV数据送入编码器,而在输出队列端同样经由过程 getOutputBuffers 和 dequeueOutputBuffer 获取输出的h264流,处理完输出数据之后,须要经由过程 relea搜刮引擎优化utputBuffer 把输出buffer还给体系,从新放到输出队列中。
关于MediaCodec更复杂的应用例子,可以参照下CTS测试琅绫擎的应用方法: EncodeDecodeTest.java
1、色彩格局问题
MediaCodec在初始化的时刻,在 configure 的时刻,须要传入一个MediaFormat对象,算作为编码器应用的时刻,我们一般须要在MediaFormat中指定视频的宽高,帧率,码率,I帧距离等根本信息,除此之外,还有一个重要的信息就是,指定编码寡居收的YUV帧的色彩格局。这个是因为因为YUV根据其采样比例,UV分量的分列次序有很多种不合的色彩格局,而对于Android的摄像头在 >
两种格局分别是YUV420P和NV21,如不雅机械上只支撑YUV420P格局的情况下,则须要先将摄像头输出的NV21格局先转换成YUV420P,才能送入编码器进行编码,不然最终出来的视频就会花屏,或者色彩出现错乱
这个算是一个不大年夜不小的坑,根本上用上了MediaCodec进行视频编码都邑赶上这个问题
2、编码器支撑特点相当有限
大年夜膳绫擎例子来看切实其实是异常原始的API,因为MediaCodec底层是直接调用了手机平台硬件的编解码才能,所以速度异常快,然则因为Google半数个Android硬件生态的┞菲控力异常弱,所以这个API有很多问题:
如不雅应用MediaCodec来编码H264视频流,对于H264格局来说,会有一些针对紧缩率以及码率相干的视频质量设置,典范的诸如Profile(baseline, main, high),Profile Level, Bitrate mode(CBR, CQ, VBR),合理设备这些参数可以让我们在一致的码率下,获得更高的紧缩率,大年夜而晋升视频的质量,Android也供给了对应的API进行设置,可以设置到MediaFormat中这些设置项:
- MediaFormat.KEY_BITRATE_MODE
- MediaFormat.KEY_PROFILE
- MediaFormat.KEY_LEVEL
但问题是,对于Profile,Level, Bitrate mode这些设置,在大年夜部分别机上都是不支撑的,即使是设置了最终也不会生效,例如设置了Profile为high,最后出来的视频依然还会是Baseline,Shit....
这个问题,在7.0以下的机械几乎是必现的,个一一个可能的原因是,Android在源码层级 hardcode 了profile的的设置:
Android直到 7.0 之后才撤消了这段处所的Hardcode
- if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- ....
- } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
- h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
- .....
- }
这个问题可以说借居导致了MediaCodec编码出来的视频质量偏低,一致码率下,难以获得跟软编码甚至iOS那样的视频质量。
这篇文┞仿重要将会对视频流的编码中两个常见问题进行分析:
- 视频编码器的选择(硬编 or 软编)?
- 若何对摄像头输出的YUV帧进行快速预处理(镜像,缩放,扭转)?
3、16位对齐请求
前面说到,MediaCodec这个API在设计的时刻,过于切近HAL层,这在很多Soc的实现上,是直接把传入MediaCodec的buffer,在不经由任何前置处理的情况下就直接送入了Soc中。而在编码h264视频流的时刻,因为h264的编码块大年夜小一般是16x16,于是乎在一开端设置视频的宽高的时刻,如不雅设置了一个没有对齐16的大年夜小,例如960x540,在某些cpu上,最终编码出来的视频就会直接 花屏 !
很明显这照样因为厂商在实现这个API的时刻,对传入的数据缺乏校验以及前置处理导致的,今朝来看,华为,三星的Soc出现这个问题会比较频繁,其他厂商的一些早期Soc也有这种问题,一般来说解决办法照样在设置视频宽高的时刻,同一设置查对齐16位之后的大年夜小就好了。
FFMpeg+x264/openh264
除了应用MediaCodec进行编码之外,别的一种比较风行的方檀卷是应用ffmpeg+x264/openh264进行软编码,ffmpeg是用于一些视频帧的预处理。这里主如果应用x264/openh264作为视频的编码器。
软硬编比较
推荐阅读
我们计算编写这些函数异常简单的版本,但真正的调试器有 thread plan 的概念,它封装了所有的单步信息。例如,调试器可能有一些复杂的逻辑去决定断点的地位,然后有一些回调函数用于断定>>>详细阅读
本文标题:谈谈关于Android视频编码的那些坑
地址:http://www.17bianji.com/lsqh/36974.html
1/2 1