⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddgrab.cpp

📁 mmread.m是matlab官方网站上公布的一个函数
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (SUCCEEDED(hr))
	{
		VideoCBs.add(grabberCB);
		_RPT0(_CRT_WARN,"Added a VideoCapture.\n");

		// if the subtype was changed on us... complain.
		if (mt.subtype != MEDIASUBTYPE_RGB24) return E_NOTIMPL;

		//set the rate and bytes per WORD info
		int width, height, dummy;
        double dummyd;
		int currentCB = VideoCBs.size()-1;

		getVideoInfo(currentCB, &width, &height, &(VideoCBs.at(currentCB)->rate), &dummy, &dummy, &dummyd);
		VideoCBs.at(currentCB)->bytesPerWORD = width*height*3;
	}

	MyFreeMediaType(mt);

	return hr;
}

HRESULT DDGrabber::insertAudioCapture(IGraphBuilder* pGraphBuilder, IBaseFilter* pRenderer)
{
	AM_MEDIA_TYPE mt = {0};
	CSampleGrabberCB* grabberCB;

	if (!pGraphBuilder || !pRenderer) return E_POINTER;

	mt.majortype = MEDIATYPE_Audio;
	mt.subtype = MEDIASUBTYPE_PCM;
	mt.formattype = FORMAT_WaveFormatEx;

	_RPT0(_CRT_WARN,"Trying to add an AudioCapture.\n");
	_RPT0(_CRT_WARN,"Trying MEDIASUBTYPE_PCM\n");
	HRESULT hr = insertCapture(pGraphBuilder, pRenderer, &mt, &grabberCB);
	if (FAILED(hr))
	{
		mt.subtype = MEDIASUBTYPE_IEEE_FLOAT;
		_RPT0(_CRT_WARN,"Trying MEDIASUBTYPE_IEEE_FLOAT\n");
		hr = insertCapture(pGraphBuilder, pRenderer, &mt, &grabberCB);
		if (FAILED(hr))
		{
			GUID null = {0};
			mt.subtype = null;
			_RPT0(_CRT_WARN,"Trying NULL\n");
			hr = insertCapture(pGraphBuilder, pRenderer, &mt, &grabberCB);
		}
	}
	if (SUCCEEDED(hr))
	{
		grabberCB->isAudio = true;
		grabberCB->subtype = mt.subtype;
		AudioCBs.add(grabberCB);
		_RPT0(_CRT_WARN,"Added an AudioCapture.\n");

		//set the rate and bytes per WORD info
		int nrChannels, bits, dummy;
        double dummyd;
		GUID subtype;
		int currentCB = AudioCBs.size()-1;

		getAudioInfo(currentCB, &nrChannels, &(AudioCBs.at(currentCB)->rate), &bits, &dummy, &dummy, &subtype, &dummyd);
		AudioCBs.at(currentCB)->bytesPerWORD = bits/8.0*nrChannels;

		// an unsupported bit depth, nrChannels combination; should only be for 4bit.
		if (AudioCBs.at(currentCB)->bytesPerWORD != bits/8.0*nrChannels) hr = E_NOTIMPL;
	}

	MyFreeMediaType(mt);

	return hr;
}

HRESULT DDGrabber::mangleGraph(IGraphBuilder* pGraphBuilder)
{
	if (!pGraphBuilder) return E_POINTER;

	IEnumFilters* filterList;
	IBaseFilter* filt;
	vector<IBaseFilter*> renderers; // if there is an audio and a video stream then we could have two renderers
	ULONG tmp;
	HRESULT hr;

	if (FAILED(hr = pGraphBuilder->EnumFilters(&filterList))) return hr;
	filterList->Reset();
	while (filterList->Next(1, &filt, &tmp) == S_OK)
	{
		if (isRenderer(filt)) 
		{
			renderers.add(filt);
		}
		else filt->Release();
	}
	filterList->Release();

	for (int i=0; i<renderers.size(); i++)
	{
		if (MEDIATYPE_Video == getMajorType(renderers.at(i)))
		{
			_RPT0(_CRT_WARN,"Inserting Video Capture...\n");
			if (FAILED(hr = insertVideoCapture(pGraphBuilder,renderers.at(i)))) return hr;
			_RPT0(_CRT_WARN,"Inserted Video Capture\n");
		} else if (MEDIATYPE_Audio == getMajorType(renderers.at(i))) {
			_RPT0(_CRT_WARN,"Inserting Audio Capture...\n");
			if (FAILED(hr = insertAudioCapture(pGraphBuilder,renderers.at(i)))) return hr;
			_RPT0(_CRT_WARN,"Inserted Audio Capture\n");
		} else {
			_RPT0(_CRT_WARN,"Renderer type not recognized.\n");
		}

		_RPT0(_CRT_WARN,"Changing to Null...\n");
		if (FAILED(hr = changeToNull(pGraphBuilder,(IBaseFilter*)renderers.at(i)))) return hr;
		_RPT0(_CRT_WARN,"Changed to Null\n");
	}

	return S_OK;
}

