Bass.BASS_ChannelGetData never returns and halts execution.

Started by Chris Oakley,

Chris Oakley

We're having a lot of trouble lately with FLAC files. One of the latest issues is that the BASS_ChannelGetData hangs and never returns.

In VB.NET if you have this sub:
    Private Sub ConvertOpus()

        Dim _sourcefile As String = "532220.flac"
        Dim _destfile As String = "532220.opus" 'Set the destination file.
        Dim _stream As Integer = 0 'Holds the stream id.
        Dim _mixer As Integer = 0 'Holds the mixer.
        _stream = Bass.BASS_StreamCreateFile(_sourcefile, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_STREAM_PRESCAN) 'Open the file.
        If _stream <> 0 Then 'Opened.
            Dim _bitrate As Integer = 128 'Set the bitrate.
            Dim _encoderid As Integer = 0 'Holds the encoder id.
            _mixer = BassMix.BASS_Mixer_StreamCreate(48000, 2, BASSFlag.BASS_STREAM_DECODE) 'Make a mixer with options.
            If _mixer <> 0 Then 'Mixer created.
                If BassMix.BASS_Mixer_StreamAddChannel(_mixer, _stream, BASSFlag.BASS_DEFAULT) Then 'Add the stream to the mixer.
                    Dim _cmd As String = $"opusenc.exe --downmix-mono --bitrate {_bitrate} --hard-cbr --raw --raw-bits=16 --raw-rate=48000 --raw-chan=2 --ignorelength --raw-endianness 0 - ""{_destfile}"
                    _encoderid = BassEnc.BASS_Encode_Start(_mixer, _cmd, BASSEncode.BASS_ENCODE_NOHEAD, Nothing, IntPtr.Zero)
                    If _encoderid <> 0 Then 'The encoder was started.
                        Dim _buffer(32767) As Byte '32KB buffer.
                        Dim _bytesRead As Integer = 0 'The bytes that will be read.
                        Do 'Loop.
                            _bytesRead = Bass.BASS_ChannelGetData(_mixer, _buffer, _buffer.Length) 'Get data into buffer which will process the encoder and write the data to the file.
                        Loop While _bytesRead > 0 'Until there is no more channel data to write to the encoder.
                        BassEnc.BASS_Encode_Stop(_encoderid) 'Stop the encoder. This can be the stream id or the encoder id - it doesn't matter.
                    End If
                End If
            End If
        End If
        Bass.BASS_StreamFree(_mixer) 'Close the mixer.
        Bass.BASS_StreamFree(_stream) 'Close the file.

    End Sub

and you call it like this as a test:
        Do
            Debug.Print(Now.ToString)
            ConvertOpus()
            Application.DoEvents()
        Loop

Eventually, after a period of time which could be 2 hours, the application stops responding and pausing the execution shows the line it's stuck on which is:
_bytesRead = Bass.BASS_ChannelGetData(_mixer, _buffer, _buffer.Length)

Which is in the Do Loop in the ConvertOpus() sub.

I don't understand why it just decides to stop, after working over and over. It's nothing to do with Opus because it's the same if you encode to Mp3 as well. It's something to do with FLAC files as a source and it makes no difference if I load the bassflac.dll with Bass.BASS_PluginLoad.

We are using the latest DLLs from the website.

I can't attach the FLAC file I'm using because it's size if 13Mb, but I can provide it on request.

Ian @ un4seen

From the "after a period of time which could be 2 hours" comment, does that mean the problem doesn't happen every time you run that code on the FLAC file? To confirm that the problem is unrelated to the encoding (which is within the BASS_ChannelGetData call), please try removing the BASS_Encode_Start call. Also confirm what decoder is being used by checking the stream's "ctype" value with BASS_ChannelGetInfo.

Is the problem affecting all FLAC files or only a particular one? You can upload an affected file to check here:

   ftp://ftp.un4seen.com/incoming/

Ian @ un4seen

Actually, I think the first thing to do is get a dump file of the frozen app, which you can do with Visual Studio's "Debug > Save Dump As" menu option after pausing execution. Please ZIP and upload the dump file to have a look at here:

    ftp://ftp.un4seen.com/incoming/

Chris Oakley

Thanks Ian. I've uploaded the file in question, it should be available to you. Let me know if it isn't and I'll try again.

Yes the problem doesn't happen all the time and the only common theme is the files that do cause the issue are FLAC files. I've used the same file over and over here to narrow down everything.

I removed the BASS_Encode_Start as suggested and of course the If block which would bypass the Do Loop with the BASS_ChannelGetData, but it's still happening and hanging on the GetData.

The dmp file is incoming.

Ian @ un4seen

Thanks. The dump file shows that it's in Media Foundation. The Media Foundation FLAC decoder is known to be a bit dodgy, so I would highly recommend using the BASSFLAC add-on (via BASS_PluginLoad) instead. You mentioned that you already tried BASSFLAC, but please try it again and get a dump file from that case too.

Chris Oakley

Okay, I'm trying that now. I will advise.

While I'm doing that, can I ask about this. If we're loading bassflac.dll via the PluginLoad, does that mean the ffmpeg.exe is redundant. Is that what you're saying the issue is, in that the ffmpeg is causing the problem?

Ian @ un4seen

No, Media Foundation is part of Windows:

    https://en.wikipedia.org/wiki/Media_Foundation

BASS will try Media Foundation decoders whenever the built-in and plugin decoders are unable to handle a file. If you know you won't ever need Media Foundation, it can be disabled via the BASS_CONFIG_MF_DISABLE option.

Chris Oakley

Thanks for that. I wouldn't like to disable it as I don't understand it. I don't want to create more problems. However, I've been running a test after loading the bassflac.dll via PluginLoad and so for it's okay. Will keep monitoring.

I presume we only have to load the dll once at the start of the app and not all the time, even in different threads?

Ian @ un4seen

Yeah, you would only need to load any add-ons via BASS_PluginLoad once, and then they can be used in BASS_StreamCreateFile/etc calls in any thread.

The main benefit of Media Foundation is AAC/MP4 support, so if you need that then best to keep it enabled.