Skip to content

Commit

Permalink
Refactored how an FSEQ File header is parsed. Fixed an issue in how t…
Browse files Browse the repository at this point in the history
…he 32 bit values were parsed.
  • Loading branch information
MartinMueller2003 committed Sep 29, 2021
1 parent e3fdb6a commit 7594102
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 119 deletions.
129 changes: 129 additions & 0 deletions ESPixelStick/src/input/InputFPPRemotePlayFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,132 @@ void c_InputFPPRemotePlayFile::CalculatePlayStartTime ()
// DEBUG_END;

} // CalculatePlayStartTime

//-----------------------------------------------------------------------------
bool c_InputFPPRemotePlayFile::ParseFseqFile ()
{
// DEBUG_START;
bool Response = false;

do // once
{
FSEQRawHeader fsqRawHeader;
FSEQParsedHeader fsqParsedHeader;

FileHandleForFileBeingPlayed = 0;
if (false == FileMgr.OpenSdFile (PlayItemName,
c_FileMgr::FileMode::FileRead,
FileHandleForFileBeingPlayed))
{
logcon (String (F ("ParseFseqFile:: Could not open file: filename: '")) + PlayItemName + "'");
break;
}

// DEBUG_V (String ("FileHandleForFileBeingPlayed: ") + String (FileHandleForFileBeingPlayed));
size_t BytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed,
(uint8_t*)&fsqRawHeader,
sizeof (fsqRawHeader), 0);
// DEBUG_V (String (" BytesRead: ") + String (BytesRead));
// DEBUG_V (String (" sizeof (fsqRawHeader): ") + String (sizeof (fsqRawHeader)));

if (BytesRead != sizeof (fsqRawHeader))
{
logcon (String (F ("ParseFseqFile:: Could not read FSEQ header: filename: '")) + PlayItemName + "'");
break;
}

// DEBUG_V ("Convert Raw Header into a processed header");
memcpy (fsqParsedHeader.header, fsqRawHeader.header, sizeof (fsqParsedHeader.header));
fsqParsedHeader.dataOffset = read16 (fsqRawHeader.dataOffset);
fsqParsedHeader.minorVersion = fsqRawHeader.minorVersion;
fsqParsedHeader.majorVersion = fsqRawHeader.majorVersion;
fsqParsedHeader.VariableHdrOffset = read16 (fsqRawHeader.VariableHdrOffset);
fsqParsedHeader.channelCount = read32 (fsqRawHeader.channelCount, 0);
fsqParsedHeader.TotalNumberOfFramesInSequence = read32 (fsqRawHeader.TotalNumberOfFramesInSequence, 0);
fsqParsedHeader.stepTime = fsqRawHeader.stepTime;
fsqParsedHeader.flags = fsqRawHeader.flags;
fsqParsedHeader.compressionType = fsqRawHeader.compressionType;
fsqParsedHeader.numCompressedBlocks = fsqRawHeader.numCompressedBlocks;
fsqParsedHeader.numSparseRanges = fsqRawHeader.numSparseRanges;
fsqParsedHeader.flags2 = fsqRawHeader.flags2;
fsqParsedHeader.id = read64 (fsqRawHeader.id, 0);

// DEBUG_V (String (" dataOffset: ") + String (fsqParsedHeader.dataOffset));
// DEBUG_V (String (" minorVersion: ") + String (fsqParsedHeader.minorVersion));
// DEBUG_V (String (" majorVersion: ") + String (fsqParsedHeader.majorVersion));
// DEBUG_V (String (" VariableHdrOffset: ") + String (fsqParsedHeader.VariableHdrOffset));
// DEBUG_V (String (" channelCount: ") + String (fsqParsedHeader.channelCount));
// DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (fsqParsedHeader.TotalNumberOfFramesInSequence));
// DEBUG_V (String (" stepTime: ") + String (fsqParsedHeader.stepTime));
// DEBUG_V (String (" flags: ") + String (fsqParsedHeader.flags));
// DEBUG_V (String (" compressionType: 0x") + String (fsqParsedHeader.compressionType, HEX));
// DEBUG_V (String (" numCompressedBlocks: ") + String (fsqParsedHeader.numCompressedBlocks));
// DEBUG_V (String (" numSparseRanges: ") + String (fsqParsedHeader.numSparseRanges));
// DEBUG_V (String (" flags2: ") + String (fsqParsedHeader.flags2));
// DEBUG_V (String (" id: 0x") + String ((unsigned long)fsqParsedHeader.id, HEX));

if (fsqParsedHeader.majorVersion != 2 || fsqParsedHeader.compressionType != 0)
{
logcon (String (F ("ParseFseqFile:: Could not start. ")) + PlayItemName + F (" is not a v2 uncompressed sequence"));
break;
}
// DEBUG_V ("");

// FrameStepTimeMS = max ((uint8_t)1, fsqParsedHeader.stepTime) * 30;
FrameStepTimeMS = max ((uint8_t)1, fsqParsedHeader.stepTime);
TotalNumberOfFramesInSequence = fsqParsedHeader.TotalNumberOfFramesInSequence;

DataOffset = fsqParsedHeader.dataOffset;
ChannelsPerFrame = fsqParsedHeader.channelCount;

memset ((void*)&SparseRanges, 0x00, sizeof (SparseRanges));
if (fsqParsedHeader.numSparseRanges)
{
if (MAX_NUM_SPARSE_RANGES < fsqParsedHeader.numSparseRanges)
{
logcon (String (F ("ParseFseqFile:: Could not start. ")) + PlayItemName + F (" Too many sparse ranges defined in file header."));
break;
}

FSEQRawRangeEntry FseqRawRanges[MAX_NUM_SPARSE_RANGES];

FileMgr.ReadSdFile (FileHandleForFileBeingPlayed,
(uint8_t*)&FseqRawRanges[0],
sizeof (FseqRawRanges),
fsqParsedHeader.numCompressedBlocks * 8 + sizeof (FseqRawRanges));

uint32_t SparseRangeIndex = 0;
for (auto & CurrentSparseRange : SparseRanges)
{
// DEBUG_V (String (" Sparse Range Index: ") + String (SparseRangeIndex));
if (SparseRangeIndex >= fsqParsedHeader.numSparseRanges)
{
// DEBUG_V (String ("No Sparse Range Data for this entry "));
++SparseRangeIndex;
continue;
}

CurrentSparseRange.DataOffset = read24 (FseqRawRanges[SparseRangeIndex].Start);
CurrentSparseRange.ChannelCount = read24 (FseqRawRanges[SparseRangeIndex].Length);

// DEBUG_V (String (" RangeChannelCount: ") + String (CurrentSparseRange.ChannelCount));
// DEBUG_V (String (" RangeDataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX));

++SparseRangeIndex;
}
}
else
{
SparseRanges[0].DataOffset = 0;
SparseRanges[0].ChannelCount = fsqParsedHeader.channelCount;
}

Response = true;

} while (false);

