BOOL CDShowCtrl::CreateRunGraph(LPCWSTR writeFilePath) { this->runFlag = FALSE; if( this->graph == NULL ){ return FALSE; } BOOL ret = TRUE; AddGraphToRot(this->graph, &m_dwRegister); HRESULT hr; for( size_t i=0; i<this->buffData.size(); i++ ){ delete this->buffData[i]; } this->buffData.clear(); tsSrc = static_cast<CTSSrcFilter *>(CTSSrcFilter::CreateInstance(NULL, &hr)); hr = tsSrc->QueryInterface(IID_IBaseFilter, reinterpret_cast<void**>(&this->bonSrc)); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = CoCreateInstance(IID_MSVideoDec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&this->videoDec ); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = CoCreateInstance(IID_MSAudioDec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&this->audioDec ); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = CoCreateInstance(IID_ATIFileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&this->writeFile ); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } this->graph->AddFilter(this->bonSrc, L"TSSrc"); this->graph->AddFilter(this->videoDec, L"Microsoft DTV-DVD Video Decoder"); this->graph->AddFilter(this->audioDec, L"Microsoft DTV-DVD Audio Decoder"); this->graph->AddFilter(this->writeFile, L"ATI MPEG File Writer"); IFileSinkFilter2 *sink = 0; hr = this->writeFile->QueryInterface(IID_IFileSinkFilter2, (void**)&sink); hr = sink->SetFileName(writeFilePath, NULL); hr = sink->SetMode(AM_FILE_OVERWRITE); SAFE_RELEASE(sink); //pinのコネクト hr = ConnectFilters(this->graph, this->bonSrc, this->videoDec); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->bonSrc, this->audioDec); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->videoDec, this->videoScaler); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->videoScaler, this->videoEnc); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->audioDec, this->audioEnc); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->videoEnc, this->muxer); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->audioEnc, this->muxer); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = ConnectFilters(this->graph, this->muxer, this->writeFile); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } hr = this->graph->QueryInterface(IID_IMediaControl, (void **)&this->mediaCtrl); if (FAILED(hr)){ ret = FALSE; goto ErrEnd; } this->preCreateFlag = TRUE; this->preCount = 0; return TRUE; ErrEnd: SAFE_RELEASE(this->bonSrc); SAFE_RELEASE(this->tsSrc); SAFE_RELEASE(this->videoDec); SAFE_RELEASE(this->audioDec); SAFE_RELEASE(this->writeFile); SAFE_RELEASE(this->videoScaler); SAFE_RELEASE(this->videoEnc); SAFE_RELEASE(this->audioEnc); SAFE_RELEASE(this->muxer); SAFE_RELEASE(this->graph); return ret; }
bool CFLVConverter::PreSaveToFLV( const HWND & hMainWnd, const CParameters & param, const wchar_t * SourceFileName, IMediaEventEx ** pMEE, Timeline * timeline) { IPin * pOutputPin = NULL; IPin * pInputPin = NULL; bool showLogo = true; m_llAudioSamplesCount = m_llVideoFramesCount = 0; int iLen = wcslen(SourceFileName)+1; DistFileName = new wchar_t[MAX_PATH]; wcscpy_s(DistFileName, MAX_PATH, SourceFileName); DistFileName[iLen-2] = 'v'; DistFileName[iLen-3] = 'l'; DistFileName[iLen-4] = 'f'; if (!OpenFileDialog(hMainWnd, SourceFileName, DistFileName)) { delete[] DistFileName; return false; } // Ask user about file quality. FileQualitySelector dlg(hMainWnd); if (IDOK == dlg.Show()) SelectedFileQuality = dlg.SelectedQuality(); else return false; SendMessage(hMainWnd, WM_NCPAINT, 1,0); iLen = wcslen(DistFileName)+14; tmpAVI = new wchar_t[iLen ]; wcscpy_s(tmpAVI, iLen, DistFileName); wcscat_s(tmpAVI, iLen, L"59temp44.avi"); // Create a DirectShow GraphBuilder object HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Filter graph built failed"), hr); Stop(); return false; } // Get DirectShow interfaces hr = pGB->QueryInterface(IID_IMediaControl, (void **)&pMC); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Create filter graph control"), hr); Stop(); return false; } hr = pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Create filter graph event handler"), hr); Stop(); return false; } // Have the graph signal event via window callbacks hr = pME->SetNotifyWindow((OAHWND)hMainWnd, WM_FGNOTIFY2, 0); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed graph notify message"), hr); Stop(); return false; } *pMEE = pME; (*pMEE)->AddRef(); if(SUCCEEDED(hr)) { // Add the source filter to the graph hr = pGB->AddSourceFilter(SourceFileName, L"SOURCE", &pSource); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed adding source filter"), hr); Stop(); return false; } // Add the splitter filter to the graph hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAVISplitter); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating splitter filter"), hr); Stop(); return false; } // Add the mixer filter to the graph hr = CoCreateInstance(CLSID_CAdder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAdder); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating adder filter"), hr); Stop(); return false; } if(timeline) { CComPtr <ITimelineFilter> cpTimelineFilter; hr = pAdder->QueryInterface(IID_ITimelineFilter, (void **)&cpTimelineFilter); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating ITimelineFilter interface"), hr); Stop(); return false; } CComPtr <ITimeline> cpTimeline; hr = timeline->QueryInterface(IID_ITimeline, (void**) &cpTimeline); if(SUCCEEDED(hr)) { hr = cpTimelineFilter->AssignTimeline(cpTimeline); if(FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed assigning ITimeline instance to filter"), hr); Stop(); return false; } } else { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating ITimeline interface"), hr); Stop(); return false; } } hr = pAdder->QueryInterface(IID_IAdder, (void **)&pAdderSettings); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating adder settings interface"), hr); Stop(); return false; } pAdderSettings->SetIntervals((void*)param.GetAllDeletedInterval(), (void*)param.GetWebDeletedInterval(), (void*)param.GetWebPosInterval(), (void*)param.GetArrowInterval(), (void*)param.GetTextInterval()); // Generate thumbnail file name. TCHAR thumbnail[MAX_PATH]; if (0 == _tcscpy_s(thumbnail, _countof(thumbnail), DistFileName)) { TCHAR *end = _tcsrchr(thumbnail, _T('.')); if (!end) end = &thumbnail[_tcslen(thumbnail)]; if ((end - &thumbnail[0]) + _tcslen(g_ThumbnailSuffix) < MAX_PATH) { _tcscpy(end, g_ThumbnailSuffix); CT2W wThumbnail(thumbnail); pAdderSettings->SetThumbnailPath(CComBSTR(wThumbnail)); } } // Add the logo filter to the graph if(showLogo) { hr = CoCreateInstance(CLSID_CWebinariaLogoFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pLogo); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating logo filter"), hr); Stop(); return false; } } // Add the mux filter to the graph hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAVIMux); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating destination avi filter"), hr); Stop(); return false; } // Add the writer filter to the graph hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWriter); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Failed creating destination avi filter"), hr); Stop(); return false; } IFileSinkFilter2 * pSink; hr = pWriter->QueryInterface(IID_IFileSinkFilter2, (void**)&pSink); pSink->SetFileName(tmpAVI, NULL); pSink->SetMode(AM_FILE_OVERWRITE); pSink->Release(); // Get the interface for the first output pin hr = GetUnconnectedPin(pSource, PINDIR_OUTPUT, &pOutputPin); hr = JoinFilterToChain(pGB, pAVISplitter, L"AVI Splitter", &pOutputPin); if(SUCCEEDED(hr)) { //asking Out pin of the avi splitter for IMediaSeeking: hr = pOutputPin->QueryInterface(IID_IMediaSeeking, (void **)&pMS); if (FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Create filter graph frame seeking"), hr); Stop(); return false; } if(showLogo) { hr = JoinFilterToChain(pGB, pLogo, L"WebinariaLogoFilter", &pOutputPin); } hr = pMS->SetTimeFormat( &TIME_FORMAT_FRAME ); if(SUCCEEDED(hr)) { pMS->GetDuration( &m_llVideoFramesCount ); } } if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, pAdder, L"Adder", &pOutputPin); } // Add compressor if(SUCCEEDED(hr)) { hr = CreateVideoCompressor(&pCompressor); if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, pCompressor, L"Video Compressor", &pOutputPin); } else { CError::ErrMsg(hMainWnd, TEXT("Error %x: Cannot add video compressor filter"), hr); } } if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, pAVIMux, L"AVI MUX", &pOutputPin); } if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, pWriter, L"File Writer", &pOutputPin); } SAFE_RELEASE(pOutputPin); if(SUCCEEDED(hr)) {//try to connect optional streams: for(int i=0; i<2; i++) { GetUnconnectedPin(pAVISplitter, PINDIR_OUTPUT, &pOutputPin); if(pOutputPin) { if(ptVideo==GetPinType(pOutputPin )) {//second video stream (webcam) GetUnconnectedPin(pAdder, PINDIR_INPUT, &pInputPin); if(pInputPin) { hr = pGB->Connect(pOutputPin, pInputPin); SAFE_RELEASE(pInputPin); if(FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Cannot connect webcam stream to muxer"), hr); } } } else if(ptAudio==GetPinType(pOutputPin )) {// audio stream GetUnconnectedPin(pAVIMux, PINDIR_INPUT, &pInputPin); if (pOutputPin && pInputPin) { hr = AssembeAudioBranch(param, pOutputPin, pInputPin); SAFE_RELEASE(pInputPin); if(FAILED(hr)) { CError::ErrMsg(hMainWnd, TEXT("Error %x: Cannot add render audio branch"), hr); } } } SAFE_RELEASE(pOutputPin); if(FAILED(hr)) { break; } } else { break; } } } if(FAILED(hr)) { Stop(); return false; } AddGraphToRot(pGB, &dwRotReg); } hr = pMC->Run(); return true; }