public static void FixPositions(Container c)
{
EbmlMaster segment = (EbmlMaster)c.FindFirst(Ids.MATROSKA_ID_SEGMENT);
bool repeatpass = false;
List<EbmlGeneric> cuepositions = c.FindAll(Ids.MATROSKA_ID_CUECLUSTERPOSITION);
List<EbmlGeneric> clusters = c.FindAll(Ids.MATROSKA_ID_CLUSTER);
int cnt = 1;
foreach (EbmlUint j in cuepositions)
{
ulong val = j.Value + segment.InputValueOffset;
EbmlMaster repo = (EbmlMaster)clusters.First(a => a.InputOffset == val);
if (repo.LinkedId != 0)
j.LinkedId = repo.LinkedId;
else
{
repo.LinkedId = j.LinkedId = cnt;
cnt++;
}
}
do
{
repeatpass = false;
//Propagate Expected Offsets
c.PropagateExpectedOffset();
//Reposition Cues
foreach (EbmlUint j in cuepositions)
{
EbmlMaster repo = (EbmlMaster)clusters.First(a => a.LinkedId==j.LinkedId);
ulong nvalue = repo.ExpectedOffset - segment.ExpectedValueOffset;
if (nvalue != j.Value)
{
repeatpass = true;
j.Value = nvalue;
}
}
if (!repeatpass)
{
//Propagate Expected Offsets
c.PropagateExpectedOffset();
//Fix Seek Header
EbmlMaster smas = (EbmlMaster)c.FindFirst(Ids.MATROSKA_ID_SEEKHEAD);
List<EbmlGeneric> seeks = c.FindAll(Ids.MATROSKA_ID_SEEKENTRY);
foreach (EbmlMaster sk in seeks)
{
EbmlUint id = (EbmlUint)sk.FindFirst(Ids.MATROSKA_ID_SEEKID);
if (id != null)
{
EbmlUint pos = (EbmlUint)sk.FindFirst(Ids.MATROSKA_ID_SEEKPOSITION);
EbmlGeneric gen = segment.FindFirst(id.Value);
if (gen == null)
{
repeatpass = true;
smas.Value.Remove(sk);
break;
}
ulong nval = gen.ExpectedOffset - segment.ExpectedValueOffset;
if (pos.Value != nval)
{
pos.Value = nval;
repeatpass = true;
}
}
}
}
} while (repeatpass);
}