mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-09-02 17:53:48 +00:00
fmp4mux: Only require header updates for caps/language/orientation if they actually changed
Also reject caps updates if they can't be handled. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2193>
This commit is contained in:
parent
c5e4181613
commit
800e4a579f
3 changed files with 61 additions and 30 deletions
|
@ -461,6 +461,9 @@ impl State {
|
|||
self.fragment_end_pts = None;
|
||||
self.chunk_start_pts = None;
|
||||
}
|
||||
fn stream_from_pad(&self, pad: &gst_base::AggregatorPad) -> Option<&Stream> {
|
||||
self.streams.iter().find(|s| *pad == s.sinkpad)
|
||||
}
|
||||
fn mut_stream_from_pad(&mut self, pad: &gst_base::AggregatorPad) -> Option<&mut Stream> {
|
||||
self.streams.iter_mut().find(|s| *pad == s.sinkpad)
|
||||
}
|
||||
|
@ -4351,31 +4354,45 @@ impl AggregatorImpl for FMP4Mux {
|
|||
self.parent_sink_event(aggregator_pad, event)
|
||||
}
|
||||
EventView::Caps(caps) => {
|
||||
// Only care of caps if streams have been setup
|
||||
let caps = caps.caps_owned();
|
||||
|
||||
gst::trace!(CAT, imp = self, "Received caps {}", caps);
|
||||
|
||||
// Only care of caps if streams have been setup and the
|
||||
// caps actually change in an incompatible way
|
||||
let mut state = self.state.lock().unwrap();
|
||||
if !state.streams.is_empty() {
|
||||
state.need_new_header =
|
||||
state
|
||||
.mut_stream_from_pad(aggregator_pad)
|
||||
.is_some_and(|stream| {
|
||||
if !self.caps_compatible(stream, caps.caps())
|
||||
&& self.header_update_allowed("caps")
|
||||
{
|
||||
gst::trace!(
|
||||
CAT,
|
||||
obj = aggregator_pad,
|
||||
"Update caps and send new headers {:?}",
|
||||
caps
|
||||
);
|
||||
stream.next_caps = Some(caps.caps_owned());
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
let stream = state.stream_from_pad(aggregator_pad);
|
||||
|
||||
if state.streams.is_empty()
|
||||
|| stream.is_none_or(|s| s.caps == caps || self.caps_compatible(s, &caps))
|
||||
{
|
||||
// No streams created yet or caps are compatible, don't have to do anything
|
||||
drop(state);
|
||||
self.parent_sink_event(aggregator_pad, event)
|
||||
} else if self.header_update_allowed("caps") {
|
||||
// Stream created and caps are not compatible, but header updates are allowed
|
||||
state.need_new_header = true;
|
||||
gst::trace!(
|
||||
CAT,
|
||||
obj = aggregator_pad,
|
||||
"Update caps and send new headers {:?}",
|
||||
caps
|
||||
);
|
||||
let stream = state.mut_stream_from_pad(aggregator_pad).unwrap();
|
||||
stream.next_caps = Some(caps);
|
||||
drop(state);
|
||||
self.parent_sink_event(aggregator_pad, event)
|
||||
} else {
|
||||
// Stream created and caps are not compatible, but header updates are not allowed
|
||||
gst::warning!(
|
||||
CAT,
|
||||
obj = aggregator_pad,
|
||||
"Updated caps not accepted {:?}",
|
||||
caps
|
||||
);
|
||||
|
||||
false
|
||||
}
|
||||
drop(state);
|
||||
self.parent_sink_event(aggregator_pad, event)
|
||||
}
|
||||
EventView::Tag(ev) => {
|
||||
let tag = ev.tag();
|
||||
|
@ -4392,7 +4409,11 @@ impl AggregatorImpl for FMP4Mux {
|
|||
if let Some(language_code) = Stream::parse_language_code(lang) {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
|
||||
if !state.streams.is_empty() && self.header_update_allowed("language code")
|
||||
if !state.streams.is_empty()
|
||||
&& state
|
||||
.stream_from_pad(aggregator_pad)
|
||||
.is_some_and(|s| s.language_code != Some(language_code))
|
||||
&& self.header_update_allowed("language code")
|
||||
{
|
||||
if tag.scope() == gst::TagScope::Global {
|
||||
gst::info!(
|
||||
|
@ -4404,8 +4425,8 @@ impl AggregatorImpl for FMP4Mux {
|
|||
|
||||
state.need_new_header = true;
|
||||
let stream = state.mut_stream_from_pad(aggregator_pad).unwrap();
|
||||
stream.language_code = Some(language_code);
|
||||
stream.tag_changed = true;
|
||||
stream.language_code = Some(language_code);
|
||||
}
|
||||
}
|
||||
} else if let Some(tag_value) = tag.get::<gst::tags::ImageOrientation>() {
|
||||
|
@ -4418,14 +4439,24 @@ impl AggregatorImpl for FMP4Mux {
|
|||
);
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
let orientation = TransformMatrix::from_tag(self, ev);
|
||||
|
||||
if !state.streams.is_empty() && self.header_update_allowed("orientation") {
|
||||
if !state.streams.is_empty()
|
||||
&& state.stream_from_pad(aggregator_pad).is_some_and(|s| {
|
||||
if tag.scope() == gst::TagScope::Stream {
|
||||
s.stream_orientation != Some(orientation)
|
||||
} else {
|
||||
s.global_orientation != orientation
|
||||
}
|
||||
})
|
||||
&& self.header_update_allowed("orientation")
|
||||
{
|
||||
state.need_new_header = true;
|
||||
let stream = state.mut_stream_from_pad(aggregator_pad).unwrap();
|
||||
if tag.scope() == gst::TagScope::Stream {
|
||||
stream.stream_orientation = Some(TransformMatrix::from_tag(self, ev));
|
||||
stream.stream_orientation = Some(orientation);
|
||||
} else {
|
||||
stream.global_orientation = TransformMatrix::from_tag(self, ev);
|
||||
stream.global_orientation = orientation;
|
||||
}
|
||||
stream.tag_changed = true;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(crate) struct TransformMatrix([[u8; 4]; 9]);
|
||||
|
||||
impl std::ops::Deref for TransformMatrix {
|
||||
|
|
|
@ -2571,7 +2571,7 @@ fn test_language_change_at_gop_boundary() {
|
|||
if i == 10 {
|
||||
let mut tl = gst::TagList::new();
|
||||
tl.make_mut()
|
||||
.add::<gst::tags::LanguageCode>(&"abc", gst::TagMergeMode::Append);
|
||||
.add::<gst::tags::LanguageCode>(&"eng", gst::TagMergeMode::Append);
|
||||
let ev = gst::event::Tag::builder(tl).build();
|
||||
h.push_event(ev);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue