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

📄 inputfile.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	VirtualDub - Video processing and capture application
//	Copyright (C) 1998-2001 Avery Lee
//
//	This program is free software; you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation; either version 2 of the License, or
//	(at your option) any later version.
//
//	This program 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 General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program; if not, write to the Free Software
//	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include <process.h>
#include <stdio.h>

#include <windows.h>
#include <vfw.h>
//#include <commdlg.h>

#include "InputFile.h"
#include "AudioSource.h"
#include "VideoSource.h"
#include "Error.h"
#include "AVIStripeSystem.h"
#include "AVIReadHandler.h"

//#include "gui.h"
#include "oshelper.h"
//#include "prefs.h"

#include "Varios.h"

#include "resourceVD.h"

//extern HINSTANCE g_hInst;
//extern char g_msgBuf[128];
//extern const char fileFiltersAppend[];
//extern HWND g_hWnd;

/////////////////////////////////////////////////////////////////////

InputFileOptions::~InputFileOptions() {
}

/////////////////////////////////////////////////////////////////////

InputFilenameNode::InputFilenameNode(const char *_n) : name(strdup(_n)) {
//	if (!name)
//		throw MyMemoryError();
}

InputFilenameNode::~InputFilenameNode() {
	free((char *)name);
}

/////////////////////////////////////////////////////////////////////

InputFile::~InputFile() {
	InputFilenameNode *ifn;

	while(ifn = listFiles.RemoveTail())
		delete ifn;
}

void InputFile::AddFilename(const char *lpszFile) {
	InputFilenameNode *ifn = new InputFilenameNode(lpszFile);

	if (ifn)
		listFiles.AddTail(ifn);
}

bool InputFile::Append(const char *szFile) {
	return false;
}

void InputFile::setOptions(InputFileOptions *) {
}

InputFileOptions *InputFile::promptForOptions(HWND) {
	return NULL;
}

InputFileOptions *InputFile::createOptions(const char *buf) {
	return NULL;
}

void InputFile::InfoDialog(HWND hwndParent) {
}

void InputFile::setAutomated(bool) {
}

bool InputFile::isOptimizedForRealtime() {
	return false;
}

bool InputFile::isStreaming() {
	return false;
}

/////////////////////////////////////////////////////////////////////

char InputFileAVI::szME[]="AVI Import Filter";

InputFileAVI::InputFileAVI(bool) {
	audioSrc = NULL;
	videoSrc = NULL;

	stripesys = NULL;
	stripe_files = NULL;
	fAutomated	= false;

	fAcceptPartial = false;
	fInternalMJPEG = false;
	fDisableFastIO = false;
	iMJPEGMode = 0;
	fccForceVideo = 0;
	fccForceVideoHandler = 0;
	lForceAudioHz = 0;

	pAVIFile = NULL;

	fCompatibilityMode = fRedoKeyFlags = false;

	fAutoscanSegments = false;
}

InputFileAVI::~InputFileAVI() {

	delete videoSrc;
	delete audioSrc;

	if (stripe_files) {
		int i;

		for(i=0; i<stripe_count; i++)
			if (stripe_files[i])
				stripe_files[i]->Release();

		delete stripe_files;
	}
	delete stripesys;

	if (pAVIFile)
		pAVIFile->Release();
}

///////////////////////////////////////////////



class InputFileAVIOptions : public InputFileOptions {
public:
	struct InputFileAVIOpts {
		int len;
		int iMJPEGMode;
		FOURCC fccForceVideo;
		FOURCC fccForceVideoHandler;
		long lForceAudioHz;

		bool fCompatibilityMode;
		bool fAcceptPartial;
		bool fRedoKeyFlags;
		bool fInternalMJPEG;
		bool fDisableFastIO;
	} opts;
		
	~InputFileAVIOptions();

	bool read(const char *buf);
	int write(char *buf, int buflen);

	static BOOL APIENTRY SetupDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam);
};

InputFileAVIOptions::~InputFileAVIOptions() {
}

bool InputFileAVIOptions::read(const char *buf) {
	const InputFileAVIOpts *pp = (const InputFileAVIOpts *)buf;

	if (pp->len != sizeof(InputFileAVIOpts))
		return false;

	opts = *pp;

	return true;
}

int InputFileAVIOptions::write(char *buf, int buflen) {
	InputFileAVIOpts *pp = (InputFileAVIOpts *)buf;

	if (buflen<sizeof(InputFileAVIOpts))
		return 0;

	opts.len = sizeof(InputFileAVIOpts);
	*pp = opts;

	return sizeof(InputFileAVIOpts);
}

///////

