Example #1
0
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;
		}