h264 – H.264 编码
h264 模块把图像编码成 Annex-B H.264 NAL 单元,可用于将视频录制到存储,或送入 rtsp – RTSP 推流 服务器。该模块可用于 ESP32-P4 构建。
编码单帧图像
import sensor, h264
enc = h264.H264Encoder(320, 240, fps=15)
nal = enc.encode(sensor.snapshot())
print("bytes:", len(nal), "keyframe:", enc.keyframe())
enc.close()
编码器尺寸必须与每一帧输入图像一致。encode() 以 bytes 返回一帧编码数据,keyframe() 用于判断最近编码的图像是否为 IDR/I 帧。
录制 H.264 裸码流
import sensor, h264
FRAME_COUNT = 300
OUT_PATH = "/sdcard/out.h264"
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=1000)
first = sensor.snapshot()
enc = h264.H264Encoder(
first.width(),
first.height(),
fps=15,
bitrate=1_500_000,
gop=15,
)
try:
with open(OUT_PATH, "wb") as output:
output.write(enc.encode(first))
for _ in range(FRAME_COUNT - 1):
output.write(enc.encode(sensor.snapshot()))
finally:
enc.close()
该示例写入不包含 MP4 容器的 Annex-B 基本码流,可使用 ffplay out.h264 播放,或在主机上重新封装。bitrate 表示目标每秒比特数,gop 表示以帧为单位的关键帧间隔,QP 上下限则控制允许的质量与体积范围。
资源与吞吐量注意事项
应为固定分辨率创建一个编码器,并在整个视频流中持续复用,使用完毕后再将其关闭。如果采集或存储无法维持配置的帧率和码率,应降低分辨率、帧率或码率,而不是反复创建编码器。
Classes
- class h264.H264Encoder(width, height, *, fps=..., gop=..., bitrate=..., qp_min=..., qp_max=...)
Hardware-accelerated H.264 video encoder. Feed it images frame by frame with encode(); it returns Annex-B NAL units ready to mux into a file or stream over the network (see the rtsp module).
Open an encoder for a fixed frame size.
- 参数:
width – frame width in pixels.
height – frame height in pixels.
fps – target frame rate; also the default GOP length.
gop – keyframe (IDR) interval in frames; 0 selects one keyframe per second (== fps).
bitrate – target bitrate in bits per second; 0 auto-selects width*height*fps.
qp_min – lower quantization-parameter bound (better quality, larger frames).
qp_max – upper quantization-parameter bound (lower quality, smaller frames).
- encode(image)
Encode one image and return its Annex-B NAL units as bytes.
- 参数:
image – source frame; its size must match the encoder width/height.
- keyframe()
Return True if the most recently encoded frame was a keyframe (IDR/I).
- close()
Release the encoder. Using the object afterwards raises OSError.