Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
201
Src/Plugins/Input/in_flv/FileProcessor.cpp
Normal file
201
Src/Plugins/Input/in_flv/FileProcessor.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
#include "FileProcessor.h"
|
||||
#include "FLVHeader.h"
|
||||
#include "FLVVideoHeader.h"
|
||||
|
||||
static int64_t Seek64(HANDLE hf, int64_t 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;
|
||||
}
|
||||
|
||||
int64_t FileSize64(HANDLE file)
|
||||
{
|
||||
LARGE_INTEGER position;
|
||||
position.QuadPart=0;
|
||||
position.LowPart = GetFileSize(file, (LPDWORD)&position.HighPart);
|
||||
|
||||
if (position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
|
||||
return INVALID_FILE_SIZE;
|
||||
else
|
||||
return position.QuadPart;
|
||||
}
|
||||
|
||||
FileProcessor::FileProcessor()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
FileProcessor::FileProcessor(const wchar_t *filename)
|
||||
{
|
||||
Init();
|
||||
processedCursor=CreateFile(filename, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
readCursor=CreateFile(filename, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
writePosition=FileSize64(readCursor);
|
||||
}
|
||||
|
||||
FileProcessor::~FileProcessor()
|
||||
{
|
||||
if (processedCursor != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(processedCursor);
|
||||
if (readCursor != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(readCursor);
|
||||
}
|
||||
|
||||
void FileProcessor::Init()
|
||||
{
|
||||
processedPosition=0;
|
||||
processedCursor=INVALID_HANDLE_VALUE;
|
||||
writePosition=0;
|
||||
readCursor=INVALID_HANDLE_VALUE;
|
||||
flen=0;
|
||||
maxTimeStamp=0;
|
||||
headerOK=false;
|
||||
}
|
||||
|
||||
int FileProcessor::Process()
|
||||
{
|
||||
int64_t oldPosition = Seek64(processedCursor, 0, FILE_CURRENT);
|
||||
|
||||
// read file header if we're at the beginning
|
||||
if (processedPosition == 0)
|
||||
{
|
||||
if (writePosition-processedPosition >= 9) // need at least nine bytes for the FLV file header
|
||||
{
|
||||
uint8_t data[9] = {0};
|
||||
DWORD bytesRead=0;
|
||||
ReadFile(processedCursor, data, 9, &bytesRead, NULL);
|
||||
if (header.Read(data, bytesRead))
|
||||
{
|
||||
headerOK=true;
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
processedPosition += bytesRead;
|
||||
return FLV_OK; // we'll make our logic just a little bit more sane by only processing one frame per pass.
|
||||
}
|
||||
else
|
||||
return FLV_ERROR;
|
||||
}
|
||||
|
||||
Seek64(processedCursor, oldPosition, FILE_BEGIN); // rollback
|
||||
return FLV_NEED_MORE_DATA;
|
||||
}
|
||||
|
||||
if (writePosition-processedPosition >= 15) // need at least fifteen bytes for the FLV frame header
|
||||
{
|
||||
uint8_t data[15] = {0};
|
||||
DWORD bytesRead=0;
|
||||
ReadFile(processedCursor, data, 15, &bytesRead, NULL);
|
||||
FrameData frameData;
|
||||
if (frameData.header.Read(data, bytesRead))
|
||||
{
|
||||
if (frameData.header.dataSize + processedPosition + 15 <= writePosition)
|
||||
{
|
||||
frameData.keyFrame = false;
|
||||
if (frameData.header.type == FLV::FRAME_TYPE_VIDEO)
|
||||
{
|
||||
FLVVideoHeader videoHeader;
|
||||
DWORD videoHeaderRead=0;
|
||||
ReadFile(processedCursor, data, 1, &videoHeaderRead, NULL);
|
||||
if (videoHeader.Read(data, bytesRead))
|
||||
{
|
||||
if (videoHeader.frameType == FLV::VIDEO_FRAMETYPE_KEYFRAME)
|
||||
{
|
||||
frameData.keyFrame = true;
|
||||
}
|
||||
}
|
||||
Seek64(processedCursor, -(int64_t)videoHeaderRead, FILE_CURRENT);
|
||||
// roll back file cursor from ReadFile
|
||||
}
|
||||
|
||||
{ // critsec enter
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
// record the offset where we found it
|
||||
frameData.location = processedPosition;
|
||||
maxTimeStamp=max(maxTimeStamp, frameData.header.timestamp);
|
||||
frames.push_back(frameData);
|
||||
} // critsec leave
|
||||
Seek64(processedCursor, frameData.header.dataSize, FILE_CURRENT);
|
||||
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
processedPosition+=bytesRead+frameData.header.dataSize;
|
||||
return FLV_OK;
|
||||
}
|
||||
Seek64(processedCursor, oldPosition, FILE_BEGIN); // rollback
|
||||
return FLV_NEED_MORE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLV_ERROR;
|
||||
}
|
||||
}
|
||||
Seek64(processedCursor, oldPosition, FILE_BEGIN); // rollback
|
||||
return FLV_NEED_MORE_DATA;
|
||||
}
|
||||
|
||||
uint32_t FileProcessor::GetMaxTimestamp()
|
||||
{
|
||||
return maxTimeStamp;
|
||||
}
|
||||
|
||||
bool FileProcessor::GetFrame(size_t frameIndex, FrameData &frameData)
|
||||
{
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
if (frameIndex < frames.size())
|
||||
{
|
||||
frameData = frames[frameIndex];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t FileProcessor::GetProcessedPosition()
|
||||
{
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
return processedPosition;
|
||||
}
|
||||
|
||||
size_t FileProcessor::Read(void *data, size_t bytes)
|
||||
{
|
||||
DWORD bytesRead = 0;
|
||||
ReadFile(readCursor, data, (DWORD)bytes, &bytesRead, NULL);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
uint64_t FileProcessor::Seek(uint64_t position)
|
||||
{
|
||||
return Seek64(readCursor, position, FILE_BEGIN);
|
||||
}
|
||||
|
||||
bool FileProcessor::GetPosition(int time_in_ms, size_t *frameIndex, bool needVideoKeyFrame)
|
||||
{
|
||||
Nullsoft::Utility::AutoLock lock(frameGuard);
|
||||
// TODO: binary search
|
||||
for (size_t f=0;f!=frames.size();f++)
|
||||
{
|
||||
if (frames[f].header.timestamp >= (uint32_t)time_in_ms)
|
||||
{
|
||||
if (needVideoKeyFrame)
|
||||
{
|
||||
while (f != 0 && !frames[f].keyFrame)
|
||||
f--;
|
||||
}
|
||||
*frameIndex = f;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FLVHeader *FileProcessor::GetHeader()
|
||||
{
|
||||
if (headerOK)
|
||||
return &header;
|
||||
else
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue