aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlmediaelement.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2017-09-06 13:49:15 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2017-09-06 13:50:56 +0200
commite169acd1d66c61746c0d6fa67d62b925e15940c5 (patch)
tree7bcef51f800635b1b11949630840ae4c4de6fa9a /components/script/dom/htmlmediaelement.rs
parentf5e23a3a903a8142ff8993418142b0554f580c7d (diff)
downloadservo-e169acd1d66c61746c0d6fa67d62b925e15940c5.tar.gz
servo-e169acd1d66c61746c0d6fa67d62b925e15940c5.zip
Put HTMLMediaElement first in its module
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r--components/script/dom/htmlmediaelement.rs348
1 files changed, 174 insertions, 174 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 965599e93c3..526672a5ad8 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -42,180 +42,6 @@ use std::sync::{Arc, Mutex};
use task_source::TaskSource;
use time::{self, Timespec, Duration};
-struct HTMLMediaElementContext {
- /// The element that initiated the request.
- elem: Trusted<HTMLMediaElement>,
- /// The response body received to date.
- data: Vec<u8>,
- /// The response metadata received to date.
- metadata: Option<Metadata>,
- /// The generation of the media element when this fetch started.
- generation_id: u32,
- /// Time of last progress notification.
- next_progress_event: Timespec,
- /// Url of resource requested.
- url: ServoUrl,
- /// Whether the media metadata has been completely received.
- have_metadata: bool,
- /// True if this response is invalid and should be ignored.
- ignore_response: bool,
-}
-
-impl FetchResponseListener for HTMLMediaElementContext {
- fn process_request_body(&mut self) {}
-
- fn process_request_eof(&mut self) {}
-
- // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
- fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
- self.metadata = metadata.ok().map(|m| {
- match m {
- FetchMetadata::Unfiltered(m) => m,
- FetchMetadata::Filtered { unsafe_, .. } => unsafe_
- }
- });
-
- // => "If the media data cannot be fetched at all..."
- let is_failure = self.metadata
- .as_ref()
- .and_then(|m| m.status
- .as_ref()
- .map(|&(s, _)| s < 200 || s >= 300))
- .unwrap_or(false);
- if is_failure {
- // Ensure that the element doesn't receive any further notifications
- // of the aborted fetch. The dedicated failure steps will be executed
- // when response_complete runs.
- self.ignore_response = true;
- }
- }
-
- fn process_response_chunk(&mut self, mut payload: Vec<u8>) {
- if self.ignore_response {
- return;
- }
-
- self.data.append(&mut payload);
-
- let elem = self.elem.root();
-
- // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
- // => "Once enough of the media data has been fetched to determine the duration..."
- if !self.have_metadata {
- self.check_metadata(&elem);
- } else {
- elem.change_ready_state(HAVE_CURRENT_DATA);
- }
-
- // https://html.spec.whatwg.org/multipage/#concept-media-load-resource step 4,
- // => "If mode is remote" step 2
- if time::get_time() > self.next_progress_event {
- let window = window_from_node(&*elem);
- window.dom_manipulation_task_source().queue_simple_event(
- elem.upcast(),
- atom!("progress"),
- &window,
- );
- self.next_progress_event = time::get_time() + Duration::milliseconds(350);
- }
- }
-
- // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
- fn process_response_eof(&mut self, status: Result<(), NetworkError>) {
- let elem = self.elem.root();
-
- // => "If the media data can be fetched but is found by inspection to be in an unsupported
- // format, or can otherwise not be rendered at all"
- if !self.have_metadata {
- elem.queue_dedicated_media_source_failure_steps();
- }
- // => "Once the entire media resource has been fetched..."
- else if status.is_ok() {
- elem.change_ready_state(HAVE_ENOUGH_DATA);
-
- elem.upcast::<EventTarget>().fire_event(atom!("progress"));
-
- elem.network_state.set(NETWORK_IDLE);
-
- elem.upcast::<EventTarget>().fire_event(atom!("suspend"));
- }
- // => "If the connection is interrupted after some media data has been received..."
- else if elem.ready_state.get() != HAVE_NOTHING {
- // Step 2
- elem.error.set(Some(&*MediaError::new(&*window_from_node(&*elem),
- MEDIA_ERR_NETWORK)));
-
- // Step 3
- elem.network_state.set(NETWORK_IDLE);
-
- // TODO: Step 4 - update delay load flag
-
- // Step 5
- elem.upcast::<EventTarget>().fire_event(atom!("error"));
- } else {
- // => "If the media data cannot be fetched at all..."
- elem.queue_dedicated_media_source_failure_steps();
- }
-
- let document = document_from_node(&*elem);
- document.finish_load(LoadType::Media(self.url.clone()));
- }
-}
-
-impl PreInvoke for HTMLMediaElementContext {
- fn should_invoke(&self) -> bool {
- //TODO: finish_load needs to run at some point if the generation changes.
- self.elem.root().generation_id.get() == self.generation_id
- }
-}
-
-impl HTMLMediaElementContext {
- fn new(elem: &HTMLMediaElement, url: ServoUrl) -> HTMLMediaElementContext {
- HTMLMediaElementContext {
- elem: Trusted::new(elem),
- data: vec![],
- metadata: None,
- generation_id: elem.generation_id.get(),
- next_progress_event: time::get_time() + Duration::milliseconds(350),
- url: url,
- have_metadata: false,
- ignore_response: false,
- }
- }
-
- fn check_metadata(&mut self, elem: &HTMLMediaElement) {
- match audio_video_metadata::get_format_from_slice(&self.data) {
- Ok(audio_video_metadata::Metadata::Video(meta)) => {
- let dur = meta.audio.duration.unwrap_or(::std::time::Duration::new(0, 0));
- *elem.video.borrow_mut() = Some(VideoMedia {
- format: format!("{:?}", meta.format),
- duration: Duration::seconds(dur.as_secs() as i64) +
- Duration::nanoseconds(dur.subsec_nanos() as i64),
- width: meta.dimensions.width,
- height: meta.dimensions.height,
- video: meta.video.unwrap_or("".to_owned()),
- audio: meta.audio.audio,
- });
- // Step 6
- elem.change_ready_state(HAVE_METADATA);
- self.have_metadata = true;
- }
- _ => {}
- }
- }
-}
-
-#[derive(HeapSizeOf, JSTraceable)]
-pub struct VideoMedia {
- format: String,
- #[ignore_heap_size_of = "defined in time"]
- duration: Duration,
- width: u32,
- height: u32,
- video: String,
- audio: Option<String>,
-}
-
#[dom_struct]
pub struct HTMLMediaElement {
htmlelement: HTMLElement,
@@ -230,6 +56,17 @@ pub struct HTMLMediaElement {
video: DOMRefCell<Option<VideoMedia>>,
}
+#[derive(HeapSizeOf, JSTraceable)]
+pub struct VideoMedia {
+ format: String,
+ #[ignore_heap_size_of = "defined in time"]
+ duration: Duration,
+ width: u32,
+ height: u32,
+ video: String,
+ audio: Option<String>,
+}
+
impl HTMLMediaElement {
pub fn new_inherited(tag_name: LocalName,
prefix: Option<Prefix>, document: &Document)
@@ -888,3 +725,166 @@ enum Resource {
Object,
Url(ServoUrl),
}
+
+struct HTMLMediaElementContext {
+ /// The element that initiated the request.
+ elem: Trusted<HTMLMediaElement>,
+ /// The response body received to date.
+ data: Vec<u8>,
+ /// The response metadata received to date.
+ metadata: Option<Metadata>,
+ /// The generation of the media element when this fetch started.
+ generation_id: u32,
+ /// Time of last progress notification.
+ next_progress_event: Timespec,
+ /// Url of resource requested.
+ url: ServoUrl,
+ /// Whether the media metadata has been completely received.
+ have_metadata: bool,
+ /// True if this response is invalid and should be ignored.
+ ignore_response: bool,
+}
+
+impl FetchResponseListener for HTMLMediaElementContext {
+ fn process_request_body(&mut self) {}
+
+ fn process_request_eof(&mut self) {}
+
+ // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
+ fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
+ self.metadata = metadata.ok().map(|m| {
+ match m {
+ FetchMetadata::Unfiltered(m) => m,
+ FetchMetadata::Filtered { unsafe_, .. } => unsafe_
+ }
+ });
+
+ // => "If the media data cannot be fetched at all..."
+ let is_failure = self.metadata
+ .as_ref()
+ .and_then(|m| m.status
+ .as_ref()
+ .map(|&(s, _)| s < 200 || s >= 300))
+ .unwrap_or(false);
+ if is_failure {
+ // Ensure that the element doesn't receive any further notifications
+ // of the aborted fetch. The dedicated failure steps will be executed
+ // when response_complete runs.
+ self.ignore_response = true;
+ }
+ }
+
+ fn process_response_chunk(&mut self, mut payload: Vec<u8>) {
+ if self.ignore_response {
+ return;
+ }
+
+ self.data.append(&mut payload);
+
+ let elem = self.elem.root();
+
+ // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
+ // => "Once enough of the media data has been fetched to determine the duration..."
+ if !self.have_metadata {
+ self.check_metadata(&elem);
+ } else {
+ elem.change_ready_state(HAVE_CURRENT_DATA);
+ }
+
+ // https://html.spec.whatwg.org/multipage/#concept-media-load-resource step 4,
+ // => "If mode is remote" step 2
+ if time::get_time() > self.next_progress_event {
+ let window = window_from_node(&*elem);
+ window.dom_manipulation_task_source().queue_simple_event(
+ elem.upcast(),
+ atom!("progress"),
+ &window,
+ );
+ self.next_progress_event = time::get_time() + Duration::milliseconds(350);
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
+ fn process_response_eof(&mut self, status: Result<(), NetworkError>) {
+ let elem = self.elem.root();
+
+ // => "If the media data can be fetched but is found by inspection to be in an unsupported
+ // format, or can otherwise not be rendered at all"
+ if !self.have_metadata {
+ elem.queue_dedicated_media_source_failure_steps();
+ }
+ // => "Once the entire media resource has been fetched..."
+ else if status.is_ok() {
+ elem.change_ready_state(HAVE_ENOUGH_DATA);
+
+ elem.upcast::<EventTarget>().fire_event(atom!("progress"));
+
+ elem.network_state.set(NETWORK_IDLE);
+
+ elem.upcast::<EventTarget>().fire_event(atom!("suspend"));
+ }
+ // => "If the connection is interrupted after some media data has been received..."
+ else if elem.ready_state.get() != HAVE_NOTHING {
+ // Step 2
+ elem.error.set(Some(&*MediaError::new(&*window_from_node(&*elem),
+ MEDIA_ERR_NETWORK)));
+
+ // Step 3
+ elem.network_state.set(NETWORK_IDLE);
+
+ // TODO: Step 4 - update delay load flag
+
+ // Step 5
+ elem.upcast::<EventTarget>().fire_event(atom!("error"));
+ } else {
+ // => "If the media data cannot be fetched at all..."
+ elem.queue_dedicated_media_source_failure_steps();
+ }
+
+ let document = document_from_node(&*elem);
+ document.finish_load(LoadType::Media(self.url.clone()));
+ }
+}
+
+impl PreInvoke for HTMLMediaElementContext {
+ fn should_invoke(&self) -> bool {
+ //TODO: finish_load needs to run at some point if the generation changes.
+ self.elem.root().generation_id.get() == self.generation_id
+ }
+}
+
+impl HTMLMediaElementContext {
+ fn new(elem: &HTMLMediaElement, url: ServoUrl) -> HTMLMediaElementContext {
+ HTMLMediaElementContext {
+ elem: Trusted::new(elem),
+ data: vec![],
+ metadata: None,
+ generation_id: elem.generation_id.get(),
+ next_progress_event: time::get_time() + Duration::milliseconds(350),
+ url: url,
+ have_metadata: false,
+ ignore_response: false,
+ }
+ }
+
+ fn check_metadata(&mut self, elem: &HTMLMediaElement) {
+ match audio_video_metadata::get_format_from_slice(&self.data) {
+ Ok(audio_video_metadata::Metadata::Video(meta)) => {
+ let dur = meta.audio.duration.unwrap_or(::std::time::Duration::new(0, 0));
+ *elem.video.borrow_mut() = Some(VideoMedia {
+ format: format!("{:?}", meta.format),
+ duration: Duration::seconds(dur.as_secs() as i64) +
+ Duration::nanoseconds(dur.subsec_nanos() as i64),
+ width: meta.dimensions.width,
+ height: meta.dimensions.height,
+ video: meta.video.unwrap_or("".to_owned()),
+ audio: meta.audio.audio,
+ });
+ // Step 6
+ elem.change_ready_state(HAVE_METADATA);
+ self.have_metadata = true;
+ }
+ _ => {}
+ }
+ }
+}