Repository navigation
Conversation
PR Summary by QodoFix audio, RTSP, OSD, and configuration reliability
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1. Live video breaks after audio changes
|
|
None of these are regressions from this PR:
|
The capture and encoding threads loop while audioOn is set, but it was only set after both threads had been created. A thread scheduled before that returned at once and audio stayed silent until the next restart.
The decimation step was computed once and kept in a static, so after /api/audio changed the sample rate RTSP G.711 audio was resampled at the old ratio and played at the wrong speed. The Q16 step also overflowed for sample rates of 65536 Hz and above. Compute it per call without overflow.
The PAUSE, RECORD and error responses were a bare status line without CSeq or the empty line ending the headers, so a client that paused kept waiting for the rest of the response. OPTIONS also advertised PAUSE, which is not supported. Send complete responses and drop PAUSE from the Public header.
Interleaved RTP writes retried EAGAIN without limit, so a client that kept its connection open but stopped reading blocked the sending thread and every other client with it. A failed send also aborted delivery to the clients after it in the list. Give up on a client after 2 s without progress and shut its socket down, which ends the session through the normal EOF path, and keep sending to the remaining clients.
A multipart POST to /api/osd without a boundary parameter, without the part header terminator or without the closing boundary dereferenced NULL or wrote with a bogus length, and a failed fopen() was passed to fwrite(). A boundary longer than 127 bytes also overflowed the char length passed to memstr() and read past the request. Any HTTP client could crash the streamer this way. Accept RFC 2046 boundaries only and answer 400 or 500 instead.
An image uploaded to /api/osd was stored as /tmp/osdN.png or .bmp, but the region thread loads osds[N].img and only falls back to /tmp/osdN.bmp when that is empty. PNG uploads were therefore never shown, and neither was any upload to a region that already named an image. Point the region at the stored file.
Decode failures were tested through the buffer pointer instead of the returned error, so a corrupt image was converted from uninitialized memory. Errors raised before the buffers were allocated freed uninitialized pointers, and the decoder context leaked on success.
The canvas leaves room for negative left bearings only, while outlined text is also drawn up to the outline thickness above, below and to either side of each glyph. With an outline set, the first glyph of a line was written in front of the canvas buffer and the last ones past its end, corrupting the heap. Clip every glyph to the canvas.
dirname() ran on the readlink() result before it was NUL-terminated, so it scanned uninitialized stack bytes and could derive the configuration path next to the executable from the wrong directory.
The web whitelist and stream destination lists are read up to an empty entry, and the parser stored up to all four entries before the caller wrote that terminator. A fourth entry therefore put the terminator past the array and its readers went on into the following settings. Parse at most three entries.
/api/audio restarts audio with a new rate, bitrate or enable state, but the MP4 muxer kept describing the old audio track. Reapply the MP4 configuration there and request an IDR so the header is rebuilt, and take mp4Mtx while doing so since the video thread muxes concurrently.
Bug fixes in shared code, found while bringing up the V4L2 backend (#72).
Audio
audioOnis set, but it was set only after both threads had been created. A thread scheduled before that returned at once, and audio stayed silent until the next restart./api/audiochanged the rate, RTSP G.711 was resampled at the old ratio and played at the wrong speed. The step calculation also overflowed at rates of 65536 Hz and above.mp4Mtx, and an IDR is requested so the header is rebuilt.RTSP
EAGAINwithout limit, so one client that stopped reading blocked every other client. A client is now dropped after 2 s without progress. A failed send no longer stops delivery to the clients after it.HTTP / OSD
/api/osdthat has a missing boundary, a missing header terminator or closing boundary, or an over-long boundary. A failedfopen()was also passed tofwrite(). Such requests now get a 400 or 500.Config
dirname()ran on thereadlink()result before it was NUL-terminated.web_whitelistorstream.destpushed the list terminator past the array. Behaviour change: these lists now hold at most three entries, so a fourth one is ignored instead of overflowing.Testing
Built for ARM (musl). On FH8626V100 hardware, with the V4L2 backend on top:
/api/audio?srate=16000, the MP4 audio track reports 16 kHz./api/osd/1appears in the stream.