mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
implement get_image_pixels() for video element
This commit is contained in:
parent
bc07154e05
commit
b75d454162
4 changed files with 48 additions and 3 deletions
|
@ -103,6 +103,7 @@ use servo_media::audio::context::AudioContext;
|
||||||
use servo_media::audio::graph::NodeId;
|
use servo_media::audio::graph::NodeId;
|
||||||
use servo_media::audio::panner_node::{DistanceModel, PanningModel};
|
use servo_media::audio::panner_node::{DistanceModel, PanningModel};
|
||||||
use servo_media::audio::param::ParamType;
|
use servo_media::audio::param::ParamType;
|
||||||
|
use servo_media::player::frame::Frame;
|
||||||
use servo_media::player::Player;
|
use servo_media::player::Player;
|
||||||
use servo_media::streams::registry::MediaStreamId;
|
use servo_media::streams::registry::MediaStreamId;
|
||||||
use servo_media::streams::MediaStreamType;
|
use servo_media::streams::MediaStreamType;
|
||||||
|
@ -516,6 +517,7 @@ unsafe_no_jsmanaged_fields!(Point2D<f32>, Rect<Au>);
|
||||||
unsafe_no_jsmanaged_fields!(Rect<f32>);
|
unsafe_no_jsmanaged_fields!(Rect<f32>);
|
||||||
unsafe_no_jsmanaged_fields!(CascadeData);
|
unsafe_no_jsmanaged_fields!(CascadeData);
|
||||||
unsafe_no_jsmanaged_fields!(WindowGLContext);
|
unsafe_no_jsmanaged_fields!(WindowGLContext);
|
||||||
|
unsafe_no_jsmanaged_fields!(Frame);
|
||||||
|
|
||||||
unsafe impl<'a> JSTraceable for &'a str {
|
unsafe impl<'a> JSTraceable for &'a str {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -136,6 +136,10 @@ impl FrameHolder {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_frame(&self) -> Frame {
|
||||||
|
self.1.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MediaFrameRenderer {
|
pub struct MediaFrameRenderer {
|
||||||
|
@ -1857,6 +1861,13 @@ impl HTMLMediaElement {
|
||||||
document_from_node(self).unregister_media_controls(&id);
|
document_from_node(self).unregister_media_controls(&id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_current_frame(&self) -> Option<Frame> {
|
||||||
|
match self.frame_renderer.lock().unwrap().current_frame_holder {
|
||||||
|
Some(ref holder) => Some(holder.get_frame()),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Placeholder for [https://github.com/servo/servo/issues/22293]
|
// XXX Placeholder for [https://github.com/servo/servo/issues/22293]
|
||||||
|
|
|
@ -23,6 +23,7 @@ use crate::fetch::FetchCanceller;
|
||||||
use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener};
|
use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener};
|
||||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use euclid::default::Size2D;
|
||||||
use html5ever::{LocalName, Prefix};
|
use html5ever::{LocalName, Prefix};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
|
@ -34,6 +35,7 @@ use net_traits::{
|
||||||
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, FetchResponseMsg,
|
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, FetchResponseMsg,
|
||||||
};
|
};
|
||||||
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
|
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
|
||||||
|
use servo_media::player::frame::Frame;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -55,6 +57,9 @@ pub struct HTMLVideoElement {
|
||||||
/// Load event blocker. Will block the load event while the poster frame
|
/// Load event blocker. Will block the load event while the poster frame
|
||||||
/// is being fetched.
|
/// is being fetched.
|
||||||
load_blocker: DomRefCell<Option<LoadBlocker>>,
|
load_blocker: DomRefCell<Option<LoadBlocker>>,
|
||||||
|
/// A copy of the last frame
|
||||||
|
#[ignore_malloc_size_of = "Frame"]
|
||||||
|
last_frame: DomRefCell<Option<Frame>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLVideoElement {
|
impl HTMLVideoElement {
|
||||||
|
@ -70,6 +75,7 @@ impl HTMLVideoElement {
|
||||||
generation_id: Cell::new(0),
|
generation_id: Cell::new(0),
|
||||||
poster_frame_canceller: DomRefCell::new(Default::default()),
|
poster_frame_canceller: DomRefCell::new(Default::default()),
|
||||||
load_blocker: Default::default(),
|
load_blocker: Default::default(),
|
||||||
|
last_frame: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +114,27 @@ impl HTMLVideoElement {
|
||||||
LoadBlocker::terminate(&mut *self.load_blocker.borrow_mut());
|
LoadBlocker::terminate(&mut *self.load_blocker.borrow_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_current_frame_data(&self) -> Option<(Option<ipc::IpcSharedMemory>, Size2D<u32>)> {
|
||||||
|
let frame = self.htmlmediaelement.get_current_frame();
|
||||||
|
if frame.is_some() {
|
||||||
|
*self.last_frame.borrow_mut() = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.last_frame.borrow().as_ref() {
|
||||||
|
Some(frame) => {
|
||||||
|
let size = Size2D::new(frame.get_width() as u32, frame.get_height() as u32);
|
||||||
|
if !frame.is_gl_texture() {
|
||||||
|
let data = Some(ipc::IpcSharedMemory::from_bytes(&frame.get_data()));
|
||||||
|
Some((data, size))
|
||||||
|
} else {
|
||||||
|
// XXX(victor): here we only have the GL texture ID.
|
||||||
|
Some((None, size))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#poster-frame
|
/// https://html.spec.whatwg.org/multipage/#poster-frame
|
||||||
fn fetch_poster_frame(&self, poster_url: &str) {
|
fn fetch_poster_frame(&self, poster_url: &str) {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
|
|
|
@ -604,9 +604,14 @@ impl WebGLRenderingContext {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TexImageSource::HTMLVideoElement(_) => {
|
TexImageSource::HTMLVideoElement(video) => match video.get_current_frame_data() {
|
||||||
// TODO: https://github.com/servo/servo/issues/6711
|
Some((data, size)) => {
|
||||||
return Ok(None);
|
let data = data.unwrap_or_else(|| {
|
||||||
|
IpcSharedMemory::from_bytes(&vec![0; size.area() as usize * 4])
|
||||||
|
});
|
||||||
|
TexPixels::new(data, size, PixelFormat::BGRA8, false)
|
||||||
|
},
|
||||||
|
None => return Ok(None),
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue