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(NesteggPacketHolder_h_) 7 # define NesteggPacketHolder_h_ 8 9 # include <stdint.h> 10 # include "nsAutoRef.h" 11 # include "nestegg/nestegg.h" 12 13 namespace mozilla { 14 15 // Holds a nestegg_packet, and its file offset. This is needed so we 16 // know the offset in the file we've played up to, in order to calculate 17 // whether it's likely we can play through to the end without needing 18 // to stop to buffer, given the current download rate. 19 class NesteggPacketHolder { 20 public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder)21 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder) 22 NesteggPacketHolder() 23 : mPacket(nullptr), 24 mOffset(-1), 25 mTimestamp(-1), 26 mDuration(-1), 27 mTrack(0), 28 mIsKeyframe(false) {} 29 Init(nestegg_packet * aPacket,int64_t aOffset,unsigned aTrack,bool aIsKeyframe)30 bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, 31 bool aIsKeyframe) { 32 uint64_t timestamp_ns; 33 if (nestegg_packet_tstamp(aPacket, ×tamp_ns) == -1) { 34 return false; 35 } 36 37 // We store the timestamp as signed microseconds so that it's easily 38 // comparable to other timestamps we have in the system. 39 mTimestamp = timestamp_ns / 1000; 40 mPacket = aPacket; 41 mOffset = aOffset; 42 mTrack = aTrack; 43 mIsKeyframe = aIsKeyframe; 44 45 uint64_t duration_ns; 46 if (!nestegg_packet_duration(aPacket, &duration_ns)) { 47 mDuration = duration_ns / 1000; 48 } 49 return true; 50 } 51 Packet()52 nestegg_packet* Packet() { 53 MOZ_ASSERT(IsInitialized()); 54 return mPacket; 55 } Offset()56 int64_t Offset() { 57 MOZ_ASSERT(IsInitialized()); 58 return mOffset; 59 } Timestamp()60 int64_t Timestamp() { 61 MOZ_ASSERT(IsInitialized()); 62 return mTimestamp; 63 } Duration()64 int64_t Duration() { 65 MOZ_ASSERT(IsInitialized()); 66 return mDuration; 67 } Track()68 unsigned Track() { 69 MOZ_ASSERT(IsInitialized()); 70 return mTrack; 71 } IsKeyframe()72 bool IsKeyframe() { 73 MOZ_ASSERT(IsInitialized()); 74 return mIsKeyframe; 75 } 76 77 private: ~NesteggPacketHolder()78 ~NesteggPacketHolder() { nestegg_free_packet(mPacket); } 79 IsInitialized()80 bool IsInitialized() { return mOffset >= 0; } 81 82 nestegg_packet* mPacket; 83 84 // Offset in bytes. This is the offset of the end of the Block 85 // which contains the packet. 86 int64_t mOffset; 87 88 // Packet presentation timestamp in microseconds. 89 int64_t mTimestamp; 90 91 // Packet duration in microseconds; -1 if unknown or retrieval failed. 92 int64_t mDuration; 93 94 // Track ID. 95 unsigned mTrack; 96 97 // Does this packet contain a keyframe? 98 bool mIsKeyframe; 99 100 // Copy constructor and assignment operator not implemented. Don't use them! 101 NesteggPacketHolder(const NesteggPacketHolder& aOther); 102 NesteggPacketHolder& operator=(NesteggPacketHolder const& aOther); 103 }; 104 105 // Queue for holding nestegg packets. 106 class WebMPacketQueue { 107 public: GetSize()108 int32_t GetSize() { return mQueue.size(); } 109 Push(NesteggPacketHolder * aItem)110 void Push(NesteggPacketHolder* aItem) { mQueue.push_back(aItem); } 111 PushFront(NesteggPacketHolder * aItem)112 void PushFront(NesteggPacketHolder* aItem) { 113 mQueue.push_front(std::move(aItem)); 114 } 115 PopFront()116 already_AddRefed<NesteggPacketHolder> PopFront() { 117 RefPtr<NesteggPacketHolder> result = std::move(mQueue.front()); 118 mQueue.pop_front(); 119 return result.forget(); 120 } 121 Reset()122 void Reset() { 123 while (!mQueue.empty()) { 124 mQueue.pop_front(); 125 } 126 } 127 128 private: 129 std::deque<RefPtr<NesteggPacketHolder>> mQueue; 130 }; 131 132 } // namespace mozilla 133 134 #endif 135