1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/wmf/WMFByteStream.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,684 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "WMF.h" 1.11 + 1.12 +#include <unknwn.h> 1.13 +#include <ole2.h> 1.14 + 1.15 +#include "WMFByteStream.h" 1.16 +#include "WMFSourceReaderCallback.h" 1.17 +#include "WMFUtils.h" 1.18 +#include "MediaResource.h" 1.19 +#include "nsISeekableStream.h" 1.20 +#include "mozilla/RefPtr.h" 1.21 +#include "nsIThreadPool.h" 1.22 +#include "nsXPCOMCIDInternal.h" 1.23 +#include "nsComponentManagerUtils.h" 1.24 +#include "mozilla/DebugOnly.h" 1.25 +#include "SharedThreadPool.h" 1.26 +#include <algorithm> 1.27 +#include <cassert> 1.28 + 1.29 +namespace mozilla { 1.30 + 1.31 +#ifdef PR_LOGGING 1.32 +PRLogModuleInfo* gWMFByteStreamLog = nullptr; 1.33 +#define WMF_BS_LOG(...) PR_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__)) 1.34 +#else 1.35 +#define WMF_BS_LOG(...) 1.36 +#endif 1.37 + 1.38 +WMFByteStream::WMFByteStream(MediaResource* aResource, 1.39 + WMFSourceReaderCallback* aSourceReaderCallback) 1.40 + : mSourceReaderCallback(aSourceReaderCallback), 1.41 + mResource(aResource), 1.42 + mReentrantMonitor("WMFByteStream.Data"), 1.43 + mOffset(0), 1.44 + mIsShutdown(false) 1.45 +{ 1.46 + NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); 1.47 + NS_ASSERTION(mSourceReaderCallback, "Must have a source reader callback."); 1.48 + 1.49 +#ifdef PR_LOGGING 1.50 + if (!gWMFByteStreamLog) { 1.51 + gWMFByteStreamLog = PR_NewLogModule("WMFByteStream"); 1.52 + } 1.53 +#endif 1.54 + WMF_BS_LOG("[%p] WMFByteStream CTOR", this); 1.55 + MOZ_COUNT_CTOR(WMFByteStream); 1.56 +} 1.57 + 1.58 +WMFByteStream::~WMFByteStream() 1.59 +{ 1.60 + MOZ_COUNT_DTOR(WMFByteStream); 1.61 + WMF_BS_LOG("[%p] WMFByteStream DTOR", this); 1.62 +} 1.63 + 1.64 +nsresult 1.65 +WMFByteStream::Init() 1.66 +{ 1.67 + NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); 1.68 + 1.69 + mThreadPool = SharedThreadPool::Get(NS_LITERAL_CSTRING("WMFByteStream IO"), 4); 1.70 + NS_ENSURE_TRUE(mThreadPool, NS_ERROR_FAILURE); 1.71 + 1.72 + NS_ConvertUTF8toUTF16 contentTypeUTF16(mResource->GetContentType()); 1.73 + if (!contentTypeUTF16.IsEmpty()) { 1.74 + HRESULT hr = wmf::MFCreateAttributes(byRef(mAttributes), 1); 1.75 + NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); 1.76 + 1.77 + hr = mAttributes->SetString(MF_BYTESTREAM_CONTENT_TYPE, 1.78 + contentTypeUTF16.get()); 1.79 + NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); 1.80 + 1.81 + WMF_BS_LOG("[%p] WMFByteStream has Content-Type=%s", this, mResource->GetContentType().get()); 1.82 + } 1.83 + return NS_OK; 1.84 +} 1.85 + 1.86 +nsresult 1.87 +WMFByteStream::Shutdown() 1.88 +{ 1.89 + { 1.90 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.91 + mIsShutdown = true; 1.92 + } 1.93 + mSourceReaderCallback->Cancel(); 1.94 + return NS_OK; 1.95 +} 1.96 + 1.97 +// IUnknown Methods 1.98 +STDMETHODIMP 1.99 +WMFByteStream::QueryInterface(REFIID aIId, void **aInterface) 1.100 +{ 1.101 + WMF_BS_LOG("[%p] WMFByteStream::QueryInterface %s", this, GetGUIDName(aIId).get()); 1.102 + 1.103 + if (aIId == IID_IMFByteStream) { 1.104 + return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface); 1.105 + } 1.106 + if (aIId == IID_IUnknown) { 1.107 + return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface); 1.108 + } 1.109 + if (aIId == IID_IMFAttributes) { 1.110 + return DoGetInterface(static_cast<IMFAttributes*>(this), aInterface); 1.111 + } 1.112 + 1.113 + *aInterface = nullptr; 1.114 + return E_NOINTERFACE; 1.115 +} 1.116 + 1.117 +NS_IMPL_ADDREF(WMFByteStream) 1.118 +NS_IMPL_RELEASE(WMFByteStream) 1.119 + 1.120 + 1.121 +// Stores data regarding an async read opreation. 1.122 +class ReadRequest MOZ_FINAL : public IUnknown { 1.123 +public: 1.124 + ReadRequest(int64_t aOffset, BYTE* aBuffer, ULONG aLength) 1.125 + : mOffset(aOffset), 1.126 + mBuffer(aBuffer), 1.127 + mBufferLength(aLength), 1.128 + mBytesRead(0) 1.129 + {} 1.130 + 1.131 + // IUnknown Methods 1.132 + STDMETHODIMP QueryInterface(REFIID aRIID, LPVOID *aOutObject); 1.133 + STDMETHODIMP_(ULONG) AddRef(); 1.134 + STDMETHODIMP_(ULONG) Release(); 1.135 + 1.136 + int64_t mOffset; 1.137 + BYTE* mBuffer; 1.138 + ULONG mBufferLength; 1.139 + ULONG mBytesRead; 1.140 + 1.141 + // IUnknown ref counting. 1.142 + ThreadSafeAutoRefCnt mRefCnt; 1.143 + NS_DECL_OWNINGTHREAD 1.144 +}; 1.145 + 1.146 +NS_IMPL_ADDREF(ReadRequest) 1.147 +NS_IMPL_RELEASE(ReadRequest) 1.148 + 1.149 +// IUnknown Methods 1.150 +STDMETHODIMP 1.151 +ReadRequest::QueryInterface(REFIID aIId, void **aInterface) 1.152 +{ 1.153 + WMF_BS_LOG("ReadRequest::QueryInterface %s", GetGUIDName(aIId).get()); 1.154 + 1.155 + if (aIId == IID_IUnknown) { 1.156 + return DoGetInterface(static_cast<IUnknown*>(this), aInterface); 1.157 + } 1.158 + 1.159 + *aInterface = nullptr; 1.160 + return E_NOINTERFACE; 1.161 +} 1.162 + 1.163 +class ProcessReadRequestEvent MOZ_FINAL : public nsRunnable { 1.164 +public: 1.165 + ProcessReadRequestEvent(WMFByteStream* aStream, 1.166 + IMFAsyncResult* aResult, 1.167 + ReadRequest* aRequestState) 1.168 + : mStream(aStream), 1.169 + mResult(aResult), 1.170 + mRequestState(aRequestState) {} 1.171 + 1.172 + NS_IMETHOD Run() { 1.173 + mStream->ProcessReadRequest(mResult, mRequestState); 1.174 + return NS_OK; 1.175 + } 1.176 +private: 1.177 + RefPtr<WMFByteStream> mStream; 1.178 + RefPtr<IMFAsyncResult> mResult; 1.179 + RefPtr<ReadRequest> mRequestState; 1.180 +}; 1.181 + 1.182 +// IMFByteStream Methods 1.183 +STDMETHODIMP 1.184 +WMFByteStream::BeginRead(BYTE *aBuffer, 1.185 + ULONG aLength, 1.186 + IMFAsyncCallback *aCallback, 1.187 + IUnknown *aCallerState) 1.188 +{ 1.189 + NS_ENSURE_TRUE(aBuffer, E_POINTER); 1.190 + NS_ENSURE_TRUE(aCallback, E_POINTER); 1.191 + 1.192 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.193 + WMF_BS_LOG("[%p] WMFByteStream::BeginRead() mOffset=%lld tell=%lld length=%lu mIsShutdown=%d", 1.194 + this, mOffset, mResource->Tell(), aLength, mIsShutdown); 1.195 + 1.196 + if (mIsShutdown || mOffset < 0) { 1.197 + return E_INVALIDARG; 1.198 + } 1.199 + 1.200 + // Create an object to store our state. 1.201 + RefPtr<ReadRequest> requestState = new ReadRequest(mOffset, aBuffer, aLength); 1.202 + 1.203 + // Create an IMFAsyncResult, this is passed back to the caller as a token to 1.204 + // retrieve the number of bytes read. 1.205 + RefPtr<IMFAsyncResult> callersResult; 1.206 + HRESULT hr = wmf::MFCreateAsyncResult(requestState, 1.207 + aCallback, 1.208 + aCallerState, 1.209 + byRef(callersResult)); 1.210 + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); 1.211 + 1.212 + // Dispatch an event to perform the read in the thread pool. 1.213 + nsCOMPtr<nsIRunnable> r = new ProcessReadRequestEvent(this, 1.214 + callersResult, 1.215 + requestState); 1.216 + nsresult rv = mThreadPool->Dispatch(r, NS_DISPATCH_NORMAL); 1.217 + 1.218 + if (mResource->GetLength() > -1) { 1.219 + mOffset = std::min<int64_t>(mOffset + aLength, mResource->GetLength()); 1.220 + } else { 1.221 + mOffset += aLength; 1.222 + } 1.223 + 1.224 + return NS_SUCCEEDED(rv) ? S_OK : E_FAIL; 1.225 +} 1.226 + 1.227 +nsresult 1.228 +WMFByteStream::Read(ReadRequest* aRequestState) 1.229 +{ 1.230 + // Read in a loop to ensure we fill the buffer, when possible. 1.231 + ULONG totalBytesRead = 0; 1.232 + nsresult rv = NS_OK; 1.233 + while (totalBytesRead < aRequestState->mBufferLength) { 1.234 + BYTE* buffer = aRequestState->mBuffer + totalBytesRead; 1.235 + ULONG bytesRead = 0; 1.236 + ULONG length = aRequestState->mBufferLength - totalBytesRead; 1.237 + rv = mResource->ReadAt(aRequestState->mOffset + totalBytesRead, 1.238 + reinterpret_cast<char*>(buffer), 1.239 + length, 1.240 + reinterpret_cast<uint32_t*>(&bytesRead)); 1.241 + NS_ENSURE_SUCCESS(rv, rv); 1.242 + totalBytesRead += bytesRead; 1.243 + if (bytesRead == 0) { 1.244 + break; 1.245 + } 1.246 + } 1.247 + aRequestState->mBytesRead = totalBytesRead; 1.248 + return NS_OK; 1.249 +} 1.250 + 1.251 +// Note: This is called on one of the thread pool's threads. 1.252 +void 1.253 +WMFByteStream::ProcessReadRequest(IMFAsyncResult* aResult, 1.254 + ReadRequest* aRequestState) 1.255 +{ 1.256 + if (mResource->GetLength() > -1 && 1.257 + aRequestState->mOffset > mResource->GetLength()) { 1.258 + aResult->SetStatus(S_OK); 1.259 + wmf::MFInvokeCallback(aResult); 1.260 + WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read offset greater than length, soft-failing read", this); 1.261 + return; 1.262 + } 1.263 + 1.264 + nsresult rv = Read(aRequestState); 1.265 + if (NS_FAILED(rv)) { 1.266 + Shutdown(); 1.267 + aResult->SetStatus(E_ABORT); 1.268 + } else { 1.269 + aResult->SetStatus(S_OK); 1.270 + } 1.271 + 1.272 + WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read %d at %lld finished rv=%x", 1.273 + this, aRequestState->mBytesRead, aRequestState->mOffset, rv); 1.274 + 1.275 + // Let caller know read is complete. 1.276 + DebugOnly<HRESULT> hr = wmf::MFInvokeCallback(aResult); 1.277 + NS_ASSERTION(SUCCEEDED(hr), "Failed to invoke callback!"); 1.278 +} 1.279 + 1.280 +STDMETHODIMP 1.281 +WMFByteStream::BeginWrite(const BYTE *, ULONG , 1.282 + IMFAsyncCallback *, 1.283 + IUnknown *) 1.284 +{ 1.285 + WMF_BS_LOG("[%p] WMFByteStream::BeginWrite()", this); 1.286 + return E_NOTIMPL; 1.287 +} 1.288 + 1.289 +STDMETHODIMP 1.290 +WMFByteStream::Close() 1.291 +{ 1.292 + WMF_BS_LOG("[%p] WMFByteStream::Close()", this); 1.293 + return S_OK; 1.294 +} 1.295 + 1.296 +STDMETHODIMP 1.297 +WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead) 1.298 +{ 1.299 + NS_ENSURE_TRUE(aResult, E_POINTER); 1.300 + NS_ENSURE_TRUE(aBytesRead, E_POINTER); 1.301 + 1.302 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.303 + 1.304 + // Extract our state object. 1.305 + RefPtr<IUnknown> unknown; 1.306 + HRESULT hr = aResult->GetObject(byRef(unknown)); 1.307 + if (FAILED(hr) || !unknown) { 1.308 + return E_INVALIDARG; 1.309 + } 1.310 + ReadRequest* requestState = 1.311 + static_cast<ReadRequest*>(unknown.get()); 1.312 + 1.313 + // Report result. 1.314 + *aBytesRead = requestState->mBytesRead; 1.315 + 1.316 + WMF_BS_LOG("[%p] WMFByteStream::EndRead() offset=%lld *aBytesRead=%u mOffset=%lld status=0x%x hr=0x%x eof=%d", 1.317 + this, requestState->mOffset, *aBytesRead, mOffset, aResult->GetStatus(), hr, IsEOS()); 1.318 + 1.319 + return aResult->GetStatus(); 1.320 +} 1.321 + 1.322 +STDMETHODIMP 1.323 +WMFByteStream::EndWrite(IMFAsyncResult *, ULONG *) 1.324 +{ 1.325 + WMF_BS_LOG("[%p] WMFByteStream::EndWrite()", this); 1.326 + return E_NOTIMPL; 1.327 +} 1.328 + 1.329 +STDMETHODIMP 1.330 +WMFByteStream::Flush() 1.331 +{ 1.332 + WMF_BS_LOG("[%p] WMFByteStream::Flush()", this); 1.333 + return S_OK; 1.334 +} 1.335 + 1.336 +STDMETHODIMP 1.337 +WMFByteStream::GetCapabilities(DWORD *aCapabilities) 1.338 +{ 1.339 + WMF_BS_LOG("[%p] WMFByteStream::GetCapabilities()", this); 1.340 + NS_ENSURE_TRUE(aCapabilities, E_POINTER); 1.341 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.342 + bool seekable = mResource->IsTransportSeekable(); 1.343 + bool cached = mResource->IsDataCachedToEndOfResource(0); 1.344 + *aCapabilities = MFBYTESTREAM_IS_READABLE | 1.345 + MFBYTESTREAM_IS_SEEKABLE | 1.346 + (!cached ? MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED : 0) | 1.347 + (!seekable ? MFBYTESTREAM_HAS_SLOW_SEEK : 0); 1.348 + return S_OK; 1.349 +} 1.350 + 1.351 +STDMETHODIMP 1.352 +WMFByteStream::GetCurrentPosition(QWORD *aPosition) 1.353 +{ 1.354 + NS_ENSURE_TRUE(aPosition, E_POINTER); 1.355 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.356 + // Note: Returning the length of stream as position when read 1.357 + // cursor is < 0 seems to be the behaviour expected by WMF, but 1.358 + // also note it doesn't seem to expect that the position is an 1.359 + // unsigned value since if you seek to > length and read WMF 1.360 + // expects the read to succeed after reading 0 bytes, but if you 1.361 + // seek to < 0 and read, the read is expected to fails... So 1.362 + // go figure... 1.363 + *aPosition = mOffset < 0 ? mResource->GetLength() : mOffset; 1.364 + WMF_BS_LOG("[%p] WMFByteStream::GetCurrentPosition() %lld", this, mOffset); 1.365 + return S_OK; 1.366 +} 1.367 + 1.368 +STDMETHODIMP 1.369 +WMFByteStream::GetLength(QWORD *aLength) 1.370 +{ 1.371 + NS_ENSURE_TRUE(aLength, E_POINTER); 1.372 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.373 + *aLength = mResource->GetLength(); 1.374 + WMF_BS_LOG("[%p] WMFByteStream::GetLength() %lld", this, *aLength); 1.375 + return S_OK; 1.376 +} 1.377 + 1.378 +bool 1.379 +WMFByteStream::IsEOS() 1.380 +{ 1.381 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.382 + return mResource->GetLength() > -1 && 1.383 + (mOffset < 0 || 1.384 + mOffset >= mResource->GetLength()); 1.385 +} 1.386 + 1.387 +STDMETHODIMP 1.388 +WMFByteStream::IsEndOfStream(BOOL *aEndOfStream) 1.389 +{ 1.390 + NS_ENSURE_TRUE(aEndOfStream, E_POINTER); 1.391 + *aEndOfStream = IsEOS(); 1.392 + WMF_BS_LOG("[%p] WMFByteStream::IsEndOfStream() %d", this, *aEndOfStream); 1.393 + return S_OK; 1.394 +} 1.395 + 1.396 +STDMETHODIMP 1.397 +WMFByteStream::Read(BYTE* aBuffer, ULONG aBufferLength, ULONG* aOutBytesRead) 1.398 +{ 1.399 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.400 + ReadRequest request(mOffset, aBuffer, aBufferLength); 1.401 + if (NS_FAILED(Read(&request))) { 1.402 + WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld failed!", this, mOffset); 1.403 + return E_FAIL; 1.404 + } 1.405 + if (aOutBytesRead) { 1.406 + *aOutBytesRead = request.mBytesRead; 1.407 + } 1.408 + WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld length=%u bytesRead=%u", 1.409 + this, mOffset, aBufferLength, request.mBytesRead); 1.410 + mOffset += request.mBytesRead; 1.411 + return S_OK; 1.412 +} 1.413 + 1.414 +STDMETHODIMP 1.415 +WMFByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin, 1.416 + LONGLONG aSeekOffset, 1.417 + DWORD aSeekFlags, 1.418 + QWORD *aCurrentPosition) 1.419 +{ 1.420 + WMF_BS_LOG("[%p] WMFByteStream::Seek(%d, %lld)", this, aSeekOrigin, aSeekOffset); 1.421 + 1.422 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.423 + 1.424 + int64_t offset = mOffset; 1.425 + if (aSeekOrigin == msoBegin) { 1.426 + offset = aSeekOffset; 1.427 + } else { 1.428 + offset += aSeekOffset; 1.429 + } 1.430 + int64_t length = mResource->GetLength(); 1.431 + if (length > -1) { 1.432 + mOffset = std::min<int64_t>(offset, length); 1.433 + } else { 1.434 + mOffset = offset; 1.435 + } 1.436 + if (aCurrentPosition) { 1.437 + *aCurrentPosition = mOffset; 1.438 + } 1.439 + 1.440 + return S_OK; 1.441 +} 1.442 + 1.443 +STDMETHODIMP 1.444 +WMFByteStream::SetCurrentPosition(QWORD aPosition) 1.445 +{ 1.446 + ReentrantMonitorAutoEnter mon(mReentrantMonitor); 1.447 + WMF_BS_LOG("[%p] WMFByteStream::SetCurrentPosition(%lld)", 1.448 + this, aPosition); 1.449 + 1.450 + int64_t length = mResource->GetLength(); 1.451 + if (length > -1) { 1.452 + mOffset = std::min<int64_t>(aPosition, length); 1.453 + } else { 1.454 + mOffset = aPosition; 1.455 + } 1.456 + 1.457 + return S_OK; 1.458 +} 1.459 + 1.460 +STDMETHODIMP 1.461 +WMFByteStream::SetLength(QWORD) 1.462 +{ 1.463 + WMF_BS_LOG("[%p] WMFByteStream::SetLength()", this); 1.464 + return E_NOTIMPL; 1.465 +} 1.466 + 1.467 +STDMETHODIMP 1.468 +WMFByteStream::Write(const BYTE *, ULONG, ULONG *) 1.469 +{ 1.470 + WMF_BS_LOG("[%p] WMFByteStream::Write()", this); 1.471 + return E_NOTIMPL; 1.472 +} 1.473 + 1.474 +// IMFAttributes methods 1.475 +STDMETHODIMP 1.476 +WMFByteStream::GetItem(REFGUID guidKey, PROPVARIANT* pValue) 1.477 +{ 1.478 + MOZ_ASSERT(mAttributes); 1.479 + return mAttributes->GetItem(guidKey, pValue); 1.480 +} 1.481 + 1.482 +STDMETHODIMP 1.483 +WMFByteStream::GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType) 1.484 +{ 1.485 + assert(mAttributes); 1.486 + return mAttributes->GetItemType(guidKey, pType); 1.487 +} 1.488 + 1.489 +STDMETHODIMP 1.490 +WMFByteStream::CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult) 1.491 +{ 1.492 + assert(mAttributes); 1.493 + return mAttributes->CompareItem(guidKey, Value, pbResult); 1.494 +} 1.495 + 1.496 +STDMETHODIMP 1.497 +WMFByteStream::Compare(IMFAttributes* pTheirs, 1.498 + MF_ATTRIBUTES_MATCH_TYPE MatchType, 1.499 + BOOL* pbResult) 1.500 +{ 1.501 + assert(mAttributes); 1.502 + return mAttributes->Compare(pTheirs, MatchType, pbResult); 1.503 +} 1.504 + 1.505 +STDMETHODIMP 1.506 +WMFByteStream::GetUINT32(REFGUID guidKey, UINT32* punValue) 1.507 +{ 1.508 + assert(mAttributes); 1.509 + return mAttributes->GetUINT32(guidKey, punValue); 1.510 +} 1.511 + 1.512 +STDMETHODIMP 1.513 +WMFByteStream::GetUINT64(REFGUID guidKey, UINT64* punValue) 1.514 +{ 1.515 + assert(mAttributes); 1.516 + return mAttributes->GetUINT64(guidKey, punValue); 1.517 +} 1.518 + 1.519 +STDMETHODIMP 1.520 +WMFByteStream::GetDouble(REFGUID guidKey, double* pfValue) 1.521 +{ 1.522 + assert(mAttributes); 1.523 + return mAttributes->GetDouble(guidKey, pfValue); 1.524 +} 1.525 + 1.526 +STDMETHODIMP 1.527 +WMFByteStream::GetGUID(REFGUID guidKey, GUID* pguidValue) 1.528 +{ 1.529 + assert(mAttributes); 1.530 + return mAttributes->GetGUID(guidKey, pguidValue); 1.531 +} 1.532 + 1.533 +STDMETHODIMP 1.534 +WMFByteStream::GetStringLength(REFGUID guidKey, UINT32* pcchLength) 1.535 +{ 1.536 + assert(mAttributes); 1.537 + return mAttributes->GetStringLength(guidKey, pcchLength); 1.538 +} 1.539 + 1.540 +STDMETHODIMP 1.541 +WMFByteStream::GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength) 1.542 +{ 1.543 + assert(mAttributes); 1.544 + return mAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); 1.545 +} 1.546 + 1.547 +STDMETHODIMP 1.548 +WMFByteStream::GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength) 1.549 +{ 1.550 + assert(mAttributes); 1.551 + return mAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); 1.552 +} 1.553 + 1.554 +STDMETHODIMP 1.555 +WMFByteStream::GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize) 1.556 +{ 1.557 + assert(mAttributes); 1.558 + return mAttributes->GetBlobSize(guidKey, pcbBlobSize); 1.559 +} 1.560 + 1.561 +STDMETHODIMP 1.562 +WMFByteStream::GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize) 1.563 +{ 1.564 + assert(mAttributes); 1.565 + return mAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); 1.566 +} 1.567 + 1.568 +STDMETHODIMP 1.569 +WMFByteStream::GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize) 1.570 +{ 1.571 + assert(mAttributes); 1.572 + return mAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); 1.573 +} 1.574 + 1.575 +STDMETHODIMP 1.576 +WMFByteStream::GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv) 1.577 +{ 1.578 + assert(mAttributes); 1.579 + return mAttributes->GetUnknown(guidKey, riid, ppv); 1.580 +} 1.581 + 1.582 +STDMETHODIMP 1.583 +WMFByteStream::SetItem(REFGUID guidKey, REFPROPVARIANT Value) 1.584 +{ 1.585 + assert(mAttributes); 1.586 + return mAttributes->SetItem(guidKey, Value); 1.587 +} 1.588 + 1.589 +STDMETHODIMP 1.590 +WMFByteStream::DeleteItem(REFGUID guidKey) 1.591 +{ 1.592 + assert(mAttributes); 1.593 + return mAttributes->DeleteItem(guidKey); 1.594 +} 1.595 + 1.596 +STDMETHODIMP 1.597 +WMFByteStream::DeleteAllItems() 1.598 +{ 1.599 + assert(mAttributes); 1.600 + return mAttributes->DeleteAllItems(); 1.601 +} 1.602 + 1.603 +STDMETHODIMP 1.604 +WMFByteStream::SetUINT32(REFGUID guidKey, UINT32 unValue) 1.605 +{ 1.606 + assert(mAttributes); 1.607 + return mAttributes->SetUINT32(guidKey, unValue); 1.608 +} 1.609 + 1.610 +STDMETHODIMP 1.611 +WMFByteStream::SetUINT64(REFGUID guidKey,UINT64 unValue) 1.612 +{ 1.613 + assert(mAttributes); 1.614 + return mAttributes->SetUINT64(guidKey, unValue); 1.615 +} 1.616 + 1.617 +STDMETHODIMP 1.618 +WMFByteStream::SetDouble(REFGUID guidKey, double fValue) 1.619 +{ 1.620 + assert(mAttributes); 1.621 + return mAttributes->SetDouble(guidKey, fValue); 1.622 +} 1.623 + 1.624 +STDMETHODIMP 1.625 +WMFByteStream::SetGUID(REFGUID guidKey, REFGUID guidValue) 1.626 +{ 1.627 + assert(mAttributes); 1.628 + return mAttributes->SetGUID(guidKey, guidValue); 1.629 +} 1.630 + 1.631 +STDMETHODIMP 1.632 +WMFByteStream::SetString(REFGUID guidKey, LPCWSTR wszValue) 1.633 +{ 1.634 + assert(mAttributes); 1.635 + return mAttributes->SetString(guidKey, wszValue); 1.636 +} 1.637 + 1.638 +STDMETHODIMP 1.639 +WMFByteStream::SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize) 1.640 +{ 1.641 + assert(mAttributes); 1.642 + return mAttributes->SetBlob(guidKey, pBuf, cbBufSize); 1.643 +} 1.644 + 1.645 +STDMETHODIMP 1.646 +WMFByteStream::SetUnknown(REFGUID guidKey, IUnknown* pUnknown) 1.647 +{ 1.648 + assert(mAttributes); 1.649 + return mAttributes->SetUnknown(guidKey, pUnknown); 1.650 +} 1.651 + 1.652 +STDMETHODIMP 1.653 +WMFByteStream::LockStore() 1.654 +{ 1.655 + assert(mAttributes); 1.656 + return mAttributes->LockStore(); 1.657 +} 1.658 + 1.659 +STDMETHODIMP 1.660 +WMFByteStream::UnlockStore() 1.661 +{ 1.662 + assert(mAttributes); 1.663 + return mAttributes->UnlockStore(); 1.664 +} 1.665 + 1.666 +STDMETHODIMP 1.667 +WMFByteStream::GetCount(UINT32* pcItems) 1.668 +{ 1.669 + assert(mAttributes); 1.670 + return mAttributes->GetCount(pcItems); 1.671 +} 1.672 + 1.673 +STDMETHODIMP 1.674 +WMFByteStream::GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue) 1.675 +{ 1.676 + assert(mAttributes); 1.677 + return mAttributes->GetItemByIndex(unIndex, pguidKey, pValue); 1.678 +} 1.679 + 1.680 +STDMETHODIMP 1.681 +WMFByteStream::CopyAllItems(IMFAttributes* pDest) 1.682 +{ 1.683 + assert(mAttributes); 1.684 + return mAttributes->CopyAllItems(pDest); 1.685 +} 1.686 + 1.687 +} // namespace mozilla