mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1157840 - Refcount NesteggPacketHolder. r=kinetik
This commit is contained in:
parent
f54e89bb60
commit
4cf40b7bd9
@ -156,7 +156,7 @@ IntelWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight)
|
|||||||
bool
|
bool
|
||||||
IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
|
IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
|
||||||
{
|
{
|
||||||
nsAutoRef<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
|
nsRefPtr<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||||
if (!holder) {
|
if (!holder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -185,13 +185,13 @@ IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
|
|||||||
// end of the resource, use the file's duration as the end time of this
|
// end of the resource, use the file's duration as the end time of this
|
||||||
// video frame.
|
// video frame.
|
||||||
uint64_t next_tstamp = 0;
|
uint64_t next_tstamp = 0;
|
||||||
nsAutoRef<NesteggPacketHolder> next_holder(mReader->NextPacket(WebMReader::VIDEO));
|
nsRefPtr<NesteggPacketHolder> next_holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||||
if (next_holder) {
|
if (next_holder) {
|
||||||
r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
|
r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mReader->PushVideoPacket(next_holder.disown());
|
mReader->PushVideoPacket(next_holder.forget());
|
||||||
} else {
|
} else {
|
||||||
next_tstamp = tstamp;
|
next_tstamp = tstamp;
|
||||||
next_tstamp += tstamp - mReader->GetLastVideoFrameTime();
|
next_tstamp += tstamp - mReader->GetLastVideoFrameTime();
|
||||||
|
@ -80,7 +80,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||||||
// stats counters using the AutoNotifyDecoded stack-based class.
|
// stats counters using the AutoNotifyDecoded stack-based class.
|
||||||
AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder());
|
AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder());
|
||||||
|
|
||||||
nsAutoRef<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
|
nsRefPtr<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||||
if (!holder) {
|
if (!holder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -109,13 +109,13 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||||||
// end of the resource, use the file's duration as the end time of this
|
// end of the resource, use the file's duration as the end time of this
|
||||||
// video frame.
|
// video frame.
|
||||||
uint64_t next_tstamp = 0;
|
uint64_t next_tstamp = 0;
|
||||||
nsAutoRef<NesteggPacketHolder> next_holder(mReader->NextPacket(WebMReader::VIDEO));
|
nsRefPtr<NesteggPacketHolder> next_holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||||
if (next_holder) {
|
if (next_holder) {
|
||||||
r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
|
r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mReader->PushVideoPacket(next_holder.disown());
|
mReader->PushVideoPacket(next_holder.forget());
|
||||||
} else {
|
} else {
|
||||||
next_tstamp = tstamp;
|
next_tstamp = tstamp;
|
||||||
next_tstamp += tstamp - mReader->GetLastVideoFrameTime();
|
next_tstamp += tstamp - mReader->GetLastVideoFrameTime();
|
||||||
|
@ -867,7 +867,7 @@ bool WebMReader::DecodeOpus(const unsigned char* aData, size_t aLength,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
|
already_AddRefed<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
|
||||||
{
|
{
|
||||||
// The packet queue that packets will be pushed on if they
|
// The packet queue that packets will be pushed on if they
|
||||||
// are not the type we are interested in.
|
// are not the type we are interested in.
|
||||||
@ -892,10 +892,10 @@ nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
|
|||||||
// Value of other track
|
// Value of other track
|
||||||
uint32_t otherTrack = aTrackType == VIDEO ? mAudioTrack : mVideoTrack;
|
uint32_t otherTrack = aTrackType == VIDEO ? mAudioTrack : mVideoTrack;
|
||||||
|
|
||||||
nsAutoRef<NesteggPacketHolder> holder;
|
nsRefPtr<NesteggPacketHolder> holder;
|
||||||
|
|
||||||
if (packets.GetSize() > 0) {
|
if (packets.GetSize() > 0) {
|
||||||
holder.own(packets.PopFront());
|
holder = packets.PopFront();
|
||||||
} else {
|
} else {
|
||||||
// Keep reading packets until we find a packet
|
// Keep reading packets until we find a packet
|
||||||
// for the track we want.
|
// for the track we want.
|
||||||
@ -903,20 +903,20 @@ nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
|
|||||||
nestegg_packet* packet;
|
nestegg_packet* packet;
|
||||||
int r = nestegg_read_packet(mContext, &packet);
|
int r = nestegg_read_packet(mContext, &packet);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
return nsReturnRef<NesteggPacketHolder>();
|
return nullptr;
|
||||||
}
|
}
|
||||||
int64_t offset = mDecoder->GetResource()->Tell();
|
int64_t offset = mDecoder->GetResource()->Tell();
|
||||||
holder.own(new NesteggPacketHolder(packet, offset));
|
holder = new NesteggPacketHolder(packet, offset);
|
||||||
|
|
||||||
unsigned int track = 0;
|
unsigned int track = 0;
|
||||||
r = nestegg_packet_track(packet, &track);
|
r = nestegg_packet_track(packet, &track);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
return nsReturnRef<NesteggPacketHolder>();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasOtherType && otherTrack == track) {
|
if (hasOtherType && otherTrack == track) {
|
||||||
// Save the packet for when we want these packets
|
// Save the packet for when we want these packets
|
||||||
otherPackets.Push(holder.disown());
|
otherPackets.Push(holder.forget());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,14 +927,14 @@ nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
|
|||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return holder.out();
|
return holder.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebMReader::DecodeAudioData()
|
bool WebMReader::DecodeAudioData()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
|
|
||||||
nsAutoRef<NesteggPacketHolder> holder(NextPacket(AUDIO));
|
nsRefPtr<NesteggPacketHolder> holder(NextPacket(AUDIO));
|
||||||
if (!holder) {
|
if (!holder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -947,7 +947,7 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
|
|||||||
// Push the video frames to the aOutput which's timestamp is less
|
// Push the video frames to the aOutput which's timestamp is less
|
||||||
// than aEndTime.
|
// than aEndTime.
|
||||||
while (true) {
|
while (true) {
|
||||||
nsAutoRef<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
nsRefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
||||||
if (!holder) {
|
if (!holder) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -958,10 +958,10 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
|
|||||||
}
|
}
|
||||||
uint64_t tstamp_usecs = tstamp / NS_PER_USEC;
|
uint64_t tstamp_usecs = tstamp / NS_PER_USEC;
|
||||||
if (tstamp_usecs >= (uint64_t)aEndTime) {
|
if (tstamp_usecs >= (uint64_t)aEndTime) {
|
||||||
PushVideoPacket(holder.disown());
|
PushVideoPacket(holder.forget());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
aOutput.PushFront(holder.disown());
|
aOutput.PushFront(holder.forget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,7 +984,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
|
|||||||
bool foundKeyframe = false;
|
bool foundKeyframe = false;
|
||||||
int64_t keyframeTime = -1;
|
int64_t keyframeTime = -1;
|
||||||
while (!foundKeyframe) {
|
while (!foundKeyframe) {
|
||||||
nsAutoRef<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
nsRefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
||||||
if (!holder) {
|
if (!holder) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1022,7 +1022,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
skipPacketQueue.PushFront(holder.disown());
|
skipPacketQueue.PushFront(holder.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size = skipPacketQueue.GetSize();
|
uint32_t size = skipPacketQueue.GetSize();
|
||||||
@ -1047,9 +1047,9 @@ bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold)
|
|||||||
return mVideoDecoder->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold);
|
return mVideoDecoder->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebMReader::PushVideoPacket(NesteggPacketHolder* aItem)
|
void WebMReader::PushVideoPacket(already_AddRefed<NesteggPacketHolder> aItem)
|
||||||
{
|
{
|
||||||
mVideoPackets.PushFront(aItem);
|
mVideoPackets.PushFront(Move(aItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "nsDeque.h"
|
|
||||||
#include "MediaDecoderReader.h"
|
#include "MediaDecoderReader.h"
|
||||||
#include "nsAutoRef.h"
|
#include "nsAutoRef.h"
|
||||||
#include "nestegg/nestegg.h"
|
#include "nestegg/nestegg.h"
|
||||||
@ -32,81 +31,58 @@
|
|||||||
// to stop to buffer, given the current download rate.
|
// to stop to buffer, given the current download rate.
|
||||||
class NesteggPacketHolder {
|
class NesteggPacketHolder {
|
||||||
public:
|
public:
|
||||||
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder)
|
||||||
NesteggPacketHolder(nestegg_packet* aPacket, int64_t aOffset)
|
NesteggPacketHolder(nestegg_packet* aPacket, int64_t aOffset)
|
||||||
: mPacket(aPacket), mOffset(aOffset)
|
: mPacket(aPacket), mOffset(aOffset) {}
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(NesteggPacketHolder);
|
|
||||||
}
|
|
||||||
~NesteggPacketHolder() {
|
|
||||||
MOZ_COUNT_DTOR(NesteggPacketHolder);
|
|
||||||
nestegg_free_packet(mPacket);
|
|
||||||
}
|
|
||||||
nestegg_packet* mPacket;
|
nestegg_packet* mPacket;
|
||||||
// Offset in bytes. This is the offset of the end of the Block
|
// Offset in bytes. This is the offset of the end of the Block
|
||||||
// which contains the packet.
|
// which contains the packet.
|
||||||
int64_t mOffset;
|
int64_t mOffset;
|
||||||
private:
|
private:
|
||||||
|
~NesteggPacketHolder() {
|
||||||
|
nestegg_free_packet(mPacket);
|
||||||
|
}
|
||||||
|
|
||||||
// Copy constructor and assignment operator not implemented. Don't use them!
|
// Copy constructor and assignment operator not implemented. Don't use them!
|
||||||
NesteggPacketHolder(const NesteggPacketHolder &aOther);
|
NesteggPacketHolder(const NesteggPacketHolder &aOther);
|
||||||
NesteggPacketHolder& operator= (NesteggPacketHolder const& aOther);
|
NesteggPacketHolder& operator= (NesteggPacketHolder const& aOther);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class nsAutoRefTraits<NesteggPacketHolder> : public nsPointerRefTraits<NesteggPacketHolder>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void Release(NesteggPacketHolder* aHolder) { delete aHolder; }
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class WebMBufferedState;
|
class WebMBufferedState;
|
||||||
static const unsigned NS_PER_USEC = 1000;
|
static const unsigned NS_PER_USEC = 1000;
|
||||||
static const double NS_PER_S = 1e9;
|
static const double NS_PER_S = 1e9;
|
||||||
|
|
||||||
// Thread and type safe wrapper around nsDeque.
|
// Queue for holding nestegg packets.
|
||||||
class PacketQueueDeallocator : public nsDequeFunctor {
|
class WebMPacketQueue {
|
||||||
virtual void* operator() (void* aObject) {
|
|
||||||
delete static_cast<NesteggPacketHolder*>(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 {
|
|
||||||
public:
|
public:
|
||||||
WebMPacketQueue()
|
int32_t GetSize() {
|
||||||
: nsDeque(new PacketQueueDeallocator())
|
return mQueue.size();
|
||||||
{}
|
|
||||||
|
|
||||||
~WebMPacketQueue() {
|
|
||||||
Reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t GetSize() {
|
void Push(already_AddRefed<NesteggPacketHolder> aItem) {
|
||||||
return nsDeque::GetSize();
|
mQueue.push_back(Move(aItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Push(NesteggPacketHolder* aItem) {
|
void PushFront(already_AddRefed<NesteggPacketHolder> aItem) {
|
||||||
NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue");
|
mQueue.push_front(Move(aItem));
|
||||||
nsDeque::Push(aItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PushFront(NesteggPacketHolder* aItem) {
|
already_AddRefed<NesteggPacketHolder> PopFront() {
|
||||||
NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue");
|
nsRefPtr<NesteggPacketHolder> result = mQueue.front().forget();
|
||||||
nsDeque::PushFront(aItem);
|
mQueue.pop_front();
|
||||||
}
|
return result.forget();
|
||||||
|
|
||||||
inline NesteggPacketHolder* PopFront() {
|
|
||||||
return static_cast<NesteggPacketHolder*>(nsDeque::PopFront());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
while (GetSize() > 0) {
|
while (!mQueue.empty()) {
|
||||||
delete PopFront();
|
mQueue.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::deque<nsRefPtr<NesteggPacketHolder>> mQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebMReader;
|
class WebMReader;
|
||||||
@ -175,10 +151,10 @@ public:
|
|||||||
// Read a packet from the nestegg file. Returns nullptr if all packets for
|
// 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
|
// the particular track have been read. Pass VIDEO or AUDIO to indicate the
|
||||||
// type of the packet we want to read.
|
// type of the packet we want to read.
|
||||||
nsReturnRef<NesteggPacketHolder> NextPacket(TrackType aTrackType);
|
already_AddRefed<NesteggPacketHolder> NextPacket(TrackType aTrackType);
|
||||||
|
|
||||||
// Pushes a packet to the front of the video packet queue.
|
// Pushes a packet to the front of the video packet queue.
|
||||||
virtual void PushVideoPacket(NesteggPacketHolder* aItem);
|
virtual void PushVideoPacket(already_AddRefed<NesteggPacketHolder> aItem);
|
||||||
|
|
||||||
int GetVideoCodec();
|
int GetVideoCodec();
|
||||||
nsIntRect GetPicture();
|
nsIntRect GetPicture();
|
||||||
@ -245,7 +221,7 @@ private:
|
|||||||
uint64_t mSeekPreroll; // Nanoseconds to discard after seeking.
|
uint64_t mSeekPreroll; // Nanoseconds to discard after seeking.
|
||||||
|
|
||||||
// Queue of video and audio packets that have been read but not decoded. These
|
// 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 mVideoPackets;
|
||||||
WebMPacketQueue mAudioPackets;
|
WebMPacketQueue mAudioPackets;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user