MediaPlayer: cache file duration in memory

* SetAttribute() will fail for read-only volumes.
* Duration() is called in playlist's Draw() method.
  Since _CalculateDuration() is very expensive because it parses
  file metadata, it causes visible drawing glitches and playlist is
  almost unusable.
* Mitigates #15221. I don't consider this a fix because first draw
  is still going to block for a long time, but at least scrolling
  works smoothly now. Ideally, file metadata would be parsed
  asynchronously in a separate thread and drawn as it becomes
  available.

Change-Id: If198d61c77a7746bcc0e19b7caeed89ce829c247
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4597
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
Kacper Kasper 2021-10-17 12:35:47 +02:00 committed by Adrien Destugues
parent 3e9824f9ef
commit ba6a1df423
2 changed files with 11 additions and 3 deletions

View File

@ -45,7 +45,8 @@ static vint32 sInstanceCount = 0;
PlaylistItem::PlaylistItem()
:
fPlaybackFailed(false),
fTrackSupplier(NULL)
fTrackSupplier(NULL),
fDuration(-1)
{
#ifdef DEBUG_INSTANCE_COUNT
atomic_add(&sInstanceCount, 1);
@ -143,8 +144,14 @@ PlaylistItem::Duration()
{
bigtime_t duration;
if (GetAttribute(ATTR_INT64_DURATION, duration) != B_OK) {
duration = this->_CalculateDuration();
SetAttribute(ATTR_INT64_DURATION, duration);
if (fDuration == -1) {
duration = this->_CalculateDuration();
if (SetAttribute(ATTR_INT64_DURATION, duration) != B_OK) {
fDuration = duration;
}
} else {
duration = fDuration;
}
}
return duration;

View File

@ -127,6 +127,7 @@ private:
BList fListeners;
bool fPlaybackFailed;
TrackSupplier* fTrackSupplier;
bigtime_t fDuration;
};
typedef BReference<PlaylistItem> PlaylistItemRef;