Very much simplified GStreamer-inspired learning framework for understanding buffer synchronization and timing
Project description
GstMini - Simplified GStreamer Learning Framework
A simplified implementation of GStreamer's core concepts for educational purposes. This framework demonstrates buffer synchronization, timing, and thread management in multimedia pipelines.
Overview
GstMini captures the essential mechanics of GStreamer without handling real multimedia content:
- Pipeline: Container managing elements and clock
- Elements: Processing units (Source, Queue, Segmenter, Sink)
- Pads: Connection points with chain functions
- Buffers: Data units carrying timestamps
- Synchronization: Clock-based timing at sinks
- Threading: Queue-based decoupling
Core Concepts Demonstrated
1. Buffer Flow via Chain Calls
Code: src/gst_mini/core/pad.py:push() → src/gst_mini/core/pad.py:_chain()
- Buffers flow synchronously through chain function calls
- Each element's chain function processes and forwards buffers
- Chain calls are blocking - upstream waits for downstream
GStreamer Reference: gstpad.c:4497-4586
2. Timestamps and Time Domains
Code: src/gst_mini/core/buffer.py:GstBuffer
Every buffer carries:
pts: Presentation timestamp (when to display)duration: Buffer durationdata: Payload
GStreamer Reference: gstbuffer.h:80-133
3. Segment Conversion
Code: src/gst_mini/core/segment.py:to_running_time()
Converts stream time to running time:
running_time = (pts - segment.start) / segment.rate + segment.base
GStreamer Reference: gstsegment.c:822-867
4. Queue Thread Decoupling
Code: src/gst_mini/elements/queue.py
Critical for live pipelines!
Two threads:
- Chain function (upstream thread): Enqueues buffers
- Loop function (downstream thread): Dequeues and pushes
This prevents live sources from blocking on sync waits.
GStreamer Reference: gstqueue.c:1271-1639
5. Synchronization at Sink
Code: src/gst_mini/elements/s3sink.py:_chain()
The synchronization formula:
running_time = segment.to_running_time(pts)
clock_time = running_time + base_time
clock.wait_until(clock_time) # BLOCKS here!
GStreamer Reference:
gstbasesink.c:2665-2828(do_sync)gstbasesink.c:2333-2404(wait_clock)
Installation
The project uses uv for package management. Install the package in development mode:
# Create virtual environment (first time only)
uv venv
Running Examples
Full Pipeline (Recommended Start)
uv run examples/full_pipeline.py
What to observe:
- LiveSource generates frames at steady 30fps
- Queue fills and empties
- Segments created every 6 seconds
- S3Sink waits on clock before "uploading"
- Frame generation never blocks!
Without Queue (Demonstrates Problem)
uv run examples/without_queue.py
What to observe:
- Frame generation becomes irregular
- LiveSource blocks during sync waits
- This shows WHY queues are essential!
Simple Synchronization
uv run examples/simple_sync.py
What to observe:
- Manual buffer pushing
- Clock wait mechanism
- Timing formula in action
Learning Path
Phase 1: Understanding Data Flow
- Read
src/gst_mini/core/buffer.py- See how timestamps are stored - Read
src/gst_mini/core/pad.py- Understand chain calls - Run
uv run examples/simple_sync.py- See synchronization in action
Key Insight: Chain calls are synchronous and blocking.
Phase 2: Understanding Timing
- Read
src/gst_mini/core/segment.py- Time domain conversion - Read
src/gst_mini/core/clock.py- Clock wait mechanism - Read
src/gst_mini/elements/s3sink.py:_chain()- See synchronization formula
Key Insight: Sync happens at sinks, not during chain calls.
Phase 3: Understanding Threading
- Read
src/gst_mini/elements/livesource.py- Live frame generation - Run
uv run examples/without_queue.py- See the blocking problem - Read
src/gst_mini/elements/queue.py- Thread decoupling solution - Run
uv run examples/full_pipeline.py- See smooth operation
Key Insight: Queues separate fast producers from slow consumers.
Phase 4: Understanding Buffering
- Read
src/gst_mini/elements/hlssegmenter.py- Accumulation strategy - Modify
target_durationin examples - Modify
max_sizeandleakymode in queue
Key Insight: Buffering enables batching and handles rate mismatches.
Experiments to Try
1. Disable Queue
In full_pipeline.py, remove the queue and link source directly to segmenter:
# pipeline.link(source, queue)
# pipeline.link(queue, segmenter)
pipeline.link(source, segmenter) # Direct link
Expected: Irregular frame generation, blocking.
2. Disable Synchronization
Set sync=False in S3Sink:
sink = S3Sink("s3sink", bucket="live-streams", sync=False)
Expected: Segments "upload" immediately, no clock waits.
3. Change Queue Size
Try different queue sizes:
queue = Queue("queue", max_size=3, leaky="upstream") # Small queue
queue = Queue("queue", max_size=100, leaky=None) # Large queue, blocking
Expected:
- Small queue with leaky: drops frames when full
- Large queue without leaky: never drops, but high latency
4. Change Leaky Mode
queue = Queue("queue", max_size=10, leaky="downstream") # Drop old buffers
Expected: Maintains low latency by dropping old data.
5. Vary FPS and Segment Duration
source = LiveSource("camera", fps=60) # Higher frame rate
segmenter = HLSSegmenter("segmenter", target_duration=2.0) # Shorter segments
Expected: More frequent segment creation.
Code Mapping to Real GStreamer
| GstMini Component | Real GStreamer | File:Line |
|---|---|---|
GstBuffer.pts |
GST_BUFFER_PTS |
gstbuffer.h:89 |
GstSegment.to_running_time() |
gst_segment_to_running_time() |
gstsegment.c:822 |
GstPad.push() |
gst_pad_push() |
gstpad.c:4795 |
GstPad._chain() |
gst_pad_chain_data_unchecked() |
gstpad.c:4497 |
Queue._chain() |
gst_queue_chain_buffer_or_list() |
gstqueue.c:1271 |
Queue._loop() |
gst_queue_loop() |
gstqueue.c:1590 |
S3Sink._chain() |
gst_base_sink_do_sync() |
gstbasesink.c:2665 |
GstClock.wait_until() |
gst_base_sink_wait_clock() |
gstbasesink.c:2333 |
Key Takeaways
- Buffers carry timestamps - Set once by source, preserved through pipeline
- Segments define time domains - Enable seeking, rate changes
- Chain calls are synchronous - Blocking data flow
- Synchronization happens at sinks - Via clock waits
- Queues decouple threads - Essential for live sources
- The sync formula:
clock_time = running_time + base_time - Thread safety: Mutexes protect queue, pad stream locks serialize data
Differences from Real GStreamer
Simplified for learning:
- No caps negotiation
- No events (except implicit segment)
- No queries
- No buffer pools or memory management
- No state change ordering
- No preroll mechanism
- Single clock (no clock providers/selection)
- No activation modes (push/pull)
- No scheduling/chain optimization
- Simplified error handling
These simplifications let you focus on the core synchronization concepts without the full GStreamer's functionality.
Next Steps
After understanding GstMini:
- Explore real GStreamer code using the file:line references
- Build a real pipeline with GStreamer applying these concepts
- Extend GstMini - Add features like:
- Multiple sinks (audio + video sync)
- Seeking support
- QoS events
- Buffer pools
- More element types
Questions to Explore
- How does the queue decide when to drop buffers?
- How would you implement rate changes (slow motion)?
- What happens if clock time goes backwards?
Happy learning!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gst_mini-0.1.0.tar.gz.
File metadata
- Download URL: gst_mini-0.1.0.tar.gz
- Upload date:
- Size: 714.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebb0dfde5a228cfdcc3ab2dc0de805973c76fcf830e79145bf3ead1ae70503df
|
|
| MD5 |
980e9b2c5d98dcbe990f6d9ad938722a
|
|
| BLAKE2b-256 |
e29d383199f51cf5f088034524a3ad46f4badef6e0a6d59dd154ef595660253e
|
File details
Details for the file gst_mini-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gst_mini-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81dfe72b0155b86c2ed39a86b5cc23ea1eff9f11cf47f294cc0f4d8611a2e8e4
|
|
| MD5 |
3c08b07026a15be92669e20aca09bd5b
|
|
| BLAKE2b-256 |
92b59220723dfb00a2313e366f91504f32369b02addf5a2b51c47590a797a334
|