BOOL APIENTRY InputFileAVIOptions::SetupDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
	InputFileAVIOptions *thisPtr = (InputFileAVIOptions *)GetWindowLong(hDlg, DWL_USER);

	switch(message) {
		case WM_INITDIALOG:
			SetWindowLong(hDlg, DWL_USER, lParam);
			SendDlgItemMessage(hDlg, IDC_FORCE_FOURCC, EM_LIMITTEXT, 4, 0);
			CheckDlgButton(hDlg, IDC_IF_NORMAL, BST_CHECKED);
			return TRUE;

		case WM_COMMAND:
			switch(LOWORD(wParam)) {
			case IDCANCEL:
				if (GetDlgItem(hDlg, IDC_ACCEPTPARTIAL))
					thisPtr->opts.fAcceptPartial = !!IsDlgButtonChecked(hDlg, IDC_ACCEPTPARTIAL);

				thisPtr->opts.fCompatibilityMode = !!IsDlgButtonChecked(hDlg, IDC_AVI_COMPATIBILITYMODE);
				thisPtr->opts.fRedoKeyFlags = !!IsDlgButtonChecked(hDlg, IDC_AVI_REKEY);
				thisPtr->opts.fInternalMJPEG = !!IsDlgButtonChecked(hDlg, IDC_AVI_INTERNALMJPEG);
				thisPtr->opts.fDisableFastIO = !!IsDlgButtonChecked(hDlg, IDC_AVI_DISABLEOPTIMIZEDIO);

				if (IsDlgButtonChecked(hDlg, IDC_IF_NORMAL))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_NORMAL;
				else if (IsDlgButtonChecked(hDlg, IDC_IF_SWAP))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_SWAP;
				else if (IsDlgButtonChecked(hDlg, IDC_IF_SPLITNOSWAP))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_SPLIT1;
				else if (IsDlgButtonChecked(hDlg, IDC_IF_SPLITSWAP))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_SPLIT2;
				else if (IsDlgButtonChecked(hDlg, IDC_IF_DISCARDFIRST))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_DISCARD1;
				else if (IsDlgButtonChecked(hDlg, IDC_IF_DISCARDSECOND))
					thisPtr->opts.iMJPEGMode = VideoSourceAVI::IFMODE_DISCARD2;

				if (IsDlgButtonChecked(hDlg, IDC_FORCE_FOURCC)) {
					union {
						char c[5];
						FOURCC fccType;
					};
					int i;

					i = SendDlgItemMessage(hDlg, IDC_FOURCC, WM_GETTEXT, sizeof c, (LPARAM)c);

					memset(c+i, ' ', 5-i);

					if (fccType == 0x20202020)
						fccType = ' BID';		// force nothing to DIB, since 0 means no force

					thisPtr->opts.fccForceVideo = fccType;
				} else
					thisPtr->opts.fccForceVideo = 0;

				if (IsDlgButtonChecked(hDlg, IDC_FORCE_HANDLER)) {
					union {
						char c[5];
						FOURCC fccType;
					};
					int i;

					i = SendDlgItemMessage(hDlg, IDC_FOURCC2, WM_GETTEXT, sizeof c, (LPARAM)c);

					memset(c+i, ' ', 5-i);

					if (fccType == 0x20202020)
						fccType = ' BID';		// force nothing to DIB, since 0 means no force

					thisPtr->opts.fccForceVideoHandler = fccType;
				} else
					thisPtr->opts.fccForceVideoHandler = 0;

				if (IsDlgButtonChecked(hDlg, IDC_FORCE_SAMPRATE))
					thisPtr->opts.lForceAudioHz = GetDlgItemInt(hDlg, IDC_AUDIORATE, NULL, FALSE);
				else
					thisPtr->opts.lForceAudioHz = 0;
				
				EndDialog(hDlg, 0);
				return TRUE;

			case IDC_FORCE_FOURCC:
				EnableWindow(GetDlgItem(hDlg, IDC_FOURCC), IsDlgButtonChecked(hDlg, IDC_FORCE_FOURCC));
				return TRUE;

			case IDC_FORCE_HANDLER:
				EnableWindow(GetDlgItem(hDlg, IDC_FOURCC2), IsDlgButtonChecked(hDlg, IDC_FORCE_HANDLER));
				return TRUE;

			case IDC_FORCE_SAMPRATE:
				EnableWindow(GetDlgItem(hDlg, IDC_AUDIORATE), IsDlgButtonChecked(hDlg, IDC_FORCE_SAMPRATE));
				return TRUE;
			}
			break;
	}

	return FALSE;
}

void InputFileAVI::setOptions(InputFileOptions *_ifo) {
	InputFileAVIOptions *ifo = (InputFileAVIOptions *)_ifo;

	fCompatibilityMode	= ifo->opts.fCompatibilityMode;
	fAcceptPartial		= ifo->opts.fAcceptPartial;
	fRedoKeyFlags		= ifo->opts.fRedoKeyFlags;
	fInternalMJPEG		= ifo->opts.fInternalMJPEG;
	fDisableFastIO		= ifo->opts.fDisableFastIO;
	iMJPEGMode			= ifo->opts.iMJPEGMode;
	fccForceVideo		= ifo->opts.fccForceVideo;
	fccForceVideoHandler= ifo->opts.fccForceVideoHandler;
	lForceAudioHz		= ifo->opts.lForceAudioHz;
}

