Added Util::packetSorter with async/sync modes, set DTSC outputs to use async mode

This commit is contained in:
Thulinma 2021-07-04 22:14:40 +02:00
parent 6042c1ea70
commit dae32ede11
5 changed files with 278 additions and 135 deletions

View file

@ -201,6 +201,133 @@ void Util::sanitizeName(std::string &streamname){
}
}
/// Initalizes the packetSorter in sync mode.
Util::packetSorter::packetSorter(){
dequeMode = false;
}
/// Sets sync mode on if true (sync), off if false (async).
void Util::packetSorter::setSyncMode(bool synced){
if (dequeMode != !synced){
dequeMode = !synced;
if (!dequeMode){
//we've switched away from deque
for (std::deque<Util::sortedPageInfo>::iterator it = dequeBuffer.begin(); it != dequeBuffer.end(); ++it){
insert(*it);
}
dequeBuffer.clear();
}else{
//we've switched away from set
for (std::set<Util::sortedPageInfo>::iterator it = setBuffer.begin(); it != setBuffer.end(); ++it){
insert(*it);
}
setBuffer.clear();
}
}
}
/// Returns true if we're synced, false if async.
bool Util::packetSorter::getSyncMode() const{return !dequeMode;}
/// Returns the amount of packets currently in the sorter.
size_t Util::packetSorter::size() const{
if (dequeMode){return dequeBuffer.size();}else{return setBuffer.size();}
}
/// Clears all packets from the sorter; does not reset mode.
void Util::packetSorter::clear(){
dequeBuffer.clear();
setBuffer.clear();
}
/// Returns a pointer to the first packet in the sorter.
const Util::sortedPageInfo * Util::packetSorter::begin() const{
if (dequeMode){
return &*dequeBuffer.begin();
}else{
return &*setBuffer.begin();
}
}
/// Inserts a new packet in the sorter.
void Util::packetSorter::insert(const sortedPageInfo &pInfo){
if (dequeMode){
dequeBuffer.push_back(pInfo);
}else{
setBuffer.insert(pInfo);
}
}
/// Removes the given track ID packet from the sorter. Removes at most one packet, make sure to prevent duplicates elsewhere!
void Util::packetSorter::dropTrack(size_t tid){
if (dequeMode){
for (std::deque<Util::sortedPageInfo>::iterator it = dequeBuffer.begin(); it != dequeBuffer.end(); ++it){
if (it->tid == tid){
dequeBuffer.erase(it);
return;
}
}
}else{
for (std::set<Util::sortedPageInfo>::iterator it = setBuffer.begin(); it != setBuffer.end(); ++it){
if (it->tid == tid){
setBuffer.erase(it);
return;
}
}
}
}
/// Removes the first packet from the sorter and inserts the given packet.
void Util::packetSorter::replaceFirst(const sortedPageInfo &pInfo){
if (dequeMode){
dequeBuffer.pop_front();
if (dequeBuffer.size() && dequeBuffer.front().time > pInfo.time){
dequeBuffer.push_front(pInfo);
}else{
dequeBuffer.push_back(pInfo);
}
}else{
setBuffer.erase(setBuffer.begin());
setBuffer.insert(pInfo);
}
}
/// Removes the first packet from the sorter and inserts it back at the end. No-op for sync mode.
void Util::packetSorter::moveFirstToEnd(){
if (dequeMode){
dequeBuffer.push_back(dequeBuffer.front());
dequeBuffer.pop_front();
}
}
/// Returns true if there is an entry in the sorter for the given track ID.
bool Util::packetSorter::hasEntry(size_t tid) const{
if (dequeMode){
for (std::deque<Util::sortedPageInfo>::const_iterator it = dequeBuffer.begin(); it != dequeBuffer.end(); ++it){
if (it->tid == tid){return true;}
}
}else{
for (std::set<Util::sortedPageInfo>::const_iterator it = setBuffer.begin(); it != setBuffer.end(); ++it){
if (it->tid == tid){return true;}
}
}
return false;
}
/// Fills toFill with track IDs of tracks that are in the sorter.
void Util::packetSorter::getTrackList(std::set<size_t> &toFill) const{
toFill.clear();
if (dequeMode){
for (std::deque<Util::sortedPageInfo>::const_iterator it = dequeBuffer.begin(); it != dequeBuffer.end(); ++it){
toFill.insert(it->tid);
}
}else{
for (std::set<Util::sortedPageInfo>::const_iterator it = setBuffer.begin(); it != setBuffer.end(); ++it){
toFill.insert(it->tid);
}
}
}
JSON::Value Util::getStreamConfig(const std::string &streamname){
JSON::Value result;
if (streamname.size() > 100){

View file

@ -50,6 +50,39 @@ namespace Util{
extern trackSortOrder defaultTrackSortOrder;
void sortTracks(std::set<size_t> & validTracks, const DTSC::Meta & M, trackSortOrder sorting, std::list<size_t> & srtTrks);
/// This struct keeps packet information sorted in playback order
struct sortedPageInfo{
bool operator<(const sortedPageInfo &rhs) const{
if (time < rhs.time){return true;}
return (time == rhs.time && tid < rhs.tid);
}
size_t tid;
uint64_t time;
uint64_t offset;
size_t partIndex;
};
/// Packet sorter used to determine which packet should be output next
class packetSorter{
public:
packetSorter();
size_t size() const;
void clear();
const sortedPageInfo * begin() const;
void insert(const sortedPageInfo &pInfo);
void dropTrack(size_t tid);
void replaceFirst(const sortedPageInfo &pInfo);
void moveFirstToEnd();
bool hasEntry(size_t tid) const;
void getTrackList(std::set<size_t> &toFill) const;
void setSyncMode(bool synced);
bool getSyncMode() const;
private:
bool dequeMode;
std::deque<sortedPageInfo> dequeBuffer;
std::set<sortedPageInfo> setBuffer;
};
class DTSCShmReader{
public: