Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High sample rate wavpack fails, higher sample rate crashes #6302

Open
ckolivas opened this issue Mar 7, 2019 · 2 comments
Open

High sample rate wavpack fails, higher sample rate crashes #6302

ckolivas opened this issue Mar 7, 2019 · 2 comments

Comments

@ckolivas
Copy link

ckolivas commented Mar 7, 2019

System information

  • Operating System: Ubuntu 18.10
  • Clementine version: Latest from git, 69a3a08a5a4eb3a03c2f7ce498f4ef5af8320d62

Expected behaviour / actual behaviour

Playback of 176.4kHz and higher sample rates should be transparent. 176.4 stutters badly, stalling for many seconds at a time despite plenty of CPU reserve and the same file playing back fine on other media players (such as mpv.) 352.8kHz and higher sample rates (eg 705600) outright crash the player with some kind of gstreamer error

15:21:38.303 ERROR logging:56                       gst_audio_decoder_finish_frame: assertion 'buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info)' failed 
15:21:38.303 ERROR logging:56                       gst_audio_decoder_finish_frame: assertion 'buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info)' failed 
15:21:38.303 ERROR MoodbarPipeline:133              Error processing  QUrl( "file:///home/con/Code/sox/mother24_352.wv" )  : "Internal data stream error." 
15:21:38.303 DEBUG GstEnginePipeline:549            1 sync bus message error 
15:21:38.303 ERROR GstEnginePipeline:658            1 "gstbaseparse.c(3611): gst_base_parse_loop (): /GstPipeline:pipeline/GstURIDecodeBin:uridecodebin-0/GstDecodeBin:decodebin1/GstWavpackParse:wavpackparse0:
streaming stopped, reason error (-5)" 
15:21:38.303 DEBUG GstEnginePipeline:549            1 sync bus message duration-changed 
15:21:38.303 ERROR MoodbarPipeline:133              Error processing  QUrl( "file:///home/con/Code/sox/mother24_352.wv" )  : "No valid frames decoded before end of stream" 
15:21:38.303 DEBUG GstEnginePipeline:549            1 sync bus message error 
15:21:38.303 ERROR GstEnginePipeline:658            1 "gstaudiodecoder.c(2263): gst_audio_decoder_sink_eventfunc (): /GstPipeline:pipeline/GstURIDecodeBin:uridecodebin-0/GstDecodeBin:decodebin1/GstWavpackDec:wavpackdec1:
no valid frames found" 

(clementine:11281): GStreamer-CRITICAL **: 15:21:38.304: gst_caps_get_structure: assertion 'GST_IS_CAPS (caps)' failed

(clementine:11281): GStreamer-CRITICAL **: 15:21:38.304: gst_structure_get_int: assertion 'structure != NULL' failed

(clementine:11281): GStreamer-CRITICAL **: 15:21:38.304: gst_mini_object_unref: assertion '
mini_object != NULL' failed

Backtrace:

(gdb) bt full
#0  0x00005648810ed334 in MoodbarBuilder::Init(int, int) (this=0x0, bands=bands@entry=128, rate_hz=0) at /home/con/Code/Clementine/src/moodbar/moodbarbuilder.cpp:40
        barkband = <optimised out>
#1  0x0000564880f12ac0 in MoodbarPipeline::NewPadCallback(_GstElement*, _GstPad*, void*) (pad=0x5648842eb500, data=0x5648838df3e0) at /home/con/Code/Clementine/src/moodbar/moodbarpipeline.cpp:155
        self = 0x5648838df3e0
        audiopad = <optimised out>
        __PRETTY_FUNCTION__ = "static void MoodbarPipeline::NewPadCallback(GstElement*, GstPad*, gpointer)"
        rate = 0
        caps = 0x0
        structure = <optimised out>
#2  0x00007f886ca43dae in ffi_call_unix64 () at ../src/x86/unix64.S:76
#3  0x00007f886ca4371f in ffi_call (cif=<optimised out>, fn=<optimised out>, rvalue=<optimised out>, avalue=<optimised out>) at ../src/x86/ffi64.c:525
        classes = {X86_64_INTEGER_CLASS, X86_64_NO_CLASS, 3385357616, 32647}
        stack = <optimised out>
        argp = <optimised out>
        arg_types = <optimised out>
        gprcount = 3
        ssecount = <optimised out>
        ngpr = 1
        nsse = 0
        i = <optimised out>
        avn = <optimised out>
        ret_in_memory = <optimised out>
        reg_args = <optimised out>
