Avoid steady-state v210 double copy
This commit is contained in:
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user