After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 727779 - avdec_h264, matroskademux: crash while seeking (1.2 regression)
avdec_h264, matroskademux: crash while seeking (1.2 regression)
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-libav
1.x
Other Linux
: Normal blocker
: 1.2.4
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 726835 727794 728235 729014 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-04-07 20:44 UTC by Jürg Billeter
Modified: 2014-06-21 18:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GDB log (32.67 KB, text/plain)
2014-04-08 09:40 UTC, Jan Alexander Steffens (heftig)
  Details
avvidec: guard against invalid libav opaque (3.36 KB, patch)
2014-04-15 19:39 UTC, Mark Nauwelaerts
committed Details | Review

Description Jürg Billeter 2014-04-07 20:44:16 UTC
Since the upgrade from 1.2.2 to 1.2.3, totem crashes frequently when seeking in H264 mkv files. Sometimes but not always, one of the following messages appears right before the segmentation fault:

CRITICAL **: gst_video_codec_frame_unref: assertion
'frame->ref_count > 0' failed

CRITICAL **: gst_video_codec_frame_ref: assertion
'frame != NULL' failed

Based on my limited testing, it appears that this regression was introduced with the fix for bug 682276, i.e., reverting commit 525539aa solves the issue here.

I don't have a proper backtrace from my system at hand, however, there is one in a Debian bug report about this issue: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=739579
Comment 1 Jan Alexander Steffens (heftig) 2014-04-08 09:40:47 UTC
Created attachment 273773 [details]
GDB log

I think I triggered this in a gst-launch pipeline:

gst-launch-1.0 -m -v tcpclientsrc ! queue2 ring-buffer-max-size=10000000 ! matroskademux name=dem ! video/x-raw ! mq.sink_0 multiqueue name=mq use-buffering=true max-size-bytes=0 max-size-buffers=0 max-size-time=1000000000 dem. ! audio/x-raw ! mq.sink_1 mq.src_0 ! identity silent=0 ! navseek seek-offset=1 ! xvimagesink mq.src_1 ! audioconvert ! alsasink

(It receives a Matroska stream containing video/x-raw and audio/x-raw streams.)

GDB log attached; note thread 8 (nav event -> navseek -> seek event -> matroskademux -> pad_pull_range -> queue2) crashing in a memcpy.
Comment 2 Tim-Philipp Müller 2014-04-09 18:28:00 UTC
I think that matroskademux commit just exposes a bug in gst-libav/libav and makes it more likely to run into that when seeking.

I'm marking this as blocker for now, we should really try to fix this for 1.2.4. If we can't fix it we should revert the matroskademux commit to at least soften the impact, so that it only happens in cornercases and not all the time.

The issue is fixed in gst-libav master which uses libav v10, for what it's worth, this only affects the 1.2 branch with libav v9.

The problem was introduced or exposed between libav v9.10 and v9.11 by this commit:

  commit 0e8ae6d10c609bb968c141aa2436413a55852590
  Author: Luca Barbato <lu_zero@gentoo.org>
  Date:   Tue Oct 22 19:17:10 2013 +0200

    mpegvideo: Drop a faulty assert
    
    That check is easily reachable by faulty input.
    
    CC:libav-stable@libav.org
    Reported-by: Torsten Sadowski <tsadowski@gmx.net>
    (cherry picked from commit 72072bf9de3241848ea86f68d2297b7a5d6ad49b)
    Signed-off-by: Reinhard Tartler <siretart@tauware.de>

which returns an assert on faulty input into a return AVERROR_INVALIDDATA;

I suspect by default the assert() was compiled out for releases and so didn't trigger, and the rest of the code just coped, but now an INVALIDDATA error is propagated, and gst-libav messes up its frame refcounting somewhere (that's my guess anyway; I more often than not get critical assertions about frame->refcount being > 0 which makes me think the problem is with gst-libav's frame refcounting and not buffer handling elsewhere).
Comment 3 Tim-Philipp Müller 2014-04-15 08:51:49 UTC
*** Bug 728235 has been marked as a duplicate of this bug. ***
Comment 4 Mark Nauwelaerts 2014-04-15 19:39:14 UTC
Created attachment 274396 [details] [review]
avvidec: guard against invalid libav opaque

Upon some examination it looks like libav is going a bit wrong here (not so much gst-libav).  More precisely, when flushing (due to the seek), libav releases buffers, so all attached opaque (GstFFMpegVidDecVideoFrame) are released.  Then, after the seek (due to some decoding problems?) libav comes up with a picture/frame that has an old opaque (already released), leading to the assert's and segfault.

Attached patch adds some logging to demonstrate this.  Moreover, it adds some book-keeping to check whether libav is coming up with an opaque it should not, and then logs and side-steps that one.

Resulting log confirms the above, and avoids crash (in tested mileage).
Comment 5 Tim-Philipp Müller 2014-04-15 21:25:12 UTC
Comment on attachment 274396 [details] [review]
avvidec: guard against invalid libav opaque

Hah, thanks! That would explain why I didn't spot what's wrong with our code :)

Fixes things for me, and looks minimally invalise / safe, so please push.

Thanks a lot for looking into this.
Comment 6 Mark Nauwelaerts 2014-04-16 20:11:38 UTC
Pushed to 1.2 branch.

commit bdbd29017d8b709ce851a5b5fac48de1ca27e3b2
Author: Mark Nauwelaerts <mnauw@users.sourceforge.net>
Date:   Tue Apr 15 21:32:07 2014 +0200

    avviddec: guard against invalid libav opaque
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=727779
Comment 7 Tim-Philipp Müller 2014-04-26 12:17:14 UTC
*** Bug 729014 has been marked as a duplicate of this bug. ***
Comment 8 Tim-Philipp Müller 2014-06-21 18:17:59 UTC
*** Bug 726835 has been marked as a duplicate of this bug. ***
Comment 9 Tim-Philipp Müller 2014-06-21 18:20:46 UTC
*** Bug 727794 has been marked as a duplicate of this bug. ***