📄 fileinfodialog.cpp
字号:
{
if (!bDiffAudioCompression && !ami.strAudioFormat.IsEmpty())
SetDlgItemText(IDC_ACODEC, ami.strAudioFormat);
else
SetDlgItemText(IDC_ACODEC, _T(""));
if (!bDiffAudioChannels && ami.audio.nChannels)
{
switch (ami.audio.nChannels)
{
case 1:
SetDlgItemText(IDC_ACHANNEL, _T("1 (Mono)"));
break;
case 2:
SetDlgItemText(IDC_ACHANNEL, _T("2 (Stereo)"));
break;
case 5:
SetDlgItemText(IDC_ACHANNEL, _T("5.1 (Surround)"));
break;
default:
SetDlgItemInt(IDC_ACHANNEL, ami.audio.nChannels, FALSE);
break;
}
}
else
SetDlgItemText(IDC_ACHANNEL, _T(""));
if (!bDiffAudioSamplesPerSec && ami.audio.nSamplesPerSec)
{
buffer.Format(_T("%.3f kHz"), ami.audio.nSamplesPerSec / 1000.0);
SetDlgItemText(IDC_ASAMPLERATE, buffer);
}
else
SetDlgItemText(IDC_ASAMPLERATE, _T(""));
if (!bDiffAudioAvgBytesPerSec && ami.audio.nAvgBytesPerSec)
{
buffer.Format(_T("%u kBit/s"), (UINT)((ami.audio.nAvgBytesPerSec * 8) / 1000.0 + 0.5));
SetDlgItemText(IDC_ABITRATE, buffer);
}
else
SetDlgItemText(IDC_ABITRATE, _T(""));
}
SetDlgItemText(IDC_FULL_FILE_INFO, ami.strInfo.str);
m_fi.SetSel(0, 0);
delete paMediaInfo;
return 0;
}
typedef struct
{
SHORT left;
SHORT top;
SHORT right;
SHORT bottom;
} RECT16;
typedef struct
{
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags;
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate;
DWORD dwStart;
DWORD dwLength;
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT16 rcFrame;
} AVIStreamHeader_fixed;
#ifndef AVIFILEINFO_NOPADDING
#define AVIFILEINFO_NOPADDING 0x0400 // from the SDK tool "RIFFWALK.EXE"
#endif
#ifndef AVIFILEINFO_TRUSTCKTYPE
#define AVIFILEINFO_TRUSTCKTYPE 0x0800 // from DirectX SDK "Types of DV AVI Files"
#endif
typedef struct
{
AVIStreamHeader_fixed hdr;
DWORD dwFormatLen;
union
{
BITMAPINFOHEADER* bmi;
PCMWAVEFORMAT* wav;
LPBYTE dat;
} fmt;
char* nam;
} STREAMHEADER;
static BOOL ReadChunkHeader(int fd, FOURCC *pfccType, DWORD *pdwLength)
{
if (read(fd, pfccType, sizeof(*pfccType)) != sizeof(*pfccType))
return FALSE;
if (read(fd, pdwLength, sizeof(*pdwLength)) != sizeof(*pdwLength))
return FALSE;
return TRUE;
}
static BOOL ParseStreamHeader(int hAviFile, DWORD dwLengthLeft, STREAMHEADER* pStrmHdr)
{
FOURCC fccType;
DWORD dwLength;
while (dwLengthLeft >= sizeof(DWORD)*2)
{
if (!ReadChunkHeader(hAviFile, &fccType, &dwLength))
return FALSE;
dwLengthLeft -= sizeof(DWORD)*2;
if (dwLength > dwLengthLeft) {
errno = 0;
return FALSE;
}
dwLengthLeft -= dwLength + (dwLength & 1);
switch (fccType)
{
case ckidSTREAMHEADER:
if (dwLength < sizeof(pStrmHdr->hdr))
{
memset(&pStrmHdr->hdr, 0x00, sizeof(pStrmHdr->hdr));
if (read(hAviFile, &pStrmHdr->hdr, dwLength) != (int)dwLength)
return FALSE;
if (dwLength & 1) {
if (lseek(hAviFile, 1, SEEK_CUR) == -1)
return FALSE;
}
}
else
{
if (read(hAviFile, &pStrmHdr->hdr, sizeof(pStrmHdr->hdr)) != sizeof(pStrmHdr->hdr))
return FALSE;
if (lseek(hAviFile, dwLength + (dwLength & 1) - sizeof(pStrmHdr->hdr), SEEK_CUR) == -1)
return FALSE;
}
dwLength = 0;
break;
case ckidSTREAMFORMAT:
if (dwLength > 4096) // expect corrupt data
return FALSE;
if ((pStrmHdr->fmt.dat = new BYTE[pStrmHdr->dwFormatLen = dwLength]) == NULL) {
errno = ENOMEM;
return FALSE;
}
if (read(hAviFile, pStrmHdr->fmt.dat, dwLength) != (int)dwLength)
return FALSE;
if (dwLength & 1)
if (lseek(hAviFile, 1, SEEK_CUR) == -1)
return FALSE;
dwLength = 0;
break;
case ckidSTREAMNAME:
if (dwLength > 512) // expect corrupt data
return FALSE;
if ((pStrmHdr->nam = new char[dwLength + 1]) == NULL) {
errno = ENOMEM;
return FALSE;
}
if (read(hAviFile, pStrmHdr->nam, dwLength) != (int)dwLength)
return FALSE;
pStrmHdr->nam[dwLength] = '\0';
if (dwLength & 1)
if (lseek(hAviFile, 1, SEEK_CUR) == -1)
return FALSE;
dwLength = 0;
break;
}
if (dwLength) {
if (lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) == -1)
return FALSE;
}
}
if (dwLengthLeft) {
if (lseek(hAviFile, dwLengthLeft, SEEK_CUR) == -1)
return FALSE;
}
return TRUE;
}
static BOOL GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo* mi, bool& rbIsAVI)
{
BOOL bResult = FALSE;
// Open AVI file
int hAviFile = _topen(pszFileName, O_RDONLY | O_BINARY);
if (hAviFile == -1)
return FALSE;
DWORD dwLengthLeft;
FOURCC fccType;
DWORD dwLength;
BOOL bSizeInvalid = FALSE;
int iStream = 0;
DWORD dwMovieChunkSize = 0;
DWORD uVideoFrames = 0;
//
// Read 'RIFF' header
//
if (!ReadChunkHeader(hAviFile, &fccType, &dwLength))
goto cleanup;
if (fccType != FOURCC_RIFF)
goto cleanup;
if (dwLength < sizeof(DWORD))
{
dwLength = 0xFFFFFFF0;
bSizeInvalid = TRUE;
}
dwLengthLeft = dwLength -= sizeof(DWORD);
//
// Read 'AVI ' or 'WAVE' header
//
FOURCC fccMain;
if (read(hAviFile, &fccMain, sizeof(fccMain)) != sizeof(fccMain))
goto cleanup;
if (fccMain == formtypeAVI)
rbIsAVI = true;
if (fccMain != formtypeAVI && fccMain != mmioFOURCC('W', 'A', 'V', 'E'))
goto cleanup;
BOOL bReadAllStreams;
bReadAllStreams = FALSE;
while (!bReadAllStreams && dwLengthLeft >= sizeof(DWORD)*2)
{
if (!ReadChunkHeader(hAviFile, &fccType, &dwLength))
goto inv_format_errno;
BOOL bInvalidLength = FALSE;
if (!bSizeInvalid)
{
dwLengthLeft -= sizeof(DWORD)*2;
if (dwLength > dwLengthLeft)
{
if (fccType == FOURCC_LIST)
bInvalidLength = TRUE;
else
goto cleanup;
}
dwLengthLeft -= (dwLength + (dwLength & 1));
}
switch (fccType)
{
case FOURCC_LIST:
if (read(hAviFile, &fccType, sizeof(fccType)) != sizeof(fccType))
goto inv_format_errno;
if (fccType != listtypeAVIHEADER && bInvalidLength)
goto inv_format;
// Some Premiere plugin is writing AVI files with an invalid size field in the LIST/hdrl chunk.
if (dwLength < sizeof(DWORD) && fccType != listtypeAVIHEADER && (fccType != listtypeAVIMOVIE || !bSizeInvalid))
goto inv_format;
dwLength -= sizeof(DWORD);
switch (fccType)
{
case listtypeAVIHEADER:
dwLengthLeft += (dwLength + (dwLength&1)) + 4;
dwLength = 0; // silently enter the header block
break;
case listtypeSTREAMHEADER:
{
BOOL bStreamRes;
STREAMHEADER strmhdr = {0};
if ((bStreamRes = ParseStreamHeader(hAviFile, dwLength, &strmhdr)) != FALSE)
{
double fSamplesSec = (strmhdr.hdr.dwScale != 0) ? (double)strmhdr.hdr.dwRate / (double)strmhdr.hdr.dwScale : 0.0F;
double fLength = (fSamplesSec != 0.0) ? (double)strmhdr.hdr.dwLength / fSamplesSec : 0.0;
if (strmhdr.hdr.fccType == streamtypeAUDIO)
{
mi->iAudioStreams++;
if (mi->iAudioStreams == 1)
{
mi->fAudioLengthSec = fLength;
if (strmhdr.dwFormatLen && strmhdr.fmt.wav)
{
*(PCMWAVEFORMAT*)&mi->audio = *strmhdr.fmt.wav;
mi->strAudioFormat = GetWaveFormatTagName(mi->audio.wFormatTag);
}
}
}
else if (strmhdr.hdr.fccType == streamtypeVIDEO)
{
mi->iVideoStreams++;
if (mi->iVideoStreams == 1)
{
uVideoFrames = strmhdr.hdr.dwLength;
mi->fVideoLengthSec = fLength;
mi->fVideoFrameRate = fSamplesSec;
if (strmhdr.dwFormatLen && strmhdr.fmt.bmi)
{
mi->video.bmiHeader = *strmhdr.fmt.bmi;
mi->strVideoFormat = GetVideoFormatName(mi->video.bmiHeader.biCompression);
}
}
}
}
delete[] strmhdr.fmt.dat;
delete[] strmhdr.nam;
if (!bStreamRes)
goto inv_format_errno;
iStream++;
dwLength = 0;
break;
}
case listtypeAVIMOVIE:
dwMovieChunkSize = dwLength;
bReadAllStreams = TRUE;
break;
}
break;
case ckidAVIMAINHDR:
if (dwLength == sizeof(MainAVIHeader))
{
MainAVIHeader avihdr;
if (read(hAviFile, &avihdr, sizeof(avihdr)) != sizeof(avihdr))
goto inv_format_errno;
if (dwLength & 1)
if (lseek(hAviFile, 1, SEEK_CUR) == -1)
goto inv_format_errno;
dwLength = 0;
}
break;
case ckidAVINEWINDEX: // idx1
bReadAllStreams = TRUE;
break;
case mmioFOURCC('f', 'm', 't', ' '):
if (fccMain == mmioFOURCC('W', 'A', 'V', 'E'))
{
STREAMHEADER strmhdr = {0};
if (dwLength > 4096) // expect corrupt data
goto inv_format;
if ((strmhdr.fmt.dat = new BYTE[strmhdr.dwFormatLen = dwLength]) == NULL) {
errno = ENOMEM;
goto inv_format_errno;
}
if (read(hAviFile, strmhdr.fmt.dat, dwLength) != (int)dwLength)
goto inv_format_errno;
if (dwLength & 1)
if (lseek(hAviFile, 1, SEEK_CUR) == -1)
goto inv_format_errno;
dwLength = 0;
strmhdr.hdr.fccType = streamtypeAUDIO;
if (strmhdr.dwFormatLen)
{
mi->iAudioStreams++;
if (mi->iAudioStreams == 1)
{
if (strmhdr.dwFormatLen && strmhdr.fmt.wav)
{
*(PCMWAVEFORMAT*)&mi->audio = *strmhdr.fmt.wav;
mi->strAudioFormat = GetWaveFormatTagName(mi->audio.wFormatTag);
}
}
}
delete[] strmhdr.fmt.dat;
delete[] strmhdr.nam;
iStream++;
bReadAllStreams = TRUE;
}
break;
}
if (bReadAllStreams)
break;
if (dwLength)
{
if (lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) == -1)
goto inv_format_errno;
}
}
if (fccMain == formtypeAVI)
{
mi->strFileFormat = _T("AVI");
if (mi->fVideoLengthSec)
{
DWORD dwVideoFramesOverhead = uVideoFrames * (sizeof(WORD) + sizeof(WORD) + sizeof(DWORD));
mi->video.dwBitRate = ((dwMovieChunkSize - dwVideoFramesOverhead) / mi->fVideoLengthSec - mi->audio.nAvgBytesPerSec) * 8;
}
}
else if (fccMain == mmioFOURCC('W', 'A', 'V', 'E'))
mi->strFileFormat = _T("WAV (RIFF)");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -