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

Code before:
        *self.player.borrow_mut() = None;
        self.video_renderer.lock().unwrap().reset();
        self.handle_resize(None, None);
    }

    pub(crate) fn set_audio_track(&self, idx: usize, enabled: bool) {
        if let Some(ref player) = *self.player.borrow() {
            if let Err(err) = player.lock().unwrap().set_audio_track(idx as i32, enabled) {
                warn!("Could not set audio track {:#?}", err);
            }
        }
    }

    pub(crate) fn set_video_track(&self, idx: usize, enabled: bool) {
        if let Some(ref player) = *self.player.borrow() {
            if let Err(err) = player.lock().unwrap().set_video_track(idx as i32, enabled) {
                warn!("Could not set video track {:#?}", err);
            }
        }
    }

    /// <https://html.spec.whatwg.org/multipage/#direction-of-playback>
    fn direction_of_playback(&self) -> PlaybackDirection {
        if self.playbackRate.get() >= 0. {
            PlaybackDirection::Forwards
        } else {
            PlaybackDirection::Backwards
        }
    }

    /// <https://html.spec.whatwg.org/multipage/#ended-playback>
    fn ended_playback(&self) -> bool {
        if self.ready_state.get() < ReadyState::HaveMetadata {
            return false;
        }

        let playback_position = self.playback_position.get();

        match self.direction_of_playback() {
            PlaybackDirection::Forwards => playback_position >= self.Duration() && !self.Loop(),
            PlaybackDirection::Backwards => playback_position <= self.earliest_possible_position(),
        }
    }

    /// <https://html.spec.whatwg.org/multipage/#reaches-the-end>
    fn end_of_playback_in_forwards_direction(&self) {
        // Step 1. If the media element has a loop attribute specified, then seek to the earliest
        // posible position of the media resource and return.
        if self.Loop() {
            self.seek(
                self.earliest_possible_position(),

Review comment (suggestion):
```suggestion
        // If the element's playbackRate is positive or zero, then the direction of playback is forwards. Otherwise, it is backwards.
        if self.playbackRate.get() >= 0. {
```

Code after:
        *self.player.borrow_mut() = None;
        self.video_renderer.lock().unwrap().reset();
        self.handle_resize(None, None);
    }

    pub(crate) fn set_audio_track(&self, idx: usize, enabled: bool) {
        if let Some(ref player) = *self.player.borrow() {
            if let Err(err) = player.lock().unwrap().set_audio_track(idx as i32, enabled) {
                warn!("Could not set audio track {:#?}", err);
            }
        }
    }

    pub(crate) fn set_video_track(&self, idx: usize, enabled: bool) {
        if let Some(ref player) = *self.player.borrow() {
            if let Err(err) = player.lock().unwrap().set_video_track(idx as i32, enabled) {
                warn!("Could not set video track {:#?}", err);
            }
        }
    }

    /// <https://html.spec.whatwg.org/multipage/#direction-of-playback>
    fn direction_of_playback(&self) -> PlaybackDirection {
        // If the element's playbackRate is positive or zero, then the direction of playback is
        // forwards. Otherwise, it is backwards.
        if self.playbackRate.get() >= 0. {
            PlaybackDirection::Forwards
        } else {
            PlaybackDirection::Backwards
        }
    }

    /// <https://html.spec.whatwg.org/multipage/#ended-playback>
    fn ended_playback(&self) -> bool {
        // A media element is said to have ended playback when:

        // The element's readyState attribute is HAVE_METADATA or greater, and
        if self.ready_state.get() < ReadyState::HaveMetadata {
            return false;
        }

        let playback_position = self.playback_position.get();

        match self.direction_of_playback() {
            // Either: The current playback position is the end of the media resource, and the
            // direction of playback is forwards, and the media element does not have a loop
            // attribute specified.
            PlaybackDirection::Forwards => playback_position >= self.Duration() && !self.Loop(),
            // Or: The current playback position is the earliest possible position, and the
            // direction of playback is backwards.
            PlaybackDirection::Backwards => playback_position <= self.earliest_possible_position(),