如何设计一个向视频插入位图的filter 请问谁能给我说说大致的思路 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 陆其明的directshow开发指南里,好像有关于向视频流里 加入位图类似例子;,可以仔细研究一下 en陆其明书上有类似例子,lz研究一下即可 自己用ReadFile..读BMP 文件。进行操作 不行。。在网上 找了 代码.用GDI加载位图。。不显示。DDCopyBitmap(IDirectDrawSurface7 *pdds, HBITMAP hbm, int x, int y, int dx, int dy) { HDC hdcImage; HDC hdc; BITMAP bm; DDSURFACEDESC2 ddsd; HRESULT hr; if (hbm == NULL || pdds == NULL) return E_FAIL; // // Select bitmap into a memoryDC so we can use it. // hdcImage = CreateCompatibleDC(NULL); if (!hdcImage) { OutputDebugString(TEXT("DDHEL: CreateCompatibleDC failed.\n")); return E_FAIL; } SelectObject(hdcImage, hbm); // // Get size of the bitmap // GetObject(hbm, sizeof(bm), &bm); dx = dx == 0 ? bm.bmWidth : dx; // Use the passed size, unless zero dy = dy == 0 ? bm.bmHeight : dy; // // Get size of surface. // ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; pdds->GetSurfaceDesc(&ddsd); if ((hr = pdds->GetDC(&hdc)) == DD_OK) { if (!StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY)) hr = E_FAIL; pdds->ReleaseDC(hdc); } DeleteDC(hdcImage); return hr; } ///////////////////lpddsprimary->Blt(&torect,lpddsback,&sourcerect,DDBLT_WAIT,NULL); //主页面 lpddsback->Lock(NULL, &ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); //离屏页面hbitmap=(HBITMAP)LoadImage(NULL,fname,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);DDCopyBitmap(lpddsback,hbitmap,0,0,800,600);if (FAILED(lpddsback->Unlock(NULL))) return(0); 这个我知道,trans inplace有一个输入PIN和一个输出PIN,我看了directshow实务精选里面有视频抠像合成两个视频流的,用到了2个输入PIN,一个是原始视频流,另一个则是要插入进去的叠加视频流,而我希望插入一张位图,能不能只用一个输入PIn完成所有操作,即我在trans inplace自带的输入PIn中同时完成图片的载入和合成然后输出 可以啊,它那个需要2个pin,是由于另一个pin它加了第2个视频流,你完全可以就一个pin,在内部的Transform函数里处理视频数据,加你的osd rageliu:我现在搭好了这个filter的框架,但有个一播放就报错的问题,我是这样实现的,1.读取硬盘中的一张BMP文件,并开辟缓冲区:PBYTE m_BmpBuffer;DWORD dwSize = GetFileSize(m_hFile,NULL);m_BmpBuffer = new BYTE[dwSize];2. 在CompleteConnect中获得Sample中视频流的图像格式://///////////////////////获得输入图像的格式信息//////////////////////// VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *)mt.Format(); m_BitCount = pVideoInfo->bmiHeader.biBitCount; m_TotalPixels = pVideoInfo->bmiHeader.biWidth*abs(pVideoInfo->bmiHeader.biHeight);3.在TransForm中,实现简单的合成://进行叠加工作 PBYTE pSrc = NULL; pSample->GetPointer(&pSrc); if(m_BmpBuffer!=NULL) { if(m_BitCount==16) { IdealMixing16Bits(pSrc,m_BmpBuffer); } else { IdealMixing32Bits(pSrc,m_BmpBuffer); } }4. 调用的是IdealMixing32Bits,播放时该函数报错,该函数内容如下:_inline void CMyFilter::IdealMixing32Bits(BYTE * outPrimary, BYTE * inMixing){ DWORD * pPrimary = (DWORD *) outPrimary; DWORD * pMixing = (DWORD *) inMixing; static DWORD backColor; // Pick up the background color DWORD temp = *pMixing; backColor = temp; for (long i = 0; i < /*m_TotalPixels*/dwFileSize; i++) { if (*pMixing != backColor)///循环执行到这里报错,此时i值较大 { *pPrimary = *pMixing; } pPrimary++; pMixing++; }}这个问题困扰我一段时间了,我不知是什么原因造成的,麻烦大家帮我看看,这个帖子我继续加分PS:我所有的代码都是在filter类中实现的,没有单独定义PIN类,视频流类型为MEDIASUBTYPE_ARGB32 dwFileSize这个是bmp的rgb数据的长度吗?看名字似乎不是相素,那循环用(dwFileSize >> 2)试试再有这里循环这样写不太好,因为有pitch,还是循环height和width比较好 bmp和原始视频长宽谁大啊,都要使用小的那个 很抱歉现在才回复啊~~视频长宽大,我用的位图的size作为循环上限,再报错的时候我看了下此时的i的值是12262,然后我把dwFileSize替换成了12262测试下,调试播放时候能够正常播放,就是没有把位图给插进来,还是播放原始的视频 如何修改一个CRichEditCtrl的滚动条颜色和样式(有图) 操作符重载 动态加载数据源,不能访问, 兄弟们来解释解释..! 是物理内存地址还是虚拟内存地址的问题? 如何打印在控件中的内容 HTTP协议状态码的含义 怎样设置条形码输入的格式 数据库中日期范围怎么比较? 求教,读扇区函数问题 前辈帮忙,我要用vc做一个人事管理系统,有什么好建议吗?麻烦您了 只运行1个实例判断,任务管理器没有,程序却提示存在??? 有关VC中使用ADO执行SQL语句的问题
陆其明书上有类似例子,lz研究一下即可
DDCopyBitmap(IDirectDrawSurface7 *pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
BITMAP bm;
DDSURFACEDESC2 ddsd;
HRESULT hr; if (hbm == NULL || pdds == NULL)
return E_FAIL; //
// Select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
if (!hdcImage) {
OutputDebugString(TEXT("DDHEL: CreateCompatibleDC failed.\n"));
return E_FAIL;
}
SelectObject(hdcImage, hbm); //
// Get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm);
dx = dx == 0 ? bm.bmWidth : dx; // Use the passed size, unless zero
dy = dy == 0 ? bm.bmHeight : dy; //
// Get size of surface.
//
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd); if ((hr = pdds->GetDC(&hdc)) == DD_OK)
{
if (!StretchBlt(hdc,
0, 0,
ddsd.dwWidth,
ddsd.dwHeight,
hdcImage,
x, y,
dx, dy,
SRCCOPY)) hr = E_FAIL;
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
return hr;
}
///////////////////
lpddsprimary->Blt(&torect,lpddsback,&sourcerect,DDBLT_WAIT,NULL); //主页面
lpddsback->Lock(NULL, &ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); //离屏页面hbitmap=(HBITMAP)LoadImage(NULL,fname,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);DDCopyBitmap(lpddsback,hbitmap,0,0,800,600);
if (FAILED(lpddsback->Unlock(NULL)))
return(0);
可以啊,它那个需要2个pin,是由于另一个pin它加了第2个视频流,你完全可以就一个pin,在内部的Transform函数里处理视频数据,加你的osd
我现在搭好了这个filter的框架,但有个一播放就报错的问题,我是这样实现的,1.读取硬盘中的一张BMP文件,并开辟缓冲区:PBYTE m_BmpBuffer;
DWORD dwSize = GetFileSize(m_hFile,NULL);
m_BmpBuffer = new BYTE[dwSize];
2. 在CompleteConnect中获得Sample中视频流的图像格式://///////////////////////获得输入图像的格式信息////////////////////////
VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *)mt.Format();
m_BitCount = pVideoInfo->bmiHeader.biBitCount;
m_TotalPixels = pVideoInfo->bmiHeader.biWidth*abs(pVideoInfo->bmiHeader.biHeight);3.在TransForm中,实现简单的合成://进行叠加工作
PBYTE pSrc = NULL;
pSample->GetPointer(&pSrc); if(m_BmpBuffer!=NULL)
{
if(m_BitCount==16)
{
IdealMixing16Bits(pSrc,m_BmpBuffer);
}
else
{
IdealMixing32Bits(pSrc,m_BmpBuffer);
}
}
4. 调用的是IdealMixing32Bits,播放时该函数报错,该函数内容如下:_inline void CMyFilter::IdealMixing32Bits(BYTE * outPrimary, BYTE * inMixing)
{
DWORD * pPrimary = (DWORD *) outPrimary;
DWORD * pMixing = (DWORD *) inMixing; static DWORD backColor;
// Pick up the background color
DWORD temp = *pMixing; backColor = temp; for (long i = 0; i < /*m_TotalPixels*/dwFileSize; i++)
{
if (*pMixing != backColor)///循环执行到这里报错,此时i值较大
{
*pPrimary = *pMixing;
}
pPrimary++;
pMixing++;
}
}这个问题困扰我一段时间了,我不知是什么原因造成的,麻烦大家帮我看看,这个帖子我继续加分PS:我所有的代码都是在filter类中实现的,没有单独定义PIN类,视频流类型为MEDIASUBTYPE_ARGB32
看名字似乎不是相素,那循环用(dwFileSize >> 2)试试再有这里循环这样写不太好,因为有pitch,还是循环height和width比较好