#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>
#include "rtsputils.h"
#include "rtspservice.h"
#include "rtputils.h"
#include "ringfifo.h"
struct profileid_sps_pps{
char base64profileid[10];
char base64sps[524];
char base64pps[524];
};
pthread_mutex_t mut;
#define MAX_SIZE 1024*1024*200
#define SDP_EL "\r\n"
#define RTSP_RTP_AVP "RTP/AVP"
struct profileid_sps_pps psp; //存base64编码的profileid sps pps
StServPrefs stPrefs;
char *title = "Magnimage W4000 RTSP Server!";
extern int num_conn_1;
extern int num_conn_2;
int g_s32Maxfd = 0;//最大轮询id号
int g_s32DoPlay_1 = 0;
int g_s32DoPlay_2 = 0;
uint32_t s_u32StartPort_1=RTP_DEFAULT_PORT;
uint32_t s_u32StartPort_2=RTP_DEFAULT_PORT + 1000;
uint32_t s_uPortPool_1[MAX_CONNECTION];//RTP端口
uint32_t s_uPortPool_2[MAX_CONNECTION];
extern int stop_schedule_1;
extern int stop_schedule_2;
int g_s32Quit_1 = 0;//退出全局变量
int g_s32Quit_2 = 0;
void RTP_port_pool_init(int port, int rtsp_num);
int UpdateSpsOrPps(unsigned char *data,int frame_type,int len);
/**************************************************************************************************
**
**
**
**************************************************************************************************/
void PrefsInit(int port)
{
int l;
//设置服务器信息全局变量
stPrefs.port = port;
strcpy(stPrefs.hostname, title);
gethostname(stPrefs.hostname,sizeof(stPrefs.hostname));
l=strlen(stPrefs.hostname);
if (getdomainname(stPrefs.hostname+l+1,sizeof(stPrefs.hostname)-l)!=0)
{
stPrefs.hostname[l]='.';
}
#ifdef RTSP_DEBUG
printf("\n");
printf("hostname is: %s\n", stPrefs.hostname);
printf("rtsp listening port is: %d\n", port);
printf("rtsp://hostIP:%d/h264 to play this\n",port);
printf("\n");
#endif
}
/**************************************************************************************************
**
**
**
**************************************************************************************************/
//为缓冲分配空间
void RTSP_initserver(RTSP_buffer *rtsp, int fd)
{
rtsp->fd = fd;
rtsp->session_list = (RTSP_session *) calloc(1, sizeof(RTSP_session));
rtsp->session_list->session_id = -1;
}
/**************************************************************************************************
**
**
**
**************************************************************************************************/
//为RTP准备两个端口
int RTP_get_port_pair(port_pair *pair, int rtsp_num)
{
int i;
if(rtsp_num == 0)
{
for (i=0; i<MAX_CONNECTION; ++i)
{
if (s_uPortPool_1[i]!=0)
{
pair->RTP=(s_uPortPool_1[i]-s_u32StartPort_1)*2+s_u32StartPort_1;
pair->RTCP=pair->RTP+1;
printf("get port0: %d\n",s_uPortPool_1[i]);
s_uPortPool_1[i]=0;
return ERR_NOERROR;
} else {
printf("get port0 Err %d, num = %d\n",s_uPortPool_1[i],i);
}
}
}
else if(rtsp_num == 1)
{
for (i=0; i<MAX_CONNECTION; ++i)
{
if (s_uPortPool_2[i]!=0)
{
pair->RTP=(s_uPortPool_2[i]-s_u32StartPort_2)*2+s_u32StartPort_2;
pair->RTCP=pair->RTP+1;
printf("get port1: %d\n",s_uPortPool_2[i]);
s_uPortPool_2[i]=0;
return ERR_NOERROR;
} else {
printf("get port1 Err %d, num = %d\n",s_uPortPool_2[i],i);
}
}
}
return ERR_GENERIC;
}
/**************************************************************************************************
**
**
**
**************************************************************************************************/
void AddClient(RTSP_buffer **ppRtspList, int fd)
{
RTSP_buffer *pRtsp=NULL,*pRtspNew=NULL;
#ifdef RTSP_DEBUG
fprintf(stderr, "%s, %d\n", __FUNCTION__, __LINE__);
#endif
//在链表头部插入第一个元素
if (*ppRtspList==NULL)
{
/*分配空间*/
if ( !(*ppRtspList=(RTSP_buffer*)calloc(1,sizeof(RTSP_buffer)) ) )
{
fprintf(stderr,"alloc memory error %s,%i\n", __FILE__, __LINE__);
return;
}
pRtsp = *ppRtspList;
}
else
{
//向链表中插入新的元素
for (pRtsp=*ppRtspList; pRtsp!=NULL; pRtsp=pRtsp->next)
{
pRtspNew=pRtsp;
}
/*在链表尾部插入*/
if (pRtspNew!=NULL)
{
if ( !(pRtspNew->next=(RTSP_buffer *)calloc(1,sizeof(RTSP_buffer)) ) )
{
fprintf(stderr, "error calloc %s,%i\n", __FILE__, __LINE__);
return;
}
pRtsp=pRtspNew->next;
pRtsp->next=NULL;
}
}
//设置最大轮询id号
if(g_s32Maxfd < fd)
{
g_s32Maxfd = fd;
}
/*初始化新添加的客户端*/
RTSP_initserver(pRtsp,fd);
fprintf(stderr,"Incoming RTSP connection accepted on socket: %d\n",pRtsp->fd);
}
/**************************************************************************************************
**
**
**
**************************************************************************************************/
/*根据缓冲区的内容,填充后边两个长度数据,检查缓冲区中消息的完整性
* return -1 on ERROR
* return RTSP_not_full (0) if a full RTSP message is NOT present in the in_buffer yet.
* return RTSP_method_rcvd (1) if a full RTSP message is present in the in_buffer and is
* ready to be handled.
* return RTSP_interlvd_rcvd (2) if a complete RTP/RTCP interleaved packet is present.
* terminate on really ugly cases.
*/
int RTSP_full_msg_rcvd(RTSP_buffer *rtsp, int *hdr_len, int *body_len)
{
int eomh; /* end of message header found */
int mb; /* message body exists */
int tc; /* terminator count */
int ws; /* white space */
unsigned int ml; /* total message length including any message body */
int bl; /* message body length */
char c; /* character */
int control;
char *p;
/*是否存在交叉存取的二进制rtp/rtcp数据包,参考RFC2326-10.12*/
if (rtsp->in_buffer[0] == '$')
{
uint16_t *intlvd_len = (uint16_t *)&rtsp->in_buffer[2]; /*跳过通道标志符*/
/*转化为主机字节序,因为长度是网络字节序*/
if ( (bl = ntohs(*intlvd_len)) <= rtsp->in_size)
{
fprintf(stderr,"Interleaved RTP or RTCP packet arrived (len: %hu).\n", bl);
if (hdr_len)
*hdr_len = 4;
if (body_len)
*body_len = bl;
return RTSP_interlvd_rcvd;
}
else
{
/*缓冲区不能完全存放数据*/
fprintf(stderr,"Non-complete Interleaved RTP or RTCP packet arrived.\n");
return RTSP_not_full;
}
}
eomh = mb = ml = bl = 0;
while (ml <= rtsp->in_size)
{
/* look for eol. */
/*计算不包含回车、换行在内的所有字符数*/
control = strcspn(&(rtsp->in_buffer[ml]), "\r\n");
if(control > 0)
ml += control;
else
return ERR_GENERIC;
/* haven't received the entire message yet. */
if (ml > rtsp->in_size)
return RTSP_not_full;
/* 处理终结符,判读是否是消息头的结束*/
tc = ws = 0;
while (!eomh && ((ml + tc + ws) < rtsp->in_size))
{
c = rtsp->in_buffer[ml + tc + ws];
/*统计回车换行*/
if (c == '\r' || c == '\n')
tc++;
else if ((tc < 3) && ((c == ' ') || (c == '\t')))
{
ws++; /*回车、换行之间的空格或者TAB,也是可以接受的 */
}
else
{
break;
}
}
/*
没有合适的资源?快使用搜索试试~ 我知道了~
linux-c语言-RTSP服务器H264.rar
共11个文件
c:5个
h:4个
h264:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 19 下载量 133 浏览量
2021-04-01
17:26:52
上传
评论 4
收藏 6.57MB RAR 举报
温馨提示
rtsp_h264服务器C语言源码
资源推荐
资源详情
资源评论
收起资源包目录
RTSPH264.rar (11个子文件)
h264
rtputils.h 683B
ringfifo.c 8KB
rtspservice.c 60KB
rtsptserver.c 4KB
1080P.h264 6.52MB
rtsputils.h 7KB
ringfifo.h 325B
rtspservice.h 482B
rtputils.c 13KB
rtsputils.c 18KB
rtsptserver 60KB
共 11 条
- 1
I&You
- 粉丝: 91
- 资源: 41
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
前往页