#4  0x00007f8874d5b901 in g_cclosure_marshal_generic () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#5  0x00007f8874d5b10d in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#6  0x00007f8874d6e05e in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#7  0x00007f8874d76715 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8  0x00007f8874d7712f in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007f88744df8b8 in gst_element_add_pad () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#10 0x00007f886ca43dae in ffi_call_unix64 () at ../src/x86/unix64.S:76
#11 0x00007f886ca4371f in ffi_call (cif=<optimised out>, fn=<optimised out>, rvalue=<optimised out>, avalue=<optimised out>) at ../src/x86/ffi64.c:525
        classes = {X86_64_INTEGER_CLASS, 32647, 3385359440, 32647}
        stack = <optimised out>
        argp = <optimised out>
        arg_types = <optimised out>
        gprcount = 3
        ssecount = <optimised out>
        ngpr = 1
        nsse = 0
        i = <optimised out>
        avn = <optimised out>
        ret_in_memory = <optimised out>
        reg_args = <optimised out>
#12 0x00007f8874d5b901 in g_cclosure_marshal_generic () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007f8874d5b10d in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007f8874d6e05e in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007f8874d76715 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#16 0x00007f8874d7712f in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#17 0x00007f88744df8b8 in gst_element_add_pad () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#18 0x00007f87f04bb171 in  () at /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstplayback.so
#19 0x00007f87f04bbee0 in  () at /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstplayback.so
#20 0x00007f88744f9093 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#21 0x00007f8874a71774 in g_hook_list_marshal () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#22 0x00007f88744f7635 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#23 0x00007f88744fa553 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#24 0x00007f88744faa49 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#25 0x00007f88744f84c0 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#26 0x00007f887450497f in gst_pad_push_event () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#27 0x00007f8874fccb3a in  () at /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0
#28 0x00007f8874fd19fb in  () at /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0
#29 0x00007f88744fa1a7 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#30 0x00007f88744fa621 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#31 0x00007f88744faa49 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#32 0x00007f88744f84c0 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#33 0x00007f887450497f in gst_pad_push_event () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#34 0x00007f88747e56d3 in  () at /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0
#35 0x00007f887452ff79 in  () at /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#36 0x00007f8874aa9ad0 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#37 0x00007f8874aa9105 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#38 0x00007f8873bf96db in start_thread (arg=0x7f87c9c89700) at pthread_create.c:463
        pd = 0x7f87c9c89700
        now = <optimised out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140221182678784, 6926702494423290771, 140221182675904, 0, 140221287296560, 140221540256816, -6976352172889238637, -6975952372523756653}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimised out>
#39 0x00007f8870a1488f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Steps to reproduce the problem (only for bugs)

Create a 176 and 352 kHz 24 bit wavpack file from an existing file:
sox input.wav -b 24 output176.wv rate 176400
sox input.wav -b 24 output352.wv rate 352800

Add output files to playlist then playback.

@jbroadus
Copy link
Contributor

I am able to reproduce this. Clementine is handling a pad-added signal after it has already handled the error message from GST. In the pad-added handler, it tries to call a method in a member that was freed in the error handler.

jbroadus added a commit to jbroadus/Clementine that referenced this issue Mar 11, 2019
As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewBufferCallback), this object
is accessed.

This change adds a MoodbarPipeline::IsRunning that uses the existance of builder_
to determine if the pipeline should be running. In NewBufferCallback, check the
result of that method before doing anything else.

See clementine-player#6302
jbroadus added a commit to jbroadus/Clementine that referenced this issue Mar 18, 2019
As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewPadCallback), this object
is accessed.

This change adds a running_ flag that we is set when the pipeline is started and
cleared on an error. We check this flag at the beginning of NewPadCallback. For
sanity sake, we also check the builder_ pointer before dereferencing.