// DEBUG_END;

return Response;

} // ParseFseqFile
5 changes: 5 additions & 0 deletions ESPixelStick/src/input/InputFPPRemotePlayFile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "../ESPixelStick.h"
#include "InputFPPRemotePlayItem.hpp"
#include "InputFPPRemotePlayFileFsm.hpp"
#include "../service/fseq.h"

class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem
{
Expand Down Expand Up @@ -65,8 +66,12 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem
uint32_t SyncCount = 0;
uint32_t SyncAdjustmentCount = 0;

#define MAX_NUM_SPARSE_RANGES 5
FSEQParsedRangeEntry SparseRanges[MAX_NUM_SPARSE_RANGES];

uint32_t CalculateFrameId (time_t now, int32_t SyncOffsetMS = 0);
void CalculatePlayStartTime ();
bool ParseFseqFile ();

#define TimeOffsetStep 0.00001

Expand Down
93 changes: 4 additions & 89 deletions ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize)
p_InputFPPRemotePlayFile->LastPlayedFrameId = CurrentFrame;

size_t TotalBytesRead = 0;
for (auto & CurrentSparseRange : SparseRanges)
for (auto & CurrentSparseRange : p_InputFPPRemotePlayFile->SparseRanges)
{
size_t ActualBytesToRead = min (MaxBytesToRead, CurrentSparseRange.ChannelCount);
if (0 == ActualBytesToRead)
Expand All @@ -230,7 +230,7 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize)
// DEBUG_V (String (" AdjustedFilePosition: ") + String (uint32_t(AdjustedFilePosition), HEX));
// DEBUG_V (String (" CurrentDestination: ") + String (uint32_t(CurrentDestination), HEX));
// DEBUG_V (String (" ActualBytesToRead: ") + String (ActualBytesToRead));
size_t ActualBytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed,
size_t ActualBytesRead = FileMgr.ReadSdFile (p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed,
CurrentDestination,
ActualBytesToRead,
AdjustedFilePosition);
Expand All @@ -243,7 +243,7 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize)
// DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence));
// DEBUG_V (String (" CurrentFrame: ") + String (CurrentFrame));

