1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/BufferMediaResource.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,173 @@ 1.4 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#if !defined(BufferMediaResource_h_) 1.10 +#define BufferMediaResource_h_ 1.11 + 1.12 +#include "MediaResource.h" 1.13 +#include "nsISeekableStream.h" 1.14 +#include "nsIPrincipal.h" 1.15 +#include <algorithm> 1.16 + 1.17 +namespace mozilla { 1.18 + 1.19 +// A simple MediaResource based on an in memory buffer. This class accepts 1.20 +// the address and the length of the buffer, and simulates a read/seek API 1.21 +// on top of it. The Read implementation involves copying memory, which is 1.22 +// unfortunate, but the MediaResource interface mandates that. 1.23 +class BufferMediaResource : public MediaResource 1.24 +{ 1.25 +public: 1.26 + BufferMediaResource(const uint8_t* aBuffer, 1.27 + uint32_t aLength, 1.28 + nsIPrincipal* aPrincipal, 1.29 + const nsACString& aContentType) : 1.30 + mBuffer(aBuffer), 1.31 + mLength(aLength), 1.32 + mOffset(0), 1.33 + mPrincipal(aPrincipal), 1.34 + mContentType(aContentType) 1.35 + { 1.36 + MOZ_COUNT_CTOR(BufferMediaResource); 1.37 + } 1.38 + 1.39 + virtual ~BufferMediaResource() 1.40 + { 1.41 + MOZ_COUNT_DTOR(BufferMediaResource); 1.42 + } 1.43 + 1.44 + virtual nsresult Close() { return NS_OK; } 1.45 + virtual void Suspend(bool aCloseImmediately) {} 1.46 + virtual void Resume() {} 1.47 + // Get the current principal for the channel 1.48 + virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() 1.49 + { 1.50 + nsCOMPtr<nsIPrincipal> principal = mPrincipal; 1.51 + return principal.forget(); 1.52 + } 1.53 + virtual bool CanClone() { return false; } 1.54 + virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) 1.55 + { 1.56 + return nullptr; 1.57 + } 1.58 + 1.59 + // These methods are called off the main thread. 1.60 + // The mode is initially MODE_PLAYBACK. 1.61 + virtual void SetReadMode(MediaCacheStream::ReadMode aMode) {} 1.62 + virtual void SetPlaybackRate(uint32_t aBytesPerSecond) {} 1.63 + virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) 1.64 + { 1.65 + *aBytes = std::min(mLength - mOffset, aCount); 1.66 + memcpy(aBuffer, mBuffer + mOffset, *aBytes); 1.67 + mOffset += *aBytes; 1.68 + MOZ_ASSERT(mOffset <= mLength); 1.69 + return NS_OK; 1.70 + } 1.71 + virtual nsresult ReadAt(int64_t aOffset, char* aBuffer, 1.72 + uint32_t aCount, uint32_t* aBytes) 1.73 + { 1.74 + nsresult rv = Seek(nsISeekableStream::NS_SEEK_SET, aOffset); 1.75 + if (NS_FAILED(rv)) return rv; 1.76 + return Read(aBuffer, aCount, aBytes); 1.77 + } 1.78 + virtual nsresult Seek(int32_t aWhence, int64_t aOffset) 1.79 + { 1.80 + MOZ_ASSERT(aOffset <= UINT32_MAX); 1.81 + switch (aWhence) { 1.82 + case nsISeekableStream::NS_SEEK_SET: 1.83 + if (aOffset < 0 || aOffset > mLength) { 1.84 + return NS_ERROR_FAILURE; 1.85 + } 1.86 + mOffset = static_cast<uint32_t> (aOffset); 1.87 + break; 1.88 + case nsISeekableStream::NS_SEEK_CUR: 1.89 + if (aOffset >= mLength - mOffset) { 1.90 + return NS_ERROR_FAILURE; 1.91 + } 1.92 + mOffset += static_cast<uint32_t> (aOffset); 1.93 + break; 1.94 + case nsISeekableStream::NS_SEEK_END: 1.95 + if (aOffset < 0 || aOffset > mLength) { 1.96 + return NS_ERROR_FAILURE; 1.97 + } 1.98 + mOffset = mLength - aOffset; 1.99 + break; 1.100 + } 1.101 + 1.102 + return NS_OK; 1.103 + } 1.104 + virtual void StartSeekingForMetadata() {} 1.105 + virtual void EndSeekingForMetadata() {} 1.106 + virtual int64_t Tell() { return mOffset; } 1.107 + 1.108 + virtual void Pin() {} 1.109 + virtual void Unpin() {} 1.110 + virtual double GetDownloadRate(bool* aIsReliable) { return 0.; } 1.111 + virtual int64_t GetLength() { return mLength; } 1.112 + virtual int64_t GetNextCachedData(int64_t aOffset) { return aOffset; } 1.113 + virtual int64_t GetCachedDataEnd(int64_t aOffset) { return mLength; } 1.114 + virtual bool IsDataCachedToEndOfResource(int64_t aOffset) { return true; } 1.115 + virtual bool IsSuspendedByCache() { return false; } 1.116 + virtual bool IsSuspended() { return false; } 1.117 + virtual nsresult ReadFromCache(char* aBuffer, 1.118 + int64_t aOffset, 1.119 + uint32_t aCount) 1.120 + { 1.121 + if (aOffset < 0) { 1.122 + return NS_ERROR_FAILURE; 1.123 + } 1.124 + 1.125 + uint32_t bytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount); 1.126 + memcpy(aBuffer, mBuffer + aOffset, bytes); 1.127 + return NS_OK; 1.128 + } 1.129 + 1.130 + virtual nsresult Open(nsIStreamListener** aStreamListener) 1.131 + { 1.132 + return NS_ERROR_FAILURE; 1.133 + } 1.134 + 1.135 + virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) 1.136 + { 1.137 + aRanges.AppendElement(MediaByteRange(0, mLength)); 1.138 + return NS_OK; 1.139 + } 1.140 + 1.141 + bool IsTransportSeekable() MOZ_OVERRIDE { return true; } 1.142 + 1.143 + virtual const nsCString& GetContentType() const MOZ_OVERRIDE 1.144 + { 1.145 + return mContentType; 1.146 + } 1.147 + 1.148 + virtual size_t SizeOfExcludingThis( 1.149 + MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE 1.150 + { 1.151 + // Not owned: 1.152 + // - mBuffer 1.153 + // - mPrincipal 1.154 + size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf); 1.155 + size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf); 1.156 + 1.157 + return size; 1.158 + } 1.159 + 1.160 + virtual size_t SizeOfIncludingThis( 1.161 + MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE 1.162 + { 1.163 + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); 1.164 + } 1.165 + 1.166 +private: 1.167 + const uint8_t * mBuffer; 1.168 + uint32_t mLength; 1.169 + uint32_t mOffset; 1.170 + nsCOMPtr<nsIPrincipal> mPrincipal; 1.171 + const nsAutoCString mContentType; 1.172 +}; 1.173 + 1.174 +} 1.175 + 1.176 +#endif