...
 
Commits (26)
......@@ -11,6 +11,7 @@ generate_safety_asserts = true
external_libraries = [
"GLib",
"GObject",
"Gst",
]
generate = [
......@@ -27,6 +28,7 @@ manual = [
"GLib.Error",
"GLib.MainContext",
"GObject.Object",
"Gst.Object",
"Gst.Element",
"GstVideo.VideoMultiviewFlags",
"GstVideo.VideoMultiviewFramePacking",
......
......@@ -12,6 +12,7 @@ external_libraries = [
"GLib",
"GObject",
"Gst",
"GstBase",
]
generate = [
......@@ -29,11 +30,14 @@ generate = [
"GstVideo.VideoFieldOrder",
"GstVideo.VideoFrameFlags",
"GstVideo.VideoMultiviewFramePacking",
"GstVideo.VideoFilter",
]
manual = [
"GObject.Object",
"Gst.Object",
"Gst.Element",
"GstBase.BaseTransform",
"GstVideo.VideoInfo",
"GstVideo.VideoFormatInfo",
"GstVideo.VideoColorimetry",
......
......@@ -46,6 +46,7 @@ On Debian/Ubuntu they can be installed with
```
$ apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav
......
[package]
name = "examples"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
[dependencies]
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
gstreamer-app = { path = "../gstreamer-app" }
gstreamer-audio = { path = "../gstreamer-audio" }
gstreamer-video = { path = "../gstreamer-video" }
gstreamer-player = { path = "../gstreamer-player", optional = true }
gtk = { git = "https://github.com/gtk-rs/gtk", features = ["v3_6"], optional = true }
gdk = { git = "https://github.com/gtk-rs/gdk", optional = true }
gio = { git = "https://github.com/gtk-rs/gio", optional = true }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
gstreamer-app = { version = "0.10", path = "../gstreamer-app" }
gstreamer-audio = { version = "0.10", path = "../gstreamer-audio" }
gstreamer-video = { version = "0.10", path = "../gstreamer-video" }
gstreamer-player = { version = "0.10", path = "../gstreamer-player", optional = true }
gtk = { version = "0.3", features = ["v3_6"], optional = true }
gdk = { version = "0.7", optional = true }
gio = { version = "0.3", optional = true }
futures = { version = "0.1", optional = true }
tokio-core = { version = "0.1", optional = true }
send-cell = "0.1"
......
extern crate gstreamer as gst;
use gst::prelude::*;
extern crate glib;
use std::error::Error as StdError;
extern crate failure;
use failure::Error;
#[macro_use]
extern crate failure_derive;
#[path = "../examples-common.rs"]
mod examples_common;
#[derive(Debug, Fail)]
#[fail(display = "Missing element {}", _0)]
struct MissingElement(String);
#[derive(Debug, Fail)]
#[fail(display = "Received error from {}: {} (debug: {:?})", src, error, debug)]
struct ErrorMessage {
src: String,
error: String,
debug: Option<String>,
#[cause] cause: glib::Error,
}
fn example_main() -> Result<(), Error> {
gst::init()?;
let mut context = gst::ParseContext::new();
let pipeline = match gst::parse_launch_full(
"audiotestsrc wave=white-noise num-buffers=100 ! flacenc ! filesink location=test.flac",
Some(&mut context),
gst::ParseFlags::NONE,
) {
Ok(pipeline) => pipeline,
Err(err) => {
if let Some(gst::ParseError::NoSuchElement) = err.kind::<gst::ParseError>() {
return Err(MissingElement(context.get_missing_elements().join(",")).into());
} else {
return Err(err.into());
}
}
};
let pipeline = pipeline
.downcast::<gst::Pipeline>()
.map_err(|_| failure::err_msg("Generated pipeline is no pipeline"))?;
let tagsetter = pipeline
.get_by_interface(gst::TagSetter::static_type())
.ok_or(failure::err_msg("No TagSetter found"))?;
let tagsetter = tagsetter
.dynamic_cast::<gst::TagSetter>()
.map_err(|_| failure::err_msg("No TagSetter found"))?;
tagsetter.set_tag_merge_mode(gst::TagMergeMode::KeepAll);
tagsetter.add::<gst::tags::Title>(&"Special randomized white-noise", gst::TagMergeMode::Append);
let bus = pipeline.get_bus().unwrap();
pipeline.set_state(gst::State::Playing).into_result()?;
while let Some(msg) = bus.timed_pop(gst::CLOCK_TIME_NONE) {
use gst::MessageView;
match msg.view() {
MessageView::Eos(..) => break,
MessageView::Error(err) => {
Err(ErrorMessage {
src: msg.get_src()
.map(|s| s.get_path_string())
.unwrap_or_else(|| String::from("None")),
error: err.get_error().description().into(),
debug: err.get_debug(),
cause: err.get_error(),
})?;
break;
}
_ => (),
}
}
pipeline.set_state(gst::State::Null).into_result()?;
Ok(())
}
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
match examples_common::run(example_main) {
Ok(r) => r,
Err(e) => eprintln!("Error! {}", e),
}
}
......@@ -15,7 +15,7 @@ use tokio_core::reactor::Core;
#[cfg(feature = "tokio")]
use std::env;
#[allow(unused_imports)]
#[cfg(feature = "tokio")]
#[path = "../examples-common.rs"]
mod examples_common;
......
......@@ -35441,6 +35441,7 @@ on the returned caps to modify it.</doc>
<class name="Stream"
c:symbol-prefix="stream"
c:type="GstStream"
version="1.10"
parent="Object"
glib:type-name="GstStream"
glib:get-type="gst_stream_get_type"
......@@ -36103,6 +36104,7 @@ application of new streaming threads and their status.</doc>
</member>
</enumeration>
<bitfield name="StreamType"
version="1.10"
glib:type-name="GstStreamType"
glib:get-type="gst_stream_type_get_type"
c:type="GstStreamType">
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-app"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer App library"
......@@ -15,14 +15,14 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
libc = "0.2"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-base-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-app-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
gstreamer-base = { path = "../gstreamer-base" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-base-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-app-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
gstreamer-base = { version = "0.10", path = "../gstreamer-base" }
[build-dependencies.rustdoc-stripper]
version = "0.1"
......
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-audio"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Audio library"
......@@ -14,12 +14,12 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-audio-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-audio-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
array-init = "0.0"
[build-dependencies.rustdoc-stripper]
......
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-base"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Base library"
......@@ -8,18 +8,18 @@ repository = "https://github.com/sdroege/gstreamer-rs"
license = "MIT/Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer-base"
documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer_base"
keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"]
build = "build.rs"
[dependencies]
bitflags = "1.0"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-base-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-base-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
[build-dependencies.rustdoc-stripper]
version = "0.1"
......
// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use glib::IsA;
use glib::translate::*;
use gst;
use BaseSink;
pub trait BaseSinkExtManual {
fn get_segment(&self) -> gst::Segment;
}
impl<O: IsA<BaseSink>> BaseSinkExtManual for O {
fn get_segment(&self) -> gst::Segment {
unsafe {
let stash = self.to_glib_none();
let sink: &ffi::GstBaseSink = &*stash.0;
::utils::MutexGuard::lock(&sink.element.object.lock);
from_glib_none(&sink.segment as *const _)
}
}
}
// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use glib::IsA;
use glib::translate::*;
use gst;
use BaseSrc;
pub trait BaseSrcExtManual {
fn get_segment(&self) -> gst::Segment;
}
impl<O: IsA<BaseSrc>> BaseSrcExtManual for O {
fn get_segment(&self) -> gst::Segment {
unsafe {
let stash = self.to_glib_none();
let src: &ffi::GstBaseSrc = &*stash.0;
::utils::MutexGuard::lock(&src.element.object.lock);
from_glib_none(&src.segment as *const _)
}
}
}
// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use glib::IsA;
use glib::translate::*;
use gst;
use BaseTransform;
pub trait BaseTransformExtManual {
fn get_segment(&self) -> gst::Segment;
}
impl<O: IsA<BaseTransform>> BaseTransformExtManual for O {
fn get_segment(&self) -> gst::Segment {
unsafe {
let stash = self.to_glib_none();
let trans: &ffi::GstBaseTransform = &*stash.0;
::utils::MutexGuard::lock(&trans.element.object.lock);
from_glib_none(&trans.segment as *const _)
}
}
}
......@@ -45,6 +45,9 @@ pub use functions::*;
mod adapter;
mod flow_combiner;
pub use flow_combiner::*;
mod base_src;
mod base_sink;
mod base_transform;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts
......@@ -53,4 +56,9 @@ pub mod prelude {
pub use gst::prelude::*;
pub use auto::traits::*;
pub use base_src::BaseSrcExtManual;
pub use base_sink::BaseSinkExtManual;
pub use base_transform::BaseTransformExtManual;
}
mod utils;
// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib::translate::mut_override;
use glib_ffi;
pub struct MutexGuard<'a>(&'a glib_ffi::GMutex);
impl<'a> MutexGuard<'a> {
pub fn lock(mutex: &'a glib_ffi::GMutex) -> Self {
unsafe {
glib_ffi::g_mutex_lock(mut_override(mutex));
}
MutexGuard(mutex)
}
}
impl<'a> Drop for MutexGuard<'a> {
fn drop(&mut self) {
unsafe {
glib_ffi::g_mutex_unlock(mut_override(self.0));
}
}
}
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-net"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Net library"
......@@ -8,17 +8,17 @@ repository = "https://github.com/sdroege/gstreamer-rs"
license = "MIT/Apache-2.0"
readme = "README.md"
homepage = "https://gstreamer.freedesktop.org"
documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer-net"
documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer_net"
keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"]
build = "build.rs"
[dependencies]
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-net-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-net-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
[build-dependencies.rustdoc-stripper]
version = "0.1"
......
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-player"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Player library"
......@@ -15,13 +15,13 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
libc = "0.2"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_12"] }
gstreamer-player-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_12"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer", features = ["v1_12"] }
gstreamer-video = { path = "../gstreamer-video", features = ["v1_12"] }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_12"] }
gstreamer-player-sys = { version = "0.4", features = ["v1_12"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer", features = ["v1_12"] }
gstreamer-video = { version = "0.10", path = "../gstreamer-video", features = ["v1_12"] }
[build-dependencies.rustdoc-stripper]
version = "0.1"
......
......@@ -20,6 +20,7 @@ use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use gst_ffi;
use gst_video;
use libc;
use std::boxed::Box as Box_;
......@@ -28,7 +29,9 @@ use std::mem::transmute;
use std::ptr;
glib_wrapper! {
pub struct Player(Object<ffi::GstPlayer, ffi::GstPlayerClass>);
pub struct Player(Object<ffi::GstPlayer, ffi::GstPlayerClass>): [
gst::Object => gst_ffi::GstObject,
];
match fn {
get_type => || ffi::gst_player_get_type(),
......
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer-video"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer Video library"
......@@ -15,12 +15,14 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
libc = "0.2"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gstreamer-video-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-base-sys = { version = "0.4", features = ["v1_8"] }
gstreamer-video-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
gstreamer = { version = "0.10", path = "../gstreamer" }
gstreamer-base = { version = "0.10", path = "../gstreamer-base" }
[build-dependencies.rustdoc-stripper]
version = "0.1"
......
// This file was generated by gir (d50d839) from gir-files (???)
// DO NOT EDIT
mod video_filter;
pub use self::video_filter::VideoFilter;
mod video_overlay;
pub use self::video_overlay::VideoOverlay;
pub use self::video_overlay::VideoOverlayExt;
......
// This file was generated by gir (d50d839) from gir-files (???)
// DO NOT EDIT
use ffi;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use gst_base;
use gst_base_ffi;
use gst_ffi;
use std::mem;
use std::ptr;
glib_wrapper! {
pub struct VideoFilter(Object<ffi::GstVideoFilter, ffi::GstVideoFilterClass>): [
gst_base::BaseTransform => gst_base_ffi::GstBaseTransform,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject,
];
match fn {
get_type => || ffi::gst_video_filter_get_type(),
}
}
impl VideoFilter {}
unsafe impl Send for VideoFilter {}
unsafe impl Sync for VideoFilter {}
// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use gst_ffi;
use glib_ffi;
use gst;
use glib;
use glib::translate::{from_glib_full, ToGlib, ToGlibPtr};
use std::ptr;
use std::mem;
pub fn convert_sample(
sample: &gst::Sample,
caps: &gst::Caps,
timeout: gst::ClockTime,
) -> Result<gst::Sample, glib::Error> {
unsafe {
let mut error = ptr::null_mut();
let ret = ffi::gst_video_convert_sample(
sample.to_glib_none().0,
caps.to_glib_none().0,
timeout.to_glib(),
&mut error,
);
if error.is_null() {
Ok(from_glib_full(ret))
} else {
Err(from_glib_full(error))
}
}
}
pub fn convert_sample_async<F>(
sample: &gst::Sample,
caps: &gst::Caps,
timeout: gst::ClockTime,
func: F,
) where
F: FnOnce(Result<gst::Sample, glib::Error>) + Send + 'static,
{
unsafe extern "C" fn convert_sample_async_trampoline<F>(
sample: *mut gst_ffi::GstSample,
error: *mut glib_ffi::GError,
user_data: glib_ffi::gpointer,
) where
F: FnOnce(Result<gst::Sample, glib::Error>) + Send + 'static,
{
callback_guard!();
let callback: &mut Option<Box<F>> = mem::transmute(user_data);
let callback = callback.take().unwrap();
if error.is_null() {
callback(Ok(from_glib_full(sample)))
} else {
callback(Err(from_glib_full(error)))
}
}
unsafe extern "C" fn convert_sample_async_free<F>(user_data: glib_ffi::gpointer)
where
F: FnOnce(Result<gst::Sample, glib::Error>) + Send + 'static,
{
callback_guard!();
let _: Box<Option<Box<F>>> = Box::from_raw(user_data as *mut _);
}
unsafe {
let user_data: Box<Option<Box<F>>> = Box::new(Some(Box::new(func)));
ffi::gst_video_convert_sample_async(
sample.to_glib_none().0,
caps.to_glib_none().0,
timeout.to_glib(),
Some(convert_sample_async_trampoline::<F>),
Box::into_raw(user_data) as glib_ffi::gpointer,
Some(convert_sample_async_free::<F>),
);
}
}
#[cfg(test)]
mod tests {
use super::*;
use gst;
use glib;
use std::sync::{Arc, Mutex};
#[test]
fn test_convert_sample_async() {
gst::init().unwrap();
let l = glib::MainLoop::new(None, false);
let mut in_buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap();
{
let buffer = in_buffer.get_mut().unwrap();
let mut data = buffer.map_writable().unwrap();
for p in data.as_mut_slice().chunks_mut(4) {
p[0] = 63;
p[1] = 127;
p[2] = 191;
p[3] = 255;
}
}
let in_caps = ::VideoInfo::new(::VideoFormat::Rgba, 320, 240)
.build()
.unwrap()
.to_caps()
.unwrap();
let sample = gst::Sample::new(
Some(&in_buffer),
Some(&in_caps),
None::<&gst::Segment>,
None,
);
let out_caps = ::VideoInfo::new(::VideoFormat::Abgr, 320, 240)
.build()
.unwrap()
.to_caps()
.unwrap();
let l_clone = l.clone();
let res_store = Arc::new(Mutex::new(None));
let res_store_clone = res_store.clone();
convert_sample_async(&sample, &out_caps, gst::CLOCK_TIME_NONE, move |res| {
*res_store_clone.lock().unwrap() = Some(res);
l_clone.quit();
});
l.run();
let res = res_store.lock().unwrap().take().unwrap();
assert!(res.is_ok(), "Error {}", res.unwrap_err());
let res = res.unwrap();
let converted_out_caps = res.get_caps().unwrap();
assert_eq!(out_caps, converted_out_caps);
let out_buffer = res.get_buffer().unwrap();
{
let data = out_buffer.map_readable().unwrap();
for p in data.as_slice().chunks(4) {
assert_eq!(p, &[255, 191, 127, 63]);
}
}
}
}
......@@ -15,7 +15,9 @@ extern crate glib;
extern crate glib_sys as glib_ffi;
extern crate gobject_sys as gobject_ffi;
extern crate gstreamer as gst;
extern crate gstreamer_base as gst_base;
extern crate gstreamer_sys as gst_ffi;
extern crate gstreamer_base_sys as gst_base_ffi;
extern crate gstreamer_video_sys as ffi;
macro_rules! assert_initialized_main_thread {
......@@ -31,6 +33,12 @@ macro_rules! skip_assert_initialized {
)
}
macro_rules! callback_guard {
() => (
let _guard = ::glib::CallbackGuard::new();
)
}
pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value};
#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
......@@ -46,12 +54,16 @@ mod video_format_info;
pub use video_format_info::*;
mod video_info;
pub use video_info::*;
mod video_frame;
pub use video_frame::VideoFrame;
pub mod video_frame;
pub use video_frame::{VideoFrame, VideoFrameRef};
mod video_overlay;
pub use video_overlay::VideoOverlayExtManual;
mod video_event;
pub use video_event::*;
mod functions;
pub use functions::*;
mod video_rectangle;
pub use video_rectangle::*;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts
......
This diff is collapsed.
// Copyright (C) 2017 Philippe Normand <philn@igalia.com~
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use glib::translate::ToGlib;
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct VideoRectangle {
pub x: i32,
pub y: i32,
pub w: i32,
pub h: i32,
}
impl VideoRectangle {
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
VideoRectangle { x, y, w, h }
}
}
pub fn center_video_rectangle(
src: &VideoRectangle,
dst: &VideoRectangle,
scale: bool,
) -> VideoRectangle {
let mut result = ffi::GstVideoRectangle {
x: 0,
y: 0,
w: 0,
h: 0,
};
let src_rect = ffi::GstVideoRectangle {
x: src.x,
y: src.y,
w: src.w,
h: src.h,
};
let dst_rect = ffi::GstVideoRectangle {
x: dst.x,
y: dst.y,
w: dst.w,
h: dst.h,
};
unsafe {
ffi::gst_video_sink_center_rect(src_rect, dst_rect, &mut result, scale.to_glib());
}
VideoRectangle::new(result.x, result.y, result.w, result.h)
}
......@@ -5,6 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field).
## [0.10.2] - 2018-02-18
### Fixed
- Fix building of messages with custom fields for types that don't have a
GstStructure
### Added
- VideoFrameRef::copy_to_ref() and ::copy_plane_to_ref(), which work with
VideoFrameRefs instead of full VideoFrames
- Getters for the BaseSrc/Sink/Transform configured segment
- Document the gstreamer-player-1.0 dependency in the README.md
## [0.10.1] - 2018-01-03
### Fixed
- Don't require &mut self for TagSetterExtManual::add()
### Added
- A TagSetter example application
- Bindings for gst_video::convert_sample() and ::convert_sample_async()
- Bindings for gst_video::VideoRectangle
- Debug impl for Sample and ::with_buffer_list() constructor
- A borrowing version of VideoFrame: VideoFrameRef
- Bindings for GstVideoFilter
### Changed
- Deprecated Sample::get_info() in favour of ::get_structure()
- Player has gst::Object as another parent class now
## [0.10.0] - 2017-12-22
### Fixed
- Various clippy warnings
......@@ -193,7 +220,8 @@ specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-v
(< 0.8.0) of the bindings can be found [here](https://github.com/arturoc/gstreamer1.0-rs).
The API of the two is incompatible.
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/sdroege/gstreamer-rs/compare/0.10.1...HEAD
[0.10.1]: https://github.com/sdroege/gstreamer-rs/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/sdroege/gstreamer-rs/compare/0.9.1...0.10.0
[0.9.1]: https://github.com/sdroege/gstreamer-rs/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/sdroege/gstreamer-rs/compare/0.8.1...0.9.0
......
[package]
name = "gstreamer"
version = "0.10.0"
version = "0.10.2"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
categories = ["api-bindings", "multimedia"]
description = "Rust bindings for GStreamer"
......@@ -15,10 +15,10 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
libc = "0.2"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/glib" }
glib-sys = "0.5"
gobject-sys = "0.5"
gstreamer-sys = { version = "0.4", features = ["v1_8"] }
glib = "0.4"
num-rational = { version = "0.1.38", default-features = false, features = [] }
lazy_static = "1.0"
futures = { version = "0.1", optional = true }
......
......@@ -775,6 +775,7 @@ impl SetValue for StreamFlags {
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
bitflags! {
pub struct StreamType: u32 {
const UNKNOWN = 1;
......@@ -785,6 +786,7 @@ bitflags! {
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
#[doc(hidden)]
impl ToGlib for StreamType {
type GlibType = ffi::GstStreamType;
......@@ -794,6 +796,7 @@ impl ToGlib for StreamType {
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
#[doc(hidden)]
impl FromGlib<ffi::GstStreamType> for StreamType {
fn from_glib(value: ffi::GstStreamType) -> StreamType {
......@@ -802,24 +805,28 @@ impl FromGlib<ffi::GstStreamType> for StreamType {
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
impl StaticType for StreamType {
fn static_type() -> Type {
unsafe { from_glib(ffi::gst_stream_type_get_type()) }
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
impl<'a> FromValueOptional<'a> for StreamType {
unsafe fn from_value_optional(value: &Value) -> Option<Self> {
Some(FromValue::from_value(value))
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
impl<'a> FromValue<'a> for StreamType {
unsafe fn from_value(value: &Value) -> Self {
from_glib(ffi::GstStreamType::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0)))
}
}
#[cfg(any(feature = "v1_10", feature = "dox"))]
impl SetValue for StreamType {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits())
......
......@@ -162,6 +162,7 @@ pub use self::flags::SegmentFlags;
#[cfg(any(feature = "v1_12", feature = "dox"))]
pub use self::flags::StackTraceFlags;
pub use self::flags::StreamFlags;
#[cfg(any(feature = "v1_10", feature = "dox"))]
pub use self::flags::StreamType;
mod alias;
......
......@@ -895,7 +895,7 @@ macro_rules! event_builder_generic_impl {
ffi::gst_event_set_running_time_offset(event, running_time_offset);
}
{
if !self.other_fields.is_empty() {
let s = StructureRef::from_glib_borrow_mut(
ffi::gst_event_writable_structure(event)
);
......@@ -1667,3 +1667,49 @@ impl<'a> CustomBothOobBuilder<'a> {
ev
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple() {
::init().unwrap();
// Event without arguments
let flush_start_evt = Event::new_flush_start().build();
match flush_start_evt.view() {
EventView::FlushStart(flush_start_evt) => {
assert!(flush_start_evt.0.get_structure().is_none());
},
_ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
}
let flush_start_evt = Event::new_flush_start()
.other_fields(&[("extra-field", &true)])
.build();
match flush_start_evt.view() {
EventView::FlushStart(flush_start_evt) => {
assert!(flush_start_evt.0.get_structure().is_some());
if let Some(other_fields) = flush_start_evt.0.get_structure() {
assert!(other_fields.has_field("extra-field"));
}
},
_ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
}
// Event with arguments
let flush_stop_evt = Event::new_flush_stop(true)
.other_fields(&[("extra-field", &true)])
.build();
match flush_stop_evt.view() {
EventView::FlushStop(flush_stop_evt) => {
assert_eq!(flush_stop_evt.get_reset_time(), true);
assert!(flush_stop_evt.0.get_structure().is_some());
if let Some(other_fields) = flush_stop_evt.0.get_structure() {
assert!(other_fields.has_field("extra-field"));
}
}
_ => panic!("flush_stop_evt.view() is not an EventView::FlushStop(_)"),
}
}
}
......@@ -1165,6 +1165,8 @@ macro_rules! message_builder_generic_impl {
}
}
// Warning: other_fields are ignored with argument-less messages
// until GStreamer 1.14 is released
pub fn other_fields(self, other_fields: &[(&'a str, &'a ToSendValue)]) -> Self {
Self {
other_fields: self.other_fields.iter().cloned()
......@@ -1183,13 +1185,19 @@ macro_rules! message_builder_generic_impl {
ffi::gst_message_set_seqnum(msg, seqnum.to_glib());
}
{
let s = StructureRef::from_glib_borrow_mut(
ffi::gst_message_get_structure(msg) as *mut _
);
for (k, v) in self.other_fields {
s.set_value(k, v.to_send_value());
if !self.other_fields.is_empty() {
// issue with argument-less messages. We need the function
// ffi::gst_message_writable_structure to sort this out
// and this function will be available in GStreamer 1.14
// See https://github.com/sdroege/gstreamer-rs/pull/75
// and https://bugzilla.gnome.org/show_bug.cgi?id=792928
let structure = ffi::gst_message_get_structure(msg);
if !structure.is_null() {
let structure = StructureRef::from_glib_borrow_mut(structure as *mut _);
for (k, v) in self.other_fields {
structure.set_value(k, v.to_send_value());
}
}
}
......@@ -2442,3 +2450,37 @@ impl<'a> RedirectBuilder<'a> {
msg
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple() {
::init().unwrap();
// Message without arguments
let eos_msg = Message::new_eos().build();
match eos_msg.view() {
MessageView::Eos(eos_msg) => {
assert!(eos_msg.0.get_structure().is_none());
},
_ => panic!("eos_msg.view() is not a MessageView::Eos(_)"),
}
// Note: can't define other_fields for argument-less messages before GStreamer 1.14
// Message with arguments
let buffering_msg = Message::new_buffering(42)
.other_fields(&[("extra-field", &true)])
.build();
match buffering_msg.view() {
MessageView::Buffering(buffering_msg) => {
assert_eq!(buffering_msg.get_percent(), 42);
assert!(buffering_msg.0.get_structure().is_some());
assert!(buffering_msg.0.get_structure().unwrap().has_field("extra-field"));
}
_ => panic!("buffering_msg.view() is not a MessageView::Buffering(_)"),
}
}
}
......@@ -7,6 +7,7 @@
// except according to those terms.
use std::ptr;
use std::fmt;
use ffi;
......@@ -49,6 +50,20 @@ impl GstRc<SampleRef> {
))
}
}
pub fn with_buffer_list<F: FormattedValue>(
buffer_list: Option<&BufferList>,
caps: Option<&Caps>,
segment: Option<&FormattedSegment<F>>,
info: Option<&StructureRef>,
) -> Self {
assert_initialized_main_thread!();
let sample = Self::new(None, caps, segment, info);
unsafe {
ffi::gst_sample_set_buffer_list(sample.to_glib_none().0, buffer_list.to_glib_none().0);
}
sample
}
}
impl SampleRef {
......@@ -68,7 +83,7 @@ impl SampleRef {
unsafe { from_glib_none(ffi::gst_sample_get_segment(self.as_mut_ptr())) }
}
pub fn get_structure(&self) -> Option<&StructureRef> {
pub fn get_info(&self) -> Option<&StructureRef> {
unsafe {
let ptr = ffi::gst_sample_get_info(self.as_mut_ptr());
if ptr.is_null() {
......@@ -78,6 +93,11 @@ impl SampleRef {
}
}
}
#[deprecated(since = "0.10.1", note = "please use `get_info` instead")]
pub fn get_structure(&self) -> Option<&StructureRef> {
self.get_info()
}
}
impl StaticType for SampleRef {
......@@ -97,5 +117,16 @@ impl ToOwned for SampleRef {
}
}
impl fmt::Debug for SampleRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Sample")
.field("buffer", &self.get_buffer())
.field("caps", &self.get_caps())
.field("segment", &self.get_segment())
.field("info", &self.get_info())
.finish()
}
}
unsafe impl Sync for SampleRef {}
unsafe impl Send for SampleRef {}
......@@ -15,13 +15,13 @@ use glib::value: