mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-09 04:32:51 +00:00
LibWeb: Stop the video decoder thread when the video element is GC'd
Otherwise, the thread will continue to run and access the media data buffer, which will have been freed. The test here is a bit strange, but the issue would only consistently repro after several GC runs.
This commit is contained in:
parent
f13ccb9a61
commit
f6407276f7
Notes:
sideshowbarker
2024-07-17 02:22:23 +09:00
Author: https://github.com/trflynn89
Commit: f6407276f7
Pull-request: https://github.com/SerenityOS/serenity/pull/24110
Issue: https://github.com/SerenityOS/serenity/issues/24044
8 changed files with 45 additions and 2 deletions
1
Tests/LibWeb/Text/data/video-gc-frame.html
Normal file
1
Tests/LibWeb/Text/data/video-gc-frame.html
Normal file
|
@ -0,0 +1 @@
|
|||
<video autoplay src="../../../../Base/home/anon/Videos/test-webm.webm"></video>
|
1
Tests/LibWeb/Text/expected/video-gc.txt
Normal file
1
Tests/LibWeb/Text/expected/video-gc.txt
Normal file
|
@ -0,0 +1 @@
|
|||
PASS (didn't crash)
|
25
Tests/LibWeb/Text/input/video-gc.html
Normal file
25
Tests/LibWeb/Text/input/video-gc.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<iframe id=iframe></iframe>
|
||||
<script src="include.js"></script>
|
||||
<script>
|
||||
function navigateIframe(src) {
|
||||
return new Promise(resolve => {
|
||||
iframe.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
iframe.src = src;
|
||||
});
|
||||
}
|
||||
|
||||
asyncTest(async done => {
|
||||
await navigateIframe("../data/video-gc-frame.html");
|
||||
await navigateIframe("../data/iframe-test-content-1.html");
|
||||
iframe.remove();
|
||||
|
||||
for (let i = 0; i < 5; ++i) {
|
||||
internals.gc();
|
||||
}
|
||||
|
||||
println("PASS (didn't crash)");
|
||||
done();
|
||||
});
|
||||
</script>
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
|
||||
#include <LibWeb/HTML/HTMLVideoElement.h>
|
||||
#include <LibWeb/HTML/VideoTrack.h>
|
||||
#include <LibWeb/HTML/VideoTrackList.h>
|
||||
#include <LibWeb/Layout/VideoBox.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/Platform/ImageCodecPlugin.h>
|
||||
|
@ -36,6 +37,14 @@ void HTMLVideoElement::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLVideoElement);
|
||||
}
|
||||
|
||||
void HTMLVideoElement::finalize()
|
||||
{
|
||||
Base::finalize();
|
||||
|
||||
for (auto video_track : video_tracks()->video_tracks())
|
||||
video_track->stop_video({});
|
||||
}
|
||||
|
||||
void HTMLVideoElement::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
|
|
@ -46,6 +46,7 @@ private:
|
|||
HTMLVideoElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void finalize() override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& value) override;
|
||||
|
|
|
@ -98,6 +98,11 @@ void VideoTrack::pause_video(Badge<HTMLVideoElement>)
|
|||
m_playback_manager->pause_playback();
|
||||
}
|
||||
|
||||
void VideoTrack::stop_video(Badge<HTMLVideoElement>)
|
||||
{
|
||||
m_playback_manager->terminate_playback();
|
||||
}
|
||||
|
||||
Duration VideoTrack::position() const
|
||||
{
|
||||
return m_playback_manager->current_playback_time();
|
||||
|
@ -141,7 +146,7 @@ void VideoTrack::set_selected(bool selected)
|
|||
// no longer in a VideoTrackList object, then the track being selected or unselected has no effect beyond changing the value of
|
||||
// the attribute on the VideoTrack object.)
|
||||
if (m_video_track_list) {
|
||||
for (auto video_track : m_video_track_list->video_tracks({})) {
|
||||
for (auto video_track : m_video_track_list->video_tracks()) {
|
||||
if (video_track.ptr() != this)
|
||||
video_track->m_selected = false;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
|
||||
void play_video(Badge<HTMLVideoElement>);
|
||||
void pause_video(Badge<HTMLVideoElement>);
|
||||
void stop_video(Badge<HTMLVideoElement>);
|
||||
|
||||
Duration position() const;
|
||||
Duration duration() const;
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
ErrorOr<void> add_track(Badge<HTMLMediaElement>, JS::NonnullGCPtr<VideoTrack>);
|
||||
void remove_all_tracks(Badge<HTMLMediaElement>);
|
||||
|
||||
Span<JS::NonnullGCPtr<VideoTrack>> video_tracks(Badge<VideoTrack>) { return m_video_tracks; }
|
||||
Span<JS::NonnullGCPtr<VideoTrack>> video_tracks() { return m_video_tracks; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/media.html#dom-videotracklist-length
|
||||
size_t length() const { return m_video_tracks.size(); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue