content/media/wmf/WMFByteStream.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6 #if !defined(WMFByteStream_h_)
michael@0 7 #define WMFByteStream_h_
michael@0 8
michael@0 9 #include "WMF.h"
michael@0 10
michael@0 11 #include "nsISupportsImpl.h"
michael@0 12 #include "nsCOMPtr.h"
michael@0 13 #include "mozilla/ReentrantMonitor.h"
michael@0 14 #include "mozilla/Attributes.h"
michael@0 15 #include "nsAutoPtr.h"
michael@0 16 #include "mozilla/RefPtr.h"
michael@0 17
michael@0 18 namespace mozilla {
michael@0 19
michael@0 20 class MediaResource;
michael@0 21 class ReadRequest;
michael@0 22 class WMFSourceReaderCallback;
michael@0 23 class SharedThreadPool;
michael@0 24
michael@0 25 // Wraps a MediaResource around an IMFByteStream interface, so that it can
michael@0 26 // be used by the IMFSourceReader. Each WMFByteStream creates a WMF Work Queue
michael@0 27 // on which blocking I/O is performed. The SourceReader requests reads
michael@0 28 // asynchronously using {Begin,End}Read(), and more rarely synchronously
michael@0 29 // using Read().
michael@0 30 //
michael@0 31 // Note: This implementation attempts to be bug-compatible with Windows Media
michael@0 32 // Foundation's implementation of IMFByteStream. The behaviour of WMF's
michael@0 33 // IMFByteStream was determined by creating it and testing the edge cases.
michael@0 34 // For details see the test code at:
michael@0 35 // https://github.com/cpearce/IMFByteStreamBehaviour/
michael@0 36 class WMFByteStream MOZ_FINAL : public IMFByteStream
michael@0 37 , public IMFAttributes
michael@0 38 {
michael@0 39 public:
michael@0 40 WMFByteStream(MediaResource* aResource, WMFSourceReaderCallback* aCallback);
michael@0 41 ~WMFByteStream();
michael@0 42
michael@0 43 nsresult Init();
michael@0 44 nsresult Shutdown();
michael@0 45
michael@0 46 // IUnknown Methods.
michael@0 47 STDMETHODIMP QueryInterface(REFIID aIId, LPVOID *aInterface);
michael@0 48 STDMETHODIMP_(ULONG) AddRef();
michael@0 49 STDMETHODIMP_(ULONG) Release();
michael@0 50
michael@0 51 // IMFByteStream Methods.
michael@0 52 STDMETHODIMP BeginRead(BYTE *aBuffer,
michael@0 53 ULONG aLength,
michael@0 54 IMFAsyncCallback *aCallback,
michael@0 55 IUnknown *aCallerState);
michael@0 56 STDMETHODIMP BeginWrite(const BYTE *, ULONG ,
michael@0 57 IMFAsyncCallback *,
michael@0 58 IUnknown *);
michael@0 59 STDMETHODIMP Close();
michael@0 60 STDMETHODIMP EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead);
michael@0 61 STDMETHODIMP EndWrite(IMFAsyncResult *, ULONG *);
michael@0 62 STDMETHODIMP Flush();
michael@0 63 STDMETHODIMP GetCapabilities(DWORD *aCapabilities);
michael@0 64 STDMETHODIMP GetCurrentPosition(QWORD *aPosition);
michael@0 65 STDMETHODIMP GetLength(QWORD *pqwLength);
michael@0 66 STDMETHODIMP IsEndOfStream(BOOL *aIsEndOfStream);
michael@0 67 STDMETHODIMP Read(BYTE *, ULONG, ULONG *);
michael@0 68 STDMETHODIMP Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin,
michael@0 69 LONGLONG aSeekOffset,
michael@0 70 DWORD aSeekFlags,
michael@0 71 QWORD *aCurrentPosition);
michael@0 72 STDMETHODIMP SetCurrentPosition(QWORD aPosition);
michael@0 73 STDMETHODIMP SetLength(QWORD);
michael@0 74 STDMETHODIMP Write(const BYTE *, ULONG, ULONG *);
michael@0 75
michael@0 76 // IMFAttributes methods
michael@0 77 STDMETHODIMP GetItem(REFGUID guidKey, PROPVARIANT* pValue);
michael@0 78 STDMETHODIMP GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType);
michael@0 79 STDMETHODIMP CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult);
michael@0 80 STDMETHODIMP Compare(IMFAttributes* pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL* pbResult);
michael@0 81 STDMETHODIMP GetUINT32(REFGUID guidKey, UINT32* punValue);
michael@0 82 STDMETHODIMP GetUINT64(REFGUID guidKey, UINT64* punValue);
michael@0 83 STDMETHODIMP GetDouble(REFGUID guidKey, double* pfValue);
michael@0 84 STDMETHODIMP GetGUID(REFGUID guidKey, GUID* pguidValue);
michael@0 85 STDMETHODIMP GetStringLength(REFGUID guidKey, UINT32* pcchLength);
michael@0 86 STDMETHODIMP GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength);
michael@0 87 STDMETHODIMP GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength);
michael@0 88 STDMETHODIMP GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize);
michael@0 89 STDMETHODIMP GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize);
michael@0 90 STDMETHODIMP GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize);
michael@0 91 STDMETHODIMP GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv);
michael@0 92 STDMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value);
michael@0 93 STDMETHODIMP DeleteItem(REFGUID guidKey);
michael@0 94 STDMETHODIMP DeleteAllItems();
michael@0 95 STDMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue);
michael@0 96 STDMETHODIMP SetUINT64(REFGUID guidKey,UINT64 unValue);
michael@0 97 STDMETHODIMP SetDouble(REFGUID guidKey, double fValue);
michael@0 98 STDMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue);
michael@0 99 STDMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue);
michael@0 100 STDMETHODIMP SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize);
michael@0 101 STDMETHODIMP SetUnknown(REFGUID guidKey, IUnknown* pUnknown);
michael@0 102 STDMETHODIMP LockStore();
michael@0 103 STDMETHODIMP UnlockStore();
michael@0 104 STDMETHODIMP GetCount(UINT32* pcItems);
michael@0 105 STDMETHODIMP GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue);
michael@0 106 STDMETHODIMP CopyAllItems(IMFAttributes* pDest);
michael@0 107
michael@0 108 // We perform an async read operation in this callback implementation.
michael@0 109 // Processes an async read request, storing the result in aResult, and
michael@0 110 // notifying the caller when the read operation is complete.
michael@0 111 void ProcessReadRequest(IMFAsyncResult* aResult,
michael@0 112 ReadRequest* aRequestState);
michael@0 113
michael@0 114 private:
michael@0 115
michael@0 116 // Locks the MediaResource and performs the read. The other read methods
michael@0 117 // call this function.
michael@0 118 nsresult Read(ReadRequest* aRequestState);
michael@0 119
michael@0 120 // Returns true if the current position of the stream is at end of stream.
michael@0 121 bool IsEOS();
michael@0 122
michael@0 123 // Reference to the thread pool in which we perform the reads asynchronously.
michael@0 124 // Note this is pool is shared amongst all active WMFByteStreams.
michael@0 125 RefPtr<SharedThreadPool> mThreadPool;
michael@0 126
michael@0 127 // Reference to the source reader's callback. We use this reference to
michael@0 128 // notify threads waiting on a ReadSample() callback to stop waiting
michael@0 129 // if the stream is closed, which happens when the media element is
michael@0 130 // shutdown.
michael@0 131 RefPtr<WMFSourceReaderCallback> mSourceReaderCallback;
michael@0 132
michael@0 133 // Resource we're wrapping.
michael@0 134 nsRefPtr<MediaResource> mResource;
michael@0 135
michael@0 136 // Protects mOffset, which is accessed by the SourceReaders thread(s), and
michael@0 137 // on the work queue thread.
michael@0 138 ReentrantMonitor mReentrantMonitor;
michael@0 139
michael@0 140 // Current offset of the logical read cursor. We maintain this separately
michael@0 141 // from the media resource's offset since a partially complete read (in Invoke())
michael@0 142 // would leave the resource's offset at a value unexpected by the caller,
michael@0 143 // since the read hadn't yet completed.
michael@0 144 int64_t mOffset;
michael@0 145
michael@0 146 // We implement IMFAttributes by forwarding all calls to an instance of the
michael@0 147 // standard IMFAttributes class, which we store a reference to here.
michael@0 148 RefPtr<IMFAttributes> mAttributes;
michael@0 149
michael@0 150 // True if the resource has been shutdown, either because the WMFReader is
michael@0 151 // shutting down, or because the underlying MediaResource has closed.
michael@0 152 bool mIsShutdown;
michael@0 153
michael@0 154 // IUnknown ref counting.
michael@0 155 ThreadSafeAutoRefCnt mRefCnt;
michael@0 156 NS_DECL_OWNINGTHREAD
michael@0 157 };
michael@0 158
michael@0 159 } // namespace mozilla
michael@0 160
michael@0 161 #endif

mercurial