The root cause has been found and fixed. Two separate bugs were introduced in 5.6.003 with the SoftCSA changes:
Bug 1 — lib/dvb/pvrparse.cpp
processPacket() was changed to return -2 for a "broken startcode" (was return 0 in 5.6.002). The new parseData() propagates this via early exit, and
asyncWrite() treats -2 as stream corruption and calls return len before the actual disk write — meaning recording data is silently discarded. This
affects channels where a PUSI packet's PES payload doesn't begin with 0x000001 (CI-decrypted channels, MPEG-1 audio, subtitle streams, etc.).
Fix: revert broken startcode to return 0. A missing PES start code means "skip PTS extraction for this packet" — it is not stream corruption.
Bug 2 — lib/dvb/filepush.cpp (the intermittent ~1/3 cause)
eFilePushThreadRecorder::m_protocol was never initialized in the constructor. 5.6.003 added a !getProtocol() guard before calling
m_ts_parser.parseData() in asyncWrite(). When the recorder object is allocated from previously-used heap memory, m_protocol contains garbage from a
prior session. !getProtocol() then returns false, parseData() is never called, no PTS timestamps are collected, and stopSave() finds no access points
and skips writing .ap entirely.
This explains the intermittent pattern: the first recording after a reboot uses fresh zero-initialized memory (works), later recordings reuse freed
heap (fails ~1/3 of the time depending on what the allocator returns).
Fix: add m_protocol(0), m_session_id(0), m_stream_id(0), m_packet_no(0) to the constructor initializer list in filepush.cpp.
Both fixes are in EB-TNAP/enigma2-OBH branch Python3.13, commits 95a0b50fdd (pvrparse) and 611af2dc83 (filepush). Verified working — .ap and .sc files
now generated correctly across FTA DVB-T, encrypted DVB, and all resolutions.
The cdf62b2 fix ("missing return value in parseData") targets a different symptom and does not address either of these root causes.