文档章节

ffdshow 源代码分析 4: 位图覆盖滤镜(滤镜部分Filter)

雷霄骅
 雷霄骅
发布于 2014/08/16 13:50
字数 1371
阅读 40
收藏 0

精选30+云产品,助力企业轻松上云!>>>

注:写了一系列的文章,都是关于ffdshow中的位图覆盖滤镜的源代码分析的,在此列一个列表:

ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)

ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings)

ffdshow 源代码分析 4: 位图覆盖滤镜(滤镜部分Filter)
ffdshow 源代码分析 5: 位图覆盖滤镜(总结)


第一篇文章介绍了ffdshow的位图覆盖滤镜的对话框(Dialog)部分:ffdshow 源代码分析2 : 位图覆盖滤镜(对话框部分Dialog)

第二篇文章介绍了ffdshow的位图覆盖滤镜的设置(Settings)部分:ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings)

此外还有一个滤镜部分(Filter)。这三个部分就可以组成一个ffdshow的滤镜功能了。本文就来简介一下ffdshow的滤镜部分。


滤镜部分(Filter)

ffdshow的滤镜的滤镜部分(怎么感觉名字有点重复 = =,算了先这么叫吧)的功能主要用于完成具体的图像处理功能。具体到位图覆盖滤镜的话,就是用于把图片覆盖到视频上面,他是ffdshow滤镜的核心。

与位图覆盖(Bitmap)滤镜的滤镜处理有关的类位于imgFilters目录下的TimgFilterBitmap.h和TimgFilterBitmap.cpp文件中。



先来看看TimgFilterBitmap.h

这里要注意一下,该类的名字叫TimgFilterBitmap。它的声明方式确实比较奇怪:DECLARE_FILTER(TimgFilterBitmap, public, TimgFilter)

可以看出DECLARE_FILTER是一个宏,具体这个宏的内部代码就先不查看了,否则会感觉很混乱,暂且留下一个小小的谜团。在这里只要知道这是声明了一个滤镜类就可以了。

其实TimgFilterBitmap的核心函数不多,就一个,那就是process(),具体的处理功能都是在这个函数里面实现的。

/*
 *雷霄骅
 *leixiaohua1020@126.com
 *中国传媒大学/数字电视技术
 */

#ifndef _TIMGFILTERBITMAP_H_
#define _TIMGFILTERBITMAP_H_
//叠加一张位图
#include "TimgFilter.h"
#include "Tfont.h"

