//------------------------------------------------------------------------------
// File: PushSourceDesktop.cpp
//
// Desc: DirectShow sample code - In-memory push mode source filter
// Provides an image of the user's desktop as a continuously updating stream.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "PushSourceDesktop.h"
#include "DibHelper.h"
/**********************************************
*
* CPushPinDesktop Class
*
*
**********************************************/
CPushPinDesktop::CPushPinDesktop(HRESULT *phr, CSource *pFilter)
: CSourceStream(NAME("Push Source Desktop"), phr, pFilter, L"Out"),
m_FramesWritten(0),
m_bZeroMemory(0),
m_iFrameNumber(0),
m_rtFrameLength(FPS_5), // Capture and display desktop 5 times per second
m_nCurrentBitDepth(32)
{
m_pParent = (CPushSourceDesktop*)pFilter;
m_hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
// The main point of this sample is to demonstrate how to take a DIB
// in host memory and insert it into a video stream.
// To keep this sample as simple as possible, we just read the desktop image
// from a file and copy it into every frame that we send downstream.
//
// In the filter graph, we connect this filter to the AVI Mux, which creates
// the AVI file with the video frames we pass to it. In this case,
// the end result is a screen capture video (GDI images only, with no
// support for overlay surfaces).
// Get the device context of the main display
HDC hDC;
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
// Get the dimensions of the main desktop window
m_rScreen.left = m_rScreen.top = 0;
m_rScreen.right = GetDeviceCaps(hDC, HORZRES);
m_rScreen.bottom = GetDeviceCaps(hDC, VERTRES);
// Save dimensions for later use in FillBuffer()
m_iImageWidth = m_rScreen.right - m_rScreen.left;
m_iImageHeight = m_rScreen.bottom - m_rScreen.top;
// Release the device context
DeleteDC(hDC);
}
CPushPinDesktop::~CPushPinDesktop()
{
DbgLog((LOG_TRACE, 3, TEXT("Frames written %d"), m_iFrameNumber));
}
//
// GetMediaType
//
// Prefer 5 formats - 8, 16 (*2), 24 or 32 bits per pixel
//
// Prefered types should be ordered by quality, with zero as highest quality.
// Therefore, iPosition =
// 0 Return a 32bit mediatype
// 1 Return a 24bit mediatype
// 2 Return 16bit RGB565
// 3 Return a 16bit mediatype (rgb555)
// 4 Return 8 bit palettised format
// >4 Invalid
//
HRESULT CPushPinDesktop::GetMediaType(int iPosition, CMediaType *pmt)
{
CheckPointer(pmt,E_POINTER);
CAutoLock cAutoLock(m_pFilter->pStateLock());
if(iPosition < 0)
return E_INVALIDARG;
// Have we run off the end of types?
if(iPosition > 4)
return VFW_S_NO_MORE_ITEMS;
VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO));
if(NULL == pvi)
return(E_OUTOFMEMORY);
// Initialize the VideoInfo structure before configuring its members
ZeroMemory(pvi, sizeof(VIDEOINFO));
switch(iPosition)
{
case 0:
{
// Return our highest quality 32bit format
// Since we use RGB888 (the default for 32 bit), there is
// no reason to use BI_BITFIELDS to specify the RGB
// masks. Also, not everything supports BI_BITFIELDS
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 32;
break;
}
case 1:
{ // Return our 24bit format
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 24;
break;
}
case 2:
{
// 16 bit per pixel RGB565
// Place the RGB masks as the first 3 doublewords in the palette area
for(int i = 0; i < 3; i++)
pvi->TrueColorInfo.dwBitMasks[i] = bits565[i];
pvi->bmiHeader.biCompression = BI_BITFIELDS;
pvi->bmiHeader.biBitCount = 16;
break;
}
case 3:
{ // 16 bits per pixel RGB555
// Place the RGB masks as the first 3 doublewords in the palette area
for(int i = 0; i < 3; i++)
pvi->TrueColorInfo.dwBitMasks[i] = bits555[i];
pvi->bmiHeader.biCompression = BI_BITFIELDS;
pvi->bmiHeader.biBitCount = 16;
break;
}
case 4:
{ // 8 bit palettised
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 8;
pvi->bmiHeader.biClrUsed = iPALETTE_COLORS;
break;
}
}
// Adjust the parameters common to all formats
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = m_iImageWidth;
pvi->bmiHeader.biHeight = m_iImageHeight;
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->bmiHeader.biClrImportant = 0;
pvi->AvgTimePerFrame = 10000000 / 24;
SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
pmt->SetType(&MEDIATYPE_Video);
pmt->SetFormatType(&FORMAT_VideoInfo);
pmt->SetTemporalCompression(FALSE);
// Work out the GUID for the subtype from the header info.
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pmt->SetSubtype(&SubTypeGUID);
pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);
return NOERROR;
} // GetMediaType
//
// CheckMediaType
//
// We will accept 8, 16, 24 or 32 bit video formats, in any
// image size that gives room to bounce.
// Returns E_INVALIDARG if the mediatype is not acceptable
//
HRESULT CPushPinDesktop::CheckMediaType(const CMediaType *pMediaType)
{
CheckPointer(pMediaType,E_POINTER);
if((*(pMediaType->Type()) != MEDIATYPE_Video) || // we only output video
!(pMediaType->IsFixedSize())) // in fixed size samples
{
return E_INVALIDARG;
}
// Check for the subtypes we support
const GUID *SubType = pMediaType->Subtype();
if (SubType == NULL)
return E_INVALIDARG;
if( (*SubType != MEDIASUBTYPE_RGB8)
&& (*SubType != MEDIASUBTYPE_RGB565)
&& (*SubType != MEDIASUBTYPE_RGB555)
&& (*SubType != MEDIASUBTYPE_RGB24)
&& (*SubType != MEDIASUBTYPE_RGB32))
{
return E_INVALIDARG;
}
// Get the format area of the media type
VIDEOINFO *pvi = (VIDEOINFO *) pMediaType->Format();
if(pvi == NULL)
return E_INVALIDARG;
// Check if the image width & height have changed
if( pvi->bmiHeader.biWidth != m_iImageWidth ||
abs(pvi->bmiHeader.biHeight) != m_iImageHeight)
{
// If the image width/height is changed, fail CheckMediaType() to force
// the renderer to resize the image.
return E_INVALIDARG;
}
// Don't accept formats with negative height, which would cause the desktop
// image to be displayed upside down.
if (pvi->bmiHeader.biHeight < 0)
return E_INVALIDARG;
return S_OK; // This format is acceptable.
} // CheckMediaType
//
// DecideBufferSize
//
// This will always be called after the format has been sucessfully
// negotiated. So we have a look at m_mt to see what size image we agreed.
// Then we can ask for buffers of the correct size to contain them.
//
HRESULT CPushPinDesktop::De
没有合适的资源?快使用搜索试试~ 我知道了~
DirectShow虚拟摄像头源码, flash qq 可用
共58个文件
h:39个
suo:4个
cpp:3个
1星 需积分: 50 66 下载量 166 浏览量
2016-04-14
01:04:09
上传
评论 3
收藏 12.92MB ZIP 举报
温馨提示
从微软官网下载的DirectShow,用例子里面的pushsource改造而来的虚拟桌面摄像头。已测支持AmCap QQ 和 flash。里面有源码和编译好的dll文件。
资源推荐
资源详情
资源评论
收起资源包目录
VCamDesktop.zip (58个子文件)
VCamDesktop
DibHelper.cpp 2KB
VCamDesktop.sdf 34.06MB
baseclasses
baseclasses.v12.suo 23KB
lib
strmbasd.lib 4.84MB
strmbase.lib 3.41MB
include
transip.h 9KB
reftime.h 3KB
amextra.h 2KB
perfstruct.h 7KB
ctlutil.h 28KB
winctrl.h 10KB
seekpt.h 887B
cprop.h 4KB
source.h 6KB
wxutil.h 16KB
refclock.h 8KB
dllsetup.h 1KB
measure.h 8KB
wxlist.h 20KB
schedule.h 4KB
combase.h 10KB
dxmperf.h 10KB
renbase.h 21KB
amfilter.h 57KB
wxdebug.h 12KB
pullpin.h 4KB
pstream.h 4KB
outputq.h 5KB
mtype.h 3KB
checkbmi.h 4KB
perflog.h 1KB
videoctl.h 8KB
sysclock.h 1KB
streams.h 7KB
msgthrd.h 4KB
transfrm.h 10KB
fourcc.h 2KB
strmctl.h 6KB
winutil.h 17KB
ddmm.h 989B
vtrans.h 7KB
cache.h 3KB
VCamDesktop.sln 1KB
VCamDesktop.vcxproj 10KB
VCamDesktop.v12.suo 21KB
VirtualCameraDesk.v12.suo 28KB
PushSourceDesktop.def 499B
PushSourceDesktop.h 5KB
DibHelper.h 2KB
VCamDesktop.vcxproj.user 165B
VCamDesktop.vcxproj.filters 1KB
pushsource.v12.suo 43KB
PushSourceDesktop.cpp 20KB
setup.cpp 4KB
bin
注册.bat 27B
反注册.bat 30B
VCamDesktop.dll 42KB
pushsource.vcproj 8KB
共 58 条
- 1
资源评论
- willian342016-09-23纯属垃圾!
- 小侠csdnn2017-03-02纯属垃圾,浪费分!
mfl213
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功