directshow如何完全释放资源

时间:2022-01-29 03:39:52
小弟我刚学习directshow,我播放一个视频文件后释放了所有的资源,再用文件IO操作该视频文件,为什么提示有其他进程正在使用该文件呢, 我该如何做到完全释放directshow对文件的占用呢?简单的示例代码如下:

// PlayFileSample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <DShow.h>
#pragma comment(lib,"strmbasd.lib")
int main(int argc, char* argv[])
{
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
return 1;
}

IGraphBuilder *pGraph;
hr = CoCreateInstance(CLSID_FilterGraph,NULL,
CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **) &pGraph);

IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pEvent);

hr = pGraph->RenderFile(L"D:\\20110101125201.AVI",NULL);
hr = pControl->Run();

long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);

long pCon = pControl->Release();
pControl = NULL;
long pEve = pEvent->Release();
pEvent = NULL;
long pGra = pGraph->Release();
pGra = NULL;

printf("pCon = %ld, pEve = %ld, pGra = %ld \n",pCon,pEve,pGra);
CoUninitialize();

HANDLE hFile = CreateFile("D:\\20110101125201.AVI",GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
LPVOID msgBuf;
DWORD nErrorCode = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
  0,
  nErrorCode,
  0,
  (LPTSTR)&msgBuf,
  0,
  NULL);
MessageBox(0,(LPTSTR)msgBuf,"GetLastError",MB_OK|MB_ICONINFORMATION);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"open file fail!","Result",MB_OK);
}else
{
MessageBox(NULL,"open file success!","Result",MB_OK);
CloseHandle(hFile);
}

return 0;
}


9 个解决方案

#1


有没用close接口?

#2


引用 1 楼 ouyh12345 的回复:
有没用close接口?


请问你是说那个close接口

#3


IGraphBuilder

#4


   CoUninitialize();

//系统释放资源是需要时间的。所以你可以尝试在这里加一个等待函数。比如:Sleep()。因为这里的多媒体资源播放和释放线程不是这个线程,所以可以用这种方法来等待。


    Sleep(5000);
     
//  先试试等待5秒的效果,如果少了,可以再增加。不要设置的太小了,因为这个需要等待的时间一般是一个浮动的范围,而不是一个确定的时间。


    HANDLE hFile = CreateFile("D:\\20110101125201.AVI",GENERIC_WRITE|GENERIC_READ,
        FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);


#5


我也遇到这样的问题了。。。帮顶一下

#6


RenderFile的方式,会自动添加需要的filter进Graph。
释放的时候,枚举一下,都做RemoveFilter,然后释放,看看

#7


搞定了   释放过程要和初始化的过程反序。

#8


可否把OK后的code 贴出来看看啊!~

#9


引用 8 楼 listenli1213 的回复:
可否把OK后的code 贴出来看看啊!~


我举的例子里面没有找到完全释放的办法,但是在我另外一个程序里面,我调整了COM借口初始化和释放的顺序。文件就没被占用了。

#1


有没用close接口?

#2


引用 1 楼 ouyh12345 的回复:
有没用close接口?


请问你是说那个close接口

#3


IGraphBuilder

#4


   CoUninitialize();

//系统释放资源是需要时间的。所以你可以尝试在这里加一个等待函数。比如:Sleep()。因为这里的多媒体资源播放和释放线程不是这个线程,所以可以用这种方法来等待。


    Sleep(5000);
     
//  先试试等待5秒的效果,如果少了,可以再增加。不要设置的太小了,因为这个需要等待的时间一般是一个浮动的范围,而不是一个确定的时间。


    HANDLE hFile = CreateFile("D:\\20110101125201.AVI",GENERIC_WRITE|GENERIC_READ,
        FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);


#5


我也遇到这样的问题了。。。帮顶一下

#6


RenderFile的方式,会自动添加需要的filter进Graph。
释放的时候,枚举一下,都做RemoveFilter,然后释放,看看

#7


搞定了   释放过程要和初始化的过程反序。

#8


可否把OK后的code 贴出来看看啊!~

#9


引用 8 楼 listenli1213 的回复:
可否把OK后的code 贴出来看看啊!~


我举的例子里面没有找到完全释放的办法,但是在我另外一个程序里面,我调整了COM借口初始化和释放的顺序。文件就没被占用了。