Avoid steady-state v210 double copy

This commit is contained in:
Johanness
2026-05-19 00:43:04 +03:00
parent 3df545e95c
commit 32f5b70f59
4 changed files with 227 additions and 37 deletions
+12
View File
@@ -2,6 +2,7 @@
#include "VideoFrame.hpp"
#include <cstddef>
#include <cstdint>
#include <string>
@@ -52,6 +53,17 @@ public:
virtual bool hasV210() const { return false; }
virtual const uint8_t* v210Data() const { return nullptr; }
virtual bool supportsDirectV210Read() const { return false; }
virtual bool readV210FrameInto(
uint32_t frameCounter,
void* destination,
size_t destinationSize)
{
(void)frameCounter;
(void)destination;
(void)destinationSize;
return false;
}
virtual uint32_t v210Width() const { return 0; }
virtual uint32_t v210Height() const { return 0; }
virtual uint32_t v210Stride() const { return 0; }
+111
View File
@@ -518,6 +518,105 @@ const VideoFrame& MxlSdkFeed::getFrame(uint32_t frameCounter)
return mFrame;
}
bool MxlSdkFeed::readV210FrameInto(
uint32_t frameCounter,
void* destination,
size_t destinationSize)
{
(void)frameCounter;
if (!mFlowOpened && !openFlow())
{
return false;
}
uint64_t index = mLastDisplayedIndex + 1;
const uint64_t currentIndex = mxlGetCurrentIndex(&mGrainRate);
if (index > currentIndex)
{
return false;
}
mxlGrainInfo grain{};
grain.version = 2;
grain.size = sizeof(mxlGrainInfo);
uint8_t* payload = nullptr;
while (true)
{
mxlStatus status = mxlFlowReaderGetGrainNonBlocking(
mReader,
index,
&grain,
&payload);
if (status == MXL_STATUS_OK)
{
break;
}
if (status == MXL_ERR_OUT_OF_RANGE_TOO_EARLY)
{
return false;
}
if (status == MXL_ERR_OUT_OF_RANGE_TOO_LATE)
{
mxlFlowRuntimeInfo runtimeInfo{};
if (mxlFlowReaderGetRuntimeInfo(mReader, &runtimeInfo) !=
MXL_STATUS_OK)
{
return false;
}
if (runtimeInfo.headIndex == 0)
{
return false;
}
index = runtimeInfo.headIndex - 1;
if (index <= mLastDisplayedIndex)
{
return false;
}
continue;
}
if (status == MXL_ERR_FLOW_INVALID)
{
std::cerr << "MxlSdkFeed: flow invalidated, reconnecting"
<< std::endl;
closeFlow();
return false;
}
std::cerr << "MxlSdkFeed: grain read error status="
<< static_cast<int>(status) << std::endl;
return false;
}
const size_t payloadSize =
static_cast<size_t>(mSourceStride) *
static_cast<size_t>(mSourceHeight);
if (payload == nullptr ||
destination == nullptr ||
payloadSize == 0 ||
destinationSize < payloadSize)
{
return false;
}
std::memcpy(destination, payload, payloadSize);
mLastDisplayedIndex = index;
++mFrameVersion;
return true;
}
FeedRuntimeStatus MxlSdkFeed::status() const
{
if (mFlowOpened && !mV210Payload.empty())
@@ -616,6 +715,7 @@ float MxlSdkFeed::srcAspectRatio() const
bool MxlSdkFeed::hasV210() const { return mFlowOpened && !mV210Payload.empty(); }
const uint8_t* MxlSdkFeed::v210Data() const { return mV210Payload.data(); }
bool MxlSdkFeed::supportsDirectV210Read() const { return mFlowOpened; }
uint32_t MxlSdkFeed::v210Width() const { return mSourceWidth; }
uint32_t MxlSdkFeed::v210Height() const { return mSourceHeight; }
uint32_t MxlSdkFeed::v210Stride() const { return mSourceStride; }
@@ -635,6 +735,17 @@ double MxlSdkFeed::frameRate() const { return 0.0; }
float MxlSdkFeed::srcAspectRatio() const { return 16.0f / 9.0f; }
bool MxlSdkFeed::hasV210() const { return false; }
const uint8_t* MxlSdkFeed::v210Data() const { return nullptr; }
bool MxlSdkFeed::supportsDirectV210Read() const { return false; }
bool MxlSdkFeed::readV210FrameInto(
uint32_t frameCounter,
void* destination,
size_t destinationSize)
{
(void)frameCounter;
(void)destination;
(void)destinationSize;
return false;
}
uint32_t MxlSdkFeed::v210Width() const { return 0; }
uint32_t MxlSdkFeed::v210Height() const { return 0; }
uint32_t MxlSdkFeed::v210Stride() const { return 0; }
+5
View File
@@ -46,6 +46,11 @@ public:
bool hasV210() const override;
const uint8_t* v210Data() const override;
bool supportsDirectV210Read() const override;
bool readV210FrameInto(
uint32_t frameCounter,
void* destination,
size_t destinationSize) override;
uint32_t v210Width() const override;
uint32_t v210Height() const override;
uint32_t v210Stride() const override;
+92 -30
View File
@@ -836,6 +836,7 @@ int main(int argc, char* argv[])
std::vector<const VideoFrame*> pendingFrames(feedCount);
std::vector<uint64_t> pendingVersions(feedCount);
std::vector<bool> pendingUploadNeeded(feedCount);
std::vector<bool> postFenceDirectV210Read(feedCount);
std::vector<double> feedUploadCredits(feedCount, 1.0);
uint64_t lastUploadPaceTicks = SDL_GetPerformanceCounter();
@@ -1353,6 +1354,11 @@ int main(int argc, char* argv[])
pendingUploadNeeded.end(),
false
);
std::fill(
postFenceDirectV210Read.begin(),
postFenceDirectV210Read.end(),
false
);
const uint64_t uploadPaceTicks =
SDL_GetPerformanceCounter();
@@ -1385,8 +1391,52 @@ int main(int argc, char* argv[])
}
}
auto recordFeedVersionStats =
[&](uint32_t feedIndex, bool uploadNeeded)
{
if (!config.logPerf)
{
return;
}
if (uploadNeeded)
{
++feedPerfStats[feedIndex].updates;
if (feeds[feedIndex]->hasGrainIndex())
{
const uint64_t grain =
feeds[feedIndex]->grainIndex();
if (feedPerfStats[feedIndex].hasLastGrain &&
grain >
feedPerfStats[feedIndex].lastGrain + 1)
{
feedPerfStats[feedIndex].skippedGrains +=
grain -
feedPerfStats[feedIndex].lastGrain -
1;
}
feedPerfStats[feedIndex].lastGrain = grain;
feedPerfStats[feedIndex].hasLastGrain = true;
}
}
else
{
++feedPerfStats[feedIndex].repeats;
}
};
for (uint32_t i = 0; i < feedCount; ++i)
{
if (v210FeedReady[i] &&
feeds[i]->supportsDirectV210Read())
{
postFenceDirectV210Read[i] = true;
continue;
}
perfSectionStartTicks =
SDL_GetPerformanceCounter();
@@ -1405,33 +1455,7 @@ int main(int argc, char* argv[])
perfStats.feedReadTicks += elapsed;
framePerf.feedReadTicks += elapsed;
if (uploadNeeded)
{
++feedPerfStats[i].updates;
if (feeds[i]->hasGrainIndex())
{
const uint64_t grain =
feeds[i]->grainIndex();
if (feedPerfStats[i].hasLastGrain &&
grain >
feedPerfStats[i].lastGrain + 1)
{
feedPerfStats[i].skippedGrains +=
grain -
feedPerfStats[i].lastGrain -
1;
}
feedPerfStats[i].lastGrain = grain;
feedPerfStats[i].hasLastGrain = true;
}
}
else
{
++feedPerfStats[i].repeats;
}
recordFeedVersionStats(i, uploadNeeded);
}
if (!uploadNeeded)
@@ -1511,12 +1535,16 @@ int main(int argc, char* argv[])
const uint32_t i =
(uploadStart + offset) % feedCount;
if (!pendingUploadNeeded[i])
const bool directV210Read =
postFenceDirectV210Read[i];
if (!directV210Read && !pendingUploadNeeded[i])
{
continue;
}
const bool isV210 = feeds[i]->hasV210();
const bool isV210 =
directV210Read || feeds[i]->hasV210();
if (config.paceUploads &&
isV210 &&
feeds[i]->hasFrameRate() &&
@@ -1543,7 +1571,7 @@ int main(int argc, char* argv[])
if (isV210)
{
if (!v210FeedReady[i])
if (!directV210Read && !v210FeedReady[i])
{
v210Decoder.createFeedResources(
ctx.physicalDevice(),
@@ -1580,6 +1608,39 @@ int main(int argc, char* argv[])
<< std::endl;
}
if (directV210Read)
{
const size_t v210Bytes =
static_cast<size_t>(
feeds[i]->v210Stride()
) *
static_cast<size_t>(
feeds[i]->v210Height()
);
const bool copied =
feeds[i]->readV210FrameInto(
frameCounter,
v210Feeds[i].v210MappedData,
v210Bytes
);
const uint64_t version =
feeds[i]->frameVersion();
const bool uploadNeeded =
copied &&
uploadedVersions[i] != version;
recordFeedVersionStats(i, uploadNeeded);
if (!uploadNeeded)
{
continue;
}
pendingVersions[i] = version;
}
else
{
std::memcpy(
v210Feeds[i].v210MappedData,
feeds[i]->v210Data(),
@@ -1588,6 +1649,7 @@ int main(int argc, char* argv[])
) * feeds[i]->v210Height()
);
}
}
else
{
copyFrameToFeedTextureStaging(