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