HRESULT DDGrabber::buildGraph(char* filename)
{
	if (!filename) return E_POINTER;

	WCHAR uniFilename[MAX_PATH];
	HRESULT hr;

	MultiByteToWideChar(CP_ACP, 0, filename, -1, uniFilename, MAX_PATH);

	// Create the graph builder
	pGraphBuilder = NULL;
	if (FAILED(hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder))) return hr;

	// make sure everything is back to "normal"; cleanUp() also releases the current pGraphBuilder, so we need to make a new one
	cleanUp();
	if (FAILED(hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder))) return hr;

	// Add some Null Renderers to the graph so that we don't have weird hardware dependences.
	IBaseFilter *pNull1, *pNull2;
	if (FAILED(hr = ::CoCreateInstance(CLSID_NullRenderer,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)&pNull1))) return hr;
	if (FAILED(hr = pGraphBuilder->AddFilter(pNull1, L"NullRender"))) return hr;
	if (FAILED(hr = ::CoCreateInstance(CLSID_NullRenderer,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)&pNull2))) return hr;
	if (FAILED(hr = pGraphBuilder->AddFilter(pNull2, L"NullRender"))) return hr;
  
	_RPT0(_CRT_WARN,"Rendering File...\n");
	if (FAILED(hr = pGraphBuilder->RenderFile(uniFilename,NULL))) return hr;
	_RPT0(_CRT_WARN,"Rendered File\n");
	
	IPin* nullPin, *tmpPin;
	nullPin = getInputPin(pNull1);
	if (nullPin->ConnectedTo(&tmpPin) == VFW_E_NOT_CONNECTED)
	{
		pGraphBuilder->RemoveFilter(pNull1);
		pNull1->Release();
	} else tmpPin->Release();
		nullPin->Release();
		nullPin = getInputPin(pNull2);
	if (nullPin->ConnectedTo(&tmpPin) == VFW_E_NOT_CONNECTED)
	{
		pGraphBuilder->RemoveFilter(pNull2);
		pNull2->Release();
	} else tmpPin->Release();
	nullPin->Release();
	
	_RPT0(_CRT_WARN,"Mangling graph...\n");
	// insert the Capture CBs, and change the Renderers to Null
	if (FAILED(hr = mangleGraph(pGraphBuilder))) return hr;
	_RPT0(_CRT_WARN,"Mangled graph...\n");
	
	return hr;
}

#ifdef MATLAB_MEX_FILE
void DDGrabber::runMatlabCommand()
{
	if (matlabCommand)
	{
		IMediaControl* pMediaControl;
		pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);

		int dims[] = {1,1};
		int width=0, height = 0;
		mxArray* plhs[] = {NULL};
		mxArray* prhs[5];
		int ExitCode;
		OAFilterState fs;
		int f;
		prhs[0] = NULL;

		mexSetTrapFlag(0);

		pMediaControl->GetState(100,&fs);
		if (fs != State_Stopped) pMediaControl->Pause(); // pause rendering so that we can process what we have so far...

		for (int i=0; i < VideoCBs.size(); i++)
		{
			CSampleGrabberCB* CB = VideoCBs.at(i);

			if (CB)
			{
				if (CB->pbFormat)
				{
					VIDEOINFOHEADER * h = (VIDEOINFOHEADER*) CB->pbFormat;
					width  = h->bmiHeader.biWidth;
					height = h->bmiHeader.biHeight;
				}

				prhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); mxGetPr(prhs[1])[0] = width;
				prhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); mxGetPr(prhs[2])[0] = height;
				prhs[3] = mxCreateDoubleMatrix(1,1,mxREAL); 
				prhs[4] = mxCreateDoubleMatrix(1,1,mxREAL); 

				for (f = lastFrames.at(i); f < CB->frames.size(); f++)
				{
					if (CB->frames.at(f))
					{
						dims[0] = CB->frameBytes.at(f);
						
						// only if the array is changing sizes do we allocate a new one
						if (prhs[0] == NULL || mxGetM(prhs[0]) != dims[0])
						{
							if (prhs[0] != NULL) mxDestroyArray(prhs[0]);
							//make matrices to pass to the matlab function
							prhs[0] = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL); // empty 2d matrix
						}
						memcpy(mxGetPr(prhs[0]),(BYTE*)CB->frames.at(f),dims[0]);
						
						mxGetPr(prhs[3])[0] = CB->frameNrs.size()==0?f+1:CB->frameNrs.at(f);
						mxGetPr(prhs[4])[0] = CB->frameTimes.size()==0?f+1:CB->frameTimes.at(f);

						//free the frame memory
						free((BYTE*)CB->frames.at(f));
						CB->frames.assign(f,NULL);
						CB->frameBytes.assign(f,0);

						_RPT3(_CRT_WARN,"mexCallMATLAB  %s f# %d #fs %d\n",matlabCommand,f,CB->frames.size());

						//call Matlab
						ExitCode = mexCallMATLAB(0,plhs,5,prhs,matlabCommand);

						_RPT1(_CRT_WARN,"ErrorCode = %d\n",ExitCode);
					}
				}
				lastFrames.assign(i,f);
				
				//free memory
				mxDestroyArray(prhs[0]);
				prhs[0] = NULL;
				mxDestroyArray(prhs[1]);
				mxDestroyArray(prhs[2]);
				mxDestroyArray(prhs[3]);
				mxDestroyArray(prhs[4]);
			}
		}

		pMediaControl->GetState(100,&fs);
		if (fs != State_Stopped) pMediaControl->Run(); // restart rendering...

		pMediaControl->Release();
	}
}
#endif


