📄 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;
int currentBuffer;
int maxread=100000;
int fSize;
#define CACHE_SIZE 3000000
//int Done=0;
char* ReadAheadBuff=0;
int BufferStart;
int BufferStartNext;
int CurrentBuffer;
int nCacheSize=1000000;
int WritePos;
HANDLE rhandle;
HANDLE eventReadDone;
int restarted=1;
/*
* The main class
*/
void Restart(int pos)
{
if (pos<0) pos=0;
WaitForSingleObject(eventReadDone,INFINITE);
SetFilePointer(file, pos,NULL, FILE_BEGIN);
// fs_seek(::file,pos,SEEK_SET);
BufferStart=pos;
BufferStartNext=pos;
WritePos=0;
maxread=200000;
restarted=1;
ReleaseMutex(eventReadDone);
#if (_WIN32_WCE>=300)
CeSetThreadQuantum(rhandle,100);
#endif
while(WritePos<CACHE_SIZE-1100000&&(WritePos+BufferStartNext<fSize)) Sleep(10);
#if (_WIN32_WCE>=300)
CeSetThreadQuantum(rhandle,25);
#endif
maxread=50000;
}
DWORD WINAPI ReadAhead(LPVOID lpParameter)
{
unsigned long size;
while (file!=NULL)
{
unsigned long n;
int readamt;
if (!file)
{
continue;
}
if (BufferStartNext+WritePos>=fSize)
{
Sleep(10);
continue;
}
if (lastReadPos-(WritePos+BufferStart)<1000000&&(lastReadPos>(WritePos+BufferStart))&&(BufferStartNext>BufferStart))
{
Sleep(10);
continue;
}
if ((WritePos-(lastReadPos-BufferStart))>CACHE_SIZE-1000000)
{
Sleep(10);
continue;
}
//printf("buffer=%d\r\n",(WritePos-(lastReadPos-BufferStart)));
WaitForSingleObject(eventReadDone,INFINITE);
readamt=maxread;
if (CACHE_SIZE-(WritePos+maxread)<0)
{
readamt=CACHE_SIZE-WritePos;
}
ReadFile(file,(void *) (ReadAheadBuff+WritePos),readamt,&size,NULL);
WritePos+=size;
//printf("Write=%d Size=%d\r\n",WritePos,size);
if (size<readamt)
{
Sleep(10);
ReleaseMutex(eventReadDone);
continue;
}
if (WritePos==CACHE_SIZE)
{
WritePos=0;
BufferStartNext=BufferStart+CACHE_SIZE;
}
ReleaseMutex(eventReadDone);
}
return 1;
}
/*
* The main class
*/
int InputMediaOpen(char* lpFilename, int mode, int type, int reservesize, int maxsize)
{
if(lpFilename) {
int n;
char temp[100];
DWORD rtid;
// ::file = NULL;
// ::mode = -1;
lastReadPos=0;
// Done=1;
// ReadAheadBuff=0;
::file =CreateFile((LPCTSTR)lpFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (::file==INVALID_HANDLE_VALUE )
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,(LPTSTR) &lpMsgBuf, 0, NULL );
MessageBox( GetActiveWindow(), (LPCTSTR)lpMsgBuf, _T("Error loading file reader"), MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
return 0;
}
// ::file =fs_open((char*)lpFilename,O_RDONLY);
//::mode = INPUT_TYPE_FILE;
fSize=GetFileSize(::file,NULL);
if (!fSize ) return 0;
if (!ReadAheadBuff)
ReadAheadBuff=(char*)malloc(CACHE_SIZE);
if (!ReadAheadBuff)
return 0;
BufferStart=0;
BufferStartNext=0;
WritePos=0;
maxread=200000;
eventReadDone=CreateMutex(NULL,false,_T("ReadDone"));
rhandle=CreateThread(NULL,NULL,ReadAhead,(LPVOID)0,0,&rtid);
#if (_WIN32_WCE>=300)
CeSetThreadQuantum(rhandle,25);
#endif
//SetThreadPriority(rhandle,THREAD_PRIORITY_BELOW_NORMAL);
//while(WritePos<CACHE_SIZE-1100000&&(WritePos<fSize)) Sleep(10);
maxread=50000;
}
return fSize;
}
void InputMediaClose()
{
int n;
if(fSize) {
CloseHandle(::file);
file=NULL;
}
Sleep(100);
free(ReadAheadBuff);
ReadAheadBuff=0;
fSize=0;
}
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)>(WritePos+BufferStartNext+20000))
{
//printf("BufferStart=%d BufferNext=%d WriteBos=%d \r\n",BufferStart, BufferStartNext,WritePos);
Restart(lastReadPos-100000);
}
while((lastReadPos+bytesleft)>(WritePos+BufferStartNext))
{
// printf("caught up\r\n");
Sleep(10);
}
if (lastReadPos+bytesleft>(BufferStart+CACHE_SIZE))
{
if (lastReadPos<(BufferStart+CACHE_SIZE))
{
memcpy((void*)data,(void*)((char*)ReadAheadBuff+(lastReadPos-BufferStart)),(BufferStart+CACHE_SIZE)-lastReadPos);
bytesleft-=((BufferStart+CACHE_SIZE)-lastReadPos);
data+=((BufferStart+CACHE_SIZE)-lastReadPos);
::lastReadPos=BufferStart+CACHE_SIZE; //+=((BufferStart+CACHE_SIZE)-lastReadPos);
}
//printf("cycle=%d\r\n",lastReadPos);
BufferStart=BufferStartNext;
restarted=0;
}
else if (lastReadPos<BufferStart-CACHE_SIZE+WritePos||(lastReadPos<BufferStart&&(restarted)))
{
//printf("BufferStart=%d BufferNext=%d WriteBos=%d \r\n",BufferStart, BufferStartNext,WritePos);
Restart(lastReadPos-100000);
}
else if (lastReadPos<BufferStart)
{
if (lastReadPos+bytesleft>(BufferStart))
{
memcpy((void*)data,(void*)((char*)ReadAheadBuff+(lastReadPos-(BufferStart-CACHE_SIZE))),BufferStart-lastReadPos);
bytesleft-=(BufferStart-lastReadPos);
data+=(BufferStart-lastReadPos);
::lastReadPos=BufferStart; //+=(BufferStart-lastReadPos);
}
else
{
memcpy((void*)data,(void*)((char*)ReadAheadBuff+(lastReadPos-(BufferStart-CACHE_SIZE))),bytesleft);
::lastReadPos+=bytesleft;
bytesleft=0;
}
}
else
{
memcpy((void*)data,(void*)((char*)ReadAheadBuff+(lastReadPos-BufferStart)),bytesleft);
::lastReadPos+=bytesleft;
bytesleft=0;
}
}
size-=bytesleft;
return size;
}
int InputMediaSeek(int size, unsigned int method)
{
switch(method)
{
case INPUT_SEEK_SET:
::lastReadPos = size;
// if (size<BufferStart-400000||(size<lastReadPos-500000))
if (size-BufferStart<WritePos+100000&& (BufferStartNext!=BufferStart))
{
//printf("BufferStart=%d BufferNext=%d WriteBos=%d \r\n",BufferStart, BufferStartNext,WritePos);
if (size-100000>0)
Restart(size-100000);
else
Restart(size);
}
return 0;
break;
case INPUT_SEEK_CUR:
if(!size) {
return ::lastReadPos;
}
else
{
int holdpos=lastReadPos;
::lastReadPos += size;
if (lastReadPos>(BufferStartNext+CACHE_SIZE))
{
//printf("BufferStart=%d BufferNext=%d WriteBos=%d respos=%d\r\n",BufferStart, BufferStartNext,WritePos,holdpos);
Restart(lastReadPos-100000);
}
return 0;
}
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -