Directshow转码失败
请求各位仁兄帮忙:
我的目的是把海康威视固有的视频格式,用Directshow转码为通用的avi格式,在GraphEdit中通过连接Filter可以把视频转码并且能够播放(附图为GraphEdit的Filter Graph),但是在代码中实现后,生成的avi文件比GraphEdit生成的文件小了一点,而且不能够播放!
以下是我的转码部分代码:
mMediaControl->Stop();
//获得源文件字符串
//CString转换为LPCWSTR !!!
wchar_t *lpszW = new WCHAR[1023];
int nLen = MultiByteToWideChar(CP_ACP, 0, strFileName, -1, NULL, NULL);
MultiByteToWideChar(CP_ACP, 0, strFileName, -1, lpszW, nLen);
IBaseFilter *pSource;
hr = AddFilterByName(mGraph,CLSID_LegacyAmFilterCategory,L"Hikvision Source Filter",L"Hikvision Source Filter",&pSource);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not Get and Add the Source filter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//获得IFileSourceFilter接口
IFileSourceFilter *pFileSourceFilter;
hr = pSource->QueryInterface(IID_IFileSourceFilter, (void**)&pFileSourceFilter);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not get the IFileSourceFilter接口", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//加载源文件
hr = pFileSourceFilter->Load (lpszW, NULL);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not load the source file", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
delete[] lpszW;
lpszW = NULL;
//海康解码器
IBaseFilter *pHikvisionDecoder;
hr = AddFilterByName(mGraph,CLSID_LegacyAmFilterCategory,L"Hikvision Decoder Filter",L"Hikvision Decoder Filter",&pHikvisionDecoder);
if (FAILED(hr))
{
MessageBox(NULL,"Could not Get and Add the Hikvision Decoder Filter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//连接Source Filter 和 Hikvision Decoder Filter
//获得Source Filter上的Video output Pin
IPin *pVideoOut = NULL;
pVideoOut = GetOutPin(pSource, 0);
if( pVideoOut == NULL )
{
MessageBox(NULL,"Could not get video output pin of Source Filter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = ConnectFilters(mGraph, pVideoOut, pHikvisionDecoder);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not connect Source Filter 和 Hikvision Decoder Filter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//Xvid编码器
IBaseFilter *pXvidMPEG4Codec;
hr = AddFilterByName(mGraph,CLSID_VideoCompressorCategory,L"Xvid MPEG-4 Codec",L"Xvid MPEG-4 Codec",&pXvidMPEG4Codec);
if (FAILED(hr))
{
MessageBox(NULL,"Could not Get and Add the Xvid MPEG-4 Codec Filter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//连接海康解码器 和 Xvid编码器
//获得海康解码器上的output Pin
IPin *pHikvisionOut = NULL;
pHikvisionOut = GetOutPin(pHikvisionDecoder, 0);
if( pHikvisionOut == NULL )
{
MessageBox(NULL,"Could not get 海康解码器上的output Pin", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = ConnectFilters(mGraph, pHikvisionOut, pXvidMPEG4Codec);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not connect 海康解码器 和 Xvid编码器", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//AVI Mux
IBaseFilter *pAVIMux;
hr = AddFilterByName(mGraph,CLSID_LegacyAmFilterCategory,L"AVI Mux",L"AVI Mux",&pAVIMux);
if (FAILED(hr))
{
MessageBox(NULL,"Could not Get and Add the AVI Mux", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
pAVIMux->QueryInterface(IID_IConfigAviMux,(void **)&pAviMux);
hr = pAviMux->SetOutputCompatibilityIndex(TRUE);
if (FAILED(hr))
{
MessageBox(NULL,"Could not SetOutputCompatibilityIndex", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//连接Xvid编码器和AVI Mux
//获得Xvid编码器的output Pin
IPin *pXvidOut = NULL;
pXvidOut = GetOutPin(pXvidMPEG4Codec, 0);
if( pXvidOut == NULL )
{
MessageBox(NULL,"Could not get Xvid编码器的output Pin", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = ConnectFilters(mGraph, pXvidOut, pAVIMux);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not connect Xvid编码器 和 AVI Mux", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//File writer
IBaseFilter *pFilewriter;
hr = AddFilterByName(mGraph,CLSID_LegacyAmFilterCategory,L"File writer",L"File writer",&pFilewriter);
if (FAILED(hr))
{
MessageBox(NULL,"Could not Get and Add the File writer", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = pFilewriter->QueryInterface(IID_IFileSinkFilter,(void**)&pSink);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not IID_IFileSinkFilter", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = pSink->SetFileName(L"c:\\0709.avi",NULL);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not c:\\0709.avi", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//连接AVI Mux和File writer
//获得AVI Mux的output Pin
IPin *pAVIMuxOut = NULL;
pAVIMuxOut = GetOutPin(pAVIMux, 0);
if( pAVIMuxOut == NULL )
{
MessageBox(NULL,"Could not get AVI Mux的output Pin", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
hr = ConnectFilters(mGraph, pAVIMuxOut, pFilewriter);
if( FAILED( hr ) )
{
MessageBox(NULL,"Could not connect AVI Mux和File writer", TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND );
return E_FAIL;
}
//Create();
hr = mMediaControl->Run();
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it
// can block indefinitely.