michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "StreamBuffer.h" michael@0: #include "prlog.h" michael@0: #include michael@0: michael@0: namespace mozilla { michael@0: michael@0: #ifdef PR_LOGGING michael@0: extern PRLogModuleInfo* gMediaStreamGraphLog; michael@0: #define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg) michael@0: #else michael@0: #define STREAM_LOG(type, msg) michael@0: #endif michael@0: michael@0: #ifdef DEBUG michael@0: void michael@0: StreamBuffer::DumpTrackInfo() const michael@0: { michael@0: STREAM_LOG(PR_LOG_ALWAYS, ("DumpTracks: mTracksKnownTime %lld", mTracksKnownTime)); michael@0: for (uint32_t i = 0; i < mTracks.Length(); ++i) { michael@0: Track* track = mTracks[i]; michael@0: if (track->IsEnded()) { michael@0: STREAM_LOG(PR_LOG_ALWAYS, ("Track[%d] %d: ended", i, track->GetID())); michael@0: } else { michael@0: STREAM_LOG(PR_LOG_ALWAYS, ("Track[%d] %d: %lld", i, track->GetID(), michael@0: track->GetEndTimeRoundDown())); michael@0: } michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: StreamTime michael@0: StreamBuffer::GetEnd() const michael@0: { michael@0: StreamTime t = mTracksKnownTime; michael@0: for (uint32_t i = 0; i < mTracks.Length(); ++i) { michael@0: Track* track = mTracks[i]; michael@0: if (!track->IsEnded()) { michael@0: t = std::min(t, track->GetEndTimeRoundDown()); michael@0: } michael@0: } michael@0: return t; michael@0: } michael@0: michael@0: StreamTime michael@0: StreamBuffer::GetAllTracksEnd() const michael@0: { michael@0: if (mTracksKnownTime < STREAM_TIME_MAX) { michael@0: // A track might be added. michael@0: return STREAM_TIME_MAX; michael@0: } michael@0: StreamTime t = 0; michael@0: for (uint32_t i = 0; i < mTracks.Length(); ++i) { michael@0: Track* track = mTracks[i]; michael@0: if (!track->IsEnded()) { michael@0: return STREAM_TIME_MAX; michael@0: } michael@0: t = std::max(t, track->GetEndTimeRoundDown()); michael@0: } michael@0: return t; michael@0: } michael@0: michael@0: StreamBuffer::Track* michael@0: StreamBuffer::FindTrack(TrackID aID) michael@0: { michael@0: if (aID == TRACK_NONE) michael@0: return nullptr; michael@0: for (uint32_t i = 0; i < mTracks.Length(); ++i) { michael@0: Track* track = mTracks[i]; michael@0: if (track->GetID() == aID) { michael@0: return track; michael@0: } michael@0: } michael@0: return nullptr; michael@0: } michael@0: michael@0: void michael@0: StreamBuffer::ForgetUpTo(StreamTime aTime) michael@0: { michael@0: // Round to nearest 50ms so we don't spend too much time pruning segments. michael@0: const MediaTime roundTo = MillisecondsToMediaTime(50); michael@0: StreamTime forget = (aTime/roundTo)*roundTo; michael@0: if (forget <= mForgottenTime) { michael@0: return; michael@0: } michael@0: mForgottenTime = forget; michael@0: michael@0: for (uint32_t i = 0; i < mTracks.Length(); ++i) { michael@0: Track* track = mTracks[i]; michael@0: if (track->IsEnded() && track->GetEndTimeRoundDown() <= forget) { michael@0: mTracks.RemoveElementAt(i); michael@0: --i; michael@0: continue; michael@0: } michael@0: TrackTicks forgetTo = std::min(track->GetEnd() - 1, track->TimeToTicksRoundDown(forget)); michael@0: track->ForgetUpTo(forgetTo); michael@0: } michael@0: } michael@0: michael@0: }