SourceBufferResource.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* -*- Mode: C++; tab-width: 8; 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
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "SourceBufferResource.h"
  6. #include <algorithm>
  7. #include "nsISeekableStream.h"
  8. #include "nsISupports.h"
  9. #include "mozilla/Logging.h"
  10. #include "MediaData.h"
  11. mozilla::LogModule* GetSourceBufferResourceLog()
  12. {
  13. static mozilla::LazyLogModule sLogModule("SourceBufferResource");
  14. return sLogModule;
  15. }
  16. #define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
  17. #define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
  18. namespace mozilla {
  19. nsresult
  20. SourceBufferResource::Close()
  21. {
  22. ReentrantMonitorAutoEnter mon(mMonitor);
  23. SBR_DEBUG("Close");
  24. //MOZ_ASSERT(!mClosed);
  25. mClosed = true;
  26. mon.NotifyAll();
  27. return NS_OK;
  28. }
  29. nsresult
  30. SourceBufferResource::ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes)
  31. {
  32. SBR_DEBUG("ReadAt(aOffset=%lld, aBuffer=%p, aCount=%u, aBytes=%p)",
  33. aOffset, aBytes, aCount, aBytes);
  34. ReentrantMonitorAutoEnter mon(mMonitor);
  35. return ReadAtInternal(aOffset, aBuffer, aCount, aBytes, /* aMayBlock = */ true);
  36. }
  37. nsresult
  38. SourceBufferResource::ReadAtInternal(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes,
  39. bool aMayBlock)
  40. {
  41. mMonitor.AssertCurrentThreadIn();
  42. MOZ_ASSERT_IF(!aMayBlock, aBytes);
  43. if (mClosed ||
  44. aOffset < 0 ||
  45. uint64_t(aOffset) < mInputBuffer.GetOffset() ||
  46. aOffset > GetLength()) {
  47. return NS_ERROR_FAILURE;
  48. }
  49. while (aMayBlock &&
  50. !mEnded &&
  51. aOffset + aCount > GetLength()) {
  52. SBR_DEBUGV("waiting for data");
  53. mMonitor.Wait();
  54. // The callers of this function should have checked this, but it's
  55. // possible that we had an eviction while waiting on the monitor.
  56. if (uint64_t(aOffset) < mInputBuffer.GetOffset()) {
  57. return NS_ERROR_FAILURE;
  58. }
  59. }
  60. uint32_t available = GetLength() - aOffset;
  61. uint32_t count = std::min(aCount, available);
  62. // Keep the position of the last read to have Tell() approximately give us
  63. // the position we're up to in the stream.
  64. mOffset = aOffset + count;
  65. SBR_DEBUGV("offset=%llu GetLength()=%u available=%u count=%u mEnded=%d",
  66. aOffset, GetLength(), available, count, mEnded);
  67. if (available == 0) {
  68. SBR_DEBUGV("reached EOF");
  69. *aBytes = 0;
  70. return NS_OK;
  71. }
  72. mInputBuffer.CopyData(aOffset, count, aBuffer);
  73. *aBytes = count;
  74. return NS_OK;
  75. }
  76. nsresult
  77. SourceBufferResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
  78. {
  79. SBR_DEBUG("ReadFromCache(aBuffer=%p, aOffset=%lld, aCount=%u)",
  80. aBuffer, aOffset, aCount);
  81. ReentrantMonitorAutoEnter mon(mMonitor);
  82. uint32_t bytesRead;
  83. nsresult rv = ReadAtInternal(aOffset, aBuffer, aCount, &bytesRead, /* aMayBlock = */ false);
  84. NS_ENSURE_SUCCESS(rv, rv);
  85. // ReadFromCache return failure if not all the data is cached.
  86. return bytesRead == aCount ? NS_OK : NS_ERROR_FAILURE;
  87. }
  88. uint32_t
  89. SourceBufferResource::EvictData(uint64_t aPlaybackOffset, int64_t aThreshold,
  90. ErrorResult& aRv)
  91. {
  92. SBR_DEBUG("EvictData(aPlaybackOffset=%llu,"
  93. "aThreshold=%u)", aPlaybackOffset, aThreshold);
  94. ReentrantMonitorAutoEnter mon(mMonitor);
  95. uint32_t result = mInputBuffer.Evict(aPlaybackOffset, aThreshold, aRv);
  96. if (result > 0) {
  97. // Wake up any waiting threads in case a ReadInternal call
  98. // is now invalid.
  99. mon.NotifyAll();
  100. }
  101. return result;
  102. }
  103. void
  104. SourceBufferResource::EvictBefore(uint64_t aOffset, ErrorResult& aRv)
  105. {
  106. SBR_DEBUG("EvictBefore(aOffset=%llu)", aOffset);
  107. ReentrantMonitorAutoEnter mon(mMonitor);
  108. mInputBuffer.EvictBefore(aOffset, aRv);
  109. // Wake up any waiting threads in case a ReadInternal call
  110. // is now invalid.
  111. mon.NotifyAll();
  112. }
  113. uint32_t
  114. SourceBufferResource::EvictAll()
  115. {
  116. SBR_DEBUG("EvictAll()");
  117. ReentrantMonitorAutoEnter mon(mMonitor);
  118. return mInputBuffer.EvictAll();
  119. }
  120. void
  121. SourceBufferResource::AppendData(MediaByteBuffer* aData)
  122. {
  123. SBR_DEBUG("AppendData(aData=%p, aLength=%u)",
  124. aData->Elements(), aData->Length());
  125. ReentrantMonitorAutoEnter mon(mMonitor);
  126. mInputBuffer.AppendItem(aData);
  127. mEnded = false;
  128. mon.NotifyAll();
  129. }
  130. void
  131. SourceBufferResource::Ended()
  132. {
  133. SBR_DEBUG("");
  134. ReentrantMonitorAutoEnter mon(mMonitor);
  135. mEnded = true;
  136. mon.NotifyAll();
  137. }
  138. SourceBufferResource::~SourceBufferResource()
  139. {
  140. SBR_DEBUG("");
  141. MOZ_COUNT_DTOR(SourceBufferResource);
  142. }
  143. SourceBufferResource::SourceBufferResource(const nsACString& aType)
  144. : mType(aType)
  145. , mMonitor("mozilla::SourceBufferResource::mMonitor")
  146. , mOffset(0)
  147. , mClosed(false)
  148. , mEnded(false)
  149. {
  150. SBR_DEBUG("");
  151. MOZ_COUNT_CTOR(SourceBufferResource);
  152. }
  153. #undef SBR_DEBUG
  154. #undef SBR_DEBUGV
  155. } // namespace mozilla