forked from mirrors/gstreamer-rs
pbutils: Add bindings for codec-utils functions
This commit is contained in:
parent
5151b76729
commit
2bb500db0b
3 changed files with 601 additions and 4 deletions
|
@ -83,10 +83,89 @@ status = "generate"
|
||||||
pattern = ".+"
|
pattern = ".+"
|
||||||
ignore = true
|
ignore = true
|
||||||
|
|
||||||
# Codec utils need some special care
|
|
||||||
[[object.function]]
|
[[object.function]]
|
||||||
pattern = "codec_utils.*"
|
pattern = "codec_utils_(aac_caps_set_level_and_profile|h264_caps_set_level_and_profile|h265_caps_set_level_tier_and_profile|mpeg4video_caps_set_level_and_profile)"
|
||||||
ignore = true
|
# Needs mutable caps references and checks for the caps
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_aac_get_level"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get AAC level"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_aac_get_profile"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get AAC profile"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h264_get_level"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get H264 level"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h264_get_profile"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get H264 profile"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h264_get_profile_flags_level"
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h265_get_level"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get H265 level"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h265_get_profile"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get H265 profile"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_h265_get_tier"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get H265 tier"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_mpeg4video_get_level"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get MPEG4 video level"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_mpeg4video_get_profile"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to get MPEG4 video profile"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_caps_get_mime_codec"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Unsupported caps"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_opus_create_caps_from_header"
|
||||||
|
[object.function.return]
|
||||||
|
nullable_return_is_error = "Failed to create caps from Opus headers"
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_opus_create_caps"
|
||||||
|
# Manual checks
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_opus_create_header"
|
||||||
|
# Manual checks
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_opus_parse_caps"
|
||||||
|
# Manual checks
|
||||||
|
manual = true
|
||||||
|
|
||||||
|
[[object.function]]
|
||||||
|
name = "codec_utils_opus_parse_header"
|
||||||
|
# Manual checks
|
||||||
|
manual = true
|
||||||
|
|
||||||
# Plugin installer API needs some manual impls
|
# Plugin installer API needs some manual impls
|
||||||
[[object.function]]
|
[[object.function]]
|
||||||
|
|
|
@ -10,6 +10,203 @@ use crate::PbUtilsCapsDescriptionFlags;
|
||||||
use glib::translate::*;
|
use glib::translate::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
#[cfg(any(feature = "v1_10", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_channels")]
|
||||||
|
pub fn codec_utils_aac_get_channels(audio_config: &[u8]) -> u32 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = audio_config.len() as u32;
|
||||||
|
unsafe { ffi::gst_codec_utils_aac_get_channels(audio_config.to_glib_none().0, len) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_index_from_sample_rate")]
|
||||||
|
pub fn codec_utils_aac_get_index_from_sample_rate(rate: u32) -> i32 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe { ffi::gst_codec_utils_aac_get_index_from_sample_rate(rate) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_level")]
|
||||||
|
pub fn codec_utils_aac_get_level(audio_config: &[u8]) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = audio_config.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_aac_get_level(
|
||||||
|
audio_config.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get AAC level"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_profile")]
|
||||||
|
pub fn codec_utils_aac_get_profile(audio_config: &[u8]) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = audio_config.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_aac_get_profile(
|
||||||
|
audio_config.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get AAC profile"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "v1_10", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_sample_rate")]
|
||||||
|
pub fn codec_utils_aac_get_sample_rate(audio_config: &[u8]) -> u32 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = audio_config.len() as u32;
|
||||||
|
unsafe { ffi::gst_codec_utils_aac_get_sample_rate(audio_config.to_glib_none().0, len) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_get_sample_rate_from_index")]
|
||||||
|
pub fn codec_utils_aac_get_sample_rate_from_index(sr_idx: u32) -> u32 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe { ffi::gst_codec_utils_aac_get_sample_rate_from_index(sr_idx) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
||||||
|
#[doc(alias = "gst_codec_utils_caps_get_mime_codec")]
|
||||||
|
pub fn codec_utils_caps_get_mime_codec(caps: &gst::Caps) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_codec_utils_caps_get_mime_codec(
|
||||||
|
caps.to_glib_none().0,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Unsupported caps"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h264_get_level")]
|
||||||
|
pub fn codec_utils_h264_get_level(sps: &[u8]) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = sps.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_h264_get_level(
|
||||||
|
sps.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get H264 level"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h264_get_level_idc")]
|
||||||
|
pub fn codec_utils_h264_get_level_idc(level: &str) -> u8 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe { ffi::gst_codec_utils_h264_get_level_idc(level.to_glib_none().0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h264_get_profile")]
|
||||||
|
pub fn codec_utils_h264_get_profile(sps: &[u8]) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = sps.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_h264_get_profile(
|
||||||
|
sps.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get H264 profile"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h265_get_level")]
|
||||||
|
pub fn codec_utils_h265_get_level(
|
||||||
|
profile_tier_level: &[u8],
|
||||||
|
) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = profile_tier_level.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_h265_get_level(
|
||||||
|
profile_tier_level.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get H265 level"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h265_get_level_idc")]
|
||||||
|
pub fn codec_utils_h265_get_level_idc(level: &str) -> u8 {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe { ffi::gst_codec_utils_h265_get_level_idc(level.to_glib_none().0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h265_get_profile")]
|
||||||
|
pub fn codec_utils_h265_get_profile(
|
||||||
|
profile_tier_level: &[u8],
|
||||||
|
) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = profile_tier_level.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_h265_get_profile(
|
||||||
|
profile_tier_level.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get H265 profile"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h265_get_tier")]
|
||||||
|
pub fn codec_utils_h265_get_tier(
|
||||||
|
profile_tier_level: &[u8],
|
||||||
|
) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = profile_tier_level.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_h265_get_tier(
|
||||||
|
profile_tier_level.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get H265 tier"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_mpeg4video_get_level")]
|
||||||
|
pub fn codec_utils_mpeg4video_get_level(
|
||||||
|
vis_obj_seq: &[u8],
|
||||||
|
) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = vis_obj_seq.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_mpeg4video_get_level(
|
||||||
|
vis_obj_seq.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get MPEG4 video level"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_mpeg4video_get_profile")]
|
||||||
|
pub fn codec_utils_mpeg4video_get_profile(
|
||||||
|
vis_obj_seq: &[u8],
|
||||||
|
) -> Result<glib::GString, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = vis_obj_seq.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_none(ffi::gst_codec_utils_mpeg4video_get_profile(
|
||||||
|
vis_obj_seq.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to get MPEG4 video profile"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_opus_create_caps_from_header")]
|
||||||
|
pub fn codec_utils_opus_create_caps_from_header(
|
||||||
|
header: &gst::Buffer,
|
||||||
|
comments: Option<&gst::Buffer>,
|
||||||
|
) -> Result<gst::Caps, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
unsafe {
|
||||||
|
Option::<_>::from_glib_full(ffi::gst_codec_utils_opus_create_caps_from_header(
|
||||||
|
header.to_glib_none().0,
|
||||||
|
comments.to_glib_none().0,
|
||||||
|
))
|
||||||
|
.ok_or_else(|| glib::bool_error!("Failed to create caps from Opus headers"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_encoding_list_all_targets")]
|
#[doc(alias = "gst_encoding_list_all_targets")]
|
||||||
pub fn encoding_list_all_targets(categoryname: Option<&str>) -> Vec<EncodingTarget> {
|
pub fn encoding_list_all_targets(categoryname: Option<&str>) -> Vec<EncodingTarget> {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use glib::translate::*;
|
use glib::translate::*;
|
||||||
use std::ptr;
|
use std::{mem, ptr};
|
||||||
|
|
||||||
pub unsafe trait CodecTag<'a>: gst::Tag<'a, TagType = &'a str> {}
|
pub unsafe trait CodecTag<'a>: gst::Tag<'a, TagType = &'a str> {}
|
||||||
|
|
||||||
|
@ -85,3 +85,324 @@ pub fn pb_utils_get_codec_description(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_aac_caps_set_level_and_profile")]
|
||||||
|
pub fn codec_utils_aac_caps_set_level_and_profile(
|
||||||
|
caps: &mut gst::CapsRef,
|
||||||
|
audio_config: &[u8],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert_eq!(caps.size(), 1);
|
||||||
|
|
||||||
|
let s = caps.structure(0).unwrap();
|
||||||
|
assert_eq!(s.name(), "audio/mpeg");
|
||||||
|
assert!(s
|
||||||
|
.get::<i32>("mpegversion")
|
||||||
|
.map_or(false, |v| v == 2 || v == 4));
|
||||||
|
|
||||||
|
let len = audio_config.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_aac_caps_set_level_and_profile(
|
||||||
|
caps.as_mut_ptr(),
|
||||||
|
audio_config.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!("Failed to set AAC level/profile to caps"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h264_caps_set_level_and_profile")]
|
||||||
|
pub fn codec_utils_h264_caps_set_level_and_profile(
|
||||||
|
caps: &mut gst::CapsRef,
|
||||||
|
sps: &[u8],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert_eq!(caps.size(), 1);
|
||||||
|
|
||||||
|
let s = caps.structure(0).unwrap();
|
||||||
|
assert_eq!(s.name(), "video/x-h264");
|
||||||
|
|
||||||
|
let len = sps.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_h264_caps_set_level_and_profile(
|
||||||
|
caps.as_mut_ptr(),
|
||||||
|
sps.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!(
|
||||||
|
"Failed to set H264 level/profile to caps"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
||||||
|
#[doc(alias = "gst_codec_utils_h264_get_profile_flags_level")]
|
||||||
|
pub fn codec_utils_h264_get_profile_flags_level(
|
||||||
|
codec_data: &[u8],
|
||||||
|
) -> Result<(u8, u8, u8), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
let len = codec_data.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
let mut profile = mem::MaybeUninit::uninit();
|
||||||
|
let mut flags = mem::MaybeUninit::uninit();
|
||||||
|
let mut level = mem::MaybeUninit::uninit();
|
||||||
|
glib::result_from_gboolean!(
|
||||||
|
ffi::gst_codec_utils_h264_get_profile_flags_level(
|
||||||
|
codec_data.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
profile.as_mut_ptr(),
|
||||||
|
flags.as_mut_ptr(),
|
||||||
|
level.as_mut_ptr()
|
||||||
|
),
|
||||||
|
"Failed to get H264 profile, flags and level"
|
||||||
|
)?;
|
||||||
|
let profile = profile.assume_init();
|
||||||
|
let flags = flags.assume_init();
|
||||||
|
let level = level.assume_init();
|
||||||
|
Ok((profile, flags, level))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_h265_caps_set_level_tier_and_profile")]
|
||||||
|
pub fn codec_utils_h265_caps_set_level_tier_and_profile(
|
||||||
|
caps: &mut gst::CapsRef,
|
||||||
|
profile_tier_level: &[u8],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert_eq!(caps.size(), 1);
|
||||||
|
|
||||||
|
let s = caps.structure(0).unwrap();
|
||||||
|
assert_eq!(s.name(), "video/x-h265");
|
||||||
|
|
||||||
|
let len = profile_tier_level.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_h265_caps_set_level_tier_and_profile(
|
||||||
|
caps.as_mut_ptr(),
|
||||||
|
profile_tier_level.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!(
|
||||||
|
"Failed to set H265 level/tier/profile to caps"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_mpeg4video_caps_set_level_and_profile")]
|
||||||
|
pub fn codec_utils_mpeg4video_caps_set_level_and_profile(
|
||||||
|
caps: &mut gst::CapsRef,
|
||||||
|
vis_obj_seq: &[u8],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert_eq!(caps.size(), 1);
|
||||||
|
|
||||||
|
let s = caps.structure(0).unwrap();
|
||||||
|
assert_eq!(s.name(), "video/mpeg");
|
||||||
|
assert!(s.get::<i32>("mpegversion").map_or(false, |v| v == 4));
|
||||||
|
|
||||||
|
let len = vis_obj_seq.len() as u32;
|
||||||
|
unsafe {
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_mpeg4video_caps_set_level_and_profile(
|
||||||
|
caps.as_mut_ptr(),
|
||||||
|
vis_obj_seq.to_glib_none().0,
|
||||||
|
len,
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!(
|
||||||
|
"Failed to set MPEG4 video level/profile to caps"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_opus_create_caps")]
|
||||||
|
pub fn codec_utils_opus_create_caps(
|
||||||
|
rate: u32,
|
||||||
|
channels: u8,
|
||||||
|
channel_mapping_family: u8,
|
||||||
|
stream_count: u8,
|
||||||
|
coupled_count: u8,
|
||||||
|
channel_mapping: &[u8],
|
||||||
|
) -> Result<gst::Caps, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert!(channel_mapping.is_empty() || channel_mapping.len() == channels as usize);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let caps = ffi::gst_codec_utils_opus_create_caps(
|
||||||
|
rate,
|
||||||
|
channels,
|
||||||
|
channel_mapping_family,
|
||||||
|
stream_count,
|
||||||
|
coupled_count,
|
||||||
|
if channel_mapping.is_empty() {
|
||||||
|
ptr::null()
|
||||||
|
} else {
|
||||||
|
channel_mapping.to_glib_none().0
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if caps.is_null() {
|
||||||
|
Err(glib::bool_error!(
|
||||||
|
"Failed to create caps from Opus configuration"
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(from_glib_full(caps))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_opus_create_header")]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn codec_utils_opus_create_header(
|
||||||
|
rate: u32,
|
||||||
|
channels: u8,
|
||||||
|
channel_mapping_family: u8,
|
||||||
|
stream_count: u8,
|
||||||
|
coupled_count: u8,
|
||||||
|
channel_mapping: &[u8],
|
||||||
|
pre_skip: u16,
|
||||||
|
output_gain: i16,
|
||||||
|
) -> Result<gst::Buffer, glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
assert!(channel_mapping.is_empty() || channel_mapping.len() == channels as usize);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let header = ffi::gst_codec_utils_opus_create_header(
|
||||||
|
rate,
|
||||||
|
channels,
|
||||||
|
channel_mapping_family,
|
||||||
|
stream_count,
|
||||||
|
coupled_count,
|
||||||
|
if channel_mapping.is_empty() {
|
||||||
|
ptr::null()
|
||||||
|
} else {
|
||||||
|
channel_mapping.to_glib_none().0
|
||||||
|
},
|
||||||
|
pre_skip,
|
||||||
|
output_gain,
|
||||||
|
);
|
||||||
|
|
||||||
|
if header.is_null() {
|
||||||
|
Err(glib::bool_error!(
|
||||||
|
"Failed to create header from Opus configuration"
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(from_glib_full(header))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_opus_parse_caps")]
|
||||||
|
pub fn codec_utils_opus_parse_caps(
|
||||||
|
caps: &gst::Caps,
|
||||||
|
channel_mapping: Option<&mut [u8; 256]>,
|
||||||
|
) -> Result<(u32, u8, u8, u8, u8), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut rate = mem::MaybeUninit::uninit();
|
||||||
|
let mut channels = mem::MaybeUninit::uninit();
|
||||||
|
let mut channel_mapping_family = mem::MaybeUninit::uninit();
|
||||||
|
let mut stream_count = mem::MaybeUninit::uninit();
|
||||||
|
let mut coupled_count = mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_opus_parse_caps(
|
||||||
|
mut_override(caps.as_ptr()),
|
||||||
|
rate.as_mut_ptr(),
|
||||||
|
channels.as_mut_ptr(),
|
||||||
|
channel_mapping_family.as_mut_ptr(),
|
||||||
|
stream_count.as_mut_ptr(),
|
||||||
|
coupled_count.as_mut_ptr(),
|
||||||
|
if let Some(channel_mapping) = channel_mapping {
|
||||||
|
channel_mapping.as_mut_ptr() as *mut [u8; 256]
|
||||||
|
} else {
|
||||||
|
ptr::null_mut()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok((
|
||||||
|
rate.assume_init(),
|
||||||
|
channels.assume_init(),
|
||||||
|
channel_mapping_family.assume_init(),
|
||||||
|
stream_count.assume_init(),
|
||||||
|
coupled_count.assume_init(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!("Failed to parse Opus caps"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_codec_utils_opus_parse_header")]
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
pub fn codec_utils_opus_parse_header(
|
||||||
|
header: &gst::Buffer,
|
||||||
|
channel_mapping: Option<&mut [u8; 256]>,
|
||||||
|
) -> Result<(u32, u8, u8, u8, u8, u16, i16), glib::BoolError> {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut rate = mem::MaybeUninit::uninit();
|
||||||
|
let mut channels = mem::MaybeUninit::uninit();
|
||||||
|
let mut channel_mapping_family = mem::MaybeUninit::uninit();
|
||||||
|
let mut stream_count = mem::MaybeUninit::uninit();
|
||||||
|
let mut coupled_count = mem::MaybeUninit::uninit();
|
||||||
|
let mut pre_skip = mem::MaybeUninit::uninit();
|
||||||
|
let mut output_gain = mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
|
let res: bool = from_glib(ffi::gst_codec_utils_opus_parse_header(
|
||||||
|
mut_override(header.as_ptr()),
|
||||||
|
rate.as_mut_ptr(),
|
||||||
|
channels.as_mut_ptr(),
|
||||||
|
channel_mapping_family.as_mut_ptr(),
|
||||||
|
stream_count.as_mut_ptr(),
|
||||||
|
coupled_count.as_mut_ptr(),
|
||||||
|
if let Some(channel_mapping) = channel_mapping {
|
||||||
|
channel_mapping.as_mut_ptr() as *mut [u8; 256]
|
||||||
|
} else {
|
||||||
|
ptr::null_mut()
|
||||||
|
},
|
||||||
|
pre_skip.as_mut_ptr(),
|
||||||
|
output_gain.as_mut_ptr(),
|
||||||
|
));
|
||||||
|
|
||||||
|
if res {
|
||||||
|
Ok((
|
||||||
|
rate.assume_init(),
|
||||||
|
channels.assume_init(),
|
||||||
|
channel_mapping_family.assume_init(),
|
||||||
|
stream_count.assume_init(),
|
||||||
|
coupled_count.assume_init(),
|
||||||
|
pre_skip.assume_init(),
|
||||||
|
output_gain.assume_init(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Err(glib::bool_error!("Failed to parse Opus header"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue