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, &timestamp_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