NZXT Signal 4K30 repareren deel 2: de groen/roze videobug

Na de reparatie heb ik het apparaat getest met verschillende HDMI-bronnen om te controleren of alles correct werkte. Zoals ik in mijn vorige bericht al aangaf:

"Ik vond één 720p60 HDMI-bron die hij niet leuk vindt — de opgenomen video verschijnt als roze en groen."

In dat bericht verwees ik ook naar enkele Reddit-threads waar soortgelijke problemen waren waargenomen bij respectievelijk een PS5 en een Nintendo Switch.

De kleuren in de beelden van de problematische HDMI-bron waren volledig fout; ze waren groen en paars. Vanuit mijn ervaring met video-encoders en -decoders wist ik dat dit typisch gedrag is bij een mismatch tussen RGB- en YUV-video. Ik twijfelde eraan of het om defecte hardware ging, zeker omdat andere gebruikers op Reddit precies dezelfde symptomen rapporteerden.

Ik liet het aanvankelijk rusten, omdat ik het niet erg vond dat dit ene apparaat niet correct capturede en ik NZXT niet had gecontacteerd. Inmiddels lijkt het apparaat volledig uit de markt te zijn verdwenen. Het is niet meer te koop via Amazon of Newegg, en de website van NZXT vermeldt het product alleen nog onder de support-sectie. Het is duidelijk dat NZXT uit de markt voor capture cards is gestapt.

Onderzoek met behulp van AI

Onlangs kreeg ik het idee om Claude te gebruiken voor dit probleem, aangezien ik de AI de laatste tijd inzet voor diepgaand reverse engineering en bug-onderzoek. (Een voorbeeld hiervan is een door mij onderzocht reverse-engineered Linux kernel V4L2-driver voor de Elgato Game Capture HD60 S). Ik vroeg me af of we samen het laatste probleem — dat ik vermoedde een firmware-probleem te zijn — konden oplossen.

Tijdens de hardwarematige reparatie had ik alle gebruikte componenten gedocumenteerd. Deze informatie gaf ik aan Claude, samen met:

  • Een beschrijving van het probleem;
  • Foto's van de fouten uit de Reddit-posts;
  • De laatste firmware-update van NZXT uit 2022;
  • Een checkout van een GitHub-repository met de driver van ITE voor de IT6805 HDMI-receiver IC, die in de Signal 4K30 wordt gebruikt.

Ik gaf specifiek aan dat ik een RGB- versus YUV-mismatch vermoedde.

De analyse van de bug

Na ongeveer 15 minuten kwam Claude terug met resultaten. De AI stemde ermee overeen dat het om een YUV- versus RGB-mismatch ging en wees op enkele veelbelovende bugs in de firmware. Om dit te verifiëren, vroeg Claude mij om zaken over het gedetecteerde signaal te controleren.

Ik ontdekte dat de Cortex-M0 microcontroller een UART heeft met debug-output. Met een draagbare oscilloscoop vond ik de ongemerkte debug-header op de PCB en bepaalde ik de TX-pin en de baudrate. Ik legde de output vast terwijl de problematische HDMI-bron was aangesloten en stuurde dit terug naar Claude. Daarnaast gebruikte ik mijn reverse-engineered Game Capture HD60 S Linux-driver om meer details te verkrijgen over het type signaal dat de bron uitzond.

Het bleek dat het bronapparaat in DVI-modus uitzond in plaats van HDMI-modus. Dit was een cruciale aanwijzing, aangezien DVI-modus betekent dat bepaalde extra pakketten, zoals AVI InfoFrames, ontbreken.

Claude pinpointte een sectie code in de standaard IT6805-driver van ITE die onjuist leek; deze code was ook aanwezig in de firmware van NZXT. Hier is een ingekorte snippet:

// REG6B[5:4]: Reg_ColMod_Set Input color mode set 00: RGB mode - 01: YUV422 mode, 10: YUV444 mode, 11: YUV420 mode
chgbank(0);
if (iTE6805_Check_HDMI_OR_DVI_Mode(iTE6805_DATA.CurrentPort) == MODE_HDMI)
{
    HDMIRX_DEBUG_PRINT(("---- CSC HDMI mode ----\n"));
    ...
    hdmirxset(0x6B, 0x30, iTE6805_DATA.AVIInfoFrame_Input_ColorFormat << 4);// seting input format by info frame ??? do not need ???
    ...
}
else
{
    ...
    HDMIRX_DEBUG_PRINT(("---- CSC DVI mode ----\n"));
    hdmirxset(0x6B, 0x30, 0x10);                        // seting input format to RGB
    ...
}

