{"id":50366079,"url":"https://github.com/rh1tech/frank-video","last_synced_at":"2026-05-30T04:04:23.616Z","repository":{"id":358305393,"uuid":"1240857796","full_name":"rh1tech/frank-video","owner":"rh1tech","description":"MPEG-1 video player for Raspberry Pi Pico 2 (RP2350) — HDMI, SD card, PS/2/USB keyboard","archived":false,"fork":false,"pushed_at":"2026-05-16T17:21:20.000Z","size":3541,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T19:24:17.763Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://frank.rh1.tech/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rh1tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T16:52:56.000Z","updated_at":"2026-05-16T18:55:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rh1tech/frank-video","commit_stats":null,"previous_names":["rh1tech/frank-video"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rh1tech/frank-video","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rh1tech%2Ffrank-video","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rh1tech%2Ffrank-video/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rh1tech%2Ffrank-video/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rh1tech%2Ffrank-video/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rh1tech","download_url":"https://codeload.github.com/rh1tech/frank-video/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rh1tech%2Ffrank-video/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33679310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T04:04:20.966Z","updated_at":"2026-05-30T04:04:23.607Z","avatar_url":"https://github.com/rh1tech.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FRANK VIDEO\n\nOfficial page: **[frank.rh1.tech](https://frank.rh1.tech/)** — hub for all FRANK boards and firmware.\n\nFRANK Video is an MPEG-1 video player for Raspberry Pi Pico 2 (RP2350) — runs on FRANK boards with HDMI output, SD card streaming, PS/2 or USB keyboard. Plays 320×240 MPEG-1 video with stereo MPEG-1 Layer-II audio in real time, decoded by [pl_mpeg](https://github.com/phoboslab/pl_mpeg).\n\n## Screenshots\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"screenshots/screen1.png\" width=\"45%\" alt=\"FRANK Video screen 1\" /\u003e\n  \u003cimg src=\"screenshots/screen2.png\" width=\"45%\" alt=\"FRANK Video screen 2\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"screenshots/screen3.png\" width=\"45%\" alt=\"FRANK Video screen 3\" /\u003e\n\u003c/p\u003e\n\n## Supported Platforms\n\nfrank-video supports two RP2350 hardware variants and two HDMI back-ends. Pin assignments are selected at build time via `BOARD_VARIANT=M1|M2`; the HDMI driver is selected via `HDMI_HSTX=ON|OFF`.\n\n| Platform | Board | Video | Audio |\n|----------|-------|-------|-------|\n| **M2** | [FRANK](https://rh1.tech/projects/frank?area=about) / [Murmulator 2.0](https://murmulator.ru) | HDMI (PIO) | I2S |\n| **M2** | FRANK / Murmulator 2.0 | HDMI (HSTX) | HDMI Audio (Data Islands) |\n| **M1** | Murmulator 1.x | HDMI (PIO) | I2S |\n\nThe default build target is **M2**. The HDMI_ALT variant uses RP2350's native HSTX peripheral for HDMI output and embeds audio inside the HDMI stream as Data Island packets — a single HDMI cable carries both video and audio, no I2S DAC needed.\n\n## Features\n\n- MPEG-1 video playback at 320×240, line-doubled to HDMI 640×480\n- MPEG-1 Layer-II audio decoded to stereo PCM, output via I2S DAC or HDMI audio (HDMI_ALT)\n- Wall-clock-paced decode with frame skipping and audio drift compensation — playback stays in sync over hours\n- Heavy-frame escape: I-frame decode skip on scenes that would blow the realtime budget\n- 8 MB QSPI PSRAM for the streaming ring buffer and pl_mpeg decoder state\n- SD card data loading (FAT32) for the video files\n- 6×6×6 sRGB-correct paletted output with 4×4 Bayer ordered dither\n- File browser UI with self-contained 5×7 font, scroll, paged navigation\n- PS/2 and USB keyboard support\n- All-I-frame MPEG-1 conversion script (`tools/convert_video.sh`) tuned for RP2350's realtime decode budget\n\n## Hardware Requirements\n\n- **Raspberry Pi Pico 2** (RP2350) or compatible board\n- **8 MB QSPI PSRAM** (mandatory — used for the streaming ring buffer)\n- **HDMI connector** (driven via 270 Ω resistors directly from the GPIO; no encoder needed)\n- **SD card module** (SPI mode)\n- **PS/2 keyboard** (or a USB keyboard if `USB_HID=1`)\n- **I2S DAC module** (e.g. TDA1387, PCM5102) for the standard build, OR an HDMI audio sink for the HDMI_ALT build\n\n\u003e **Note:** When `USB_HID=1` is set, the native USB port is used as a USB HID host for keyboard input. USB serial console (CDC) is disabled in this mode; use UART for debug output. PS/2 stays enabled either way.\n\n### PSRAM\n\nfrank-video requires 8 MB PSRAM for the 256 KB pl_mpeg streaming ring buffer plus internal demux buffers that grow at runtime. Without PSRAM, the player cannot stream video. You can obtain PSRAM-equipped hardware in several ways:\n\n1. **Solder a PSRAM chip** on top of the Flash chip on a Pico 2 clone (SOP-8 flash chips are only available on clones, not the original Pico 2).\n2. **Build a [Nyx 2](https://rh1.tech/projects/nyx?area=nyx2)** – a DIY RP2350 board with integrated PSRAM.\n3. **Purchase a [Pimoroni Pico Plus 2](https://shop.pimoroni.com/products/pimoroni-pico-plus-2?variant=42092668289107)** – a ready-made Pico 2 with 8 MB PSRAM.\n\n## Pin Assignments (M1 / M2)\n\n\u003e The PSRAM CS pin is auto-detected from the RP2350 chip package at boot:\n\u003e - **RP2350B**: GPIO 47 (M1 and M2)\n\u003e - **RP2350A**: GPIO 19 (M1) or GPIO 8 (M2)\n\n| Function | Signal      | M1 GPIO | M2 GPIO |\n|----------|-------------|:-------:|:-------:|\n| HDMI     | CLK−        | 6       | 12      |\n| HDMI     | CLK+        | 7       | 13      |\n| HDMI     | D0−         | 8       | 14      |\n| HDMI     | D0+         | 9       | 15      |\n| HDMI     | D1−         | 10      | 16      |\n| HDMI     | D1+         | 11      | 17      |\n| HDMI     | D2−         | 12      | 18      |\n| HDMI     | D2+         | 13      | 19      |\n| SD Card  | CLK         | 2       | 6       |\n| SD Card  | MOSI        | 3       | 7       |\n| SD Card  | MISO        | 4       | 4       |\n| SD Card  | CS          | 5       | 5       |\n| PS/2 Keyboard | CLK    | 0       | 2       |\n| PS/2 Keyboard | DATA   | 1       | 3       |\n| I2S Audio | DATA       | 26      | 9       |\n| I2S Audio | BCLK/LRCLK | 27      | 10      |\n\n\u003e **HDMI** pins are driven directly through 270 Ω series resistors. No HDMI encoder is needed.\n\u003e **HDMI_ALT** (HSTX) requires M2 only — HSTX is hard-wired to GPIO 12-19, which only the M2 layout exposes for HDMI.\n\u003e When the HDMI_ALT build is used, audio is embedded in the HDMI stream and the I2S pins are unused.\n\n## How to Use\n\n### SD Card Setup\n\n1. Format an SD card as **FAT32**.\n2. Copy your `.mpg` files to a `/video` directory on the card (or place them at the root — both work).\n3. Insert the SD card and power on the device.\n\n### Converting Source Material\n\nfrank-video plays MPEG-1 streams encoded for the RP2350's decode budget. Use the bundled converter:\n\n```bash\n./tools/convert_video.sh input.mp4 [output.mpg]\n```\n\nThe converter produces:\n- 320×240 video at 24 fps, all I-frames (`-q:v 14 -g 1 -bf 0`)\n- 32 kHz mono MPEG-1 Layer-II audio at 64 kbps\n- Letterboxed/pillarboxed to fit 320×240 with black bars\n\nIf no output path is given, the file is written next to the input with a `.mpg` extension.\n\n### File Browser\n\nOn boot, frank-video shows a file browser listing the `.mpg` files found on the SD card. Use the arrow keys to navigate, **Enter** to start playback, **ESC** during playback to stop and return to the browser.\n\nIf no SD card is inserted, an error message is shown.\n\n### Controls\n\n| Action | Key |\n|--------|-----|\n| Navigate file list | ↑ ↓ |\n| Page up / down | PgUp / PgDn |\n| Jump to first / last | Home / End |\n| Start playback | Enter |\n| Stop playback | ESC |\n| Pause / resume | Space |\n\n## Building\n\n### Prerequisites\n\n1. Install the [Raspberry Pi Pico SDK](https://github.com/raspberrypi/pico-sdk) (version 2.0+).\n2. Set the environment variable: `export PICO_SDK_PATH=/path/to/pico-sdk`.\n3. Install the ARM GCC toolchain (`arm-none-eabi-gcc`).\n\n### Build\n\n```bash\ngit clone https://github.com/rh1tech/frank-video.git\ncd frank-video\n./build.sh                                          # Default: M2, 504/166/66 MHz, PIO HDMI, USB CDC\nUSB_HID=1 ./build.sh                                # Enable USB HID host (debug over UART)\nUSB_HID=1 ./build.sh -DHDMI_HSTX=ON                 # M2 with HSTX HDMI + HDMI audio\n./build.sh -DBOARD_VARIANT=M1                       # M1 layout\n```\n\nOutput: `build/frank-video.uf2`\n\n### Build Options\n\n- **`BOARD_VARIANT`** (default `M2`): `M1` or `M2` — selects the GPIO map.\n- **`CPU_SPEED`** (default `504`): one of `252` / `378` / `504` MHz. Higher is faster but needs higher core voltage.\n- **`PSRAM_SPEED`** (default `166`): one of `84` / `100` / `133` / `166` MHz. Lower is more conservative for noisy boards.\n- **`FLASH_SPEED`** (default `66`): the QSPI flash maximum frequency in MHz.\n- **`HDMI_HSTX`** (default `OFF`): `ON` enables the RP2350 native HSTX HDMI driver with HDMI audio over Data Islands. Requires `BOARD_VARIANT=M2` (HSTX is hard-wired to GPIO 12-19).\n- **`USB_HID=1`** (env var): enable USB HID keyboard host. Disables the USB CDC stdio console; debug output is routed to UART.\n\n### Release Build\n\nBuild all release variants (M1/HDMI, M2/HDMI, M2/HDMI_ALT — all at 504/166/66 with USB_HID=1) at once:\n\n```bash\n./release.sh             # Interactive version prompt\n./release.sh 1.01        # Specify version\n```\n\nThis produces three UF2 files in `release/`:\n\n- `m1p2_hdmi_pio_frank-video_\u003cversion\u003e.uf2` — M1 board, legacy PIO HDMI + I2S audio\n- `m2p2_hdmi_pio_frank-video_\u003cversion\u003e.uf2` — M2 board, legacy PIO HDMI + I2S audio\n- `m2p2_hdmi_hstx_frank-video_\u003cversion\u003e.uf2` — M2 board, HSTX HDMI with HDMI audio (no I2S needed)\n\n### Flashing\n\n```bash\n# With device in BOOTSEL mode:\n./flash.sh\n\n# Or manually:\npicotool load build/frank-video.uf2\n```\n\n## Troubleshooting\n\n### Crashes or HDMI dropouts\n\nLower the PSRAM and flash speeds:\n\n```bash\n./build.sh -DPSRAM_SPEED=100 -DFLASH_SPEED=50\n```\n\nPSRAM at 166 MHz is right at the edge of the SPI margin; a small drop to 100 MHz is usually enough on imperfect boards.\n\n### Audio drifts behind video on long playback\n\nMake sure your `.mpg` was produced by the bundled `tools/convert_video.sh`. The 32 kHz Layer-II encoding is matched to the player's drift-compensation logic; arbitrary MPEG-1 streams (especially those with B-frames or sample rates other than 32/44.1/48 kHz) may not stay in sync.\n\n### Heavy-frame freezes on busy scenes\n\nThe default `-q:v 14` quality target keeps per-frame decode cost bounded. If you tweaked the converter to a lower quantiser (`-q:v 6` or so) and see freezes during high-detail scenes, raise the quantiser back toward 14. The player's IDCT cost scales with the number of non-zero AC coefficients, not bytes per frame.\n\n## License\n\nCopyright (c) 2026 Mikhail Matveev \u003c\u003cxtreme@rh1.tech\u003e\u003e\n\nfrank-video's RP2350 platform layer, drivers, and integration code added by Mikhail Matveev are licensed under the GNU General Public License v3.0 — see [LICENSE](LICENSE) for details.\n\nfrank-video is built on top of [pl_mpeg](https://github.com/phoboslab/pl_mpeg) (MIT) and various Pico-side drivers ported from sister rh1tech projects. The combined work is distributed under GPL-3.0-or-later.\n\n\u003e **Note:** No copyrighted video material is included or redistributed. You must convert your own video files using `tools/convert_video.sh` and copy them to the SD card.\n\n## Acknowledgments\n\nThis project builds on a long chain of open-source work. frank-video is the RP2350 platform port; the MPEG-1 decoder and most of the heavy lifting come from upstream projects.\n\n| Project | Author(s) | License | Used For |\n|---------|-----------|---------|----------|\n| [pl_mpeg](https://github.com/phoboslab/pl_mpeg) | Dominic Szablewski | MIT | MPEG-1 video + audio decoder |\n| [pico-spec](https://github.com/DnCraptor/pico-spec) | DnCraptor | GPL-3.0 | PIO HDMI driver foundation |\n| [pico_hdmi](https://github.com/fliperama86/pico_hdmi) | fliperama86 | Unlicense | HSTX HDMI driver foundation (HDMI_ALT build) |\n| [FatFS](http://elm-chan.org/fsw/ff/) | ChaN | Custom permissive | FAT32 filesystem for SD card |\n| [pico_fatfs_test](https://github.com/elehobica/pico_fatfs_test) | Elehobica | BSD-2-Clause | SD card PIO-SPI driver |\n| [TinyUSB](https://github.com/hathach/tinyusb) | Ha Thach | MIT | USB HID host driver (when `USB_HID=1`) |\n| [Raspberry Pi Pico SDK](https://github.com/raspberrypi/pico-sdk) | Raspberry Pi Foundation | BSD-3-Clause | Hardware abstraction layer |\n\nSpecial thanks to:\n\n- **Dominic Szablewski (phoboslab)** for pl_mpeg, the single-header MPEG-1 decoder that makes this whole project tractable.\n- **fliperama86** for pico_hdmi — the HSTX driver and HDMI Data Island packet code is adapted from that project.\n- **shuichitakano** for the original pico-infones port that inspired the Pico-side audio approach across the rh1tech projects.\n- **ChaN** for FatFS, the lifeblood of every SD-card-using Pico project.\n- **Elehobica** for the PIO-SPI SD card driver.\n- The **Murmulator community** for hardware designs, pinouts, and testing.\n- The **Raspberry Pi Foundation** for the RP2350 and Pico SDK.\n\n## Author\n\nMikhail Matveev \u003c\u003cxtreme@rh1.tech\u003e\u003e\n\n[https://rh1.tech](https://rh1.tech) | [GitHub](https://github.com/rh1tech/frank-video)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frh1tech%2Ffrank-video","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frh1tech%2Ffrank-video","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frh1tech%2Ffrank-video/lists"}