HRESULT DDGrabber::doCapture()
{
	HRESULT hr;
	IMediaControl* pMediaControl;
	IMediaEvent* pMediaEventEx;
	IMediaFilter* pMediaFilter;
	IMediaSeeking* pMediaSeeking;

	pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
	pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&pMediaEventEx);
	pGraphBuilder->QueryInterface(IID_IMediaFilter, (void **)&pMediaFilter);
	pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void **)&pMediaSeeking);

	if (pMediaControl == NULL || pMediaEventEx == NULL || pMediaFilter == NULL || pMediaSeeking == NULL) return E_NOINTERFACE;

	_RPT1(_CRT_WARN,"tryseeking: %d\n",tryseeking);
	if (tryseeking)
	{
		_RPT2(_CRT_WARN,"frameNrs.size(): %d  stopTime: %f\n",tryseeking,(float)stopTime);
		if (frameNrs.size() > 0)
		{
			LONGLONG firstFrame = frameNrs.at(0);
			_RPT0(_CRT_WARN,"Trying SetTimeFormat TIME_FORMAT_FRAME\n");
			if (SUCCEEDED(pMediaSeeking->SetTimeFormat(&TIME_FORMAT_FRAME)) && 
				SUCCEEDED(pMediaSeeking->SetPositions(&firstFrame, AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning )))
			{
				_RPT0(_CRT_WARN,"SetTimeFormat SUCCEEDED\n");
				for (int i=0; i < VideoCBs.size(); i++)
				{
					CSampleGrabberCB* CB = VideoCBs.at(i);
					for (int j=0; j<frameNrs.size(); j++) CB->frameNrs.assign(j,frameNrs.at(j)-firstFrame+1);
				}
			} else {_RPT0(_CRT_WARN,"SetTimeFormat FAILED\n");}
		} else if (stopTime) {
			REFERENCE_TIME llstartTime = startTime*10000000;
			_RPT0(_CRT_WARN,"Trying SetTimeFormat TIME_FORMAT_MEDIA_TIME\n");
			if (SUCCEEDED(pMediaSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME)))
			{
				_RPT0(_CRT_WARN,"SetTimeFormat SUCCEEDED\n");
				if (SUCCEEDED(pMediaSeeking->SetPositions(&llstartTime, AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning ))) {_RPT0(_CRT_WARN,"SetPositions SUCCEEDED\n");}
			} else {_RPT0(_CRT_WARN,"SetTimeFormat FAILED\n");}
		}
	}
    
	//turn off the clock, so that it will run as fast as possible
	pMediaFilter->SetSyncSource(NULL);

	InitializeCriticalSection(&CriticalSection);

	// Run the graph and wait for completion.
	if (FAILED(hr = pMediaControl->Run())) return hr;

	long evCode = 0;
	bool allDone = false;
	stopForced = false;

#ifdef MATLAB_MEX_FILE
	// initialize the lastFrames vector
	lastFrames.clear();
	for (int i=0; i < VideoCBs.size(); i++) lastFrames.add(0);
#endif

	while (pMediaEventEx->WaitForCompletion(1000, &evCode) == E_ABORT)
	{
		allDone = true;
		for (int i=0; i < VideoCBs.size(); i++)
		{
			if (VideoCBs.at(i) && !VideoCBs.at(i)->disabled && !VideoCBs.at(i)->done) allDone = false;
			_RPT2(_CRT_WARN,"Testing VideoCB: %d allDone: %d \n",i,allDone);
		}
		for (int i=0; i < AudioCBs.size(); i++)
		{
			if (AudioCBs.at(i) && !AudioCBs.at(i)->disabled && !AudioCBs.at(i)->done) allDone = false;
			_RPT2(_CRT_WARN,"Testing AudioCBs: %d allDone: %d \n",i,allDone);
		}

		if (allDone)
		{
			_RPT0(_CRT_WARN,"STOP!!! \n");
			// if all of the video streams are done, then force a stop
			if (FAILED(hr = pMediaControl->Stop())) return hr;
			stopForced = true;
		}

#ifdef MATLAB_MEX_FILE
		runMatlabCommand();
#endif
	}

	DeleteCriticalSection(&CriticalSection);

	// make sure everything has really stopped before returning.
	if (FAILED(hr = pMediaControl->Stop())) return hr;

#ifdef MATLAB_MEX_FILE
	runMatlabCommand();
#endif

	pMediaEventEx->Release();
	pMediaControl->Release();
	pMediaFilter->Release();
	pMediaSeeking->Release();

	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -