Opened 5 years ago

Last modified 4 years ago

#16031 new bug

MediaPlayer uses too much RAM?

Reported by: miqlas Owned by: nobody
Priority: normal Milestone: Unscheduled
Component: Kits/Media Kit Version: R1/Development
Keywords: Cc: ttcoder
Blocked By: Blocking:
Platform: All

Description

MediaPlayer uses too much RAM while playing a playlist. To reproduce: 1) open MediaPlayer 2) Open more media file 3) check the memory usage 4) press next-previous many times (you can use pg up and down shortcuts) 5) memory usage rise. i was able to achaive over 2GB with 2 mp3.

Maybe it is just a cache.

Attachments (1)

BMediaFile-leak.cpp (1.8 KB ) - added by ttcoder 4 years ago.
Short and sweet test bench for BMediaFile and BMediaTrack

Download all attachments as: .zip

Change History (11)

comment:1 by ttcoder, 5 years ago

Hi miqlas, by RAM use do you mean...

  • ProcessController > memory usage > MediaPlayer ?
  • ActivityMonitor's graph (which one?) ?
  • Something else ?

comment:2 by miqlas, 5 years ago

@ttcoder: both ProcessController and ActivityMon shows excess ram usage.

comment:3 by ttcoder, 5 years ago

Component: Applications/MediaPlayerKits/Media Kit
Owner: changed from stippi to nobody
Platform: x86-64All

Well good find ! Downloading and trying out the "pre beta-2" image from the Haiku forum, I see that MediaPlayer does seem to have a big heap leak. (whereas the heaps of media_server and media_addon_server remain completely steady).

The leak is circa 1 MB per song, so it might be that #14047 or something similar is back with a vengeance. Which is odd since AFAICT not much has changed in the Media Kit ; maybe a tweak or two in the ffmpeg add-on? Might be too late to find and fix during this development cycle, but this should be looked into after the beta is released IMHO.

~/Desktop> uname -a
Haiku shredder 1 hrev54154+31 May 13 2020 03:10: x86_64 x86_64 Haiku
~/Desktop> listarea MediaPlayer | grep heap
...
18267                             heap  0x1115f583f000   610000   5d5000     0     0     0

EDIT:

For some reason, after a few hours of continued playback on a few dozen songs I can't get the heap usage past 11.9 MB:

~/Desktop> listarea MediaPlayer | grep heap
18267                             heap  0x1115f583f000   740000   708000     0     0     0

Will test more in a few days.

Version 1, edited 5 years ago by ttcoder (previous) (next) (diff)

comment:4 by ttcoder, 5 years ago

Cc: ttcoder added

comment:5 by waddlesplash, 4 years ago

I guess the most likely culprit here is hrev54121.

comment:6 by ttcoder, 4 years ago

Makes sense. The e.g. return B_LAST_BUFFER_ERROR; statement short circuits a bunch of stuff, including e.g. if (loadingChunkStatus == B_LAST_BUFFER_ERROR) return _FushOneVideoFrameFromDecoderBuffer(); and one needs to dig deep to know what ffmpeg routine to call when. The usual ffmpeg gimmickery... Wish they'd have written ffmpeg as object-oriented code sigh.

If no one beats me to it (:-/), after beta2 is released I'll set up an HDD (instead of just USB stick) partition to play with, and setup the usual leak_check_analyser.sh test routine to collect more data, this generally allows to save quite some debugging time.

PS - haven't seen anyone test RAM usage on other media apps, but there's been no relevant MediaPlayer change that I remember, so I'll bet it's not the culprit and ffmpeg/add-on must be the culprit, as was the case numerous times before.

comment:7 by pulkomandy, 4 years ago

Does https://review.haiku-os.org/c/haiku/+/2562 make a difference here? It fixes some of the handling of B_LAST_BUFFER_ERROR on MediaPlayer side (but is still incomplete).

As for short-circuiting "a bunch of stuff", the code you refer to is in a "if (error == AVERROR(EAGAIN))", and would not be executed if error == AVERROR_EOF. The only thing that is short circuited is _HandleNewVideoFrameAndUpdateSystemState(), which we don't want to do because there is no frame to render, if I understand things correctly?

by ttcoder, 4 years ago

Attachment: BMediaFile-leak.cpp added

Short and sweet test bench for BMediaFile and BMediaTrack

comment:8 by ttcoder, 4 years ago

Turns out gcc is not installed on this stick (probably had to work-around the stick's small 600 MiB partition size or something). Anyway, attached the now-classical test case above. Compiles in a flash, runs in a few seconds. Results take a bit of thinking to interpret, but not all that much IIRC.

(EDIT: basically, each attempt at decoding the mp3 should end by returning the memory it used, except for 80 bytes; so whatever memory usage is listed before the first decoding run is the "baseline", and any increment above and beyond 80 bytes per run is a regression IIRC)

EDIT2: note to self: try the test with both plain mp3s and mp3s that include album art

Last edited 4 years ago by ttcoder (previous) (diff)

comment:9 by ttcoder, 4 years ago

Seems there is a (small) leak regression indeed. Here's the result for 50 runs:

$ uname -a
Haiku shredder 1 hrev54154+31 May 13 2020 03:10: x86_64 x86_64 Haiku
$ gcc -g BMediaFile-leak.cpp -lbe -lmedia -lroot_debug
$ LD_PRELOAD=libroot_debug.so ./a.out > bmedia_result
$ cat bmedia_result | sort | uniq

------done decoding file-------
total allocations: 393; total bytes: 192199
total allocations: 5114; total bytes: 774543
total allocations: 5115; total bytes: 774631
total allocations: 5116; total bytes: 774719
total allocations: 5117; total bytes: 774807
total allocations: 5118; total bytes: 774895
total allocations: 5119; total bytes: 774983
total allocations: 5120; total bytes: 775071
total allocations: 5121; total bytes: 775159
total allocations: 5122; total bytes: 775247
total allocations: 5123; total bytes: 775335
total allocations: 5124; total bytes: 775423
total allocations: 5125; total bytes: 775511
total allocations: 5126; total bytes: 775599
total allocations: 5127; total bytes: 775687
total allocations: 5128; total bytes: 775775
total allocations: 5129; total bytes: 775863
total allocations: 5130; total bytes: 775951
total allocations: 5131; total bytes: 776039
total allocations: 5132; total bytes: 776127
total allocations: 5133; total bytes: 776215
total allocations: 5134; total bytes: 776303
total allocations: 5135; total bytes: 776391
total allocations: 5136; total bytes: 776479
total allocations: 5137; total bytes: 776567
total allocations: 5138; total bytes: 776655
total allocations: 5139; total bytes: 776743
total allocations: 5140; total bytes: 776831
total allocations: 5141; total bytes: 776919
total allocations: 5142; total bytes: 777007
total allocations: 5143; total bytes: 777095
total allocations: 5144; total bytes: 777183
total allocations: 5145; total bytes: 777271
total allocations: 5146; total bytes: 777359
total allocations: 5147; total bytes: 777447
total allocations: 5148; total bytes: 777535
total allocations: 5149; total bytes: 777623
total allocations: 5150; total bytes: 777711
total allocations: 5151; total bytes: 777799
total allocations: 5152; total bytes: 777887
total allocations: 5153; total bytes: 777975
total allocations: 5154; total bytes: 778063
total allocations: 5155; total bytes: 778151
total allocations: 5156; total bytes: 778239
total allocations: 5157; total bytes: 778327
total allocations: 5158; total bytes: 778415
total allocations: 5159; total bytes: 778503
total allocations: 5160; total bytes: 778591
total allocations: 5161; total bytes: 778679
total allocations: 5162; total bytes: 778767
total allocations: 5163; total bytes: 778855
total allocations: 5363; total bytes: 860087
total allocations: 5363; total bytes: 862615
total allocations: 5365; total bytes: 860263
total allocations: 5365; total bytes: 860279
total allocations: 5367; total bytes: 860455
total allocations: 5370; total bytes: 860735
total allocations: 5371; total bytes: 861447
total allocations: 5372; total bytes: 860911
total allocations: 5373; total bytes: 861623
total allocations: 5374; total bytes: 865967
total allocations: 5374; total bytes: 867007
total allocations: 5376; total bytes: 861887
total allocations: 5376; total bytes: 862495
total allocations: 5376; total bytes: 867183
total allocations: 5379; total bytes: 863367
total allocations: 5380; total bytes: 862239
total allocations: 5380; total bytes: 862847
total allocations: 5380; total bytes: 863455
total allocations: 5383; total bytes: 863719
total allocations: 5384; total bytes: 863807
total allocations: 5386; total bytes: 864591
total allocations: 5388; total bytes: 864767
total allocations: 5389; total bytes: 864247
total allocations: 5389; total bytes: 864855
total allocations: 5393; total bytes: 867639
total allocations: 5395; total bytes: 862935
total allocations: 5396; total bytes: 867295
total allocations: 5398; total bytes: 868079
total allocations: 5400; total bytes: 865823
total allocations: 5400; total bytes: 869295
total allocations: 5401; total bytes: 869383
total allocations: 5402; total bytes: 869471
total allocations: 5403; total bytes: 869559
total allocations: 5404; total bytes: 867999
total allocations: 5404; total bytes: 869647
total allocations: 5407; total bytes: 868871
total allocations: 5408; total bytes: 868959
total allocations: 5409; total bytes: 868439
total allocations: 5409; total bytes: 869047
total allocations: 5410; total bytes: 868527
total allocations: 5411; total bytes: 868615
total allocations: 5412; total bytes: 868095
total allocations: 5413; total bytes: 869399
total allocations: 5414; total bytes: 867663
total allocations: 5415; total bytes: 867143
total allocations: 5415; total bytes: 868967
total allocations: 5416; total bytes: 870703
total allocations: 5418; total bytes: 869839
total allocations: 5421; total bytes: 871143
total allocations: 5422; total bytes: 871231

The "normal" sustained leak rate is 80 bytes per BMediaFile/Track, so for 50 runs that should be 80*50=4000 bytes. Yet there is 871231 - 774543 or ca. 100'000 bytes leaked per fifty runs.

comment:10 by ttcoder, 4 years ago

However, the same test ran on an mp3 with a tiny Album Art pic yields this:

$ cat bmedia_result | sort | uniq

------done decoding file-------
total allocations: 5114; total bytes: 774543
(..)
total allocations: 5700; total bytes: 959167
total allocations: 5701; total bytes: 959255
total allocations: 5703; total bytes: 959431

I.e. 959431 - 774543 = 184888 bytes

With a bigger JPEG album art pic:

total allocations: 5114; total bytes: 774559
(..)
total allocations: 5711; total bytes: 1436471

So there a few kilobytes in play for each run indeed. Not the end of the world but will be worth me trying to build the (patched) ffmpeg add-on on x64 (never tried a build other than on x32 so far). I'll place it in /system/non-packaged/add-ons/media/plugins/ and see how it behaves... and if it gets picked up by my test-case program.

*EDIT*: errr... the sort | uniq processing used in my tests hides the fact that there are two lines output for each iteration, on different "waves" of memory allocation, so the raw (unprocessed) dump of course consists of lots of see-sawing.. If not comparing apples to oranges but just comparing apple to apple (top of each "saw"), we see 80-something increments. So bottom line, I've been unable to reproduce a _sustained_ leak so far

(emphasis on "sustained": the a.out binary gets to 37 MB memory usage in the first second of running; but who cares, if it stays that way for weeks and months)

Next I'll try on a "production" app.

If that fails to leak either, it would mean that MediaPlayer is the one that leaks, and not MediaKit I guess ; does MediaPlayer really get to 2 GiB memory heap itself ??

Last edited 4 years ago by ttcoder (previous) (diff)
Note: See TracTickets for help on using tickets.