Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

jml5qh
I currently have two streams running from rtspsrc at the same time on an iPad. Both streams have audio and video in them. At the end of each audio pad, I have an osxaudiosink element. There are times where I stop both the streams at the same time. For example, when the user goes to another page. At this time, I set the rtspsrc pipeline to GST_STATE_NULL. However, random this call can block for up to 30 seconds and then I see the following errors in my console:

[aurioc] 1590: AURemoteIO@0x10801c640: IOThread exiting with error 0x10004002
(AudioToolbox)[1038] <Notice>: 1334: AURemoteIO::Stop: error 0x10004003 calling TerminateOwnIOThread

Doing some searching around, a lot of people seem to think it has do with calling AudioUnitGetProperty in the render callback. I don't see that happening in the code, but I do see AudioUnitGetProperty called in the audio ring buffer delay callback.

Another interesting thing to note is I never see the issue when only streaming from one rtspsrc stream. It only starts happening when I stream from two at a time.
Reply | Threaded
Open this post in threaded view
|

Re: Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

jml5qh
I have a sample project where I can reproduce the issue at https://www.dropbox.com/s/6qeijiwuxbz1lrx/GStreamerAudioError.zip?dl=0. Note it may take a few times to trigger the issue.
Reply | Threaded
Open this post in threaded view
|

Re: Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

jml5qh
Doing some testing, I can fix this issue by moving the following line above AudioOutputUnitStop in gstosxcoreaudiocommon. gst_core_audio_io_proc_stop:

  if (core_audio->io_proc_active) {
    gst_core_audio_remove_render_callback (core_audio);
  }

Any ideas why this would fix it? Is this just a red herring? Any thoughts on ways to fix this? TIA for any help you can provide.
Reply | Threaded
Open this post in threaded view
|

Re: Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

jml5qh
I also realized the sample project I previously attached had a bug that prevented the error from surfacing. Here is an updated project that should successfully reproduce the issue: https://www.dropbox.com/s/0zh4ejp3vmfi4fr/GStreamerAudioError.zip?dl=0. Please let me know if you aren't able to reproduce.
Reply | Threaded
Open this post in threaded view
|

Re: Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

Arun Raghavan-4
In reply to this post by jml5qh
On Wed, 4 Jan 2017, at 04:01 AM, jml5qh wrote:

> Doing some testing, I can fix this issue by moving the following line
> above
> AudioOutputUnitStop in gstosxcoreaudiocommon.
> gst_core_audio_io_proc_stop:
>
>   if (core_audio->io_proc_active) {
>     gst_core_audio_remove_render_callback (core_audio);
>   }
>
> Any ideas why this would fix it? Is this just a red herring? Any thoughts
> on
> ways to fix this? TIA for any help you can provide.

As you say, there isn't really any callback to AudioUnitGetProperty in
the render callback. I wonder if there is some idiosyncrasy/bug in the
AudioUnit code that can't deal with the render callback being active + a
get property on another thread + potentially a call to stop the io_proc
from a third thread.

-- Arun
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Stopping multiple osxaudiosink instances leads to AURemoteIO IOThread error

jml5qh
I think you may be on to something Arun. One thing I also noticed was removing the pause in the ringbuffer solved the issue. Eventually, this pause leads to gst_core_audio_remove_render_callback being called. This method eventually leads to an AudioUnitSetProperty. Since it sounds like AudioUnitGetProperty is an issue, I wonder if AudioUnitSetProperty is also an issue.

My question for the GStreamer developers: How safe is it to NULL out the pause callback when you are about to stop the stream? It looks like gst_core_audio_io_proc_stop eventually calls gst_core_audio_remove_render_callback anyway. Here is the current code that seems to be working:

GstElement *audioSink = gst_bin_get_by_name(this->receiverPipeline, "audio_sink");
        if (audioSink)
        {
            GstAudioBaseSink *baseSink = GST_AUDIO_BASE_SINK_CAST(audioSink);
            GstAudioRingBuffer *theBuffer = baseSink->ringbuffer;
            GstAudioRingBufferClass *theClass = GST_AUDIO_RING_BUFFER_GET_CLASS(theBuffer);
            theClass->pause = NULL;
        }