struct TffPict;
struct TbitmapSettings;
//特别的声明方式 = =
DECLARE_FILTER(TimgFilterBitmap, public, TimgFilter)
private:
//图像
TffPict *bitmap;
//内存
Tbuffer bitmapbuf;
char_t oldflnm[MAX_PATH];
typedef void (*Tblendplane)(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
//注意 这个类有一个实例,名字叫w
class TrenderedSubtitleLineBitmap : public TrenderedSubtitleWordBase
{
public:
    TrenderedSubtitleLineBitmap(void): TrenderedSubtitleWordBase(false) {}
    TffPict *pict;
    const TbitmapSettings *cfg;
	//叠加
    Tblendplane blend;
	//打印
    virtual void print(int startx, int starty /* not used */, unsigned int dx[3], int dy1[3], unsigned char *dstLn[3], const stride_t stride[3], const unsigned char *bmp[3], const unsigned char *msk[3], REFERENCE_TIME rtStart = REFTIME_INVALID) const;
} w;
TrenderedSubtitleLine l;
//是TrenderedSubtitleLine的一个vector
TrenderedSubtitleLines ls;
int oldmode;
//几种叠加方式
template<class _mm> static void blend(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
template<class _mm> static void add(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
template<class _mm> static void darken(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
template<class _mm> static void lighten(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
template<class _mm> static void softlight(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
template<class _mm> static void exclusion(const TcspInfo &cspInfo, const unsigned int dx[3], const unsigned int dy[3], unsigned char *dst[3], const stride_t dststride[3], const unsigned char *src[3], const stride_t srcstride[3], int strength, int invstrength);
//获取叠加方式
template<class _mm> static Tblendplane getBlend(int mode);
protected:
virtual bool is(const TffPictBase &pict, const TfilterSettingsVideo *cfg);
virtual uint64_t getSupportedInputColorspaces(const TfilterSettingsVideo *cfg) const
{
    return FF_CSPS_MASK_YUV_PLANAR;
}
public:
TimgFilterBitmap(IffdshowBase *Ideci, Tfilters *Iparent);
virtual ~TimgFilterBitmap();
//核心函数(Filter配置信息队列,图像,配置信息)
virtual HRESULT process(TfilterQueue::iterator it, TffPict &pict, const TfilterSettingsVideo *cfg0);
};

#endif



再来看看TimgFilterBitmap.cpp

这个文件本身代码量是比较大的,只是其他部分我都还没有仔细分析,确实没那没多时间。。。在这里仅简要分析一下最核心的函数process()。正是这个函数真正实现了滤镜的功能。在这个位图叠加滤镜中,process()实现了位图在视频上面的叠加功能。

//核心函数(Filter配置信息队列,图像,配置信息)
HRESULT TimgFilterBitmap::process(TfilterQueue::iterator it, TffPict &pict, const TfilterSettingsVideo *cfg0)
{
	//都有这一句= =
    if (is(pict, cfg0)) {
		//Bitmap的配置信息
        const TbitmapSettings *cfg = (const TbitmapSettings*)cfg0;
        init(pict, cfg->full, cfg->half);
        unsigned char *dst[4];
        bool cspChanged = getCurNext(FF_CSPS_MASK_YUV_PLANAR, pict, cfg->full, COPYMODE_DEF, dst);
		//处理
        if (!bitmap || cspChanged || stricmp(oldflnm, cfg->flnm) != 0) {
            ff_strncpy(oldflnm, cfg->flnm, countof(oldflnm));
            if (bitmap) {
                delete bitmap;
            }
			//新建一张图
			//通过cfg->flnm路径
			//载入bitmapbuf
            bitmap = new TffPict(csp2, cfg->flnm, bitmapbuf, deci);
			//3个颜色分量?
            for (int i = 0; i < 3; i++) {
                w.dx[i] = bitmap->rectFull.dx >> bitmap->cspInfo.shiftX[i];
                w.dy[i] = bitmap->rectFull.dy >> bitmap->cspInfo.shiftY[i];
                w.bmp[i] = bitmap->data[i];
                w.bmpmskstride[i] = bitmap->stride[i];
            }
            w.dxChar = w.dx[0];
            w.dyChar = w.dy[0];
        }

        if (bitmap->rectFull.dx != 0) {
            if (oldmode != cfg->mode)
                if (Tconfig::cpu_flags & FF_CPU_SSE2) {
					//获取叠加方式(SSE2)
					//在cfg的mode里
                    w.blend = getBlend<Tsse2>(oldmode = cfg->mode);
                } else {
					//获取叠加方式(MMX)
                    w.blend = getBlend<Tmmx>(oldmode = cfg->mode);
                }
			//输出到屏幕上的设置
            TprintPrefs prefs(deci, NULL);
			//各种参数
            prefs.dx = dx2[0];
            prefs.dy = dy2[0];
            prefs.xpos = cfg->posx;
            prefs.ypos = cfg->posy;
			//模式不同的话
            if (cfg->posmode == 1) {
                prefs.xpos *= -1;
                prefs.ypos *= -1;
            }
            prefs.align = cfg->align;
            prefs.linespacing = 100;
            prefs.csp = pict.csp;
            w.pict = &pict;
            w.cfg = cfg;
			//打印,需要用到TprintPrefs
            ls.print(prefs, dst, stride2);
        }
    }
	//最后都是这一句?
    return parent->processSample(++it, pict);
}




雷霄骅

雷霄骅

粉丝 219
博文 419
码字总数 2129
作品 4
朝阳
程序员
私信 提问
加载中
请先登录后再评论。
ffdshow 源代码分析 5: 位图覆盖滤镜(总结)

注:写了一系列的文章,都是关于ffdshow中的位图覆盖滤镜的源代码分析的,在此列一个列表: ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog) ffdshow 源代码分析 3: 位图覆盖滤镜...

雷霄骅
2014/08/16
24
0
ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings)

注:写了一系列的文章,都是关于ffdshow中的位图覆盖滤镜的源代码分析的,在此列一个列表: ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog) ffdshow 源代码分析 3: 位图覆盖滤镜...

雷霄骅
2014/08/16
23
0
ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)

注:写了一系列的文章,都是关于ffdshow中的位图覆盖滤镜的源代码分析的,在此列一个列表: ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog) ffdshow 源代码分析 3: 位图覆盖滤镜...

雷霄骅
2014/08/16
37
0
ffdshow 源代码分析1 : 整体结构

ffdshow是一个非常强大的DirectShow解码器,封装了ffmpeg,libmpeg2等解码库。它也提供了丰富的加工处理选项,可以锐化画面,调节画面的亮度等等。不止是视频,FFDShow现在同样可以解码音频,...

雷霄骅
2014/08/16
58
0
[总结]FFMPEG视音频编解码零基础学习方法

在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者。在和大家探讨的过程中,我忽然发现了一...

雷霄骅
2014/08/16
2.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

博客园二次元主题——Sakura

碎碎念 嗯,时隔多久也记不清了,我又回来了,总算是忙里偷闲把这篇文章写出来,有人要过很多次我的博客园美化方案,但是实在是忙啊,也因为我的前台技术不好,代码bug很多,所以也有点不想把...

osc_2y6i16fz
55分钟前
19
0
highcharts 自适应div的宽度

如果窗口变化时,highcharts图表是自带自适应的,但是切换折叠菜单时,highchats图表并不自适应外层div的宽度。如何实现适应div的宽度? 在网上找到有个 reflow 的方法,我是在项目中引入的 ...

tianyawhl
55分钟前
23
0
个人作业——软件工程实践总结&个人技术博客

这个作业属于哪个课程 2020春|S班 (福州大学) 这个作业要求在哪里 个人作业——软件工程实践总结&个人技术博客 这个作业的目标 回顾这门课程带来的提升、团队总结、实践中的经验总结、对下届...

osc_g032zryv
56分钟前
17
0
从封装变化的角度看设计模式——对象创建

封装变化之对象创建 在对象创建的过程中,经常会出现的一个问题就是通过显示地指定一个类来创建对象,从而导致紧耦合。这是因为创建对象时指定类名将使你受特定实现的约束而不是特定接口的约...

osc_r5t7sskd
57分钟前
19
0
从封装变化的角度看设计模式——对象创建

封装变化之对象创建 在对象创建的过程中,经常会出现的一个问题就是通过显示地指定一个类来创建对象,从而导致紧耦合。这是因为创建对象时指定类名将使你受特定实现的约束而不是特定接口的约...

osc_i5oyb1xr
58分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部