#linux cブロードキャストストリームメディアファイル(トークンバケツ)
18206 ワード
ソース:https://github.com/FzhangSpace/net_radio.git
(一)概要
(二)モジュール区分
送信側
(三)実現の詳細
3.0送受信時のパケット構造
新しく出会った関数や使い方
3.1トークンバケツ
新しく出会った関数や使い方
3.2メディアリソース処理モジュール
新しく出会った関数や使い方
3.3メニュー送信モジュール
3.4メニュー送信モジュール
新しく出会った関数や使い方
(四)プログラムの主体
新しく出会った関数や使い方
(四)総括
(一)概要
, , , 200 , , , , mpg123
(二)モジュール区分
送信側
:
, , ,
:
:
:
,
(三)実現の詳細
3.0送受信時のパケット構造
./src/include/proto.h
./src/include/site_types.h
#defien CHNNR 200 /* */
#define LISTCHNID 0 /* */
#define MINCHNID 1 /* */
#define MAXCHNID (MINCHNID+CHNNR-1) /* */
#define MSG_CHANNEL_MAX (65536-20-8) /* */
typedef uint8_t chnid_t; /* */
/* */
struct msg_channel_st {
chnid_t id; /* MUST BETWEEN [MINCHIND, MAXCHIND] */
uint8_t data[1]; /* , */
} __attribute__((packed));
/* , , */
#define MSG_LIST_MAX (65536-20-8)
struct msg_listentry_st { /* */
chnid_t id; /* MUST BETWEEN [MINCHIND, MAXCHIND] */
uint16_t len; /* , */
uint8_t desrc[1]; /* , */
} __attribute__((packed));
/* */
struct msg_list_st { /* */
chnid_t id; /* MUST BE LISTCHNID */
struct msg_listentry_st entry[1]; /* , */
} __attribute__((packed));
新しく出会った関数や使い方
, , ,
, ,
struct list {
struct list *next;
char data[0];
};
32 ,sizeof(struct list) 4 ,data , 0 , data struct list ,
struct list *ptr = malloc(sizeof(struct list)+20);
20 , data ,
3.1トークンバケツ
./src/server/mytbf.h
./src/server/mytbf.c
, , , ,
(burst), ( )(cps), (token);
, cps
/* */
struct mytbf_st {
int cps; /* */
int burst; /* */
int token; /* */
pthread_mutex_t mut; /* token */
pthread_cond_t cond; /* , , */
};
tpyedef void mytbf_t; //
static struct mytbf_st *tbf[TBFMAX]; /* */
static pthread_mutex_t mut_tbf = PTHREAD_MUTEX_INITIALIZER;
static pthread_t tid_timer;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
mytbf_t *mytbf_init(int cps, int burst); // , cps burst
static void module_load(void); // ,
static void *thr_timer_func(void *unused); //
static void *module_unload(void); // , atexit ,
static int get_free_pos(); //
,
int mytbf_fetchtoken(mytbf_t *,int n); // , ,
int mytbf_returntoken(mytbf_t *, int n); // ,
int mytbf_destroy(mytbf_t *); //
, , , , , .
, ,
新しく出会った関数や使い方
//
struct timespec t;
t.tv_sec = 1; //m
t.tv_nsec = 0; //ns
/* , , , , 1s , */
while (nanosleep(&t, &t) != 0) {
if (errno != EINTR) {
syslog(LOG_ERR, "nanosleep(): %s", strerror(errno));
exit(1);
}
}
// ( void, )
int atexit(void (*function)(void));
// , ( void, )
pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
3.2メディアリソース処理モジュール
./src/server/medialib.c
./src/server/medialib.h
./tmp/media , , .MP3 desc.test ( ), , 200
/* */
struct mlib_listentry_st { /* */
chnid_t id; // id
char *desc; // , desc.test
};
struct channel_context_st { /* */
chnid_t id; // id
char *desc; //
glob_t mp3glob; // ("*.mp3")
int pos; // mp3glob
off_t offset; //
int fd; //
mytbf_t *tbf; //
};
/***************API**********/
static struct channel_context_st channel[MAXCHNID+1]; //
/* , */
int mlib_getchnlist(struct mlib_listentry_st **, int *);
static struct channel_context_st *path2entry(const char *path) // ,
mytbf_t *mytbf_init(int cps, int burst); //
// , buf ,
ssize_t mlib_readchn(chnid_t cid, void* buf, ssize_t len);
int mytbf_fetchtoken(mytbf_t *,int n); // ,
static int open_next(chnid_t id); // read 0, ,
int mytbf_returntoken(mytbf_t *, int n); // , ,
int mlib_freechnlist(struct mlib_listentry_st *); // channel
`int mlib_getchnlist(struct mlib_listentry_st **result, int *resnum)`
`snprintf(path, PATHSIZE, "%s/*", server_conf.media_dir)`; "/var/media/*" ,`server_conf.media_dir` ("/var/media")( )
`glob(path, 0, NULL, &globres)` , `globres`
`globres.gl_pathc` , malloc
`globres.gl_pathv[i]`, `globres.gl_pathc`, ,
`res = path2entry(globres.gl_pathv[i]);` (id, , ),
path2entry `mlib_listentry_st`,
.
`ssize_t mlib_readchn(chnid_t cid, void* buf, ssize_t len);`
`tbfsize = mytbf_fetchtoken(channel[id].tbf, size);` ;
`len = pread(channel[id].fd, buf, tbfsize, channel[id].offset);` offset
`mytbf_returntoken(channel[id].tbf, tbfsize-len);`
新しく出会った関数や使い方
#include
int glob(const char *pattern, int flags,
int (*errfunc) (const char *epath, int eerrno),
glob_t *pglob);
typedef struct {
size_t gl_pathc; /*gl_pathv Count of paths matched so far */
char **gl_pathv; /* List of matched pathnames. */
size_t gl_offs; /* Slots to reserve in `gl_pathv'. GLOB_DOOFS */
} glob_t;
/* glob pattern , /* ( , ),
pglob, 4 , , ,
, pglob , , NULL;
glob
*/
#include
char *strdup(const char *s);
strdup malloc() s , s ,
. free
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
read , offset ,
3.3メニュー送信モジュール
./src/server/thr_list.h
./src/server/thr_list.c
,
/* */
int thr_list_create(struct mlib_listentry_st *listp, int nr_ent)
listp nr_ent ,
struct mlib_listentry_st , struct msg_list_st
listp struct msg_list_st . malloc
1s
3.4メニュー送信モジュール
int thr_channel_create(struct mlib_listentry_st *ptr)
static void *thr_channel_func(void *ptr)
len = mlib_readchn(ent->id, sbufp->data, datasize); ,
新しく出会った関数や使い方
#include
int sched_yield(void);
, CPU ,
(四)プログラムの主体
int serversd; //socket ,
struct sockaddr_in sndaddr; //
// , server_conf.h proto.h ,
struct server_conf_st server_conf = {
.rcvport = DEFAULT_RCVPORT, //
.mgroup = DEFAULT_MGROUP, // ip
.media_dir = DEFAULT_MEDIADIR, //
.ifname = DEFAULT_IF, // 'eth0'
.runmode = run_daemon //
};
1.
2. , server_conf
3.
4. socket , socket ,UPD, , , ,
5. , , mlib_getchnlist
6.
7.
8. , ,
新しく出会った関数や使い方
,
// ,
#include
void openlog(const char *ident, int option, int facility); // , ,
void syslog(int priority, const char *format, ...); // ,( , )====>printf
void closelog(void); //
#include
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
(四)総括
, .
, , , , ; ,
, , , , BUG .
, , ,
, .
, , ,
, , , .
, , , , ,
.
, , , ,
, static , API .
, malloc , free,