diff options
Diffstat (limited to 'dom/media/webm/NesteggPacketHolder.h')
-rw-r--r-- | dom/media/webm/NesteggPacketHolder.h | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/dom/media/webm/NesteggPacketHolder.h b/dom/media/webm/NesteggPacketHolder.h new file mode 100644 index 0000000000..7c74f752d3 --- /dev/null +++ b/dom/media/webm/NesteggPacketHolder.h @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#if !defined(NesteggPacketHolder_h_) +# define NesteggPacketHolder_h_ + +# include <deque> +# include <stdint.h> +# include "nsAutoRef.h" +# include "nestegg/nestegg.h" + +namespace mozilla { + +// Holds a nestegg_packet, and its file offset. This is needed so we +// know the offset in the file we've played up to, in order to calculate +// whether it's likely we can play through to the end without needing +// to stop to buffer, given the current download rate. +class NesteggPacketHolder { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder) + NesteggPacketHolder() + : mPacket(nullptr), + mOffset(-1), + mTimestamp(-1), + mDuration(-1), + mTrack(0), + mIsKeyframe(false) {} + + bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, + bool aIsKeyframe) { + uint64_t timestamp_ns; + if (nestegg_packet_tstamp(aPacket, ×tamp_ns) == -1) { + return false; + } + + // We store the timestamp as signed microseconds so that it's easily + // comparable to other timestamps we have in the system. + mTimestamp = timestamp_ns / 1000; + mPacket = aPacket; + mOffset = aOffset; + mTrack = aTrack; + mIsKeyframe = aIsKeyframe; + + uint64_t duration_ns; + if (!nestegg_packet_duration(aPacket, &duration_ns)) { + mDuration = duration_ns / 1000; + } + return true; + } + + nestegg_packet* Packet() { + MOZ_ASSERT(IsInitialized()); + return mPacket; + } + int64_t Offset() { + MOZ_ASSERT(IsInitialized()); + return mOffset; + } + int64_t Timestamp() { + MOZ_ASSERT(IsInitialized()); + return mTimestamp; + } + int64_t Duration() { + MOZ_ASSERT(IsInitialized()); + return mDuration; + } + unsigned Track() { + MOZ_ASSERT(IsInitialized()); + return mTrack; + } + bool IsKeyframe() { + MOZ_ASSERT(IsInitialized()); + return mIsKeyframe; + } + + private: + ~NesteggPacketHolder() { nestegg_free_packet(mPacket); } + + bool IsInitialized() { return mOffset >= 0; } + + nestegg_packet* mPacket; + + // Offset in bytes. This is the offset of the end of the Block + // which contains the packet. + int64_t mOffset; + + // Packet presentation timestamp in microseconds. + int64_t mTimestamp; + + // Packet duration in microseconds; -1 if unknown or retrieval failed. + int64_t mDuration; + + // Track ID. + unsigned mTrack; + + // Does this packet contain a keyframe? + bool mIsKeyframe; + + // Copy constructor and assignment operator not implemented. Don't use them! + NesteggPacketHolder(const NesteggPacketHolder& aOther); + NesteggPacketHolder& operator=(NesteggPacketHolder const& aOther); +}; + +// Queue for holding nestegg packets. +class WebMPacketQueue { + public: + int32_t GetSize() { return mQueue.size(); } + + void Push(NesteggPacketHolder* aItem) { mQueue.push_back(aItem); } + + void PushFront(NesteggPacketHolder* aItem) { + mQueue.push_front(std::move(aItem)); + } + + already_AddRefed<NesteggPacketHolder> PopFront() { + RefPtr<NesteggPacketHolder> result = std::move(mQueue.front()); + mQueue.pop_front(); + return result.forget(); + } + + void Reset() { + while (!mQueue.empty()) { + mQueue.pop_front(); + } + } + + private: + std::deque<RefPtr<NesteggPacketHolder>> mQueue; +}; + +} // namespace mozilla + +#endif |