|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
|
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 "WMF.h" |
|
8 |
|
9 #include <unknwn.h> |
|
10 #include <ole2.h> |
|
11 |
|
12 #include "WMFByteStream.h" |
|
13 #include "WMFSourceReaderCallback.h" |
|
14 #include "WMFUtils.h" |
|
15 #include "MediaResource.h" |
|
16 #include "nsISeekableStream.h" |
|
17 #include "mozilla/RefPtr.h" |
|
18 #include "nsIThreadPool.h" |
|
19 #include "nsXPCOMCIDInternal.h" |
|
20 #include "nsComponentManagerUtils.h" |
|
21 #include "mozilla/DebugOnly.h" |
|
22 #include "SharedThreadPool.h" |
|
23 #include <algorithm> |
|
24 #include <cassert> |
|
25 |
|
26 namespace mozilla { |
|
27 |
|
28 #ifdef PR_LOGGING |
|
29 PRLogModuleInfo* gWMFByteStreamLog = nullptr; |
|
30 #define WMF_BS_LOG(...) PR_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__)) |
|
31 #else |
|
32 #define WMF_BS_LOG(...) |
|
33 #endif |
|
34 |
|
35 WMFByteStream::WMFByteStream(MediaResource* aResource, |
|
36 WMFSourceReaderCallback* aSourceReaderCallback) |
|
37 : mSourceReaderCallback(aSourceReaderCallback), |
|
38 mResource(aResource), |
|
39 mReentrantMonitor("WMFByteStream.Data"), |
|
40 mOffset(0), |
|
41 mIsShutdown(false) |
|
42 { |
|
43 NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); |
|
44 NS_ASSERTION(mSourceReaderCallback, "Must have a source reader callback."); |
|
45 |
|
46 #ifdef PR_LOGGING |
|
47 if (!gWMFByteStreamLog) { |
|
48 gWMFByteStreamLog = PR_NewLogModule("WMFByteStream"); |
|
49 } |
|
50 #endif |
|
51 WMF_BS_LOG("[%p] WMFByteStream CTOR", this); |
|
52 MOZ_COUNT_CTOR(WMFByteStream); |
|
53 } |
|
54 |
|
55 WMFByteStream::~WMFByteStream() |
|
56 { |
|
57 MOZ_COUNT_DTOR(WMFByteStream); |
|
58 WMF_BS_LOG("[%p] WMFByteStream DTOR", this); |
|
59 } |
|
60 |
|
61 nsresult |
|
62 WMFByteStream::Init() |
|
63 { |
|
64 NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); |
|
65 |
|
66 mThreadPool = SharedThreadPool::Get(NS_LITERAL_CSTRING("WMFByteStream IO"), 4); |
|
67 NS_ENSURE_TRUE(mThreadPool, NS_ERROR_FAILURE); |
|
68 |
|
69 NS_ConvertUTF8toUTF16 contentTypeUTF16(mResource->GetContentType()); |
|
70 if (!contentTypeUTF16.IsEmpty()) { |
|
71 HRESULT hr = wmf::MFCreateAttributes(byRef(mAttributes), 1); |
|
72 NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); |
|
73 |
|
74 hr = mAttributes->SetString(MF_BYTESTREAM_CONTENT_TYPE, |
|
75 contentTypeUTF16.get()); |
|
76 NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); |
|
77 |
|
78 WMF_BS_LOG("[%p] WMFByteStream has Content-Type=%s", this, mResource->GetContentType().get()); |
|
79 } |
|
80 return NS_OK; |
|
81 } |
|
82 |
|
83 nsresult |
|
84 WMFByteStream::Shutdown() |
|
85 { |
|
86 { |
|
87 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
88 mIsShutdown = true; |
|
89 } |
|
90 mSourceReaderCallback->Cancel(); |
|
91 return NS_OK; |
|
92 } |
|
93 |
|
94 // IUnknown Methods |
|
95 STDMETHODIMP |
|
96 WMFByteStream::QueryInterface(REFIID aIId, void **aInterface) |
|
97 { |
|
98 WMF_BS_LOG("[%p] WMFByteStream::QueryInterface %s", this, GetGUIDName(aIId).get()); |
|
99 |
|
100 if (aIId == IID_IMFByteStream) { |
|
101 return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface); |
|
102 } |
|
103 if (aIId == IID_IUnknown) { |
|
104 return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface); |
|
105 } |
|
106 if (aIId == IID_IMFAttributes) { |
|
107 return DoGetInterface(static_cast<IMFAttributes*>(this), aInterface); |
|
108 } |
|
109 |
|
110 *aInterface = nullptr; |
|
111 return E_NOINTERFACE; |
|
112 } |
|
113 |
|
114 NS_IMPL_ADDREF(WMFByteStream) |
|
115 NS_IMPL_RELEASE(WMFByteStream) |
|
116 |
|
117 |
|
118 // Stores data regarding an async read opreation. |
|
119 class ReadRequest MOZ_FINAL : public IUnknown { |
|
120 public: |
|
121 ReadRequest(int64_t aOffset, BYTE* aBuffer, ULONG aLength) |
|
122 : mOffset(aOffset), |
|
123 mBuffer(aBuffer), |
|
124 mBufferLength(aLength), |
|
125 mBytesRead(0) |
|
126 {} |
|
127 |
|
128 // IUnknown Methods |
|
129 STDMETHODIMP QueryInterface(REFIID aRIID, LPVOID *aOutObject); |
|
130 STDMETHODIMP_(ULONG) AddRef(); |
|
131 STDMETHODIMP_(ULONG) Release(); |
|
132 |
|
133 int64_t mOffset; |
|
134 BYTE* mBuffer; |
|
135 ULONG mBufferLength; |
|
136 ULONG mBytesRead; |
|
137 |
|
138 // IUnknown ref counting. |
|
139 ThreadSafeAutoRefCnt mRefCnt; |
|
140 NS_DECL_OWNINGTHREAD |
|
141 }; |
|
142 |
|
143 NS_IMPL_ADDREF(ReadRequest) |
|
144 NS_IMPL_RELEASE(ReadRequest) |
|
145 |
|
146 // IUnknown Methods |
|
147 STDMETHODIMP |
|
148 ReadRequest::QueryInterface(REFIID aIId, void **aInterface) |
|
149 { |
|
150 WMF_BS_LOG("ReadRequest::QueryInterface %s", GetGUIDName(aIId).get()); |
|
151 |
|
152 if (aIId == IID_IUnknown) { |
|
153 return DoGetInterface(static_cast<IUnknown*>(this), aInterface); |
|
154 } |
|
155 |
|
156 *aInterface = nullptr; |
|
157 return E_NOINTERFACE; |
|
158 } |
|
159 |
|
160 class ProcessReadRequestEvent MOZ_FINAL : public nsRunnable { |
|
161 public: |
|
162 ProcessReadRequestEvent(WMFByteStream* aStream, |
|
163 IMFAsyncResult* aResult, |
|
164 ReadRequest* aRequestState) |
|
165 : mStream(aStream), |
|
166 mResult(aResult), |
|
167 mRequestState(aRequestState) {} |
|
168 |
|
169 NS_IMETHOD Run() { |
|
170 mStream->ProcessReadRequest(mResult, mRequestState); |
|
171 return NS_OK; |
|
172 } |
|
173 private: |
|
174 RefPtr<WMFByteStream> mStream; |
|
175 RefPtr<IMFAsyncResult> mResult; |
|
176 RefPtr<ReadRequest> mRequestState; |
|
177 }; |
|
178 |
|
179 // IMFByteStream Methods |
|
180 STDMETHODIMP |
|
181 WMFByteStream::BeginRead(BYTE *aBuffer, |
|
182 ULONG aLength, |
|
183 IMFAsyncCallback *aCallback, |
|
184 IUnknown *aCallerState) |
|
185 { |
|
186 NS_ENSURE_TRUE(aBuffer, E_POINTER); |
|
187 NS_ENSURE_TRUE(aCallback, E_POINTER); |
|
188 |
|
189 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
190 WMF_BS_LOG("[%p] WMFByteStream::BeginRead() mOffset=%lld tell=%lld length=%lu mIsShutdown=%d", |
|
191 this, mOffset, mResource->Tell(), aLength, mIsShutdown); |
|
192 |
|
193 if (mIsShutdown || mOffset < 0) { |
|
194 return E_INVALIDARG; |
|
195 } |
|
196 |
|
197 // Create an object to store our state. |
|
198 RefPtr<ReadRequest> requestState = new ReadRequest(mOffset, aBuffer, aLength); |
|
199 |
|
200 // Create an IMFAsyncResult, this is passed back to the caller as a token to |
|
201 // retrieve the number of bytes read. |
|
202 RefPtr<IMFAsyncResult> callersResult; |
|
203 HRESULT hr = wmf::MFCreateAsyncResult(requestState, |
|
204 aCallback, |
|
205 aCallerState, |
|
206 byRef(callersResult)); |
|
207 NS_ENSURE_TRUE(SUCCEEDED(hr), hr); |
|
208 |
|
209 // Dispatch an event to perform the read in the thread pool. |
|
210 nsCOMPtr<nsIRunnable> r = new ProcessReadRequestEvent(this, |
|
211 callersResult, |
|
212 requestState); |
|
213 nsresult rv = mThreadPool->Dispatch(r, NS_DISPATCH_NORMAL); |
|
214 |
|
215 if (mResource->GetLength() > -1) { |
|
216 mOffset = std::min<int64_t>(mOffset + aLength, mResource->GetLength()); |
|
217 } else { |
|
218 mOffset += aLength; |
|
219 } |
|
220 |
|
221 return NS_SUCCEEDED(rv) ? S_OK : E_FAIL; |
|
222 } |
|
223 |
|
224 nsresult |
|
225 WMFByteStream::Read(ReadRequest* aRequestState) |
|
226 { |
|
227 // Read in a loop to ensure we fill the buffer, when possible. |
|
228 ULONG totalBytesRead = 0; |
|
229 nsresult rv = NS_OK; |
|
230 while (totalBytesRead < aRequestState->mBufferLength) { |
|
231 BYTE* buffer = aRequestState->mBuffer + totalBytesRead; |
|
232 ULONG bytesRead = 0; |
|
233 ULONG length = aRequestState->mBufferLength - totalBytesRead; |
|
234 rv = mResource->ReadAt(aRequestState->mOffset + totalBytesRead, |
|
235 reinterpret_cast<char*>(buffer), |
|
236 length, |
|
237 reinterpret_cast<uint32_t*>(&bytesRead)); |
|
238 NS_ENSURE_SUCCESS(rv, rv); |
|
239 totalBytesRead += bytesRead; |
|
240 if (bytesRead == 0) { |
|
241 break; |
|
242 } |
|
243 } |
|
244 aRequestState->mBytesRead = totalBytesRead; |
|
245 return NS_OK; |
|
246 } |
|
247 |
|
248 // Note: This is called on one of the thread pool's threads. |
|
249 void |
|
250 WMFByteStream::ProcessReadRequest(IMFAsyncResult* aResult, |
|
251 ReadRequest* aRequestState) |
|
252 { |
|
253 if (mResource->GetLength() > -1 && |
|
254 aRequestState->mOffset > mResource->GetLength()) { |
|
255 aResult->SetStatus(S_OK); |
|
256 wmf::MFInvokeCallback(aResult); |
|
257 WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read offset greater than length, soft-failing read", this); |
|
258 return; |
|
259 } |
|
260 |
|
261 nsresult rv = Read(aRequestState); |
|
262 if (NS_FAILED(rv)) { |
|
263 Shutdown(); |
|
264 aResult->SetStatus(E_ABORT); |
|
265 } else { |
|
266 aResult->SetStatus(S_OK); |
|
267 } |
|
268 |
|
269 WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read %d at %lld finished rv=%x", |
|
270 this, aRequestState->mBytesRead, aRequestState->mOffset, rv); |
|
271 |
|
272 // Let caller know read is complete. |
|
273 DebugOnly<HRESULT> hr = wmf::MFInvokeCallback(aResult); |
|
274 NS_ASSERTION(SUCCEEDED(hr), "Failed to invoke callback!"); |
|
275 } |
|
276 |
|
277 STDMETHODIMP |
|
278 WMFByteStream::BeginWrite(const BYTE *, ULONG , |
|
279 IMFAsyncCallback *, |
|
280 IUnknown *) |
|
281 { |
|
282 WMF_BS_LOG("[%p] WMFByteStream::BeginWrite()", this); |
|
283 return E_NOTIMPL; |
|
284 } |
|
285 |
|
286 STDMETHODIMP |
|
287 WMFByteStream::Close() |
|
288 { |
|
289 WMF_BS_LOG("[%p] WMFByteStream::Close()", this); |
|
290 return S_OK; |
|
291 } |
|
292 |
|
293 STDMETHODIMP |
|
294 WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead) |
|
295 { |
|
296 NS_ENSURE_TRUE(aResult, E_POINTER); |
|
297 NS_ENSURE_TRUE(aBytesRead, E_POINTER); |
|
298 |
|
299 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
300 |
|
301 // Extract our state object. |
|
302 RefPtr<IUnknown> unknown; |
|
303 HRESULT hr = aResult->GetObject(byRef(unknown)); |
|
304 if (FAILED(hr) || !unknown) { |
|
305 return E_INVALIDARG; |
|
306 } |
|
307 ReadRequest* requestState = |
|
308 static_cast<ReadRequest*>(unknown.get()); |
|
309 |
|
310 // Report result. |
|
311 *aBytesRead = requestState->mBytesRead; |
|
312 |
|
313 WMF_BS_LOG("[%p] WMFByteStream::EndRead() offset=%lld *aBytesRead=%u mOffset=%lld status=0x%x hr=0x%x eof=%d", |
|
314 this, requestState->mOffset, *aBytesRead, mOffset, aResult->GetStatus(), hr, IsEOS()); |
|
315 |
|
316 return aResult->GetStatus(); |
|
317 } |
|
318 |
|
319 STDMETHODIMP |
|
320 WMFByteStream::EndWrite(IMFAsyncResult *, ULONG *) |
|
321 { |
|
322 WMF_BS_LOG("[%p] WMFByteStream::EndWrite()", this); |
|
323 return E_NOTIMPL; |
|
324 } |
|
325 |
|
326 STDMETHODIMP |
|
327 WMFByteStream::Flush() |
|
328 { |
|
329 WMF_BS_LOG("[%p] WMFByteStream::Flush()", this); |
|
330 return S_OK; |
|
331 } |
|
332 |
|
333 STDMETHODIMP |
|
334 WMFByteStream::GetCapabilities(DWORD *aCapabilities) |
|
335 { |
|
336 WMF_BS_LOG("[%p] WMFByteStream::GetCapabilities()", this); |
|
337 NS_ENSURE_TRUE(aCapabilities, E_POINTER); |
|
338 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
339 bool seekable = mResource->IsTransportSeekable(); |
|
340 bool cached = mResource->IsDataCachedToEndOfResource(0); |
|
341 *aCapabilities = MFBYTESTREAM_IS_READABLE | |
|
342 MFBYTESTREAM_IS_SEEKABLE | |
|
343 (!cached ? MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED : 0) | |
|
344 (!seekable ? MFBYTESTREAM_HAS_SLOW_SEEK : 0); |
|
345 return S_OK; |
|
346 } |
|
347 |
|
348 STDMETHODIMP |
|
349 WMFByteStream::GetCurrentPosition(QWORD *aPosition) |
|
350 { |
|
351 NS_ENSURE_TRUE(aPosition, E_POINTER); |
|
352 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
353 // Note: Returning the length of stream as position when read |
|
354 // cursor is < 0 seems to be the behaviour expected by WMF, but |
|
355 // also note it doesn't seem to expect that the position is an |
|
356 // unsigned value since if you seek to > length and read WMF |
|
357 // expects the read to succeed after reading 0 bytes, but if you |
|
358 // seek to < 0 and read, the read is expected to fails... So |
|
359 // go figure... |
|
360 *aPosition = mOffset < 0 ? mResource->GetLength() : mOffset; |
|
361 WMF_BS_LOG("[%p] WMFByteStream::GetCurrentPosition() %lld", this, mOffset); |
|
362 return S_OK; |
|
363 } |
|
364 |
|
365 STDMETHODIMP |
|
366 WMFByteStream::GetLength(QWORD *aLength) |
|
367 { |
|
368 NS_ENSURE_TRUE(aLength, E_POINTER); |
|
369 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
370 *aLength = mResource->GetLength(); |
|
371 WMF_BS_LOG("[%p] WMFByteStream::GetLength() %lld", this, *aLength); |
|
372 return S_OK; |
|
373 } |
|
374 |
|
375 bool |
|
376 WMFByteStream::IsEOS() |
|
377 { |
|
378 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
379 return mResource->GetLength() > -1 && |
|
380 (mOffset < 0 || |
|
381 mOffset >= mResource->GetLength()); |
|
382 } |
|
383 |
|
384 STDMETHODIMP |
|
385 WMFByteStream::IsEndOfStream(BOOL *aEndOfStream) |
|
386 { |
|
387 NS_ENSURE_TRUE(aEndOfStream, E_POINTER); |
|
388 *aEndOfStream = IsEOS(); |
|
389 WMF_BS_LOG("[%p] WMFByteStream::IsEndOfStream() %d", this, *aEndOfStream); |
|
390 return S_OK; |
|
391 } |
|
392 |
|
393 STDMETHODIMP |
|
394 WMFByteStream::Read(BYTE* aBuffer, ULONG aBufferLength, ULONG* aOutBytesRead) |
|
395 { |
|
396 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
397 ReadRequest request(mOffset, aBuffer, aBufferLength); |
|
398 if (NS_FAILED(Read(&request))) { |
|
399 WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld failed!", this, mOffset); |
|
400 return E_FAIL; |
|
401 } |
|
402 if (aOutBytesRead) { |
|
403 *aOutBytesRead = request.mBytesRead; |
|
404 } |
|
405 WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld length=%u bytesRead=%u", |
|
406 this, mOffset, aBufferLength, request.mBytesRead); |
|
407 mOffset += request.mBytesRead; |
|
408 return S_OK; |
|
409 } |
|
410 |
|
411 STDMETHODIMP |
|
412 WMFByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin, |
|
413 LONGLONG aSeekOffset, |
|
414 DWORD aSeekFlags, |
|
415 QWORD *aCurrentPosition) |
|
416 { |
|
417 WMF_BS_LOG("[%p] WMFByteStream::Seek(%d, %lld)", this, aSeekOrigin, aSeekOffset); |
|
418 |
|
419 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
420 |
|
421 int64_t offset = mOffset; |
|
422 if (aSeekOrigin == msoBegin) { |
|
423 offset = aSeekOffset; |
|
424 } else { |
|
425 offset += aSeekOffset; |
|
426 } |
|
427 int64_t length = mResource->GetLength(); |
|
428 if (length > -1) { |
|
429 mOffset = std::min<int64_t>(offset, length); |
|
430 } else { |
|
431 mOffset = offset; |
|
432 } |
|
433 if (aCurrentPosition) { |
|
434 *aCurrentPosition = mOffset; |
|
435 } |
|
436 |
|
437 return S_OK; |
|
438 } |
|
439 |
|
440 STDMETHODIMP |
|
441 WMFByteStream::SetCurrentPosition(QWORD aPosition) |
|
442 { |
|
443 ReentrantMonitorAutoEnter mon(mReentrantMonitor); |
|
444 WMF_BS_LOG("[%p] WMFByteStream::SetCurrentPosition(%lld)", |
|
445 this, aPosition); |
|
446 |
|
447 int64_t length = mResource->GetLength(); |
|
448 if (length > -1) { |
|
449 mOffset = std::min<int64_t>(aPosition, length); |
|
450 } else { |
|
451 mOffset = aPosition; |
|
452 } |
|
453 |
|
454 return S_OK; |
|
455 } |
|
456 |
|
457 STDMETHODIMP |
|
458 WMFByteStream::SetLength(QWORD) |
|
459 { |
|
460 WMF_BS_LOG("[%p] WMFByteStream::SetLength()", this); |
|
461 return E_NOTIMPL; |
|
462 } |
|
463 |
|
464 STDMETHODIMP |
|
465 WMFByteStream::Write(const BYTE *, ULONG, ULONG *) |
|
466 { |
|
467 WMF_BS_LOG("[%p] WMFByteStream::Write()", this); |
|
468 return E_NOTIMPL; |
|
469 } |
|
470 |
|
471 // IMFAttributes methods |
|
472 STDMETHODIMP |
|
473 WMFByteStream::GetItem(REFGUID guidKey, PROPVARIANT* pValue) |
|
474 { |
|
475 MOZ_ASSERT(mAttributes); |
|
476 return mAttributes->GetItem(guidKey, pValue); |
|
477 } |
|
478 |
|
479 STDMETHODIMP |
|
480 WMFByteStream::GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType) |
|
481 { |
|
482 assert(mAttributes); |
|
483 return mAttributes->GetItemType(guidKey, pType); |
|
484 } |
|
485 |
|
486 STDMETHODIMP |
|
487 WMFByteStream::CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult) |
|
488 { |
|
489 assert(mAttributes); |
|
490 return mAttributes->CompareItem(guidKey, Value, pbResult); |
|
491 } |
|
492 |
|
493 STDMETHODIMP |
|
494 WMFByteStream::Compare(IMFAttributes* pTheirs, |
|
495 MF_ATTRIBUTES_MATCH_TYPE MatchType, |
|
496 BOOL* pbResult) |
|
497 { |
|
498 assert(mAttributes); |
|
499 return mAttributes->Compare(pTheirs, MatchType, pbResult); |
|
500 } |
|
501 |
|
502 STDMETHODIMP |
|
503 WMFByteStream::GetUINT32(REFGUID guidKey, UINT32* punValue) |
|
504 { |
|
505 assert(mAttributes); |
|
506 return mAttributes->GetUINT32(guidKey, punValue); |
|
507 } |
|
508 |
|
509 STDMETHODIMP |
|
510 WMFByteStream::GetUINT64(REFGUID guidKey, UINT64* punValue) |
|
511 { |
|
512 assert(mAttributes); |
|
513 return mAttributes->GetUINT64(guidKey, punValue); |
|
514 } |
|
515 |
|
516 STDMETHODIMP |
|
517 WMFByteStream::GetDouble(REFGUID guidKey, double* pfValue) |
|
518 { |
|
519 assert(mAttributes); |
|
520 return mAttributes->GetDouble(guidKey, pfValue); |
|
521 } |
|
522 |
|
523 STDMETHODIMP |
|
524 WMFByteStream::GetGUID(REFGUID guidKey, GUID* pguidValue) |
|
525 { |
|
526 assert(mAttributes); |
|
527 return mAttributes->GetGUID(guidKey, pguidValue); |
|
528 } |
|
529 |
|
530 STDMETHODIMP |
|
531 WMFByteStream::GetStringLength(REFGUID guidKey, UINT32* pcchLength) |
|
532 { |
|
533 assert(mAttributes); |
|
534 return mAttributes->GetStringLength(guidKey, pcchLength); |
|
535 } |
|
536 |
|
537 STDMETHODIMP |
|
538 WMFByteStream::GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength) |
|
539 { |
|
540 assert(mAttributes); |
|
541 return mAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); |
|
542 } |
|
543 |
|
544 STDMETHODIMP |
|
545 WMFByteStream::GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength) |
|
546 { |
|
547 assert(mAttributes); |
|
548 return mAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); |
|
549 } |
|
550 |
|
551 STDMETHODIMP |
|
552 WMFByteStream::GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize) |
|
553 { |
|
554 assert(mAttributes); |
|
555 return mAttributes->GetBlobSize(guidKey, pcbBlobSize); |
|
556 } |
|
557 |
|
558 STDMETHODIMP |
|
559 WMFByteStream::GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize) |
|
560 { |
|
561 assert(mAttributes); |
|
562 return mAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); |
|
563 } |
|
564 |
|
565 STDMETHODIMP |
|
566 WMFByteStream::GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize) |
|
567 { |
|
568 assert(mAttributes); |
|
569 return mAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); |
|
570 } |
|
571 |
|
572 STDMETHODIMP |
|
573 WMFByteStream::GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv) |
|
574 { |
|
575 assert(mAttributes); |
|
576 return mAttributes->GetUnknown(guidKey, riid, ppv); |
|
577 } |
|
578 |
|
579 STDMETHODIMP |
|
580 WMFByteStream::SetItem(REFGUID guidKey, REFPROPVARIANT Value) |
|
581 { |
|
582 assert(mAttributes); |
|
583 return mAttributes->SetItem(guidKey, Value); |
|
584 } |
|
585 |
|
586 STDMETHODIMP |
|
587 WMFByteStream::DeleteItem(REFGUID guidKey) |
|
588 { |
|
589 assert(mAttributes); |
|
590 return mAttributes->DeleteItem(guidKey); |
|
591 } |
|
592 |
|
593 STDMETHODIMP |
|
594 WMFByteStream::DeleteAllItems() |
|
595 { |
|
596 assert(mAttributes); |
|
597 return mAttributes->DeleteAllItems(); |
|
598 } |
|
599 |
|
600 STDMETHODIMP |
|
601 WMFByteStream::SetUINT32(REFGUID guidKey, UINT32 unValue) |
|
602 { |
|
603 assert(mAttributes); |
|
604 return mAttributes->SetUINT32(guidKey, unValue); |
|
605 } |
|
606 |
|
607 STDMETHODIMP |
|
608 WMFByteStream::SetUINT64(REFGUID guidKey,UINT64 unValue) |
|
609 { |
|
610 assert(mAttributes); |
|
611 return mAttributes->SetUINT64(guidKey, unValue); |
|
612 } |
|
613 |
|
614 STDMETHODIMP |
|
615 WMFByteStream::SetDouble(REFGUID guidKey, double fValue) |
|
616 { |
|
617 assert(mAttributes); |
|
618 return mAttributes->SetDouble(guidKey, fValue); |
|
619 } |
|
620 |
|
621 STDMETHODIMP |
|
622 WMFByteStream::SetGUID(REFGUID guidKey, REFGUID guidValue) |
|
623 { |
|
624 assert(mAttributes); |
|
625 return mAttributes->SetGUID(guidKey, guidValue); |
|
626 } |
|
627 |
|
628 STDMETHODIMP |
|
629 WMFByteStream::SetString(REFGUID guidKey, LPCWSTR wszValue) |
|
630 { |
|
631 assert(mAttributes); |
|
632 return mAttributes->SetString(guidKey, wszValue); |
|
633 } |
|
634 |
|
635 STDMETHODIMP |
|
636 WMFByteStream::SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize) |
|
637 { |
|
638 assert(mAttributes); |
|
639 return mAttributes->SetBlob(guidKey, pBuf, cbBufSize); |
|
640 } |
|
641 |
|
642 STDMETHODIMP |
|
643 WMFByteStream::SetUnknown(REFGUID guidKey, IUnknown* pUnknown) |
|
644 { |
|
645 assert(mAttributes); |
|
646 return mAttributes->SetUnknown(guidKey, pUnknown); |
|
647 } |
|
648 |
|
649 STDMETHODIMP |
|
650 WMFByteStream::LockStore() |
|
651 { |
|
652 assert(mAttributes); |
|
653 return mAttributes->LockStore(); |
|
654 } |
|
655 |
|
656 STDMETHODIMP |
|
657 WMFByteStream::UnlockStore() |
|
658 { |
|
659 assert(mAttributes); |
|
660 return mAttributes->UnlockStore(); |
|
661 } |
|
662 |
|
663 STDMETHODIMP |
|
664 WMFByteStream::GetCount(UINT32* pcItems) |
|
665 { |
|
666 assert(mAttributes); |
|
667 return mAttributes->GetCount(pcItems); |
|
668 } |
|
669 |
|
670 STDMETHODIMP |
|
671 WMFByteStream::GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue) |
|
672 { |
|
673 assert(mAttributes); |
|
674 return mAttributes->GetItemByIndex(unIndex, pguidKey, pValue); |
|
675 } |
|
676 |
|
677 STDMETHODIMP |
|
678 WMFByteStream::CopyAllItems(IMFAttributes* pDest) |
|
679 { |
|
680 assert(mAttributes); |
|
681 return mAttributes->CopyAllItems(pDest); |
|
682 } |
|
683 |
|
684 } // namespace mozilla |