文档章节

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

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

注:写了一系列的文章,都是关于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);
}




本文转载自:http://blog.csdn.net/leixiaohua1020/article/details/13006213

雷霄骅
粉丝 205
博文 419
码字总数 2129
作品 4
朝阳
程序员
私信 提问
K-Lite Codec Pack 5.40发布

K-Lite Codec Pack作为多格式视频解决方案的领头者,从未减慢过更新的步伐,每次更新都会带来不少的改进,此次更新甚至是连Corporate版也更新了。 安装过K-Lite Codec Pack之后,您的播放器就...

红薯
2009/11/06
1K
0
下载:Win7codecs 3.1.6 正式版

Windows 7 Codecs是一款适用于Windows 7等系统的视频解码器,无需安装其他的Codec或者Filter即可使用,支持几乎所有常用格式的解码,配合Windows Media Player使用更是能带来极佳的体验。Win...

小卒过河
2011/10/21
1K
4
Mp4编码全介绍

什么是MP4?听闻它是一种“容器格式”,那是什么? 容器格式允许你将不同种类的多媒体数据流(多为视频流和音频流)合并在一个单一的文件内。 多媒体容器格式,就是我们熟知的AVI(.avi), MP...

AlphaJay
2010/05/07
8.9K
0
Win7codecs 3.2.4 新版发布

近期,Win7codecs动作频频,几乎每几日都会升级到最新版本,如此频繁地更新主要是为了优化软件性能,新功能倒是没有见到。今 天,Win7codecs 3.2.4以迅雷不及掩耳之势发布了,同样也是对部分...

红薯
2011/11/08
935
4
Win7codecs 2.8.5 正式版发布

Win7codecs 2.8.5正式版发布。Windows 7 Codecs就是最初的Win7codecs,是一款较为知名的系统解码包,通过安装该解码包,我们可以用任何的播放器播放DVD,电影和视频剪辑(比如 Quicktime,AVI...

小卒过河
2011/04/30
912
1

没有更多内容

加载失败,请刷新页面

加载更多

好程序员web前端分享逻辑运算

  一门计算机语言,编程的核心在于逻辑思想,当我们在编写程序的时候,逻辑是否通顺,是能否正确写出程序的关键,可以说如果你掌握了逻辑,那么你就踏入了计算机编程的大门。 &&与 || 或 ...

好程序员IT
16分钟前
1
0
我的Linux系统开始学习的过程

我的Linux系统开始学习的过程 Linux系统,不知大家是否了解。接触计算机不多或对计算机不感冒的人可能对其比较陌生,曾经的我也是。上大学前的我的确对Linux一无所知,那时候接触面窄,都没有...

linuxCool
17分钟前
1
0
让自己的网站可以被搜索

第一步:先注册一个属于自己的域名,这个域名是独一无二的。推荐到主机屋注册一个,其实在哪里注册都是一样的,但是主机屋提供免费的地址解析服务(只对在主机屋注册的域名免费)。 主机屋官...

WinkJie
19分钟前
1
0
全站加速(DCDN)- IP应用加速产品解读

5月22日下午15点,阿里云全站加速(DCDN)-IP应用加速如期发布。IP应用加速是阿里云自主研发的一款更高效、更安全、更便捷的动态加速产品,结合阿里云CDN本身的资源优势,利用就近接入、智能...

阿里云官方博客
22分钟前
1
0
k8s常用命令

1.创建deployment资源kubectl apply -f nginx.yml2.删除deployment资源kubectl delete -f nginx.yml3.查看deployment资源基本信息deployment资源(运行的服务资源)kubectl get...

平头哥-Enjoystudy
23分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部