DirectVobSub(VsFilter)的基本原理和实现实现
来源:互联网 发布:c语言实现文件复制传输 编辑:程序博客网 时间:2024/05/21 06:58
DirectVobSub,以前习惯被称作 VSFilter,是一个Microsoft Windows的插件(DirectShow滤镜),用来在视频播放时加载外部字幕。
DirectVobSub/VSFilter曾经是一个独立的程序VobSub的一部分,这个程序还有诸如从DVD-Video中提取字幕或制作文字字幕等功能。Vobsub的最后一个版本是2.23,然后便停止了开发。之后,VSFilter成为了开源网站SourceForge上的“guliverkli”项目的一部分,但这个计划也于2005年停止开发,最后的版本是2.37。从2007年起,它又成为了“Guliverkli2”项目的一部分,自2.38版本起,VSFilter被称作DirectVobSub。
*注:以上来自维基百科。
目前VsFilter由MPC-HC维护,其最新版本为2.41,本文即基于此版本。
从实现层面上来说,其内部是一个DirectShow的Transform Filter,负责将字幕文件中的字幕转换成bitmap并叠加在从输入Pin进入的图像,并交给输出Pin。
DirectVobSub/VSFilter曾经是一个独立的程序VobSub的一部分,这个程序还有诸如从DVD-Video中提取字幕或制作文字字幕等功能。Vobsub的最后一个版本是2.23,然后便停止了开发。之后,VSFilter成为了开源网站SourceForge上的“guliverkli”项目的一部分,但这个计划也于2005年停止开发,最后的版本是2.37。从2007年起,它又成为了“Guliverkli2”项目的一部分,自2.38版本起,VSFilter被称作DirectVobSub。
*注:以上来自维基百科。
目前VsFilter由MPC-HC维护,其最新版本为2.41,本文即基于此版本。
从实现层面上来说,其内部是一个DirectShow的Transform Filter,负责将字幕文件中的字幕转换成bitmap并叠加在从输入Pin进入的图像,并交给输出Pin。
线程结构:
VsFilter接口是线程安全的,主要包含两个线程:
1.文件监控线程:CDirectVobSubFilter::ThreadProc,监控文件的修改,如果文件状态变化,需要重新加载;
2.字幕图片生成线程:CSubPicQueue::ThreadProc,CSubPicQueue内部维护一个队列,字幕文件加载后,立刻转换10条字幕成图片,放入该队列,每消耗一个图片,则立即补充一个,直到字幕播放结束。
主要模块:
1.CDirectVobSubFilter:Filter的实现,提供Filter接口实现、Pin的基本操作、Transform函数实现(也就是叠加)、文件监控线程;2.SubPic:字幕图片缓存维护,CSubPicProviderImpl数据提供者接口;
3.Subtitles:字幕到图片转换的实现算法,主要包含:
1)STS:CSimpleTextSubtitle,加载字幕文件获得字幕信息条目STSEntry;
struct STSEntry {
CStringW str;
bool fUnicode;
CString style, actor, effect;
CRect marginRect;
int layer;
REFERENCE_TIME start, end;
int readorder;
};
2)STS:CRenderedTextSubtitle,派生自STS:CSimpleTextSubtitle,从字幕信息条目STSEntry生成并维护字幕对象CSubtitle,CSubtitle(派生自CAtlList<CLine*>)->CAtlList<CWord*>->CPoint,也就是维护了字幕形状的基本信息;
3)Rasterizer:光栅化(bitmap生成),CWord从其派生,将字的形状信息转化成像素,从而可以叠加到图片上。
主要流程:
1.加载VsFilter.dll,创建VsFilter的com实例,并获取IID_IDirectVobSub接口,此时将创建文件监控线程;2.连接Source Filter、VsFilter、Render Filter,此时将创建字幕图片生成线程;
3.调用IID_IDirectVobSub接口的put_FileName方法,设置字幕文件,VsFilter将加载该字幕文件,同时字幕图片生成线程将建立字幕图片缓存;
4.Filter Graph开始工作后,CDirectVobSubFilter::Transform函数获得输入Sample以及时间戳,通过输入sample的时间戳查找SubPic缓存队列中的图片,如果查不到,则从Entry中查找并生成bitmap,然后将字幕bitmap与输入sample的surface进行叠加(alphablt),叠加完成进行适当的转换(转成YUY2),然后拷贝到输出Sample。SubPic缓存队列维持长度为10,每消耗一条,则补充一条。
关键的数据流程:
1.CSimpleTextSubtitle::Open,获得CAtlArray<STSEntry>,加载字幕文件;2.CRenderedTextSubtitle::GetSubtitle,获得CAtlMap<int, CSubtitle*> m_subtitleCache,将字幕信息转化成字幕图形信息CSubtitle;
3.CSubPicQueue::ThreadProc->CSubPicQueueImpl::RenderTo->CRenderedTextSubtitle::Render->CLine::PaintOutline->CWord::Paint->CText::CreatePath()
BeginPath(g_hDC);
TextOutW(g_hDC, 0, 0, m_str, m_str.GetLength());
EndPath(g_hDC);
->Rasterizer::ScanConvert->Rasterizer::Rasterize
通过BeginPath、TextOutW、EndPath这3个GDI函数获得文字的路径点集合,并以这个路径为基础构建轮廓、阴影等像素,从而实现光栅化。
4.CSubPicQueue::EnqueueSubPic,缓存生成的bitmap图片;
5.CDirectVobSubFilter::Transform->CSubPicQueue::LookupSubPic->CMemSubPic::AlphaBlt,Source Filter推送过来一个Sample,通过输入sample的时间戳从bitmap缓存中查找对应的bitmap,然后进行透明度混合。
如过是YV12输入,有以下步骤:
Y分量叠加:
if (s2[3] < 0xff) {
d2[0] = (((d2[0] - 0x10) * s2[3]) >> 8) + s2[1];
}
U、V分量叠加:
unsigned int ia = (s2[3] + s2[3 + src.pitch] + is2[3] + is2[3 + src.pitch]) >> 2;
if (ia < 0xff) {
*d2 = BYTE((((*d2 - 0x80) * ia) >> 8) + ((s2[0] + s2[src.pitch]) >> 1));
}
6.CBaseVideoFilter::CopyBuffer(如果需要则先进行必要的转换,如BitBltFromI420ToYUY2)->CTransformOutputPin::Deliver,拷贝叠加后的图片到输出sample。
总结:
VsFilter通过获取输出的文字路径点集合,转化成形状,并光栅化成bitmap像素,然后与输入的图像进行alpha混合,达到字幕叠加的目的,实际上是图像叠加。所有的操作都是使用CPU进行计算,所以会明显增加CPU的开销。 0 0
- DirectVobSub(VsFilter)的基本原理和实现实现
- java 注解的基本原理和编程实现
- 遗传算法的基本原理和matlab实现
- Bloom Filter 的基本原理和实现
- 遗传算法的基本原理和matlab实现
- UPNP实现的基本原理
- 中断实现的基本原理
- dfs实现的基本原理
- API Hook基本原理和实现
- API Hook基本原理和实现
- API Hook基本原理和实现
- API Hook基本原理和实现
- API Hook基本原理和实现
- API Hook基本原理和实现
- I2C的基本原理和linux中I2C架构的实现
- I2C的基本原理和linux中I2C架构的实现 .
- 局域网实现监听的基本原理
- 局域网实现监听的基本原理
- 利用git工具上传本地代码到远程仓库
- Linux Awk命令详解
- c语言函数指针的理解与使用
- 【leetcode】1.Two Sum
- ie下兼容奇偶
- DirectVobSub(VsFilter)的基本原理和实现实现
- Oracle分页
- git的配置
- H5 微信开发 小bug
- Eclipse alt+/代码提示不好用的解决方法
- 解决jsp页面取出的数据乱码
- androoid framework学习之 - InCallUI中CallButton界面更新介绍(audioButton等)
- 使用idea创建springboot项目并打成war包发布到weblogic上
- opencv 一种不均匀光照的补偿方法