content/media/MediaQueue.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #if !defined(MediaQueue_h_)
     7 #define MediaQueue_h_
     9 #include "nsDeque.h"
    10 #include "nsTArray.h"
    11 #include "mozilla/ReentrantMonitor.h"
    12 #include "mozilla/RefPtr.h"
    13 #include "MediaTaskQueue.h"
    15 namespace mozilla {
    17 // Thread and type safe wrapper around nsDeque.
    18 template <class T>
    19 class MediaQueueDeallocator : public nsDequeFunctor {
    20   virtual void* operator() (void* anObject) {
    21     delete static_cast<T*>(anObject);
    22     return nullptr;
    23   }
    24 };
    26 template <class T> class MediaQueue : private nsDeque {
    27  public:
    29    MediaQueue()
    30      : nsDeque(new MediaQueueDeallocator<T>()),
    31        mReentrantMonitor("mediaqueue"),
    32        mEndOfStream(false)
    33    {}
    35   ~MediaQueue() {
    36     Reset();
    37   }
    39   inline int32_t GetSize() {
    40     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    41     return nsDeque::GetSize();
    42   }
    44   inline void Push(T* aItem) {
    45     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    46     nsDeque::Push(aItem);
    47   }
    49   inline void PushFront(T* aItem) {
    50     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    51     nsDeque::PushFront(aItem);
    52   }
    54   inline T* PopFront() {
    55     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    56     T* rv = static_cast<T*>(nsDeque::PopFront());
    57     if (rv) {
    58       NotifyPopListeners();
    59     }
    60     return rv;
    61   }
    63   inline T* Peek() {
    64     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    65     return static_cast<T*>(nsDeque::Peek());
    66   }
    68   inline T* PeekFront() {
    69     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    70     return static_cast<T*>(nsDeque::PeekFront());
    71   }
    73   inline void Empty() {
    74     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    75     nsDeque::Empty();
    76   }
    78   inline void Erase() {
    79     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    80     nsDeque::Erase();
    81   }
    83   void Reset() {
    84     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    85     while (GetSize() > 0) {
    86       T* x = PopFront();
    87       delete x;
    88     }
    89     mEndOfStream = false;
    90   }
    92   bool AtEndOfStream() {
    93     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    94     return GetSize() == 0 && mEndOfStream;
    95   }
    97   // Returns true if the media queue has had its last item added to it.
    98   // This happens when the media stream has been completely decoded. Note this
    99   // does not mean that the corresponding stream has finished playback.
   100   bool IsFinished() {
   101     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   102     return mEndOfStream;
   103   }
   105   // Informs the media queue that it won't be receiving any more items.
   106   void Finish() {
   107     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   108     mEndOfStream = true;
   109   }
   111   // Returns the approximate number of microseconds of items in the queue.
   112   int64_t Duration() {
   113     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   114     if (GetSize() < 2) {
   115       return 0;
   116     }
   117     T* last = Peek();
   118     T* first = PeekFront();
   119     return last->mTime - first->mTime;
   120   }
   122   void LockedForEach(nsDequeFunctor& aFunctor) const {
   123     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   124     ForEach(aFunctor);
   125   }
   127   // Extracts elements from the queue into aResult, in order.
   128   // Elements whose start time is before aTime are ignored.
   129   void GetElementsAfter(int64_t aTime, nsTArray<T*>* aResult) {
   130     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   131     if (!GetSize())
   132       return;
   133     int32_t i;
   134     for (i = GetSize() - 1; i > 0; --i) {
   135       T* v = static_cast<T*>(ObjectAt(i));
   136       if (v->GetEndTime() < aTime)
   137         break;
   138     }
   139     // Elements less than i have a end time before aTime. It's also possible
   140     // that the element at i has a end time before aTime, but that's OK.
   141     for (; i < GetSize(); ++i) {
   142       aResult->AppendElement(static_cast<T*>(ObjectAt(i)));
   143     }
   144   }
   146   uint32_t FrameCount() {
   147     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   148     uint32_t frames = 0;
   149     for (int32_t i = 0; i < GetSize(); ++i) {
   150       T* v = static_cast<T*>(ObjectAt(i));
   151       frames += v->mFrames;
   152     }
   153     return frames;
   154   }
   156   void ClearListeners() {
   157     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   158     mPopListeners.Clear();
   159   }
   161   void AddPopListener(nsIRunnable* aRunnable, MediaTaskQueue* aTaskQueue) {
   162     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   163     mPopListeners.AppendElement(Listener(aRunnable, aTaskQueue));
   164   }
   166 private:
   167   mutable ReentrantMonitor mReentrantMonitor;
   169   struct Listener {
   170     Listener(nsIRunnable* aRunnable, MediaTaskQueue* aTaskQueue)
   171       : mRunnable(aRunnable)
   172       , mTarget(aTaskQueue)
   173     {
   174     }
   175     Listener(const Listener& aOther)
   176       : mRunnable(aOther.mRunnable)
   177       , mTarget(aOther.mTarget)
   178     {
   179     }
   180     RefPtr<nsIRunnable> mRunnable;
   181     RefPtr<MediaTaskQueue> mTarget;
   182   };
   184   nsTArray<Listener> mPopListeners;
   186   void NotifyPopListeners() {
   187     for (uint32_t i = 0; i < mPopListeners.Length(); i++) {
   188       Listener& l = mPopListeners[i];
   189       l.mTarget->Dispatch(l.mRunnable);
   190     }
   191   }
   193   // True when we've decoded the last frame of data in the
   194   // bitstream for which we're queueing frame data.
   195   bool mEndOfStream;
   196 };
   198 } // namespace mozilla
   200 #endif

mercurial