doubao_chat/apps/wifi_ipc/wifi/stream/video_rt_rtp.c

218 lines
4.7 KiB
C

#include "rtp/rtp_h264.h"
#include "sys_common.h"
#include "system/spinlock.h"
#include "os/os_api.h"
#include "server/rt_stream_pkg.h"
#include "app_config.h"
#include "lwip.h"
#include "lwip/sockets.h"
#include "sock_api/sock_api.h"
#include "os/os_api.h"
#include "stream_core.h"
/*
UDP端口:2224
UDP 每片数据包 格式:
|1byte 类型 | 1byte 保留 | 2byte payload长度 | 4byte 序号 | 4byte 帧大小 | 4byte 偏移 | 4byte 时间戳 | payload |
*/
#if __SDRAM_SIZE__ >= (8 * 1024 * 1024)
#define UDP_SEND_BUF_SIZE (44*1472)
#else
#define UDP_SEND_BUF_SIZE (16*1472)
#endif
#define VIDEO_FRQ_60HZ 60
#define VIDEO_FRQ_30HZ 30
#define VIDEO_FRQ_15HZ 15
#define MAX_PAYLOAD (1472-sizeof(struct frm_head))//最后4字节属于h264流的
static u32 video_timestramp = 0;
static u32 audio_timestramp = 0;
static u32 seq = 1;
static u32 aux_frame_cnt = 0;
extern int atoi(const char *__nptr);
static int path_analyze(struct rt_stream_info *info, const *path)
{
char *tmp = NULL;
char *tmp2 = NULL;
char ip[15] = {0};
u16 port = 0;
tmp = strstr(path, "rtp://");
if (!tmp) {
return -1;
}
tmp += strlen("rtp://");
tmp2 = strchr(tmp, ':');
printf("tmp=%s len=%d\n", tmp, tmp2 - tmp);
strncpy(ip, tmp, tmp2 - tmp);
port = atoi(tmp2 + 1);
printf("remote ip:%s port:%d\n", ip, port);
info->addr.sin_family = AF_INET;
info->addr.sin_addr.s_addr = inet_addr(ip);
info->addr.sin_port = htons(port);
return 0;
}
static void *get_sock_handler(int (*cb_func)(enum sock_api_msg_type type, void *priv), void *priv)
{
void *fd = NULL;
if (0) { //条件链表
//add P2P code
} else {
fd = sock_reg(AF_INET, SOCK_DGRAM, 0, cb_func, priv);
if (fd == NULL) {
printf("%s %d->Error in socket()\n", __func__, __LINE__);
return NULL;
}
u32 millsec = 100;
sock_setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const void *)&millsec, sizeof(millsec));
return fd;
}
}
static struct rt_stream_info *net_rt_vpkg_open(const char *path, const char *mode)
{
int flags = 0;
int err;
struct rt_stream_info *info = (struct rt_stream_info *)calloc(1, sizeof(struct rt_stream_info));
if (info == NULL) {
printf("%s %d->Error in malloc()\n", __func__, __LINE__);
return NULL;
}
info->udp_send_buf = (char *)malloc(UDP_SEND_BUF_SIZE);
if (info->udp_send_buf == NULL) {
printf("%s %d->Error in malloc()\n", __func__, __LINE__);
free(info);
return NULL;
}
if (path_analyze(info, path)) {
printf("%s %d->Error in path_analyze\n", __func__, __LINE__);
free(info);
return NULL;
}
info->fd = get_sock_handler(NULL, NULL);
if (!info->fd) {
printf("%s %d->Error get_sock_handler\n", __func__, __LINE__);
free(info);
return NULL;
}
return info;
err1:
free(info->udp_send_buf);
free(info);
return NULL;
}
static int net_rt_vpkg_close(struct rt_stream_info *info)
{
video_timestramp = 0;
audio_timestramp = 0;
aux_frame_cnt = 0;
//os_sem_del(&mutex,OS_DEL_ALWAYS);
sock_unreg(info->fd);
free(info->udp_send_buf);
free(info);
return 0;
}
static u32 old_times = 0;
static u32 new_times = 0;
static int net_rt_send_frame(struct rt_stream_info *info, char *buffer, size_t len, u8 type)
{
struct rt_stream_cli_info *cli = NULL;
struct list_head *pos = NULL;
int ret;
int find = 0;
char *tmp = NULL;
int sps_data_len = 0;
int pps_data_len = 0;
tmp = buffer + 4;
if (*tmp == 0x67) {
memcpy(&sps_data_len, buffer, 4);
sps_data_len = htonl(sps_data_len);
memcpy(&pps_data_len, buffer + 4 + sps_data_len, 4);
pps_data_len = htonl(pps_data_len);
ret = rtp_h264_send_frame(info, buffer + 4, sps_data_len, 30);
if (ret < 0) {
puts("rt_stream_sent error!\n");
return -1;
}
ret = rtp_h264_send_frame(info, buffer + sps_data_len + 4 + 4, pps_data_len, 30);
if (ret < 0) {
puts("rt_stream_sent error!\n");
return -1;
}
ret = rtp_h264_send_frame(info, buffer + sps_data_len + pps_data_len + 12, len - sps_data_len - pps_data_len - 12, 30);
if (ret < 0) {
puts("rt_stream_sent error!\n");
return -1;
}
} else {
ret = rtp_h264_send_frame(info, buffer + 4, len - 4, 30);
if (ret < 0) {
puts("rt_stream_sent error!\n");
return -1;
}
}
return len;
}
REGISTER_NET_VIDEO_STREAM_SUDDEV(rtp_video_stream_sub) = {
.name = "rtp",
.open = net_rt_vpkg_open,
.write = net_rt_send_frame,
.close = net_rt_vpkg_close,
};