Index: /trunk/src/VBox/Main/include/WebMWriter.h
===================================================================
--- /trunk/src/VBox/Main/include/WebMWriter.h	(revision 75029)
+++ /trunk/src/VBox/Main/include/WebMWriter.h	(revision 75030)
@@ -289,19 +289,56 @@
 
     /**
+     * Structure for a single cue point track position entry.
+     */
+    struct WebMCueTrackPosEntry
+    {
+        WebMCueTrackPosEntry(uint64_t a_offCluster)
+            : offCluster(a_offCluster) { }
+
+        /** Offset (in bytes) of the related cluster containing the given position. */
+        uint64_t offCluster;
+    };
+
+    /** Map for keeping track position entries for a single cue point.
+     *  The key is the track number (*not* UUID!). */
+    typedef std::map<uint8_t, WebMCueTrackPosEntry *> WebMCueTrackPosMap;
+
+    /**
      * Structure for keeping a cue point.
      */
     struct WebMCuePoint
     {
-        WebMCuePoint(WebMTrack *a_pTrack, uint64_t a_offCluster, WebMTimecodeAbs a_tcAbs)
-            : pTrack(a_pTrack)
-            , offCluster(a_offCluster), tcAbs(a_tcAbs) { }
-
-        /** Associated track. */
-        WebMTrack      *pTrack;
-        /** Offset (in bytes) of the related cluster containing the given position. */
-        uint64_t        offCluster;
+        WebMCuePoint(WebMTimecodeAbs a_tcAbs)
+            : tcAbs(a_tcAbs) { }
+
+        virtual ~WebMCuePoint()
+        {
+            Clear();
+        }
+
+        void Clear(void)
+        {
+            WebMCueTrackPosMap::iterator itTrackPos = Pos.begin();
+            while (itTrackPos != Pos.end())
+            {
+                WebMCueTrackPosEntry *pTrackPos = itTrackPos->second;
+                AssertPtr(pTrackPos);
+                delete pTrackPos;
+
+                Pos.erase(itTrackPos);
+                itTrackPos = Pos.begin();
+            }
+
+            Assert(Pos.empty());
+        }
+
+        /** Map containing all track positions for this specific cue point. */
+        WebMCueTrackPosMap Pos;
         /** Absolute time code according to the segment time base. */
-        WebMTimecodeAbs tcAbs;
-    };
+        WebMTimecodeAbs    tcAbs;
+    };
+
+    /** List of cue points. */
+    typedef std::list<WebMCuePoint *> WebMCuePointList;
 
     /**
@@ -383,5 +420,5 @@
         uint64_t                        offCues;
         /** List of cue points. Needed for seeking table. */
-        std::list<WebMCuePoint>         lstCues;
+        WebMCuePointList                lstCuePoints;
 
         /** Total number of clusters. */
Index: /trunk/src/VBox/Main/src-client/WebMWriter.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/WebMWriter.cpp	(revision 75029)
+++ /trunk/src/VBox/Main/src-client/WebMWriter.cpp	(revision 75030)
@@ -680,17 +680,15 @@
                       Cluster.uID, Cluster.tcAbsStartMs, mapAbsPTSMs, Cluster.offStart));
 
-            if (CurSeg.cClusters)
-                AssertMsg(Cluster.tcAbsStartMs, ("[C%RU64] @ %RU64 starting timecode is 0 which is invalid\n",
-                                                 Cluster.uID, Cluster.offStart));
+            /* Insert cue points for all tracks if a new cluster has been started. */
+            WebMCuePoint *pCuePoint = new WebMCuePoint(Cluster.tcAbsStartMs);
 
             WebMTracks::iterator itTrack = CurSeg.mapTracks.begin();
             while (itTrack != CurSeg.mapTracks.end())
             {
-                /* Insert cue points for all tracks if a new cluster has been started. */
-                WebMCuePoint cue(itTrack->second /* pTrack */, Cluster.offStart, Cluster.tcAbsStartMs);
-                CurSeg.lstCues.push_back(cue);
-
+                pCuePoint->Pos[itTrack->first] = new WebMCueTrackPosEntry(Cluster.offStart);
                 ++itTrack;
             }
+
+            CurSeg.lstCuePoints.push_back(pCuePoint);
 
             subStart(MkvElem_Cluster)
@@ -731,6 +729,15 @@
                 && (pBlock->Data.fFlags & VBOX_WEBM_BLOCK_FLAG_KEY_FRAME))
             {
-                WebMCuePoint cue(pBlock->pTrack, Cluster.offStart, Cluster.tcAbsStartMs);
-                CurSeg.lstCues.push_back(cue);
+                /* Insert cue points for all tracks if a new cluster has been started. */
+                WebMCuePoint *pCuePoint = new WebMCuePoint(CurSeg.tcAbsLastWrittenMs);
+
+                WebMTracks::iterator itTrack = CurSeg.mapTracks.begin();
+                while (itTrack != CurSeg.mapTracks.end())
+                {
+                    pCuePoint->Pos[itTrack->first] = new WebMCueTrackPosEntry(Cluster.offStart);
+                    ++itTrack;
+                }
+
+                CurSeg.lstCuePoints.push_back(pCuePoint);
             }
 
@@ -784,23 +791,36 @@
     subStart(MkvElem_Cues);
 
-    std::list<WebMCuePoint>::iterator itCuePoint = CurSeg.lstCues.begin();
-    while (itCuePoint != CurSeg.lstCues.end())
-    {
-        /* Sanity. */
-        AssertPtr(itCuePoint->pTrack);
-
-        LogFunc(("CuePoint @ %RU64: Track #%RU8 (Cluster @ %RU64, tcAbs=%RU64)\n",
-                 RTFileTell(getFile()), itCuePoint->pTrack->uTrack,
-                 itCuePoint->offCluster, itCuePoint->tcAbs));
+    WebMCuePointList::iterator itCuePoint = CurSeg.lstCuePoints.begin();
+    while (itCuePoint != CurSeg.lstCuePoints.end())
+    {
+        WebMCuePoint *pCuePoint = (*itCuePoint);
+        AssertPtr(pCuePoint);
+
+        LogFunc(("CuePoint @ %RU64: %zu tracks, tcAbs=%RU64)\n",
+                 RTFileTell(getFile()), pCuePoint->Pos.size(), pCuePoint->tcAbs));
 
         subStart(MkvElem_CuePoint)
-            .serializeUnsignedInteger(MkvElem_CueTime,                itCuePoint->tcAbs)
-            .subStart(MkvElem_CueTrackPositions)
-                .serializeUnsignedInteger(MkvElem_CueTrack,           itCuePoint->pTrack->uTrack)
-                .serializeUnsignedInteger(MkvElem_CueClusterPosition, itCuePoint->offCluster - CurSeg.offStart, 8)
-                .subEnd(MkvElem_CueTrackPositions)
-            .subEnd(MkvElem_CuePoint);
-
-        itCuePoint++;
+            .serializeUnsignedInteger(MkvElem_CueTime, pCuePoint->tcAbs);
+
+            WebMCueTrackPosMap::iterator itTrackPos = pCuePoint->Pos.begin();
+            while (itTrackPos != pCuePoint->Pos.end())
+            {
+                WebMCueTrackPosEntry *pTrackPos = itTrackPos->second;
+                AssertPtr(pTrackPos);
+
+                LogFunc(("TrackPos (track #%RU32) @ %RU64, offCluster=%RU64)\n",
+                         itTrackPos->first, RTFileTell(getFile()), pTrackPos->offCluster));
+
+                subStart(MkvElem_CueTrackPositions)
+                    .serializeUnsignedInteger(MkvElem_CueTrack,           itTrackPos->first)
+                    .serializeUnsignedInteger(MkvElem_CueClusterPosition, pTrackPos->offCluster - CurSeg.offStart, 8)
+                    .subEnd(MkvElem_CueTrackPositions);
+
+                ++itTrackPos;
+            }
+
+        subEnd(MkvElem_CuePoint);
+
+        ++itCuePoint;
     }
 
@@ -872,5 +892,5 @@
     const WebMTimecodeAbs tcAbsDurationMs = CurSeg.tcAbsLastWrittenMs - CurSeg.tcAbsStartMs;
 
-    if (!CurSeg.lstCues.empty())
+    if (!CurSeg.lstCuePoints.empty())
     {
         LogFunc(("tcAbsDurationMs=%RU64\n", tcAbsDurationMs));
