初始化均在include/fenice/目录下
初始化TRACE-POINT (INCLUDE在UTIL.H文件,提示程序开始)
初始化TSOCKET (功能稍后补充,转至socket.h,typedef int tsocket;)
初始化struct timespec
{
__time_t tv_sec; /* Seconds. */
long int tv_nsec; /* Nanoseconds. */
};
包含于(include/fenice/time.h)
struct timespec ts = { 0, 0 };
运行 fncheader(); 转至 fnchead.c文件 输出软件版本 信息
printf("/n%s %s %s- Open Media Streaming Project - Politecnico di Torino/n/n", PACKAGE, VERSION, svnrev);
其中在config.h中
#define PACKAGE "fenice"
#define VERSION "1.11"
获取端口号:extern serv_prefs prefs;
int prefs_get_port()
{
return prefs.port;
}
其中serv_prefs 的结构为:
typedef struct _serv_prefs {
char hostname[256];
char serv_root[256];
char log[256];
unsigned int port;
unsigned int max_session;
} serv_prefs; (端口什么时候赋值,为什么用EXTERN)
fnc_log(FNC_LOG_INFO,"Waiting for RTSP connections on port %d.../n", port);
写入日志功能。。。
#define FNC_LOG_INFO 3
在FNC_LOG.h文件
---------------------------------------------------------------------------------------------------------------------------------------------
调用tcp_listen.c中的方法:main_fd = tcp_listen(port); 首先是TCP的连接监听
初始化SOCK地址struct sockaddr_in s;
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
#define __SOCKADDR_COMMON(sa_prefix) /
sa_family_t sa_prefix##family -------------------------------不懂
extern int socket (int __domain, int __type, int __protocol) __THROW; 引用LINUX中的SOCKET函数?
判断1
if ((f = socket(AF_INET, SOCK_STREAM, 0))<0)
{
fnc_log(FNC_LOG_ERR,"socket() error in tcp_listen./n" );
return ERR_GENERIC;
}
判断2
设置并绑定SOCK的地址
setsockopt(f, SOL_SOCKET, SO_REUSEADDR, (char *) &v, sizeof(int));
s.sin_family = AF_INET;
s.sin_addr.s_addr = htonl(INADDR_ANY);
s.sin_port = htons(port);
if (bind (f, (struct sockaddr *)&s, sizeof (s)))
{
fnc_log(FNC_LOG_ERR,"bind() error in tcp_listen" );
f, SOL_N
}
-----------------------------------------------------------------------------------------------------------------------------------------------
schedule.c schedule_list
if (schedule_init() == ERR_FATAL)
{
fnc_log(FNC_LOG_FATAL,"Fatal: Can't start scheduler. Server is aborting./n");
return 0;
}
且在schedule_init.c文件中
#define MAX_PROCESS 1/*number of fork*/
#define MAX_CONNECTION 100/*rtsp connection*/
#define ONE_FORK_MAX_CONNECTION ((int)(MAX_CONNECTION/MAX_PROCESS))
schedule_list sched[ONE_FORK_MAX_CONNECTION];
typedef struct _schedule_list
{
int valid;
RTP_session *rtp_session;/*RTP*/
/*RTSP_session *rtsp_session;*/
RTP_play_action play_action
} schedule_list;
-----------------------------------------------------------------------------------------------------------------------------------------------
RTP SESSION定义:
typedef struct _RTP_session
{
RTP_transport transport;
unsigned char rtcp_inbuffer[RTCP_BUFFERSIZE];
int rtcp_insize;
unsigned char rtcp_outbuffer[RTCP_BUFFERSIZE];
uint32 rtcp_outsize;
double mprev_tx_time;
unsigned int PreviousCount;
short MinimumReached;
short MaximumReached;
int sched_id;
unsigned int start_seq;
unsigned int start_rtptime;
unsigned char pause;
unsigned char started;
unsigned int seq;
unsigned int ssrc;
char sd_filename[255];
media_entry *current_media;
SD_descr *sd_descr;
OMSConsumer *cons;
RTCP_stats rtcp_stats[2];
struct _RTP_session *next;
unsigned char is_multicast_dad;/*if is it an multicast son it cannot do TEARDOWN etc...*/
} RTP_session;
------------------------------------------------------RTP SESSION比较恐怖 暂时忽略先-------------------------------------------
查看schedule_init() 方法知:
#ifdef THREADED
pthread_t thread; 定义了线程
/* Thread identifiers */
typedef unsigned long int pthread_t;
初始化schedule_list
for (i=0; i<ONE_FORK_MAX_CONNECTION; ++i)
{
sched[i].rtp_session=NULL;
sched[i].play_action=NULL;
sched[i].valid=0;
}
然后初始化线程操作:
pthread_create(&thread,NULL,schedule_do,0);
调用pthread.h文件
extern int pthread_create (pthread_t *__restrict __threadp,
__const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),
void *__restrict __arg) __THROW;
然后执行RTP模块:端口缓冲池初始化
RTP_port_pool_init(RTP_DEFAULT_PORT);
uint32 port_pool[ONE_FORK_MAX_CONNECTION];
void RTP_port_pool_init(int port)
{
int i;
start_port=port;
for (i=0; i<ONE_FORK_MAX_CONNECTION; ++i) {
port_pool[i]=i+start_port;
}
}
---------------------------------------------------------------------------------------------------------------------------------------
while (1)
{
nanosleep(&ts, NULL); ------------------睡眠等待
trace_point();
eventloop(main_fd);
}
extern int nanosleep (__const struct timespec *__requested_time,
struct timespec *__remaining);
循环运行eventloop(main_fd);函数,见eventloop.c代码文件
其中代码第四行:
static RTSP_buffer *rtsp_list=NULL;
RTSP服务管理。。。