LCOV - code coverage report
Current view: top level - dom/media - MediaQueue.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 93 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 42 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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_
       8             : 
       9             : #include "mozilla/ReentrantMonitor.h"
      10             : #include "mozilla/TaskQueue.h"
      11             : 
      12             : #include "nsDeque.h"
      13             : #include "MediaEventSource.h"
      14             : #include "TimeUnits.h"
      15             : 
      16             : namespace mozilla {
      17             : 
      18             : // Thread and type safe wrapper around nsDeque.
      19             : template <class T>
      20           0 : class MediaQueueDeallocator : public nsDequeFunctor {
      21           0 :   virtual void* operator() (void* aObject) {
      22           0 :     RefPtr<T> releaseMe = dont_AddRef(static_cast<T*>(aObject));
      23           0 :     return nullptr;
      24             :   }
      25             : };
      26             : 
      27             : template <class T>
      28             : class MediaQueue : private nsDeque {
      29             : public:
      30           0 :   MediaQueue()
      31           0 :     : nsDeque(new MediaQueueDeallocator<T>()),
      32             :       mReentrantMonitor("mediaqueue"),
      33           0 :       mEndOfStream(false)
      34           0 :   {}
      35             : 
      36           0 :   ~MediaQueue() {
      37           0 :     Reset();
      38           0 :   }
      39             : 
      40           0 :   inline size_t GetSize() const {
      41           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      42           0 :     return nsDeque::GetSize();
      43             :   }
      44             : 
      45           0 :   inline void Push(T* aItem) {
      46           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      47           0 :     MOZ_ASSERT(!mEndOfStream);
      48           0 :     MOZ_ASSERT(aItem);
      49           0 :     NS_ADDREF(aItem);
      50           0 :     MOZ_ASSERT(aItem->GetEndTime() >= aItem->mTime);
      51           0 :     nsDeque::Push(aItem);
      52           0 :     mPushEvent.Notify(RefPtr<T>(aItem));
      53           0 :   }
      54             : 
      55           0 :   inline already_AddRefed<T> PopFront() {
      56           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      57           0 :     RefPtr<T> rv = dont_AddRef(static_cast<T*>(nsDeque::PopFront()));
      58           0 :     if (rv) {
      59           0 :       mPopEvent.Notify(rv);
      60             :     }
      61           0 :     return rv.forget();
      62             :   }
      63             : 
      64           0 :   inline RefPtr<T> PeekFront() const {
      65           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      66           0 :     return static_cast<T*>(nsDeque::PeekFront());
      67             :   }
      68             : 
      69           0 :   void Reset() {
      70           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      71           0 :     while (GetSize() > 0) {
      72           0 :       RefPtr<T> x = dont_AddRef(static_cast<T*>(nsDeque::PopFront()));
      73             :     }
      74           0 :     mEndOfStream = false;
      75           0 :   }
      76             : 
      77           0 :   bool AtEndOfStream() const {
      78           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      79           0 :     return GetSize() == 0 && mEndOfStream;
      80             :   }
      81             : 
      82             :   // Returns true if the media queue has had its last item added to it.
      83             :   // This happens when the media stream has been completely decoded. Note this
      84             :   // does not mean that the corresponding stream has finished playback.
      85           0 :   bool IsFinished() const {
      86           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      87           0 :     return mEndOfStream;
      88             :   }
      89             : 
      90             :   // Informs the media queue that it won't be receiving any more items.
      91           0 :   void Finish() {
      92           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      93           0 :     if (!mEndOfStream) {
      94           0 :       mEndOfStream = true;
      95           0 :       mFinishEvent.Notify();
      96             :     }
      97           0 :   }
      98             : 
      99             :   // Returns the approximate number of microseconds of items in the queue.
     100           0 :   int64_t Duration() {
     101           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     102           0 :     if (GetSize() == 0) {
     103           0 :       return 0;
     104             :     }
     105           0 :     T* last = static_cast<T*>(nsDeque::Peek());
     106           0 :     T* first = static_cast<T*>(nsDeque::PeekFront());
     107           0 :     return (last->GetEndTime() - first->mTime).ToMicroseconds();
     108             :   }
     109             : 
     110           0 :   void LockedForEach(nsDequeFunctor& aFunctor) const {
     111           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     112           0 :     ForEach(aFunctor);
     113           0 :   }
     114             : 
     115             :   // Extracts elements from the queue into aResult, in order.
     116             :   // Elements whose start time is before aTime are ignored.
     117           0 :   void GetElementsAfter(int64_t aTime, nsTArray<RefPtr<T>>* aResult) {
     118           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     119           0 :     if (GetSize() == 0)
     120           0 :       return;
     121             :     size_t i;
     122           0 :     for (i = GetSize() - 1; i > 0; --i) {
     123           0 :       T* v = static_cast<T*>(ObjectAt(i));
     124           0 :       if (v->GetEndTime().ToMicroseconds() < aTime)
     125           0 :         break;
     126             :     }
     127             :     // Elements less than i have a end time before aTime. It's also possible
     128             :     // that the element at i has a end time before aTime, but that's OK.
     129           0 :     for (; i < GetSize(); ++i) {
     130           0 :       RefPtr<T> elem = static_cast<T*>(ObjectAt(static_cast<size_t>(i)));
     131           0 :       aResult->AppendElement(elem);
     132             :     }
     133             :   }
     134             : 
     135           0 :   void GetElementsAfter(const media::TimeUnit& aTime,
     136             :                         nsTArray<RefPtr<T>>* aResult) {
     137           0 :     GetElementsAfter(aTime.ToMicroseconds(), aResult);
     138           0 :   }
     139             : 
     140           0 :   void GetFirstElements(uint32_t aMaxElements, nsTArray<RefPtr<T>>* aResult) {
     141           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     142           0 :     for (size_t i = 0; i < aMaxElements && i < GetSize(); ++i) {
     143           0 :       *aResult->AppendElement() = static_cast<T*>(ObjectAt(i));
     144             :     }
     145           0 :   }
     146             : 
     147           0 :   uint32_t FrameCount() {
     148           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     149           0 :     uint32_t frames = 0;
     150           0 :     for (size_t i = 0; i < GetSize(); ++i) {
     151           0 :       T* v = static_cast<T*>(ObjectAt(i));
     152           0 :       frames += v->mFrames;
     153             :     }
     154           0 :     return frames;
     155             :   }
     156             : 
     157           0 :   MediaEventSource<RefPtr<T>>& PopEvent() {
     158           0 :     return mPopEvent;
     159             :   }
     160             : 
     161           0 :   MediaEventSource<RefPtr<T>>& PushEvent() {
     162           0 :     return mPushEvent;
     163             :   }
     164             : 
     165           0 :   MediaEventSource<void>& FinishEvent() {
     166           0 :     return mFinishEvent;
     167             :   }
     168             : 
     169             : private:
     170             :   mutable ReentrantMonitor mReentrantMonitor;
     171             :   MediaEventProducer<RefPtr<T>> mPopEvent;
     172             :   MediaEventProducer<RefPtr<T>> mPushEvent;
     173             :   MediaEventProducer<void> mFinishEvent;
     174             :   // True when we've decoded the last frame of data in the
     175             :   // bitstream for which we're queueing frame data.
     176             :   bool mEndOfStream;
     177             : };
     178             : 
     179             : } // namespace mozilla
     180             : 
     181             : #endif

Generated by: LCOV version 1.13