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 672701 - mpegvideoparse: high cpu usage breaks playback of mpeg2 video in mkv on dreambox
mpegvideoparse: high cpu usage breaks playback of mpeg2 video in mkv on dreambox
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
0.10.23
Other Linux
: Normal normal
: 0.10.24
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2012-03-23 15:48 UTC by Andreas Frisch
Modified: 2012-05-22 12:56 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
mpegvideoparser: Optimize scanning for start code (2.17 KB, patch)
2012-05-09 18:36 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review
mpegvideoparser: Fix gst_mpeg_video_parse to parse a single frame (2.64 KB, patch)
2012-05-09 18:37 UTC, Nicolas Dufresne (ndufresne)
reviewed Details | Review

Description Andreas Frisch 2012-03-23 15:48:27 UTC
ftp://82.149.226.170/BrokenPlayback2.mkv
gst-launch playbin2 used to be able to play this file just fine up to 0.10.35
now it's entirely broken, if i'm lucky i get a big blocked still frame every few seconds.

playback commandline:
GST_DEBUG_NO_COLOR=1 GST_DEBUG=*:5 gst-launch playbin2 uri=file:///media/hdd/BrokenPlayback2.mkv flags=1 >log_35.log 2>&1

logfiles and pipeline graphs to be attached
Comment 1 Andreas Frisch 2012-03-23 15:53:13 UTC
ftp://test4711:test4711@82.149.226.170/bug672701_resources.tar.bz2 for the debug logs and pipeline graphs (too large for bugzilla)

test4711:test4711 is also the login for the test mkv
Comment 2 Andreas Frisch 2012-03-23 16:22:09 UTC
further experiments have shown that
gst-launch filesrc location=BrokenPlayback2.mkv ! matroskademux ! dvbvideosink
works just fine but when introducing the respective video parser element
gst-launch filesrc location=BrokenPlayback2.mkv ! matroskademux ! mpegvideoparse ! dvbvideosink
then we get the same exact error pattern like when using playbin2

the problem may be caused by excess cpu load
without the parser, playback consumes 3-6%, with playbin2 it's at full load

this problem is limited to our embedded architecture with a hardware decoder, on the pc it doesn't cause problems

and it's apparently limited to MPEG2 streams, h264parse doesn't cause this kind of problems
Comment 3 Nicolas Dufresne (ndufresne) 2012-05-09 18:36:10 UTC
Created attachment 213760 [details] [review]
mpegvideoparser: Optimize scanning for start code
Comment 4 Nicolas Dufresne (ndufresne) 2012-05-09 18:37:18 UTC
Created attachment 213761 [details] [review]
mpegvideoparser: Fix gst_mpeg_video_parse to parse a single frame

The approach is to stop processing the buffer when a complete frame has been
parsed. This is one solution, another way around could be to mimic the mpeg4
parser and only parse 1 packet per _parse() call.
Comment 5 Nicolas Dufresne (ndufresne) 2012-05-09 18:40:20 UTC
Source can also be seen at:
http://cgit.collabora.com/git/user/nicolas/gst-plugins-bad.git/log/?h=672701-mpegvideoparse-slow
Comment 6 Sebastian Dröge (slomo) 2012-05-10 13:40:21 UTC
Review of attachment 213760 [details] [review]:

Doesn't look wrong but do you also have some numbers (just curious :) )? And do the addition of new branches in the code really improve performance that much, especially as this doesn't look very friendly to branch prediction? Might make sense to use lookup table maybe?

Couldn't you use the byte reader scanning function here instead (and optimize that the same way?)?
Comment 7 Sebastian Dröge (slomo) 2012-05-10 13:50:30 UTC
Review of attachment 213761 [details] [review]:

Is this really always parsing everything up to a frame? Shouldn't it request more data from the base class if no data is left and you're not at the frames=2 break?
Comment 8 Edward Hervey 2012-05-21 12:00:36 UTC
I ran callgrind on a HD mpeg2 video file and I get the following (averaged instructions/calls)

instruction/calls    | git       | +1st patch  | +2nd patch
------------------------------------------------------------------
gst_mpeg_video_parse | 1 446 974 | 420 373     | 310 743

                                   (29.1%)     | (21.5%)


So essentially it's 5 times faster.
Comment 9 Edward Hervey 2012-05-21 12:30:06 UTC
(In reply to comment #6)
> Review of attachment 213760 [details] [review]:
> 
> Doesn't look wrong but do you also have some numbers (just curious :) )? And do
> the addition of new branches in the code really improve performance that much,
> especially as this doesn't look very friendly to branch prediction? Might make
> sense to use lookup table maybe?

  The checks are actually laid out in order of biggest probability, the branch prediction is therefore the closest to reality.
  For a perfectly random sequence, there's a 254/256 (99.2%) probability that the 3rd byte is > 1, followed by a 255/256 (99.6%) probabilty that the 2nd byte is non null. I'd say the prediction is pretty well established :)

  The impact on L1 read miss is on the same order, since you might need to "read back" (i.e. refetch) data which you don't have locally... but that only happens with a 1/128 probability.
Comment 10 Mark Nauwelaerts 2012-05-21 16:39:12 UTC
The problem seems due to the codec parsing lib here.

In the mpeg4 case the codec parser allows scanning from one start code to the next and is used as such by the parser element, which retains full state control that way (and similarly so for h264).

In the mpeg2 case the codec parser wants to parse it all and return a list of start code position.  One possible problem is that it scans more than needed.  The patch tries to prevent this by tracking some state in the codec parsing lib scan, but that is only possible if the data is always provided (to the lib) from the frame's start (otherwise it will not manage to track state properly).  However, that too is inefficient since that means always scanning from the start.

So, IMO, the mpeg1/2 codec lib should preferably be adjusted more in line with the others.
Comment 11 Tim-Philipp Müller 2012-05-21 16:50:45 UTC
> So, IMO, the mpeg1/2 codec lib should preferably be adjusted more in line with
> the others.

+1 (and perhaps we could get rid of the GList stuff too somehow?)
Comment 12 Mark Nauwelaerts 2012-05-22 12:53:56 UTC
So done:

[0.10]
commit 100fddfbe913ad0fc87b13231473b7024f521337
Author: Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Date:   Tue May 22 14:00:36 2012 +0200

    mpegvideoparse: tweak codec parser API and adjust parser element
    
    ... to allow for more efficient parsing and (more) consistent parsing API
    among various codec parsers.
    
    Fixes #672701.
Comment 13 Mark Nauwelaerts 2012-05-22 12:56:59 UTC
[0.11]
commit 28f3858b94c19929bf6eeb1ebb4442cdee0e46b2
Author: Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Date:   Tue May 22 14:00:36 2012 +0200

    mpegvideoparse: tweak codec parser API and adjust parser element
    
    ... to allow for more efficient parsing and (more) consistent parsing API
    among various codec parsers.
    
    Fixes #672701.
    
    Conflicts:
    
        gst/videoparsers/gstmpegvideoparse.c