content/media/wmf/WMFSourceReaderCallback.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     7 #include "WMFSourceReaderCallback.h"
     8 #include "WMFUtils.h"
    10 namespace mozilla {
    12 #ifdef PR_LOGGING
    13 static PRLogModuleInfo* gWMFSourceReaderCallbackLog = nullptr;
    14 #define WMF_CB_LOG(...) PR_LOG(gWMFSourceReaderCallbackLog, PR_LOG_DEBUG, (__VA_ARGS__))
    15 #else
    16 #define WMF_CB_LOG(...)
    17 #endif
    19 // IUnknown Methods
    20 STDMETHODIMP
    21 WMFSourceReaderCallback::QueryInterface(REFIID aIId, void **aInterface)
    22 {
    23   WMF_CB_LOG("WMFSourceReaderCallback::QueryInterface %s", GetGUIDName(aIId).get());
    25   if (aIId == IID_IMFSourceReaderCallback) {
    26     return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
    27   }
    28   if (aIId == IID_IUnknown) {
    29     return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
    30   }
    32   *aInterface = nullptr;
    33   return E_NOINTERFACE;
    34 }
    36 NS_IMPL_ADDREF(WMFSourceReaderCallback)
    37 NS_IMPL_RELEASE(WMFSourceReaderCallback)
    39 WMFSourceReaderCallback::WMFSourceReaderCallback()
    40   : mMonitor("WMFSourceReaderCallback")
    41   , mResultStatus(S_OK)
    42   , mStreamFlags(0)
    43   , mTimestamp(0)
    44   , mSample(nullptr)
    45   , mReadFinished(false)
    46 {
    47 #ifdef PR_LOGGING
    48   if (!gWMFSourceReaderCallbackLog) {
    49     gWMFSourceReaderCallbackLog = PR_NewLogModule("WMFSourceReaderCallback");
    50   }
    51 #endif
    52 }
    54 HRESULT
    55 WMFSourceReaderCallback::NotifyReadComplete(HRESULT aReadStatus,
    56                                             DWORD aStreamIndex,
    57                                             DWORD aStreamFlags,
    58                                             LONGLONG aTimestamp,
    59                                             IMFSample *aSample)
    60 {
    61   // Note: aSample can be nullptr on success if more data is required!
    62   ReentrantMonitorAutoEnter mon(mMonitor);
    64   if (mSample) {
    65     // The WMFReader should have called Wait() to retrieve the last
    66     // sample returned by the last ReadSample() call, but if we're
    67     // aborting the read before Wait() is called the sample ref
    68     // can be non-null.
    69     mSample->Release();
    70     mSample = nullptr;
    71   }
    73   if (SUCCEEDED(aReadStatus)) {
    74     if (aSample) {
    75       mTimestamp = aTimestamp;
    76       mSample = aSample;
    77       mSample->AddRef();
    78     }
    79   }
    81   mResultStatus = aReadStatus;
    82   mStreamFlags = aStreamFlags;
    84   // Set the sentinal value and notify the monitor, so that threads waiting
    85   // in Wait() are awoken.
    86   mReadFinished = true;
    87   mon.NotifyAll();
    89   return S_OK;
    90 }
    92 STDMETHODIMP
    93 WMFSourceReaderCallback::OnReadSample(HRESULT aReadStatus,
    94                                       DWORD aStreamIndex,
    95                                       DWORD aStreamFlags,
    96                                       LONGLONG aTimestamp,
    97                                       IMFSample *aSample)
    98 {
    99   WMF_CB_LOG("WMFSourceReaderCallback::OnReadSample() hr=0x%x flags=0x%x time=%lld sample=%p",
   100              aReadStatus, aStreamFlags, aTimestamp, aSample);
   101   return NotifyReadComplete(aReadStatus,
   102                             aStreamIndex,
   103                             aStreamFlags,
   104                             aTimestamp,
   105                             aSample);
   106 }
   108 HRESULT
   109 WMFSourceReaderCallback::Cancel()
   110 {
   111   WMF_CB_LOG("WMFSourceReaderCallback::Cancel()");
   112   return NotifyReadComplete(E_ABORT,
   113                             0,
   114                             0,
   115                             0,
   116                             nullptr);
   117 }
   119 STDMETHODIMP
   120 WMFSourceReaderCallback::OnEvent(DWORD, IMFMediaEvent *)
   121 {
   122   return S_OK;
   123 }
   125 STDMETHODIMP
   126 WMFSourceReaderCallback::OnFlush(DWORD)
   127 {
   128   return S_OK;
   129 }
   131 HRESULT
   132 WMFSourceReaderCallback::Wait(DWORD* aStreamFlags,
   133                               LONGLONG* aTimeStamp,
   134                               IMFSample** aSample)
   135 {
   136   ReentrantMonitorAutoEnter mon(mMonitor);
   137   WMF_CB_LOG("WMFSourceReaderCallback::Wait() starting wait");
   138   while (!mReadFinished) {
   139     mon.Wait();
   140   }
   141   mReadFinished = false;
   142   WMF_CB_LOG("WMFSourceReaderCallback::Wait() done waiting");
   144   *aStreamFlags = mStreamFlags;
   145   *aTimeStamp = mTimestamp;
   146   *aSample = mSample;
   147   HRESULT hr = mResultStatus;
   149   mSample = nullptr;
   150   mTimestamp = 0;
   151   mStreamFlags = 0;
   152   mResultStatus = S_OK;
   154   return hr;
   155 }
   157 } // namespace mozilla

mercurial