Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
283
Src/Plugins/Input/in_dshow/header_avi.cpp
Normal file
283
Src/Plugins/Input/in_dshow/header_avi.cpp
Normal file
|
@ -0,0 +1,283 @@
|
|||
#include <windows.h>
|
||||
#include "header_avi.h"
|
||||
#include <mmsystem.h>
|
||||
#include <bfc/platform/types.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
|
||||
DWORD dwMaxBytesPerSec; // max. transfer rate
|
||||
DWORD dwPaddingGranularity; // pad to multiples of this
|
||||
// size; normally 2K.
|
||||
DWORD dwFlags; // the ever-present flags
|
||||
DWORD dwTotalFrames; // # frames in file
|
||||
DWORD dwInitialFrames;
|
||||
DWORD dwStreams;
|
||||
DWORD dwSuggestedBufferSize;
|
||||
|
||||
DWORD dwWidth;
|
||||
DWORD dwHeight;
|
||||
|
||||
DWORD dwReserved[4];
|
||||
}
|
||||
MainAVIHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FOURCC fccType;
|
||||
FOURCC fccHandler;
|
||||
DWORD dwFlags; /* Contains AVITF_* flags */
|
||||
WORD wPriority;
|
||||
WORD wLanguage;
|
||||
DWORD dwInitialFrames;
|
||||
DWORD dwScale;
|
||||
DWORD dwRate; /* dwRate / dwScale == samples/second */
|
||||
DWORD dwStart;
|
||||
DWORD dwLength; /* In units above... */
|
||||
DWORD dwSuggestedBufferSize;
|
||||
DWORD dwQuality;
|
||||
DWORD dwSampleSize;
|
||||
RECT rcFrame;
|
||||
}
|
||||
AVIStreamHeader;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#ifndef mmioFOURCC
|
||||
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
|
||||
( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \
|
||||
( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) )
|
||||
#endif /* mmioFOURCC */
|
||||
|
||||
HeaderAvi::HeaderAvi(bool bAllowHttpConnection /* = false */)
|
||||
: bAllowHttp(bAllowHttpConnection), fh(INVALID_HANDLE_VALUE)
|
||||
{}
|
||||
|
||||
HeaderAvi::~HeaderAvi()
|
||||
{}
|
||||
|
||||
int HeaderAvi::getInfos(const wchar_t *filename, bool checkMetadata)
|
||||
{
|
||||
{
|
||||
fh = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (fh == INVALID_HANDLE_VALUE) return 0;
|
||||
}
|
||||
|
||||
int riffid = read_dword();
|
||||
if (riffid != mmioFOURCC('R', 'I', 'F', 'F'))
|
||||
{
|
||||
myfclose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned __int32 filesize = read_dword();
|
||||
int aviid = read_dword();
|
||||
if (aviid != mmioFOURCC('A', 'V', 'I', ' '))
|
||||
{
|
||||
myfclose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int last_fccType = 0;
|
||||
while (1)
|
||||
{
|
||||
int id = read_dword();
|
||||
if (!id) break;
|
||||
|
||||
if (id == mmioFOURCC('L', 'I', 'S', 'T'))
|
||||
{
|
||||
unsigned __int32 len = read_dword() - 4;
|
||||
id = read_dword();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case mmioFOURCC('m', 'o', 'v', 'i'):
|
||||
{
|
||||
// MOVI header
|
||||
//if (!checkMetadata) // might have metadata at the end of the file, so we gotta keep going
|
||||
//{
|
||||
myfclose();
|
||||
return 1;
|
||||
//}
|
||||
len = (len + 1) & (~1);
|
||||
myfseek(len, FILE_CURRENT);
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'N', 'F', 'O'):
|
||||
{
|
||||
if (!checkMetadata)
|
||||
{
|
||||
if (len)
|
||||
myfseek(len, FILE_CURRENT);
|
||||
break;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
int infoId = read_dword();
|
||||
unsigned __int32 infoSize = read_dword();
|
||||
unsigned __int32 chunksize = (infoSize + 1) & (~1);
|
||||
len -= (chunksize + 8);
|
||||
switch (infoId)
|
||||
{
|
||||
// TODO: IYER for year, but is it string or number?
|
||||
// TODO: ITRK for track, but is it string or number?
|
||||
case mmioFOURCC('I', 'C', 'O', 'M'):
|
||||
{
|
||||
composer = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
composer[infoSize] = 0;
|
||||
myfread(composer, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'P', 'U', 'B'):
|
||||
{
|
||||
publisher = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
publisher[infoSize] = 0;
|
||||
myfread(publisher, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'A', 'L', 'B'):
|
||||
{
|
||||
album = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
album[infoSize] = 0;
|
||||
myfread(album, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'G', 'N', 'R'):
|
||||
{
|
||||
genre = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
genre[infoSize] = 0;
|
||||
myfread(genre, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'C', 'M', 'T'):
|
||||
{
|
||||
comment = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
comment[infoSize] = 0;
|
||||
myfread(comment, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'A', 'R', 'T'):
|
||||
{
|
||||
artist = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
artist[infoSize] = 0;
|
||||
myfread(artist, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('I', 'N', 'A', 'M'):
|
||||
{
|
||||
title = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
|
||||
title[infoSize] = 0;
|
||||
myfread(title, infoSize, 1);
|
||||
chunksize -= infoSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (chunksize > 0) myfseek(chunksize, FILE_CURRENT);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned __int32 size2 = read_dword();
|
||||
size_t chunksize = (size2 + 1) & (~1);
|
||||
switch (id)
|
||||
{
|
||||
case mmioFOURCC('a', 'v', 'i', 'h'):
|
||||
{
|
||||
MainAVIHeader ah;
|
||||
size_t l = min(size2, sizeof(ah));
|
||||
myfread(&ah, l, 1);
|
||||
chunksize -= l;
|
||||
video_h = ah.dwHeight; video_w = ah.dwWidth;
|
||||
if (video_h && video_w) has_video = true;
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('s', 't', 'r', 'h'):
|
||||
{
|
||||
AVIStreamHeader ash;
|
||||
size_t l = min(size2, sizeof(ash));
|
||||
myfread(&ash, l, 1);
|
||||
chunksize -= l;
|
||||
last_fccType = ash.fccType;
|
||||
if (last_fccType == mmioFOURCC('v', 'i', 'd', 's'))
|
||||
{
|
||||
float frametime = (float)ash.dwScale / ((float)ash.dwRate / 1000);
|
||||
length = (int)((float)ash.dwLength * frametime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mmioFOURCC('s', 't', 'r', 'f'):
|
||||
{
|
||||
if (last_fccType == mmioFOURCC('v', 'i', 'd', 's'))
|
||||
{
|
||||
}
|
||||
else if (last_fccType == mmioFOURCC('a', 'u', 'd', 's'))
|
||||
{
|
||||
WAVEFORMATEX wfe;
|
||||
size_t l = min(chunksize, sizeof(wfe));
|
||||
myfread(&wfe, sizeof(wfe), 1);
|
||||
audio_bps = wfe.wBitsPerSample;
|
||||
audio_srate = wfe.nSamplesPerSec;
|
||||
audio_nch = wfe.nChannels;
|
||||
if (!audio_bps) audio_bps = 16;
|
||||
has_audio = true;
|
||||
chunksize -= l;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (chunksize > 0) myfseek((long)chunksize, FILE_CURRENT);
|
||||
}
|
||||
|
||||
myfclose();
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t HeaderAvi::myfread(void *buffer, size_t size, size_t count)
|
||||
{
|
||||
DWORD bytesRead = 0;
|
||||
ReadFile(fh, buffer, (DWORD)(size*count), &bytesRead, NULL);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
int HeaderAvi::myfclose()
|
||||
{
|
||||
return CloseHandle(fh);
|
||||
}
|
||||
|
||||
// Note; Only supports SEEK_CUR for http (which is what is used)
|
||||
int HeaderAvi::myfseek(long offset, DWORD origin)
|
||||
{
|
||||
return SetFilePointer(fh, offset, 0, origin);
|
||||
|
||||
}
|
||||
/* TODO:
|
||||
__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
|
||||
li.QuadPart = distance;
|
||||
|
||||
li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
|
||||
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
{
|
||||
li.QuadPart = -1;
|
||||
}
|
||||
|
||||
return li.QuadPart;
|
||||
}
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue