Merge pull request #552 from webadderallorg/fix/windows-wgc-relative-timestamps

fix(windows): normalize WGC video timestamps
This commit is contained in:
Phạm Thị Minh Hồng
2026-05-22 18:13:03 +07:00
committed by GitHub
4 changed files with 44 additions and 7 deletions
@@ -5,10 +5,10 @@
"helpers": {
"wgc-capture": {
"binaryName": "wgc-capture.exe",
"binarySha256": "b840fb2847ac8fcfc5137febfc8dd49b55a4d15bea4f9185a0916fb0c1544bed",
"binarySha256": "47a67765a0b7fdd9936e41a2f7e62f6408bd426774f7854e6378194ebe3ae827",
"sourceDir": "electron/native/wgc-capture",
"sourceFingerprint": "fdbc8002a894a1300c7fed58a0f7aae18119dbb2bd71bcaacf3bfc398db904a9",
"updatedAt": "2026-05-22T10:12:36.734Z"
"sourceFingerprint": "696c9f56da75105941063b7940eb91c231e781e9a3a4ba885e47bcfdf798f13f",
"updatedAt": "2026-05-22T10:43:18.337Z"
},
"cursor-monitor": {
"binaryName": "cursor-monitor.exe",
Binary file not shown.
+38 -4
View File
@@ -152,6 +152,7 @@ bool MFEncoder::initialize(const std::wstring& outputPath, int width, int height
const int uvSize = (width_ / 2) * (height_ / 2) * 2;
nv12Buffer_.resize(ySize + uvSize);
lastFrameBuffer_.clear();
firstSampleTimeHns_ = -1;
lastSampleTimeHns_ = -1;
initialized_ = true;
@@ -234,14 +235,17 @@ bool MFEncoder::writeFrame(ID3D11Texture2D* texture, int64_t timestampHns) {
// WGC may stop delivering frames while the scene is static; keep the MP4
// timeline continuous by repeating the previous frame before writing a new one.
if (!lastFrameBuffer_.empty() && !extendLastFrameToLocked(timestampHns)) {
int64_t normalizedTimestampHns = 0;
normalizeWriteTimestampHnsLocked(timestampHns, normalizedTimestampHns);
if (!lastFrameBuffer_.empty() && !extendLastFrameToLocked(normalizedTimestampHns)) {
return false;
}
bool wroteSample = writeNv12SampleLocked(nv12Buffer_, timestampHns);
bool wroteSample = writeNv12SampleLocked(nv12Buffer_, normalizedTimestampHns);
if (wroteSample) {
lastFrameBuffer_ = nv12Buffer_;
lastSampleTimeHns_ = timestampHns;
lastSampleTimeHns_ = normalizedTimestampHns;
}
return wroteSample;
}
@@ -249,7 +253,36 @@ bool MFEncoder::writeFrame(ID3D11Texture2D* texture, int64_t timestampHns) {
bool MFEncoder::extendLastFrameTo(int64_t timestampHns) {
std::lock_guard<std::mutex> lock(mutex_);
return extendLastFrameToLocked(timestampHns);
int64_t normalizedTimestampHns = 0;
if (!normalizeTimelineTimestampHnsLocked(timestampHns, normalizedTimestampHns)) {
return false;
}
return extendLastFrameToLocked(normalizedTimestampHns);
}
void MFEncoder::normalizeWriteTimestampHnsLocked(int64_t timestampHns, int64_t& normalizedTimestampHns) {
if (firstSampleTimeHns_ < 0) {
firstSampleTimeHns_ = timestampHns < 0 ? 0 : timestampHns;
}
normalizedTimestampHns = timestampHns - firstSampleTimeHns_;
if (normalizedTimestampHns < 0) {
normalizedTimestampHns = 0;
}
}
bool MFEncoder::normalizeTimelineTimestampHnsLocked(
int64_t timestampHns,
int64_t& normalizedTimestampHns
) const {
if (firstSampleTimeHns_ < 0) return false;
normalizedTimestampHns = timestampHns - firstSampleTimeHns_;
if (normalizedTimestampHns < 0) {
normalizedTimestampHns = 0;
}
return true;
}
bool MFEncoder::extendLastFrameToLocked(int64_t timestampHns) {
@@ -332,6 +365,7 @@ bool MFEncoder::finalize() {
lastFrameBuffer_.clear();
nv12Buffer_.shrink_to_fit();
lastFrameBuffer_.shrink_to_fit();
firstSampleTimeHns_ = -1;
lastSampleTimeHns_ = -1;
MFShutdown();
return SUCCEEDED(hr);
@@ -24,6 +24,8 @@ public:
bool finalize();
private:
void normalizeWriteTimestampHnsLocked(int64_t timestampHns, int64_t& normalizedTimestampHns);
bool normalizeTimelineTimestampHnsLocked(int64_t timestampHns, int64_t& normalizedTimestampHns) const;
bool extendLastFrameToLocked(int64_t timestampHns);
bool writeNv12SampleLocked(const std::vector<uint8_t>& frameBuffer, int64_t timestampHns);
@@ -39,6 +41,7 @@ private:
int width_ = 0;
int height_ = 0;
int fps_ = 60;
int64_t firstSampleTimeHns_ = -1;
int64_t lastSampleTimeHns_ = -1;
bool initialized_ = false;
std::mutex mutex_;