Deze code bepaalt of de IT6805 een HDMI- of DVI-signaal heeft gedetecteerd en configureert registers op basis van dat resultaat. Als het een HDMI-signaal is, wordt de kleurmodus direct uit het AVI InfoFrame gehaald en geplaatst in bits 4 en 5 van register 0x6B.

Als het echter een DVI-signaal is, gaat de code ervan uit dat het videosignaal RGB moet zijn, en probeert hij diezelfde bits in register 0x6B voor RGB-modus te configureren.

Echter, de code is fout. De commentaar zegt correct dat het in dit geval geconfigureerd moet worden voor RGB (“seting input format to RGB”), maar in werkelijkheid schrijft de code 01 naar bits 5:4. Volgens de commentaar bovenaan betekent dit echter YUV 4:2:2-modus.

Ik vermoed dat de oorspronkelijke ITE-ontwikkelaar een leesfout heeft gemaakt. In de commentaar staat 00: RGB mode. De manier waarop de tekst is opgebouwd (met een streepje voor RGB en komma's voor de rest) kan ervoor zorgen dat men onbewust RGB mode – 01 leest.

De oplossing: Firmware Patchen

Omdat de debug UART geen mogelijkheid bood om de registers van de IT6805 direct te lezen of te schrijven, was de enige manier om dit te testen het patchen van de firmware. Hoewel Claude adviseerde om eerst via SWD een backup van de firmware te maken om "bricking" te voorkomen, besloot ik het risico te nemen.

Claude hielp me met het volgende:

  1. Reverse engineeren van de NZXT firmware-update utility om te begrijpen hoe deze werkt.
  2. Controleren of het veilig was om de firmware simpelweg te patchen (zonder dat een checksum of CRC de update zou blokkeren).
  3. Het aanpassen van één byte in de NZXT-firmware: de instructie movs r2, #16 werd gewijzigd in movs r2, #0.

Daarnaast schreef Claude een command-line utility die de firmware reflasht met behulp van de DLL uit de updater van NZXT. De standaard utility van NZXT kon ik niet gebruiken, omdat deze weigert een update te installeren als het apparaat al "up to date" is.

Na het uitvoeren van de updater en het opnieuw opstarten van de capture card, opende ik OBS. Tot mijn opluchting werkte alles nog, en de bug was verdwenen! De kleuren van mijn DVI-bron waren nu perfect.

Conclusie

Dit was definitief de oorzaak. Aangezien het een bug is in de driver van ITE, beïnvloedt dit waarschijnlijk veel andere apparaten die deze vendor-code gebruiken zonder deze uitgebreid te testen met verschillende HDMI-bronnen.

In mijn geval leverde het bronapparaat helemaal geen InfoFrames. Een HDMI-sink device dat een signaal zonder InfoFrames tegenkomt, zou moeten aannemen dat de data RGB is. Andere gebruikers kunnen tegen dit probleem aanlopen, zelfs met moderne HDMI-bronnen, als ze bijvoorbeeld een oude DVI-monitor aangesloten hebben op de passthrough-poort waarvan de EDID om wat voor reden dan ook geen HDMI-modus ondersteunt.

Het is mogelijk dat de PS5 en Switch uit de Reddit-posts een ander probleem hadden met dezelfde symptomen, maar voor mijn specifieke situatie werkte de fix van Claude perfect.

Voor wie dezelfde uitgeproduceerde NZXT Signal 4K30 capture card heeft, heb ik de firmware-bugfix gedeeld in deze GitHub-repository, inclusief installatie-instructies: https://github.com/dougg3/nzxt-signal-4k30-color-bug-firmware-patch/

Ik ben diep onder de indruk van hoe goed Claude is geworden in het opsporen van bugs en het reverse engineeren van firmware. Hoewel ik soms tegen de cybersecurity-beveiligingen (guardrails) van Anthropic aanloop bij dergelijke projecten, was dit project een compleet succes. Het voelt goed om het verhaal van mijn Signal 4K30 reparatie definitief af te kunnen sluiten.