首页 > 代码库 > 如何写一个处理多媒体的中间库

如何写一个处理多媒体的中间库

这里实现一个简单的多媒体数据流的处理库,它是以Filter的思想来实现的,通过Filter可以实现多路数据采集,处理和输出;

 

 

 

 一. 如何实现一个filter

1.定义一个Filter descripter 结构,它包含了Filter的主要属性和行为;

typedef struct McFilterDesc{	McFilterId id;	const char* name;	const char* text;	McFilterCategory category;	const char* encFormat;	int ninputs;	int noutputs;	McFilterFunc init;	McFilterFunc preprocess;	McFilterFunc process;	McFilterFunc postProcess;	McFilterFunc uninit;	McFilterMethod* methods;}UC_McFilterDesc;

  

2. 定义Filter结构体

struct McFilter{	UC_McFilterDesc* desc;	pthread_mutex_t lock;	struct McQueue **inputs;	struct McQueue **outputs;	McFilterNotifyFunc notify;	void* notifyUd;	void* data;	struct McTicker* ticker;	uint32_t lastTick;	bool seen;};

 

3. 根据Filter descripter 创建Filter 实例

UC_McFilter* mc_filter_new_from_desc(UC_McFilterDesc* desc){	UC_McFilter* filter;	filter = (UC_McFilter*)malloc(sizeof(UC_McFilter));	pthread_mutex_init(&filter->lock, NULL);	filter->desc = desc;	if(desc->ninputs > 0) filter->inputs = (UC_McQueue**)malloc(sizeof(UC_McQueue*) * desc->ninputs);	if(desc->noutputs > 0) filter->outputs = (UC_McQueue**)malloc(sizeof(UC_McQueue*) * desc->noutputs);	if(desc->init != NULL)		desc->init(filter);	return filter;}

  

二. 将创建的Filter 链接起来

UC_McQueue* mc_queue_new(UC_McFilter* filter1, int pin1, UC_McFilter* filter2, int pin2){	UC_McQueue* queue = (UC_McQueue*)malloc(sizeof(UC_McQueue));	uc_queue_init(&queue->q);	queue->prev.filter = filter1;	queue->prev.pin = pin1;	queue->next.filter = filter2;	queue->next.pin = pin2;	return queue;}int mc_filter_link(UC_McFilter* filter1, int pin1, UC_McFilter* filter2, int pin2){	UC_McQueue* queue;	queue = mc_queue_new(filter1, pin1, filter2, pin2);	filter1->outputs[pin1] = queue;	filter2->inputs[pin2] = queue;	return 0;}

  

三. 将Filter链表加入运行表中

1. 创建Ticker结构,并启动运行线程

struct McTicker{	pthread_mutex_t lock;	pthread_cond_t	cond;	pthread_t	thread;	UC_McList* execList;	int interval;	int execId;	uint32_t ticks;	uint64_t time;	bool run;};typedef struct McTicker UC_McTicker;static void ticker_start(UC_McTicker* ticker){	ticker->run = TRUE;	pthread_create(&ticker->thread, NULL, ticker_run, ticker);}static void ticker_init(UC_McTicker* ticker){	pthread_mutex_init(&ticker->lock, NULL);	pthread_cond_init(&ticker->cond, NULL);	ticker->execList = NULL;	ticker->ticks = 1;	ticker->time = 0;	ticker->interval = 10;	ticker->run = FALSE;	ticker->execId = 0;	ticker_start(ticker);}

  

 

2. 将source filter 加入到Ticker的execList中

int mc_ticker_attach(UC_McTicker* ticker, UC_McFilter* filter){	UC_McList* sources = NULL;	UC_McList* filters = NULL;	UC_McList* iter;	if(filter->ticker != NULL){		printf("Filter %s had beeb scheded\n", filter->desc->name);		return 0;	}	printf("%s is invoked\n", __FUNCTION__);	ticker_find_filters(&filters, filter);	sources = ticker_get_sources(filters);	//printf("%s is invoked 2\n", __FUNCTION__);	if(sources == NULL){		mc_list_free(filters);		return -1;	}	//printf("%s is invoked 3\n", __FUNCTION__);	for(iter = filters; iter != NULL; iter = iter->next){		mc_filter_preprocess((UC_McFilter*)iter->data, ticker);	}	//printf("%s is invoked 4\n", __FUNCTION__);	pthread_mutex_lock(&ticker->lock);	ticker->execList = mc_list_concat(ticker->execList, sources);	pthread_mutex_unlock(&ticker->lock);	mc_list_free(filters);	printf("%s is invoked exit\n", __FUNCTION__);	return 0;}

  

3. 运行流程图