One Year of ORF2 Trouble: Building My Own Tvheadend Patch with AI Help

During a test with ORF 2, everything looked unspectacular at first: the stream was running, then the regional news started – and at some point the picture was gone. Not briefly gone, not with a small glitch, but gone in a way that meant Tvheadend could practically no longer recover the channel after the switch. The return from the regional to the national program was particularly easy to reproduce: frozen picture, stop and play had no effect, switching channels did not help either. In the test, the reliable way to recover was, of all things, to restart Tvheadend. As a fix, that is about as elegant as rebooting the fuse box when the lights go out.The reproducible error turned into a fairly stubborn technical question: what does ORF 2 change in the transport stream at that moment – and why does Tvheadend stumble over exactly that?

Tvheadend is not a playground in my setup, but the central TV server. The satellite dish supplies the signal, and Tvheadend distributes it over the home network or Wi-Fi to the televisions. That allowed me to replace conventional cable TV: no additional monthly cable-TV fee and, above all, no coaxial cable to every single device. Wherever a network connection or Wi-Fi is available, a suitable client can show live TV. On top of that, there are central recordings, timeshift and a backend that runs independently of the televisions. For the troubleshooting described below, the ORF2 stream switch served as the technical test case.

I still describe my general setup with Docker, SAT>IP, recordings, timeshift and transcoding in the Tvheadend basics article. This article, on the other hand, is about a reproducible stream error – and how workarounds, targeted tests around 7:21 p.m. and Codex analysis eventually turned into my own patch for the official Tvheadend repository.

⚠

As of October 4, 2026: The combined pull request #2206 is open, ready for review and not merged. The GitHub issue #1973 is still open as well. The fix described here is therefore not yet part of Tvheadend master and is not a regularly shipped standard feature.

Tvheadend: an amazing amount of TV in one server

For me, Tvheadend is still one of those open-source projects whose feature list is longer than some user manuals: DVB-S/S2, DVB-C, DVB-T, SAT>IP, IPTV, HTSP, recordings, timeshift and transcoding. In particular, the ability to make an existing satellite installation available centrally and then distribute television over the normal network makes conventional star-shaped TV cabling unnecessary in many rooms. In my case, this setup also replaces an active cable-TV subscription.

At the same time, you can tell that the project has a long history. The codebase is large and has grown over time, some of the technology looks a little dated today, and the release cadence is unusual as well. Anyone checking the GitHub releases on September 30, 2026 will still find v4.3 marked as a Pre-release. Current commits continue to land in the master branch, however, and the official container registry keeps publishing new images; at the time of research, the tags latest, master and edge pointed to the same freshly built digest.

Tvheadend is certainly not abandoned. It is more of a special mix of active development and a very mature, complex foundation. Not every bug therefore disappears quickly into a traditional stable release. The ORF2 issue illustrates that quite well: it was opened on October 25, 2025 and was still open almost a year later. The fact that developers and testers nevertheless spend time on such a specific broadcasting edge case is, to me, more of an argument for the project than against it.

A workaround is not a fix

Technically, the error is quite specific. In the test case, it is easy to explain: ORF 2 switches between national and regional program segments for its regional news broadcasts. The service remains in place, but the video, audio and teletext PIDs can change. That is exactly where Tvheadend could lose the running stream. The open issue #1973 describes the same effect: the last picture freezes, after stop and play the channel stays black, and restarting Tvheadend is the workaround.

My first reaction in the test setup was therefore very pragmatic: the main thing was to get the stream back after the switch. Two ORF2 services, switching priorities, API and cron scripts, a watchdog – that allowed the error to be caught automatically. I had also documented that earlier approach in the basics article.

A workaround has one unpleasant property, though: it remains a workaround. It has to know about the error, react at the right moment and repair something outside Tvheadend that Tvheadend itself should really handle properly. As a test aid it was useful; as the actual fix, it was not. So I wanted to know why the channel died in the first place.

What AI actually changed here

Programming is nothing new to me. What was new was getting into a large, unfamiliar C codebase like Tvheadend and, of all things, tracking down a bug that appears only when a very specific change occurs in a running MPEG transport stream. This is exactly where AI became a lever for me.

I did not unleash Codex with a magical „fix Tvheadend“ prompt. Instead, I gave it source code, specific log files and observations. I had it analyze suspicious code paths, explain connections and compare possible causes. After that, every suggestion had to go back into the test: compile, start, wait for the ORF2 switch and check whether the live stream, timeshift and recording path still worked.

