diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2023-06-01 19:24:24 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2023-06-06 22:43:56 +0300 |
commit | 245990a0788b9f63988a6be5efdc156214f77060 (patch) | |
tree | efe596b8e3c1a5bcf0335b515d5aa9055b6edd80 | |
parent | c9d2ba306b5488e1d91b543c85a504c3beee8667 (diff) |
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/1233>
-rw-r--r-- | mux/fmp4/src/fmp4mux/imp.rs | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/mux/fmp4/src/fmp4mux/imp.rs b/mux/fmp4/src/fmp4mux/imp.rs index ece9338d7..8a2f9494b 100644 --- a/mux/fmp4/src/fmp4mux/imp.rs +++ b/mux/fmp4/src/fmp4mux/imp.rs @@ -1389,12 +1389,21 @@ impl FMP4Mux { break; } - // Otherwise if this is the first stream and no full GOP is queued then we need - // to wait for more data. + // Otherwise if this is the first stream, no full GOP is queued and the first + // 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 chunk_end_pts.is_none() { - gst::info!(CAT, obj: stream.sinkpad, "Don't have a full GOP at the end of a fragment"); + if gop.start_pts >= dequeue_end_pts + || (!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); } else { gst::info!(CAT, obj: stream.sinkpad, "Including incomplete GOP"); @@ -1867,8 +1876,17 @@ impl FMP4Mux { ); } else { // 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. - if all_eos || stream.sinkpad.is_eos() { + // EOS or this stream simply has only buffers after this chunk: we just + // 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 } else { if settings.chunk_duration.is_some() { |