📄 inputfile.cpp
字号:
// 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 + -