Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何获取MediaCodec编码器的跨距和Y平面对齐值_Android_Encoding_Android Mediacodec - Fatal编程技术网

Android 如何获取MediaCodec编码器的跨距和Y平面对齐值

Android 如何获取MediaCodec编码器的跨距和Y平面对齐值,android,encoding,android-mediacodec,Android,Encoding,Android Mediacodec,关于这个主题,有几个相关的问题和讨论: 我正在将相机预览帧(NV21转换为NV12)传送到MediaCodec编码器(NV12akaCOLOR\u formatYUV420半平面)。看起来,在一些装有高通编码器的设备上,运行的安卓版本低于4.3,我必须进行一些输入帧处理,以便接收正确颜色的后帧 在运行Android 4.2.2的Sony Xperia ZR上,我必须添加Y平面对齐,以便在几乎所有分辨率下都能工作。上面的代码为不能除以32的宽度添加了1024字节对齐,为其他分辨率添加了

关于这个主题,有几个相关的问题和讨论:

我正在将相机预览帧(
NV21
转换为
NV12
)传送到
MediaCodec
编码器(
NV12
aka
COLOR\u formatYUV420半平面
)。看起来,在一些装有高通编码器的设备上,运行的安卓版本低于
4.3
,我必须进行一些输入帧处理,以便接收正确颜色的后帧

在运行Android 4.2.2的Sony Xperia ZR上,我必须添加
Y
平面对齐,以便在几乎所有分辨率下都能工作。上面的代码为不能除以32的宽度添加了1024字节对齐,为其他分辨率添加了2048字节对齐。它使
MediaCodec
能够对所有分辨率的帧进行正确编码,这些分辨率可以除以
16
(除了
176x144
,因为
UV
平面看起来未对齐)

int getYPadding(){
if(mediacodeinfo.getName()包含(“OMX.qcom”)和&android.os.Build.VERSION.SDK_INT<18){
如果((getWidth()%32)!=0){
返回值(getWidth()*getHeight())%1024;
}否则{
返回值(getWidth()*getHeight())%2048;
}
}
返回0;
}
我试着在运行相同的Android 4.2.2的LG G2上测试这种对齐方式,它有高通公司的编码器,看起来它不能正常工作<代码>UV平面未对齐(框架底部的绿色条纹)。我无法计算两款手机的填充物

我还可以使用
高通公司
芯片组访问运行
安卓4.3
索尼Xperia Z1
,看起来它没有这样的问题。每个分辨率的视频看起来都很好,
Y
平面无论如何都不需要对齐


我知道它与硬件相关,可能很复杂,但由于我必须支持运行
4.3
之前的Android系统的用户,我有一个问题。是否有可能通过编程确定给定颜色格式的编码器期望的平面对齐和垂直/水平跨距值?

问题简而言之:在Android 4.3(API 18)之前,视频编码没有任何限制

因此,
MediaCodec
在不同设备上的行为不一致,一些bug没有被注意到。这些测试执行您所询问的功能,因此您可以可靠地将YUV数据提供给4.3+设备(尽管您仍然需要在运行时检测它是要平面还是半平面)

对于您的具体问题,较旧的高通设备上的Y平面需要在2K边界对齐,这与您的代码所做的不完全相同。对于720p视频,这是自然发生的(720*1280==450*2048),对于176x144,您需要调整1280以在26624而不是25344处开始UV平面。您需要在缓冲区内设置绝对对齐,而不是固定的填充量——使用
uvoffset=(width*height+2047)和~2047


您需要检测编解码器供应商和Android软件版本,如果是高通4.3之前版本,则需要进行此调整。如果您的需求发生变化,并且您可以针对API 18+,这些问题就会消失。(您可以使用
Surface
输入到
MediaCodec
,这避免了U/V交换问题,尽管这取决于您的需要,可能没有什么用处。)

感谢您的回答,@fadden you's awees!:)通过正确的对齐方式,我终于能够在
索尼Xperia ZR
上实现所有分辨率。LG G2上仍然有问题,但我想我会把它总结成一个单独的问题,并附上一些屏幕截图。除此之外,您更可能希望在2K边界对齐Y平面和UV平面。例如,对于480x480的RGB视频分辨率,要传递给MediaCodec的Yuv420缓冲区的大小应为:YUVBufferSize+yOffset+uvOffset,其转换为:(480*480*1.5)+(2048-((480*480)%2048))+(2048-((480*480/2)%2048))。我不知道LG_G2使用哪种编码器,如果是qcom编码器,那么您可以尝试这种逻辑。希望这有帮助。
int getYPadding() {
    if (mediaCodecInfo.getName().contains("OMX.qcom") && android.os.Build.VERSION.SDK_INT < 18) {
        if ((getWidth() % 32) != 0) {
            return (getWidth()*getHeight()) % 1024;
        } else {
            return (getWidth()*getHeight()) % 2048;
        }
    }
    return 0;
}