HarmonyOS鸿蒙Next中旋转后的NV21数据 H264编码花屏、底部有绿边
HarmonyOS鸿蒙Next中旋转后的NV21数据 H264编码花屏、底部有绿边 场景:
做音视频通话的功能,横屏采集编码是没问题的,在竖屏状态下,对拿到的NV21数据进行了90度旋转后扔进编码器,发现编码出来的视频画面是花屏的且底部有绿边
配置:
采集分辨率:width-1280 height-720
数据旋转90度:这里用pixelMap的旋转和libyuv的旋转都尝试过
编码器参数:width-720 height-1280 NV21格式
已确认旋转后的NV21原始数据是没问题的,本地写文件用工具查看过
之前怀疑是跨距内存对齐问题,但是旋转后的YUV数据是正常的就排除了此选项
请问下此问题要如何排查解决
更多关于HarmonyOS鸿蒙Next中旋转后的NV21数据 H264编码花屏、底部有绿边的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,可以采取以下方式解决:
【背景知识】
- 数据对齐:在计算机读取数据时存在数据对齐,计算机一般都为32位或者64位,故一般数据对齐都为4字节或8字节的整数倍。如果数据非4字节或8字节对齐,就会需要额外花销来处理,为了避免这种额外的开销,通常会使用0或者其它数据在未对齐的数据末尾进行填充对齐。
- 宽高:图像数据中有效的宽高。
- 宽高跨距:跨距(Stride),是图像存储在内存中,每一行数据所占空间的真实大小,它大于或等于通过图像分辨率宽度计算的字节长度。由于内存对齐的缘故,方便提取数据,每行数据的字节数可能要求为一个数的倍数,这时不足的字节数由padding填充。(Stride = width + padding)
在可编程位图中有两种表示方式为RGB和YUV,RGB色彩空间的图像储存多为bmp格式的位图,其通常是由54字节的文件头信息头加上图片数据所组成。RGB的色彩空间以三原色来组合表示一个像素点,YUV格式色彩空间以亮度,色调,色饱和度来表示一个像素点。RGB色彩空间更适合图像采集和显示,YUV空间更适合编码和存储。在存储和编码之前,RGB图像要转换为YUV图像,而YUV图像在显示之前通常有必要转换回RGB。
【解决方案】
原因分析:在图像渲染时,若宽高和padding被错误的对齐,会导致图片出现斜条纹:
假设图片对齐为8,宽为6,跨距为8,填充为2,当跨距设置错误时会出现下面两种情况:
- 当padding填充不够时(假设为1),因为对齐为8此时会读取8个像素数据,现在只有1个padding,此时就会把第二行的像素数据多读取一个。
此时画面因为像素的错位显示呈现出左下往右上的撕裂斜条纹。
- 同理此时跨距过大,即padding填充过多时(假设为3)会导致多的一个填充被下一行像素数据读取。
此时画面因为像素的错位显示呈现出左上往右下的撕裂斜条纹。
解决方案:
根据不同的硬件限制,编解码器自动对齐的字节不同,可以使用OH_VideoEncoder_GetInputDescription查询得到AVformat,再用OH_AVFormat_GetIntValue获取OH_MD_KEY_VIDEO_STRIDE的值进行处理。详细处理方式参考视频编码文档中的调用OH_VideoEncoder_PushInputBuffer写入编码图像步骤。
可以参考:
更多关于HarmonyOS鸿蒙Next中旋转后的NV21数据 H264编码花屏、底部有绿边的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
你好,想要问下本地写文件用工具查看过是指把旋转后的YUV数据读取显示出来确认的数据正常吗?以及能否提供下变换前后的YUV数据来排查下问题?
HarmonyOS Next中NV21数据旋转后H264编码花屏和绿边问题
HarmonyOS Next中NV21数据旋转后H264编码花屏和绿边问题,主要因YUV数据旋转处理不当导致。旋转操作可能破坏YUV平面对齐,造成内存越界。绿边源于UV分量错位,H264编码时误将UV数据识别为Y分量。需确保旋转后UV分量保持2x2采样结构,且stride对齐编码器要求。建议使用系统提供的YUV转换接口处理旋转,避免手动操作引发数据错位。
从描述看,旋转后的NV21数据本身正常,但编码后出现花屏和绿边,问题很可能出在编码器配置或数据传递环节。
首先检查编码器输入的跨距(stride)参数。NV21格式要求Y分量跨距必须为16字节对齐,UV分量跨距为Y跨距的一半。旋转后分辨率变为720x1280,建议:
- 确认编码器输入的Y平面跨距为736(720向上取整到16的倍数)
- UV平面跨距应为368
- 验证传递给编码器的数据指针是否包含正确的跨距信息
其次检查色彩空间配置。绿边通常与UV分量错位有关:
- 确认编码器色彩格式设置为NV21而非NV12
- 检查旋转后UV分量的内存排列,确保V分量在U分量之前
最后验证时间戳设置:
- 确保输入帧的时间戳连续递增
- 检查编码器是否因时间戳异常丢弃了参考帧
建议在编码前添加数据校验,将旋转后的数据直接送入解码器验证,以隔离编码器问题。