Skip to content

Commit 6e864ed

Browse files
author
bors-servo
authored
Auto merge of #303 - ceyusa:external-oes-texture, r=ferjm
Handling external OES textures Fix #291
2 parents 131007e + 6b7dee2 commit 6e864ed

File tree

8 files changed

+69
-130
lines changed

8 files changed

+69
-130
lines changed

Cargo.lock

Lines changed: 0 additions & 96 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backends/gstreamer/player.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ impl GStreamerPlayer {
598598
let frame = render
599599
.lock()
600600
.unwrap()
601-
.get_frame_from_sample(&sample)
601+
.get_frame_from_sample(sample)
602602
.or_else(|_| Err(gst::FlowError::Error))?;
603603
renderer.lock().unwrap().render(frame);
604604
notify!(observer, PlayerEvent::FrameUpdated);

backends/gstreamer/render-unix/lib.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! Internally it uses GStreamer's *glsinkbin* element as *videosink*
66
//! wrapping the *appsink* from the Player. And the shared frames are
7-
//! mapped as texuture IDs.
7+
//! mapped as texture IDs.
88
99
#![cfg(any(
1010
target_os = "linux",
@@ -31,6 +31,7 @@ use sm_player::PlayerError;
3131
use std::sync::{Arc, Mutex};
3232

3333
struct GStreamerBuffer {
34+
is_external_oes: bool,
3435
frame: gst_video::VideoFrame<gst_video::video_frame::Readable>,
3536
}
3637

@@ -39,7 +40,11 @@ impl Buffer for GStreamerBuffer {
3940
// packed formats are guaranteed to be in a single plane
4041
if self.frame.format() == gst_video::VideoFormat::Rgba {
4142
let tex_id = self.frame.get_texture_id(0).ok_or_else(|| ())?;
42-
Ok(FrameData::Texture(tex_id))
43+
Ok(if self.is_external_oes {
44+
FrameData::OESTexture(tex_id)
45+
} else {
46+
FrameData::Texture(tex_id)
47+
})
4348
} else {
4449
Err(())
4550
}
@@ -170,7 +175,7 @@ impl Render for RenderUnix {
170175
true
171176
}
172177

173-
fn build_frame(&self, buffer: gst::Buffer, info: gst_video::VideoInfo) -> Result<Frame, ()> {
178+
fn build_frame(&self, sample: gst::Sample) -> Result<Frame, ()> {
174179
if self.gst_context.lock().unwrap().is_none() && self.gl_upload.lock().unwrap().is_some() {
175180
*self.gst_context.lock().unwrap() =
176181
if let Some(glupload) = self.gl_upload.lock().unwrap().as_ref() {
@@ -183,13 +188,33 @@ impl Render for RenderUnix {
183188
};
184189
}
185190

191+
let buffer = sample.get_buffer_owned().ok_or_else(|| ())?;
192+
let caps = sample.get_caps().ok_or_else(|| ())?;
193+
194+
let is_external_oes = caps
195+
.get_structure(0)
196+
.and_then(|s| {
197+
s.get::<&str>("texture-target").and_then(|target| {
198+
if target == "external-oes" {
199+
Some(s)
200+
} else {
201+
None
202+
}
203+
})
204+
})
205+
.is_some();
206+
207+
let info = gst_video::VideoInfo::from_caps(caps).ok_or_else(|| ())?;
186208
let frame =
187209
gst_video::VideoFrame::from_buffer_readable_gl(buffer, &info).or_else(|_| Err(()))?;
188210

189211
Frame::new(
190212
info.width() as i32,
191213
info.height() as i32,
192-
Arc::new(GStreamerBuffer { frame }),
214+
Arc::new(GStreamerBuffer {
215+
is_external_oes,
216+
frame,
217+
}),
193218
)
194219
}
195220

@@ -210,7 +235,7 @@ impl Render for RenderUnix {
210235
let caps = gst::Caps::builder("video/x-raw")
211236
.features(&[&gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY])
212237
.field("format", &gst_video::VideoFormat::Rgba.to_string())
213-
.field("texture-target", &"2D")
238+
.field("texture-target", &gst::List::new(&[&"2D", &"external-oes"]))
214239
.build();
215240
appsink
216241
.set_property("caps", &caps)

backends/gstreamer/render.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ mod platform {
5353
false
5454
}
5555

56-
fn build_frame(&self, _: gst::Buffer, _: gst_video::VideoInfo) -> Result<Frame, ()> {
56+
fn build_frame(&self, _: gst::Sample) -> Result<Frame, ()> {
5757
Err(())
5858
}
5959

@@ -95,14 +95,14 @@ impl GStreamerRender {
9595
}
9696
}
9797

98-
pub fn get_frame_from_sample(&self, sample: &gst::Sample) -> Result<Frame, ()> {
99-
let buffer = sample.get_buffer_owned().ok_or_else(|| ())?;
100-
let caps = sample.get_caps().ok_or_else(|| ())?;
101-
let info = gst_video::VideoInfo::from_caps(caps).ok_or_else(|| ())?;
102-
98+
pub fn get_frame_from_sample(&self, sample: gst::Sample) -> Result<Frame, ()> {
10399
if let Some(render) = self.render.as_ref() {
104-
render.build_frame(buffer, info)
100+
render.build_frame(sample)
105101
} else {
102+
let buffer = sample.get_buffer_owned().ok_or_else(|| ())?;
103+
let caps = sample.get_caps().ok_or_else(|| ())?;
104+
let info = gst_video::VideoInfo::from_caps(caps).ok_or_else(|| ())?;
105+
106106
let frame =
107107
gst_video::VideoFrame::from_buffer_readable(buffer, &info).or_else(|_| Err(()))?;
108108

backends/gstreamer/render/lib.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,15 @@ pub trait Render {
2424

2525
/// Returns the Player's `Frame` to be consumed by the API user.
2626
///
27-
/// The implementator of this method will map the `buffer`,
28-
/// according the `info`, to the rendering appropiate
29-
/// structure. In the case of OpenGL-based renders, the `Frame`,
30-
/// instead of the raw data, will transfer the texture ID.
27+
/// The implementator of this method will map the `sample`'s
28+
/// buffer to the rendering appropiate structure. In the case of
29+
/// OpenGL-based renders, the `Frame`, instead of the raw data,
30+
/// will transfer the texture ID.
3131
///
3232
/// # Arguments
3333
///
34-
/// * `buffer` - the GStreamer buffer to map
35-
/// * `info` - buffer's video information
36-
fn build_frame(
37-
&self,
38-
buffer: gst::Buffer,
39-
info: gst_video::VideoInfo,
40-
) -> Result<sm_player::frame::Frame, ()>;
34+
/// * `sample` - the GStreamer sample with the buffer to map
35+
fn build_frame(&self, sample: gst::Sample) -> Result<sm_player::frame::Frame, ()>;
4136

4237
/// Sets the proper *video-sink* to GStreamer's `pipeline`, this
4338
/// video sink is simply a decorator of the passed `appsink`.

examples/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ euclid = { version = "0.19.0", optional = true }
88
failure = { version = "0.1", optional = true }
99
failure_derive = { version = "0.1", optional = true }
1010
gleam = { version = "0.6.8", optional = true }
11-
hyper = { version = "0.12", optional = true }
1211
rand = { version = "0.5.0", optional = true }
1312
time = { version = "0.1.40", optional = true }
1413
serde = {version = "1.0", optional = true }
@@ -29,7 +28,7 @@ clap = { version = "2.33", default-features = false, optional = true }
2928

3029
[features]
3130
default = []
32-
gui = [ "winit", "glutin", "clap", "webrender", "webrender_api" ]
31+
gui = [ "euclid", "clap", "failure", "failure_derive", "gleam", "glutin", "webrender", "webrender_api", "winit" ]
3332
player = [ "ipc-channel" ]
3433
noise = [ "rand" ]
3534
webrtc = [ "serde", "serde_derive", "serde_json" ]

0 commit comments

Comments
 (0)