1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "StreamTracks.h"
7 #include "mozilla/Logging.h"
8 #include <algorithm>
9 
10 namespace mozilla {
11 
12 #ifdef DEBUG
13 
14 extern LazyLogModule gMediaStreamGraphLog;
15 #define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
16 
DumpTrackInfo() const17 void StreamTracks::DumpTrackInfo() const {
18   STREAM_LOG(LogLevel::Info,
19              ("DumpTracks: mTracksKnownTime %" PRId64, mTracksKnownTime));
20   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
21     Track* track = mTracks[i];
22     if (track->IsEnded()) {
23       STREAM_LOG(LogLevel::Info, ("Track[%d] %d: ended", i, track->GetID()));
24     } else {
25       STREAM_LOG(LogLevel::Info, ("Track[%d] %d: %" PRId64 "", i,
26                                   track->GetID(), track->GetEnd()));
27     }
28   }
29 }
30 #endif
31 
GetEnd() const32 StreamTime StreamTracks::GetEnd() const {
33   StreamTime t = mTracksKnownTime;
34   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
35     Track* track = mTracks[i];
36     if (!track->IsEnded()) {
37       t = std::min(t, track->GetEnd());
38     }
39   }
40   return t;
41 }
42 
GetAllTracksEnd() const43 StreamTime StreamTracks::GetAllTracksEnd() const {
44   if (mTracksKnownTime < STREAM_TIME_MAX) {
45     // A track might be added.
46     return STREAM_TIME_MAX;
47   }
48   StreamTime t = 0;
49   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
50     Track* track = mTracks[i];
51     if (!track->IsEnded()) {
52       return STREAM_TIME_MAX;
53     }
54     t = std::max(t, track->GetEnd());
55   }
56   return t;
57 }
58 
FindTrack(TrackID aID) const59 StreamTracks::Track* StreamTracks::FindTrack(TrackID aID) const {
60   if (aID == TRACK_NONE || mTracks.IsEmpty()) {
61     return nullptr;
62   }
63 
64   // The tracks are sorted by ID. We can use a binary search.
65 
66   uint32_t left = 0, right = mTracks.Length() - 1;
67   while (left <= right) {
68     uint32_t middle = (left + right) / 2;
69     if (mTracks[middle]->GetID() == aID) {
70       return mTracks[middle];
71     }
72 
73     if (mTracks[middle]->GetID() > aID) {
74       if (middle == 0) {
75         break;
76       }
77 
78       right = middle - 1;
79     } else {
80       left = middle + 1;
81     }
82   }
83 
84   return nullptr;
85 }
86 
ForgetUpTo(StreamTime aTime)87 void StreamTracks::ForgetUpTo(StreamTime aTime) {
88   // Only prune if there is a reasonable chunk (50ms @ 48kHz) to forget, so we
89   // don't spend too much time pruning segments.
90   const StreamTime minChunkSize = 2400;
91   if (aTime < mForgottenTime + minChunkSize) {
92     return;
93   }
94   mForgottenTime = aTime;
95 
96   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
97     Track* track = mTracks[i];
98     StreamTime forgetTo = std::min(track->GetEnd() - 1, aTime);
99     track->ForgetUpTo(forgetTo);
100   }
101 }
102 
Clear()103 void StreamTracks::Clear() { mTracks.Clear(); }
104 
105 }  // namespace mozilla
106