Bug 1158226 - Store timestamps on the NesteggPacketHolder. r=kinetik

This commit is contained in:
Bobby Holley 2015-04-23 16:42:59 -07:00
parent 1fadbab407
commit 301c50d6de
4 changed files with 58 additions and 27 deletions

View File

@ -161,7 +161,7 @@ IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
return false; return false;
} }
nestegg_packet* packet = holder->mPacket; nestegg_packet* packet = holder->Packet();
unsigned int track = 0; unsigned int track = 0;
int r = nestegg_packet_track(packet, &track); int r = nestegg_packet_track(packet, &track);
if (r == -1) { if (r == -1) {
@ -187,7 +187,7 @@ IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
uint64_t next_tstamp = 0; uint64_t next_tstamp = 0;
nsRefPtr<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->Packet(), &next_tstamp);
if (r == -1) { if (r == -1) {
return false; return false;
} }

View File

@ -85,7 +85,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
return false; return false;
} }
nestegg_packet* packet = holder->mPacket; nestegg_packet* packet = holder->Packet();
unsigned int track = 0; unsigned int track = 0;
int r = nestegg_packet_track(packet, &track); int r = nestegg_packet_track(packet, &track);
if (r == -1) { if (r == -1) {
@ -111,7 +111,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
uint64_t next_tstamp = 0; uint64_t next_tstamp = 0;
nsRefPtr<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->Packet(), &next_tstamp);
if (r == -1) { if (r == -1) {
return false; return false;
} }
@ -207,7 +207,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
VideoInfo videoInfo = mReader->GetMediaInfo().mVideo; VideoInfo videoInfo = mReader->GetMediaInfo().mVideo;
nsRefPtr<VideoData> v = VideoData::Create(videoInfo, nsRefPtr<VideoData> v = VideoData::Create(videoInfo,
mReader->GetDecoder()->GetImageContainer(), mReader->GetDecoder()->GetImageContainer(),
holder->mOffset, holder->Offset(),
tstamp_usecs, tstamp_usecs,
(next_tstamp / NS_PER_USEC) - tstamp_usecs, (next_tstamp / NS_PER_USEC) - tstamp_usecs,
b, b,

View File

@ -582,19 +582,19 @@ bool WebMReader::InitOpusDecoder()
return r == OPUS_OK; return r == OPUS_OK;
} }
bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset) bool WebMReader::DecodeAudioPacket(NesteggPacketHolder* aHolder)
{ {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
int r = 0; int r = 0;
unsigned int count = 0; unsigned int count = 0;
r = nestegg_packet_count(aPacket, &count); r = nestegg_packet_count(aHolder->Packet(), &count);
if (r == -1) { if (r == -1) {
return false; return false;
} }
uint64_t tstamp = 0; uint64_t tstamp = 0;
r = nestegg_packet_tstamp(aPacket, &tstamp); r = nestegg_packet_tstamp(aHolder->Packet(), &tstamp);
if (r == -1) { if (r == -1) {
return false; return false;
} }
@ -638,16 +638,16 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
unsigned char* data; unsigned char* data;
size_t length; size_t length;
r = nestegg_packet_data(aPacket, i, &data, &length); r = nestegg_packet_data(aHolder->Packet(), i, &data, &length);
if (r == -1) { if (r == -1) {
return false; return false;
} }
if (mAudioCodec == NESTEGG_CODEC_VORBIS) { if (mAudioCodec == NESTEGG_CODEC_VORBIS) {
if (!DecodeVorbis(data, length, aOffset, tstamp_usecs, &total_frames)) { if (!DecodeVorbis(data, length, aHolder->Offset(), tstamp_usecs, &total_frames)) {
return false; return false;
} }
} else if (mAudioCodec == NESTEGG_CODEC_OPUS) { } else if (mAudioCodec == NESTEGG_CODEC_OPUS) {
if (!DecodeOpus(data, length, aOffset, tstamp_usecs, aPacket)) { if (!DecodeOpus(data, length, aHolder->Offset(), tstamp_usecs, aHolder->Packet())) {
return false; return false;
} }
} }
@ -906,7 +906,10 @@ already_AddRefed<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackTyp
return nullptr; return nullptr;
} }
int64_t offset = mDecoder->GetResource()->Tell(); int64_t offset = mDecoder->GetResource()->Tell();
holder = new NesteggPacketHolder(packet, offset); holder = new NesteggPacketHolder();
if (!holder->Init(packet, offset)) {
return nullptr;
}
unsigned int track = 0; unsigned int track = 0;
r = nestegg_packet_track(packet, &track); r = nestegg_packet_track(packet, &track);
@ -939,7 +942,7 @@ bool WebMReader::DecodeAudioData()
return false; return false;
} }
return DecodeAudioPacket(holder->mPacket, holder->mOffset); return DecodeAudioPacket(holder);
} }
bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput) bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
@ -952,7 +955,7 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
break; break;
} }
uint64_t tstamp = 0; uint64_t tstamp = 0;
int r = nestegg_packet_tstamp(holder->mPacket, &tstamp); int r = nestegg_packet_tstamp(holder->Packet(), &tstamp);
if (r == -1) { if (r == -1) {
break; break;
} }
@ -989,12 +992,12 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
break; break;
} }
unsigned int count = 0; unsigned int count = 0;
int r = nestegg_packet_count(holder->mPacket, &count); int r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) { if (r == -1) {
break; break;
} }
uint64_t tstamp = 0; uint64_t tstamp = 0;
r = nestegg_packet_tstamp(holder->mPacket, &tstamp); r = nestegg_packet_tstamp(holder->Packet(), &tstamp);
if (r == -1) { if (r == -1) {
break; break;
} }
@ -1003,7 +1006,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
unsigned char* data; unsigned char* data;
size_t length; size_t length;
r = nestegg_packet_data(holder->mPacket, i, &data, &length); r = nestegg_packet_data(holder->Packet(), i, &data, &length);
if (r == -1) { if (r == -1) {
foundKeyframe = true; foundKeyframe = true;
break; break;

View File

@ -25,6 +25,10 @@
#include "OpusParser.h" #include "OpusParser.h"
namespace mozilla {
static const unsigned NS_PER_USEC = 1000;
static const double NS_PER_S = 1e9;
// Holds a nestegg_packet, and its file offset. This is needed so we // 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 // 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 // whether it's likely we can play through to the end without needing
@ -32,27 +36,51 @@
class NesteggPacketHolder { class NesteggPacketHolder {
public: public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder)
NesteggPacketHolder(nestegg_packet* aPacket, int64_t aOffset) NesteggPacketHolder() : mPacket(nullptr), mOffset(-1), mTimestamp(-1) {}
: mPacket(aPacket), mOffset(aOffset) {}
bool Init(nestegg_packet* aPacket, int64_t aOffset)
{
uint64_t timestamp_ns;
if (nestegg_packet_tstamp(aPacket, &timestamp_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;
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; }
private:
~NesteggPacketHolder()
{
nestegg_free_packet(mPacket);
}
bool IsInitialized() { return mOffset >= 0; }
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:
~NesteggPacketHolder() { // Packet presentation timestamp in microseconds.
nestegg_free_packet(mPacket); int64_t mTimestamp;
}
// 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);
}; };
namespace mozilla {
class WebMBufferedState; class WebMBufferedState;
static const unsigned NS_PER_USEC = 1000;
static const double NS_PER_S = 1e9;
// Queue for holding nestegg packets. // Queue for holding nestegg packets.
class WebMPacketQueue { class WebMPacketQueue {
@ -174,7 +202,7 @@ protected:
// or an un-recoverable read error has occured. The reader's monitor // or an un-recoverable read error has occured. The reader's monitor
// must be held during this call. The caller is responsible for freeing // must be held during this call. The caller is responsible for freeing
// aPacket. // aPacket.
bool DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset); bool DecodeAudioPacket(NesteggPacketHolder* aHolder);
bool DecodeVorbis(const unsigned char* aData, size_t aLength, bool DecodeVorbis(const unsigned char* aData, size_t aLength,
int64_t aOffset, uint64_t aTstampUsecs, int64_t aOffset, uint64_t aTstampUsecs,
int32_t* aTotalFrames); int32_t* aTotalFrames);