1392人阅读
终于,经过漫长的百度搜索、学习、测验,要到了游戏的视频和音频。虽然还有很多局限性,但是结果是要到了音视频,存储到媒体文件。在此,把我的经验和方法分享一下。
局限性:仅适合平台,且我只在下用过,且只试过游戏《仙剑外传》。且游戏的最小化功能被弄得用不了了。对要求较高(因为要视频编码)。稳定性不确定。音频截取的方式也有些不可靠。
1)视频的采集
从最开始只知道的基本元素,到后来终于知道了一些。某天知道了的使用,顺利的显示了的序列图像,同时也能把窗体的图像下来,存好。由于工作上做了一些和视频编码相关的,所以就很顺利的截取到桌面的格式的序列图片,转成的,然后视频编码(一般要格式的)后存起来。
在某次玩《仙剑外传》时,突然想到自己应该能把里面的画面存成视频了,于是用上面采集桌面的方式试了试。有几个因素导致做不下去。首先是速度问题,采集一张的图像需要毫秒左右(的,的显卡),然后就是采集下来的图片很大概率不全(少房子或者少人物),当然后来试了一下在截之前给窗体发一个不要画的消息(现在都忘了是什么消息了),画面是全了,但是影响游戏,游戏玩的不正常。
百度和上说可以钩的来实现,可惜这个事情我真不会。
软件录视频好像还挺好使,就是当时不知道它什么原理。百度也搜不到想要的实现原理或者例子。
。。。。。。
过了比较长的一段时间后,明白了的,后来在上下到一个工程,可以截取进程的,程序很全,后来可能是由于不是很稳定(莫名奇妙死掉),而且没有在当时截到的,所以也慢慢心凉了,的出现让事情有了转机,至少它不那么容易随便死掉。是的,我最后就是靠着采集到视频。
这里并不想说有多强、多好,实际上我只会简单用,照着里的例子抄,最后还要考例子里生成的运行游戏。。。。。。
detours截取的还是非常简单的,照着例子抄就是了。主要截取的需要注意一些问题。我的运气不错,用了的接口,正好我对还有一定了解。所以我截到函数Direct3DCreate9(Ex),这样得到IDirect3D9指针,需要用此指针去截它的虚函数。我这里的目的是截取视频,所以我选择了截IDirect3DDevice9的函数方法,此方法是负责最后显示画面的,在调用它之前,我把画面复制一份保存下来,达到截取视频的目的。所以这里的顺序是截取IDirect3D9的方法CreateDevice得到IDirect3DDevice9指针,截取的方法,在取代的函数里面做处理。具体的实现后面会贴出一定的代码,以及提供整个工程下载的地址(版本),这里就不细说了。
函数D3DXLoadSurfaceFromSurface可以很快的从back表面转到(其它的原色空间不一定行)的离屏表面,然后拷贝下来数据,然后转成(用里的),存在某个空间,另起一个线程去取,做编码操作等。
截取虚方法时需要数地址,写过一次就知道怎么回事了。最基本的一个方法也是找到地址,把它覆盖成自己函数的地址。
没说清楚?没关心,我也没指望自己能说的清楚。反正最后也是最好的方法就是源代码了,看代码吧。虽然我的代码不规整,也极少有注释。
2)音频的采集
音频最后还是很伤士气的。我是先弄到了视频,然后也想用同样的方法去要音频,发现就截到一个的,,然后再也不知道它用了哪些相关的函数,上面的截的方法就行不通了。不顺利。后来听说可以采集声卡的声音,然而百度时很难分辨它是说截麦克风还是电脑播出的声音。然后看到一篇,“”,说可以采集电脑发出的声音,半信半疑的跟着它写,最后发现这不就是采集麦克风的代码吗,因为以前写过。。。。。。指望枚举不同设备来实现?发现我的机器就一个输出声卡设备。结果自然是没要到想要的结果。
但是戏剧性剧情发生,把立体声混音的音量选项钩上(麦克风的自然没了),上面那段截麦克风的代码结果截到电脑播放出的声音了。。。。。。这里还要说的是在上没找到那个设置,据说可以通过注册表修改,我就不找那些事了。还有说最新的声卡驱动为防拷贝,把立体声混音的功能弄没了,如果这样,这个方法就完全没用了。
就这样在特定的条件下,也就顺利要到音频了。
接下来的事就好办了,把音视频弄到一起,注意时间同步,编码后存到一个文件,最终形成媒体文件,达到记录的效果。
3)工程主要是利用的库做一个,用里的运行游戏,把做的加载到游戏的进程中,然后里会截取上面视频采集说的一些函数,在替代函数里做相应的处理。下面会贴出代码。
我这里其实基本的要素都有了,但很不全。我是希望大家一起学习讨论,指出我这里的不足、或者给出更好的方案。还有一些问题的解决,如最小化的问题,音频采集是不是有更好的方式?
整个工程在我的上传资源应该有一份,其中afterglow是在ffmpeg上自己写的一个库,包括原始音视频数据编码存储媒体文件功能。
//////////////////////////////////////////////////////////////////////////////
Detour Test Program (extend.cpp of extend.dll)
Microsoft Research Detours Package, Version 3.0.
Copyright (c) Microsoft Corporation.
All rights reserved.
An example dynamically detouring a function.
#include &stdio.h&
#include &windows.h&
#include &detours.h&
#include &ddraw.h&
#include &d3dx9.h&
#include &DSound.h&
#include &afterglow.h&
#pragma comment(lib, &detours.lib&)
#pragma comment(lib, &d3dx9.lib&)
#pragma comment(lib, &afterglow.lib&)
#pragma comment(lib, &Winmm.lib&)
#pragma comment(lib, &dsound.lib&)
#pragma comment(lib, &dxguid.lib&)
typedef struct KSDT_frame
struct KSDT_struct
char outfilename[1024];
double pred_time, pred_
int frameR
IDirect3DDevice9 *pD
IDirect3DSurface9 *pOffscreenS // D3DFMT_X8R8G8B8??
IDirect3DSurface9* pB
pifu::ks_image_t *pPicSrc, *pPicDst, *pPicBGR;
pifu::KsSwscale sws, sws1;
pifu::KsOutputFormat *pOF;
pifu::KsPacketMalloc&KSDT_frame& *pFrameMalloc, *pAudioM
pifu::KsPacketOrder&KSDT_frame& *pFrameOrder, *pAudioO
int64_t frameK
pifu::KsThread *pT
int thread_
pifu::KsThread *pAudioT
__int64 baseVideoTime, baseAudioTime, baseT
static int (WINAPI * True_EntryPoint)(VOID) = NULL;
typedef HRESULT (WINAPI *FuncDirectDrawCreate)( GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *);
typedef HRESULT (WINAPI *FuncDirectDrawCreateEx)( GUID FAR *, LPVOID *, REFIID, IUnknown FAR *);
typedef IDirect3D9 * (WINAPI *FuncDirect3DCreate9)(UINT SDKVersion);
typedef HRESULT (WINAPI *FuncD3DCreateDevice)(void *pThis,UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface);
typedef HRESULT (WINAPI *FuncD3DDevicePresent)(void *pThis,CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
typedef HRESULT (WINAPI *FuncDirectSoundCreate8)( LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter);
FuncDirectDrawCreate True_DirectDrawCreate = NULL;
FuncDirectDrawCreateEx True_DirectDrawCreateEx = NULL;
FuncDirect3DCreate9 True_Direct3DCreate9 = NULL;
FuncD3DCreateDevice True_D3DCreateDevice = NULL;
FuncD3DDevicePresent True_D3DDevicePresent = NULL;
FuncDirectSoundCreate8 True_DirectSoundCreate8 = NULL;
int WINAPI DT_EntryPoint();
HRESULT WINAPI DT_DirectDrawCreate( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
HRESULT WINAPI DT_DirectDrawCreateEx( GUID FAR * lpGuid, LPVOID
*lplpDD, REFIID
iid,IUnknown FAR *pUnkOuter );
IDirect3D9 * WINAPI DT_Direct3DCreate9(UINT SDKVersion);
HRESULT WINAPI DT_D3DCreateDevice(void *pThis,UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface);
HRESULT WINAPI DT_D3DDevicePresent(void *pThis,CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
HRESULT WINAPI DT_DirectSoundCreate8( LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter);
static void SaveThread(void *);
static void AudioThread(void *);
static void LogMessage(const char * msg)
static FILE * logFile = fopen(&D:\\DetoursLog.txt&, &w&);
fprintf(logFile, msg);
fflush(logFile);
//MMRESULT waveOutOpen(
LPHW***EOUT
uDeviceID,
LPW***EFORMATEX pwfx,
dwCallback,
dwCallbackInstance,
MMRESULT (WINAPI * True_waveOutOpen)(
LPHW***EOUT phwo,
UINT uDeviceID,
LPCW***EFORMATEX pwfx,
DWORD_PTR dwCallback,
DWORD_PTR dwInstance,
DWORD fdwOpen
) = waveOutO
MMRESULT (WINAPI * True_waveOutWrite)( HW***EOUT hwo, LPW***EHDR pwh, UINT cbwh) = waveOutW
MMRESULT (WINAPI * True_waveOutClose)( HW***EOUT hwo) = waveOutC
BOOL (WINAPI*
True_PlaySoundW)( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound) = PlaySoundW;
BOOL (WINAPI*
True_PlaySoundA)( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound) = PlaySoundA;
MMRESULT(WINAPI* True_waveOutPrepareHeader)( HW***EOUT hwo, LPW***EHDR pwh,
UINT cbwh) = waveOutPrepareH
MMRESULT WINAPI DT_waveOutOpen(
LPHW***EOUT phwo,
UINT uDeviceID,
LPCW***EFORMATEX pwfx,
DWORD_PTR dwCallback,
DWORD_PTR dwInstance,
DWORD fdwOpen
//LogMessage(&DT_DLL.dll: DT_waveOutOpen Call\n&);
MMRESULT hr = True_waveOutOpen(phwo, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen);
//char msg[128];
//sprintf(msg, &%x %u %u %u %u %u %u %u\n&, phwo==NULL?0:(*phwo), uDeviceID, pwfx-&wBitsPerSample,
pwfx-&nChannels, pwfx-&nSamplesPerSec, dwCallback, dwInstance, fdwOpen);
//LogMessage(msg);
MMRESULT WINAPI DT_waveOutWrite( HW***EOUT hwo, LPW***EHDR pwh, UINT cbwh)
char msg[128];
sprintf(msg, &write: %x %u %u %u\n&, hwo, pwh-&dwBufferLength, pwh-&dwFlags, pwh-&dwLoops);
LogMessage(msg);
return True_waveOutWrite(hwo, pwh, cbwh);
MMRESULT WINAPI DT_waveOutClose( HW***EOUT hwo)
char msg[128];
sprintf(msg, &close: %x\n&, hwo);
LogMessage(msg);
return True_waveOutClose(hwo);
BOOL WINAPI DT_PlaySoundW( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
LogMessage(&DT_PlaySound\n&);
return True_PlaySoundW(pszSound, hmod, fdwSound);
BOOL WINAPI DT_PlaySoundA( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound)
LogMessage(&DT_PlaySound\n&);
return True_PlaySoundA(pszSound, hmod, fdwSound);
MMRESULT WINAPI DT_waveOutPrepareHeader( HW***EOUT hwo, LPW***EHDR pwh,
UINT cbwh)
LogMessage(&True_waveOutPrepareHeader\n&);
return True_waveOutPrepareHeader(hwo, pwh, cbwh);
int WINAPI DT_EntryPoint()
// We couldn't call LoadLibrary in DllMain, so our functions here.
// We separate out the functions in the export table (Target)
// from the ones that require debug symbols (Hidden).
True_DirectDrawCreate = (FuncDirectDrawCreate)DetourFindFunction(&ddraw.dll&, &DirectDrawCreate&);
True_DirectDrawCreateEx = (FuncDirectDrawCreateEx)DetourFindFunction(&ddraw.dll&, &DirectDrawCreateEx&);
True_Direct3DCreate9 = (FuncDirect3DCreate9)DetourFindFunction(&d3d9.dll&, &Direct3DCreate9&);
//True_DirectSoundCreate8 = (FuncDirectSoundCreate8)DetourFindFunction(&dsound.dll&, &DirectSoundCreate8&);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)True_DirectDrawCreate, DT_DirectDrawCreate);
DetourAttach(&(PVOID&)True_DirectDrawCreateEx, DT_DirectDrawCreateEx);
DetourAttach(&(PVOID&)True_Direct3DCreate9, DT_Direct3DCreate9);
//DetourAttach(&(PVOID&)True_DirectSoundCreate8, DT_DirectSoundCreate8);
//DetourAttach(&(PVOID&)True_waveOutOpen, DT_waveOutOpen);
//DetourAttach(&(PVOID&)True_waveOutWrite, DT_waveOutWrite);
//DetourAttach(&(PVOID&)True_waveOutClose, DT_waveOutClose);
//DetourAttach(&(PVOID&)True_PlaySoundW, DT_PlaySoundW);
//DetourAttach(&(PVOID&)True_PlaySoundA, DT_PlaySoundA);
//DetourAttach(&(PVOID&)True_waveOutPrepareHeader, DT_waveOutPrepareHeader);
DetourTransactionCommit();
LogMessage(&DT_DLL.dll: Calling EntryPoint\n&);
return True_EntryPoint();
HRESULT WINAPI DT_DirectDrawCreate( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter )
LogMessage(&DT_DLL.dll: DT_DirectDrawCreate Call\n&);
HRESULT hr = True_DirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
HRESULT WINAPI DT_DirectDrawCreateEx( GUID FAR * lpGuid, LPVOID
*lplpDD, REFIID
iid,IUnknown FAR *pUnkOuter )
LogMessage(&DT_DLL.dll: DT_DirectDrawCreateEx Call\n&);
HRESULT hr = True_DirectDrawCreateEx(lpGuid, lplpDD, iid, pUnkOuter);
IDirect3D9 * WINAPI DT_Direct3DCreate9(UINT SDKVersion)
LogMessage(&DT_DLL.dll: DT_Direct3DCreate9 Call\n&);
IDirect3D9 * pd3d = True_Direct3DCreate9(SDKVersion);
int **ppInt = (int**)(pd3d);
True_D3DCreateDevice = (FuncD3DCreateDevice)((*ppInt)[16]);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)True_D3DCreateDevice, DT_D3DCreateDevice);
DetourTransactionCommit();
return pd3d;
HRESULT WINAPI DT_DirectSoundCreate8( LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter)
LogMessage(&DT_DLL.dll: DT_DirectSoundCreate8 Call\n&);
return True_DirectSoundCreate8(pcGuidDevice, ppDS8, pUnkOuter);
HRESULT WINAPI DT_D3DCreateDevice(void *pThis,UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface)
LogMessage(&DT_DLL.dll: DT_D3DCreateDevice Call\n&);
HRESULT hr = True_D3DCreateDevice(pThis, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
if (hr == D3D_OK)
ksdt.pDevice = *ppReturnedDeviceI
ksdt.hwnd = hFocusWindow == NULL ? pPresentationParameters-&hDeviceWindow : hFocusW
ksdt.w = pPresentationParameters-&BackBufferW
ksdt.h = pPresentationParameters-&BackBufferH
//ksdt.oufile = fopen(&D:\\nony.data&, &wb&);
HRESULT hr1 = ksdt.pDevice-&CreateOffscreenPlainSurface(ksdt.w, ksdt.h, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ksdt.pOffscreenSurface, NULL);
// init for save media
ksdt.pPicSrc = new pifu::ks_image_t(PIFU_CSP_BGRA, ksdt.w, ksdt.h);
ksdt.pPicDst = new pifu::ks_image_t(PIFU_CSP_I420, ksdt.w, ksdt.h);
ksdt.pPicBGR = new pifu::ks_image_t(PIFU_CSP_BGR, ksdt.w, ksdt.h);
ksdt.pFrameMalloc = new pifu::KsPacketMalloc&KSDT_frame&(ksdt.w*ksdt.h*3/2, 5, 20);
ksdt.pFrameOrder
= new pifu::KsPacketOrder&KSDT_frame&(0);
ksdt.pAudioMalloc = new pifu::KsPacketMalloc&KSDT_frame&(, 512);
ksdt.pAudioOrder
= new pifu::KsPacketOrder&KSDT_frame&(0);
ksdt.frameRate = 60;
ksdt.pred_avg = 1.0/ksdt.frameR
pifu::ks_codecinfo_t infos[2];
int b = 0;
infos[b].m_id =
infos[b].m_codec = pifu::KSFF_CODEC_H264;
infos[b].m_flag = 0;
infos[b].m_vwidth = ksdt.w;
infos[b].m_vheight = ksdt.h;
infos[b].m_vframerate_num = ksdt.frameR
infos[b].m_vframerate_den = 1;
infos[b].m_bitrate = 3000000;
ksdt.samplerate = 48000;
ksdt.channels = 2;
int a = 1;
infos[a].m_id =
infos[a].m_codec = pifu::KSFF_CODEC_AAC;
infos[a].m_flag = 0;
infos[a].m_asamplerate = ksdt.
infos[a].m_achannels = ksdt.
infos[a].m_awbits = 16;
infos[a].m_bitrate = 128000;
strcpy(ksdt.outfilename, &D:\\ww.mkv&);
ksdt.pOF = new pifu::KsOutputFormat(ksdt.outfilename, 2, infos/*, 2*/);
ksdt.baseVideoTime = ksdt.baseAudioTime = -1;
::QueryPerformanceFrequency((LARGE_INTEGER*)&ksdt.baseTime);
ksdt.thread_state = 1;
ksdt.pThread = new pifu::KsThread(SaveThread, 0);
ksdt.pAudioThread = new pifu::KsThread(AudioThread, 0);
int **ppInt = (int**)(*ppReturnedDeviceInterface);
True_D3DDevicePresent = (FuncD3DDevicePresent)((*ppInt)[17]);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)True_D3DDevicePresent, DT_D3DDevicePresent);
DetourTransactionCommit();
HRESULT WINAPI DT_D3DDevicePresent(void *pThis,CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion)
//::GetWindowRect(ksdt.hwnd, &r);
////if (r.left != 0)
char msg[128];
sprintf(msg, &%d %d %d %d\n&, r.left, r.right, r.top, r.bottom);
LogMessage(msg);
//return True_D3DDevicePresent(pThis, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
if (!ksdt.kst_init)
ksdt.kst_init =
ksdt.kst.restart();
QueryPerformanceCounter((LARGE_INTEGER*)&ksdt.baseVideoTime);
ksdt.pred_count = 0;
ksdt.pred_time = 0;
double t = ksdt.kst.get_elapsed() + 0.002; // 0.002??修正值??
if (t &= ksdt.pred_time)
while (ksdt.pred_count*ksdt.pred_avg & t) ksdt.pred_count++;
HRESULT hr1;
if (ksdt.pBack == NULL)
ksdt.pDevice-&GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &ksdt.pBack);
hr1 = D3DXLoadSurfaceFromSurface(ksdt.pOffscreenSurface, 0, 0, ksdt.pBack, 0, 0, D3DX_FILTER_NONE, 0);
if (hr1 == D3D_OK)
D3DLOCKED_RECT
ksdt.pOffscreenSurface-&LockRect(&r, 0, D3DLOCK_READONLY);
memcpy(ksdt.pPicSrc-&plane[0], r.pBits, ksdt.w*ksdt.h*4);
ksdt.pOffscreenSurface-&UnlockRect();
ksdt.sws.scale(ksdt.pPicSrc, ksdt.pPicBGR);
ksdt.sws1.scale(ksdt.pPicBGR, ksdt.pPicDst);
KSDT_frame *p = ksdt.pFrameMalloc-&getBuffer();
if (p != NULL){
p-&pts = (int64_t)((ksdt.pred_count-1)*ksdt.pred_avg*1000 + 0.5);
p-&len = ksdt.w * ksdt.h *3/2;
memcpy(p-&buf, ksdt.pPicDst-&plane[0], p-&len);
ksdt.pFrameOrder-&putBuffer(ksdt.frameKey++, p);
ksdt.pred_time = ksdt.pred_count*ksdt.pred_
return True_D3DDevicePresent(pThis, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
if (DetourIsHelperProcess()) {
return TRUE;
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
LogMessage(&DT_DLL.dll: Starting.\n&);
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
True_EntryPoint = (int (WINAPI *)())DetourGetEntryPoint(NULL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)True_EntryPoint, DT_EntryPoint);
error = DetourTransactionCommit();
if (error == NO_ERROR)
LogMessage(&DT_DLL.dll: Detoured EntryPoint().\n&);
LogMessage(&DT_DLL.dll: Error detouring EntryPoint(). \n&);
else if (dwReason == DLL_PROCESS_DETACH) {
LogMessage(&DT_DLL.dll: DETACH\n&);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Detach functions found from the export table.
if (True_DirectDrawCreate != NULL)
DetourDetach(&(PVOID&)True_DirectDrawCreate, (PVOID)DT_DirectDrawCreate);
if (True_DirectDrawCreateEx != NULL)
DetourDetach(&(PVOID&)True_DirectDrawCreateEx, (PVOID)DT_DirectDrawCreateEx);
if (True_Direct3DCreate9 != NULL)
DetourDetach(&(PVOID&)True_Direct3DCreate9, (PVOID)DT_Direct3DCreate9);
//if (True_DirectSoundCreate8 != NULL)
DetourDetach(&(PVOID&)True_DirectSoundCreate8, DT_DirectSoundCreate8);
if (True_D3DCreateDevice != NULL)
DetourDetach(&(PVOID&)True_D3DCreateDevice, (PVOID)DT_D3DCreateDevice);
if (True_D3DDevicePresent != NULL)
DetourDetach(&(PVOID&)True_D3DDevicePresent, (PVOID)DT_D3DDevicePresent);
//DetourDetach(&(PVOID&)True_waveOutOpen, DT_waveOutOpen);
//DetourDetach(&(PVOID&)True_waveOutWrite, DT_waveOutWrite);
//DetourDetach(&(PVOID&)True_waveOutClose, DT_waveOutClose);
//DetourDetach(&(PVOID&)True_PlaySoundW, DT_PlaySoundW);
//DetourDetach(&(PVOID&)True_PlaySoundA, DT_PlaySoundA);
//DetourDetach(&(PVOID&)True_waveOutPrepareHeader, DT_waveOutPrepareHeader);
// Detach the entry point.
DetourDetach(&(PVOID&)True_EntryPoint, DT_EntryPoint);
error = DetourTransactionCommit();
// destroy??
if (ksdt.pThread != NULL){
ksdt.thread_state = 0;
ksdt.pThread-&join();
KS_SAFE_DELETE(ksdt.pThread);
if (ksdt.pAudioThread != NULL){
ksdt.pAudioThread-&join();
KS_SAFE_DELETE(ksdt.pAudioThread);
if (ksdt.pFrameMalloc != NULL && ksdt.pFrameOrder != NULL)
ksdt.pFrameMalloc-&freeBuffer(ksdt.pFrameOrder-&getClear());
KS_SAFE_DELETE(ksdt.pFrameMalloc);
KS_SAFE_DELETE(ksdt.pFrameOrder);
//if (ksdt.pAudioMalloc != NULL && ksdt.pAudioOrder != NULL)
ksdt.pAudioMalloc-&freeBuffer(ksdt.pAudioOrder-&getClear());
KS_SAFE_DELETE(ksdt.pAudioMalloc);
KS_SAFE_DELETE(ksdt.pAudioOrder);
KS_SAFE_DELETE(ksdt.pOF);
KS_SAFE_DELETE(ksdt.pPicSrc);
KS_SAFE_DELETE(ksdt.pPicBGR);
KS_SAFE_DELETE(ksdt.pPicDst);
return TRUE;
static void SaveThread(void *)
KSDT_frame *pA=NULL, *pV=NULL;
::timeBeginPeriod(1);
__int64 dav = 0x00LL, based = 0;
bool vBool =
bool aBool =
while (true)
if (ksdt.thread_state == 0)
if (pV==NULL) pV = ksdt.pFrameOrder-&getBuffer();
if (pA==NULL) pA = ksdt.pAudioOrder-&getBuffer();
if (pV == NULL && pA == NULL){
if (!vBool || !aBool){
if (pV!=NULL) { ksdt.pFrameMalloc-&freeBuffer(pV); pV=NULL; vBool = }
if (pA!=NULL) { ksdt.pAudioMalloc-&freeBuffer(pA); pA=NULL; aBool = }
if (dav == 0x00LL){
if (pV == NULL || pA == NULL) {
dav = (ksdt.baseVideoTime - ksdt.baseAudioTime) * 1000/ksdt.baseT
//char msg[128];
//sprintf(msg, &dav: %I64d %I64d %I64d\n&, dav, pV-&pts, pA-&pts);
//LogMessage(msg);
if (pV-&pts &= pA-&pts - dav){
based = pV-&
based = pA-&pts -
if (pA == NULL){
ksdt.pOF-&input_data(0, pV-&buf, pV-&len, pV-&pts-based, 0);
ksdt.pFrameMalloc-&freeBuffer(pV); pV=NULL;
}else if (pV == NULL){
ksdt.pOF-&input_data(1, pA-&buf, pA-&len, pA-&pts-dav-based, 1);
ksdt.pAudioMalloc-&freeBuffer(pA); pA=NULL;
if (pV-&pts &= pA-&pts - dav){
ksdt.pOF-&input_data(0, pV-&buf, pV-&len, pV-&pts-based, 0);
ksdt.pFrameMalloc-&freeBuffer(pV); pV=NULL;
ksdt.pOF-&input_data(1, pA-&buf, pA-&len, pA-&pts-dav-based, 1);
ksdt.pAudioMalloc-&freeBuffer(pA); pA=NULL;
::timeEndPeriod(1);
static void AudioThread(void *)
LPDIRECTSOUNDCAPTURE8 lpDSC = NULL;
LPDIRECTSOUNDCAPTUREBUFFER lpDSCBuffer = NULL;
HRESULT hr = DirectSoundCaptureCreate8(
DSCBUFFERDESC
LPDIRECTSOUNDCAPTUREBUFFER
W***EFORMATEX
{ W***E_FORMAT_PCM, ksdt.channels, ksdt.samplerate, ksdt.samplerate*ksdt.channels*2, 4, 16, 0 };
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = wfx.nAvgBytesPerS // 1秒的数据
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
hr = lpDSC-&CreateCaptureBuffer(&dscbd, &lpDSCBuffer, NULL);
//hr = pDSCB-&QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)lpDSCBuffer); /* 此函数不知为何会调用失败,所以不转接口了 */
//pDSCB-&Release();
char msg[128];
sprintf(msg, &hr: %d\n&, hr);
LogMessage(msg);
if (lpDSCBuffer == NULL)
//lpDSCBuffer-&Release();
//lpDSC-&Release();
hr = lpDSCBuffer-&Start(DSCBSTART_LOOPING);
DWORD capPos, readP
int LEN = ksdt.samplerate*ksdt.channels*2;
int starts = 0,
pifu::ks_packet_t pkt(LEN*2);
int bBase =
int framesize = 4096;
__int64 totalsize = 0, key = 0;
KSDT_frame *p;
LPVOID ptr1, ptr2;
DWORD bytes1, bytes2;
if (ksdt.thread_state == 0)
Sleep(20);
hr = lpDSCBuffer-&GetCurrentPosition(&capPos, &readPos);
if (!bBase)
QueryPerformanceCounter((LARGE_INTEGER*)&ksdt.baseAudioTime);
starts = readP
if (readPos & starts){
len = (LEN - starts) + readP
else len = readPos-
lpDSCBuffer-&Lock(starts, len, &ptr1, &bytes1, &ptr2, &bytes2, 0);
pkt.append((uint8_t*)ptr1, bytes1);
if (ptr2 != 0)
pkt.append((uint8_t*)ptr2, bytes2);
lpDSCBuffer-&Unlock(ptr1, bytes1, ptr2, bytes2);
starts = readP
if (pkt.size &= framesize)
int j = 0;
while (j + framesize &= pkt.size)
p = ksdt.pAudioMalloc-&getBuffer();
memcpy(p-&buf, pkt.data+j, framesize);
p-&pts = totalsize * 1000 / LEN;
sprintf(msg, &hr: %I64d\n&, p-&pts);
LogMessage(msg);
ksdt.pAudioOrder-&putBuffer(key++, p);
totalsize +=
if (j & pkt.size)
memmove(pkt.data, pkt.data+j, pkt.size-j);
pkt.size -=
lpDSCBuffer-&Stop();
lpDSC-&Release();
///////////////////////////////////////////////////////////////// End of File.
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15911次
排名:千里之外
评论:22条
(1)(1)(1)(2)(1)(1)