Split direct v210 read and copy timing

This commit is contained in:
Johanness
2026-05-19 15:02:22 +03:00
parent 973c547c53
commit b096f32d75
6 changed files with 102 additions and 7 deletions
+9 -1
View File
@@ -17,6 +17,12 @@ enum class FeedRuntimeStatus
Error Error
}; };
struct V210ReadTiming
{
uint64_t sourceReadNs = 0;
uint64_t payloadCopyNs = 0;
};
class IVideoFeed class IVideoFeed
{ {
public: public:
@@ -57,11 +63,13 @@ public:
virtual bool readV210FrameInto( virtual bool readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) size_t destinationSize,
V210ReadTiming* timing = nullptr)
{ {
(void)frameCounter; (void)frameCounter;
(void)destination; (void)destination;
(void)destinationSize; (void)destinationSize;
(void)timing;
return false; return false;
} }
virtual uint32_t v210Width() const { return 0; } virtual uint32_t v210Width() const { return 0; }
+34 -2
View File
@@ -575,10 +575,17 @@ const VideoFrame& MxlSdkFeed::getFrame(uint32_t frameCounter)
bool MxlSdkFeed::readV210FrameInto( bool MxlSdkFeed::readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) size_t destinationSize,
V210ReadTiming* timing)
{ {
(void)frameCounter; (void)frameCounter;
if (timing != nullptr)
{
timing->sourceReadNs = 0;
timing->payloadCopyNs = 0;
}
if (!mFlowOpened && !openFlow()) if (!mFlowOpened && !openFlow())
{ {
return false; return false;
@@ -598,6 +605,8 @@ bool MxlSdkFeed::readV210FrameInto(
uint8_t* payload = nullptr; uint8_t* payload = nullptr;
const auto readStart = std::chrono::steady_clock::now();
while (true) while (true)
{ {
mxlStatus status = mxlFlowReaderGetGrainNonBlocking( mxlStatus status = mxlFlowReaderGetGrainNonBlocking(
@@ -653,6 +662,8 @@ bool MxlSdkFeed::readV210FrameInto(
return false; return false;
} }
const auto readEnd = std::chrono::steady_clock::now();
const size_t payloadSize = const size_t payloadSize =
static_cast<size_t>(mSourceStride) * static_cast<size_t>(mSourceStride) *
static_cast<size_t>(mSourceHeight); static_cast<size_t>(mSourceHeight);
@@ -665,7 +676,22 @@ bool MxlSdkFeed::readV210FrameInto(
return false; return false;
} }
const auto copyStart = std::chrono::steady_clock::now();
std::memcpy(destination, payload, payloadSize); std::memcpy(destination, payload, payloadSize);
const auto copyEnd = std::chrono::steady_clock::now();
if (timing != nullptr)
{
timing->sourceReadNs =
static_cast<uint64_t>(
std::chrono::duration_cast<std::chrono::nanoseconds>(
readEnd - readStart).count());
timing->payloadCopyNs =
static_cast<uint64_t>(
std::chrono::duration_cast<std::chrono::nanoseconds>(
copyEnd - copyStart).count());
}
mLastDisplayedIndex = index; mLastDisplayedIndex = index;
++mFrameVersion; ++mFrameVersion;
return true; return true;
@@ -793,11 +819,17 @@ bool MxlSdkFeed::supportsDirectV210Read() const { return false; }
bool MxlSdkFeed::readV210FrameInto( bool MxlSdkFeed::readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) size_t destinationSize,
V210ReadTiming* timing)
{ {
(void)frameCounter; (void)frameCounter;
(void)destination; (void)destination;
(void)destinationSize; (void)destinationSize;
if (timing != nullptr)
{
timing->sourceReadNs = 0;
timing->payloadCopyNs = 0;
}
return false; return false;
} }
uint32_t MxlSdkFeed::v210Width() const { return 0; } uint32_t MxlSdkFeed::v210Width() const { return 0; }
+2 -1
View File
@@ -50,7 +50,8 @@ public:
bool readV210FrameInto( bool readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) override; size_t destinationSize,
V210ReadTiming* timing = nullptr) override;
uint32_t v210Width() const override; uint32_t v210Width() const override;
uint32_t v210Height() const override; uint32_t v210Height() const override;
uint32_t v210Stride() const override; uint32_t v210Stride() const override;
+20 -1
View File
@@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <chrono>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@@ -151,8 +152,15 @@ bool SyntheticV210Feed::supportsDirectV210Read() const
bool SyntheticV210Feed::readV210FrameInto( bool SyntheticV210Feed::readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) size_t destinationSize,
V210ReadTiming* timing)
{ {
if (timing != nullptr)
{
timing->sourceReadNs = 0;
timing->payloadCopyNs = 0;
}
if (destination == nullptr || mPayloads.empty()) if (destination == nullptr || mPayloads.empty())
{ {
return false; return false;
@@ -171,7 +179,18 @@ bool SyntheticV210Feed::readV210FrameInto(
return false; return false;
} }
const auto copyStart = std::chrono::steady_clock::now();
std::memcpy(destination, payload.data(), payload.size()); std::memcpy(destination, payload.data(), payload.size());
const auto copyEnd = std::chrono::steady_clock::now();
if (timing != nullptr)
{
timing->payloadCopyNs =
static_cast<uint64_t>(
std::chrono::duration_cast<std::chrono::nanoseconds>(
copyEnd - copyStart).count());
}
mGrainIndex = index; mGrainIndex = index;
++mFrameVersion; ++mFrameVersion;
return true; return true;
+2 -1
View File
@@ -30,7 +30,8 @@ public:
bool readV210FrameInto( bool readV210FrameInto(
uint32_t frameCounter, uint32_t frameCounter,
void* destination, void* destination,
size_t destinationSize) override; size_t destinationSize,
V210ReadTiming* timing = nullptr) override;
uint32_t v210Width() const override; uint32_t v210Width() const override;
uint32_t v210Height() const override; uint32_t v210Height() const override;
uint32_t v210Stride() const override; uint32_t v210Stride() const override;
+35 -1
View File
@@ -47,6 +47,8 @@ struct PerfStats
uint64_t feedReadTicks = 0; uint64_t feedReadTicks = 0;
uint64_t uploadDecodeTicks = 0; uint64_t uploadDecodeTicks = 0;
uint64_t stageCopyTicks = 0; uint64_t stageCopyTicks = 0;
uint64_t directV210SourceReadNs = 0;
uint64_t directV210PayloadCopyNs = 0;
uint64_t uploadRecordTicks = 0; uint64_t uploadRecordTicks = 0;
uint64_t submitPresentTicks = 0; uint64_t submitPresentTicks = 0;
uint64_t idleDelayTicks = 0; uint64_t idleDelayTicks = 0;
@@ -65,6 +67,8 @@ struct FramePerfStats
uint64_t fenceWaitTicks = 0; uint64_t fenceWaitTicks = 0;
uint64_t feedReadTicks = 0; uint64_t feedReadTicks = 0;
uint64_t stageCopyTicks = 0; uint64_t stageCopyTicks = 0;
uint64_t directV210SourceReadNs = 0;
uint64_t directV210PayloadCopyNs = 0;
uint64_t maxStageCopyTicks = 0; uint64_t maxStageCopyTicks = 0;
uint64_t maxStageCopyBytes = 0; uint64_t maxStageCopyBytes = 0;
uint32_t maxStageCopyFeed = 0; uint32_t maxStageCopyFeed = 0;
@@ -1610,6 +1614,7 @@ int main(int argc, char* argv[])
if (directV210Read) if (directV210Read)
{ {
V210ReadTiming directReadTiming{};
const size_t v210Bytes = const size_t v210Bytes =
static_cast<size_t>( static_cast<size_t>(
feeds[i]->v210Stride() feeds[i]->v210Stride()
@@ -1622,7 +1627,8 @@ int main(int argc, char* argv[])
feeds[i]->readV210FrameInto( feeds[i]->readV210FrameInto(
frameCounter, frameCounter,
v210Feeds[i].v210MappedData, v210Feeds[i].v210MappedData,
v210Bytes v210Bytes,
&directReadTiming
); );
const uint64_t version = const uint64_t version =
feeds[i]->frameVersion(); feeds[i]->frameVersion();
@@ -1632,6 +1638,18 @@ int main(int argc, char* argv[])
recordFeedVersionStats(i, uploadNeeded); recordFeedVersionStats(i, uploadNeeded);
if (config.logPerf)
{
perfStats.directV210SourceReadNs +=
directReadTiming.sourceReadNs;
perfStats.directV210PayloadCopyNs +=
directReadTiming.payloadCopyNs;
framePerf.directV210SourceReadNs +=
directReadTiming.sourceReadNs;
framePerf.directV210PayloadCopyNs +=
directReadTiming.payloadCopyNs;
}
if (!uploadNeeded) if (!uploadNeeded)
{ {
continue; continue;
@@ -2117,6 +2135,14 @@ int main(int argc, char* argv[])
<< (framePerf.feedReadTicks * invMs) << (framePerf.feedReadTicks * invMs)
<< "ms stageCopy=" << "ms stageCopy="
<< (framePerf.stageCopyTicks * invMs) << (framePerf.stageCopyTicks * invMs)
<< "ms v210Read="
<< (static_cast<double>(
framePerf.directV210SourceReadNs) /
1000000.0)
<< "ms v210Copy="
<< (static_cast<double>(
framePerf.directV210PayloadCopyNs) /
1000000.0)
<< "ms stageCopies=" << "ms stageCopies="
<< framePerf.stageCopies << framePerf.stageCopies
<< " v210Copies=" << " v210Copies="
@@ -2168,6 +2194,14 @@ int main(int argc, char* argv[])
<< (perfStats.uploadDecodeTicks * invMs / frames) << (perfStats.uploadDecodeTicks * invMs / frames)
<< "ms stageCopy=" << "ms stageCopy="
<< (perfStats.stageCopyTicks * invMs / frames) << (perfStats.stageCopyTicks * invMs / frames)
<< "ms v210Read="
<< (static_cast<double>(
perfStats.directV210SourceReadNs) /
1000000.0 / frames)
<< "ms v210Copy="
<< (static_cast<double>(
perfStats.directV210PayloadCopyNs) /
1000000.0 / frames)
<< "ms uploadRecord=" << "ms uploadRecord="
<< (perfStats.uploadRecordTicks * invMs / frames) << (perfStats.uploadRecordTicks * invMs / frames)
<< "ms submitPresent=" << "ms submitPresent="