SourceBufferResource.cpp (4933B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "SourceBufferResource.h" 8 9 #include "MediaData.h" 10 #include "mozilla/Logging.h" 11 #include "mozilla/TaskQueue.h" 12 13 mozilla::LogModule* GetSourceBufferResourceLog() { 14 static mozilla::LazyLogModule sLogModule("SourceBufferResource"); 15 return sLogModule; 16 } 17 18 #define SBR_DEBUG(arg, ...) \ 19 DDMOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, \ 20 "::%s: " arg, __func__, ##__VA_ARGS__) 21 #define SBR_DEBUGV(arg, ...) \ 22 DDMOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, \ 23 "::%s: " arg, __func__, ##__VA_ARGS__) 24 25 namespace mozilla { 26 27 RefPtr<GenericPromise> SourceBufferResource::Close() { 28 MOZ_ASSERT(OnThread()); 29 SBR_DEBUG("Close"); 30 mClosed = true; 31 return GenericPromise::CreateAndResolve(true, __func__); 32 } 33 34 nsresult SourceBufferResource::ReadAt(int64_t aOffset, char* aBuffer, 35 uint32_t aCount, uint32_t* aBytes) { 36 SBR_DEBUG("ReadAt(aOffset=%" PRId64 ", aBuffer=%p, aCount=%u, aBytes=%p)", 37 aOffset, aBytes, aCount, aBytes); 38 return ReadAtInternal(aOffset, aBuffer, aCount, aBytes); 39 } 40 41 nsresult SourceBufferResource::ReadAtInternal(int64_t aOffset, char* aBuffer, 42 uint32_t aCount, 43 uint32_t* aBytes) { 44 MOZ_ASSERT(OnThread()); 45 MOZ_ASSERT(aOffset >= 0); 46 uint32_t available = mInputBuffer.GetLength() - aOffset; 47 uint32_t count = std::min(aCount, available); 48 SBR_DEBUGV("offset=%" PRId64 " GetLength()=%" PRIu64 49 " available=%u count=%u mEnded=%d", 50 aOffset, mInputBuffer.GetLength(), available, count, mEnded); 51 52 if (mClosed) { 53 return NS_ERROR_DOM_INVALID_STATE_ERR; 54 } 55 if (aOffset < 0) { 56 return NS_ERROR_DOM_MEDIA_RANGE_ERR; 57 } 58 if (static_cast<uint64_t>(aOffset) < mInputBuffer.GetOffset()) { 59 // Requested bytes have been evicted. 60 return NS_ERROR_NOT_AVAILABLE; 61 } 62 if (mEnded) { 63 if (static_cast<uint64_t>(aOffset) > mInputBuffer.GetLength()) { 64 return NS_ERROR_DOM_MEDIA_RANGE_ERR; 65 } 66 } else { 67 if (static_cast<uint64_t>(aOffset) + aCount > mInputBuffer.GetLength()) { 68 return NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA; 69 } 70 } 71 72 if (available == 0) { 73 SBR_DEBUGV("reached EOF"); 74 *aBytes = 0; 75 return NS_OK; 76 } 77 78 mInputBuffer.CopyData(aOffset, count, aBuffer); 79 *aBytes = count; 80 81 return NS_OK; 82 } 83 84 nsresult SourceBufferResource::ReadFromCache(char* aBuffer, int64_t aOffset, 85 uint32_t aCount) { 86 SBR_DEBUG("ReadFromCache(aBuffer=%p, aOffset=%" PRId64 ", aCount=%u)", 87 aBuffer, aOffset, aCount); 88 uint32_t bytesRead; 89 nsresult rv = ReadAtInternal(aOffset, aBuffer, aCount, &bytesRead); 90 NS_ENSURE_SUCCESS(rv, rv); 91 92 // ReadFromCache return failure if not all the data is cached. 93 return bytesRead == aCount ? NS_OK : NS_ERROR_FAILURE; 94 } 95 96 uint32_t SourceBufferResource::EvictData(uint64_t aPlaybackOffset, 97 int64_t aThreshold) { 98 MOZ_ASSERT(OnThread()); 99 SBR_DEBUG("EvictData(aPlaybackOffset=%" PRIu64 100 "," 101 "aThreshold=%" PRId64 ")", 102 aPlaybackOffset, aThreshold); 103 uint32_t result = mInputBuffer.Evict(aPlaybackOffset, aThreshold); 104 return result; 105 } 106 107 void SourceBufferResource::EvictBefore(uint64_t aOffset) { 108 MOZ_ASSERT(OnThread()); 109 SBR_DEBUG("EvictBefore(aOffset=%" PRIu64 ")", aOffset); 110 111 mInputBuffer.EvictBefore(aOffset); 112 } 113 114 uint32_t SourceBufferResource::EvictAll() { 115 MOZ_ASSERT(OnThread()); 116 SBR_DEBUG("EvictAll()"); 117 return mInputBuffer.EvictAll(); 118 } 119 120 void SourceBufferResource::AppendData(MediaByteBuffer* aData) { 121 AppendData(MediaSpan(aData)); 122 } 123 124 void SourceBufferResource::AppendData(const MediaSpan& aData) { 125 MOZ_ASSERT(OnThread()); 126 SBR_DEBUG("AppendData(aData=%p, aLength=%zu)", aData.Elements(), 127 aData.Length()); 128 mInputBuffer.AppendItem(aData); 129 mEnded = false; 130 } 131 132 void SourceBufferResource::Ended() { 133 MOZ_ASSERT(OnThread()); 134 SBR_DEBUG(""); 135 mEnded = true; 136 } 137 138 SourceBufferResource::~SourceBufferResource() { SBR_DEBUG(""); } 139 140 SourceBufferResource::SourceBufferResource() 141 #if defined(DEBUG) 142 : mThread(AbstractThread::GetCurrent()) 143 #endif 144 { 145 SBR_DEBUG(""); 146 } 147 148 #if defined(DEBUG) 149 const AbstractThread* SourceBufferResource::GetThread() const { 150 return mThread; 151 } 152 bool SourceBufferResource::OnThread() const { 153 return !GetThread() || GetThread()->IsCurrentThreadIn(); 154 } 155 #endif 156 157 #undef SBR_DEBUG 158 #undef SBR_DEBUGV 159 } // namespace mozilla