Solution to partial commercial skipping esp. with live games

I had this issue for months, and decided to put my extra Claude Code tokens on it. AI is amazing--it not only diagnosed and created a work-around, but also has a suggestion to the Channels devs to fix it. I don't have the source code, but it was able to use the installed files to diagnose the fix. Wow! What a time to be alive!

I asked CC to generate a post for this forum and here it is below:

TL;DR: If commercial markers stop partway through a game you're watching while it records, comskip has probably crashed. I traced this to an unbounded copy into the fixed ccData[500] caption buffer in comskip. The overflow corrupts the XDS entry count, and the XDS parser then runs off the end of memory. Each live retry can trigger it. Turning off caption detection stopped the crash in my testing, but the workaround has real trade-offs (below).

The root cause work was done by Claude (Anthropic's AI, running in Claude Code on my server), including the crash dump analysis, the disassembly and the test design. I asked the questions and made the calls on what to change. Please check the findings for yourselves, but the reproduction below takes seconds.

Environment

  • Channels DVR 2026.10.24.0621 on Windows 11, x64
  • Comskip 0.83.001 (comskip.exe PE timestamp 0x6ad64702)
  • HDHomeRun FLEX 4K, over-the-air MPEG-2 with captions
  • "Start live detection when watching in-progress recording" enabled

Symptoms

  • Commercial markers stop partway through a recording you're watching while it records. This mostly showed up on sports.
  • The DVR log shows:
    Commercial detection failed for <file>: exit status 0xc0000005: Comskip 0.83.001, made using ffmpeg
  • After the recording ends, the DVR doesn't rerun detection, so the partial markers stay. Redetect Commercials fixes that recording.
  • From June 13 to November 1, my DVR log shows 87 live scans crashed and 48 finished. Through October 31, all 156 standard scans succeeded.

Root cause

The fault. Comskip faults at comskip.exe+0x2fd2d, in the XDS packet handling, while looping over 100-byte entries. Three captured crashes, two on a growing file and one on a finished file, all fault at that instruction and read the same bad address, 0x244fe00c, just past the end of the .data section.

The corrupted value. The XDS entry count is garbage: 0x1F01FE19, 0x3898FEFE and 0x0305FE90 in the three crashes. That count sits 504 bytes after the start of the caption buffer, whose GA94 header is at RVA 0x1cb525e0.

The overflow. In the Fancy Bits source, video_packet_process copies AV_FRAME_DATA_A53_CC side data with no bound (mpeg2dec.c about lines 1715-1733, buffer at comskip.c:927). I don't know the exact commit in this binary, but the disassembly at +0x34ac0 shows the same unbounded copy:

ccDataLen = sd->size + 7;
...
ccData[i+7] = sd->data[i];   // no bound, ccData is 500 bytes

The dump shows about 10 frames' worth of caption triples joined together in that buffer (each starts fc 80 80 fd, padded with fa 00 00). They run past the end and onto the count. The bytes overwriting the count are caption data, such as fe 01 1f.

The crash. When an XDS end-of-packet byte (0x8f) arrives, the parser searches its table using the corrupted count and walks off the end of memory.

Why live scans (partly inference). At the end of a growing file, comskip's retry path closes and reopens the file, then seeks by byte estimate to a point that is usually mid-GOP. FFmpeg's mpeg12dec.c appends A53 data for each picture, up to 6000 bytes, so captions from skipped pictures can arrive together on the first decoded picture. That fits the dump and explains why a standard scan, which only starts once at the head of the file, doesn't hit it. We read that in the source but didn't observe it directly. What we can't yet explain: why crash rates vary so much by run. Crashed runs died after 12 to 355 retries, while two runs survived more than 2,300 each with no crash.

This doesn't look like the same bug as the August and September caption fixes (v2026.08.11, v2026.08.14, v2026.09.05). This build includes them and still crashes. From the commits, the August fixes look like a different code path. I found no existing forum report or GitHub issue for this one.

Reproduce it in under a minute

No DVR, live recording or admin rights needed. Copy the comskip.ini from a live scan's log folder (it has live_tv=1), then run this on a finished recording with captions:

comskip.exe --selftest=4 --ini=<that ini> --output=<scratch folder> "<recording>.mpg"

--selftest=4 forces the same reopen-and-seek every 500 frames. On a 3.5-hour MPEG-2 recording, it crashed in 24 seconds after 19 seeks, at the same instruction as the live crashes. That's one recording; I haven't tried it on others.

When run from a normal user account, Windows also writes a dump to %LOCALAPPDATA%\CrashDumps. Crashes under the DVR service left no such record.

Test results

Removing detect_method bit 16 (123 to 107) stops the caption parsing, though the overflowing copy itself still runs.

Test Captions on (123) Captions off (107)
Selftest, finished recording, 1 thread Crash after 19 seeks 1,608 seeks, exit 0
Selftest, finished recording, 6 threads Not run 1,608 seeks, exit 0
Standalone live scans on a game in progress 3 of 3 crashed (12, 124, 145 retries) No crash in 752 retries (I stopped it)

On the real DVR, the first live scan using the workaround caught up to live on an NFL game and hadn't crashed when I wrote this, about 30 minutes in. Earlier scans on that same game had crashed 6 times. That's one game, so treat it as promising.

Accuracy of a captions-off standard scan against that recording's existing markers:

Recording Agreement Breaks (both scans)
World Series game, 3.5 h 99.17% 25
NFL game, 4.1 h 99.64% 27

Those are agreement with the old markers, not checks against the true ad times, and it's only two recordings. Shows that lean more on captions could do worse.

Ruled out by testing or log analysis: CPU load, a separate high-CPU scheduled job (crashes showed no correlation, and most predate it), broadcast clock resets, and seek distance.

Workaround

Create comskip.ini in the DVR's data folder (on Windows, C:\ProgramData\ChannelsDVR\data\). The DVR reads it at each scan, so no restart is needed. To undo it, delete the file.

verbose=10
detect_method=107
punish_no_logo=0
cc_correct_type_modifier=1
length_nonstrict_modifier=1.5
combined_length_nonstrict_modifier=1
min_show_segment_length=222
min_commercialbreak=45
use_existing_logo_file=0
logo_fraction=0.39
delete_logo_file=1
output_vdr=1
output_edl=1
output_ffmeta=1
output_ffsplit=1
thread_count=6
live_tv=1
live_tv_retries=24

That's the DVR's generated default for this build, with detect_method changed and the last three lines added. Set thread_count to suit your CPU.

Before you use it:

  • The override replaces the DVR's generated ini completely. The DVR doesn't add its usual per-scan settings, so without the last three lines, live scans get live_tv=0 and stop at the end of the file with no error. Normally the DVR uses thread_count=1 for live scans, so 6 threads here is a change.
  • It applies to every recording, not only sports, and caption detection is off for all of them.
  • Finished scans take longer, by about 1.4 minutes in my test, because live_tv=1 makes comskip retry at the end of each file.
  • You stop getting new defaults from Channels while the file exists. Delete it once this is fixed.
  • The API won't do this. Comskip keeps the first value of a repeated key, so a setting appended after the default detect_method is ignored.
  • Only tested on Windows, with OTA MPEG-2, on one server.
  • Don't raise verbose to 12 or higher while debugging this. From the source, a large ccDataLen can then overflow a stack buffer in ProcessCCData.

If you don't need markers while a recording is in progress, turning off live detection is simpler. Standard scans didn't crash for me.

Suggested fix for the Channels devs

Not compiled or tested. Clamp the copy in video_packet_process:

int n = FFMIN(sd->size, (int)sizeof(ccData) - 7);
ccDataLen = n + 7;
for (int j = 0; j < n; j++)
    ccData[j+7] = sd->data[j];

Ideally, also split accumulated data into chunks of at most 31 triplets, since ccData[5] holds a 5-bit count, and bound temp[2000] in ProcessCCData. A related improvement on the DVR side would be to rerun detection when a recording finishes if its live scan failed. Keeping existing markers until a rescan produces new ones would help too.

I can submit diagnostics and share the crash dumps if that's useful.

Yes, we would like diagnostics.

I've been getting regular comskip c0000005 crashes for live commercial detection while watching KCAL news.

Diagnostics: 8ea4b9f9-851b-4cc6-b2c7-1d1876a91251
Timestamp: 2026/11/01 21:17:29.939160

Here are my submitted logs: 5ff7ec9f-5113-49eb-9149-baa8e62dbfd2

AI claims it can be reproduced in under a minute

No DVR, live recording or admin rights needed. Copy the comskip.ini from a live scan's log folder (it has live_tv=1), then run this on a finished recording with captions:

comskip.exe --selftest=4 --ini=<that ini> --output=<scratch folder> "<recording>.mpg"

--selftest=4 forces the same reopen-and-seek every 500 frames. On a 3.5-hour MPEG-2 recording, it crashed in 24 seconds after 19 seeks, at the same instruction as the live crashes.

When run from a normal user account, Windows also writes a dump to %LOCALAPPDATA%\CrashDumps. Crashes under the DVR service left no such record.