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