FileMediaResource.h (4975B)
1 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 6 #ifndef mozilla_dom_media_FileMediaResource_h 7 #define mozilla_dom_media_FileMediaResource_h 8 9 #include "BaseMediaResource.h" 10 #include "mozilla/Mutex.h" 11 12 namespace mozilla { 13 14 class FileMediaResource : public BaseMediaResource { 15 public: 16 FileMediaResource(MediaResourceCallback* aCallback, nsIChannel* aChannel, 17 nsIURI* aURI, int64_t aSize = -1 /* unknown size */) 18 : BaseMediaResource(aCallback, aChannel, aURI), 19 mSize(aSize), 20 mLock("FileMediaResource.mLock"), 21 mSizeInitialized(aSize != -1) {} 22 ~FileMediaResource() = default; 23 24 // Main thread 25 nsresult Open(nsIStreamListener** aStreamListener) override; 26 RefPtr<GenericPromise> Close() override; 27 void Suspend(bool aCloseImmediately) override {} 28 void Resume() override {} 29 already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override; 30 bool HadCrossOriginRedirects() override; 31 nsresult ReadFromCache(char* aBuffer, int64_t aOffset, 32 uint32_t aCount) override; 33 34 // These methods are called off the main thread. 35 36 // Other thread 37 void SetReadMode(MediaCacheStream::ReadMode aMode) override {} 38 void SetPlaybackRate(uint32_t aBytesPerSecond) override {} 39 nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, 40 uint32_t* aBytes) override; 41 // (Probably) file-based, caching recommended. 42 bool ShouldCacheReads() override { return true; } 43 44 // Any thread 45 void Pin() override {} 46 void Unpin() override {} 47 double GetDownloadRate(bool* aIsReliable) override { 48 // The data's all already here 49 *aIsReliable = true; 50 return 100 * 1024 * 1024; // arbitray, use 100MB/s 51 } 52 53 int64_t GetLength() override { 54 MutexAutoLock lock(mLock); 55 56 EnsureSizeInitialized(); 57 return mSizeInitialized ? mSize : 0; 58 } 59 60 int64_t GetNextCachedData(int64_t aOffset) override { 61 MutexAutoLock lock(mLock); 62 63 EnsureSizeInitialized(); 64 return (aOffset < mSize) ? aOffset : -1; 65 } 66 67 int64_t GetCachedDataEnd(int64_t aOffset) override { 68 MutexAutoLock lock(mLock); 69 70 EnsureSizeInitialized(); 71 return std::max(aOffset, mSize); 72 } 73 bool IsDataCachedToEndOfResource(int64_t aOffset) override { return true; } 74 bool IsTransportSeekable() override { return true; } 75 76 nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override; 77 78 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { 79 // Might be useful to track in the future: 80 // - mInput 81 return BaseMediaResource::SizeOfExcludingThis(aMallocSizeOf); 82 } 83 84 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override { 85 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); 86 } 87 88 protected: 89 // These Unsafe variants of Read and Seek perform their operations 90 // without acquiring mLock. The caller must obtain the lock before 91 // calling. The implmentation of Read, Seek and ReadAt obtains the 92 // lock before calling these Unsafe variants to read or seek. 93 nsresult UnsafeRead(char* aBuffer, uint32_t aCount, uint32_t* aBytes) 94 MOZ_REQUIRES(mLock); 95 nsresult UnsafeSeek(int32_t aWhence, int64_t aOffset) MOZ_REQUIRES(mLock); 96 97 private: 98 // Ensures mSize is initialized, if it can be. 99 // mLock must be held when this is called, and mInput must be non-null. 100 void EnsureSizeInitialized() MOZ_REQUIRES(mLock); 101 already_AddRefed<MediaByteBuffer> UnsafeMediaReadAt(int64_t aOffset, 102 uint32_t aCount) 103 MOZ_REQUIRES(mLock); 104 105 // The file size, or -1 if not known. Immutable after Open(). 106 // Can be used from any thread. 107 // XXX FIX? is this under mLock? comments are contradictory 108 int64_t mSize MOZ_GUARDED_BY(mLock); 109 110 // This lock handles synchronisation between calls to Close() and 111 // the Read, Seek, etc calls. Close must not be called while a 112 // Read or Seek is in progress since it resets various internal 113 // values to null. 114 // This lock protects mSeekable, mInput, mSize, and mSizeInitialized. 115 Mutex mLock; 116 117 // Seekable stream interface to file. This can be used from any 118 // thread. 119 nsCOMPtr<nsISeekableStream> mSeekable MOZ_GUARDED_BY(mLock); 120 121 // Input stream for the media data. This can be used from any 122 // thread. 123 nsCOMPtr<nsIInputStream> mInput MOZ_GUARDED_BY(mLock); 124 125 // Whether we've attempted to initialize mSize. Note that mSize can be -1 126 // when mSizeInitialized is true if we tried and failed to get the size 127 // of the file. 128 bool mSizeInitialized MOZ_GUARDED_BY(mLock); 129 // Set to true if NotifyDataEnded callback has been processed (which only 130 // occurs if resource size is known) 131 bool mNotifyDataEndedProcessed = false; 132 }; 133 134 } // namespace mozilla 135 136 #endif // mozilla_dom_media_FileMediaResource_h