Skip to content

Commit f57034d

Browse files
committed
feat: adaptive multi-view decoding and a D button for the debug text (#85)
- Every camera stays on screen: cells start on key frames only (IDR/IRAP and parameter sets), then are promoted to full rate in priority order (the audio cell, then slot order) while the estimated load (macroblocks/s) fits the capacity. Promotion waits for the next key frame. Decoder losses (queue overflow, no input buffer) for 3 s demote the lowest-priority full cell and lower the capacity; a load that plays 30 s without losses is proven, and a probe up to 25 % above the capacity is tried. Pausing remains only as a last resort when even key frames are lost. - DecodePlanner holds this logic (pure Java, tested). The capacity starts from the decoder's declared budget (getSupportedFrameRatesFor 1080p) and the learnt value is stored per device (settings 'decoder_capacity'). - Corner text: 'WxH codec key frames · N fps' for key-frame cells. - D in the menu after U turns the debug text on/off (stored). Off: only cells that need attention (not connected, errors, limits, paused, key frames) show text. - READMEs: D in the menu table, adaptive grid and the measured AG-216 budget. - Tests: DecodePlannerTest; CellStatsTest updated (key-frame start, key NAL types).
1 parent d88da73 commit f57034d

10 files changed

Lines changed: 504 additions & 49 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ A beta channel is available on [Google Play](https://play.google.com/apps/intern
6262
| **Q** | Turn multi-view (Quad) on or off |
6363
| **1**–**8** | Switch to a camera slot. The active slot's number shows the connection quality: green under 100 ms of jitter, yellow 100–300 ms, red above 300 ms. A grey number is an empty slot. |
6464
| **U** | Show the reserved UDP cell of the 3×3 grid full-screen |
65+
| **D** | Debug text in every multi-view cell: resolution, codec, decoded/received fps. Off: only cells that need attention show text |
6566
| **Settings** | Edit the URL and the transport of the active slot (single-camera mode only) |
6667
| **WebUI** | Open the camera's web interface; credentials come from the RTSP URL (single-camera mode only) |
6768
| **Exit** | Close the app. The small text next to it is the app version and build hash. |
@@ -88,7 +89,7 @@ adb shell am start -a android.intent.action.SEND -t text/plain \
8889

8990
### Multi-view (Quad)
9091

91-
Shows the configured slots in a 2×2 grid, or in a 3×3 grid once any of slots 5–8 is used. The ninth cell of the 3×3 grid is reserved for a camera that pushes RTP over UDP; for now it only shows the address and port to send to, and **U** in the menu opens it full-screen. To watch such a camera today, put a [`udp://` URL](#udp-slots-majestic-outgoing) into any slot. Each cell has its own connection and decoder, so the device's video decoder limits how many high-resolution streams play smoothly: with five or more cameras, their substreams are a good choice. Some cameras accept only one RTSP client at a time. Long-press a cell to play its audio (long-press it again to mute); the selected cell shows an AUDIO badge and is remembered. Tap any cell to open the menu.
92+
Shows the configured slots in a 2×2 grid, or in a 3×3 grid once any of slots 5–8 is used. The ninth cell of the 3×3 grid is reserved for a camera that pushes RTP over UDP; for now it only shows the address and port to send to, and **U** in the menu opens it full-screen. To watch such a camera today, put a [`udp://` URL](#udp-slots-majestic-outgoing) into any slot. Each cell has its own connection and decoder, and the device's video decoder has a fixed budget: the AG-216 test box, for example, decodes about two 1080p30 streams at full rate. So the grid adapts: cells start on key frames only, then decode every frame in priority order (the cell whose sound plays, then slot order) while the decoder keeps up. Cells beyond that stay on key frames, with the picture updated once per key frame interval and `key frames` in the corner. The limit is learnt on each device by measurement. Substreams of the cameras, where available, let more cells play at full rate. A cell over the decoder's instance limit shows `Decoder limit: N × H.265`. Some cameras accept only one RTSP client at a time. Long-press a cell to play its audio (long-press it again to mute); the selected cell shows an AUDIO badge and is remembered. Tap any cell to open the menu.
9293

9394
## Transports
9495

@@ -226,7 +227,7 @@ Most devices below were reported with the legacy 1.0x version (`basic` branch);
226227
| Tablet | Samsung Tab A7 (SM-T505) | 12 | 4.19.157-perf- | 1.0x | |
227228
| Set-top box | A95X F3 AIR | 9 (SlimBOXtv AOSP 9.14, no GAPPS) | 4.9.113 | 1.0x | |
228229
| Set-top box | IE X3 Air | 9 (SlimBOXtv AOSP 9.14, no GAPPS) | 4.9.113 | 1.0x | |
229-
| Set-top box | AG-216 | 10 | 4.9.170 | v2 1.28 | v2 test device: 8-camera multi-view, H.264/H.265, Opus/AAC/L16 |
230+
| Set-top box | AG-216 | 10 | 4.9.170 | v2 1.28 | v2 test device; decoder budget measured at ≈ 1080p60 in total (two 1080p30 at full rate) |
230231
| Set-top box | SberBox SBDV-00001 | custom | 4.9.228 | 1.0x | |
231232
| Set-top box | X96Q (Allwinner H313) | 10 | 4.9.170 | 1.0x | |
232233
| TV | Haier Candy Android TV 2K | 11 | 4.9.243+ | 1.0x | No icon in the device's app list |

‎README.ru.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
| **Q** | Включить или выключить мультивид (Quad) |
6363
| **1**–**8** | Переключиться на слот камеры. Цвет номера активного слота показывает качество связи: зелёный — джиттер меньше 100 мс, жёлтый — 100–300 мс, красный — больше 300 мс. Серый номер — пустой слот. |
6464
| **U** | Показать на весь экран зарезервированную ячейку UDP сетки 3×3 |
65+
| **D** | Отладочный текст в каждой ячейке мультивида: разрешение, кодек, декодировано/получено кадр/с. Выключено — текст только у ячеек, требующих внимания |
6566
| **Settings** | Изменить адрес и транспорт активного слота (только в режиме одной камеры) |
6667
| **WebUI** | Открыть веб-интерфейс камеры; логин и пароль берутся из RTSP-адреса (только в режиме одной камеры) |
6768
| **Exit** | Закрыть приложение. Мелкий текст рядом — версия приложения и хеш сборки. |
@@ -88,7 +89,7 @@ adb shell am start -a android.intent.action.SEND -t text/plain \
8889

8990
### Мультивид (Quad)
9091

91-
Показывает настроенные слоты сеткой 2×2, а если занят хотя бы один из слотов 5–8 — сеткой 3×3. Девятая ячейка сетки 3×3 зарезервирована под камеру, которая сама отправляет RTP по UDP; пока в ней показаны только адрес и порт, куда слать поток, а кнопка **U** в меню открывает её на весь экран. Чтобы смотреть такую камеру уже сейчас, укажите в любом слоте [адрес `udp://`](#слоты-udp-majestic-outgoing). У каждой ячейки своё подключение и свой декодер, поэтому число плавно идущих потоков высокого разрешения ограничено видеодекодером устройства: для пяти и более камер лучше брать их дополнительные потоки (substream). Некоторые камеры допускают только одно RTSP-подключение одновременно. Долгое нажатие на ячейку включает её звук (повторное — выключает); у выбранной ячейки виден значок AUDIO, выбор запоминается. Коснитесь любой ячейки, чтобы открыть меню.
92+
Показывает настроенные слоты сеткой 2×2, а если занят хотя бы один из слотов 5–8 — сеткой 3×3. Девятая ячейка сетки 3×3 зарезервирована под камеру, которая сама отправляет RTP по UDP; пока в ней показаны только адрес и порт, куда слать поток, а кнопка **U** в меню открывает её на весь экран. Чтобы смотреть такую камеру уже сейчас, укажите в любом слоте [адрес `udp://`](#слоты-udp-majestic-outgoing). У каждой ячейки своё подключение и свой декодер, а у видеодекодера устройства постоянный бюджет: тестовая приставка AG-216, например, декодирует в полном темпе примерно два потока 1080p30. Поэтому сетка подстраивается: ячейки стартуют на ключевых кадрах, затем по приоритету (ячейка со звуком, потом по номеру слота) переходят на все кадры, пока декодер успевает. Остальные остаются на ключевых кадрах — картинка обновляется раз в интервал между ключевыми кадрами, в углу пометка `key frames`. Предел определяется замером на каждом устройстве. Дополнительные потоки камер (substream), если они есть, позволяют показать в полном темпе больше ячеек. Ячейка сверх лимита экземпляров декодера показывает `Decoder limit: N × H.265`. Некоторые камеры допускают только одно RTSP-подключение одновременно. Долгое нажатие на ячейку включает её звук (повторное — выключает); у выбранной ячейки виден значок AUDIO, выбор запоминается. Коснитесь любой ячейки, чтобы открыть меню.
9293

9394
## Транспорты
9495

@@ -226,7 +227,7 @@ export KEY_PASS=your_key_password
226227
| Планшет | Samsung Tab A7 (SM-T505) | 12 | 4.19.157-perf- | 1.0x | |
227228
| ТВ-приставка | A95X F3 AIR | 9 (SlimBOXtv AOSP 9.14, без GAPPS) | 4.9.113 | 1.0x | |
228229
| ТВ-приставка | IE X3 Air | 9 (SlimBOXtv AOSP 9.14, без GAPPS) | 4.9.113 | 1.0x | |
229-
| ТВ-приставка | AG-216 | 10 | 4.9.170 | v2 1.28 | Тестовое устройство v2: мультивид на 8 камер, H.264/H.265, Opus/AAC/L16 |
230+
| ТВ-приставка | AG-216 | 10 | 4.9.170 | v2 1.28 | Тестовое устройство v2; бюджет декодера по замеру ≈ 1080p60 суммарно (два 1080p30 в полном темпе) |
230231
| ТВ-приставка | SberBox SBDV-00001 | своя | 4.9.228 | 1.0x | |
231232
| ТВ-приставка | X96Q (Allwinner H313) | 10 | 4.9.170 | 1.0x | |
232233
| Телевизор | Haier Candy Android TV 2K | 11 | 4.9.243+ | 1.0x | Нет значка в списке приложений |

‎README.zh-CN.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
| **Q** | 开启或关闭多画面模式(Quad) |
6363
| **1**–**8** | 切换摄像机槽位。当前槽位编号的颜色表示连接质量:绿色为抖动低于 100 毫秒,黄色为 100–300 毫秒,红色为高于 300 毫秒。灰色编号表示该槽位未配置。 |
6464
| **U** | 全屏显示 3×3 网格中预留的 UDP 画面 |
65+
| **D** | 在每个多画面格子中显示调试信息:分辨率、编码、已解码/已接收帧率。关闭时仅需关注的格子显示文字 |
6566
| **Settings** | 编辑当前槽位的地址和传输方式(仅单路模式) |
6667
| **WebUI** | 打开摄像机网页界面,用户名和密码取自 RTSP 地址(仅单路模式) |
6768
| **Exit** | 退出应用。旁边的小字是应用版本号和构建哈希。 |
@@ -88,7 +89,7 @@ adb shell am start -a android.intent.action.SEND -t text/plain \
8889

8990
### 多画面模式(Quad)
9091

91-
以 2×2 网格显示已配置的槽位;只要使用了第 5–8 个槽位中的任意一个,就改为 3×3 网格。3×3 网格的第九格预留给通过 UDP 主动推送 RTP 的摄像机;目前其中仅显示推流目标地址和端口,菜单中的 **U** 可将其全屏显示。如需立即观看此类摄像机,请在任意槽位中填写 [`udp://` 地址](#udp-槽位-majestic-outgoing)。每个画面都有独立的连接和解码器,因此能流畅播放多少路高分辨率码流取决于设备的视频解码器:五路及以上时建议使用摄像机的子码流。部分摄像机同一时间只允许一个 RTSP 客户端。长按某个画面即可播放其声音(再次长按则静音);被选中的画面显示 AUDIO 标记,选择会被记住。点击任意画面即可打开菜单。
92+
以 2×2 网格显示已配置的槽位;只要使用了第 5–8 个槽位中的任意一个,就改为 3×3 网格。3×3 网格的第九格预留给通过 UDP 主动推送 RTP 的摄像机;目前其中仅显示推流目标地址和端口,菜单中的 **U** 可将其全屏显示。如需立即观看此类摄像机,请在任意槽位中填写 [`udp://` 地址](#udp-槽位-majestic-outgoing)。每个画面都有独立的连接和解码器,而设备视频解码器的处理能力是固定的:例如测试用的 AG-216 盒子以全帧率大约只能解码两路 1080p30。因此网格会自适应:各画面先只解码关键帧,然后按优先级(正在播放声音的画面,其次按槽位顺序)在解码器跟得上时切换为全帧率。其余画面保持只解码关键帧,画面按关键帧间隔更新,角落显示 `key frames`。上限在每台设备上通过实测确定。如摄像机提供子码流,可让更多画面以全帧率播放。超出解码器实例上限的画面显示 `Decoder limit: N × H.265`。部分摄像机同一时间只允许一个 RTSP 客户端。长按某个画面即可播放其声音(再次长按则静音);被选中的画面显示 AUDIO 标记,选择会被记住。点击任意画面即可打开菜单。
9293

9394
## 传输方式
9495

@@ -226,7 +227,7 @@ export KEY_PASS=your_key_password
226227
| 平板 | Samsung Tab A7 (SM-T505) | 12 | 4.19.157-perf- | 1.0x | |
227228
| 电视盒子 | A95X F3 AIR | 9(SlimBOXtv AOSP 9.14,无 GAPPS) | 4.9.113 | 1.0x | |
228229
| 电视盒子 | IE X3 Air | 9(SlimBOXtv AOSP 9.14,无 GAPPS) | 4.9.113 | 1.0x | |
229-
| 电视盒子 | AG-216 | 10 | 4.9.170 | v2 1.28 | v2 测试设备:8 路多画面,H.264/H.265,Opus/AAC/L16 |
230+
| 电视盒子 | AG-216 | 10 | 4.9.170 | v2 1.28 | v2 测试设备;实测解码能力约为总计 1080p60(全帧率两路 1080p30) |
230231
| 电视盒子 | SberBox SBDV-00001 | 定制系统 | 4.9.228 | 1.0x | |
231232
| 电视盒子 | X96Q(全志 H313) | 10 | 4.9.170 | 1.0x | |
232233
| 电视 | Haier Candy Android TV 2K | 11 | 4.9.243+ | 1.0x | 应用列表中没有图标 |

0 commit comments

Comments
 (0)