This solution is not complete as there still some syncronization issues. With
this specific situation, the error and new pad callbacks appear to always occur
on the same thread, but it's probably not true for all error conditions. The
object is also destroyed by a different thread, so it's possible that an async
callback may occur at the wrong time during the deletion of the object.

See clementine-player#6302
jbroadus added a commit to jbroadus/Clementine that referenced this issue Mar 18, 2019
As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewPadCallback), this object
is accessed.

This change adds a running_ flag that is set when the pipeline is started and
cleared on an error, end of stream, or object destruction. We check this flag at
the beginning of NewPadCallback. For sanity sake, we also check the builder_
pointer before dereferencing. Note that checking the state of the pipeline
wasn't an option since the pipeline is in the process of changing states during
the pad-added callback and gst_element_get_state wants to block during a state
change.

This solution is not complete as there are still some syncronization issues.
With this specific situation, the error and new pad callbacks appear to always
occur on the same thread, but that's probably not true for all error conditions.
The object is also destroyed by a different thread, so it may be possible that a
callback can occur at the wrong time during or after the deletion of the object.

See clementine-player#6302
@jbroadus
Copy link
Contributor

Note that PR 6308 only addresses the crash reported here.

sjohannes pushed a commit to exaile/moodbar that referenced this issue Jun 22, 2019
(Patch taken from Clementine rev 55edcf5321051e44281f067a7e3ee44871982c12.
The following is the original commit message.)

As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewPadCallback), this object
is accessed.

This change adds a running_ flag that is set when the pipeline is started and
cleared on an error, end of stream, or object destruction. We check this flag at
the beginning of NewPadCallback. For sanity sake, we also check the builder_
pointer before dereferencing. Note that checking the state of the pipeline
wasn't an option since the pipeline is in the process of changing states during
the pad-added callback and gst_element_get_state wants to block during a state
change.

This solution is not complete as there are still some syncronization issues.
With this specific situation, the error and new pad callbacks appear to always
occur on the same thread, but that's probably not true for all error conditions.
The object is also destroyed by a different thread, so it may be possible that a
callback can occur at the wrong time during or after the deletion of the object.

See clementine-player/Clementine#6302
sjohannes pushed a commit to exaile/moodbar that referenced this issue Aug 31, 2020
As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewPadCallback), this object
is accessed.

This change adds a running_ flag that is set when the pipeline is started and
cleared on an error, end of stream, or object destruction. We check this flag at
the beginning of NewPadCallback. For sanity sake, we also check the builder_
pointer before dereferencing. Note that checking the state of the pipeline
wasn't an option since the pipeline is in the process of changing states during
the pad-added callback and gst_element_get_state wants to block during a state
change.

This solution is not complete as there are still some syncronization issues.
With this specific situation, the error and new pad callbacks appear to always
occur on the same thread, but that's probably not true for all error conditions.
The object is also destroyed by a different thread, so it may be possible that a
callback can occur at the wrong time during or after the deletion of the object.

See clementine-player/Clementine#6302
sjohannes pushed a commit to exaile/moodbar that referenced this issue Aug 31, 2020
(Patch taken from Clementine rev 55edcf5321051e44281f067a7e3ee44871982c12.
The following is the original commit message.)

As reported in issue 6302, playing a stream that causes gstreamer to error at
start can cause a crash. The problem occurs when the MoodbarPipeline receives a
pad-added signal after it has handled an error callback. In the error callback,
the builder_ is freed. In the pad-added handler (NewPadCallback), this object
is accessed.

This change adds a running_ flag that is set when the pipeline is started and
cleared on an error, end of stream, or object destruction. We check this flag at
the beginning of NewPadCallback. For sanity sake, we also check the builder_
pointer before dereferencing. Note that checking the state of the pipeline
wasn't an option since the pipeline is in the process of changing states during
the pad-added callback and gst_element_get_state wants to block during a state
change.

This solution is not complete as there are still some syncronization issues.
With this specific situation, the error and new pad callbacks appear to always
occur on the same thread, but that's probably not true for all error conditions.
The object is also destroyed by a different thread, so it may be possible that a
callback can occur at the wrong time during or after the deletion of the object.

See clementine-player/Clementine#6302
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants