mf
Media Framework
|
Timed ring buffer with changed semantics, for dual-thread use. More...
#include <shared_ring.h>
Public Types | |
using | section_view_type = timed_ring::section_view_type |
Public Member Functions | |
shared_ring (const frame_array_properties &, bool seekable, time_unit end_time=-1) | |
void | initialize () |
const frame_format & | format () const noexcept |
time_unit | capacity () const |
Capacity of buffer. More... | |
section_view_type | begin_write (time_unit write_duration) |
Begin writing write_duration frames at current write start time. More... | |
section_view_type | try_begin_write (time_unit write_duration) |
Begin writing write_duration frames at current write start time, if they are available. More... | |
bool | wait_writable (event &break_event) |
Wait until a frame become writable, or break_event occurs. More... | |
void | end_write (time_unit written_duration, bool mark_end=false) |
End writing written_duration frames. More... | |
section_view_type | begin_read_span (time_span) |
Begin reading frames at time span span. More... | |
section_view_type | begin_read (time_unit read_duration) |
Begin reading read_duration frames at current read start time. More... | |
section_view_type | try_begin_read (time_unit read_duration) |
Begin reading read_duration frames at current read start time, if they are available. More... | |
bool | wait_readable (event &break_event) |
Wait until a frame become readable, or break_event occurs. More... | |
void | end_read (time_unit read_duration) |
End reading read_duration frames. More... | |
void | skip (time_unit skip_duration) |
Skips duration frames. More... | |
bool | is_seekable () const |
Check if the ring is seekable. More... | |
void | seek (time_unit target_time) |
Seeks to read time t. More... | |
bool | can_seek (time_unit target_time) const |
Verifies if is is possible to seek to read time t. More... | |
time_unit | current_time () const |
Time of last written frame in buffer. More... | |
time_unit | write_start_time () const |
Presumptive start time of next write. More... | |
time_unit | read_start_time () const |
Read start time. More... | |
time_span | writable_time_span () const |
Currently writable time span. More... | |
time_span | readable_time_span () const |
Currently readable time span. More... | |
time_unit | writable_duration () const |
Currently writable duration. More... | |
time_unit | readable_duration () const |
Currently readable duration. More... | |
time_unit | end_time () const |
End of file time. */. More... | |
bool | end_time_is_defined () const |
True if end of file time is known. */. More... | |
bool | writer_reached_end () const |
True if writer has written last frame. More... | |
bool | reader_reached_end () const |
True if reader has read last frame. More... | |
Timed ring buffer with changed semantics, for dual-thread use.
Not derived from timed_ring because semantics are changed and functionality is added. Interface and implementation, and scope of functionality designed to prevent data races and deadlocks. Must be used with two threads, one reader and one writer. Added functionality compared to timed_ring:
end_write()
, when it wrote at least 1 frame. Reader responds by not waiting for any more frames, even if at start of begin_read()
, duration was not yet known. mf::shared_ring::shared_ring | ( | const frame_array_properties & | prop, |
bool | seekable, | ||
time_unit | end_time = -1 |
||
) |
auto mf::shared_ring::begin_read | ( | time_unit | read_duration | ) |
Begin reading read_duration frames at current read start time.
If span to read crosses end of buffer, it is truncated. When already at end, zero-length section is returned. Then end_read() must not be called. Waits until read_duration (after truncation) frames become readable. For non-seekable buffer only: end may be marked while waiting, and so returned section may be truncated even if end time was not defined prior to call. Returns section for writer to read from, with time information. Reader may also freely write into the returned section. Must be called from single reader thread only, and followed by call to end_read().
auto mf::shared_ring::begin_read_span | ( | time_span | span | ) |
Begin reading frames at time span span.
If span does not start at readable_time_span().start_time()
, seeks to span.start_time()
first. Then behaves as begin_read(span.duration())
.
auto mf::shared_ring::begin_write | ( | time_unit | write_duration | ) |
Begin writing write_duration frames at current write start time.
If span to write crosses end of buffer, it is truncated. For seekable buffer only: returned section may have start time different to writable_time_span().start_time()
when reader seeked to another time inbetween. When at end (already before, or following wait and seek), zero-length section is returned, and start time of returned time span equals end_time()
. Then end_write() must not be called. Waits until write_duration (after truncation) frames become writable. Returns section for writer to write into, with time information. Must be called from single writer thread only, and followed by call to end_write().
bool mf::shared_ring::can_seek | ( | time_unit | target_time | ) | const |
Verifies if is is possible to seek to read time t.
Returns false when buffer is not seekable, or when time is out of bounds.
|
inline |
Capacity of buffer.
Maximal readable and writable frames that fit in buffer.
time_unit mf::shared_ring::current_time | ( | ) | const |
Time of last written frame in buffer.
Equivalent to write_start_time() - 1
. -1 in initial state.
void mf::shared_ring::end_read | ( | time_unit | read_duration | ) |
End reading read_duration frames.
Must be called after begin_read() or begin_read_span(). read_duration must be lesser of equal to duration of section returned by that function.
|
inline |
End of file time. */.
Returns -1 if not defined. For non-seekable buffer, reader must not rely on this value because it can change between end_time() call and begin_read() call.
|
inline |
True if end of file time is known. */.
void mf::shared_ring::end_write | ( | time_unit | written_duration, |
bool | mark_end = false |
||
) |
End writing written_duration frames.
Must be called after begin_write(). written_duration must be lesser of equal to duration of section returned by begin_write(). For non-seekable buffer, mark_end is used to mark this written frame(s) as last. mark_end cannot be set when written_duration is zero. The reader cannot seek to other position inbetween begin_write() and end_write() calls of writer.
|
inlinenoexcept |
void mf::shared_ring::initialize | ( | ) |
|
inline |
Check if the ring is seekable.
As specified in construction.
time_unit mf::shared_ring::read_start_time | ( | ) | const |
Read start time.
Value gets changed by reader. Start time of view returned by begin_read(), unless reader seeks to another frame.
|
inline |
Currently readable duration.
Equivalent to readable_time_span().duration()
.
time_span mf::shared_ring::readable_time_span | ( | ) | const |
Currently readable time span.
Span starting from read_start_time(), going until end of currently readable span, or end of stream, whichever comes earlier. That is, reader can wait for more than this span in former case. Span is fetched atomically.
bool mf::shared_ring::reader_reached_end | ( | ) | const |
True if reader has read last frame.
Unlike end_time(), the result cannot change between reader_reached_end() and begin_read() call: for non-seekable buffer, the writer can only mark end after writing at least one frame, and hence cannot retroactively mark current read start position as being the end.
void mf::shared_ring::seek | ( | time_unit | target_time | ) |
Seeks to read time t.
Can only be called on seekable buffer. Must be called from single reader thread only. Sets read start position to absolute time t, producing internal discontinuity in buffer. Change is signalled to writer by the section returned by begin_write()
, and writer must react by writing frames for that time.
void mf::shared_ring::skip | ( | time_unit | skip_duration | ) |
Skips duration frames.
If span to skip crosses end of buffer, it is truncated, and skips to end of file. duration can be larger than buffer capacity. For non-seekable buffer, reads and discards duration frames, possibly letting writer fill up buffer multiple times. For seekable buffer, equivalent to seek(read_start_time() + duration)
. Must be called from single reader thread only.
auto mf::shared_ring::try_begin_read | ( | time_unit | read_duration | ) |
Begin reading read_duration frames at current read start time, if they are available.
Like begin_read(), but never waits. Instead returns null view when the frames are not available.
auto mf::shared_ring::try_begin_write | ( | time_unit | write_duration | ) |
Begin writing write_duration frames at current write start time, if they are available.
Like begin_write(), but never waits. Instead returns null view when the frames are not available.
bool mf::shared_ring::wait_readable | ( | event & | break_event | ) |
Wait until a frame become readable, or break_event occurs.
If no frame is readable (either because writer has not written enough frames from the ring buffer yet or read start time is at end), waits until at least one frame becomes available, or break_event occurs. If break_event occured, returns false. Otherwise, repeats until at least one frames is readable. Also waits if write start position is at end time, until break_event occurs.
bool mf::shared_ring::wait_writable | ( | event & | break_event | ) |
Wait until a frame become writable, or break_event occurs.
If no frame is writable (either because reader has not read enough frames from the ring buffer yet or write start time is at end), waits until at least one frame becomes available, or break_event occurs. If break_event occured, returns false. Otherwise, repeats until at least one frames is writable. Also waits if write start position is at end time, until seek occurs or break_event occurs.
|
inline |
Currently writable duration.
Equivalent to writable_time_span().duration()
.
time_span mf::shared_ring::writable_time_span | ( | ) | const |
Currently writable time span.
Span starting from write_start_time(), going until end of currently writable span, or end of stream, whichever comes earlier. That is, writer can wait for more than this span in former case. Span is fetched atomically.
time_unit mf::shared_ring::write_start_time | ( | ) | const |
Presumptive start time of next write.
Value gets changed by writer. For seekable policy, if can also be changed by reader, including during a begin_write() call while writer is waiting. Writer must always use start time of span returned by begin_write() of try_begin_write() instead.
bool mf::shared_ring::writer_reached_end | ( | ) | const |
True if writer has written last frame.
For non-seekable buffer, true after end_write() call with mark end. begin_write() returns empty view if called after this returned true. (Except if seek occured inbetween).