gstreamer-pbutils: Update manual code to 2018 edition

This commit is contained in:
Sebastian Dröge 2020-11-22 12:10:54 +02:00
parent 34656810ad
commit 0c17f32eee
7 changed files with 72 additions and 118 deletions

View file

@ -11,16 +11,14 @@ homepage = "https://gstreamer.freedesktop.org"
documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/gstreamer_pbutils/" documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/gstreamer_pbutils/"
keywords = ["gstreamer", "multimedia", "audio", "pbutils", "gnome"] keywords = ["gstreamer", "multimedia", "audio", "pbutils", "gnome"]
build = "build.rs" build = "build.rs"
edition = "2018"
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "1.0"
libc = "0.2" libc = "0.2"
glib-sys = { git = "https://github.com/gtk-rs/gtk-rs" } ffi = { package = "gstreamer-pbutils-sys", path = "../gstreamer-pbutils/sys", features = ["v1_8"] }
gobject-sys = { git = "https://github.com/gtk-rs/gtk-rs" }
gstreamer-sys = { path = "../gstreamer/sys", features = ["v1_8"] }
gstreamer-pbutils-sys = { path = "../gstreamer-pbutils/sys", features = ["v1_8"] }
glib = { git = "https://github.com/gtk-rs/gtk-rs" } glib = { git = "https://github.com/gtk-rs/gtk-rs" }
gstreamer = { path = "../gstreamer" } gst = { package = "gstreamer", path = "../gstreamer" }
thiserror = "1.0" thiserror = "1.0"
[build-dependencies] [build-dependencies]
@ -28,14 +26,14 @@ gstreamer-rs-lgpl-docs = { path = "../docs", optional = true }
[features] [features]
default = [] default = []
v1_10 = ["gstreamer/v1_10", "gstreamer-pbutils-sys/v1_10"] v1_10 = ["gst/v1_10", "ffi/v1_10"]
v1_12 = ["gstreamer/v1_12", "gstreamer-pbutils-sys/v1_12", "v1_10"] v1_12 = ["gst/v1_12", "ffi/v1_12", "v1_10"]
v1_14 = ["gstreamer/v1_14", "gstreamer-pbutils-sys/v1_14", "v1_12"] v1_14 = ["gst/v1_14", "ffi/v1_14", "v1_12"]
v1_16 = ["gstreamer/v1_16", "gstreamer-pbutils-sys/v1_16", "v1_14"] v1_16 = ["gst/v1_16", "ffi/v1_16", "v1_14"]
v1_18 = ["gstreamer/v1_18", "gstreamer-pbutils-sys/v1_18", "v1_16"] v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
embed-lgpl-docs = ["gstreamer-rs-lgpl-docs"] embed-lgpl-docs = ["gstreamer-rs-lgpl-docs"]
purge-lgpl-docs = ["gstreamer-rs-lgpl-docs"] purge-lgpl-docs = ["gstreamer-rs-lgpl-docs"]
dox = ["v1_18", "gstreamer-pbutils-sys/dox", "glib/dox", "gstreamer/dox"] dox = ["v1_18", "ffi/dox", "glib/dox", "gst/dox"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["dox", "embed-lgpl-docs"] features = ["dox", "embed-lgpl-docs"]

View file

@ -7,9 +7,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use gst; use crate::auto::Discoverer;
use auto::Discoverer;
use glib::object::{Cast, ObjectType}; use glib::object::{Cast, ObjectType};
use glib::signal::connect_raw; use glib::signal::connect_raw;
@ -18,17 +16,13 @@ use glib::translate::*;
use glib::IsA; use glib::IsA;
use glib::Value; use glib::Value;
use glib_sys;
use gobject_sys;
use gst_pbutils_sys;
use std::boxed::Box as Box_; use std::boxed::Box as Box_;
use std::mem::transmute; use std::mem::transmute;
impl Discoverer { impl Discoverer {
pub fn set_property_timeout(&self, timeout: gst::ClockTime) { pub fn set_property_timeout(&self, timeout: gst::ClockTime) {
unsafe { unsafe {
gobject_sys::g_object_set_property( glib::gobject_ffi::g_object_set_property(
self.as_ptr() as *mut _, self.as_ptr() as *mut _,
"timeout".to_glib_none().0, "timeout".to_glib_none().0,
Value::from(&timeout).to_glib_none().0, Value::from(&timeout).to_glib_none().0,
@ -39,7 +33,7 @@ impl Discoverer {
pub fn get_property_timeout(&self) -> gst::ClockTime { pub fn get_property_timeout(&self) -> gst::ClockTime {
let mut value = Value::from(&0u64); let mut value = Value::from(&0u64);
unsafe { unsafe {
gobject_sys::g_object_get_property( glib::gobject_ffi::g_object_get_property(
self.as_ptr() as *mut _, self.as_ptr() as *mut _,
"timeout".to_glib_none().0, "timeout".to_glib_none().0,
value.to_glib_none_mut().0, value.to_glib_none_mut().0,
@ -70,9 +64,9 @@ impl Discoverer {
} }
unsafe extern "C" fn notify_timeout_trampoline<P, F: Fn(&P) + Send + Sync + 'static>( unsafe extern "C" fn notify_timeout_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
this: *mut gst_pbutils_sys::GstDiscoverer, this: *mut ffi::GstDiscoverer,
_param_spec: glib_sys::gpointer, _param_spec: glib::ffi::gpointer,
f: glib_sys::gpointer, f: glib::ffi::gpointer,
) where ) where
P: IsA<Discoverer>, P: IsA<Discoverer>,
{ {

View file

@ -7,8 +7,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use DiscovererStreamInfo; use crate::DiscovererStreamInfo;
use DiscovererStreamInfoExt; use crate::DiscovererStreamInfoExt;
#[derive(Debug)] #[derive(Debug)]
pub struct Iter { pub struct Iter {

View file

@ -7,21 +7,16 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use DiscovererVideoInfo; use crate::DiscovererVideoInfo;
use glib::translate::*; use glib::translate::*;
use gst;
use gst_pbutils_sys;
impl DiscovererVideoInfo { impl DiscovererVideoInfo {
pub fn get_framerate(&self) -> gst::Fraction { pub fn get_framerate(&self) -> gst::Fraction {
unsafe { unsafe {
gst::Fraction::new( gst::Fraction::new(
gst_pbutils_sys::gst_discoverer_video_info_get_framerate_num(self.to_glib_none().0) ffi::gst_discoverer_video_info_get_framerate_num(self.to_glib_none().0) as i32,
as i32, ffi::gst_discoverer_video_info_get_framerate_denom(self.to_glib_none().0) as i32,
gst_pbutils_sys::gst_discoverer_video_info_get_framerate_denom(
self.to_glib_none().0,
) as i32,
) )
} }
} }
@ -29,10 +24,8 @@ impl DiscovererVideoInfo {
pub fn get_par(&self) -> gst::Fraction { pub fn get_par(&self) -> gst::Fraction {
unsafe { unsafe {
gst::Fraction::new( gst::Fraction::new(
gst_pbutils_sys::gst_discoverer_video_info_get_par_num(self.to_glib_none().0) ffi::gst_discoverer_video_info_get_par_num(self.to_glib_none().0) as i32,
as i32, ffi::gst_discoverer_video_info_get_par_denom(self.to_glib_none().0) as i32,
gst_pbutils_sys::gst_discoverer_video_info_get_par_denom(self.to_glib_none().0)
as i32,
) )
} }
} }

View file

@ -7,20 +7,15 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use glib;
use gst;
use gst_pbutils_sys;
use gst_sys;
use thiserror::Error; use thiserror::Error;
use glib::object::IsA; use glib::object::IsA;
use glib::translate::*; use glib::translate::*;
use auto::EncodingAudioProfile; use crate::auto::EncodingAudioProfile;
use auto::EncodingContainerProfile; use crate::auto::EncodingContainerProfile;
use auto::EncodingProfile; use crate::auto::EncodingProfile;
use auto::EncodingVideoProfile; use crate::auto::EncodingVideoProfile;
trait EncodingProfileBuilderCommon { trait EncodingProfileBuilderCommon {
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool); fn set_allow_dynamic_output(&self, allow_dynamic_output: bool);
@ -43,7 +38,7 @@ trait EncodingProfileBuilderCommon {
impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O { impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) { fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_allow_dynamic_output( ffi::gst_encoding_profile_set_allow_dynamic_output(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
allow_dynamic_output.to_glib(), allow_dynamic_output.to_glib(),
); );
@ -53,7 +48,7 @@ impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
fn set_description(&self, description: Option<&str>) { fn set_description(&self, description: Option<&str>) {
let description = description.to_glib_none(); let description = description.to_glib_none();
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_description( ffi::gst_encoding_profile_set_description(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
description.0, description.0,
); );
@ -62,7 +57,7 @@ impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
fn set_enabled(&self, enabled: bool) { fn set_enabled(&self, enabled: bool) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_enabled( ffi::gst_encoding_profile_set_enabled(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
enabled.to_glib(), enabled.to_glib(),
); );
@ -71,7 +66,7 @@ impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
fn set_format(&self, format: &gst::Caps) { fn set_format(&self, format: &gst::Caps) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_format( ffi::gst_encoding_profile_set_format(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
format.to_glib_none().0, format.to_glib_none().0,
); );
@ -81,33 +76,27 @@ impl<O: IsA<EncodingProfile>> EncodingProfileBuilderCommon for O {
fn set_name(&self, name: Option<&str>) { fn set_name(&self, name: Option<&str>) {
let name = name.to_glib_none(); let name = name.to_glib_none();
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_name(self.as_ref().to_glib_none().0, name.0); ffi::gst_encoding_profile_set_name(self.as_ref().to_glib_none().0, name.0);
} }
} }
fn set_presence(&self, presence: u32) { fn set_presence(&self, presence: u32) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_presence( ffi::gst_encoding_profile_set_presence(self.as_ref().to_glib_none().0, presence);
self.as_ref().to_glib_none().0,
presence,
);
} }
} }
fn set_preset(&self, preset: Option<&str>) { fn set_preset(&self, preset: Option<&str>) {
let preset = preset.to_glib_none(); let preset = preset.to_glib_none();
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_preset( ffi::gst_encoding_profile_set_preset(self.as_ref().to_glib_none().0, preset.0);
self.as_ref().to_glib_none().0,
preset.0,
);
} }
} }
fn set_preset_name(&self, preset_name: Option<&str>) { fn set_preset_name(&self, preset_name: Option<&str>) {
let preset_name = preset_name.to_glib_none(); let preset_name = preset_name.to_glib_none();
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_profile_set_preset_name( ffi::gst_encoding_profile_set_preset_name(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
preset_name.0, preset_name.0,
); );
@ -133,10 +122,10 @@ macro_rules! declare_encoding_profile_has_restriction(
unsafe { unsafe {
let restriction = match restriction { let restriction = match restriction {
Some(restriction) => restriction.to_glib_full(), Some(restriction) => restriction.to_glib_full(),
None => gst_sys::gst_caps_new_any(), None => gst::ffi::gst_caps_new_any(),
}; };
gst_pbutils_sys::gst_encoding_profile_set_restriction( ffi::gst_encoding_profile_set_restriction(
profile.to_glib_none().0, profile.to_glib_none().0,
restriction, restriction,
); );
@ -149,7 +138,7 @@ macro_rules! declare_encoding_profile_has_restriction(
let profile: &EncodingProfile = glib::object::Cast::upcast_ref(self); let profile: &EncodingProfile = glib::object::Cast::upcast_ref(self);
unsafe { unsafe {
from_glib_full(gst_pbutils_sys::gst_encoding_profile_get_restriction( from_glib_full(ffi::gst_encoding_profile_get_restriction(
profile.to_glib_none().0, profile.to_glib_none().0,
)) ))
} }
@ -169,7 +158,7 @@ impl EncodingAudioProfile {
let preset = preset.to_glib_none(); let preset = preset.to_glib_none();
let restriction = restriction.to_glib_none(); let restriction = restriction.to_glib_none();
unsafe { unsafe {
from_glib_full(gst_pbutils_sys::gst_encoding_audio_profile_new( from_glib_full(ffi::gst_encoding_audio_profile_new(
format.to_glib_none().0, format.to_glib_none().0,
preset.0, preset.0,
restriction.0, restriction.0,
@ -192,7 +181,7 @@ impl EncodingVideoProfile {
let preset = preset.to_glib_none(); let preset = preset.to_glib_none();
let restriction = restriction.to_glib_none(); let restriction = restriction.to_glib_none();
unsafe { unsafe {
from_glib_full(gst_pbutils_sys::gst_encoding_video_profile_new( from_glib_full(ffi::gst_encoding_video_profile_new(
format.to_glib_none().0, format.to_glib_none().0,
preset.0, preset.0,
restriction.0, restriction.0,
@ -203,13 +192,13 @@ impl EncodingVideoProfile {
fn set_pass(&self, pass: u32) { fn set_pass(&self, pass: u32) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_video_profile_set_pass(self.to_glib_none().0, pass); ffi::gst_encoding_video_profile_set_pass(self.to_glib_none().0, pass);
} }
} }
fn set_variableframerate(&self, variableframerate: bool) { fn set_variableframerate(&self, variableframerate: bool) {
unsafe { unsafe {
gst_pbutils_sys::gst_encoding_video_profile_set_variableframerate( ffi::gst_encoding_video_profile_set_variableframerate(
self.to_glib_none().0, self.to_glib_none().0,
variableframerate.to_glib(), variableframerate.to_glib(),
); );
@ -231,7 +220,7 @@ impl EncodingContainerProfile {
let description = description.to_glib_none(); let description = description.to_glib_none();
let preset = preset.to_glib_none(); let preset = preset.to_glib_none();
unsafe { unsafe {
from_glib_full(gst_pbutils_sys::gst_encoding_container_profile_new( from_glib_full(ffi::gst_encoding_container_profile_new(
name.0, name.0,
description.0, description.0,
format.to_glib_none().0, format.to_glib_none().0,
@ -245,8 +234,8 @@ impl EncodingContainerProfile {
profile: &P, profile: &P,
) -> Result<(), glib::error::BoolError> { ) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
glib_result_from_gboolean!( glib::glib_result_from_gboolean!(
gst_pbutils_sys::gst_encoding_container_profile_add_profile( ffi::gst_encoding_container_profile_add_profile(
self.to_glib_none().0, self.to_glib_none().0,
profile.as_ref().to_glib_full(), profile.as_ref().to_glib_full(),
), ),
@ -504,10 +493,9 @@ impl<'a> EncodingContainerProfileBuilder<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use auto::EncodingContainerProfile; use crate::auto::EncodingContainerProfile;
use auto::EncodingProfileExt; use crate::auto::EncodingProfileExt;
use auto::EncodingVideoProfile; use crate::auto::EncodingVideoProfile;
use gst;
const AUDIO_PROFILE_NAME: &str = "audio-profile"; const AUDIO_PROFILE_NAME: &str = "audio-profile";
const AUDIO_PROFILE_DESCRIPTION: &str = "audio-profile-description"; const AUDIO_PROFILE_DESCRIPTION: &str = "audio-profile-description";

View file

@ -6,10 +6,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use glib;
use glib::translate::*; use glib::translate::*;
use gst;
use gst_pbutils_sys;
use std::ptr; use std::ptr;
pub unsafe trait CodecTag<'a>: gst::Tag<'a, TagType = &'a str> {} pub unsafe trait CodecTag<'a>: gst::Tag<'a, TagType = &'a str> {}
@ -27,8 +24,8 @@ pub fn pb_utils_add_codec_description_to_tag_list_for_tag<'a, T: CodecTag<'a>>(
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let codec_tag = T::tag_name(); let codec_tag = T::tag_name();
unsafe { unsafe {
glib_result_from_gboolean!( glib::glib_result_from_gboolean!(
gst_pbutils_sys::gst_pb_utils_add_codec_description_to_tag_list( ffi::gst_pb_utils_add_codec_description_to_tag_list(
taglist.as_mut_ptr(), taglist.as_mut_ptr(),
codec_tag.to_glib_none().0, codec_tag.to_glib_none().0,
caps.as_ptr(), caps.as_ptr(),
@ -44,8 +41,8 @@ pub fn pb_utils_add_codec_description_to_tag_list(
) -> Result<(), glib::BoolError> { ) -> Result<(), glib::BoolError> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
unsafe { unsafe {
glib_result_from_gboolean!( glib::glib_result_from_gboolean!(
gst_pbutils_sys::gst_pb_utils_add_codec_description_to_tag_list( ffi::gst_pb_utils_add_codec_description_to_tag_list(
taglist.as_mut_ptr(), taglist.as_mut_ptr(),
ptr::null_mut(), ptr::null_mut(),
caps.as_ptr(), caps.as_ptr(),
@ -60,11 +57,9 @@ pub fn pb_utils_get_encoder_description(
) -> Result<glib::GString, glib::error::BoolError> { ) -> Result<glib::GString, glib::error::BoolError> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
unsafe { unsafe {
match from_glib_full(gst_pbutils_sys::gst_pb_utils_get_encoder_description( match from_glib_full(ffi::gst_pb_utils_get_encoder_description(caps.as_ptr())) {
caps.as_ptr(),
)) {
Some(s) => Ok(s), Some(s) => Ok(s),
None => Err(glib_bool_error!("Failed to get encoder description")), None => Err(glib::glib_bool_error!("Failed to get encoder description")),
} }
} }
} }
@ -74,11 +69,9 @@ pub fn pb_utils_get_decoder_description(
) -> Result<glib::GString, glib::error::BoolError> { ) -> Result<glib::GString, glib::error::BoolError> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
unsafe { unsafe {
match from_glib_full(gst_pbutils_sys::gst_pb_utils_get_decoder_description( match from_glib_full(ffi::gst_pb_utils_get_decoder_description(caps.as_ptr())) {
caps.as_ptr(),
)) {
Some(s) => Ok(s), Some(s) => Ok(s),
None => Err(glib_bool_error!("Failed to get decoder description")), None => Err(glib::glib_bool_error!("Failed to get decoder description")),
} }
} }
} }
@ -88,11 +81,9 @@ pub fn pb_utils_get_codec_description(
) -> Result<glib::GString, glib::error::BoolError> { ) -> Result<glib::GString, glib::error::BoolError> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
unsafe { unsafe {
match from_glib_full(gst_pbutils_sys::gst_pb_utils_get_codec_description( match from_glib_full(ffi::gst_pb_utils_get_codec_description(caps.as_ptr())) {
caps.as_ptr(),
)) {
Some(s) => Ok(s), Some(s) => Ok(s),
None => Err(glib_bool_error!("Failed to get codec description")), None => Err(glib::glib_bool_error!("Failed to get codec description")),
} }
} }
} }

View file

@ -8,31 +8,19 @@
#![cfg_attr(feature = "dox", feature(doc_cfg))] #![cfg_attr(feature = "dox", feature(doc_cfg))]
#[macro_use] pub use ffi;
extern crate bitflags;
extern crate libc;
use std::sync::Once; use std::sync::Once;
#[macro_use]
extern crate glib;
extern crate glib_sys;
extern crate gobject_sys;
extern crate gstreamer as gst;
extern crate gstreamer_pbutils_sys as gst_pbutils_sys;
extern crate gstreamer_sys as gst_sys;
extern crate thiserror;
static PBUTILS_INIT: Once = Once::new(); static PBUTILS_INIT: Once = Once::new();
macro_rules! assert_initialized_main_thread { macro_rules! assert_initialized_main_thread {
() => { () => {
if unsafe { ::gst_sys::gst_is_initialized() } != ::glib_sys::GTRUE { if unsafe { gst::ffi::gst_is_initialized() } != glib::ffi::GTRUE {
panic!("GStreamer has not been initialized. Call `gst::init` first."); panic!("GStreamer has not been initialized. Call `gst::init` first.");
} }
::PBUTILS_INIT.call_once(|| { crate::PBUTILS_INIT.call_once(|| {
unsafe { ::gst_pbutils_sys::gst_pb_utils_init() }; unsafe { ffi::gst_pb_utils_init() };
}); });
}; };
} }
@ -47,22 +35,22 @@ macro_rules! skip_assert_initialized {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
#[allow(unused_imports)] #[allow(unused_imports)]
mod auto; mod auto;
pub use auto::functions::*; pub use crate::auto::functions::*;
pub use auto::*; pub use crate::auto::*;
mod discoverer; mod discoverer;
pub use discoverer::*; pub use crate::discoverer::*;
pub mod discoverer_stream_info; pub mod discoverer_stream_info;
mod discoverer_video_info; mod discoverer_video_info;
pub use discoverer_video_info::*; pub use crate::discoverer_video_info::*;
mod encoding_profile; mod encoding_profile;
pub use encoding_profile::*; pub use crate::encoding_profile::*;
pub mod functions; pub mod functions;
pub use functions::*; pub use crate::functions::*;
// Re-export all the traits in a prelude module, so that applications // Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts // can always "use gst::prelude::*" without getting conflicts
@ -70,8 +58,10 @@ pub mod prelude {
pub use glib::prelude::*; pub use glib::prelude::*;
pub use gst::prelude::*; pub use gst::prelude::*;
pub use auto::traits::*; pub use crate::auto::traits::*;
pub use encoding_profile::{EncodingProfileBuilder, EncodingProfileHasRestrictionGetter}; pub use crate::encoding_profile::{
EncodingProfileBuilder, EncodingProfileHasRestrictionGetter,
};
pub use functions::CodecTag; pub use crate::functions::CodecTag;
} }