if (0 != FileHandleForFileBeingPlayed)
if (0 != p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed)
{
logcon (F ("File Playback Failed to read enough data"));
Stop ();
Expand Down Expand Up @@ -288,101 +288,16 @@ void fsm_PlayFile_state_PlayingFile::Init (c_InputFPPRemotePlayFile* Parent)
--p_InputFPPRemotePlayFile->RemainingPlayCount;
// DEBUG_V (String ("RemainingPlayCount: ") + p_InputFPPRemotePlayFile->RemainingPlayCount);

FSEQHeader fsqHeader;
FileHandleForFileBeingPlayed = 0;
if (false == FileMgr.OpenSdFile (p_InputFPPRemotePlayFile->PlayItemName,
c_FileMgr::FileMode::FileRead,
FileHandleForFileBeingPlayed))
if (!p_InputFPPRemotePlayFile->ParseFseqFile ())
{
logcon (String (F ("StartPlaying:: Could not open file: filename: '")) + p_InputFPPRemotePlayFile->PlayItemName + "'");
Stop ();
break;
}

// DEBUG_V (String ("FileHandleForFileBeingPlayed: ") + String (FileHandleForFileBeingPlayed));
p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed = FileHandleForFileBeingPlayed;
size_t BytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed,
(uint8_t*)&fsqHeader,
sizeof (FSEQHeader), 0);
// DEBUG_V (String ("BytesRead: ") + String (BytesRead));
// DEBUG_V (String ("sizeof (fsqHeader): ") + String (sizeof (fsqHeader)));

if (BytesRead != sizeof (fsqHeader))
{
logcon (String (F ("StartPlaying:: Could not read FSEQ header: filename: '")) + p_InputFPPRemotePlayFile->PlayItemName + "'");
Stop ();
break;
}
// DEBUG_V ("");

if (fsqHeader.majorVersion != 2 || fsqHeader.compressionType != 0)
{
logcon (String (F ("StartPlaying:: Could not start. ")) + p_InputFPPRemotePlayFile->PlayItemName + F (" is not a v2 uncompressed sequence"));
Stop ();
break;
}
// DEBUG_V ("");

p_InputFPPRemotePlayFile->LastPlayedFrameId = 0;
p_InputFPPRemotePlayFile->DataOffset = fsqHeader.dataOffset;
p_InputFPPRemotePlayFile->ChannelsPerFrame = fsqHeader.channelCount;
// p_InputFPPRemotePlayFile->FrameStepTimeMS = max ((uint8_t)1, fsqHeader.stepTime) * 30;
p_InputFPPRemotePlayFile->FrameStepTimeMS = max ((uint8_t)1, fsqHeader.stepTime);
p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence = fsqHeader.TotalNumberOfFramesInSequence;
p_InputFPPRemotePlayFile->CalculatePlayStartTime ();

memset ((void*)&SparseRanges, 0x00, sizeof (SparseRanges));
if (fsqHeader.numSparseRanges)
{
if (MAX_NUM_SPARSE_RANGES < fsqHeader.numSparseRanges)
{
logcon (String (F ("StartPlaying:: Could not start. ")) + p_InputFPPRemotePlayFile->PlayItemName + F (" Too many sparse ranges defined."));
Stop ();
break;
}

FSEQRangeEntry FseqRanges[MAX_NUM_SPARSE_RANGES];

// DEBUG_V (String (" numCompressedBlocks: ") + String (fsqHeader.numCompressedBlocks));

FileMgr.ReadSdFile (FileHandleForFileBeingPlayed,
(uint8_t*)&FseqRanges[0],
sizeof (FseqRanges),
fsqHeader.numCompressedBlocks * 8 + sizeof(fsqHeader));

// DEBUG_V (String (" numSparseRanges: ") + String (fsqHeader.numSparseRanges));
uint32_t SparseRangeIndex = 0;
for (auto& CurrentSparseRange : SparseRanges)
{
// DEBUG_V (String (" Sparse Range Index: ") + String (SparseRangeIndex));
if (SparseRangeIndex >= fsqHeader.numSparseRanges)
{
// DEBUG_V (String ("No Sparse Range Data for this entry "));
++SparseRangeIndex;
continue;
}

CurrentSparseRange.DataOffset = read24 (FseqRanges[SparseRangeIndex].Start);
CurrentSparseRange.ChannelCount = read24 (FseqRanges[SparseRangeIndex].Length);

// DEBUG_V (String (" ChannelCount: ") + String (CurrentSparseRange.ChannelCount));
// DEBUG_V (String (" DataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX));

++SparseRangeIndex;
}
}
else
{
SparseRanges[0].DataOffset = 0;
SparseRanges[0].ChannelCount = fsqHeader.channelCount;
}

// DEBUG_V (String (" LastPlayedFrameId: ") + String (p_InputFPPRemotePlayFile->LastPlayedFrameId));
// DEBUG_V (String (" numCompressedBlocks: ") + String (fsqHeader.numCompressedBlocks));
// DEBUG_V (String (" DataOffset: ") + String (p_InputFPPRemotePlayFile->DataOffset));
// DEBUG_V (String (" Total ChannelsPerFrame: ") + String (p_InputFPPRemotePlayFile->ChannelsPerFrame));
// DEBUG_V (String (" FrameStepTimeMS: ") + String (p_InputFPPRemotePlayFile->FrameStepTimeMS));
// DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence));
// DEBUG_V (String (" StartTimeMS: ") + String (p_InputFPPRemotePlayFile->StartTimeMS));
// DEBUG_V (String (" RemainingPlayCount: ") + p_InputFPPRemotePlayFile->RemainingPlayCount);

Expand Down
5 changes: 0 additions & 5 deletions ESPixelStick/src/input/InputFPPRemotePlayFileFsm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ class fsm_PlayFile_state_PlayingFile : public fsm_PlayFile_state
uint32_t ChannelCount;
};

#define MAX_NUM_SPARSE_RANGES 5
SparseRange SparseRanges[MAX_NUM_SPARSE_RANGES];
c_FileMgr::FileId FileHandleForFileBeingPlayed = 0;


}; // fsm_PlayFile_state_PlayingFile

/*****************************************************************************/
Expand Down
30 changes: 15 additions & 15 deletions ESPixelStick/src/service/FPPDiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,28 +406,28 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St
DynamicJsonDocument JsonDoc (4*1024);
JsonObject JsonData = JsonDoc.to<JsonObject> ();

FSEQHeader fsqHeader;
FSEQRawHeader fsqHeader;
FileMgr.ReadSdFile (fseq, (byte*)&fsqHeader, sizeof (fsqHeader), 0);

JsonData[F ("Name")] = fname;
JsonData[CN_Version] = String (fsqHeader.majorVersion) + "." + String (fsqHeader.minorVersion);
JsonData[F ("ID")] = int64String (fsqHeader.id);
JsonData[F ("ID")] = int64String (read64 (fsqHeader.id, 0));
JsonData[F ("StepTime")] = String (fsqHeader.stepTime);
JsonData[F ("NumFrames")] = String (fsqHeader.TotalNumberOfFramesInSequence);
JsonData[F ("NumFrames")] = String (read32 (fsqHeader.TotalNumberOfFramesInSequence, 0));
JsonData[F ("CompressionType")] = fsqHeader.compressionType;

uint32_t maxChannel = fsqHeader.channelCount;
uint32_t maxChannel = read32 (fsqHeader.channelCount, 0);

if (0 != fsqHeader.numSparseRanges)
{
JsonArray JsonDataRanges = JsonData.createNestedArray (F ("Ranges"));

maxChannel = 0;

uint8_t* RangeDataBuffer = (uint8_t*)malloc (6 * fsqHeader.numSparseRanges);
FSEQRangeEntry* CurrentFSEQRangeEntry = (FSEQRangeEntry*)RangeDataBuffer;
uint8_t* RangeDataBuffer = (uint8_t*)malloc (sizeof(FSEQRawRangeEntry) * fsqHeader.numSparseRanges);
FSEQRawRangeEntry* CurrentFSEQRangeEntry = (FSEQRawRangeEntry*)RangeDataBuffer;

FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRangeEntry), fsqHeader.numCompressedBlocks * 8 + 32);
FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRawRangeEntry), fsqHeader.numCompressedBlocks * 8 + 32);

for (int CurrentRangeIndex = 0;
CurrentRangeIndex < fsqHeader.numSparseRanges;
Expand All @@ -450,10 +450,10 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St
}

JsonData[F ("MaxChannel")] = String (maxChannel);
JsonData[F ("ChannelCount")] = String (fsqHeader.channelCount);
JsonData[F ("ChannelCount")] = String (read32 (fsqHeader.channelCount,0));

uint32_t FileOffsetToCurrentHeaderRecord = read16 ((uint8_t*)&fsqHeader.headerLen);
uint32_t FileOffsetToStartOfSequenceData = read16 ((uint8_t*)&fsqHeader.dataOffset); // DataOffset
uint32_t FileOffsetToCurrentHeaderRecord = read16 (fsqHeader.VariableHdrOffset);
uint32_t FileOffsetToStartOfSequenceData = read16 (fsqHeader.dataOffset); // DataOffset

// DEBUG_V (String ("FileOffsetToCurrentHeaderRecord: ") + String (FileOffsetToCurrentHeaderRecord));
// DEBUG_V (String ("FileOffsetToStartOfSequenceData: ") + String (FileOffsetToStartOfSequenceData));
Expand All @@ -462,16 +462,16 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St
{
JsonArray JsonDataHeaders = JsonData.createNestedArray (F ("variableHeaders"));

char FSEQVariableDataHeaderBuffer[sizeof (FSEQVariableDataHeader) + 1];
char FSEQVariableDataHeaderBuffer[sizeof (FSEQRawVariableDataHeader) + 1];
memset ((uint8_t*)FSEQVariableDataHeaderBuffer, 0x00, sizeof (FSEQVariableDataHeaderBuffer));
FSEQVariableDataHeader* pCurrentVariableHeader = (FSEQVariableDataHeader*)FSEQVariableDataHeaderBuffer;
FSEQRawVariableDataHeader* pCurrentVariableHeader = (FSEQRawVariableDataHeader*)FSEQVariableDataHeaderBuffer;

while (FileOffsetToCurrentHeaderRecord < FileOffsetToStartOfSequenceData)
{
FileMgr.ReadSdFile (fseq, (byte*)FSEQVariableDataHeaderBuffer, sizeof (FSEQVariableDataHeader), FileOffsetToCurrentHeaderRecord);
FileMgr.ReadSdFile (fseq, (byte*)FSEQVariableDataHeaderBuffer, sizeof (FSEQRawVariableDataHeader), FileOffsetToCurrentHeaderRecord);

int VariableDataHeaderTotalLength = read16 ((uint8_t*)&(pCurrentVariableHeader->length));
int VariableDataHeaderDataLength = VariableDataHeaderTotalLength - sizeof (FSEQVariableDataHeader);
int VariableDataHeaderDataLength = VariableDataHeaderTotalLength - sizeof (FSEQRawVariableDataHeader);

String HeaderTypeCode (pCurrentVariableHeader->type);

Expand All @@ -488,7 +488,7 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St
free (VariableDataHeaderDataBuffer);
}

FileOffsetToCurrentHeaderRecord += VariableDataHeaderTotalLength + sizeof (FSEQVariableDataHeader);
FileOffsetToCurrentHeaderRecord += VariableDataHeaderTotalLength + sizeof (FSEQRawVariableDataHeader);
} // while there are headers to process
} // there are headers to process

Expand Down
Loading

0 comments on commit 7594102

Please sign in to comment.