今天要用DirectShow做一个音频采集程序,结果遇到的第一个问题便是开发环境的搭建,需要几步准备。
1)下载支持DirectShow的SDK
2)将SDK中的include和lib目录配置到VC6.0下(一般SDK在安装过程中会自己配置)
3)编译SDK中samples中提供的项目,得到Strmbasd.lib winmm.lib库文件,这个要在新建的DirectShow工程中引用
第一步,我为了能够开发DirectShow程序,曾想过用VC6.0或者VS2005,只要这两个有一个配置成功了,我便用哪个,因为我对开发环境并不关注。
我先后下载并安装了微软提供的两个SDK,一个是Windows.Server.2003.Platform.SDK.Feb.2003.Edition-QUANTUM,另一个是DXSDK_Aug08。这两个到后来我没有配置成功,所以这里略过,我没配置成功不代表别人就配置不成。
我最后下载了成功配置的SDK,这就是dx9sdk,在百度里搜索“DirectX9.0b SDK Summer 2003”应该可以搜到并下载。安装之后,果然有这个目录:<SDK root>\SAMPLES\C++\DirectShow\BASECLASSES
下面,进入第二步。
第二步,打开VC6.0
Tools->Options->Directories
Include - 添加<SDK root>\Include
Lib - 添加<SDK root>\Lib
- 添加<SDK root>\SAMPLES\C++\DirectShow\BASECLASSES\DEBUG //这个目录在第3步之后会出现的
第三步,对于<SDK root>\SAMPLES\C++\DirectShow\BASECLASSES的编译,我要转引网上一篇我十分感激的文章:
转引开始:
我也是个初学者,要是以下的文章有什么错误,请给我留言,谢谢!
[1] 请确保您的机子上已经安装了VS 2005和DirectX 9.0b SDK。DX9.0 SDK的下载地址就不写了,自己在网上找吧!(我的DX9.0安装在D盘根目录下)
[2] 首先编译SamplesC++DirectShowBaseClasses目录下的baseclasses.sln以得到两个库文件(strbase.lib和strmbase.lib)。以下介绍的主要是如何修改编译中的错误,这也是众多文章中没有叙述的部分。自己写的,有些啰嗦,请原谅哦!
进入DirectShow的安装目录,找到SamplesC++DirectShowBaseClasses,双击baseclasses.sln打开该解决方案。首先看到的会是Visual Studio的转换向导,不用管它,直接Next到Finish。
点击F5,调试运行,你会见到下面的错误(至少我编译的时候就是这样的结果):
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>dllentry.cpp
1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(222) : error C2146: syntax error : missing ';' before identifier 'PVOID64'
1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(222) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(5940) : error C2146: syntax error : missing ';' before identifier 'Buffer'
1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(5940) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(5940) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:DXSDKSamplesC++DirectShowBaseClassesctlutil.h(278) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:DXSDKincludeuuids.h : warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss
1>Build log was saved at "file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 6 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
没办法,改错。(网上老外的文章中说过,不过也不明白什么意思!)
双击1>D:Program FilesMicrosoft Visual Studio 8VCPlatformSDKincludewinnt.h(222) : error C2146: syntax error : missing ';' before identifier 'PVOID64' 跳转到出错的位置。
你会见到错误语句:typedef void * POINTER_64 PVOID64;
这样的定义,VS2005中是不支持的。将其修改为两条语句:
#define POINTER_64 __ptr64
typedef void *PVOID;
typedef void *POINTER_64 PVOID64;
然后调试运行,会发现还有1条错误:
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>dllentry.cpp
1>d:DXSDKSamplesC++DirectShowBaseClassesctlutil.h(278) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:DXSDKincludeuuids.h : warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss
1>Build log was saved at "file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 1 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
只有继续改啦!双击1>d:DXSDKSamplesC++DirectShowBaseClassesctlutil.h(278) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 跳转到出错的位置。
你会见到错误语句:operator=(LONG);
只是没有返回值嘛!给它加一个就行了,将其改为:LONG operator=(LONG);
再次调试运行,哇塞!更多错误:
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>wxdebug.cpp
1>.wxdebug.cpp(534) : warning C4996: '_vsnwprintf' was declared deprecated
1> D:Program FilesMicrosoft Visual Studio 8VCincludestdio.h(450) : see declaration of '_vsnwprintf'
1> Message: 'This function or variable may be unsafe. Consider using _vsnwprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See _disibledevent="file:///d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm">file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 10 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
有错就改啦!双击1>.wxdebug.cpp(567) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 跳到出错位置。
你会见到出错语句:static g_dwLastRefresh = 0;
静态类型变量有这么定义的吗?总得给个类型吧!将其改为:static DWORD g_dwLastRefresh = 0;为什么类型指定为DWORD?看程序中的语句就明白了——保证相同类型的变量进行运算。
再次调试运行:
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>winutil.cpp
1>.winutil.cpp(2104) : error C2065: 'Count' : undeclared identifier
1>.winutil.cpp(2106) : error C2228: left of '.peRed' must have class/struct/union
1>.winutil.cpp(2106) : error C2228: left of '.peRed' must have class/struct/union
1>.winutil.cpp(2107) : error C2228: left of '.peGreen' must have class/struct/union
1>.winutil.cpp(2107) : error C2228: left of '.peGreen' must have class/struct/union
1>.winutil.cpp(2108) : error C2228: left of '.peBlue' must have class/struct/union
1>.winutil.cpp(2108) : error C2228: left of '.peBlue' must have class/struct/union
1>.winutil.cpp(2124) : error C2228: left of '.peFlags' must have class/struct/union
1>outputq.cpp
1>.outputq.cpp(664) : error C2065: 'iDone' : undeclared identifier
1>Generating Code...
1>Build log was saved at "file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 9 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
错误少了一个哦!继续努力!双击1>.winutil.cpp(2104) : error C2065: 'Count' : undeclared identifier跳到出错位置。
你会见到出错语句:for (Count = 0;Count < Result;Count++) {
Count没有定义?看该语句上面的语句:
for (UINT Count = 0;Count < Result;Count++) {
if (SystemEntries[Count].peRed != pEntry[Count].peRed ||
SystemEntries[Count].peGreen != pEntry[Count].peGreen ||
SystemEntries[Count].peBlue != pEntry[Count].peBlue) {
bIdentityPalette = FALSE;
}
}
// And likewise compare against the last ten entries
Result = GetSystemPaletteEntries(hdc,PalHiStart,PalLoCount,SystemEntries);
看到了吧!Count是在循环体内定义的变量,出了循环之后就“生命”over了。所以将它定义到外面去。将以上的语句改为:
UINT Count = 0;
for (Count = 0;Count < Result;Count++) {
if (SystemEntries[Count].peRed != pEntry[Count].peRed ||
SystemEntries[Count].peGreen != pEntry[Count].peGreen ||
SystemEntries[Count].peBlue != pEntry[Count].peBlue) {
bIdentityPalette = FALSE;
}
}
// And likewise compare against the last ten entries
Result = GetSystemPaletteEntries(hdc,PalHiStart,PalLoCount,SystemEntries);
再次调试运行:
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>winutil.cpp
1>outputq.cpp
1>.outputq.cpp(664) : error C2065: 'iDone' : undeclared identifier
1>Generating Code...
1>Build log was saved at "file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
不错哦!错误剩下一个了!再改,双击1>.outputq.cpp(664) : error C2065: 'iDone' : undeclared identifier
跳到出错位置。
你会见到出错语句:*nSamplesProcessed = iDone - iLost;
iDone没有定义?OK,继续看它上面的语句:
// Loop processing the samples in batches
LONG iLost = 0;
for (long iDone = 0;
iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway);
) {
// ...
同样的,将iDone的定义放到循环体的外面去,改为:
// Loop processing the samples in batches
LONG iLost = 0;
long iDone = 0;
for (iDone = 0;
iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway);
) {
// ...
改完了以后,再次调试运行:
1>------ Build started: Project: BaseClasses, Configuration: Debug Unicode Win32 ------
1>Compiling...
1>outputq.cpp
1>Creating library...
1>Build log was saved at "file://d:DXSDKSamplesC++DirectShowBaseClassesDebug_UnicodeBuildLog.htm"
1>BaseClasses - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
总算见到succeeded了,呵呵!你调出来了吗?
转引结束 原文地址如下:http://blog.chinaunix.net/u1/33950/showart_716130.html
上面的转引,讲述了如何编译出我们需要的库文件Strmbasd.lib,按照转引上的方法生成了这个库文件后,在VC6.0的Project->Setting->Link
添加Strmbasd.lib winmm.lib
以上准备结束之后,就可以编译我们的DirectShow程序啦~~~
一个参考源代码,可以用来测试
#include <Dshow.h>
#include <Streams.h>
#include <stdio.h>
void main(void)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// Build the graph. IMPORTANT: Change this string to a file on your system.
// hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
hr = pGraph->RenderFile(L"E:\\DX90SDK\\Samples\\Media\\chicken.wmv", NULL); // 打开一个媒体文件
if (SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it
// can block indefinitely.
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
完。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/out_of_memory/archive/2008/12/10/3486726.aspx