Context
I’m trying to implement a (draft) profile ISOBMFF, called the NGA GEOINT Imagery Profile for ISR (GIMI). One of the requirements is a per-sample identifier in the form urn:uuid:<uuid>
. I can generate it my modified mux/mp4 implementation, but it would be useful if it could be applied earlier in the processing pipeline, so analysis elements could associate the analysis results with the sample.
To do that, I’ve created a simple Meta to hold the sample identifier, and an element to put the sample identifier on, and that looks like it works.
However when I try to pull out the identifier in the mux/mp4 element, I get assertions.
Debugging
It looks like I have a similar problem to Implementing a new GstMeta,but call gst_meta_api_type_register error - #3 by ndufresne and the G_DEBUG=fatal_criticals
suggestion seems to align.
I reproduce the problem on the command line, using:
gst-launch-1.0 -v videotestsrc num-buffers=250 ! video/x-raw,width=1280,height=720,format=I420 ! x264enc ! sampleidentstamper identifier-kind=urn-uuid ! gimimp4mux classification=U ! filesink location=out.mp4
In the debug output, I see: g_pointer_type_register_static: assertion 'g_type_from_name (name) == 0' failed
, and the backtrace looks like this:
#0 0x00007ffff7d556a1 in g_logv () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#1 0x00007ffff7d55953 in g_log () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007ffff7cd4042 in g_pointer_type_register_static () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#3 0x00007ffff7ec6a87 in gst_meta_api_type_register () at /lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#4 0x00007ffff66b8383 in gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure#0} () at generic/sampleident/src/sampleidentmeta.rs:110
#5 std::sync::once_lock::{impl#0}::get_or_init::{closure#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}> () at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once_lock.rs:276
#6 std::sync::once_lock::{impl#0}::initialize::{closure#0}<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !> (p=<optimised out>)
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once_lock.rs:483
#7 std::sync::once::{impl#2}::call_once_force::{closure#0}<std::sync::once_lock::{impl#0}::initialize::{closure_env#0}<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !>> (p=<optimised out>) at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once.rs:217
#8 std::sys::sync::once::futex::Once::call<std::sync::once::{impl#2}::call_once_force::{closure_env#0}<std::sync::once_lock::{impl#0}::initialize::{closure_env#0}<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !>>> (self=0x7ffff67f86d0 <gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::TYPE+8>, ignore_poisoning=true, f=<optimised out>)
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/sync/once/futex.rs:124
#9 0x00007ffff66b8be1 in std::sync::once::Once::call_once_force<std::sync::once_lock::{impl#0}::initialize::{closure_env#0}<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !>> (self=<optimised out>, f=...) at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once.rs:217
#10 std::sync::once_lock::OnceLock<glib::types::Type>::initialize<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !>
(self=<optimised out>, f=...) at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once_lock.rs:482
#11 0x00007ffff672f577 in std::sync::once_lock::OnceLock<glib::types::Type>::get_or_try_init<glib::types::Type, std::sync::once_lock::{impl#0}::get_or_init::{closure_env#0}<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>, !> (self=0x7ffff67f86c8 <gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::TYPE>, f=...) at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once_lock.rs:364
#12 std::sync::once_lock::OnceLock<glib::types::Type>::get_or_init<glib::types::Type, gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::{closure_env#0}>
(self=0x7ffff67f86c8 <gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type::TYPE>, f=...) at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sync/once_lock.rs:276
#13 gstsampleident::sampleidentmeta::imp::sample_identification_meta_api_get_type () at generic/sampleident/src/sampleidentmeta.rs:109
#14 0x00007ffff66cabb4 in gstreamer::buffer::BufferRef::meta_mut<gstsampleident::sampleidentmeta::SampleIdentificationMeta> (self=0x7fffe44aa2e0) at /home/bradh/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/083c5bd/gstreamer/src/buffer.rs:571
#15 gstmp4::mp4mux::imp::MP4Mux::drain_buffers (self=0x555555856ef0, settings=<optimised out>, state=0x555555856ef8, buffers=0x7fffe8003780) at mux/mp4/src/mp4mux/imp.rs:1169
#16 0x00007ffff66d09c1 in gstmp4::mp4mux::imp::{impl#7}::aggregate (self=0x555555856ef0, _timeout=<optimised out>) at mux/mp4/src/mp4mux/imp.rs:1861
The code at mux/mp4/src/mp4mux/imp.rs:1169 (backtrace step #15) looks like:
if let Some(meta) = buffer.make_mut().meta_mut::<sampleidentmeta::SampleIdentificationMeta>() {
that appears to be calling down into the meta, where it ends up in this block:
*TYPE.get_or_init(|| unsafe {
let t = glib::Type::from_glib(gst::ffi::gst_meta_api_type_register(
c"GstSampleIdentificationMetaAPI".as_ptr() as *const _,
[ptr::null::<std::os::raw::c_char>()].as_ptr() as *mut *const _,
));
assert_ne!(t, glib::Type::INVALID);
t
})
Where the gst_meta_api_type_register() call fails. It looks like its working OK for the stamper element, but the mux isn’t working. In the related report, it was identified that the meta is registered twice, which looks possible, but I don’t understand why.
Additional details
The source for my meta is at generic/sampleident/src/sampleidentmeta.rs · cabf878cc5defa78f7f47cca079505ca3c670368 · Brad Hards / gst-plugins-rs · GitLab
The imp source for the stamper element is at generic/sampleident/src/sampleidentmeta.rs · cabf878cc5defa78f7f47cca079505ca3c670368 · Brad Hards / gst-plugins-rs · GitLab
The imp for my modified mux element is at mux/mp4/src/mp4mux/imp.rs · cabf878cc5defa78f7f47cca079505ca3c670368 · Brad Hards / gst-plugins-rs · GitLab
Questions
Is there an obvious problem with what I’m trying here?
Is there an easy fix, or an alternative approach.
Is there a way to debug this further?