Bug 1261900: [webm] P1. Use block duration if known. r?kinetik
The duration returned however appears to always be zero.
MozReview-Commit-ID: 8llqDhAqNmk
--- a/dom/media/webm/NesteggPacketHolder.h
+++ b/dom/media/webm/NesteggPacketHolder.h
@@ -14,39 +14,49 @@ 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), mIsKeyframe(false) {}
+ NesteggPacketHolder()
+ : mPacket(nullptr)
+ , mOffset(-1)
+ , mTimestamp(-1)
+ , mDuration(-1)
+ , 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);
}
@@ -57,16 +67,19 @@ private:
// 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);
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -506,40 +506,45 @@ WebMDemuxer::GetNextPacket(TrackInfo::Tr
int r = 0;
unsigned int count = 0;
r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) {
return false;
}
int64_t tstamp = holder->Timestamp();
+ int64_t duration = holder->Duration();
- // The end time of this frame is the start time of the next frame. Fetch
+ // The end time of this frame is the start time of the next frame. Fetch
// the timestamp of the next packet for this track. If we've reached the
// end of the resource, use the file's duration as the end time of this
// video frame.
int64_t next_tstamp = INT64_MIN;
if (aType == TrackInfo::kAudioTrack) {
RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushAudioPacket(next_holder);
+ } else if (duration >= 0) {
+ next_tstamp = tstamp + duration;
} else if (!mIsMediaSource ||
(mIsMediaSource && mLastAudioFrameTime.isSome())) {
next_tstamp = tstamp;
next_tstamp += tstamp - mLastAudioFrameTime.refOr(0);
} else {
PushAudioPacket(holder);
}
mLastAudioFrameTime = Some(tstamp);
} else if (aType == TrackInfo::kVideoTrack) {
RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushVideoPacket(next_holder);
+ } else if (duration >= 0) {
+ next_tstamp = tstamp + duration;
} else if (!mIsMediaSource ||
(mIsMediaSource && mLastVideoFrameTime.isSome())) {
next_tstamp = tstamp;
next_tstamp += tstamp - mLastVideoFrameTime.refOr(0);
} else {
PushVideoPacket(holder);
}
mLastVideoFrameTime = Some(tstamp);