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/video0fourcc、分辨率、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.wavhw: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 的职责完全不同。
