fmp4mux: Don't wait for more data if a stream has no GOP starting before fragment end

Simply don't output anything for this stream and only include it in the
future.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1229>
This commit is contained in:
Sebastian Dröge 2023-06-01 19:24:24 +03:00
parent a5fcd66c95
commit 2e83107c18

View file

@ -1389,12 +1389,21 @@ impl FMP4Mux {
break; break;
} }
// Otherwise if this is the first stream and no full GOP is queued then we need // Otherwise if this is the first stream, no full GOP is queued and the first
// to wait for more data. // GOP is starting inside this fragment then we need to wait for more data.
// //
// If this is not the first stream then take an incomplete GOP. // If this is not the first stream then take an incomplete GOP.
if chunk_end_pts.is_none() { if gop.start_pts >= dequeue_end_pts
gst::info!(CAT, obj: stream.sinkpad, "Don't have a full GOP at the end of a fragment"); || (!gop.final_earliest_pts && !all_eos && !stream.sinkpad.is_eos())
{
gst::trace!(
CAT,
obj: stream.sinkpad,
"GOP starts after fragment end",
);
break;
} else if chunk_end_pts.is_none() {
gst::info!(CAT, obj: stream.sinkpad, "Don't have a full GOP at the end of a fragment for the first stream");
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA); return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
} else { } else {
gst::info!(CAT, obj: stream.sinkpad, "Including incomplete GOP"); gst::info!(CAT, obj: stream.sinkpad, "Including incomplete GOP");
@ -1867,8 +1876,17 @@ impl FMP4Mux {
); );
} else { } else {
// If nothing was dequeued for the first stream then this is OK if we're at // If nothing was dequeued for the first stream then this is OK if we're at
// EOS: we just consider the next stream as first stream then. // EOS or this stream simply has only buffers after this chunk: we just
if all_eos || stream.sinkpad.is_eos() { // consider the next stream as first stream then.
let stream_after_chunk = stream.queued_gops.back().map_or(false, |gop| {
gop.start_pts
>= if fragment_filled {
fragment_start_pts + settings.fragment_duration
} else {
chunk_start_pts + settings.chunk_duration.unwrap()
}
});
if all_eos || stream.sinkpad.is_eos() || stream_after_chunk {
// This is handled below generally if nothing was dequeued // This is handled below generally if nothing was dequeued
} else { } else {
if settings.chunk_duration.is_some() { if settings.chunk_duration.is_some() {