Repository navigation
fix(basic): RTSP handshake, EOF, thread lifecycle, SDP parsing, CI (#36–#40) - #41
Conversation
- Define GIT_HASH, GIT_BRANCH, TAG_NAME and TIME before they are used, so the Telegram caption is no longer empty (fixes #39). - Same branch policy as v2: only basic and v2 update the 'latest' release and post to Telegram; other branches upload a workflow artifact. A '/' in a branch name is replaced in the artifact name.
- tcp_stream(): every read is checked for end of stream and throws IOException, so a closed connection triggers a reconnect instead of an endless loop or a NegativeArraySizeException (fixes #36). - The handshake reads responses byte by byte from the same buffered stream that tcp_stream() uses, honours Content-Length for the SDP and checks status codes, so no RTP bytes are lost (fixes #37). - Worker threads exit on a generation counter instead of a shared boolean; flags are volatile and onPause closes the socket, so a quick pause/resume no longer leaves duplicate threads (fixes #38). - Track URLs come from a=control (including '*' and Content-Base), the video codec from a=rtpmap (legacy 96/97 without rtpmap), audio is only set up when present and only L16 is played, with the rate from the SDP. A failed audio SETUP is not fatal. The unused UDP code with fixed ports is removed, and credentials are no longer sent in the request line (fixes #40). - Odd-length L16 payloads no longer throw. Version 1.07.1.
PR Summary by QodoFix basic RTSP streaming, thread lifecycle, and release workflow
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1.
|
- Skip interleaved RTP frames that arrive before an RTSP response. - Publish the socket and set activeStream only for the current generation, under one lock shared with onPause/startListener; a stale thread only clears its own socket. - Pick the first supported payload type from each m= line instead of only the first one listed. - Dispatch packets by interleaved channel: channel 0 is video and channel 2 is audio, even when both use the same payload type. - Resolve root-relative a=control values against scheme://host:port. - Recreate the AudioTrack when a reconnect announces another rate.
Fixes #36, fixes #37, fixes #38, fixes #39, fixes #40.
All changes stay inside the single-file design of
basic. The debug APK is about 34 KB.Changes
read += input.read()hangs forever when the connection closes-1and throwsIOException, so the outer loop reconnectsBufferedReaderswallowed the first RTP packets (SPS/PPS/IDR)BufferedInputStreamthattcp_stream()uses. The SDP is read byContent-Length. Status codes are checked.volatilevolatile;onPausecloses the socket; a stale thread does not reset the state of a newer connectionbasic/v2, as onv2.#40 in detail
a=control, with support for*, absolute URLs and theContent-Baseheader.a=rtpmap, so H.265 on PT 96 works. If there is nortpmap, the old 96/97 convention is kept.SETUPis sent only when the SDP has an audio track, and its failure is not fatal.rtpmap, the old PT 100 and the old rate estimate are kept. PCMU/AAC are no longer played as noise.mTypeflag was never set anywhere, so UDP was dead code (and only port 5000 was ever opened).user:passwordis no longer included in the request line; it is sent only inAuthorization: Basic.Also: an odd-length L16 payload no longer throws.
versionNameis now 1.07.1;versionCodeis unchanged (7), so the new versionCode cannot collide with builds already uploaded to Google Play.Verification
assembleDebugandlintDebuglocally: no new lint warnings.Decoderinstance created bypassing theActivityconstructor): 21/21 pass.Content-Length, and the byte after the response stays in the stream;parseSdp:a=control:*, absolute control, no audio track, H.265 on PT 96, legacy 96/97/100, L16/16000, PCMU not played;tcp_stream: EOF in the body, in the header, and a clean EOF all end inIOException(no hang);