📄 inputmedia.cpp
字号:
/***************************************************************************************
*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. *
* *
* The GPL can be found at: http://www.gnu.org/copyleft/gpl.html *
* *
* *
****************************************************************************************
* Authors: *
* Marc Dukette *
**************************************************************************************/
#include "stdafx.h"
#include "InputMedia.h"
/*
* Seek Enum
*/
enum {
INPUT_SEEK_SET,
INPUT_SEEK_CUR,
INPUT_SEEK_END
};
// DWORD mode;
HANDLE file;
int filesize;
/*
* HTTP/FTP stuff
*/
HANDLE ioMutex;
long lastReadPos;
DWORD currentBuffer;
int fSize;
HANDLE eventOn4;
HANDLE eventDone;
int Done=0;
char* ReadAheadBuff[12];
int BufferStart[12];
int BufferSize[12];
int NumBuff=0;
int CurrentBuffer;
int CacheSize=1000000;
int RestartPoint;
HANDLE rhandle;
HANDLE eventReadDone;
/*
* The main class
*/
void Restart(int pos, int full)
{
int n;
if (full)
{
CurrentBuffer=0;
for (n=0;n<NumBuff;n++)
{
BufferStart[n]=0;
BufferSize[n]=0;
}
WaitForSingleObject(eventReadDone,INFINITE);
SetFilePointer(::file, pos,NULL, FILE_BEGIN);
BufferStart[0]=pos;
BufferSize[0]=0;
ReleaseMutex(eventReadDone);
ResetEvent(eventDone);
SetEvent(eventOn4);
WaitForSingleObject(eventDone,INFINITE);
}
else
{
CurrentBuffer=0;
memcpy(ReadAheadBuff[0],ReadAheadBuff[NumBuff-1]+(pos-BufferStart[NumBuff-1]),(BufferSize[NumBuff-1]-(pos-BufferStart[NumBuff-1])));
BufferSize[0]=(BufferSize[NumBuff-1]-(pos-BufferStart[NumBuff-1]));
BufferStart[0]=pos;
for (n=1;n<NumBuff;n++)
{
BufferStart[n]=0;
BufferSize[n]=0;
}
SetEvent(eventOn4);
// readstart=
//SetEvent(eventDone);
}
}
DWORD WINAPI ReadAhead(LPVOID lpParameter)
{
DWORD size;
HANDLE eventOn4=CreateEvent(NULL,true,false,_T("eventon4"));
HANDLE eventDone=CreateEvent(NULL,true,false,_T("eventDone"));
HANDLE eventReadDone=CreateMutex(NULL,false,_T("ReadDone"));
Done=0;
while(file!=NULL)
{
int n;
WaitForSingleObject(eventOn4,INFINITE);
ResetEvent(eventOn4);
if (!file)
{
// ReleaseMutex(eventReadDone);
continue;
}
WaitForSingleObject(eventReadDone,INFINITE);
// OutputDebugString(_T("Start Reading"));
ReadFile(file,(void *) (((char*)ReadAheadBuff[0])+BufferSize[0]),(1000000)-BufferSize[0],(LPDWORD) &size,NULL);
BufferSize[0]+=size;
for (n=1;n<NumBuff;n++)
{
BufferStart[n]=BufferStart[n-1]+BufferSize[n-1];
ReadFile(file,(void *) ReadAheadBuff[n],1000000,(LPDWORD) &size,NULL);
BufferSize[n]=size;
}
// OutputDebugString(_T("Done Reading"));
SetEvent(eventDone);
ReleaseMutex(eventReadDone);
}
CloseHandle(eventOn4);
CloseHandle(eventDone);
CloseHandle(eventReadDone);
Done=1;
return 1;
}
/*
* The main class
*/
INPUTMEDIA_API int InputMediaOpen(LPTSTR lpFilename, int mode, int type, int reservesize, int maxsize)
{
if(lpFilename) {
int n;
TCHAR temp[100];
::file = NULL;
// ::mode = -1;
lastReadPos=0;
Done=1;
for (n=0;n<NumBuff;n++)
{
ReadAheadBuff[n]=0;
}
::file =CreateFile((LPCTSTR)lpFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (::file==INVALID_HANDLE_VALUE ) return 0;
//::mode = INPUT_TYPE_FILE;
MEMORYSTATUS ms;
GlobalMemoryStatus(&ms);
maxsize*=1000000;
if (maxsize==0) maxsize=12000000;
if (reservesize!=-1) CacheSize=ms.dwAvailPhys-reservesize; //1000000;
if (CacheSize>maxsize)
CacheSize=maxsize;
fSize=GetFileSize(::file,NULL);
if (fSize<CacheSize)
{
CacheSize=fSize+100000;
if (CacheSize<2000000) CacheSize=2000000;
RestartPoint=-1;
}
else
{
if (CacheSize<2000000) CacheSize=2000000;
RestartPoint=CacheSize/10;
}
if (RestartPoint<400000&&(RestartPoint>0)) RestartPoint=400000;
if (RestartPoint>800000) RestartPoint=800000;
NumBuff=(CacheSize/1000000);
if ((NumBuff*1000000)<CacheSize) NumBuff++;
for (n=0;n<NumBuff;n++)
{
BufferStart[n]=0;
BufferSize[n]=0;
ReadAheadBuff[n]=(char*)malloc(1000000);
if (!ReadAheadBuff[n])
{
MessageBox(GetActiveWindow(),_T("Error allocating buffer"),_itow(CacheSize,temp,10),MB_OK);
return 0;
}
}
eventOn4=CreateEvent(NULL,true,false,_T("eventon4"));
eventDone=CreateEvent(NULL,true,false,_T("eventDone"));
eventReadDone=CreateMutex(NULL,false,_T("ReadDone"));
SetEvent(eventOn4);
CurrentBuffer=0;
BufferStart[0]=0;
DWORD rtid;
Done=0;
rhandle=CreateThread(NULL,NULL,ReadAhead,(LPVOID)0,0,&rtid);
WaitForSingleObject(eventDone,INFINITE);
#if (_WIN32_WCE>=300)
CeSetThreadQuantum(rhandle,25);
#endif
}
return fSize;
}
INPUTMEDIA_API void InputMediaClose()
{
int n;
//TerminateThread(rhandle,0);
if(::file) {
CloseHandle(::file);
}
for (n=0;n<NumBuff;n++)
if (ReadAheadBuff[n]) free(ReadAheadBuff[n]);
::file=NULL;
SetEvent(eventOn4);
while(!Done) Sleep(100);
CloseHandle(eventOn4);
CloseHandle(eventDone);
CloseHandle(eventReadDone);
}
INPUTMEDIA_API int InputMediaRead(char *data, unsigned int size)
{
int bytesleft;
if (size+lastReadPos>fSize)
size=fSize-lastReadPos;
bytesleft=size;
while(bytesleft&&(lastReadPos<fSize))
{
if (lastReadPos+bytesleft>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]))
{
if (CurrentBuffer==(NumBuff-1)&&(BufferSize[CurrentBuffer]==1000000))
{
Restart(lastReadPos-100000,1);
}
else
{
if (BufferSize[CurrentBuffer]==1000000)
{
memcpy((void*)data,(void*)((char*)ReadAheadBuff[CurrentBuffer]+(lastReadPos-BufferStart[CurrentBuffer])),BufferSize[CurrentBuffer]-(lastReadPos-BufferStart[CurrentBuffer]));
data+=BufferSize[CurrentBuffer]-(lastReadPos-BufferStart[CurrentBuffer]);
bytesleft-=BufferSize[CurrentBuffer]-(lastReadPos-BufferStart[CurrentBuffer]);
lastReadPos+=BufferSize[CurrentBuffer]-(lastReadPos-BufferStart[CurrentBuffer]);
CurrentBuffer++;
}
}
}
else if ((lastReadPos+bytesleft>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]-RestartPoint))&&(BufferSize[CurrentBuffer]==1000000)&&(CurrentBuffer==(NumBuff-1)))
{
Restart(lastReadPos-100000,0);
}
else if(BufferSize[CurrentBuffer]>0)
{
if (BufferSize[CurrentBuffer]<(bytesleft))
{
bytesleft-=BufferSize[CurrentBuffer];
}
if (lastReadPos-BufferStart[CurrentBuffer]+bytesleft>BufferSize[CurrentBuffer])
{
bytesleft-=BufferSize[CurrentBuffer]-(lastReadPos-BufferStart[CurrentBuffer]);
}
memcpy((void*)data,(void*)((char*)ReadAheadBuff[CurrentBuffer]+(lastReadPos-BufferStart[CurrentBuffer])),bytesleft);
::lastReadPos+=bytesleft;
bytesleft=0;
}
}
size-=bytesleft;
return size;
}
INPUTMEDIA_API int InputMediaSeek(int size, unsigned int method)
{
switch(method)
{
case INPUT_SEEK_SET:
if (size<BufferStart[CurrentBuffer])
{
if (size<BufferStart[0])
{
Restart(size,1);
}
else
{
while(size<BufferStart[CurrentBuffer])
CurrentBuffer--;
}
}
if (size>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]))
{
if (size>(BufferStart[NumBuff-1]+BufferSize[NumBuff-1]))
{
Restart(size-100000,1);
}
else if (size>(BufferStart[NumBuff-1]+BufferSize[NumBuff-1]-RestartPoint)&&(BufferSize[NumBuff-1]==1000000))
{
Restart(size-100000,0);
}
else
{
while (size>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]))
if (BufferSize[CurrentBuffer]==1000000) CurrentBuffer++;
}
}
::lastReadPos = size;
return 0;
break;
case INPUT_SEEK_CUR:
if(!size) {
return ::lastReadPos;
}
else
{
::lastReadPos += size;
if (lastReadPos>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]))
{
if (::lastReadPos>(BufferStart[NumBuff-1]+BufferSize[NumBuff-1]))
{
Restart(lastReadPos-100000,1);
}
else if (::lastReadPos>(BufferStart[NumBuff-1]+BufferSize[NumBuff-1]-RestartPoint)&&(BufferSize[NumBuff-1]==1000000))
{
Restart(lastReadPos-100000,0);
}
else
{
while (lastReadPos>(BufferStart[CurrentBuffer]+BufferSize[CurrentBuffer]))
if (BufferSize[CurrentBuffer]==1000000) CurrentBuffer++;
}
}
return 0;
}
break;
case INPUT_SEEK_END:
SetFilePointer( ::file, size, NULL,FILE_END);
return 0;
break;
}
return 0;
}
// This is the constructor of a class that has been exported.
// see InputMedia.h for the class definition
CInputMedia::CInputMedia()
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -