I would like to make a tool to get an AVI file as input and convert it to WMV file and save it on my hard disc. In GraphEdit I was successful to do it as you can see in
I started to make the COM C++ code for the same task to have the same effect but I don't get where the issue might be that prevent me to have the final converted file. This is the code I have written (there's a lot of memory leak). I checked all returned values and all are OKAY, so there is no error in calls.
#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;
}
Edited:
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);
}
The provided filter graph does not produce a WMV (also known as ASF) file. Instead, you are trying to create an AVI file with .WMV extension (you are using AVI Mux!).
Second issue is use of Smart Tee filter, it should not be used in such transcoding graph. Smart Tee has its own (and documented) designation.
To produce a WMV file, you need to connect MJPEG decoder output to input of an instance of WM ASF Writer Filter. The filter needs to be configured and have a profile attached.
For more information, see Creating ASF Files in DirectShow.
Also from MSDN right on your question: