ffmpeg添加图片水印的畸变问题
PAR/SAR/DAR
定义
- PAR(Pixel Aspect Ratio) 像素宽高比:单个像素的宽高比,通常该值为1,即正方形像素;若不为1,则为长方形像素。
- SAR(Sample Aspect Ratio) 采样纵横比:视频横向对应的像素个数比上视频纵向的像素个数,即为我们通常提到的分辨率。
- DAR(Display Aspect Ratio) 显示宽高比:终端显示时,播放画面的宽高比。
计算公式
SAR x PAR = DAR
通过上述公式,可以根据SAR、PAR、DAR中的两个计算出另外一个
ffmpeg中的分辨率、SAR、DAR
先来看一个样例视频的视频信息
"width": 1920,
"height": 1080,
"coded_width": 1920,
"coded_height": 1088,
"has_b_frames": 2,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv420p",
分析上述样例视频的avinfo信息可知:
- 分辨率=1920x108
- sar=1:1
- dar=16:9
实际上,由于通常PAR=1:1,使得帧画面的宽高比=分辨率(即宽高像素数目)
此时,ffmpeg对于分辨率、sar、dar有如下公式:
W/H * SAR = DAR
上述样例视频,1920/1080 * (1/1) = 16:9
再看另外一个样例视频的视频信息
"width": 480,
"height": 320,
"coded_width": 480,
"coded_height": 320,
"has_b_frames": 2,
"sample_aspect_ratio": "32:27",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv420p",
上述视频,480/320 * (32/27) = 16/9
水印畸变
播放形变
一般视频终端播放是否发生形变,可以根据如下参数来判定:
- 当SAR=1:1时,分辨率宽高比 = DAR,表示帧画面在终端播放时不会产生形变
- 当SAR!=1:1时,分辨率宽高比 != DAR,表示帧画面在终端播放时会产生形变
终端播放形变方式
形变方式通常可以分为三种:
- 保持短边不变,长边缩放
- 保持长边不变,短边缩放
- 长边短边同时缩放
若以样例视频二为例,上述三种形变方式可得:
- 原始画面480x320,短边保持不变,此时H=320,DAR=16/9,得W=320/9*16=569,即长边缩放比为569/480=1.185
- 原始画面480x320,长边边保持不变,此时W=480,DAR=16/9,得H=480/16*9=270,即短边的缩放比为270/320=0.84375
- 根据播放器实际情况发生变化
播放形变带来的水印形变
图片水印通常直接合成在原始帧画面中,故播放端的形变会连带造成水印产生畸变
以上述形变方式1为例,假设为原始视频打上一个40x40的方形水印,在终端播放时,长边会进行1.185倍的缩放,故实际水印显示大小约为47x40,畸变成为一个长方形水印
图片水印畸变的解决方案
在实际的生产应用中,有些需求水印要保持原始的长宽比,不能发生畸变,此时需要对图片水印畸变进行修正
反向修正水印图片
顾名思义,由于畸变发生在播放终端,故可以预测畸变行为,预先将水印图片变形后再压入原始帧画面,预变形图片会按预期畸变后恢复正常
以样例视频二为例,添加40x40的水印,假设采用第一种形变方式:
- 计算可知,原始帧画面横边缩放比为1.185
- 反向压缩水印视频W=40/1.185=34,即将水印图片压缩成为34x40
- 终端播放,根据第一种形变方式,长边缩放,图片水印W’=34*1.185=40,即恢复到40x40的水印图片
第二种形变方式处理方式相同
上述方式存在问题:
如果预测的形变方式与终端实际形变方式不同,可能造成水印图片等比缩放
比如,预测第一种形变方式,实际终端播放采用第二中形变方式:
- 水印图片压缩后34x40
- 终端播放时,短边缩放比为0.84375,播放时水印高H=40*0.84375=34,即水印图片实际播放大小为34x34,即实际水印等比缩放了0.84375倍
而若是终端播放采用第三种形变方式,则水印图片畸变不可预测,故修正后仍可能畸变
(由于播放形变取决的终端行为,故对水印畸变的情况并不能准确预测,不同的畸变模式的修正方式不一样,博主仅能据工作中的实际处理情况给出一些解决方案,欢迎大家指正)