Skip to content

约 2 分钟阅读

02. 音视频参数与内存格式 ​

摄像头协商失败或推流带宽不够时,最先要做的是把参数换算成数据量。分辨率描述一帧有多少像素,帧率描述每秒有多少帧,码率描述压缩后每秒传多少比特;它们不是同一个指标。

视频参数 ​

1920×1080 表示每帧有 2,073,600 个像素;30 FPS 表示每秒产生 30 帧。压缩视频的码率还受画面复杂度、编码器、GOP、质量参数和运动情况影响,同一分辨率可以有完全不同的码率和观感。

颜色表示也有层次:RGB 适合显示和图像处理,YUV/YCbCr 把亮度和色度分开。YUV 4:2:0 通过降低色度采样密度减少数据量;NV12 是一种具体的半平面内存布局,前面是完整 Y 平面,后面是交错 UV 平面。看到 NV12 时,应同时记录 width、height、stride(或 bytesperline)和实际 buffer 大小。

8 bit、无 padding 的 NV12 单帧约为:

text
Y:  width × height
UV: width × height ÷ 2
总计 ≈ width × height × 1.5 字节

以 1920×1080、30 FPS 为例,一帧约 3,110,400 字节(约 2.97 MiB),原始数据吞吐约 93.3 MB/s。驱动为了对齐行宽时,真实大小可能大于这个理论值,不能用公式替代 sizeimage。

V4L2 设备先查询能力,再开始采集:

bash
v4l2-ctl --list-formats-ext -d /dev/video0
v4l2-ctl --get-fmt-video -d /dev/video0

fourcc、分辨率、bytesperline 和 sizeimage 必须和后续转换或编码器的输入合同一致。YUYV、MJPEG 和 NV12 不是只改一个字符串就能互换的格式。

音频参数 ​

PCM 是采样和量化后的未压缩数字音频。采样率决定每秒取多少个样本,位深决定每个样本的刻度,声道数决定同时记录几路信号。未压缩数据率可以按下式估算:

text
每秒字节数 = 采样率 × (位深 ÷ 8) × 声道数

48 kHz、16 bit、双声道的 PCM 为 48000 × 2 × 2 = 192000 字节/秒,也就是 1.536 Mbit/s。这个数字是原始 PCM 吞吐,不能当作 AAC 或 MP3 的压缩码率。

在 Linux 上先查看声卡能力,再选择明确格式录音:

bash
arecord -l
aplay -l
arecord -D hw:1,0 -t wav -f S16_LE -r 48000 -c 2 -d 5 capture.wav

hw:1,0 只是示例设备,必须替换成实际查询结果。硬件不支持目标采样率时,记录原生能力并显式重采样,不要用软件转换掩盖设备协商失败。

Buffer、带宽与延迟 ​

Buffer 同时决定稳定性和等待时间。视频每帧约 3 MB 时,排队 10 帧就可能占用约 30 MB;音频按 20 ms 一帧时,16 kHz、单声道、16 bit 一帧是 16000 × 0.02 × 2 = 640 字节。队列应有明确容量,满了以后选择丢弃、阻塞、落盘或降低质量,不能无限增长。

实时系统还要记录每个环节的排队深度和时间戳。只看平均帧率会漏掉偶发的长尾延迟;应同时看丢帧、underrun/overrun、CPU/RSS、DMA buffer 和显示等待。

常见误区 ​

  • DPI 是打印或显示像素密度概念,不能替代视频分辨率。
  • 提高码率不能恢复已经丢失的细节,源视频质量和编码参数同样重要。
  • 采样率更高不保证听感更好,录制条件、编码器和播放设备也会改变结果。
  • stride 大于 width 时,按 width 计算的理论大小不等于驱动实际 buffer 大小。

下一篇进入编码和容器,解释为什么同样是 1080p,H.264、H.265、MP4 和 HLS 的职责完全不同。

别急,先让缓存热一下。