InputFileOptions *InputFileAVI::createOptions(const char *buf) {
	InputFileAVIOptions *ifo = new InputFileAVIOptions();

	if (!ifo) throw MyMemoryError();

	if (!ifo->read(buf)) {
		delete ifo;
		return NULL;
	}

	return ifo;
}

InputFileOptions *InputFileAVI::promptForOptions(HWND hwnd) {
	InputFileAVIOptions *ifo = new InputFileAVIOptions();

	if (!ifo) throw MyMemoryError();

	DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_EXTOPENOPTS_AVI),
			hwnd, InputFileAVIOptions::SetupDlgProc, (LPARAM)ifo);

	return ifo;
}

///////////////////////////////////////////////

static bool fileExists(const char *fn) {
	DWORD dwAttrib = GetFileAttributes(fn);

	return dwAttrib != -1 && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

void InputFileAVI::EnableSegmentAutoscan() {
	fAutoscanSegments = true;
}

void InputFileAVI::ForceCompatibility() {
	fCompatibilityMode = true;
}

void InputFileAVI::setAutomated(bool fAuto) {
	fAutomated = fAuto;
}

void InputFileAVI::Init(char *szFile) {
	HRESULT err;
	PAVIFILE paf;

	AddFilename(szFile);

	if (fCompatibilityMode) {
		if (err = AVIFileOpen(&paf, szFile, OF_READ, NULL))
			throw MyAVIError(szME, err);

		if (!(pAVIFile = CreateAVIReadHandler(paf))) {
			AVIFileRelease(paf);
			throw MyMemoryError();
		}
	} else {
		if (!(pAVIFile = CreateAVIReadHandler(szFile)))
			throw MyMemoryError();
	}

	if (fDisableFastIO)
		pAVIFile->EnableFastIO(false);

	if (!(videoSrc = new VideoSourceAVI(pAVIFile,NULL,NULL,fInternalMJPEG, iMJPEGMode, fccForceVideo, fccForceVideoHandler)))
		throw MyMemoryError();

	if (!videoSrc->init())
		throw MyError("%s: problem opening video stream", szME);

	if (fRedoKeyFlags)
		((VideoSourceAVI *)videoSrc)->redoKeyFlags();
	else if (pAVIFile->isIndexFabricated() && !fAutomated && !videoSrc->isKeyframeOnly())
		MessageBox(NULL,
//NFJ		"Warning: VirtualDub has reconstructed the index for this file, but you have not specified "
//NFJ		"rekeying in the extended open options dialog.  Seeking in this file may be slow.",
			"The File integrity is NOT OK",
			"AVI Import Filter Warning",
			MB_OK|MB_ICONEXCLAMATION);

	if (videoSrc->isType1() && !fAutomated)
		MessageBox(NULL,
//NFJ		"Warning: Type-1 DV file detected. Type-1 DV files have video and audio combined into one stream, "
//NFJ		"and VirtualDub currently cannot extract the audio. Only the video stream will be available."
			"This program doesn't accept Type-1 DV files"
			,
			"AVI Import Filter Warning",
			MB_OK|MB_ICONEXCLAMATION);


	audioSrc = new AudioSourceAVI(pAVIFile);
	if (!audioSrc->init()) {
		delete audioSrc;
		audioSrc = NULL;
	} else if (lForceAudioHz) {
		WAVEFORMATEX *pwfex = (WAVEFORMATEX *)audioSrc->getFormat();

		pwfex->nAvgBytesPerSec = MulDiv(pwfex->nAvgBytesPerSec, lForceAudioHz, pwfex->nSamplesPerSec);
		pwfex->nSamplesPerSec = lForceAudioHz;
		audioSrc->streamInfo.dwScale = pwfex->nBlockAlign;
		audioSrc->streamInfo.dwRate = pwfex->nAvgBytesPerSec;
	}

	if (fAutoscanSegments) {
		char szPath[MAX_PATH], szNameTail[MAX_PATH];
		const char *pszName = SplitPathName(szFile);
		char *s = szNameTail;

		strcpy(szNameTail, pszName);
		memcpy(szPath, szFile, pszName-szFile);
		szPath[pszName-szFile]=0;

		while(*s)
			++s;

		if (s > szNameTail+7 && !stricmp(s-7, ".00.avi")) {
			int nSegment = 0;
			const char *pszPath;

			s -= 7;
			*s=0;

			MergePath(szPath, szNameTail);
			s = szPath;
			while(*s)
				++s;

			try {
				while(pAVIFile->getSegmentHint(&pszPath)) {

					wsprintf(s, ".%02d.avi", ++nSegment);

					if (!fileExists(szPath)) {
						if (pszPath && *pszPath) {
							strcpy(szPath, pszPath);
							MergePath(szPath, szNameTail);
							s = szPath;
							while(*s)
								++s;
						}
						wsprintf(s, ".%02d.avi", nSegment);
					}

⌨️ 快捷键说明

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