Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mux/fmp4/tests/tests.rs')
-rw-r--r--mux/fmp4/tests/tests.rs324
1 files changed, 324 insertions, 0 deletions
diff --git a/mux/fmp4/tests/tests.rs b/mux/fmp4/tests/tests.rs
index ac59e3779..a32e65fc7 100644
--- a/mux/fmp4/tests/tests.rs
+++ b/mux/fmp4/tests/tests.rs
@@ -1669,3 +1669,327 @@ fn test_chunking_multi_stream() {
let ev = h1.pull_event().unwrap();
assert_eq!(ev.type_(), gst::EventType::Eos);
}
+
+#[test]
+fn test_chunking_single_stream_gops_after_fragment_end_before_next_chunk_end() {
+ init();
+
+ let caps = gst::Caps::builder("video/x-h264")
+ .field("width", 1920i32)
+ .field("height", 1080i32)
+ .field("framerate", gst::Fraction::new(30, 1))
+ .field("stream-format", "avc")
+ .field("alignment", "au")
+ .field("codec_data", gst::Buffer::with_size(1).unwrap())
+ .build();
+
+ let mut h = gst_check::Harness::new("cmafmux");
+
+ // 5s fragment duration, 1s chunk duration
+ h.element()
+ .unwrap()
+ .set_property("fragment-duration", 5.seconds());
+ h.element()
+ .unwrap()
+ .set_property("chunk-duration", 1.seconds());
+
+ h.set_src_caps(caps);
+ h.play();
+
+ // Push 15 buffers of 0.5s each, 1st and 12th buffer without DELTA_UNIT flag
+ for i in 0..15 {
+ let mut buffer = gst::Buffer::with_size(1).unwrap();
+ {
+ let buffer = buffer.get_mut().unwrap();
+ buffer.set_pts(i * 500.mseconds());
+ buffer.set_dts(i * 500.mseconds());
+ buffer.set_duration(500.mseconds());
+ if i != 0 && i != 11 {
+ buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
+ }
+ }
+ assert_eq!(h.push(buffer), Ok(gst::FlowSuccess::Ok));
+
+ if i == 2 {
+ let ev = loop {
+ let ev = h.pull_upstream_event().unwrap();
+ if ev.type_() != gst::EventType::Reconfigure
+ && ev.type_() != gst::EventType::Latency
+ {
+ break ev;
+ }
+ };
+
+ assert_eq!(ev.type_(), gst::EventType::CustomUpstream);
+ assert_eq!(
+ gst_video::UpstreamForceKeyUnitEvent::parse(&ev).unwrap(),
+ gst_video::UpstreamForceKeyUnitEvent {
+ running_time: Some(5.seconds()),
+ all_headers: true,
+ count: 0
+ }
+ );
+ }
+ }
+
+ // Crank the clock: this should bring us to the end of the first fragment
+ h.crank_single_clock_wait().unwrap();
+
+ let mut expected_ts = gst::ClockTime::ZERO;
+ let mut num_buffers = 0;
+
+ let header = h.pull().unwrap();
+ assert_eq!(
+ header.flags(),
+ gst::BufferFlags::HEADER | gst::BufferFlags::DISCONT
+ );
+ assert_eq!(header.pts(), Some(expected_ts));
+ assert_eq!(header.dts(), Some(expected_ts));
+
+ // There should be 7 chunks now, and the 1st and 7th are starting a fragment.
+ // Each chunk should have two buffers except for the 6th.
+ for chunk in 0..7 {
+ let chunk_header = h.pull().unwrap();
+ if chunk == 0 || chunk == 6 {
+ assert_eq!(chunk_header.flags(), gst::BufferFlags::HEADER);
+ } else {
+ assert_eq!(
+ chunk_header.flags(),
+ gst::BufferFlags::HEADER | gst::BufferFlags::DELTA_UNIT
+ );
+ }
+ assert_eq!(chunk_header.pts(), Some(expected_ts));
+ assert_eq!(chunk_header.dts(), Some(expected_ts));
+ if chunk == 5 {
+ assert_eq!(chunk_header.duration(), Some(500.mseconds()));
+ } else {
+ assert_eq!(chunk_header.duration(), Some(1.seconds()));
+ }
+
+ for buffer_idx in 0..2 {
+ let buffer = h.pull().unwrap();
+ num_buffers += 1;
+ if buffer_idx == 1 || (chunk == 5 && buffer_idx == 0) {
+ assert_eq!(
+ buffer.flags(),
+ gst::BufferFlags::DELTA_UNIT | gst::BufferFlags::MARKER
+ );
+ } else {
+ assert_eq!(buffer.flags(), gst::BufferFlags::DELTA_UNIT);
+ }
+ assert_eq!(buffer.pts(), Some(expected_ts));
+ assert_eq!(buffer.dts(), Some(expected_ts));
+ assert_eq!(buffer.duration(), Some(500.mseconds()));
+
+ expected_ts += 500.mseconds();
+
+ // Only one buffer in this chunk
+ if chunk == 5 && buffer_idx == 0 {
+ break;
+ }
+ }
+ }
+
+ h.push_event(gst::event::Eos::new());
+
+ // There should be one remaining chunk now, containing two 500ms buffer.
+ for _chunk in 7..8 {
+ let chunk_header = h.pull().unwrap();
+ assert_eq!(
+ chunk_header.flags(),
+ gst::BufferFlags::HEADER | gst::BufferFlags::DELTA_UNIT
+ );
+ assert_eq!(chunk_header.pts(), Some(expected_ts));
+ assert_eq!(chunk_header.dts(), Some(expected_ts));
+ assert_eq!(chunk_header.duration(), Some(1.seconds()));
+
+ for buffer_idx in 0..2 {
+ let buffer = h.pull().unwrap();
+ num_buffers += 1;
+ if buffer_idx == 1 {
+ assert_eq!(
+ buffer.flags(),
+ gst::BufferFlags::DELTA_UNIT | gst::BufferFlags::MARKER
+ );
+ } else {
+ assert_eq!(buffer.flags(), gst::BufferFlags::DELTA_UNIT);
+ }
+ assert_eq!(buffer.pts(), Some(expected_ts));
+ assert_eq!(buffer.dts(), Some(expected_ts));
+ assert_eq!(buffer.duration(), Some(500.mseconds()));
+ expected_ts += 500.mseconds();
+ }
+ }
+
+ assert_eq!(num_buffers, 15);
+
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::StreamStart);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Caps);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Segment);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Eos);
+}
+
+#[test]
+fn test_chunking_single_stream_gops_after_fragment_end_after_next_chunk_end() {
+ init();
+
+ let caps = gst::Caps::builder("video/x-h264")
+ .field("width", 1920i32)
+ .field("height", 1080i32)
+ .field("framerate", gst::Fraction::new(30, 1))
+ .field("stream-format", "avc")
+ .field("alignment", "au")
+ .field("codec_data", gst::Buffer::with_size(1).unwrap())
+ .build();
+
+ let mut h = gst_check::Harness::new("cmafmux");
+
+ // 5s fragment duration, 1s chunk duration
+ h.element()
+ .unwrap()
+ .set_property("fragment-duration", 5.seconds());
+ h.element()
+ .unwrap()
+ .set_property("chunk-duration", 1.seconds());
+
+ h.set_src_caps(caps);
+ h.play();
+
+ // Push 15 buffers of 0.5s each, 1st and 14th buffer without DELTA_UNIT flag
+ for i in 0..15 {
+ let mut buffer = gst::Buffer::with_size(1).unwrap();
+ {
+ let buffer = buffer.get_mut().unwrap();
+ buffer.set_pts(i * 500.mseconds());
+ buffer.set_dts(i * 500.mseconds());
+ buffer.set_duration(500.mseconds());
+ if i != 0 && i != 13 {
+ buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
+ }
+ }
+ assert_eq!(h.push(buffer), Ok(gst::FlowSuccess::Ok));
+
+ if i == 2 {
+ let ev = loop {
+ let ev = h.pull_upstream_event().unwrap();
+ if ev.type_() != gst::EventType::Reconfigure
+ && ev.type_() != gst::EventType::Latency
+ {
+ break ev;
+ }
+ };
+
+ assert_eq!(ev.type_(), gst::EventType::CustomUpstream);
+ assert_eq!(
+ gst_video::UpstreamForceKeyUnitEvent::parse(&ev).unwrap(),
+ gst_video::UpstreamForceKeyUnitEvent {
+ running_time: Some(5.seconds()),
+ all_headers: true,
+ count: 0
+ }
+ );
+ }
+ }
+
+ // Crank the clock: this should bring us to the end of the first fragment
+ h.crank_single_clock_wait().unwrap();
+
+ let mut expected_ts = gst::ClockTime::ZERO;
+ let mut num_buffers = 0;
+
+ let header = h.pull().unwrap();
+ assert_eq!(
+ header.flags(),
+ gst::BufferFlags::HEADER | gst::BufferFlags::DISCONT
+ );
+ assert_eq!(header.pts(), Some(expected_ts));
+ assert_eq!(header.dts(), Some(expected_ts));
+
+ // There should be 7 chunks now, and the 1st is starting a fragment.
+ // Each chunk should have two buffers except for the 7th.
+ for chunk in 0..7 {
+ let chunk_header = h.pull().unwrap();
+ if chunk == 0 {
+ assert_eq!(chunk_header.flags(), gst::BufferFlags::HEADER);
+ } else {
+ assert_eq!(
+ chunk_header.flags(),
+ gst::BufferFlags::HEADER | gst::BufferFlags::DELTA_UNIT
+ );
+ }
+ assert_eq!(chunk_header.pts(), Some(expected_ts));
+ assert_eq!(chunk_header.dts(), Some(expected_ts));
+ if chunk == 6 {
+ assert_eq!(chunk_header.duration(), Some(500.mseconds()));
+ } else {
+ assert_eq!(chunk_header.duration(), Some(1.seconds()));
+ }
+
+ for buffer_idx in 0..2 {
+ let buffer = h.pull().unwrap();
+ num_buffers += 1;
+ if buffer_idx == 1 || (chunk == 6 && buffer_idx == 0) {
+ assert_eq!(
+ buffer.flags(),
+ gst::BufferFlags::DELTA_UNIT | gst::BufferFlags::MARKER
+ );
+ } else {
+ assert_eq!(buffer.flags(), gst::BufferFlags::DELTA_UNIT);
+ }
+ assert_eq!(buffer.pts(), Some(expected_ts));
+ assert_eq!(buffer.dts(), Some(expected_ts));
+ assert_eq!(buffer.duration(), Some(500.mseconds()));
+
+ expected_ts += 500.mseconds();
+
+ // Only one buffer in this chunk
+ if chunk == 6 && buffer_idx == 0 {
+ break;
+ }
+ }
+ }
+
+ h.push_event(gst::event::Eos::new());
+
+ // There should be two remaining chunks now, containing two 500ms buffers.
+ // This should start a new fragment.
+ for _chunk in 7..8 {
+ let chunk_header = h.pull().unwrap();
+ assert_eq!(chunk_header.flags(), gst::BufferFlags::HEADER);
+ assert_eq!(chunk_header.pts(), Some(expected_ts));
+ assert_eq!(chunk_header.dts(), Some(expected_ts));
+ assert_eq!(chunk_header.duration(), Some(1.seconds()));
+
+ for buffer_idx in 0..2 {
+ let buffer = h.pull().unwrap();
+ num_buffers += 1;
+ if buffer_idx == 1 {
+ assert_eq!(
+ buffer.flags(),
+ gst::BufferFlags::DELTA_UNIT | gst::BufferFlags::MARKER
+ );
+ } else {
+ assert_eq!(buffer.flags(), gst::BufferFlags::DELTA_UNIT);
+ }
+ assert_eq!(buffer.pts(), Some(expected_ts));
+ assert_eq!(buffer.dts(), Some(expected_ts));
+ assert_eq!(buffer.duration(), Some(500.mseconds()));
+ expected_ts += 500.mseconds();
+ }
+ }
+
+ assert_eq!(num_buffers, 15);
+
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::StreamStart);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Caps);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Segment);
+ let ev = h.pull_event().unwrap();
+ assert_eq!(ev.type_(), gst::EventType::Eos);
+}