AV_PIX_FMT_NV12像素修改方法及linesize参数匹配异常问题咨询
NV12格式像素操作与linesize参数问题解答
12bpp标注与uint8_t类型的兼容性说明
AV_PIX_FMT_NV12标注的12bpp是单像素平均占用比特数,计算逻辑为:每4个Y像素共享1组U、V分量,总数据量为 (宽×高×8bit) + (宽×高/2 ×8bit)= 宽×高×12bit,平均到每个像素刚好12bit,和单个Y/U/V分量均为8位uint8_t类型完全不冲突,不需要做位拆分操作,直接按字节读写分量即可。
NV12像素值修改方法
假设待修改的像素坐标为(x, y),其中x取值范围为[0, 图像宽度-1],y取值范围为[0, 图像高度-1],操作步骤如下:
- 修改Y分量:直接访问Y平面对应位置赋值即可,示例:
frame->data[0][y * frame->linesize[0] + x] = 目标Y值;
Y值常规取值范围为0255,广播电视标准范围为16235。 - 修改对应UV分量:4:2:0格式下,每2×2个Y像素共享一组U、V,因此UV坐标需要取整:
U、V值常规取值范围为0255,广播电视标准范围为16240。int uv_x = x / 2; int uv_y = y / 2; // 修改U分量 frame->data[1][uv_y * frame->linesize[1] + uv_x * 2] = 目标U值; // 修改V分量 frame->data[1][uv_y * frame->linesize[1] + uv_x * 2 + 1] = 目标V值;
注意:必须使用
linesize计算行偏移,不能直接用图像宽度,linesize存在对齐填充的情况下会大于实际图像宽度,直接用宽度计算会出现行错位问题。
linesize参数合理性说明
你观测到的linesize[0]和linesize[1]均为1920属于正常情况,不存在错误:
- 首先不能使用
strlen计算视频帧平面的长度,strlen是用于计算C风格字符串长度的函数,以\0(数值为0的字节)作为结束标志,而YUV平面属于二进制缓冲区,内部可能存在任意位置的0值,也没有末尾的\0结束符,你得到的1044587是无效值,没有任何参考意义。 - NV12的UV平面每行有效字节数为:(图像宽度/2) × 2 = 图像宽度,如果你的图像宽度为1920,UV平面
linesize为1920完全符合预期。linesize本身就允许大于每行有效字节数,多余部分为硬件对齐用的填充字节,不需要读写填充区域即可。
内容的提问来源于stack exchange,提问作者user14290993
相关产品推荐
相关产品推荐

