diff --git a/headers/private/media/AdapterIO.h b/headers/private/media/AdapterIO.h index 6d48c27cf6..ccd073e072 100644 --- a/headers/private/media/AdapterIO.h +++ b/headers/private/media/AdapterIO.h @@ -54,26 +54,30 @@ public: virtual status_t SetSize(off_t size); virtual status_t GetSize(off_t* size) const; + virtual status_t Open(); + virtual void Close(); + + void SeekCompleted(); + status_t SetBuffer(BPositionIO* buffer); + BInputAdapter* BuildInputAdapter(); protected: friend class BInputAdapter; - void SetBuffer(BPositionIO* io); + virtual status_t SeekRequested(off_t position); ssize_t BackWrite(const void* buffer, size_t size); - status_t SeekRequested(off_t position); - status_t SeekCompleted(off_t position); - private: status_t _EvaluateWait(off_t position); int32 fFlags; - bigtime_t fTimeout; RelativePositionIO* fBuffer; off_t fTotalSize; + bool fOpened; + sem_id fSeekSem; BInputAdapter* fInputAdapter; diff --git a/src/kits/media/AdapterIO.cpp b/src/kits/media/AdapterIO.cpp index 4cad54d6fb..d9a5e7d150 100644 --- a/src/kits/media/AdapterIO.cpp +++ b/src/kits/media/AdapterIO.cpp @@ -8,21 +8,23 @@ #include -#include - #include "debug.h" +#define TIMEOUT_QUANTA 100000 + + class RelativePositionIO : public BPositionIO { public: - RelativePositionIO(BAdapterIO* owner, BPositionIO* buffer) + RelativePositionIO(BAdapterIO* owner, BPositionIO* buffer, bigtime_t timeout) : BPositionIO(), fOwner(owner), fBackPosition(0), fStartOffset(0), - fBuffer(buffer) + fBuffer(buffer), + fTimeout(timeout) { fOwner->GetFlags(&fFlags); } @@ -84,8 +86,15 @@ public: if (ret != B_OK) return B_ERROR; - while(bufferSize < position) { - snooze(100000); + bigtime_t totalTimeOut = 0; + + while(bufferSize <= position) { + if (fTimeout != B_INFINITE_TIMEOUT && totalTimeOut >= fTimeout) + return B_TIMED_OUT; + + snooze(TIMEOUT_QUANTA); + + totalTimeOut += TIMEOUT_QUANTA; GetSize(&bufferSize); } return B_OK; @@ -147,10 +156,15 @@ public: { AutoWriteLocker _(fLock); - off_t currentPos = Position(); off_t ret = fBuffer->WriteAt(fBackPosition, buffer, size); fBackPosition += ret; - return fBuffer->Seek(currentPos, SEEK_SET); + return ret; + } + + void SetBuffer(BPositionIO* buffer) + { + delete fBuffer; + fBuffer = buffer; } bool IsStreaming() const @@ -188,19 +202,26 @@ private: int32 fFlags; mutable RWLocker fLock; + + bigtime_t fTimeout; }; BAdapterIO::BAdapterIO(int32 flags, bigtime_t timeout) : fFlags(flags), - fTimeout(timeout), fBuffer(NULL), + fTotalSize(0), + fOpened(false), + fSeekSem(-1), fInputAdapter(NULL) { CALLED(); - fBuffer = new RelativePositionIO(this, new BMallocIO()); + fBuffer = new RelativePositionIO(this, new BMallocIO(), timeout); + + if (fBuffer->IsSeekable()) + fSeekSem = create_sem(0, "BAdapterIO seek sem"); } @@ -214,6 +235,8 @@ BAdapterIO::~BAdapterIO() { CALLED(); + Close(); + delete fInputAdapter; delete fBuffer; } @@ -233,7 +256,8 @@ BAdapterIO::ReadAt(off_t position, void* buffer, size_t size) { CALLED(); - printf("read at %d %d \n", (int)position, (int)size); + TRACE("BAdapterIO::ReadAt %" B_PRId64 " %" B_PRId64 "\n", position, size); + status_t ret = _EvaluateWait(position+size); if (ret != B_OK) return ret; @@ -260,6 +284,7 @@ BAdapterIO::Seek(off_t position, uint32 seekMode) { CALLED(); + // TODO: Support seekModes status_t ret = _EvaluateWait(position); if (ret != B_OK) return ret; @@ -305,6 +330,66 @@ BAdapterIO::GetSize(off_t* size) const } +status_t +BAdapterIO::Open() +{ + CALLED(); + + fOpened = true; + return B_OK; +} + + +void +BAdapterIO::Close() +{ + CALLED(); + + fOpened = false; +} + + +void +BAdapterIO::SeekCompleted() +{ + CALLED(); + release_sem(fSeekSem); +} + + +status_t +BAdapterIO::SetBuffer(BPositionIO* buffer) +{ + // We can't change the buffer while we + // are running. + if (fOpened) + return B_ERROR; + + fBuffer->SetBuffer(buffer); + return B_OK; +} + + +BInputAdapter* +BAdapterIO::BuildInputAdapter() +{ + if (fInputAdapter != NULL) + return fInputAdapter; + + fInputAdapter = new BInputAdapter(this); + return fInputAdapter; +} + + +status_t +BAdapterIO::SeekRequested(off_t position) +{ + CALLED(); + + return B_ERROR; +} + + ssize_t BAdapterIO::BackWrite(const void* buffer, size_t size) { @@ -329,6 +414,9 @@ BAdapterIO::_EvaluateWait(off_t pos) && fBuffer->IsSeekable()) { if (SeekRequested(pos) != B_OK) return B_UNSUPPORTED; + + acquire_sem(fSeekSem); + fBuffer->ResetStartOffset(pos); } } @@ -336,35 +424,6 @@ BAdapterIO::_EvaluateWait(off_t pos) } -BInputAdapter* -BAdapterIO::BuildInputAdapter() -{ - if (fInputAdapter != NULL) - return fInputAdapter; - - fInputAdapter = new BInputAdapter(this); - return fInputAdapter; -} - - -status_t -BAdapterIO::SeekRequested(off_t position) -{ - CALLED(); - - return B_ERROR; -} - - -status_t -BAdapterIO::SeekCompleted(off_t position) -{ - CALLED(); - - return fBuffer->ResetStartOffset(position); -} - - BInputAdapter::BInputAdapter(BAdapterIO* io) : fIO(io)