问题描述
使用01Studio K230mini, 我有一个很简单的需求,边录视频边显示,请问应该用什么方法来实现呢?
已经尝试的方法:
-
直接使用 MP4Container 来采集,好像没办法实时显示吧,还是我的使用方式不对?
遇到的问题有:
1) 把 yuv420sp_img 复制一份并转换成显示需要的 RGB565 格式, 但是使用转换图片格式转换方法
img2 = yuv420sp_img.to_rgb565(copy=True)
一直失败,经过查看得知支持的图像格式 没有YUV420SP, 难道是这个原因?
2) 把采集和编码的数据格式都改成 RGB565 , 碰到的问题
encoder.GetStream(venc_chn, streamData) 无法获取到编码数据, 可能是输入的数据有问题,请问应该如何改?
===============================================================================================================
def stream_venc_test(file_name,width=1280, height=720):
print("venc_test start")
venc_chn = VENC_CHN_ID_0
width = ALIGN_UP(width, 16)
venc_payload_type = K_PT_H264
# 判断文件类型
suffix = file_name.split('.')[-1]
if suffix == '264':
venc_payload_type = K_PT_H264
elif suffix == '265':
venc_payload_type = K_PT_H265
else:
print("Unknown file extension")
return
# 初始化sensor
sensor = Sensor(id=0)
sensor.reset()
# 设置camera 输出buffer
# set chn0 output size
sensor.set_framesize(width = width, height = height, alignment=12)
# set chn0 output format
sensor.set_pixformat(Sensor.RGB565)
Display.init(Display.ST7701, width=g_display_width, height=g_display_height, osd_num=2, to_ide=False) # 启用IDE显示功能 / Enable IDE display function
# 实例化video encoder
encoder = Encoder()
# 设置video encoder 输出buffer
encoder.SetOutBufs(venc_chn, 8, width, height)
# init media manager
MediaManager.init()
if (venc_payload_type == K_PT_H264):
chnAttr = ChnAttrStr(encoder.PAYLOAD_TYPE_H264, encoder.H264_PROFILE_MAIN, width, height)
elif (venc_payload_type == K_PT_H265):
chnAttr = ChnAttrStr(encoder.PAYLOAD_TYPE_H265, encoder.H265_PROFILE_MAIN, width, height)
streamData = StreamData()
# 创建编码器
encoder.Create(venc_chn, chnAttr)
# 开始编码
encoder.Start(venc_chn)
# 启动camera
sensor.run()
frame_count = 0
print("save stream to file: ", file_name)
yuv420sp_img = None
frame_info = k_video_frame_info()
with open(file_name, "wb") as fo:
try:
while True:
os.exitpoint()
yuv420sp_img = sensor.snapshot(chn=CAM_CHN_ID_0)
if (yuv420sp_img == -1):
print("yuv420sp_img error")
continue
show_img = image.Image(g_display_width, g_display_height, image.RGB565)
#print("create show_image success")
#img2 = image.Image(g_image_width, g_image_height, image.RGB565)
#print("create img2 success")
#img2 = yuv420sp_img.to_rgb565(copy=True)
#print("convert show_image success")
show_img.draw_image(yuv420sp_img, 0, 0, g_display_width / g_image_width, g_display_height / g_image_height)
print("draw show_image success")
Display.show_image(show_img, 0, 0, Display.LAYER_OSD1, 150)
print("display show_image success")
frame_info.v_frame.width = yuv420sp_img.width()
frame_info.v_frame.height = yuv420sp_img.height()
frame_info.v_frame.pixel_format = Sensor.RGB565
frame_info.pool_id = yuv420sp_img.poolid()
frame_info.v_frame.phys_addr[0] = yuv420sp_img.phyaddr()
#frame_info.v_frame.phys_addr[1] = yuv420sp_img.phyaddr(1)
if (yuv420sp_img.width() == 800 and yuv420sp_img.height() == 480):
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
elif (yuv420sp_img.width() == 1920 and yuv420sp_img.height() == 1080):
frame_info.v_frame.phys_addr[1] = frame_info.v_frame.phys_addr[0] + frame_info.v_frame.width*frame_info.v_frame.height + 3072
elif (yuv420sp_img.width() == 640 and yuv420sp_img.height() == 360):
frame_info.v_frame.phys_addr[1] = frame_info.v_frame.phys_addr[0] + frame_info.v_frame.width*frame_info.v_frame.height + 3072
else:
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)
print("encoder sendframe success")
encoder.GetStream(venc_chn, streamData) # 无法获取编码数据
print("encoder getStream success")
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) # 释放一帧码流
frame_count += 1
print("frame_count = ", frame_count)
if frame_count >= 200:
break
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
import sys
sys.print_exception(e)
gc.collect()
# 停止camera
sensor.stop()
# 停止编码
encoder.Stop(venc_chn)
# 销毁编码器
encoder.Destroy(venc_chn)
Display.deinit()
# 清理buffer
MediaManager.deinit()
print("venc_test stop")
硬件板卡
01Studio K230mini
软件版本
CanMV_K230_01Studio_micropython_v1.4-16-g3a2aed8_nncase_v2.9.0.img
硬件板卡
01Studio K230mini
软件版本
CanMV_K230_01Studio_micropython_v1.4-16-g3a2aed8_nncase_v2.9.0.img