mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-06 14:52:34 +02:00
Manage block files with std::shared_ptr, BlockHash stores weak_ptr
This commit is contained in:
parent
84ccdca5c3
commit
8b72bd2f92
@ -101,7 +101,6 @@ ArrayOf<char> BlockFile::fullSummary;
|
|||||||
/// @param samples The number of samples this BlockFile contains.
|
/// @param samples The number of samples this BlockFile contains.
|
||||||
BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
|
BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
|
||||||
mLockCount(0),
|
mLockCount(0),
|
||||||
mRefCount(1),
|
|
||||||
mFileName(std::move(fileName)),
|
mFileName(std::move(fileName)),
|
||||||
mLen(samples),
|
mLen(samples),
|
||||||
mSummaryInfo(samples)
|
mSummaryInfo(samples)
|
||||||
@ -165,28 +164,6 @@ bool BlockFile::IsLocked()
|
|||||||
return mLockCount > 0;
|
return mLockCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increases the reference count of this block by one. Only
|
|
||||||
/// DirManager should call this method.
|
|
||||||
void BlockFile::Ref() const
|
|
||||||
{
|
|
||||||
mRefCount++;
|
|
||||||
BLOCKFILE_DEBUG_OUTPUT("Ref", mRefCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decreases the reference count of this block by one. If this
|
|
||||||
/// causes the count to become zero, deletes the associated disk
|
|
||||||
/// file and deletes this object
|
|
||||||
bool BlockFile::Deref() const
|
|
||||||
{
|
|
||||||
mRefCount--;
|
|
||||||
BLOCKFILE_DEBUG_OUTPUT("Deref", mRefCount);
|
|
||||||
if (mRefCount <= 0) {
|
|
||||||
delete this;
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a buffer containing a summary block describing this sample
|
/// Get a buffer containing a summary block describing this sample
|
||||||
/// data. This must be called by derived classes when they
|
/// data. This must be called by derived classes when they
|
||||||
/// are constructed, to allow them to construct their summary data,
|
/// are constructed, to allow them to construct their summary data,
|
||||||
|
@ -44,15 +44,12 @@ class SummaryInfo {
|
|||||||
|
|
||||||
|
|
||||||
class BlockFile;
|
class BlockFile;
|
||||||
|
using BlockFilePtr = std::shared_ptr<BlockFile>;
|
||||||
|
|
||||||
// to do: use shared_ptr instead
|
|
||||||
using BlockFilePtr = BlockFile *;
|
|
||||||
|
|
||||||
// to do: make this a synonym for make_shared
|
|
||||||
template< typename Result, typename... Args >
|
template< typename Result, typename... Args >
|
||||||
inline Result *make_blockfile (Args && ... args)
|
inline std::shared_ptr< Result > make_blockfile (Args && ... args)
|
||||||
{
|
{
|
||||||
return new Result( std::forward< Args > ( args )... );
|
return std::make_shared< Result > ( std::forward< Args > ( args )... );
|
||||||
}
|
}
|
||||||
|
|
||||||
class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
||||||
@ -168,17 +165,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class DirManager;
|
|
||||||
friend class AudacityApp;
|
|
||||||
//needed for Ref/Deref access.
|
|
||||||
friend class ODComputeSummaryTask;
|
|
||||||
friend class ODDecodeTask;
|
|
||||||
friend class ODPCMAliasBlockFile;
|
|
||||||
|
|
||||||
virtual void Ref() const;
|
|
||||||
virtual bool Deref() const;
|
|
||||||
virtual int RefCount(){return mRefCount;}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Calculate summary data for the given sample data
|
/// Calculate summary data for the given sample data
|
||||||
/// Overrides have differing details of memory management
|
/// Overrides have differing details of memory management
|
||||||
@ -199,7 +185,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int mLockCount;
|
int mLockCount;
|
||||||
mutable int mRefCount;
|
|
||||||
|
|
||||||
static ArrayOf<char> fullSummary;
|
static ArrayOf<char> fullSummary;
|
||||||
|
|
||||||
|
@ -94,10 +94,6 @@ static void ReplaceBlockFiles(AudacityProject *project,
|
|||||||
const auto src = &*f;
|
const auto src = &*f;
|
||||||
if (hash.count( src ) > 0) {
|
if (hash.count( src ) > 0) {
|
||||||
const auto &dst = hash[src];
|
const auto &dst = hash[src];
|
||||||
|
|
||||||
dirManager->Deref(src);
|
|
||||||
dirManager->Ref(dst);
|
|
||||||
|
|
||||||
f = dst;
|
f = dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,11 +219,6 @@ static void RemoveDependencies(AudacityProject *project,
|
|||||||
// However, that didn't actually change any references to these
|
// However, that didn't actually change any references to these
|
||||||
// blockfiles in the Sequences, so we do that next...
|
// blockfiles in the Sequences, so we do that next...
|
||||||
ReplaceBlockFiles(project, blockFileHash);
|
ReplaceBlockFiles(project, blockFileHash);
|
||||||
|
|
||||||
// Subtract one from reference count of NEW block files; they're
|
|
||||||
// now all referenced the proper number of times by the Sequences
|
|
||||||
for (const auto &pair : blockFileHash)
|
|
||||||
dirManager->Deref(pair.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -454,7 +454,7 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
while ((iter != mBlockFileHash.end()) && success)
|
while ((iter != mBlockFileHash.end()) && success)
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -486,7 +486,7 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
|
|||||||
BlockHash::iterator iter = mBlockFileHash.begin();
|
BlockHash::iterator iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -726,7 +726,7 @@ auto DirManager::GetBalanceInfo() -> BalanceInfo &
|
|||||||
auto it = mBlockFileHash.begin(), end = mBlockFileHash.end();
|
auto it = mBlockFileHash.begin(), end = mBlockFileHash.end();
|
||||||
while (it != end)
|
while (it != end)
|
||||||
{
|
{
|
||||||
BlockFilePtr ptr { it->second };
|
BlockFilePtr ptr { it->second.lock() };
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
auto name = it->first;
|
auto name = it->first;
|
||||||
mBlockFileHash.erase( it++ );
|
mBlockFileHash.erase( it++ );
|
||||||
@ -1006,7 +1006,7 @@ bool DirManager::ContainsBlockFile(const BlockFile *b) const
|
|||||||
BlockHash::const_iterator it = mBlockFileHash.find(result.name.GetName());
|
BlockHash::const_iterator it = mBlockFileHash.find(result.name.GetName());
|
||||||
if (it == mBlockFileHash.end())
|
if (it == mBlockFileHash.end())
|
||||||
return false;
|
return false;
|
||||||
BlockFilePtr ptr = it->second;
|
BlockFilePtr ptr = it->second.lock();
|
||||||
return ptr && (b == &*ptr);
|
return ptr && (b == &*ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1015,7 +1015,7 @@ bool DirManager::ContainsBlockFile(const wxString &filepath) const
|
|||||||
// check what the hash returns in case the blockfile is from a different project
|
// check what the hash returns in case the blockfile is from a different project
|
||||||
BlockHash::const_iterator it = mBlockFileHash.find(filepath);
|
BlockHash::const_iterator it = mBlockFileHash.find(filepath);
|
||||||
return it != mBlockFileHash.end() &&
|
return it != mBlockFileHash.end() &&
|
||||||
BlockFilePtr{ it->second };
|
BlockFilePtr{ it->second.lock() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds one to the reference count of the block file,
|
// Adds one to the reference count of the block file,
|
||||||
@ -1027,7 +1027,6 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
|||||||
const auto &fn = result.name;
|
const auto &fn = result.name;
|
||||||
|
|
||||||
if (!b->IsLocked()) {
|
if (!b->IsLocked()) {
|
||||||
b->Ref();
|
|
||||||
//mchinen:July 13 2009 - not sure about this, but it needs to be added to the hash to be able to save if not locked.
|
//mchinen:July 13 2009 - not sure about this, but it needs to be added to the hash to be able to save if not locked.
|
||||||
//note that this shouldn't hurt mBlockFileHash's that already contain the filename, since it should just overwrite.
|
//note that this shouldn't hurt mBlockFileHash's that already contain the filename, since it should just overwrite.
|
||||||
//but it's something to watch out for.
|
//but it's something to watch out for.
|
||||||
@ -1148,7 +1147,6 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
|||||||
// See http://bugzilla.audacityteam.org/show_bug.cgi?id=451#c13.
|
// See http://bugzilla.audacityteam.org/show_bug.cgi?id=451#c13.
|
||||||
// Lock pBlockFile so that the ~BlockFile() will not DELETE the file on disk.
|
// Lock pBlockFile so that the ~BlockFile() will not DELETE the file on disk.
|
||||||
pBlockFile->Lock();
|
pBlockFile->Lock();
|
||||||
delete pBlockFile;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1162,7 +1160,7 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
|||||||
|
|
||||||
wxString name = target->GetFileName().name.GetName();
|
wxString name = target->GetFileName().name.GetName();
|
||||||
auto &wRetrieved = mBlockFileHash[name];
|
auto &wRetrieved = mBlockFileHash[name];
|
||||||
BlockFilePtr retrieved = wRetrieved;
|
BlockFilePtr retrieved = wRetrieved.lock();
|
||||||
if (retrieved) {
|
if (retrieved) {
|
||||||
// Lock it in order to DELETE it safely, i.e. without having
|
// Lock it in order to DELETE it safely, i.e. without having
|
||||||
// it DELETE the file, too...
|
// it DELETE the file, too...
|
||||||
@ -1260,38 +1258,6 @@ bool DirManager::CopyToNewProjectDirectory(BlockFile *f)
|
|||||||
return MoveOrCopyToNewProjectDirectory(f, true);
|
return MoveOrCopyToNewProjectDirectory(f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirManager::Ref(BlockFile * f)
|
|
||||||
{
|
|
||||||
f->Ref();
|
|
||||||
//printf("Ref(%d): %s\n",
|
|
||||||
// f->mRefCount,
|
|
||||||
// (const char *)f->mFileName.GetFullPath().mb_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
int DirManager::GetRefCount(BlockFile * f)
|
|
||||||
{
|
|
||||||
return f->mRefCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirManager::Deref(BlockFile * f)
|
|
||||||
{
|
|
||||||
const wxString theFileName = f->GetFileName().name.GetName();
|
|
||||||
|
|
||||||
//printf("Deref(%d): %s\n",
|
|
||||||
// f->mRefCount-1,
|
|
||||||
// (const char *)f->mFileName.GetFullPath().mb_str());
|
|
||||||
|
|
||||||
if (f->Deref()) {
|
|
||||||
// If Deref() returned true, the reference count reached zero
|
|
||||||
// and this block is no longer needed. Remove it from the hash
|
|
||||||
// table.
|
|
||||||
|
|
||||||
mBlockFileHash.erase(theFileName);
|
|
||||||
BalanceInfoDel(theFileName);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirManager::EnsureSafeFilename(const wxFileName &fName)
|
bool DirManager::EnsureSafeFilename(const wxFileName &fName)
|
||||||
{
|
{
|
||||||
// Quick check: If it's not even in our alias list,
|
// Quick check: If it's not even in our alias list,
|
||||||
@ -1352,7 +1318,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
|
|||||||
BlockHash::iterator iter = mBlockFileHash.begin();
|
BlockHash::iterator iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1395,7 +1361,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
|
|||||||
BlockHash::iterator iter = mBlockFileHash.begin();
|
BlockHash::iterator iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1423,7 +1389,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
|
|||||||
BlockHash::iterator iter = mBlockFileHash.begin();
|
BlockHash::iterator iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1558,7 +1524,7 @@ _("Project check of \"%s\" folder \
|
|||||||
while (iter != missingAliasedFileAUFHash.end())
|
while (iter != missingAliasedFileAUFHash.end())
|
||||||
{
|
{
|
||||||
// This type cast is safe. We checked that it's an alias block file earlier.
|
// This type cast is safe. We checked that it's an alias block file earlier.
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
wxASSERT(b);
|
wxASSERT(b);
|
||||||
if (!b)
|
if (!b)
|
||||||
@ -1625,7 +1591,7 @@ _("Project check of \"%s\" folder \
|
|||||||
BlockHash::iterator iter = missingAUFHash.begin();
|
BlockHash::iterator iter = missingAUFHash.begin();
|
||||||
while (iter != missingAUFHash.end())
|
while (iter != missingAUFHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
wxASSERT(b);
|
wxASSERT(b);
|
||||||
if (!b)
|
if (!b)
|
||||||
@ -1689,7 +1655,7 @@ _("Project check of \"%s\" folder \
|
|||||||
BlockHash::iterator iter = missingAUHash.begin();
|
BlockHash::iterator iter = missingAUHash.begin();
|
||||||
while (iter != missingAUHash.end())
|
while (iter != missingAUHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
wxASSERT(b);
|
wxASSERT(b);
|
||||||
if (!b)
|
if (!b)
|
||||||
@ -1801,7 +1767,7 @@ void DirManager::FindMissingAliasedFiles(
|
|||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
wxString key = iter->first; // file name and extension
|
wxString key = iter->first; // file name and extension
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1841,7 +1807,7 @@ void DirManager::FindMissingAUFs(
|
|||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
const wxString &key = iter->first;
|
const wxString &key = iter->first;
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1871,7 +1837,7 @@ void DirManager::FindMissingAUs(
|
|||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
const wxString &key = iter->first;
|
const wxString &key = iter->first;
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1975,7 +1941,7 @@ void DirManager::FillBlockfilesCache()
|
|||||||
iter = mBlockFileHash.begin();
|
iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -1995,7 +1961,7 @@ void DirManager::FillBlockfilesCache()
|
|||||||
int current = 0;
|
int current = 0;
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -2020,7 +1986,7 @@ void DirManager::WriteCacheToDisk()
|
|||||||
iter = mBlockFileHash.begin();
|
iter = mBlockFileHash.begin();
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
@ -2040,7 +2006,7 @@ void DirManager::WriteCacheToDisk()
|
|||||||
int current = 0;
|
int current = 0;
|
||||||
while (iter != mBlockFileHash.end())
|
while (iter != mBlockFileHash.end())
|
||||||
{
|
{
|
||||||
BlockFilePtr b = iter->second;
|
BlockFilePtr b = iter->second.lock();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
|
@ -34,9 +34,10 @@ class SequenceTest;
|
|||||||
WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, DirHash);
|
WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, DirHash);
|
||||||
|
|
||||||
class BlockFile;
|
class BlockFile;
|
||||||
using BlockFilePtr = BlockFile *;
|
using BlockFilePtr = std::shared_ptr<BlockFile>;
|
||||||
|
|
||||||
WX_DECLARE_HASH_MAP(wxString, BlockFilePtr, wxStringHash, wxStringEqual, BlockHash);
|
WX_DECLARE_HASH_MAP(wxString, std::weak_ptr<BlockFile>, wxStringHash,
|
||||||
|
wxStringEqual, BlockHash);
|
||||||
|
|
||||||
wxMemorySize GetFreeMemory();
|
wxMemorySize GetFreeMemory();
|
||||||
|
|
||||||
@ -101,12 +102,6 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
|
|||||||
|
|
||||||
bool EnsureSafeFilename(const wxFileName &fName);
|
bool EnsureSafeFilename(const wxFileName &fName);
|
||||||
|
|
||||||
void Ref(BlockFile * f);
|
|
||||||
void Deref(BlockFile * f);
|
|
||||||
|
|
||||||
// For debugging only
|
|
||||||
int GetRefCount(BlockFile * f);
|
|
||||||
|
|
||||||
void SetLoadingTarget(BlockArray *pArray, unsigned idx)
|
void SetLoadingTarget(BlockArray *pArray, unsigned idx)
|
||||||
{
|
{
|
||||||
mLoadingTarget = pArray;
|
mLoadingTarget = pArray;
|
||||||
|
@ -34,6 +34,7 @@ using std::isinf;
|
|||||||
namespace std {
|
namespace std {
|
||||||
using std::tr1::shared_ptr;
|
using std::tr1::shared_ptr;
|
||||||
using std::tr1::weak_ptr;
|
using std::tr1::weak_ptr;
|
||||||
|
using std::tr1::static_pointer_cast;
|
||||||
using std::tr1::remove_reference;
|
using std::tr1::remove_reference;
|
||||||
|
|
||||||
template<typename X> struct default_delete
|
template<typename X> struct default_delete
|
||||||
|
@ -75,19 +75,6 @@ Sequence::Sequence(const Sequence &orig, const std::shared_ptr<DirManager> &proj
|
|||||||
|
|
||||||
Sequence::~Sequence()
|
Sequence::~Sequence()
|
||||||
{
|
{
|
||||||
DerefAllFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sequence::DerefAllFiles()
|
|
||||||
{
|
|
||||||
for (size_t i = 0, nn = mBlock.size(); i < nn; i++)
|
|
||||||
{
|
|
||||||
BlockFile *& pOldFile = mBlock[i].f;
|
|
||||||
if (pOldFile) {
|
|
||||||
mDirManager->Deref(pOldFile);
|
|
||||||
pOldFile = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleCount Sequence::GetMaxBlockSize() const
|
sampleCount Sequence::GetMaxBlockSize() const
|
||||||
@ -210,8 +197,6 @@ bool Sequence::ConvertToSampleFormat(sampleFormat format, bool* pbChanged)
|
|||||||
// Invalidate all the old, non-aliased block files.
|
// Invalidate all the old, non-aliased block files.
|
||||||
// Aliased files will be converted at save, per comment above.
|
// Aliased files will be converted at save, per comment above.
|
||||||
|
|
||||||
DerefAllFiles();
|
|
||||||
|
|
||||||
// Replace with NEW blocks.
|
// Replace with NEW blocks.
|
||||||
mBlock.swap(newBlockArray);
|
mBlock.swap(newBlockArray);
|
||||||
}
|
}
|
||||||
@ -550,7 +535,6 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
auto file =
|
auto file =
|
||||||
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
|
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
|
||||||
|
|
||||||
mDirManager->Deref(block.f);
|
|
||||||
block.f = file;
|
block.f = file;
|
||||||
|
|
||||||
for (unsigned int i = b + 1; i < numBlocks; i++)
|
for (unsigned int i = b + 1; i < numBlocks; i++)
|
||||||
@ -635,8 +619,6 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
Blockify(newBlock, s + lastStart, sampleBuffer.ptr(), rightLen);
|
Blockify(newBlock, s + lastStart, sampleBuffer.ptr(), rightLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
mDirManager->Deref(splitBlock.f);
|
|
||||||
|
|
||||||
// Copy remaining blocks to NEW block array and
|
// Copy remaining blocks to NEW block array and
|
||||||
// swap the NEW block array in for the old
|
// swap the NEW block array in for the old
|
||||||
for (i = b + 1; i < numBlocks; i++)
|
for (i = b + 1; i < numBlocks; i++)
|
||||||
@ -681,13 +663,10 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
|||||||
silentFile = make_blockfile<SilentBlockFile>(idealSamples);
|
silentFile = make_blockfile<SilentBlockFile>(idealSamples);
|
||||||
while (len >= idealSamples) {
|
while (len >= idealSamples) {
|
||||||
sTrack.mBlock.push_back(SeqBlock(silentFile, pos));
|
sTrack.mBlock.push_back(SeqBlock(silentFile, pos));
|
||||||
mDirManager->Ref(silentFile);
|
|
||||||
|
|
||||||
pos += idealSamples;
|
pos += idealSamples;
|
||||||
len -= idealSamples;
|
len -= idealSamples;
|
||||||
}
|
}
|
||||||
if (silentFile)
|
|
||||||
mDirManager->Deref(silentFile);
|
|
||||||
if (len) {
|
if (len) {
|
||||||
sTrack.mBlock.push_back(SeqBlock(
|
sTrack.mBlock.push_back(SeqBlock(
|
||||||
make_blockfile<SilentBlockFile>(len), pos));
|
make_blockfile<SilentBlockFile>(len), pos));
|
||||||
@ -1151,11 +1130,8 @@ bool Sequence::CopyWrite(SampleBuffer &scratch,
|
|||||||
Read(scratch.ptr(), mSampleFormat, b, 0, length);
|
Read(scratch.ptr(), mSampleFormat, b, 0, length);
|
||||||
memcpy(scratch.ptr() + start*sampleSize, buffer, len*sampleSize);
|
memcpy(scratch.ptr() + start*sampleSize, buffer, len*sampleSize);
|
||||||
|
|
||||||
BlockFile *const oldBlockFile = b.f;
|
|
||||||
b.f = mDirManager->NewSimpleBlockFile(scratch.ptr(), length, mSampleFormat);
|
b.f = mDirManager->NewSimpleBlockFile(scratch.ptr(), length, mSampleFormat);
|
||||||
|
|
||||||
mDirManager->Deref(oldBlockFile);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1233,7 +1209,6 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
|
|||||||
if (start == block.start &&
|
if (start == block.start &&
|
||||||
blen == fileLength) {
|
blen == fileLength) {
|
||||||
|
|
||||||
mDirManager->Deref(block.f);
|
|
||||||
block.f = make_blockfile<SilentBlockFile>(blen);
|
block.f = make_blockfile<SilentBlockFile>(blen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1545,7 +1520,6 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
|
|||||||
static_cast< SimpleBlockFile * >( &*newLastBlock.f )
|
static_cast< SimpleBlockFile * >( &*newLastBlock.f )
|
||||||
->SaveXML( *blockFileLog );
|
->SaveXML( *blockFileLog );
|
||||||
|
|
||||||
mDirManager->Deref(lastBlock.f);
|
|
||||||
lastBlock = newLastBlock;
|
lastBlock = newLastBlock;
|
||||||
|
|
||||||
len -= addLen;
|
len -= addLen;
|
||||||
@ -1651,12 +1625,10 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
|
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
|
||||||
b, pos + len, newLen - pos);
|
b, pos + len, newLen - pos);
|
||||||
|
|
||||||
BlockFile *const oldFile = b.f;
|
|
||||||
b = SeqBlock(
|
b = SeqBlock(
|
||||||
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
|
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
|
||||||
b.start
|
b.start
|
||||||
);
|
);
|
||||||
mDirManager->Deref(oldFile);
|
|
||||||
|
|
||||||
for (unsigned int j = b0 + 1; j < numBlocks; j++)
|
for (unsigned int j = b0 + 1; j < numBlocks; j++)
|
||||||
mBlock[j].start -= len;
|
mBlock[j].start -= len;
|
||||||
@ -1705,8 +1677,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
|
|
||||||
newBlock.erase(newBlock.end() - 1);
|
newBlock.erase(newBlock.end() - 1);
|
||||||
Blockify(newBlock, prepreBlock.start, scratch.ptr(), sum);
|
Blockify(newBlock, prepreBlock.start, scratch.ptr(), sum);
|
||||||
|
|
||||||
mDirManager->Deref(prepreBlock.f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1714,15 +1684,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
// right on the beginning of a block.
|
// right on the beginning of a block.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b0 != b1) {
|
|
||||||
mDirManager->Deref(preBlock.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, DELETE blocks strictly between b0 and b1
|
|
||||||
for (i = b0 + 1; i < b1; i++) {
|
|
||||||
mDirManager->Deref(mBlock[i].f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, symmetrically, grab the samples in block b1 after the
|
// Now, symmetrically, grab the samples in block b1 after the
|
||||||
// deletion point into postBuffer. If this is enough samples
|
// deletion point into postBuffer. If this is enough samples
|
||||||
// for its own block, or if this would be the last block in
|
// for its own block, or if this would be the last block in
|
||||||
@ -1757,15 +1718,12 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
|
|
||||||
Blockify(newBlock, start, scratch.ptr(), sum);
|
Blockify(newBlock, start, scratch.ptr(), sum);
|
||||||
b1++;
|
b1++;
|
||||||
|
|
||||||
mDirManager->Deref(postpostBlock.f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The sample where we begin deletion happens to fall
|
// The sample where we begin deletion happens to fall
|
||||||
// right on the end of a block.
|
// right on the end of a block.
|
||||||
}
|
}
|
||||||
mDirManager->Deref(postBlock.f);
|
|
||||||
|
|
||||||
// Copy the remaining blocks over from the old array
|
// Copy the remaining blocks over from the old array
|
||||||
for (i = b1 + 1; i < numBlocks; i++)
|
for (i = b1 + 1; i < numBlocks; i++)
|
||||||
@ -1822,11 +1780,11 @@ void Sequence::DebugPrintf(wxString *dest) const
|
|||||||
for (i = 0; i < mBlock.size(); i++) {
|
for (i = 0; i < mBlock.size(); i++) {
|
||||||
const SeqBlock &seqBlock = mBlock[i];
|
const SeqBlock &seqBlock = mBlock[i];
|
||||||
*dest += wxString::Format
|
*dest += wxString::Format
|
||||||
(wxT(" Block %3u: start %8lld, len %8lld, refs %d, "),
|
(wxT(" Block %3u: start %8lld, len %8lld, refs %ld, "),
|
||||||
i,
|
i,
|
||||||
(long long) seqBlock.start,
|
(long long) seqBlock.start,
|
||||||
seqBlock.f ? (long long) seqBlock.f->GetLength() : 0,
|
seqBlock.f ? (long long) seqBlock.f->GetLength() : 0,
|
||||||
seqBlock.f ? mDirManager->GetRefCount(seqBlock.f) : 0);
|
seqBlock.f ? seqBlock.f.use_count() : 0);
|
||||||
|
|
||||||
if (seqBlock.f)
|
if (seqBlock.f)
|
||||||
*dest += seqBlock.f->GetFileName().name.GetFullName();
|
*dest += seqBlock.f->GetFileName().name.GetFullName();
|
||||||
|
@ -30,7 +30,7 @@ typedef wxLongLong_t sampleCount; /** < A native 64-bit integer type, because
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class BlockFile;
|
class BlockFile;
|
||||||
using BlockFilePtr = BlockFile *;
|
using BlockFilePtr = std::shared_ptr<BlockFile>;
|
||||||
|
|
||||||
class DirManager;
|
class DirManager;
|
||||||
|
|
||||||
@ -238,8 +238,6 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
|||||||
// Private methods
|
// Private methods
|
||||||
//
|
//
|
||||||
|
|
||||||
void DerefAllFiles();
|
|
||||||
|
|
||||||
int FindBlock(sampleCount pos) const;
|
int FindBlock(sampleCount pos) const;
|
||||||
|
|
||||||
bool AppendBlock(const SeqBlock &b);
|
bool AppendBlock(const SeqBlock &b);
|
||||||
|
@ -74,33 +74,6 @@ ODPCMAliasBlockFile::~ODPCMAliasBlockFile()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increases the reference count of this block by one. Only
|
|
||||||
/// DirManager should call this method.
|
|
||||||
/// This method has been overidden to be threadsafe. It is important especially
|
|
||||||
/// if two blockfiles deref at the same time resulting in a double deletion of the file
|
|
||||||
void ODPCMAliasBlockFile::Ref() const
|
|
||||||
{
|
|
||||||
mRefMutex.Lock();
|
|
||||||
BlockFile::Ref();
|
|
||||||
mRefMutex.Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decreases the reference count of this block by one. If this
|
|
||||||
/// causes the count to become zero, deletes the associated disk
|
|
||||||
/// file and deletes this object
|
|
||||||
bool ODPCMAliasBlockFile::Deref() const
|
|
||||||
{
|
|
||||||
bool ret;
|
|
||||||
mDerefMutex.Lock();
|
|
||||||
ret = BlockFile::Deref();
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
//Deref returns true when deleted, in which case we should not be touching instance variables, or ever calling this function again.
|
|
||||||
mDerefMutex.Unlock();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Check to see if we have the file for these calls.
|
//Check to see if we have the file for these calls.
|
||||||
|
@ -143,13 +143,6 @@ protected:
|
|||||||
sampleFormat format, ArrayOf<char> &cleanup) override;
|
sampleFormat format, ArrayOf<char> &cleanup) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Thread-safe versions
|
|
||||||
void Ref() const override;
|
|
||||||
bool Deref() const override;
|
|
||||||
//needed for Ref/Deref access.
|
|
||||||
friend class DirManager;
|
|
||||||
friend class ODComputeSummaryTask;
|
|
||||||
friend class ODDecodeTask;
|
|
||||||
|
|
||||||
ODLock mWriteSummaryMutex;
|
ODLock mWriteSummaryMutex;
|
||||||
|
|
||||||
@ -162,11 +155,6 @@ protected:
|
|||||||
//lock the read data - libsndfile can't handle two reads at once?
|
//lock the read data - libsndfile can't handle two reads at once?
|
||||||
mutable ODLock mReadDataMutex;
|
mutable ODLock mReadDataMutex;
|
||||||
|
|
||||||
|
|
||||||
//lock the Ref counting
|
|
||||||
mutable ODLock mDerefMutex;
|
|
||||||
mutable ODLock mRefMutex;
|
|
||||||
|
|
||||||
mutable ODLock mSummaryAvailableMutex;
|
mutable ODLock mSummaryAvailableMutex;
|
||||||
bool mSummaryAvailable;
|
bool mSummaryAvailable;
|
||||||
bool mSummaryBeingComputed;
|
bool mSummaryBeingComputed;
|
||||||
|
@ -49,8 +49,6 @@ void ODComputeSummaryTask::Terminate()
|
|||||||
//The terminate block won't allow DoSomeInternal and this method to be run async, so this is thread-safe.
|
//The terminate block won't allow DoSomeInternal and this method to be run async, so this is thread-safe.
|
||||||
//Deref the block files since they are ref'ed when put into the array.
|
//Deref the block files since they are ref'ed when put into the array.
|
||||||
mBlockFilesMutex.Lock();
|
mBlockFilesMutex.Lock();
|
||||||
for(unsigned int i=0;i<mBlockFiles.size();i++)
|
|
||||||
mBlockFiles[i]->Deref();
|
|
||||||
mBlockFiles.clear();
|
mBlockFiles.clear();
|
||||||
mBlockFilesMutex.Unlock();
|
mBlockFilesMutex.Unlock();
|
||||||
}
|
}
|
||||||
@ -78,7 +76,7 @@ void ODComputeSummaryTask::DoSomeInternal()
|
|||||||
//first check to see if the ref count is at least 2. It should have one
|
//first check to see if the ref count is at least 2. It should have one
|
||||||
//from when we added it to this instance's mBlockFiles array, and one from
|
//from when we added it to this instance's mBlockFiles array, and one from
|
||||||
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
||||||
if(bf->RefCount()>=2)
|
if(bf.use_count() >= 2)
|
||||||
{
|
{
|
||||||
bf->DoWriteSummary();
|
bf->DoWriteSummary();
|
||||||
success = true;
|
success = true;
|
||||||
@ -93,8 +91,6 @@ void ODComputeSummaryTask::DoSomeInternal()
|
|||||||
mMaxBlockFiles--;
|
mMaxBlockFiles--;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Release the refcount we placed on it.
|
|
||||||
bf->Deref();
|
|
||||||
//take it out of the array - we are done with it.
|
//take it out of the array - we are done with it.
|
||||||
mBlockFiles.erase(mBlockFiles.begin());
|
mBlockFiles.erase(mBlockFiles.begin());
|
||||||
|
|
||||||
@ -169,7 +165,7 @@ void ODComputeSummaryTask::CalculatePercentComplete()
|
|||||||
///by default left to right, or frome the point the user has clicked.
|
///by default left to right, or frome the point the user has clicked.
|
||||||
void ODComputeSummaryTask::Update()
|
void ODComputeSummaryTask::Update()
|
||||||
{
|
{
|
||||||
std::vector<ODPCMAliasBlockFile*> tempBlocks;
|
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > tempBlocks;
|
||||||
|
|
||||||
mWaveTrackMutex.Lock();
|
mWaveTrackMutex.Lock();
|
||||||
|
|
||||||
@ -204,8 +200,8 @@ void ODComputeSummaryTask::Update()
|
|||||||
const auto &file = block.f;
|
const auto &file = block.f;
|
||||||
if(file->IsDataAvailable() && !file->IsSummaryAvailable())
|
if(file->IsDataAvailable() && !file->IsSummaryAvailable())
|
||||||
{
|
{
|
||||||
file->Ref();
|
const auto odpcmaFile =
|
||||||
ODPCMAliasBlockFile *const odpcmaFile = static_cast<ODPCMAliasBlockFile*>(file);
|
std::static_pointer_cast<ODPCMAliasBlockFile>(file);
|
||||||
odpcmaFile->SetStart(block.start);
|
odpcmaFile->SetStart(block.start);
|
||||||
odpcmaFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
|
odpcmaFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
|
||||||
|
|
||||||
@ -234,11 +230,9 @@ void ODComputeSummaryTask::Update()
|
|||||||
|
|
||||||
|
|
||||||
///Computes the summary calculation queue order of the blockfiles
|
///Computes the summary calculation queue order of the blockfiles
|
||||||
void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks)
|
void ODComputeSummaryTask::OrderBlockFiles
|
||||||
|
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks)
|
||||||
{
|
{
|
||||||
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
|
|
||||||
for(unsigned int i=0;i<mBlockFiles.size();i++)
|
|
||||||
mBlockFiles[i]->Deref();
|
|
||||||
mBlockFiles.clear();
|
mBlockFiles.clear();
|
||||||
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
||||||
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
|
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
|
||||||
@ -252,7 +246,7 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
|
|||||||
//check to see if the refcount is at least two before we add it to the list.
|
//check to see if the refcount is at least two before we add it to the list.
|
||||||
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
||||||
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
||||||
if(unorderedBlocks[i]->RefCount()>=2)
|
if(unorderedBlocks[i].use_count() >= 2)
|
||||||
{
|
{
|
||||||
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
||||||
//and add ones that are closer.
|
//and add ones that are closer.
|
||||||
@ -276,7 +270,6 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Otherwise, let it be deleted and forget about it.
|
//Otherwise, let it be deleted and forget about it.
|
||||||
unorderedBlocks[i]->Deref();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,8 @@ protected:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
///Orders the input as either On-Demand or default layered order.
|
///Orders the input as either On-Demand or default layered order.
|
||||||
void OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks);
|
void OrderBlockFiles
|
||||||
|
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks);
|
||||||
|
|
||||||
///tells us whether or not Update has been run at least once.
|
///tells us whether or not Update has been run at least once.
|
||||||
void MarkUpdateRan();
|
void MarkUpdateRan();
|
||||||
@ -72,7 +73,7 @@ protected:
|
|||||||
|
|
||||||
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
|
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
|
||||||
ODLock mBlockFilesMutex;
|
ODLock mBlockFilesMutex;
|
||||||
std::vector<ODPCMAliasBlockFile*> mBlockFiles;
|
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > mBlockFiles;
|
||||||
int mMaxBlockFiles;
|
int mMaxBlockFiles;
|
||||||
int mComputedBlockFiles;
|
int mComputedBlockFiles;
|
||||||
ODLock mHasUpdateRanMutex;
|
ODLock mHasUpdateRanMutex;
|
||||||
|
@ -56,7 +56,7 @@ void ODDecodeTask::DoSomeInternal()
|
|||||||
//first check to see if the ref count is at least 2. It should have one
|
//first check to see if the ref count is at least 2. It should have one
|
||||||
//from when we added it to this instance's mBlockFiles array, and one from
|
//from when we added it to this instance's mBlockFiles array, and one from
|
||||||
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
||||||
if(bf->RefCount()>=2)
|
if(bf.use_count()>=2)
|
||||||
{
|
{
|
||||||
//OD TODO: somehow pass the bf a reference to the decoder that manages it's file.
|
//OD TODO: somehow pass the bf a reference to the decoder that manages it's file.
|
||||||
//we need to ensure that the filename won't change or be moved. We do this by calling LockRead(),
|
//we need to ensure that the filename won't change or be moved. We do this by calling LockRead(),
|
||||||
@ -86,7 +86,6 @@ void ODDecodeTask::DoSomeInternal()
|
|||||||
|
|
||||||
//Release the refcount we placed on it if we are successful
|
//Release the refcount we placed on it if we are successful
|
||||||
if(ret >= 0 ) {
|
if(ret >= 0 ) {
|
||||||
bf->Deref();
|
|
||||||
//take it out of the array - we are done with it.
|
//take it out of the array - we are done with it.
|
||||||
mBlockFiles.erase(mBlockFiles.begin());
|
mBlockFiles.erase(mBlockFiles.begin());
|
||||||
|
|
||||||
@ -126,8 +125,7 @@ bool ODDecodeTask::SeekingAllowed()
|
|||||||
///by default creates the order of the wavetrack to load.
|
///by default creates the order of the wavetrack to load.
|
||||||
void ODDecodeTask::Update()
|
void ODDecodeTask::Update()
|
||||||
{
|
{
|
||||||
|
std::vector< std::shared_ptr< ODDecodeBlockFile > > tempBlocks;
|
||||||
std::vector<ODDecodeBlockFile*> tempBlocks;
|
|
||||||
|
|
||||||
mWaveTrackMutex.Lock();
|
mWaveTrackMutex.Lock();
|
||||||
|
|
||||||
@ -154,12 +152,12 @@ void ODDecodeTask::Update()
|
|||||||
{
|
{
|
||||||
//since we have more than one ODBlockFile, we will need type flags to cast.
|
//since we have more than one ODBlockFile, we will need type flags to cast.
|
||||||
SeqBlock &block = (*blocks)[i];
|
SeqBlock &block = (*blocks)[i];
|
||||||
BlockFile *const file = block.f;
|
const auto &file = block.f;
|
||||||
ODDecodeBlockFile *oddbFile;
|
std::shared_ptr<ODDecodeBlockFile> oddbFile;
|
||||||
if (!file->IsDataAvailable() &&
|
if (!file->IsDataAvailable() &&
|
||||||
(oddbFile = static_cast<ODDecodeBlockFile*>(file))->GetDecodeType() == this->GetODType())
|
(oddbFile =
|
||||||
|
std::static_pointer_cast<ODDecodeBlockFile>(file))->GetDecodeType() == this->GetODType())
|
||||||
{
|
{
|
||||||
file->Ref();
|
|
||||||
oddbFile->SetStart(block.start);
|
oddbFile->SetStart(block.start);
|
||||||
oddbFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
|
oddbFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
|
||||||
|
|
||||||
@ -186,11 +184,9 @@ void ODDecodeTask::Update()
|
|||||||
|
|
||||||
|
|
||||||
///Orders the input as either On-Demand or default layered order.
|
///Orders the input as either On-Demand or default layered order.
|
||||||
void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks)
|
void ODDecodeTask::OrderBlockFiles
|
||||||
|
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks)
|
||||||
{
|
{
|
||||||
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
|
|
||||||
for(unsigned int i=0;i<mBlockFiles.size();i++)
|
|
||||||
mBlockFiles[i]->Deref();
|
|
||||||
mBlockFiles.clear();
|
mBlockFiles.clear();
|
||||||
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
||||||
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
|
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
|
||||||
@ -203,7 +199,7 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
|
|||||||
//check to see if the refcount is at least two before we add it to the list.
|
//check to see if the refcount is at least two before we add it to the list.
|
||||||
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
||||||
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
||||||
if(unorderedBlocks[i]->RefCount()>=2)
|
if(unorderedBlocks[i].use_count() >= 2)
|
||||||
{
|
{
|
||||||
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
||||||
//and add ones that are closer.
|
//and add ones that are closer.
|
||||||
@ -227,8 +223,6 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Otherwise, let it be deleted and forget about it.
|
|
||||||
unorderedBlocks[i]->Deref();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,10 +85,11 @@ protected:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
///Orders the input as either On-Demand or default layered order.
|
///Orders the input as either On-Demand or default layered order.
|
||||||
void OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks);
|
void OrderBlockFiles
|
||||||
|
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks);
|
||||||
|
|
||||||
|
|
||||||
std::vector<ODDecodeBlockFile*> mBlockFiles;
|
std::vector<std::shared_ptr<ODDecodeBlockFile>> mBlockFiles;
|
||||||
std::vector<movable_ptr<ODFileDecoder>> mDecoders;
|
std::vector<movable_ptr<ODFileDecoder>> mDecoders;
|
||||||
|
|
||||||
int mMaxBlockFiles;
|
int mMaxBlockFiles;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user