![](/img/trans.png)
[英]DirectShow C++ : wrong duration and Fps in resulting avi file
[英]Convert AVI file to WMV in C++ DirectShow; GraphEdit and source code
我想制作一個工具來獲取AVI文件作為輸入並將其轉換為WMV文件並將其保存在硬盤上。 如您所見,在GraphEdit中,我成功完成了此操作
我開始使同一任務的COM C ++代碼具有相同的效果,但我不明白問題所在可能是阻止我獲得最終的轉換文件。 這是我編寫的代碼(有很多內存泄漏)。 我檢查了所有返回的值,並且都正常,因此調用中沒有錯誤。
#include <dshow.h>
#pragma comment(lib,"Strmiids.lib")
#define AVI_FILE_PATH L"C:\\...\\Desktop\\oo.avi"
#define WMV_FILE_PATH L"C:\\...\\Desktop\\BRGMovie.wmv"
int main() {
IGraphBuilder* pGraph = NULL;
IBaseFilter* pSource = NULL;
IBaseFilter* pAviSplitter = NULL;
IBaseFilter* pMjpegDecompressor = NULL;
IBaseFilter* pSmartTee = NULL;
IBaseFilter* pAviMux = NULL;
IBaseFilter* pFileWriter = NULL;
ICaptureGraphBuilder2* pBuild = NULL;
IFileSourceFilter* FileSource = NULL;
CoInitialize(NULL);
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph );
CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSource );
CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pAviSplitter );
CoCreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pMjpegDecompressor);
CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSmartTee );
CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pAviMux );
CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pFileWriter );
CoCreateInstance(CLSID_FileSource, NULL, CLSCTX_INPROC_SERVER, IID_IFileSourceFilter, (void**)&FileSource);
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
pGraph->AddFilter(pSource, NULL);
pGraph->AddFilter(pAviSplitter, NULL);
pGraph->AddFilter(pMjpegDecompressor, NULL);
pGraph->AddFilter(pSmartTee, NULL);
pGraph->AddFilter(pAviMux, NULL);
pGraph->AddFilter(pFileWriter, NULL);
pSource->QueryInterface(IID_IFileSourceFilter, (void**)&FileSource);
FileSource->Load(AVI_FILE_PATH, NULL);
pBuild->SetOutputFileName(&MEDIASUBTYPE_Asf, WMV_FILE_PATH, &pAviMux, NULL);
pBuild->RenderStream(NULL, &MEDIATYPE_Video, pSource, 0, pAviMux);
IEnumPins* EnumPins = NULL;
IPin* OutPin = NULL;
IPin* InPin = NULL;
ULONG fetched = NULL;
PIN_INFO pinfo;
// find source output
pSource->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &OutPin, &fetched);
EnumPins->Release();
// find AviSplitter input
pAviSplitter->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &InPin, &fetched);
InPin->QueryPinInfo(&pinfo);
pinfo.pFilter->Release();
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
// find AviSplitter upper output
EnumPins->Reset();
EnumPins->Next(1, &OutPin, &fetched);
OutPin->QueryPinInfo(&pinfo);
pinfo.pFilter->Release();
EnumPins->Skip(1);
EnumPins->Release();
// find MjpegDecompressor input
pMjpegDecompressor->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &InPin, &fetched);
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
// find MjpegDecompressor output
EnumPins->Reset();
EnumPins->Next(1, &OutPin, &fetched);
OutPin->QueryPinInfo(&pinfo);
pinfo.pFilter->Release();
EnumPins->Release();
// find SmartTee input
pSmartTee->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &InPin, &fetched);
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
// find SmartTee output
EnumPins->Reset();
EnumPins->Next(1, &OutPin, &fetched);
OutPin->QueryPinInfo(&pinfo);
pinfo.pFilter->Release();
EnumPins->Skip(1);
// find AVIMux input
pAviMux->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &InPin, &fetched);
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
EnumPins->Skip(1);
// find AVIMux output
EnumPins->Reset();
EnumPins->Next(1, &OutPin, &fetched);
OutPin->QueryPinInfo(&pinfo);
pinfo.pFilter->Release();
// find FileWriter input
pFileWriter->EnumPins(&EnumPins);
EnumPins->Reset();
EnumPins->Next(1, &InPin, &fetched);
EnumPins->Release();
pGraph->Connect(OutPin, InPin);
InPin->Release();
OutPin->Release();
FileSource->Release();
CoUninitialize();
return 0;
}
編輯:
int main() {
IGraphBuilder* pGraph = NULL;
IBaseFilter* pASFWriter = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
ICaptureGraphBuilder2* pBuild = NULL;
HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
hr = CoCreateInstance(CLSID_WMAsfWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pASFWriter);
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
hr = pBuild->SetOutputFileName(&MEDIASUBTYPE_Asf, WMV_FILE_PATH, &pASFWriter, NULL);
hr = pGraph->RenderFile(AVI_FILE_PATH, NULL);
hr = pControl->Run();
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
}
提供的過濾器圖不會產生WMV(也稱為ASF)文件。 相反,您正在嘗試創建擴展名為.WMV的AVI文件(正在使用AVI Mux!)。
第二個問題是使用Smart Tee過濾器,不應在此類轉碼圖中使用它。 Smart Tee有其自己的(和記錄的)名稱。
要生成WMV文件,您需要將MJPEG解碼器輸出連接到WM ASF Writer Filter實例的輸入。 過濾器需要配置並附帶配置文件。
有關更多信息,請參見在DirectShow中創建ASF文件 。
同樣是從MSDN直接提出的問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.