Codex helped me find my way around the unfamiliar codebase, narrow down suspicious areas more quickly and explain connections that I had not fully understood myself down to the last detail. That was a major part of the benefit for me: I did not first have to understand the entire Tvheadend codebase before I could work meaningfully on this specific problem.

7:21 p.m.: when a bug has a broadcast schedule

The test cycle was almost funnier than the bug itself. For the patch tests, on several days I deliberately used the short window around approximately 7:21 p.m. At that time, the ORF2 stream under test switched from the regional program back to the national one – exactly the moment when the problematic PID switch occurred.

The workflow was correspondingly slow: change the code, rebuild it, start Tvheadend with the patch and then wait for the stream switch. If it did not work, the next meaningful repetition might not be possible until the following day. My debugger therefore did not have a breakpoint, but a broadcast schedule.

As tedious as that was, it also had an advantage: every bit of progress had to prove itself against the actual stream switch. A patch that looked clean in the code was only interesting to me once Tvheadend survived the switching point in the test.

The first fix: tiny change, big effect

The first solid root cause was surprisingly unspectacular. During the ORF2 switch, elementary streams are replaced while the service remains active. In elementary_stream_create_parent(), Tvheadend could stop the search too early when a teletext stream had moved. As a result, the highest internal component index already in use was no longer reliably taken into account.

In the unfavorable case, two components received the same internal index – in the documented ORF2 case, for example, H.264 video and teletext. The first pull request #2204 essentially does something astonishingly simple: it searches the existing stream list completely before assigning a new unique index to the replacement stream.

That was the first real aha moment. A bug that looked in the test like the complete death of a channel and repeatedly required a restart could be traced in the live path to a comparatively small logic change.

Live stream fixed. Naturally, the story was not over.

The patch could not only repair the live path, though. Tvheadend also processes the same stream for recordings and timeshift. If the source PIDs change while the service is running, these paths also have to understand which new stream corresponds to the previous video, audio or teletext stream.

Pass-through recordings needed a stable output mapping: the source PID may change, but the recording should still keep a consistent program externally. Timeshift was even trickier. On August 4, the combined PR was even moved back to draft because live TV and recording were already continuing to work, but time-shifted live TV after a PID change was not yet reliable.

Several variants and tests followed until jumping back in the buffer and switching back to live also worked with the correct stream mapping in each case. The changes from #2204 and #2205 are now bundled in the open PR #2206. It contains three separate building blocks: unique stream indexes, stable PIDs for pass-through recordings and restoration of the active stream mapping after timeshift seeks.

From an AI suggestion to a tested patch

Codex helped me understand the relationships between stream reconfiguration, recording and timeshift more quickly and try out different approaches. It would be an exaggeration to claim that I completely understood the entire codebase or every detail afterward. For this specific problem, that was not necessary either: I could have the relevant areas explained to me, ask follow-up questions, test changes and move step by step closer to the cause.

That is exactly why, for me, the interesting part is not „AI writes a patch“, but the combination of AI, my own experience and real tests. A convincing-looking diff is not proof. Only compiling, trying it out, observing the error, refining the change and testing again turns it into something that can hold up in an unfamiliar codebase.

What changed as a result: you do not have to master every detail of a project before you can make a useful start. If you understand the basics – or have the AI explain them to you ;-) – provide precise observations and carefully verify the results, you can now get into unfamiliar systems much faster. That is exactly how this ORF2 test case ultimately became a contribution to Tvheadend development.

Is the ORF2 fix already included in Tvheadend?

No, not as of September 30, 2026. #2206 is open and ready for review, but not merged. The issue #1973 is still open. The branch page for #2206 also explicitly states that this branch is not deployed.

Anyone running Tvheadend in production should therefore distinguish between a successful test build, an open pull request, a merge into master and an actually shipped version. The patch has made it from a restart workaround in the test case to a cleanly isolated and practically tested fix – but it has not crossed the project's finish line yet.

Sources

positive Bewertung({{pro_count}})
Rate Post:
{{percentage}} % positive
negative Bewertung({{con_count}})

THANK YOU for your review!

created by Bernhard | published: | Updated: | Übersetzung Deutsch |🔔 | Comments:0

Questions / Comments