diff --git a/modules/ANSCV/ANSRTSP.cpp b/modules/ANSCV/ANSRTSP.cpp index bf726bb..09e4851 100644 --- a/modules/ANSCV/ANSRTSP.cpp +++ b/modules/ANSCV/ANSRTSP.cpp @@ -1103,18 +1103,22 @@ extern "C" __declspec(dllexport) int GetRTSPCVImage( RTSP_DBG("[GetRTSPCVImage] SKIP CUDA — player not playing (reconnecting?)"); } - // Lightweight timing via spdlog (no OutputDebugString). - // Logs only when the frame grab + D2D exceeds 50ms — helps diagnose stalls - // without the overhead of per-frame debug logging. + // Lightweight timing — logs only when frame grab + D2D exceeds 50ms. + // Goes to both spdlog (console/file) AND OutputDebugString (DebugView) + // but ONLY for slow frames, so the overhead is negligible (<1 call/sec + // under normal conditions vs 500+/sec with full debug logging). auto t2 = std::chrono::steady_clock::now(); double getImageMs = std::chrono::duration(t1 - t0).count(); double cudaMs = std::chrono::duration(t2 - t1).count(); double totalMs = getImageMs + cudaMs; if (totalMs > 50.0) { - (*Handle)->_logger.LogWarn("GetRTSPCVImage", - std::format("SLOW FRAME: total={:.1f}ms (getImage={:.1f}ms cuda={:.1f}ms) {}x{}", - totalMs, getImageMs, cudaMs, width, height), - __FILE__, __LINE__); + auto msg = std::format("SLOW FRAME: total={:.1f}ms (getImage={:.1f}ms cuda={:.1f}ms) {}x{}", + totalMs, getImageMs, cudaMs, width, height); + (*Handle)->_logger.LogWarn("GetRTSPCVImage", msg, __FILE__, __LINE__); +#ifdef _WIN32 + auto dbg = std::format("[GetRTSPCVImage] {}\n", msg); + OutputDebugStringA(dbg.c_str()); +#endif } return 1; // Success diff --git a/modules/ANSCV/GpuNV12SlotPool.cpp b/modules/ANSCV/GpuNV12SlotPool.cpp index b15b028..dadbdd6 100644 --- a/modules/ANSCV/GpuNV12SlotPool.cpp +++ b/modules/ANSCV/GpuNV12SlotPool.cpp @@ -55,8 +55,15 @@ GpuNV12Slot* GpuNV12SlotPool::acquire(int gpuIdx, int w, int h) { // 3. No matching free slot — allocate a new one if under the limit if (static_cast(m_slots.size()) >= GPU_NV12_POOL_MAX_SLOTS) { - NV12POOL_DBG("acquire: POOL FULL (%zu slots) — fallback to CPU path", - m_slots.size()); + // Always log POOL FULL to DebugView — this is a critical diagnostic. + { + char _buf[128]; + snprintf(_buf, sizeof(_buf), "[NV12Pool] POOL FULL (%zu slots) — fallback to CPU\n", m_slots.size()); +#ifdef _WIN32 + OutputDebugStringA(_buf); +#endif + fprintf(stderr, "%s", _buf); + } return nullptr; } @@ -100,6 +107,19 @@ GpuNV12Slot* GpuNV12SlotPool::acquire(int gpuIdx, int w, int h) { GpuNV12Slot* raw = slot.get(); m_slots.push_back(std::move(slot)); + // Always log new slot allocation to DebugView (rare event — once per resolution per camera). + { + char _buf[256]; + snprintf(_buf, sizeof(_buf), + "[NV12Pool] NEW slot #%zu: %dx%d gpu=%d Y=%p UV=%p pitchY=%zu stream=%p\n", + m_slots.size(), w, h, gpuIdx, raw->bufY, raw->bufUV, raw->pitchY, raw->copyStream); +#ifdef _WIN32 + OutputDebugStringA(_buf); +#endif + fprintf(stderr, "%s", _buf); + } + + // Also log POOL FULL to DebugView (important diagnostic). NV12POOL_DBG("acquire: NEW slot Y=%p UV=%p pitchY=%zu pitchUV=%zu %dx%d gpu=%d stream=%p (total=%zu)", raw->bufY, raw->bufUV, raw->pitchY, raw->pitchUV, w, h, gpuIdx, raw->copyStream, m_slots.size());