www.pudn.com > SBDcode.rar > ConsoleApp.cpp


/* 
 *	Copyright (c) 2003, Jim Easterbrook 
 * 
 * 
 *	This file is part of shot-change. 
 * 
 *  shot-change is free software; you can redistribute it and/or modify 
 *  it under the terms of the GNU Lesser General Public License as published by 
 *  the Free Software Foundation; either version 2.1 of the License, or 
 *  (at your option) any later version. 
 * 
 *  shot-change is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU Lesser General Public License for more details. 
 * 
 *  You should have received a copy of the GNU Lesser General Public License 
 *  along with shot-change; if not, write to the Free Software 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */ 
 
#pragma comment(exestr,"$Id: ConsoleApp.cpp,v 1.1.1.1 2003/03/20 11:49:00 easter Exp $") 
 
/* 
 * $Log: ConsoleApp.cpp,v $ 
 * Revision 1.1.1.1  2003/03/20 11:49:00  easter 
 * Initial import 
 * 
 */ 
 
#include  
#include  
#include  
 
#include "CutDetector.h" 
 
static FILE		*cd_out; 
 
IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, int PinCount) 
{ 
	IEnumPins		*pEnum; 
	IPin			*pPin; 
	PIN_DIRECTION	PinDirThis; 
 
	if (pFilter->EnumPins(&pEnum) != S_OK) 
		return NULL; 
	while(pEnum->Next(1, &pPin, 0) == S_OK) 
	{ 
		if (pPin->QueryDirection(&PinDirThis) == S_OK) 
			if (PinDirThis == PinDir) 
				PinCount = PinCount - 1; 
		if (PinCount == 0) 
			break; 
		pPin->Release(); 
	} 
	pEnum->Release(); 
	return (PinCount == 0 ? pPin : NULL); 
} 
 
static IGraphBuilder	*pGraph = NULL; 
static IMediaControl	*pMediaControl = NULL; 
static IMediaEvent		*pMediaEvent = NULL; 
static IMediaFilter		*pMediaFilter = NULL; 
static IBaseFilter		*pSourceFilter = NULL; 
static IBaseFilter		*pCutDetector = NULL; 
static ICDControl		*pCDControl = NULL; 
static IPin				*pInPin = NULL, *pOutPin = NULL; 
 
void CleanRelease(IUnknown **pObj) 
{ 
	if (*pObj == NULL) 
		return; 
	(*pObj)->Release(); 
	*pObj = NULL; 
	return; 
} 
 
void 
CleanUp(void) 
{ 
	CleanRelease((IUnknown**)&pInPin); 
	CleanRelease((IUnknown**)&pOutPin); 
	CleanRelease((IUnknown**)&pCDControl); 
	CleanRelease((IUnknown**)&pCutDetector); 
	CleanRelease((IUnknown**)&pSourceFilter); 
	CleanRelease((IUnknown**)&pMediaFilter); 
	CleanRelease((IUnknown**)&pMediaEvent); 
	CleanRelease((IUnknown**)&pMediaControl); 
	CleanRelease((IUnknown**)&pGraph); 
	CoUninitialize(); 
} 
 
void 
CheckResult(const HRESULT hr) 
{ 
	char	ErrorText[MAX_ERROR_TEXT_LEN]; 
	char	Message[MAX_ERROR_TEXT_LEN + 20]; 
 
	if (SUCCEEDED(hr)) 
		return; 
	if (AMGetErrorText(hr, ErrorText, MAX_ERROR_TEXT_LEN) == 0) 
		sprintf(Message, "Error %8x", hr); 
	else 
		sprintf(Message, "Error %8x: %s", hr, ErrorText); 
	MessageBox(NULL, Message, "CutDetector error", MB_OK | MB_ICONINFORMATION); 
	CleanUp(); 
	exit(1); 
} 
 
//int CallBack(int FrameNumber, float Probability, int Duration) 
int CallBack(int FrameNo, int f1,float f2,float f3,float f4,float I1,float I2,float I3,float I4) 
 
{ 
	fprintf(cd_out, "%9d %9d %9g %9g %9g %7g %7g %7g %7g\n",FrameNo,f1,f2,f3,f4,I1,I2,I3,I4); 
	if (cd_out == stdout) 
		fflush(cd_out); 
	return 0; 
} 
 
int 
main(int argc, char* argv[]) 
{ 
	long		EvCode; 
	WCHAR		InFileName[_MAX_PATH]; 
 
	if (argc == 3) 
	{ 
		if ((cd_out = fopen(argv[2], "wc")) == NULL) { 
			fprintf(stderr, "Failed to open out_file '%s'\n", argv[2]); 
			return 2; 
		} 
	} 
	else if (argc == 2) 
	{ 
		cd_out = stdout; 
	} 
	else 
	{ 
		fprintf(stderr, "Usage: %s in_file [out_file]\n", argv[0]); 
		return 1; 
	} 
 
	MultiByteToWideChar(CP_ACP, 0, argv[1], -1, InFileName, 
		sizeof(InFileName)/sizeof(InFileName[0])); 
 
	// Initialise COM 
	CheckResult(CoInitialize(NULL)); 
 
	// Create graph builder and get interfaces 
	CheckResult(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&pGraph)); 
	CheckResult(pGraph->QueryInterface(IID_IMediaControl, (void**)&pMediaControl)); 
	CheckResult(pGraph->QueryInterface(IID_IMediaEvent, (void**)&pMediaEvent)); 
	CheckResult(pGraph->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter)); 
 
	// Add source filter to graph 
	CheckResult(pGraph->AddSourceFilter(InFileName, L"File source", &pSourceFilter)); 
 
	// Add cut detector to graph 
	CheckResult(CoCreateInstance(CLSID_CutDetector, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pCutDetector)); 
	CheckResult(pGraph->AddFilter(pCutDetector, L"Cut detector")); 
 
	// Get cut detector control interface and set parameters 
	CheckResult(pCutDetector->QueryInterface(IID_ICDControl, (void**)&pCDControl)); 
	pCDControl->SetCallBack(&CallBack); 
	pCDControl->SetThreshold(-0.2); 
 
	// Connect source filter to cut detector 
	pOutPin = GetPin(pSourceFilter, PINDIR_OUTPUT, 1); 
	pInPin = GetPin(pCutDetector, PINDIR_INPUT, 1); 
	CheckResult(pGraph->Connect(pOutPin, pInPin)); 
	CleanRelease((IUnknown**)&pInPin); 
	CleanRelease((IUnknown**)&pOutPin); 
/* 
	// Render cut detector's video output 
	pOutPin = GetPin(pCutDetector, PINDIR_OUTPUT, 1); 
	CheckResult(pGraph->Render(pOutPin)); 
	CleanRelease((IUnknown**)&pOutPin); 
*/ 
	// Run the graph, as quickly as possible 
	CheckResult(pMediaFilter->SetSyncSource(NULL)); 
	CheckResult(pMediaControl->Run()); 
 
	// Wait for completion 
	EvCode = 0; 
	CheckResult(pMediaEvent->WaitForCompletion(INFINITE, &EvCode)); 
 
	// Stop the graph 
	CheckResult(pMediaControl->Stop()); 
 
	fclose(cd_out); 
 
	CleanUp(); 
	return 0; 
}