问题描述
参考了手册:VENC模块API手册
frame_info.v_frame.phys_addr[1] = frame_info.v_frame.phys_addr[0] + frame_info.v_frame.width*frame_info.v_frame.height + 1024
1.根据不同宽高增加的物理地址偏是怎么确定的,案例中地址+长宽+常数数字1024,这个常数什么作用,我的1280*720图片要修改为什么
2.encoder.SendFrame(venc_chn,frame_info)是手动设置帧,link = MediaManager.link(sensor.sensor.bind_info()['src'], (VIDEO_ENCODE_MOD_ID, VENC_DEV_ID, VENC_CHN_ID_0))是自动绑定帧,是这样理解吗,他们不能一起
3.上次提问说除了YUV420SP,还支持 ARGB8888、BGRA8888 等格式输入,此时需要rtsp推流,想要把888转换为bgra8888,转化始终不成功,frame_info.pixel_format不知道应该写什么,或是转化有问题,代码如下:
硬件板卡
庐山派
软件版本
CanMV v1.4-2-g873d625(based on Micropython e00a144) on 2025-09-12; k230_canmv_lckfb with K230
硬件板卡
庐山派
软件版本
CanMV v1.4-2-g873d625(based on Micropython e00a144) on 2025-09-12; k230_canmv_lckfb with K230
复现步骤
# 初始化摄像头传感器
sensor = Cam()
# 摄像头镜像翻转
# 通道初始化 / GRAYSCALE
sensor.init(type=Sensor.YUV420SP, capture_size=(1280,720),chn=0,alignment=12,debug_mode=0)
sensor.init(type=Sensor.RGB888, capture_size=(1280,720),chn=1,alignment=0,debug_mode=0)
# sensor.init(type=Sensor.RGBP888, capture_size=(1280,720),chn=2,alignment=0,debug_mode=0)
# sensor.encoder_init()
dis_width, dis_height = sensor.sensor._framesize[1]
Display.init(Display.VIRT, width=dis_width, height=dis_height, to_ide=True)
# 初始化编码器
encoder = Encoder()
# 编码器通道同步图像大小 / 必须在 MediaManager.init() 之前调用
encoder.SetOutBufs(VENC_CHN_ID_0, 8, dis_width, dis_height)
MediaManager.init()
print(f"bind:{sensor.sensor.bind_info()}")
# 必须在 MediaManager.init() 之后调用
# link = MediaManager.link(sensor.sensor.bind_info()['src'], (VIDEO_ENCODE_MOD_ID, VENC_DEV_ID, VENC_CHN_ID_0))
chnAttr = ChnAttrStr(encoder.PAYLOAD_TYPE_H264, encoder.H264_PROFILE_MAIN, dis_width, dis_height)
encoder.Create(VENC_CHN_ID_0, chnAttr)
# 初始化 RTSP
rtspserver = mm.rtsp_server() # 实例化 RTSP 服务器
rtspserver.rtspserver_init(8554)
rtspserver.rtspserver_createsession("test", mm.multi_media_type.media_h264, False)
rtspserver.rtspserver_start()
encoder.Start(VENC_CHN_ID_0)
# 启动摄像头
# sensor.encoder_run()
sensor.run()
print(rtspserver.rtspserver_getrtspurl("test"))
streamData = StreamData() # 码流结构体
if __name__ == "__main__":
# “安全退出点(Exit Point)”,允许脚本在阻塞或长循环中被外部请求安全中断并退出
os.exitpoint(os.EXITPOINT_ENABLE)
try:
while True:
os.exitpoint() # 系统安全退出点
# m_uni.TP(True)
sleep(0.01)
#----------------------------------------------------------------------------------------
# 采集 / 逐渐添加类型
img_gray = sensor.cap_read(0)
img_888 = sensor.cap_read(1)
img_bgra = rgb_to_bgra8888(img_888)
frame_info = k_video_frame_info() # 构造视频帧信息结构体
frame_info.v_frame.width = img_bgra.width()
frame_info.v_frame.height = img_bgra.height()
frame_info.v_frame.pixel_format = image.BGRA8888
frame_info.pool_id = img_bgra.poolid()
frame_info.v_frame.phys_addr[0] = img_bgra.phyaddr()
frame_info.v_frame.phys_addr[1] = frame_info.v_frame.phys_addr[0] + frame_info.v_frame.width*frame_info.v_frame.height
encoder.SendFrame(venc_chn,frame_info)
encoder.GetStream(venc_chn, streamData) # 获取一帧码流
for pack_idx in range(0, streamData.pack_cnt):
stream_data = uctypes.bytearray_at(streamData.data[pack_idx], streamData.data_size[pack_idx])
fo.write(stream_data) # 码流写文件
print("stream size: ", streamData.data_size[pack_idx], "stream type: ", streamData.stream_type[pack_idx])
encoder.ReleaseStream(venc_chn, streamData) # 释放一帧码流
encoder.SendFrame(venc_chn,frame_info)
# 获取编码码流
encoder.GetStream(VENC_CHN_ID_0, streamData)
# stream_info("after", streamData)
# 推流
for idx in range(streamData.pack_cnt):
data = bytes(uctypes.bytearray_at(streamData.data[idx], streamData.data_size[idx]))
rtspserver.rtspserver_sendvideodata("test", data, streamData.data_size[idx], 1000)
# 释放码流
encoder.ReleaseStream(VENC_CHN_ID_0, streamData)
#----------------------------------------------------------------------------------------
# 图像显示部分 / 关闭时display_img会变为None引起属性空报错
# display_img = img_gray
display_img = img_888
# display_img = img_p888 # 不宜直接展示,用于运算
# 图像缩放&显示
if display_img:
xx=int((dis_width-display_img.width())/2)
yy=int((dis_height-display_img.height())/2)
Display.show_image(display_img,x=xx,y=yy)
finally:
print("即将停止")
# 清理操作
sensor.stop() # 停止摄像头
# sensor.encoder_stop() # 停止编码器
# del link
encoder.Stop(VENC_CHN_ID_0)
encoder.Destroy(VENC_CHN_ID_0)
MediaManager.deinit() # 反初始化媒体管理器
# 停止推流
rtspserver.rtspserver_stop()
rtspserver.rtspserver_deinit()
# gc.collect()
print("test 停止")
硬件板卡
庐山派
软件版本
CanMV v1.4-2-g873d625(based on Micropython e00a144) on 2025-09-12; k230_canmv_lckfb with K230
硬件板卡
庐山派
软件版本
CanMV v1.4-2-g873d625(based on Micropython e00a144) on 2025-09-12; k230_canmv_lckfb with K230

运行时会卡住,只能按键复位