Otherwise that code will just be expanded to nothing when compiled
-DG_DISABLE_ASSERT (PS: why is mainloop_start() called in the init
function and not when changing state to READY?)
Keep track of the paused state of the source and leave the read function when
paused.
don't wait for a latency update when the delay is not yet known but simply
return 0 instead of blocking.
Keep track of the corked state of the stream.
Fix the state changes.
We can't wait for the ENTER/LEAVE messages to be be posted because the base
class sometimes calls the start method with the object lock, which would block
the message posting.
Instead, just assume that the message will be posted soon and continue. We'll
have to fix this in the base class.
Emit stream-status messages for the pulse thread.
Don't use our own GCond for signaling but simply use the pulse mainloop
mechanisms for synchronisation.
See #587695
Upper volume limmit was 1000. That appear unneceasrily high. It would also cause
sever distortion if accidentialy used. Now its 10 (~ +15db) which is also in
sync with volume and playbin2.
Since we map the ringbuffer to the pulseaudio internal ringbuffer, flush the
pulseaudio buffer when we are asked to clear the ringbuffer.
This avoids some leftover audio after a seek.
Hack around thread-safety issues in GObject and our racy _get_type()
functions (we could easily fix the _get_type() functions, but we still
need to hack around the GObject class races until we require a newer
GLib version, I think).
First we ignore request to fill the ringbuffer which are less then a segment.
The small request where causing stutter.
Then we disable flushing the stream when running against pa 0.9.12 as this
triggers an assertiong in the sound server and terminates it. It does not happen
with 0.9.10 and 0.9.14.
We can use prebuf = 0 to instruct pulse to not pause the stream on underflows.
This way we can remove the underflow callback. We however have to manually
uncork the stream now when we have no available space in the buffer or when we
are writing too far away from the current read_index.
when we switch streams, the clock will reset to 0. Make sure that the provided
clock doesn't get stuck when this happens by keeping an initial offset. We also
need to make sure that we subtract this offset in samples when writing to the
ringbuffer.
If the caps changes, the sink is reset without transitioning through
a PAUSED->PLAYING state change, resulting in a corked stream. This avoids
the problem by checking that the stream is uncorked when writing samples
to it.
When trying to write out a segment, wait until there is enough free space
for the entire segment. This helps to reduce ripple in the clock reporting,
where the app might query the playback position while only half a segment
has been written (and is therefore reported by _delay(), even though
the ring buffer has not yet been advanced)
g_atomic_int_(get|set) only work on ints and the flags are
an enum (which on most architectures is stored as an int).
Also the way the flags were accessed atomically would still
leave a possible race condition and we don't do it in any
other mixer track implementation, let alone at any other
place where an integer could be changed from different
threads. Removing the g_atomic_int_(get|set) will only
introduce a new race condition on architectures where
integers could be half-written while reading them
which shouldn't be the case for any modern architecture
and if we really care about this we need to use
g_atomic_int_(get|set) at many other places too.
Apart from that g_atomic_int_(set|get) will result in
aliasing warnings if their argument is explicitely
casted to an int *. Fixes bug #571153.