Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_image_pixels() implementation for video element #24233

Merged
merged 3 commits into from Oct 5, 2019
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

implement get_image_pixels() for video element

  • Loading branch information
ceyusa committed Oct 4, 2019
commit b75d45416220cd69e6d3091f65c70793cb89b2ae
@@ -103,6 +103,7 @@ use servo_media::audio::context::AudioContext;
use servo_media::audio::graph::NodeId;
use servo_media::audio::panner_node::{DistanceModel, PanningModel};
use servo_media::audio::param::ParamType;
use servo_media::player::frame::Frame;
use servo_media::player::Player;
use servo_media::streams::registry::MediaStreamId;
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!(CascadeData);
unsafe_no_jsmanaged_fields!(WindowGLContext);
unsafe_no_jsmanaged_fields!(Frame);

unsafe impl<'a> JSTraceable for &'a str {
#[inline]
@@ -136,6 +136,10 @@ impl FrameHolder {
unreachable!();
}
}

fn get_frame(&self) -> Frame {
self.1.clone()
}
}

pub struct MediaFrameRenderer {
@@ -1857,6 +1861,13 @@ impl HTMLMediaElement {
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]
@@ -23,6 +23,7 @@ use crate::fetch::FetchCanceller;
use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener};
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
use dom_struct::dom_struct;
use euclid::default::Size2D;
use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
@@ -34,6 +35,7 @@ use net_traits::{
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, FetchResponseMsg,
};
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
use servo_media::player::frame::Frame;
use servo_url::ServoUrl;
use std::cell::Cell;
use std::sync::{Arc, Mutex};
@@ -55,6 +57,9 @@ pub struct HTMLVideoElement {
/// Load event blocker. Will block the load event while the poster frame
/// is being fetched.
load_blocker: DomRefCell<Option<LoadBlocker>>,
/// A copy of the last frame
#[ignore_malloc_size_of = "Frame"]
last_frame: DomRefCell<Option<Frame>>,
}

impl HTMLVideoElement {
@@ -70,6 +75,7 @@ impl HTMLVideoElement {
generation_id: Cell::new(0),
poster_frame_canceller: DomRefCell::new(Default::default()),
load_blocker: Default::default(),
last_frame: Default::default(),
}
}

@@ -108,6 +114,27 @@ impl HTMLVideoElement {
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
fn fetch_poster_frame(&self, poster_url: &str) {
// Step 1.
@@ -604,9 +604,14 @@ impl WebGLRenderingContext {
return Ok(None);
}
},
TexImageSource::HTMLVideoElement(_) => {
// TODO: https://github.com/servo/servo/issues/6711
return Ok(None);
TexImageSource::HTMLVideoElement(video) => match video.get_current_frame_data() {
Some((data, size)) => {
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),
},
}))
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.