Repository: servo/servo
File: components/script/dom/html/htmlmediaelement.rs (Rust)

Code before:

        let global = self.global();
        let window = global.as_window();

        // Update the media session metadata title with the obtained metadata.
        window.Navigator().MediaSession().update_title(
            metadata
                .title
                .clone()
                .unwrap_or(window.get_url().into_string()),
        );
    }

    fn playback_video_frame_updated(&self) {
        // Check if the frame was resized
        if let Some(frame) = self.video_renderer.lock().unwrap().current_frame {
            self.handle_resize(Some(frame.width as u32), Some(frame.height as u32));
        }
    }

    fn playback_need_data(&self, can_gc: CanGc) {
        // The player needs more data. If we already have a valid fetch request, we do nothing.
        // Otherwise, if we have no request and the previous request was cancelled because we got an
        // EnoughData event, we restart fetching where we left.
        if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() {
            if let Some(cancel_reason) = current_fetch_context.cancel_reason() {
                // XXX(ferjm) Ideally we should just create a fetch request from
                // where we left. But keeping track of the exact next byte that the
                // media backend expects is not the easiest task, so I'm simply
                // seeking to the current playback position for now which will create
                // a new fetch request for the last rendered frame.
                if *cancel_reason == CancelReason::Backoff {
                    self.seek(self.playback_position.get(), false, can_gc);
                }
                return;
            }

            if let Err(e) = {
                let mut data_source = current_fetch_context.data_source().borrow_mut();
                data_source.set_locked(false);
                data_source.process_into_player_from_queue(self.player.borrow().as_ref().unwrap())
            } {
                // If we are pushing too much data and we know that we can
                // restart the download later from where we left, we cancel
                // the current request. Otherwise, we continue the request
                // assuming that we may drop some frames.
                if e == PlayerError::EnoughData {
                    current_fetch_context.cancel(CancelReason::Backoff);
                }
            }
        }

Review comment (suggestion):
As far as I can see, the changes to this part of the code are not required to solve the original issue, right? If that's true, I would prefer to revert them as well as the changes to make `current_fetch_context` use `#[no_trace]`, because I'm still not confident that that's a good long-term solution.

Code after:
        let global = self.global();
        let window = global.as_window();

        // Update the media session metadata title with the obtained metadata.
        window.Navigator().MediaSession().update_title(
            metadata
                .title
                .clone()
                .unwrap_or(window.get_url().into_string()),
        );
    }

    fn playback_video_frame_updated(&self) {
        // Check if the frame was resized
        if let Some(frame) = self.video_renderer.lock().unwrap().current_frame {
            self.handle_resize(Some(frame.width as u32), Some(frame.height as u32));
        }
    }

    fn playback_need_data(&self, can_gc: CanGc) {
        // The player needs more data.
        // If we already have a valid fetch request, we do nothing.
        // Otherwise, if we have no request and the previous request was
        // cancelled because we got an EnoughData event, we restart
        // fetching where we left.
        if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() {
            if let Some(reason) = current_fetch_context.cancel_reason() {
                // XXX(ferjm) Ideally we should just create a fetch request from
                // where we left. But keeping track of the exact next byte that the
                // media backend expects is not the easiest task, so I'm simply
                // seeking to the current playback position for now which will create
                // a new fetch request for the last rendered frame.
                if *reason == CancelReason::Backoff {
                    self.seek(self.playback_position.get(), false, can_gc);
                }
                return;
            }
        }

        if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() {
            if let Err(e) = {
                let mut data_source = current_fetch_context.data_source().borrow_mut();
                data_source.set_locked(false);
                data_source.process_into_player_from_queue(self.player.borrow().as_ref().unwrap())
            } {
                // If we are pushing too much data and we know that we can
                // restart the download later from where we left, we cancel
                // the current request. Otherwise, we continue the request
                // assuming that we may drop some frames.
                if e == PlayerError::EnoughData {
                    current_fetch_context.cancel(CancelReason::Backoff);