218 lines
4.7 KiB
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,
|
|
};
|
|
|
|
|