BK7256是BEKEN博通一个集成了WiFi 6和低功耗蓝牙BLE的双核32位RISC-V架构SOC,支持摄像头,可使用wifi局域网UDP视频传输。本例使用到摄像头GC2145。
1.创建UDP任务。
bk_err_t user_skinhelper_udp_init(void)
{
int ret;
LOGI("app_demo_udp_init\\n");
if (!user_skinhelper_udp_hdl)
{
ret = rtos_create_thread(&user_skinhelper_udp_hdl,
4,
"skinhelper",
(beken_thread_function_t)user_skinhelper_udp_main,
1024 * 4,//2
(beken_thread_arg_t)NULL);
if (ret != kNoErr)
{
LOGE("Error: Failed to create spidma_intfer: %d\\n", ret);
return kGeneralErr;
}
}
return kNoErr;
}
2在任务里实现初始化及根据需要创建socket与端口
static void user_skinhelper_udp_main(beken_thread_arg_t data)
{
GLOBAL_INT_DECLARATION();
int maxfd, ret = 0;
int rcv_len = 0;
// struct sockaddr_in user_skinhelper_data_udp_remote;
socklen_t srvaddr_len = 0;
fd_set watchfd;
struct timeval timeout;
u8 *rcv_buf = NULL;
LOGI("user_skinhelper_udp_main entry\\n");
(void)(data);
rcv_buf = (u8 *) os_malloc((APP_DEMO_UDP_RCV_BUF_LEN + 1) * sizeof(u8));
if (!rcv_buf)
{
LOGE("udp os_malloc failed\\n");
goto out;
}
// for image transfer
user_skinhelper_image_udp_remote = (struct sockaddr_in *)os_malloc(sizeof(struct sockaddr_in));
if (!user_skinhelper_image_udp_remote)
{
LOGE("udp os_malloc failed\\n");
goto out;
}
user_skinhelper_udp_image_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (user_skinhelper_udp_image_fd == -1)
{
LOGE("vo socket failed\\n");
goto out;
}
user_skinhelper_image_udp_remote->sin_family = AF_INET;
user_skinhelper_image_udp_remote->sin_port = htons(USER_SKINHELPER_UDP_IMAGE_PORT);
user_skinhelper_image_udp_remote->sin_addr.s_addr = htonl(INADDR_ANY);
srvaddr_len = (socklen_t)sizeof(struct sockaddr_in);
if (bind(user_skinhelper_udp_image_fd, (struct sockaddr *)user_skinhelper_image_udp_remote, srvaddr_len) == -1)
{
LOGE("bind failed\\n");
goto out;
}
printf("socket user_skinhelper_udp_image_fd:%d,port:%d\\n",user_skinhelper_udp_image_fd,USER_SKINHELPER_UDP_IMAGE_PORT);
user_skinhelper_remote = (struct sockaddr_in *)os_malloc(sizeof(struct sockaddr_in));
if (!user_skinhelper_remote)
{
LOGE("udp os_malloc failed\\n");
goto out;
}
// for video transfer
user_skinhelper_udp_video_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (user_skinhelper_udp_video_fd == -1)
{
LOGE("socket failed\\n");
goto out;
}
user_skinhelper_remote->sin_family = AF_INET;
user_skinhelper_remote->sin_port = htons(USER_SKINHELPER_UDP_VIDEO_PORT);
user_skinhelper_remote->sin_addr.s_addr = htonl(INADDR_ANY);
srvaddr_len = (socklen_t)sizeof(struct sockaddr_in);
if (bind(user_skinhelper_udp_video_fd, (struct sockaddr *)user_skinhelper_remote, srvaddr_len) == -1)
{
LOGE("bind failed\\n");
goto out;
}
printf("socket user_skinhelper_udp_video_fd:%d,port:%d\\n",user_skinhelper_udp_video_fd,USER_SKINHELPER_UDP_VIDEO_PORT);
maxfd = (user_skinhelper_udp_image_fd > user_skinhelper_udp_video_fd) ? user_skinhelper_udp_image_fd : user_skinhelper_udp_video_fd;
// for data transfer
user_skinhelper_udp_data_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (user_skinhelper_udp_data_fd == -1)
{
LOGE("socket failed\\n");
goto out;
}
user_skinhelper_data_udp_remote = (struct sockaddr_in *)os_malloc(sizeof(struct sockaddr_in));
if (!user_skinhelper_data_udp_remote)
{
LOGE("user_skinhelper_data_udp_remote os_malloc failed\\n");
goto out;
}
user_skinhelper_data_udp_remote->sin_family = AF_INET;
user_skinhelper_data_udp_remote->sin_port = htons(USER_SKINHELPER_UDP_DATA_PORT);
user_skinhelper_data_udp_remote->sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(user_skinhelper_udp_data_fd, (struct sockaddr *)user_skinhelper_data_udp_remote, srvaddr_len) == -1)
{
LOGE("bind failed\\n");
goto out;
}
printf("socket user_skinhelper_udp_data_fd:%d,port:%d\\n",user_skinhelper_udp_data_fd,USER_SKINHELPER_UDP_DATA_PORT);
maxfd = (maxfd > user_skinhelper_udp_data_fd) ? maxfd : user_skinhelper_udp_data_fd;
timeout.tv_sec = APP_DEMO_UDP_SOCKET_TIMEOUT / 1000;
timeout.tv_usec = (APP_DEMO_UDP_SOCKET_TIMEOUT % 1000) * 1000;
GLOBAL_INT_DISABLE();
user_skinhelper_udp_video_romote_connected = 0;
user_skinhelper_udp_run = 1;
#if USER_SKINHELPER_EN_IMAGE_TRANSFER
user_skinhelper_udp_image_romote_connected = 0;
#endif
GLOBAL_INT_RESTORE();
#if 0
app_msg_send(UDP_BOARDCAST,NULL,0);
user_udp_timer_init();
// user_video_start();
// user_photo_start();
#endif
user_udp_timer_init();
//bk_timer_start(TVIDEO_TIMER_CHANNEL, TVIDEO_TIMER_VALUE, tvideo_timer_check_callback);
while (user_skinhelper_udp_run)
{
FD_ZERO(&watchfd);
FD_SET(user_skinhelper_udp_video_fd, &watchfd);
FD_SET(user_skinhelper_udp_data_fd, &watchfd);
#if USER_SKINHELPER_EN_IMAGE_TRANSFER
FD_SET(user_skinhelper_udp_image_fd, &watchfd);
#endif
//DBD("wait for select\\n");
ret = select(maxfd + 1, &watchfd, NULL, NULL, &timeout);
if (ret < 0)
{
LOGE("select ret:%d\\n", ret);
break;
}
else
{
// is video fd, data transfer
if (FD_ISSET(user_skinhelper_udp_video_fd, &watchfd))
{
rcv_len = recvfrom(user_skinhelper_udp_video_fd, rcv_buf, APP_DEMO_UDP_RCV_BUF_LEN, 0,
(struct sockaddr *)user_skinhelper_remote, &srvaddr_len);
if (rcv_len <= 0)
{
// close this socket
LOGE("recv close fd:%d\\\\n", user_skinhelper_udp_video_fd);
break;
}
else
{
rcv_len = (rcv_len > APP_DEMO_UDP_RCV_BUF_LEN) ? APP_DEMO_UDP_RCV_BUF_LEN : rcv_len;
rcv_buf[rcv_len] = 0;
user_skinhelper_udp_video_receiver(rcv_buf, rcv_len, user_skinhelper_remote);
}
}
else if (FD_ISSET(user_skinhelper_udp_data_fd, &watchfd))
{
rcv_len = recvfrom(user_skinhelper_udp_data_fd, rcv_buf, APP_DEMO_UDP_RCV_BUF_LEN, 0,
(struct sockaddr *)user_skinhelper_data_udp_remote, &srvaddr_len);
if (rcv_len <= 0)
{
// close this socket
LOGE("recv close fd:%d\\\\n", user_skinhelper_udp_data_fd);
break;
}
else
{
rcv_len = (rcv_len > APP_DEMO_UDP_RCV_BUF_LEN) ? APP_DEMO_UDP_RCV_BUF_LEN : rcv_len;
rcv_buf[rcv_len] = 0;
user_skinhelper_udp_data_receiver(rcv_buf, rcv_len,user_skinhelper_data_udp_remote);
}
}
#if USER_SKINHELPER_EN_IMAGE_TRANSFER
if (FD_ISSET(user_skinhelper_udp_image_fd, &watchfd))
{
rcv_len = recvfrom(user_skinhelper_udp_image_fd, rcv_buf, APP_DEMO_UDP_RCV_BUF_LEN, 0,
(struct sockaddr *)user_skinhelper_image_udp_remote, &srvaddr_len);
if (rcv_len <= 0)
{
// close this socket
LOGE("recv close fd:%d\\n", user_skinhelper_udp_image_fd);
break;
}
else
{
rcv_len = (rcv_len > APP_DEMO_UDP_RCV_BUF_LEN) ? APP_DEMO_UDP_RCV_BUF_LEN : rcv_len;
rcv_buf[rcv_len] = 0;
user_skinhelper_udp_image_receiver(rcv_buf, rcv_len, user_skinhelper_image_udp_remote);
}
}
#endif // USER_SKINHELPER_EN_IMAGE_TRANSFER
}
}
out:
LOGE("user_skinhelper_udp_main exit %d\\n", user_skinhelper_udp_run);
media_app_transfer_close();
#if (defined(CONFIG_CAMERA) || defined(CONFIG_USB_UVC))
media_app_camera_close(APP_CAMERA_DVP_JPEG);
media_app_camera_close(APP_CAMERA_UVC_MJPEG);
#endif
#if AUDIO_TRANSFER_ENABLE
/* deinit audio transfer driver */
bk_aud_intf_drv_deinit();
#endif
if (rcv_buf)
{
os_free(rcv_buf);
rcv_buf = NULL;
}
#if USER_SKINHELPER_EN_IMAGE_TRANSFER
if (user_skinhelper_udp_image_fd != -1)
{
close(user_skinhelper_udp_image_fd);
user_skinhelper_udp_image_fd = -1;
}
if (user_skinhelper_image_udp_remote)
{
os_free(user_skinhelper_image_udp_remote);
user_skinhelper_image_udp_remote = NULL;
}
#endif // USER_SKINHELPER_EN_IMAGE_TRANSFER
if (user_skinhelper_remote)
{
os_free(user_skinhelper_remote);
user_skinhelper_remote = NULL;
}
if (user_skinhelper_udp_video_fd != -1)
{
close(user_skinhelper_udp_video_fd);
user_skinhelper_udp_video_fd = -1;
}
if (user_skinhelper_udp_data_fd != -1)
{
close(user_skinhelper_udp_data_fd);
user_skinhelper_udp_data_fd = -1;
}
GLOBAL_INT_DISABLE();
user_skinhelper_udp_video_romote_connected = 0;
user_skinhelper_udp_run = 0;
#if USER_SKINHELPER_EN_IMAGE_TRANSFER
user_skinhelper_udp_image_romote_connected = 0;
#endif
GLOBAL_INT_RESTORE();
user_skinhelper_udp_hdl = NULL;
rtos_delete_thread(NULL);
}
3.在上面的user_skinhelper_udp_video_receiver
,user_skinhelper_udp_data_receiver
,user_skinhelper_udp_image_receiver
分别实现视频、通讯协议数据、图片的传输处理。BK有相应的调试APP,可以配合使用。此功能需连接上WIFI,并获取到路由分配IP,与上位机(APP等)在局域网内实现双向通讯,视频、图片传输。
更多回帖