[Bug 783314] Playbin Repeat play / pause , video playback hangs

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Tue Jun 20 06:41:33 UTC 2017


https://bugzilla.gnome.org/show_bug.cgi?id=783314

--- Comment #9 from shakin at outlook.com <shakin at outlook.com> ---
Created attachment 354076
  --> https://bugzilla.gnome.org/attachment.cgi?id=354076&action=edit
audioringbuffer-Playbin-Repeat-play-pause-playback-hangs.patch

This patch can work for me.please review it.
The problem is subtle.

Audio render was requesting to write in ringbuffer,which is suspended by a
pause request,that interrupts a complete segment write.
----
01-02 07:14:18.536 25519 25906 D  [gstaudioringbuffer.c:1574] <ringbuffer>
pointer at 8744, write to 8754-0, diff 10, segtotal 10, segsize 3528, base 0
01-02 07:14:18.536 25519 25906 D  [gstaudioringbuffer.c:1395] <ringbuffer> not
allowed to start
01-02 07:14:18.536 25519 25906 D  [gstaudioringbuffer.c:1661] <ringbuffer>
stopped processing
01-02 07:14:18.536 25519 25906 D  [gstaudiobasesink.c:2200] <audiobasesink>
wrote 913 of 941
01-02 07:14:18.536 25519 25906 D  [gstbasesink.c:2265] <basesink> waiting in
preroll for flush or PLAYING
....
01-02 07:14:20.397 25519 25906 D  [gstaudiobasesink.c:2200] <audiobasesink>
wrote 0 of 28
...
01-02 07:14:20.907 25519 25906 D  [gstaudiobasesink.c:2200] <audiobasesink>
wrote 0 of 28
...
01-02 07:14:21.330 25519 25906 D  [gstaudiobasesink.c:2200] <audiobasesink>
wrote 0 of 28
...
01-02 07:14:21.848 25519 25906 D  [gstaudiobasesink.c:2200] <audiobasesink>
wrote 0 of 28
...
-----
As shown in the log,
*At Nth time, in PLAYING, desired write segment length=941,
Paused, actually written length=913

diff == segtotal,There is not enough space,to wait for the ringbuffer to have
the remaining space, that is, the device consumes the data in the ringbuffer.

*At (N+1)th time,PAUSED,desired write left segment length=28,
But in the consumer
thread(openslesringbuffer.c:_opensles_player_cb()->gst_audio_ring_buffer_prepare_read()),
we judge the ringbuffer state,fail when nothing is started and just return, let
opensles does not read any data.

Let's take a look at the opensles callback function call stack and see what
happens,
----
#0  android::AudioTrack::stop (this=0xab2a0d00) at
frameworks/av/media/libmedia/AudioTrack.cpp:548
#1  0xf410cd84 in audioTrack_callBack_pullFromBuffQueue (event=<optimized out>,
user=0xabeb2c00, info=<optimized out>)
    at frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:1264
#2  0xf75ab180 in android::AudioTrack::processAudioBuffer (this=0xab2a0d00) at
frameworks/av/media/libmedia/AudioTrack.cpp:1782
#3  0xf75ab36c in android::AudioTrack::AudioTrackThread::threadLoop
(this=0xab29a758) at frameworks/av/media/libmedia/AudioTrack.cpp:2145
#4  0xf749e576 in android::Thread::_threadLoop (user=0xab29a758) at
system/core/libutils/Threads.cpp:776
#5  0xf749e0e6 in thread_data_t::trampoline (t=<optimized out>) at
system/core/libutils/Threads.cpp:101
#6  0xf76d763c in __pthread_start (arg=0xabe8fc00, arg at entry=<error reading
variable: value has been optimized out>)
    at bionic/libc/bionic/pthread_create.cpp:141
#7  0xf76d5568 in __start_thread (fn=<optimized out>, arg=<optimized out>) at
bionic/libc/bionic/clone.cpp:41
#8  0x00000000 in ?? ()
(gdb) bt full
#0  android::AudioTrack::stop (this=0xab2a0d00) at
frameworks/av/media/libmedia/AudioTrack.cpp:548
        lock = {mLock = @0xab2a0ef4}
        t = {m_ptr = 0xab29a758}
#1  0xf410cd84 in audioTrack_callBack_pullFromBuffQueue (event=<optimized out>,
user=0xabeb2c00, info=<optimized out>)
    at frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:1264
        prefetchCallback = 0x0
        prefetchContext = 0x0
        prefetchEvents = 0
        pBuff = <optimized out>
        callbackPContext = <optimized out>
        info = <optimized out>
        user = 0xabeb2c00
        event = <optimized out>
#2  0xf75ab180 in android::AudioTrack::processAudioBuffer (this=0xab2a0d00) at
frameworks/av/media/libmedia/AudioTrack.cpp:1782
        nonContig = 944
        err = <optimized out>
        avail = <optimized out>
        reqSize = 480
        audioBuffer = {frameCount = 120, size = 0, {raw = 0xed54f180, i16 =
0xed54f180, i8 = 0xed54f180 "*"}}
        writtenSize = <optimized out>
        releasedFrames = <optimized out>
        active = true
        markerReached = <optimized out>
        newPosition = <optimized out>
        updatePeriod = <optimized out>
        sequence = 1
        requested = <optimized out>
        newPosCount = <optimized out>
        sampleRate = 44100
        notificationFrames = 940
        waitStreamEnd = false
        loopPeriod = 0
---
In SLES of context PLAYING state, because there is no data to read(Actually we
have at least 28byte, but the ringbuffer limit is not written yet), AudioTrack
suspended the thread, waiting for the next time there is data recovery, so
callback function _opensles_player_cb will not be implemented.

So the problem occurs, the producer thread needs to write data without space
and wait to be consumed, and the consumer thread because of a wrong state
judge, did not read the data and suspended the callback function, leading to
this state will continue forever until someone flushing ringbuffer or exit.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list