GNOME Bugzilla – Bug 743925
osxaudiosink won't reconfigure sink caps
Last modified: 2015-03-03 18:03:07 UTC
Once osxaudiosink's device is open, it fixates on the initial caps and refuses to accept new caps. This is erroneous since the Audio Unit is can accept a new ASBD, and GstAudioRingBuffer supports reconfiguration as well. (This causes a problem, e.g. with interaudiosrc, which might produce a silent buffer with rate:48000 before producing one coming from the interaudiosink with actual rate:$MY_PIPELINE_RATE.) Therefore, we need to change: static GstCaps * gst_osx_audio_sink_getcaps (GstBaseSink * sink, GstCaps * filter) { ... #if 0 if (buf->acquired && buf->spec.caps) { /* Caps are fixed, use what we have */ ret = gst_caps_ref (buf->spec.caps); } #endif .... I've tested this on iOS 8. I will submit a patch once I test it on OS X too.
What's the status here? It should indeed just work, the ringbuffer handles all the reconfiguration for us.
I've researched it, implemented above fix in my code and it works fine on iOS. I won't have time till mid-next week, so either I'll submit a patch (after I take care of the osx test code) or, go ahead :)
Created attachment 297508 [details] [review] Patch Tested on iOS, by observing the actual interaudiosrc / interaudiosink issue we've seen in OpenWebRTC is fixed. Tested on OS X, through a custom test program that: 1) Creates 'osxaudiosrc ! queue ! audioconvert ! audioresample ! capsfilter ! queue ! osxaudiosink'. 2) After a few seconds, sets caps=audio/x-raw,rate=8000 on the capsfilter. Before this fix, this will result in a negotiation error.
Created attachment 298378 [details] [review] osxaudiosink: Allow renegotiating caps I've made a couple of small modifications to your patch for correctness. But this doesn't actually work for me (neither did your old patch) -- after renegotiation, I hear no audio. I'll attach a small test program to make sure we're on the same page.
Created attachment 298379 [details] Test program for ringbuffer renegotiation Tested that this works with pulsesink on Linux, but with osxaudiosink, there is only silence after renegotiation. I do see the render function being called on the sink, so not sure why the data is lost.
We might be reading silence from the ringbuffer, which happens if we read areas that are not written yet (i.e. read to fast). Check where the silence first appears with gst_util_dump_mem() or similar :)
Nice catch -- if I wait longer after reconfigure it does start playing, so I guess it seems to be writing at the offset it expected, but the ringbuffer has been reset, so we have silence for that period.
On my OS X, the test program exhibits the same behavior without the patch as well. About the correction to the (In reply to Arun Raghavan from comment #4) > I've made a couple of small modifications to your patch for correctness. The old code didn't get template caps either if the ring buffer wasn't open. I would however change this: if (!ret && osxsink->cached_caps) ret = gst_caps_ref (osxsink->cached_caps); to: if (osxsink->cached_caps) ret = gst_caps_ref (osxsink->cached_caps); I know the current get_caps are bad, but I was planning to address this in the mega-patch to bug 743758.
Created attachment 298433 [details] [review] My patch revised
Comment on attachment 298433 [details] [review] My patch revised I'd already fixed this -- guess I'd attached an old version of the patch. Pushed now, and fixed for osxaudiosrc too. Thanks!
As an additional note, baseaudiosink was also fixed to reset the audio clock if needed (the problem discussed in comment #7).