PluginManager: Refactor of MediaIOWrapper

* Use BPositionIO version of Read/Write.
* Implementation of fallback buffering.
* Other cleanup.
This commit is contained in:
Dario Casalinuovo
2016-03-25 22:00:27 +01:00
parent 6efbc4bb54
commit deb9166054
+52 -50
View File
@@ -19,6 +19,8 @@
PluginManager gPluginManager; PluginManager gPluginManager;
#define BLOCK_SIZE 4096
class BMediaIOWrapper : public BMediaIO { class BMediaIOWrapper : public BMediaIO {
public: public:
@@ -28,10 +30,14 @@ public:
fPosition(NULL), fPosition(NULL),
fMedia(NULL), fMedia(NULL),
fFile(NULL), fFile(NULL),
fFallbackBuffer(NULL),
fFallbackPosition(0),
fErr(B_NO_ERROR) fErr(B_NO_ERROR)
{ {
fPosition = dynamic_cast<BPositionIO*>(source); fPosition = dynamic_cast<BPositionIO*>(source);
fMedia = dynamic_cast<BMediaIO*>(source); fMedia = dynamic_cast<BMediaIO*>(source);
fFile = dynamic_cast<BFile*>(source);
fData = source;
// No need to do additional buffering if we have // No need to do additional buffering if we have
// a BBufferIO or a BMediaIO. // a BBufferIO or a BMediaIO.
@@ -40,40 +46,29 @@ public:
// Source needs to be at least a BPositionIO to wrap with a BBufferIO // Source needs to be at least a BPositionIO to wrap with a BBufferIO
if (fPosition != NULL) { if (fPosition != NULL) {
fPosition = new(std::nothrow) BBufferIO(fPosition, 65536, true); fPosition = new(std::nothrow) BBufferIO(fPosition, 65536, true);
// We have to reset our BDataIO reference
fData = dynamic_cast<BDataIO*>(fPosition);
if (fPosition == NULL) { if (fPosition == NULL) {
fErr = B_NO_MEMORY; fErr = B_NO_MEMORY;
return; return;
} }
// We have to reset our BDataIO reference too
fData = dynamic_cast<BDataIO*>(fPosition);
} else { } else {
TRACE("Unable to improve performance with a BufferIO\n");
// TODO: fallback buffering // TODO: fallback buffering
// In this case we have to supply our own form
// of pseudo-seekable object from a non-seekable
// BDataIO.
fFallbackBuffer = new BMallocIO();
fFallbackBuffer->SetBlockSize(BLOCK_SIZE);
TRACE("Unable to improve performance with a BufferIO\n");
} }
} else {
fData = source;
} }
fFile = dynamic_cast<BFile*>(source);
} }
virtual ~BMediaIOWrapper() virtual ~BMediaIOWrapper()
{ {
} }
virtual ssize_t Read(void* buffer, size_t size) // BPositionIO interface
{
return fData->Read(buffer, size);
}
virtual ssize_t Write(const void* buffer, size_t size)
{
return fData->Write(buffer, size);
}
virtual status_t Flush()
{
return fData->Flush();
}
virtual ssize_t ReadAt(off_t position, void* buffer, virtual ssize_t ReadAt(off_t position, void* buffer,
size_t size) size_t size)
@@ -81,9 +76,22 @@ public:
if (IsSeekable()) if (IsSeekable())
return fPosition->ReadAt(position, buffer, size); return fPosition->ReadAt(position, buffer, size);
// if (IsCached()) { if (IsEndless()) {
// off_t nextPos = position+size;
// } off_t bufSize = 0;
fFallbackBuffer->GetSize(&bufSize);
if (fFallbackPosition == position
&& nextPos > bufSize) {
fData->Read(buffer, size);
fFallbackBuffer->WriteAt(fFallbackPosition, buffer, size);
fFallbackPosition = nextPos;
return size;
} else if (nextPos <= bufSize) {
fFallbackPosition = nextPos;
return fFallbackBuffer->ReadAt(position, buffer, size);
}
}
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
} }
@@ -94,6 +102,11 @@ public:
if (IsSeekable()) if (IsSeekable())
return fPosition->WriteAt(position, buffer, size); return fPosition->WriteAt(position, buffer, size);
if (IsEndless() && position == fFallbackPosition) {
fData->Write(buffer, size);
fFallbackPosition = position+size;
}
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
} }
@@ -102,32 +115,34 @@ public:
if (IsSeekable()) if (IsSeekable())
return fPosition->Seek(position, seekMode); return fPosition->Seek(position, seekMode);
// if (IsCached()) { if (IsEndless())
// return fFallbackBuffer->Seek(position, seekMode);
// }
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
} }
virtual off_t Position() const virtual off_t Position() const
{ {
if (!IsEndless()) if (IsSeekable())
return fPosition->Position(); return fPosition->Position();
// TODO: buffering if (IsEndless())
return fFallbackBuffer->Position();
return 0; return B_NOT_SUPPORTED;
} }
virtual status_t SetSize(off_t size) virtual status_t SetSize(off_t size)
{ {
if (IsEndless()) if (IsEndless())
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
// TODO: What a non seekable stream should do here?
return fPosition->SetSize(size); return fPosition->SetSize(size);
} }
virtual status_t GetSize(off_t* size) const virtual status_t GetSize(off_t* size) const
{ {
if (IsEndless()) if (IsEndless())
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
@@ -135,6 +150,8 @@ public:
return fPosition->GetSize(size); return fPosition->GetSize(size);
} }
// BMediaIO interface
virtual bool IsSeekable() const virtual bool IsSeekable() const
{ {
if (IsMedia()) if (IsMedia())
@@ -152,26 +169,14 @@ public:
{ {
if (IsMedia()) if (IsMedia())
return fMedia->IsEndless(); return fMedia->IsEndless();
if (IsPosition()) if (IsPosition())
return false; return false;
return true; return true;
} }
virtual bool IsCached() const // Utility methods
{
return true;
}
virtual size_t CacheSize() const
{
// TODO: it should be another buffering level
// but we might to optimize with the underlying level
//if (IsMedia() && IsCached())
// return CacheSize();
return B_NOT_SUPPORTED;
}
status_t InitCheck() const status_t InitCheck() const
{ {
@@ -179,11 +184,6 @@ public:
} }
protected: protected:
// Utility methods
bool IsData() const
{
return fData != NULL;
}
bool IsPosition() const bool IsPosition() const
{ {
@@ -201,6 +201,8 @@ private:
BMediaIO* fMedia; BMediaIO* fMedia;
BFile* fFile; BFile* fFile;
BMallocIO* fFallbackBuffer;
off_t fFallbackPosition;
status_t fErr; status_t fErr;
}; };