请求各位仁兄帮忙:
我的目的是把海康威视固有的视频格式,用Directshow转码为通用的avi格式,在GraphEdit中通过连接Filter可以把视频转码并且能够播放(附图为GraphEdit的Filter Graph),但是在代码中实现后,生成的avi文件比GraphEdit生成的文件小了一点,而且不能够播放!
以下是我的转码部分代码:
- C/C++ code
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();