diff --git a/nodes/pip/main.cpp b/nodes/pip/main.cpp index 02ed452..d9d55a3 100644 --- a/nodes/pip/main.cpp +++ b/nodes/pip/main.cpp @@ -117,7 +117,8 @@ class PiPNode : public dmf::NodeBase { uint64_t index = mxlGetCurrentIndex(&rate); log("start index=%llu", index); - uint64_t frame_count = 0, timeout_count = 0; + uint64_t frame_count = 0, stall_count = 0; + bool fatal = false; while (dmf::g_running.load(std::memory_order_relaxed)) { // WaitForDataAt expects TAI nanoseconds, not a grain index. @@ -130,46 +131,64 @@ class PiPNode : public dmf::NodeBase { uint8_t* bg_buf = nullptr; uint8_t* inset_buf = nullptr; - mxlFlowReaderGetGrainNonBlocking(bg_reader, index, &bg_grain, &bg_buf); - mxlFlowReaderGetGrainNonBlocking(inset_reader, index, &inset_grain, &inset_buf); + const mxlStatus bg_st = mxlFlowReaderGetGrainNonBlocking( + bg_reader, index, &bg_grain, &bg_buf); + const mxlStatus in_st = mxlFlowReaderGetGrainNonBlocking( + inset_reader, index, &inset_grain, &inset_buf); - mxlGrainInfo out_grain{}; - uint8_t* out_buf = nullptr; - if (mxlFlowWriterOpenGrain(out_writer, index, &out_grain, &out_buf) == MXL_STATUS_OK) { - std::memcpy(out_buf, bg_buf, - static_cast(bg_stride) * static_cast(bg_h)); + if (bg_st != MXL_STATUS_OK || in_st != MXL_STATUS_OK || !bg_buf || !inset_buf) { + log("grain read after sync OK: bg=%s inset=%s at index=%llu", + dmf::mxl_status_str(bg_st), dmf::mxl_status_str(in_st), index); + index++; + } else { + mxlGrainInfo out_grain{}; + uint8_t* out_buf = nullptr; + const mxlStatus wst = mxlFlowWriterOpenGrain( + out_writer, index, &out_grain, &out_buf); + if (wst != MXL_STATUS_OK) { + log("writer OpenGrain failed (%s) at index=%llu", + dmf::mxl_status_str(wst), index); + } else { + std::memcpy(out_buf, bg_buf, + static_cast(bg_stride) * static_cast(bg_h)); - dmf::v210::scale_and_overlay( - inset_buf, inset_stride, inset_w, inset_h, - out_buf, out_stride, - pip_x, pip_y, clamped_w, clamped_h, - Y0, Y1, Cb0, Cb1, Cr0, Cr1); + dmf::v210::scale_and_overlay( + inset_buf, inset_stride, inset_w, inset_h, + out_buf, out_stride, + pip_x, pip_y, clamped_w, clamped_h, + Y0, Y1, Cb0, Cb1, Cr0, Cr1); - out_grain.flags = (bg_grain.flags | inset_grain.flags) & MXL_GRAIN_FLAG_INVALID; - out_grain.validSlices = out_grain.totalSlices; - mxlFlowWriterCommitGrain(out_writer, &out_grain); - frame_count++; + out_grain.flags = (bg_grain.flags | inset_grain.flags) & MXL_GRAIN_FLAG_INVALID; + out_grain.validSlices = out_grain.totalSlices; + mxlFlowWriterCommitGrain(out_writer, &out_grain); + frame_count++; + if (frame_count % 25 == 0) + log("heartbeat frames=%llu stalls=%llu index=%llu", + frame_count, stall_count, index); + } + index++; } - index++; } else if (st == MXL_ERR_TIMEOUT || st == MXL_ERR_OUT_OF_RANGE_TOO_EARLY || st == MXL_ERR_OUT_OF_RANGE_TOO_LATE) { - timeout_count++; + stall_count++; const uint64_t current = mxlGetCurrentIndex(&rate); - index = (current > index) ? current : index + 1; - if (timeout_count % 25 == 1) - log("sync stall (%s) frames=%llu count=%llu", - dmf::mxl_status_str(st), frame_count, timeout_count); + const uint64_t next = (current > index) ? current : index + 1; + log("sync stall (%s) at index=%llu → jumping to %llu frames=%llu", + dmf::mxl_status_str(st), index, next, frame_count); + index = next; } else { - log("sync error (%s) at index=%llu", dmf::mxl_status_str(st), index); + log("sync fatal (%s) at index=%llu", dmf::mxl_status_str(st), index); + fatal = true; break; } } - log("stopped at index=%llu frames=%llu timeouts=%llu", - index, frame_count, timeout_count); + log("stopped: %s frames=%llu stalls=%llu index=%llu", + fatal ? "fatal error" : "shutdown signal", + frame_count, stall_count, index); mxlReleaseFlowSynchronizationGroup(instance(), sync_group); mxlReleaseFlowReader(instance(), bg_reader);