From 7b3c4b00396adcedd6b3dfa2002ea40054ded20e Mon Sep 17 00:00:00 2001 From: trav90 Date: Sun, 9 Jul 2017 01:36:40 -0500 Subject: [PATCH] Refcount NesteggPacketHolder Also move WebM code away from nsDeque. --- dom/media/webm/IntelWebMVideoDecoder.cpp | 6 +- dom/media/webm/SoftwareWebMVideoDecoder.cpp | 6 +- dom/media/webm/WebMReader.cpp | 32 ++++----- dom/media/webm/WebMReader.h | 78 +++++++-------------- 4 files changed, 49 insertions(+), 73 deletions(-) diff --git a/dom/media/webm/IntelWebMVideoDecoder.cpp b/dom/media/webm/IntelWebMVideoDecoder.cpp index 56a90a133e..1f63292013 100644 --- a/dom/media/webm/IntelWebMVideoDecoder.cpp +++ b/dom/media/webm/IntelWebMVideoDecoder.cpp @@ -156,7 +156,7 @@ IntelWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight) bool IntelWebMVideoDecoder::Demux(nsRefPtr& aSample, bool* aEOS) { - nsAutoRef holder(mReader->NextPacket(WebMReader::VIDEO)); + nsRefPtr holder(mReader->NextPacket(WebMReader::VIDEO)); if (!holder) { return false; } @@ -185,13 +185,13 @@ IntelWebMVideoDecoder::Demux(nsRefPtr& aSample, bool* aEOS) // end of the resource, use the file's duration as the end time of this // video frame. uint64_t next_tstamp = 0; - nsAutoRef next_holder(mReader->NextPacket(WebMReader::VIDEO)); + nsRefPtr next_holder(mReader->NextPacket(WebMReader::VIDEO)); if (next_holder) { r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp); if (r == -1) { return false; } - mReader->PushVideoPacket(next_holder.disown()); + mReader->PushVideoPacket(next_holder.forget()); } else { next_tstamp = tstamp; next_tstamp += tstamp - mReader->GetLastVideoFrameTime(); diff --git a/dom/media/webm/SoftwareWebMVideoDecoder.cpp b/dom/media/webm/SoftwareWebMVideoDecoder.cpp index 8cf596dbd9..23b02d199a 100644 --- a/dom/media/webm/SoftwareWebMVideoDecoder.cpp +++ b/dom/media/webm/SoftwareWebMVideoDecoder.cpp @@ -97,7 +97,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip, // stats counters using the AutoNotifyDecoded stack-based class. AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder()); - nsAutoRef holder(mReader->NextPacket(WebMReader::VIDEO)); + nsRefPtr holder(mReader->NextPacket(WebMReader::VIDEO)); if (!holder) { return false; } @@ -126,13 +126,13 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip, // end of the resource, use the file's duration as the end time of this // video frame. uint64_t next_tstamp = 0; - nsAutoRef next_holder(mReader->NextPacket(WebMReader::VIDEO)); + nsRefPtr next_holder(mReader->NextPacket(WebMReader::VIDEO)); if (next_holder) { r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp); if (r == -1) { return false; } - mReader->PushVideoPacket(next_holder.disown()); + mReader->PushVideoPacket(next_holder.forget()); } else { next_tstamp = tstamp; next_tstamp += tstamp - mReader->GetLastVideoFrameTime(); diff --git a/dom/media/webm/WebMReader.cpp b/dom/media/webm/WebMReader.cpp index 4ebf09eefb..516d3770a3 100644 --- a/dom/media/webm/WebMReader.cpp +++ b/dom/media/webm/WebMReader.cpp @@ -865,7 +865,7 @@ bool WebMReader::DecodeOpus(const unsigned char* aData, size_t aLength, return true; } -nsReturnRef WebMReader::NextPacket(TrackType aTrackType) +already_AddRefed WebMReader::NextPacket(TrackType aTrackType) { // The packet queue that packets will be pushed on if they // are not the type we are interested in. @@ -890,10 +890,10 @@ nsReturnRef WebMReader::NextPacket(TrackType aTrackType) // Value of other track uint32_t otherTrack = aTrackType == VIDEO ? mAudioTrack : mVideoTrack; - nsAutoRef holder; + nsRefPtr holder; if (packets.GetSize() > 0) { - holder.own(packets.PopFront()); + holder = packets.PopFront(); } else { // Keep reading packets until we find a packet // for the track we want. @@ -901,20 +901,20 @@ nsReturnRef WebMReader::NextPacket(TrackType aTrackType) nestegg_packet* packet; int r = nestegg_read_packet(mContext, &packet); if (r <= 0) { - return nsReturnRef(); + return nullptr; } int64_t offset = mDecoder->GetResource()->Tell(); - holder.own(new NesteggPacketHolder(packet, offset)); + holder = new NesteggPacketHolder(packet, offset); unsigned int track = 0; r = nestegg_packet_track(packet, &track); if (r == -1) { - return nsReturnRef(); + return already_AddRefed(); } if (hasOtherType && otherTrack == track) { // Save the packet for when we want these packets - otherPackets.Push(holder.disown()); + otherPackets.Push(holder.forget()); continue; } @@ -925,14 +925,14 @@ nsReturnRef WebMReader::NextPacket(TrackType aTrackType) } while (true); } - return holder.out(); + return holder.forget(); } bool WebMReader::DecodeAudioData() { MOZ_ASSERT(OnTaskQueue()); - nsAutoRef holder(NextPacket(AUDIO)); + nsRefPtr holder(NextPacket(AUDIO)); if (!holder) { return false; } @@ -945,7 +945,7 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput) // Push the video frames to the aOutput which's timestamp is less // than aEndTime. while (true) { - nsAutoRef holder(NextPacket(VIDEO)); + nsRefPtr holder(NextPacket(VIDEO)); if (!holder) { break; } @@ -956,10 +956,10 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput) } uint64_t tstamp_usecs = tstamp / NS_PER_USEC; if (tstamp_usecs >= (uint64_t)aEndTime) { - PushVideoPacket(holder.disown()); + PushVideoPacket(holder.forget()); return true; } else { - aOutput.PushFront(holder.disown()); + aOutput.PushFront(holder.forget()); } } @@ -982,7 +982,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold) bool foundKeyframe = false; int64_t keyframeTime = -1; while (!foundKeyframe) { - nsAutoRef holder(NextPacket(VIDEO)); + nsRefPtr holder(NextPacket(VIDEO)); if (!holder) { break; } @@ -1020,7 +1020,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold) break; } } - skipPacketQueue.PushFront(holder.disown()); + skipPacketQueue.PushFront(holder.forget()); } uint32_t size = skipPacketQueue.GetSize(); @@ -1045,9 +1045,9 @@ bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) return mVideoDecoder->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold); } -void WebMReader::PushVideoPacket(NesteggPacketHolder* aItem) +void WebMReader::PushVideoPacket(already_AddRefed aItem) { - mVideoPackets.PushFront(aItem); + mVideoPackets.PushFront(Move(aItem)); } nsRefPtr diff --git a/dom/media/webm/WebMReader.h b/dom/media/webm/WebMReader.h index a79d109fda..1e9e46fdb7 100644 --- a/dom/media/webm/WebMReader.h +++ b/dom/media/webm/WebMReader.h @@ -8,7 +8,6 @@ #include -#include "nsDeque.h" #include "MediaDecoderReader.h" #include "nsAutoRef.h" #include "nestegg/nestegg.h" @@ -32,81 +31,58 @@ // to stop to buffer, given the current download rate. class NesteggPacketHolder { public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder) NesteggPacketHolder(nestegg_packet* aPacket, int64_t aOffset) - : mPacket(aPacket), mOffset(aOffset) - { - MOZ_COUNT_CTOR(NesteggPacketHolder); - } - ~NesteggPacketHolder() { - MOZ_COUNT_DTOR(NesteggPacketHolder); - nestegg_free_packet(mPacket); - } + : mPacket(aPacket), mOffset(aOffset) {} + nestegg_packet* mPacket; // Offset in bytes. This is the offset of the end of the Block // which contains the packet. int64_t mOffset; private: + ~NesteggPacketHolder() { + nestegg_free_packet(mPacket); + } + // Copy constructor and assignment operator not implemented. Don't use them! NesteggPacketHolder(const NesteggPacketHolder &aOther); NesteggPacketHolder& operator= (NesteggPacketHolder const& aOther); }; -template <> -class nsAutoRefTraits : public nsPointerRefTraits -{ -public: - static void Release(NesteggPacketHolder* aHolder) { delete aHolder; } -}; - namespace mozilla { class WebMBufferedState; static const unsigned NS_PER_USEC = 1000; static const double NS_PER_S = 1e9; -// Thread and type safe wrapper around nsDeque. -class PacketQueueDeallocator : public nsDequeFunctor { - virtual void* operator() (void* aObject) { - delete static_cast(aObject); - return nullptr; - } -}; - -// Typesafe queue for holding nestegg packets. It has -// ownership of the items in the queue and will free them -// when destroyed. -class WebMPacketQueue : private nsDeque { +// Queue for holding nestegg packets. +class WebMPacketQueue { public: - WebMPacketQueue() - : nsDeque(new PacketQueueDeallocator()) - {} - - ~WebMPacketQueue() { - Reset(); + int32_t GetSize() { + return mQueue.size(); } - inline int32_t GetSize() { - return nsDeque::GetSize(); + void Push(already_AddRefed aItem) { + mQueue.push_back(Move(aItem)); } - inline void Push(NesteggPacketHolder* aItem) { - NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue"); - nsDeque::Push(aItem); + void PushFront(already_AddRefed aItem) { + mQueue.push_front(Move(aItem)); } - inline void PushFront(NesteggPacketHolder* aItem) { - NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue"); - nsDeque::PushFront(aItem); - } - - inline NesteggPacketHolder* PopFront() { - return static_cast(nsDeque::PopFront()); + already_AddRefed PopFront() { + nsRefPtr result = mQueue.front().forget(); + mQueue.pop_front(); + return result.forget(); } void Reset() { - while (GetSize() > 0) { - delete PopFront(); + while (!mQueue.empty()) { + mQueue.pop_front(); } } + +private: + std::deque> mQueue; }; class WebMReader; @@ -175,10 +151,10 @@ public: // Read a packet from the nestegg file. Returns nullptr if all packets for // the particular track have been read. Pass VIDEO or AUDIO to indicate the // type of the packet we want to read. - nsReturnRef NextPacket(TrackType aTrackType); + already_AddRefed NextPacket(TrackType aTrackType); // Pushes a packet to the front of the video packet queue. - virtual void PushVideoPacket(NesteggPacketHolder* aItem); + virtual void PushVideoPacket(already_AddRefed aItem); int GetVideoCodec(); nsIntRect GetPicture(); @@ -245,7 +221,7 @@ private: uint64_t mSeekPreroll; // Nanoseconds to discard after seeking. // Queue of video and audio packets that have been read but not decoded. These - // must only be accessed from the state machine thread. + // must only be accessed from the decode thread. WebMPacketQueue mVideoPackets; WebMPacketQueue mAudioPackets;