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

这里实现一个简单的多媒体数据流的处理库,它是以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. 运行流程图

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

时间: 2024-10-28 14:15:02

如何写一个处理多媒体的中间库的相关文章

利用epoll写一个"迷你"的网络事件库

epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了.epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存I

分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业不是百度来的,我只是百度了一些示例代码的意思,怎么用!算了,越解释万一越黑呢!哈哈O(∩_∩)O哈哈~) ----------------------------------------------------------------分界线------------------------------

我想写一个Linux下的C++程序库--记我的C++库设计历程:设计一个TCP服务程序

我想写一个Linux下的C++程序库,实现一些常用的功能. 我首先想到的就是实现一个TCP监听程序.该程序应该具有哪些功能呢? 1: 启动/停止监听 2: 有客户端连接时,通知调用者 3: 与客户端断开时,通知调用者 4: 有消息到达时,通知调用者 5: 尽量避免程序退出时有没有close的socket. 该程序的大体接口及结构主要用一个类表示,内容如下: #pragma once #include <functional> namespace Hi { /* * @ brief TCP监听会

【转载】写一个js库需要怎样的知识储备和技术程度?

作者:小爝链接:https://www.zhihu.com/question/30274750/answer/118846177来源:知乎著作权归作者所有,转载请联系作者获得授权. 1,如何编写健壮的javascript代码,鲁棒性,简单总结几条我觉得是常识的事:1.1 一个javascript库最好的实现方式是占用最少的命名空间,比如window对象上或者global对象上只占用一个引用.1.2 健壮的js程序对输入都会有完善的类型检查和异常处理,边界值的判断.1.3 对js的几种继承方式要足

JAVA用标准库自己写一个字符串翻转方法,翻转字符串中字母非单词

例如输入:I love programming 输出:I evol gnimmargorp 算法思路就是:根据空格提取每一个单词,存放在一个buffer里进行翻转处理,再添加到新的字符串.最后新的字符串就完成整个方法过程. public class ReserveString { public String reserve(String sentence){ String backS = new String(); StringBuffer temp = new StringBuffer();

自己动手写一个iOS 网络请求库的三部曲[转]

代码示例:https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary 开源项目:Pitaya,适合大文件上传的 HTTP 请求库:https://github.com/johnlui/Pitaya 本系列文章中,我们将尝试使用 NSURLSession 技术构建一个自己的网络请求库. NSURLSession 简介 NSURLSession 是 iOS7 引入的新网络请求接口,在 WWDC2013

一个类似于jq的小型库

本人写了一个类似于jq的小型库,不过只是写了部分方法而已.并没有jq那么全面,下面就介绍下有哪些方法可以使用 第一个是选择器, 选择器比较简单 只支持ID选择器 $(‘#id_name’) Class选择器$(‘.class_name’) 标签选择器$(‘tag _name’) 并没有像jq那样拥有高级的选择器. 方法有 Js延迟加载 Ready     $(document).ready(function(){ // 在这里写你的代码... }); $(functoin(){ }) 事件有 C

基于zabbix用Python写一个运维流量气象图

前言:同事问我,你写运维平台最先写哪一部分?好吧,还真把我问倒了,因为这是在问最应该放在放在第一位的东西~作为一个工作不足两年,运维不足一年的新手来说,还真不敢妄下评论,其实按照我的思路,觉得最重要的部分肯定是故障处理,报警,但是这一块怎么写?怎么说?肯定不能重复造轮子了,不过我最想写的是报表系统,思路是有的,但是一直耽搁了,详情参考http://youerning.blog.51cto.com/10513771/1708925. 好吧,在回到那个问题,应该先写哪个部分.我没回答,反问他了. 他

写一个ajax程序就是如此简单

写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发技术.     2:基于web标准XHTML+CSS的表示:     3:使用 DOM进行动态显示及交互:     4:使用 XML 和 XSLT 进行数据交换及相关操作:     5:使用 XMLHttpRequest 进行异步数据查询.检索: 程序员应用ajax的途经: 1:.Net下的Ajax