Avoid steady-state v210 double copy
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "VideoFrame.hpp"
|
#include "VideoFrame.hpp"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -52,6 +53,17 @@ public:
|
|||||||
virtual bool hasV210() const { return false; }
|
virtual bool hasV210() const { return false; }
|
||||||
|
|
||||||
virtual const uint8_t* v210Data() const { return nullptr; }
|
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 v210Width() const { return 0; }
|
||||||
virtual uint32_t v210Height() const { return 0; }
|
virtual uint32_t v210Height() const { return 0; }
|
||||||
virtual uint32_t v210Stride() const { return 0; }
|
virtual uint32_t v210Stride() const { return 0; }
|
||||||
|
|||||||
+111
@@ -518,6 +518,105 @@ const VideoFrame& MxlSdkFeed::getFrame(uint32_t frameCounter)
|
|||||||
return mFrame;
|
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
|
FeedRuntimeStatus MxlSdkFeed::status() const
|
||||||
{
|
{
|
||||||
if (mFlowOpened && !mV210Payload.empty())
|
if (mFlowOpened && !mV210Payload.empty())
|
||||||
@@ -616,6 +715,7 @@ float MxlSdkFeed::srcAspectRatio() const
|
|||||||
|
|
||||||
bool MxlSdkFeed::hasV210() const { return mFlowOpened && !mV210Payload.empty(); }
|
bool MxlSdkFeed::hasV210() const { return mFlowOpened && !mV210Payload.empty(); }
|
||||||
const uint8_t* MxlSdkFeed::v210Data() const { return mV210Payload.data(); }
|
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::v210Width() const { return mSourceWidth; }
|
||||||
uint32_t MxlSdkFeed::v210Height() const { return mSourceHeight; }
|
uint32_t MxlSdkFeed::v210Height() const { return mSourceHeight; }
|
||||||
uint32_t MxlSdkFeed::v210Stride() const { return mSourceStride; }
|
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; }
|
float MxlSdkFeed::srcAspectRatio() const { return 16.0f / 9.0f; }
|
||||||
bool MxlSdkFeed::hasV210() const { return false; }
|
bool MxlSdkFeed::hasV210() const { return false; }
|
||||||
const uint8_t* MxlSdkFeed::v210Data() const { return nullptr; }
|
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::v210Width() const { return 0; }
|
||||||
uint32_t MxlSdkFeed::v210Height() const { return 0; }
|
uint32_t MxlSdkFeed::v210Height() const { return 0; }
|
||||||
uint32_t MxlSdkFeed::v210Stride() const { return 0; }
|
uint32_t MxlSdkFeed::v210Stride() const { return 0; }
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ public:
|
|||||||
|
|
||||||
bool hasV210() const override;
|
bool hasV210() const override;
|
||||||
const uint8_t* v210Data() 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 v210Width() const override;
|
||||||
uint32_t v210Height() const override;
|
uint32_t v210Height() const override;
|
||||||
uint32_t v210Stride() 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<const VideoFrame*> pendingFrames(feedCount);
|
||||||
std::vector<uint64_t> pendingVersions(feedCount);
|
std::vector<uint64_t> pendingVersions(feedCount);
|
||||||
std::vector<bool> pendingUploadNeeded(feedCount);
|
std::vector<bool> pendingUploadNeeded(feedCount);
|
||||||
|
std::vector<bool> postFenceDirectV210Read(feedCount);
|
||||||
std::vector<double> feedUploadCredits(feedCount, 1.0);
|
std::vector<double> feedUploadCredits(feedCount, 1.0);
|
||||||
uint64_t lastUploadPaceTicks = SDL_GetPerformanceCounter();
|
uint64_t lastUploadPaceTicks = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
@@ -1353,6 +1354,11 @@ int main(int argc, char* argv[])
|
|||||||
pendingUploadNeeded.end(),
|
pendingUploadNeeded.end(),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
std::fill(
|
||||||
|
postFenceDirectV210Read.begin(),
|
||||||
|
postFenceDirectV210Read.end(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
const uint64_t uploadPaceTicks =
|
const uint64_t uploadPaceTicks =
|
||||||
SDL_GetPerformanceCounter();
|
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)
|
for (uint32_t i = 0; i < feedCount; ++i)
|
||||||
{
|
{
|
||||||
|
if (v210FeedReady[i] &&
|
||||||
|
feeds[i]->supportsDirectV210Read())
|
||||||
|
{
|
||||||
|
postFenceDirectV210Read[i] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
perfSectionStartTicks =
|
perfSectionStartTicks =
|
||||||
SDL_GetPerformanceCounter();
|
SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
@@ -1405,33 +1455,7 @@ int main(int argc, char* argv[])
|
|||||||
perfStats.feedReadTicks += elapsed;
|
perfStats.feedReadTicks += elapsed;
|
||||||
framePerf.feedReadTicks += elapsed;
|
framePerf.feedReadTicks += elapsed;
|
||||||
|
|
||||||
if (uploadNeeded)
|
recordFeedVersionStats(i, 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uploadNeeded)
|
if (!uploadNeeded)
|
||||||
@@ -1511,12 +1535,16 @@ int main(int argc, char* argv[])
|
|||||||
const uint32_t i =
|
const uint32_t i =
|
||||||
(uploadStart + offset) % feedCount;
|
(uploadStart + offset) % feedCount;
|
||||||
|
|
||||||
if (!pendingUploadNeeded[i])
|
const bool directV210Read =
|
||||||
|
postFenceDirectV210Read[i];
|
||||||
|
|
||||||
|
if (!directV210Read && !pendingUploadNeeded[i])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isV210 = feeds[i]->hasV210();
|
const bool isV210 =
|
||||||
|
directV210Read || feeds[i]->hasV210();
|
||||||
if (config.paceUploads &&
|
if (config.paceUploads &&
|
||||||
isV210 &&
|
isV210 &&
|
||||||
feeds[i]->hasFrameRate() &&
|
feeds[i]->hasFrameRate() &&
|
||||||
@@ -1543,7 +1571,7 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
if (isV210)
|
if (isV210)
|
||||||
{
|
{
|
||||||
if (!v210FeedReady[i])
|
if (!directV210Read && !v210FeedReady[i])
|
||||||
{
|
{
|
||||||
v210Decoder.createFeedResources(
|
v210Decoder.createFeedResources(
|
||||||
ctx.physicalDevice(),
|
ctx.physicalDevice(),
|
||||||
@@ -1580,6 +1608,39 @@ int main(int argc, char* argv[])
|
|||||||
<< std::endl;
|
<< 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(
|
std::memcpy(
|
||||||
v210Feeds[i].v210MappedData,
|
v210Feeds[i].v210MappedData,
|
||||||
feeds[i]->v210Data(),
|
feeds[i]->v210Data(),
|
||||||
@@ -1588,6 +1649,7 @@ int main(int argc, char* argv[])
|
|||||||
) * feeds[i]->v210Height()
|
) * feeds[i]->v210Height()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copyFrameToFeedTextureStaging(
|
copyFrameToFeedTextureStaging(
|
||||||
|
|||||||
Reference in New Issue
Block a user