-
Notifications
You must be signed in to change notification settings - Fork 7
VPLAY-12164 Http 404 for mpd while channel change #845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev_sprint_25_2
Are you sure you want to change the base?
Changes from all commits
2d6fffc
4d6be34
62d4beb
42b9a38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5238,6 +5238,15 @@ void PrivateInstanceAAMP::TeardownStream(bool newTune, bool disableDownloads) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ReleaseStreamLock(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if(disableDownloads) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // stop the mpd update immediately after Stream abstraction delete | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // stop the mpd update immediately after Stream abstraction delete | |
| /* | |
| * DASH-specific teardown: explicitly stop MPD updates as soon as the | |
| * stream abstraction has been stopped/deleted. | |
| * | |
| * Rationale: | |
| * - When changing channels, the MPD downloader may still be running | |
| * background manifest refreshes based on the old stream abstraction | |
| * state (periods, adaptation sets, timelines, etc.). | |
| * - If the service reuses the same MPD URL for the new channel or if | |
| * the old MPD becomes invalid while those refreshes are still in | |
| * flight, the downloader can issue requests that no longer match | |
| * the server state, leading to transient HTTP 404s during channel | |
| * changes (as described in the PR). | |
| * | |
| * By releasing the MPD downloader here, immediately after | |
| * mpStreamAbstractionAAMP is torn down and only when downloads are | |
| * being disabled, we ensure that no further MPD refreshes are issued | |
| * based on stale stream state. | |
| * | |
| * Note: | |
| * - There is also a later mMPDDownloaderInstance->Release() call in | |
| * Stop() (line 8107) which serves as a final safety net / global | |
| * cleanup. | |
| * - This earlier Release() in TeardownStream is the intentional, | |
| * protocol-aware shutdown point required to avoid the 404 bursts | |
| * seen on rapid channel changes; the Stop()-level call must not be | |
| * treated as a replacement for this one. | |
| */ |
sayanurag marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this call be removed from other places since it is done here? I.e. from PrivateInstanceAAMP::detach() and PrivateInstanceAAMP::Stop()
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new code block accesses mMPDDownloaderInstance without holding mLock. While this appears consistent with similar patterns elsewhere in the codebase (e.g., Stop() at line 8091 and detach() at line 7110), consider whether explicit locking is needed here for thread safety. The Release() method has internal locking via mMPDDnldMutex, but the pointer access itself is not synchronized. If mMPDDownloaderInstance can be deleted or modified from another thread during teardown, this could lead to a race condition.
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| AampMPDDownloader *mpdDownloader = NULL; | |
| lock.lock(); | |
| mpdDownloader = mMPDDownloaderInstance; | |
| lock.unlock(); | |
| if(mpdDownloader != NULL) | |
| { | |
| mpdDownloader->Release(); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change introduces a potential double-call to mMPDDownloaderInstance->Release(). When TeardownStream(true, true) is called from Stop() (line 8088), this new code will call Release(), and then Stop() calls it again at line 8091-8094. While Release() is idempotent (protected by the mReleaseCalled flag), consider whether the duplicate call in Stop() should be removed to avoid confusion and make the cleanup flow clearer.
| if(disableDownloads) | |
| { | |
| // stop the mpd update immediately after Stream abstraction delete | |
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| } | |
| } | |
| // Note: MPD downloader Release() is handled by the caller (e.g. Stop()) | |
| // to avoid duplicate Release() calls when TeardownStream(true, true) is | |
| // invoked from Stop(). |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code uses a raw pointer (mMPDDownloaderInstance) with manual lifecycle management (new at line 5628, SAFE_DELETE at line 8199). Consider refactoring to use a smart pointer (e.g., std::unique_ptr) to follow modern C++ RAII principles and improve memory safety. This would make ownership semantics clearer and eliminate the possibility of memory leaks.
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new code path (calling mMPDDownloaderInstance->Release() inside TeardownStream when disableDownloads is true) lacks test coverage.
The existing TeardownStream tests in test/utests/tests/PrivAampTests/PrivAampTests.cpp (TeardownStreamTest, TeardownStreamTest_1, TeardownStreamTest_2) do not verify:
- That Release() is called when disableDownloads=true
- That Release() is NOT called when disableDownloads=false
- The interaction with mMPDDownloaderInstance being null vs non-null
Add test cases to verify this behavior, especially for the scenario described in the ticket (channel change causing HTTP 404 errors).
Copilot
AI
Jan 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change introduces a potential duplicate Release() call when TeardownStream is invoked from the Stop() function. At line 8102, Stop() calls TeardownStream(true, true) with disableDownloads=true, which will trigger this new Release() call. Then at line 8107, Stop() calls mMPDDownloaderInstance->Release() again.
While Release() is idempotent (protected by the mReleaseCalled flag), this duplication suggests a design issue. Consider one of the following solutions:
- Remove the Release() call at line 8107 in Stop() since it's now handled in TeardownStream
- Remove this new code and keep the existing Release() call in Stop() at line 8107
- Add a clear comment explaining why Release() is called in both locations if both are truly needed
The PR description mentions "Moving the Teardown operation before the mpd update release cause some delay" which suggests option 1 (removing the call from Stop()) may be the intended solution.
| if(disableDownloads) | |
| { | |
| // stop the mpd update immediately after Stream abstraction delete | |
| if(mMPDDownloaderInstance != nullptr) | |
| { | |
| mMPDDownloaderInstance->Release(); | |
| } | |
| } |
Uh oh!
There was an error while loading. Please reload this page.