JD2022-TU1/main/extern/libwebm/custom/mkvparser/clusters.cpp

101 lines
2.5 KiB
C++

#include "clusters.hpp"
#include "cluster.hpp"
#include <cassert>
#include <algorithm>
namespace mkvparser
{
Clusters::Clusters()
: m_clusterLimit(0)
{
}
Clusters::~Clusters()
{
clear();
}
void Clusters::clear()
{
ClusterVect_t::iterator first = m_clusters.begin();
ClusterVect_t::iterator last = m_clusters.end();
for ( ; first != last; ++first)
{
Cluster* const p = *first;
assert(p);
delete p;
}
m_clusters.clear();
}
Clusters::iterator Clusters::insert(iterator position, const value_type& val)
{
if (m_clusterLimit != 0 && m_clusters.size() >= m_clusterLimit)
position = RemoveOneCluster(position);
return m_clusters.insert(position, val);
}
void Clusters::SetClusterDestructionObserver(ClusterDestructionObserver* observer)
{
m_observers.push_back(observer);
}
void Clusters::RemoveClusterDestructionObserver(ClusterDestructionObserver* observer)
{
ObserverVect_t::iterator it = std::find(m_observers.begin(), m_observers.end(), observer);
if (it != m_observers.end())
m_observers.erase(it);
}
Clusters::iterator Clusters::RemoveOneCluster(iterator insertPosition)
{
// try to remove clusters behind insert position
if (!m_clusters.empty())
{
typedef std::iterator_traits<iterator>::difference_type diff_type;
diff_type posFromBegin = std::distance(m_clusters.begin(), insertPosition);
for (size_type i = 0; i < size_type(posFromBegin); ++i)
{
if (TryRemoveClusterAt(i))
{
--posFromBegin;
return m_clusters.begin() + posFromBegin;
}
}
// could not remove from the beginning, try from the end
for (size_type i = m_clusters.size() - 1; i > size_type(posFromBegin); --i)
{
if (TryRemoveClusterAt(i))
return m_clusters.begin() + posFromBegin;
}
}
// no removal
return insertPosition;
}
bool Clusters::TryRemoveClusterAt(size_type n)
{
bool canRemove = true;
ObserverVect_t::const_iterator first = m_observers.begin();
ObserverVect_t::const_iterator last = m_observers.end();
for (; first != last; ++first)
canRemove = canRemove && (*first)->CanDestroyCluster(m_clusters[n]);
if (canRemove)
{
// remove
Cluster* c = m_clusters[n];
delete c;
m_clusters.erase(m_clusters.begin() + n);
return true;
}
return false;
}
} // namespace mkvparser