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

4 回复

开发者您好,可以采取以下方式解决:

【背景知识】

  • 数据对齐:在计算机读取数据时存在数据对齐,计算机一般都为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,建议:

  1. 确认编码器输入的Y平面跨距为736(720向上取整到16的倍数)
  2. UV平面跨距应为368
  3. 验证传递给编码器的数据指针是否包含正确的跨距信息

其次检查色彩空间配置。绿边通常与UV分量错位有关:

  1. 确认编码器色彩格式设置为NV21而非NV12
  2. 检查旋转后UV分量的内存排列,确保V分量在U分量之前

最后验证时间戳设置:

  1. 确保输入帧的时间戳连续递增
  2. 检查编码器是否因时间戳异常丢弃了参考帧

建议在编码前添加数据校验,将旋转后的数据直接送入解码器验证,以隔离编码器问题。

回到顶部