LCOV - code coverage report
Current view: top level - dom/media/webm - WebMDemuxer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 50 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 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(WebMDemuxer_h_)
       7             : #define WebMDemuxer_h_
       8             : 
       9             : #include "nsTArray.h"
      10             : #include "MediaDataDemuxer.h"
      11             : #include "MediaResource.h"
      12             : #include "NesteggPacketHolder.h"
      13             : #include "mozilla/Move.h"
      14             : 
      15             : #include <deque>
      16             : #include <stdint.h>
      17             : 
      18             : typedef struct nestegg nestegg;
      19             : 
      20             : namespace mozilla {
      21             : 
      22             : class WebMBufferedState;
      23             : 
      24             : // Queue for holding MediaRawData samples
      25           0 : class MediaRawDataQueue
      26             : {
      27             :  public:
      28           0 :   uint32_t GetSize()
      29             :   {
      30           0 :     return mQueue.size();
      31             :   }
      32             : 
      33           0 :   void Push(MediaRawData* aItem)
      34             :   {
      35           0 :     mQueue.push_back(aItem);
      36           0 :   }
      37             : 
      38           0 :   void Push(already_AddRefed<MediaRawData>&& aItem)
      39             :   {
      40           0 :     mQueue.push_back(Move(aItem));
      41           0 :   }
      42             : 
      43             :   void PushFront(MediaRawData* aItem) {
      44             :     mQueue.push_front(aItem);
      45             :   }
      46             : 
      47           0 :   void PushFront(already_AddRefed<MediaRawData>&& aItem)
      48             :   {
      49           0 :     mQueue.push_front(Move(aItem));
      50           0 :   }
      51             : 
      52           0 :   void PushFront(MediaRawDataQueue&& aOther)
      53             :   {
      54           0 :     while (!aOther.mQueue.empty()) {
      55           0 :       PushFront(aOther.Pop());
      56             :     }
      57           0 :   }
      58             : 
      59           0 :   already_AddRefed<MediaRawData> PopFront()
      60             :   {
      61           0 :     RefPtr<MediaRawData> result = mQueue.front().forget();
      62           0 :     mQueue.pop_front();
      63           0 :     return result.forget();
      64             :   }
      65             : 
      66           0 :   already_AddRefed<MediaRawData> Pop()
      67             :   {
      68           0 :     RefPtr<MediaRawData> result = mQueue.back().forget();
      69           0 :     mQueue.pop_back();
      70           0 :     return result.forget();
      71             :   }
      72             : 
      73           0 :   void Reset()
      74             :   {
      75           0 :     while (!mQueue.empty()) {
      76           0 :       mQueue.pop_front();
      77             :     }
      78           0 :   }
      79             : 
      80             :   MediaRawDataQueue& operator=(const MediaRawDataQueue& aOther)
      81             :   {
      82             :     mQueue = aOther.mQueue;
      83             :     return *this;
      84             :   }
      85             : 
      86           0 :   const RefPtr<MediaRawData>& First() const
      87             :   {
      88           0 :     return mQueue.front();
      89             :   }
      90             : 
      91           0 :   const RefPtr<MediaRawData>& Last() const
      92             :   {
      93           0 :     return mQueue.back();
      94             :   }
      95             : 
      96             : private:
      97             :   std::deque<RefPtr<MediaRawData>> mQueue;
      98             : };
      99             : 
     100             : class WebMTrackDemuxer;
     101             : 
     102             : class WebMDemuxer : public MediaDataDemuxer
     103             : {
     104             : public:
     105             :   explicit WebMDemuxer(MediaResource* aResource);
     106             :   // Indicate if the WebMDemuxer is to be used with MediaSource. In which
     107             :   // case the demuxer will stop reads to the last known complete block.
     108             :   WebMDemuxer(MediaResource* aResource, bool aIsMediaSource);
     109             : 
     110             :   RefPtr<InitPromise> Init() override;
     111             : 
     112             :   bool HasTrackType(TrackInfo::TrackType aType) const override;
     113             : 
     114             :   uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
     115             : 
     116             :   UniquePtr<TrackInfo> GetTrackInfo(TrackInfo::TrackType aType,
     117             :                                     size_t aTrackNumber) const;
     118             : 
     119             :   already_AddRefed<MediaTrackDemuxer>
     120             :   GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
     121             : 
     122             :   bool IsSeekable() const override;
     123             : 
     124             :   bool IsSeekableOnlyInBufferedRanges() const override;
     125             : 
     126             :   UniquePtr<EncryptionInfo> GetCrypto() override;
     127             : 
     128             :   bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
     129             : 
     130             :   // Demux next WebM packet and append samples to MediaRawDataQueue
     131             :   nsresult GetNextPacket(TrackInfo::TrackType aType,
     132             :                          MediaRawDataQueue *aSamples);
     133             : 
     134             :   nsresult Reset(TrackInfo::TrackType aType);
     135             : 
     136             :   // Pushes a packet to the front of the audio packet queue.
     137             :   void PushAudioPacket(NesteggPacketHolder* aItem);
     138             : 
     139             :   // Pushes a packet to the front of the video packet queue.
     140             :   void PushVideoPacket(NesteggPacketHolder* aItem);
     141             : 
     142             :   // Public accessor for nestegg callbacks
     143           0 :   bool IsMediaSource() const
     144             :   {
     145           0 :     return mIsMediaSource;
     146             :   }
     147             : 
     148           0 :   int64_t LastWebMBlockOffset() const
     149             :   {
     150           0 :     return mLastWebMBlockOffset;
     151             :   }
     152             : 
     153             :   struct NestEggContext
     154             :   {
     155           0 :     NestEggContext(WebMDemuxer* aParent, MediaResource* aResource)
     156           0 :       : mParent(aParent)
     157             :       , mResource(aResource)
     158           0 :       , mContext(nullptr)
     159             :     {
     160           0 :     }
     161             : 
     162             :     ~NestEggContext();
     163             : 
     164             :     int Init();
     165             : 
     166             :     // Public accessor for nestegg callbacks
     167             : 
     168           0 :     bool IsMediaSource() const { return mParent->IsMediaSource(); }
     169           0 :     MediaResourceIndex* GetResource() { return &mResource; }
     170             : 
     171           0 :     int64_t GetEndDataOffset() const
     172             :     {
     173           0 :       return (!mParent->IsMediaSource() || mParent->LastWebMBlockOffset() < 0)
     174           0 :              ? mResource.GetLength()
     175           0 :              : mParent->LastWebMBlockOffset();
     176             :     }
     177             : 
     178             :     WebMDemuxer* mParent;
     179             :     MediaResourceIndex mResource;
     180             :     nestegg* mContext;
     181             :   };
     182             : 
     183             : private:
     184             :   friend class WebMTrackDemuxer;
     185             : 
     186             :   ~WebMDemuxer();
     187             :   void InitBufferedState();
     188             :   nsresult ReadMetadata();
     189             :   void NotifyDataArrived() override;
     190             :   void NotifyDataRemoved() override;
     191             :   void EnsureUpToDateIndex();
     192             :   media::TimeIntervals GetBuffered();
     193             :   nsresult SeekInternal(TrackInfo::TrackType aType,
     194             :                         const media::TimeUnit& aTarget);
     195             :   CryptoTrack GetTrackCrypto(TrackInfo::TrackType aType, size_t aTrackNumber);
     196             : 
     197             :   // Read a packet from the nestegg file. Returns nullptr if all packets for
     198             :   // the particular track have been read. Pass TrackInfo::kVideoTrack or
     199             :   // TrackInfo::kVideoTrack to indicate the type of the packet we want to read.
     200             :   nsresult NextPacket(TrackInfo::TrackType aType,
     201             :                       RefPtr<NesteggPacketHolder>& aPacket);
     202             : 
     203             :   // Internal method that demuxes the next packet from the stream. The caller
     204             :   // is responsible for making sure it doesn't get lost.
     205             :   nsresult DemuxPacket(TrackInfo::TrackType aType,
     206             :                        RefPtr<NesteggPacketHolder>& aPacket);
     207             : 
     208             :   // libnestegg audio and video context for webm container.
     209             :   // Access on reader's thread only.
     210             :   NestEggContext mVideoContext;
     211             :   NestEggContext mAudioContext;
     212           0 :   MediaResourceIndex& Resource(TrackInfo::TrackType aType)
     213             :   {
     214             :     return aType == TrackInfo::kVideoTrack
     215           0 :            ? mVideoContext.mResource : mAudioContext.mResource;
     216             :   }
     217           0 :   nestegg* Context(TrackInfo::TrackType aType) const
     218             :   {
     219             :     return aType == TrackInfo::kVideoTrack
     220           0 :            ? mVideoContext.mContext : mAudioContext.mContext;
     221             :   }
     222             : 
     223             :   MediaInfo mInfo;
     224             :   nsTArray<RefPtr<WebMTrackDemuxer>> mDemuxers;
     225             : 
     226             :   // Parser state and computed offset-time mappings.  Shared by multiple
     227             :   // readers when decoder has been cloned.  Main thread only.
     228             :   RefPtr<WebMBufferedState> mBufferedState;
     229             :   RefPtr<MediaByteBuffer> mInitData;
     230             : 
     231             : 
     232             :   // Queue of video and audio packets that have been read but not decoded.
     233             :   WebMPacketQueue mVideoPackets;
     234             :   WebMPacketQueue mAudioPackets;
     235             : 
     236             :   // Index of video and audio track to play
     237             :   uint32_t mVideoTrack;
     238             :   uint32_t mAudioTrack;
     239             : 
     240             :   // Nanoseconds to discard after seeking.
     241             :   uint64_t mSeekPreroll;
     242             : 
     243             :   // Calculate the frame duration from the last decodeable frame using the
     244             :   // previous frame's timestamp.  In NS.
     245             :   Maybe<int64_t> mLastAudioFrameTime;
     246             :   Maybe<int64_t> mLastVideoFrameTime;
     247             : 
     248             :   // Codec ID of audio track
     249             :   int mAudioCodec;
     250             :   // Codec ID of video track
     251             :   int mVideoCodec;
     252             : 
     253             :   // Booleans to indicate if we have audio and/or video data
     254             :   bool mHasVideo;
     255             :   bool mHasAudio;
     256             :   bool mNeedReIndex;
     257             : 
     258             :   // The last complete block parsed by the WebMBufferedState. -1 if not set.
     259             :   // We cache those values rather than retrieving them for performance reasons
     260             :   // as nestegg only performs 1-byte read at a time.
     261             :   int64_t mLastWebMBlockOffset;
     262             :   const bool mIsMediaSource;
     263             : 
     264             :   Maybe<nsIntSize> mLastSeenFrameSize;
     265             :   // This will be populated only if a resolution change occurs, otherwise it
     266             :   // will be left as null so the original metadata is used
     267             :   RefPtr<TrackInfoSharedPtr> mSharedVideoTrackInfo;
     268             : 
     269             :   EncryptionInfo mCrypto;
     270             : };
     271             : 
     272             : class WebMTrackDemuxer : public MediaTrackDemuxer
     273             : {
     274             : public:
     275             :   WebMTrackDemuxer(WebMDemuxer* aParent,
     276             :                   TrackInfo::TrackType aType,
     277             :                   uint32_t aTrackNumber);
     278             : 
     279             :   UniquePtr<TrackInfo> GetInfo() const override;
     280             : 
     281             :   RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;
     282             : 
     283             :   RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
     284             : 
     285             :   void Reset() override;
     286             : 
     287             :   nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override;
     288             : 
     289             :   RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
     290             :     const media::TimeUnit& aTimeThreshold) override;
     291             : 
     292             :   media::TimeIntervals GetBuffered() override;
     293             : 
     294             :   int64_t GetEvictionOffset(const media::TimeUnit& aTime) override;
     295             : 
     296             :   void BreakCycles() override;
     297             : 
     298             : private:
     299             :   friend class WebMDemuxer;
     300             :   ~WebMTrackDemuxer();
     301             :   void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
     302             :   void SetNextKeyFrameTime();
     303             :   nsresult NextSample(RefPtr<MediaRawData>& aData);
     304             :   RefPtr<WebMDemuxer> mParent;
     305             :   TrackInfo::TrackType mType;
     306             :   UniquePtr<TrackInfo> mInfo;
     307             :   Maybe<media::TimeUnit> mNextKeyframeTime;
     308             :   bool mNeedKeyframe;
     309             : 
     310             :   // Queued samples extracted by the demuxer, but not yet returned.
     311             :   MediaRawDataQueue mSamples;
     312             : };
     313             : 
     314             : } // namespace mozilla
     315             : 
     316             : #endif

Generated by: LCOV version 1.13