MediaPlayer: Avoid to recreate the supplier more than needed

* MediaPlayer attempted to recreate each time the media supplier(s),
and implictly it recreated also the BMediaFile. This works fine with
local data that can be accessed fastly, but makes lots of troubles
with network streams such as BMediaIO. The result of this was that
the Streamer plugin has been recreated each time having memory and
network wasted other than performances.
* I tried to keep intact the previous logic, and it looks OK for me,
this has been done by moving out of the Controller the ownership of
the TrackSupplier and adding a little utility class that do the
releasing job previously done by the ObjectDeleter.
* Reviews are appreciated.
This commit is contained in:
Dario Casalinuovo
2016-06-30 16:54:40 +02:00
parent 936696c78a
commit 70efd0db0a
8 changed files with 109 additions and 54 deletions
+61 -36
View File
@@ -53,6 +53,31 @@
using std::nothrow; using std::nothrow;
class TrackSupplierReleaser {
public:
TrackSupplierReleaser(PlaylistItemRef& owner)
:
fOwner(owner),
fRelease(true)
{}
virtual ~TrackSupplierReleaser()
{
if (fRelease)
fOwner.Get()->ReleaseTrackSupplier();
}
void Detach()
{
fRelease = false;
}
private:
PlaylistItemRef& fOwner;
bool fRelease;
};
void void
HandleError(const char *text, status_t err) HandleError(const char *text, status_t err)
{ {
@@ -100,7 +125,6 @@ Controller::Controller()
fMuted(false), fMuted(false),
fItem(NULL), fItem(NULL),
fTrackSupplier(NULL),
fVideoSupplier(new ProxyVideoSupplier()), fVideoSupplier(new ProxyVideoSupplier()),
fAudioSupplier(new ProxyAudioSupplier(this)), fAudioSupplier(new ProxyAudioSupplier(this)),
@@ -235,13 +259,13 @@ Controller::SetTo(const PlaylistItemRef& item)
return B_OK; return B_OK;
} }
fItem = item;
fAudioSupplier->SetSupplier(NULL, fVideoFrameRate); fAudioSupplier->SetSupplier(NULL, fVideoFrameRate);
fVideoSupplier->SetSupplier(NULL); fVideoSupplier->SetSupplier(NULL);
ObjectDeleter<TrackSupplier> oldTrackSupplierDeleter(fTrackSupplier); if (fItem != NULL)
fTrackSupplier = NULL; TrackSupplierReleaser oldSupplierReleaser(fItem);
fItem = item;
// Do not delete the supplier chain until after we called // Do not delete the supplier chain until after we called
// NodeManager::Init() to setup a new media node chain // NodeManager::Init() to setup a new media node chain
@@ -266,12 +290,12 @@ Controller::SetTo(const PlaylistItemRef& item)
if (fItem.Get() == NULL) if (fItem.Get() == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
TrackSupplier* trackSupplier = fItem->CreateTrackSupplier(); TrackSupplier* trackSupplier = fItem->GetTrackSupplier();
if (trackSupplier == NULL) { if (trackSupplier == NULL) {
_NotifyFileChanged(item.Get(), B_NO_MEMORY); _NotifyFileChanged(item.Get(), B_NO_MEMORY);
return B_NO_MEMORY; return B_NO_MEMORY;
} }
ObjectDeleter<TrackSupplier> trackSupplierDeleter(trackSupplier); TrackSupplierReleaser trackSupplierReleaser(fItem);
status_t err = trackSupplier->InitCheck(); status_t err = trackSupplier->InitCheck();
if (err != B_OK) { if (err != B_OK) {
@@ -286,20 +310,17 @@ Controller::SetTo(const PlaylistItemRef& item)
return B_MEDIA_NO_HANDLER; return B_MEDIA_NO_HANDLER;
} }
fTrackSupplier = trackSupplier;
SelectAudioTrack(0); SelectAudioTrack(0);
SelectVideoTrack(0); SelectVideoTrack(0);
if (fAudioTrackSupplier == NULL && fVideoTrackSupplier == NULL) { if (fAudioTrackSupplier == NULL && fVideoTrackSupplier == NULL) {
printf("Controller::SetTo: no audio or video tracks found or " printf("Controller::SetTo: no audio or video tracks found or "
"no decoders\n"); "no decoders\n");
fTrackSupplier = NULL;
_NotifyFileChanged(item.Get(), B_MEDIA_NO_HANDLER); _NotifyFileChanged(item.Get(), B_MEDIA_NO_HANDLER);
return B_MEDIA_NO_HANDLER; return B_MEDIA_NO_HANDLER;
} }
trackSupplierDeleter.Detach(); trackSupplierReleaser.Detach();
// prevent blocking the creation of new overlay buffers // prevent blocking the creation of new overlay buffers
if (fVideoView) if (fVideoView)
@@ -423,8 +444,8 @@ Controller::AudioTrackCount()
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier != NULL) if (fItem != NULL && fItem->HasTrackSupplier())
return fTrackSupplier->CountAudioTracks(); return fItem->GetTrackSupplier()->CountAudioTracks();
return 0; return 0;
} }
@@ -434,8 +455,8 @@ Controller::VideoTrackCount()
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier != NULL) if (fItem != NULL && fItem->HasTrackSupplier())
return fTrackSupplier->CountVideoTracks(); return fItem->GetTrackSupplier()->CountVideoTracks();
return 0; return 0;
} }
@@ -445,8 +466,8 @@ Controller::SubTitleTrackCount()
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier != NULL) if (fItem != NULL && fItem->HasTrackSupplier())
return fTrackSupplier->CountSubTitleTracks(); return fItem->GetTrackSupplier()->CountSubTitleTracks();
return 0; return 0;
} }
@@ -455,11 +476,12 @@ status_t
Controller::SelectAudioTrack(int n) Controller::SelectAudioTrack(int n)
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
ObjectDeleter<AudioTrackSupplier> deleter(fAudioTrackSupplier); ObjectDeleter<AudioTrackSupplier> deleter(fAudioTrackSupplier);
fAudioTrackSupplier = fTrackSupplier->CreateAudioTrackForIndex(n); fAudioTrackSupplier
= fItem->GetTrackSupplier()->CreateAudioTrackForIndex(n);
if (fAudioTrackSupplier == NULL) if (fAudioTrackSupplier == NULL)
return B_BAD_INDEX; return B_BAD_INDEX;
@@ -505,11 +527,12 @@ Controller::SelectVideoTrack(int n)
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier); ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier);
fVideoTrackSupplier = fTrackSupplier->CreateVideoTrackForIndex(n); fVideoTrackSupplier
= fItem->GetTrackSupplier()->CreateVideoTrackForIndex(n);
if (fVideoTrackSupplier == NULL) if (fVideoTrackSupplier == NULL)
return B_BAD_INDEX; return B_BAD_INDEX;
@@ -550,11 +573,12 @@ Controller::SelectSubTitleTrack(int n)
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
fSubTitlesIndex = n; fSubTitlesIndex = n;
fSubTitles = fTrackSupplier->SubTitleTrackForIndex(n); fSubTitles =
fItem->GetTrackSupplier()->SubTitleTrackForIndex(n);
const SubTitle* subTitle = NULL; const SubTitle* subTitle = NULL;
if (fSubTitles != NULL) if (fSubTitles != NULL)
@@ -586,10 +610,11 @@ Controller::SubTitleTrackName(int n)
{ {
BAutolock _(this); BAutolock _(this);
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return NULL; return NULL;
const SubTitles* subTitles = fTrackSupplier->SubTitleTrackForIndex(n); const SubTitles* subTitles
= fItem->GetTrackSupplier()->SubTitleTrackForIndex(n);
if (subTitles == NULL) if (subTitles == NULL)
return NULL; return NULL;
@@ -800,7 +825,7 @@ bool
Controller::HasFile() Controller::HasFile()
{ {
// you need to hold the data lock // you need to hold the data lock
return fTrackSupplier != NULL; return fItem != NULL && fItem->HasTrackSupplier();
} }
@@ -808,9 +833,9 @@ status_t
Controller::GetFileFormatInfo(media_file_format* fileFormat) Controller::GetFileFormatInfo(media_file_format* fileFormat)
{ {
// you need to hold the data lock // you need to hold the data lock
if (!fTrackSupplier) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
return fTrackSupplier->GetFileFormatInfo(fileFormat); return fItem->GetTrackSupplier()->GetFileFormatInfo(fileFormat);
} }
@@ -818,9 +843,9 @@ status_t
Controller::GetCopyright(BString* copyright) Controller::GetCopyright(BString* copyright)
{ {
// you need to hold the data lock // you need to hold the data lock
if (!fTrackSupplier) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
return fTrackSupplier->GetCopyright(copyright); return fItem->GetTrackSupplier()->GetCopyright(copyright);
} }
@@ -890,9 +915,9 @@ status_t
Controller::GetMetaData(BMessage* metaData) Controller::GetMetaData(BMessage* metaData)
{ {
// you need to hold the data lock // you need to hold the data lock
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
return fTrackSupplier->GetMetaData(metaData); return fItem->GetTrackSupplier()->GetMetaData(metaData);
} }
@@ -900,9 +925,9 @@ status_t
Controller::GetVideoMetaData(int32 index, BMessage* metaData) Controller::GetVideoMetaData(int32 index, BMessage* metaData)
{ {
// you need to hold the data lock // you need to hold the data lock
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
return fTrackSupplier->GetVideoMetaData(index, metaData); return fItem->GetTrackSupplier()->GetVideoMetaData(index, metaData);
} }
@@ -910,9 +935,9 @@ status_t
Controller::GetAudioMetaData(int32 index, BMessage* metaData) Controller::GetAudioMetaData(int32 index, BMessage* metaData)
{ {
// you need to hold the data lock // you need to hold the data lock
if (fTrackSupplier == NULL) if (fItem == NULL || !fItem->HasTrackSupplier())
return B_NO_INIT; return B_NO_INIT;
return fTrackSupplier->GetAudioMetaData(index, metaData); return fItem->GetTrackSupplier()->GetAudioMetaData(index, metaData);
} }
-1
View File
@@ -197,7 +197,6 @@ private:
bool fMuted; bool fMuted;
PlaylistItemRef fItem; PlaylistItemRef fItem;
TrackSupplier* fTrackSupplier;
ProxyVideoSupplier* fVideoSupplier; ProxyVideoSupplier* fVideoSupplier;
ProxyAudioSupplier* fAudioSupplier; ProxyAudioSupplier* fAudioSupplier;
@@ -288,7 +288,7 @@ FilePlaylistItem::RestoreFromTrash()
// #pragma mark - // #pragma mark -
TrackSupplier* TrackSupplier*
FilePlaylistItem::CreateTrackSupplier() const FilePlaylistItem::_CreateTrackSupplier() const
{ {
MediaFileTrackSupplier* supplier MediaFileTrackSupplier* supplier
= new(std::nothrow) MediaFileTrackSupplier(); = new(std::nothrow) MediaFileTrackSupplier();
@@ -400,7 +400,7 @@ FilePlaylistItem::ImageRef() const
bigtime_t bigtime_t
FilePlaylistItem::_CalculateDuration() const FilePlaylistItem::_CalculateDuration()
{ {
BMediaFile mediaFile(&Ref()); BMediaFile mediaFile(&Ref());
@@ -52,9 +52,6 @@ public:
virtual status_t MoveIntoTrash(); virtual status_t MoveIntoTrash();
virtual status_t RestoreFromTrash(); virtual status_t RestoreFromTrash();
// playback
virtual TrackSupplier* CreateTrackSupplier() const;
status_t AddRef(const entry_ref& ref); status_t AddRef(const entry_ref& ref);
const entry_ref& Ref() const { return fRefs[0]; } const entry_ref& Ref() const { return fRefs[0]; }
@@ -62,7 +59,9 @@ public:
const entry_ref& ImageRef() const; const entry_ref& ImageRef() const;
protected: protected:
virtual bigtime_t _CalculateDuration() const; virtual bigtime_t _CalculateDuration();
// playback
virtual TrackSupplier* _CreateTrackSupplier() const;
private: private:
status_t _SetAttribute(const char* attrName, status_t _SetAttribute(const char* attrName,
+29 -4
View File
@@ -42,7 +42,8 @@ static vint32 sInstanceCount = 0;
PlaylistItem::PlaylistItem() PlaylistItem::PlaylistItem()
: :
fPlaybackFailed(false) fPlaybackFailed(false),
fTrackSupplier(NULL)
{ {
#ifdef DEBUG_INSTANCE_COUNT #ifdef DEBUG_INSTANCE_COUNT
atomic_add(&sInstanceCount, 1); atomic_add(&sInstanceCount, 1);
@@ -60,6 +61,31 @@ PlaylistItem::~PlaylistItem()
} }
TrackSupplier*
PlaylistItem::GetTrackSupplier()
{
if (fTrackSupplier == NULL)
fTrackSupplier = _CreateTrackSupplier();
return fTrackSupplier;
}
void
PlaylistItem::ReleaseTrackSupplier()
{
delete fTrackSupplier;
fTrackSupplier = NULL;
}
bool
PlaylistItem::HasTrackSupplier() const
{
return fTrackSupplier != NULL;
}
BString BString
PlaylistItem::Name() const PlaylistItem::Name() const
{ {
@@ -160,10 +186,10 @@ PlaylistItem::_NotifyListeners() const
} }
bigtime_t PlaylistItem::_CalculateDuration() const bigtime_t PlaylistItem::_CalculateDuration()
{ {
// To be overridden in subclasses with more efficient methods // To be overridden in subclasses with more efficient methods
TrackSupplier* supplier = CreateTrackSupplier(); TrackSupplier* supplier = GetTrackSupplier();
AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0); AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0);
VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0); VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0);
@@ -173,7 +199,6 @@ bigtime_t PlaylistItem::_CalculateDuration() const
delete vi; delete vi;
delete au; delete au;
delete supplier;
return duration; return duration;
} }
+10 -3
View File
@@ -90,8 +90,13 @@ public:
virtual status_t MoveIntoTrash() = 0; virtual status_t MoveIntoTrash() = 0;
virtual status_t RestoreFromTrash() = 0; virtual status_t RestoreFromTrash() = 0;
// playback // Create and return the TrackSupplier if it doesn't exist,
virtual TrackSupplier* CreateTrackSupplier() const = 0; // this object is used for media playback.
TrackSupplier* GetTrackSupplier();
// Delete and reset the TrackSupplier
void ReleaseTrackSupplier();
// Return whether the supplier has been initialized
bool HasTrackSupplier() const;
void SetPlaybackFailed(); void SetPlaybackFailed();
bool PlaybackFailed() const bool PlaybackFailed() const
@@ -103,11 +108,13 @@ public:
protected: protected:
void _NotifyListeners() const; void _NotifyListeners() const;
virtual bigtime_t _CalculateDuration() const; virtual bigtime_t _CalculateDuration();
virtual TrackSupplier* _CreateTrackSupplier() const = 0;
private: private:
BList fListeners; BList fListeners;
bool fPlaybackFailed; bool fPlaybackFailed;
TrackSupplier* fTrackSupplier;
}; };
typedef BReference<PlaylistItem> PlaylistItemRef; typedef BReference<PlaylistItem> PlaylistItemRef;
@@ -32,7 +32,6 @@ UrlPlaylistItem::UrlPlaylistItem(const BMessage* archive)
UrlPlaylistItem::~UrlPlaylistItem() UrlPlaylistItem::~UrlPlaylistItem()
{ {
delete fUrl;
} }
@@ -128,7 +127,7 @@ UrlPlaylistItem::RestoreFromTrash()
TrackSupplier* TrackSupplier*
UrlPlaylistItem::CreateTrackSupplier() const UrlPlaylistItem::_CreateTrackSupplier() const
{ {
MediaFileTrackSupplier* supplier MediaFileTrackSupplier* supplier
= new(std::nothrow) MediaFileTrackSupplier(); = new(std::nothrow) MediaFileTrackSupplier();
@@ -45,10 +45,11 @@ public:
virtual status_t MoveIntoTrash(); virtual status_t MoveIntoTrash();
virtual status_t RestoreFromTrash(); virtual status_t RestoreFromTrash();
virtual TrackSupplier* CreateTrackSupplier() const;
BUrl Url() const; BUrl Url() const;
protected:
virtual TrackSupplier* _CreateTrackSupplier() const;
private: private:
BUrl fUrl; BUrl fUrl;
}; };